Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

### Changed

- config: enable temporal decay, MMR, and importance scoring by default in semantic memory; existing configs with explicit `enabled = false` are unaffected (#2101)
- config: change default vector backend from Qdrant to SQLite — zero-dependency out-of-box experience; set `vector_backend = "qdrant"` to revert (#2101)
- config: enable anomaly detection, audit logging, and cost tracking by default; `max_daily_cents = 0` (unlimited) — cost is tracked but not capped (#2101)
- config: enable `autosave_assistant` by default (`min_length = 20`); assistant responses are now persisted to semantic memory unless explicitly disabled (#2101)

- refactor(zeph-llm): remove redundant `schema` feature gate — `schemars` is now a mandatory dependency of `zeph-llm`; all `#[cfg(feature = "schema")]` / `#[cfg_attr(feature = "schema", ...)]` annotations removed; `chat_typed`, `chat_typed_erased`, structured output types, and the `extractor` module are always compiled (#2100)
- Promote `scheduler` and `guardrail` features to the default feature set; users with `default-features = false` are unaffected

Expand Down
20 changes: 10 additions & 10 deletions config/default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,13 @@ prune_protect_tokens = 40000
# Minimum relevance score for cross-session memory results (0.0-1.0)
cross_session_score_threshold = 0.35
# Vector backend: "qdrant" (external) or "sqlite" (embedded, zero-dependency)
# vector_backend = "qdrant"
vector_backend = "sqlite"
# Token safety margin multiplier for compaction budget (must be > 0)
# token_safety_margin = 1.0
# Redact credentials from LLM context before sending
# redact_credentials = true
# Auto-save assistant responses to semantic memory
# autosave_assistant = false
autosave_assistant = true
# Minimum character length for autosave (shorter responses skip embedding)
# autosave_min_length = 20
# Store a lightweight session summary on shutdown when no hard compaction fired
Expand Down Expand Up @@ -270,14 +270,14 @@ recall_limit = 5
vector_weight = 0.7
keyword_weight = 0.3
# Temporal decay: penalize older memories by age
# temporal_decay_enabled = false
temporal_decay_enabled = true
# temporal_decay_half_life_days = 30
# MMR re-ranking: diversify recall results
# mmr_enabled = false
mmr_enabled = true
# mmr_lambda = 0.7
# Write-time importance scoring: boost recall rank for messages with explicit markers (#2021)
# importance_enabled = false
# importance_weight = 0.15
importance_enabled = true
importance_weight = 0.15

# Code RAG: AST-based code indexing and hybrid retrieval
# Requires Qdrant for semantic retrieval; tree-sitter grammars are always available
Expand Down Expand Up @@ -364,9 +364,9 @@ max_dynamic_servers = 10

[cost]
# Track LLM API costs and enforce daily budget
enabled = false
enabled = true
# Maximum daily spend in cents (0 = unlimited)
max_daily_cents = 500
max_daily_cents = 0

[observability]
# Tracing exporter: "" (disabled) or "otlp" (requires otel feature)
Expand Down Expand Up @@ -462,7 +462,7 @@ max_overflow_bytes = 10485760

[tools.audit]
# Enable audit logging for tool executions
enabled = false
enabled = true
# Audit destination: "stdout" or file path (e.g., "./data/audit.jsonl")
destination = "stdout"

Expand All @@ -487,7 +487,7 @@ default_effect = "deny"

[tools.anomaly]
# Enable sliding-window anomaly detection for tool execution errors
enabled = false
enabled = true
# Number of recent tool calls to track in the window
window_size = 10
# Error ratio threshold for warning alerts (0.0-1.0)
Expand Down
19 changes: 11 additions & 8 deletions crates/zeph-config/config/default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,13 @@ prune_protect_tokens = 40000
# Minimum relevance score for cross-session memory results (0.0-1.0)
cross_session_score_threshold = 0.35
# Vector backend: "qdrant" (external) or "sqlite" (embedded, zero-dependency)
# vector_backend = "qdrant"
vector_backend = "sqlite"
# Token safety margin multiplier for compaction budget (must be > 0)
# token_safety_margin = 1.0
# Redact credentials from LLM context before sending
# redact_credentials = true
# Auto-save assistant responses to semantic memory
# autosave_assistant = false
autosave_assistant = true
# Minimum character length for autosave (shorter responses skip embedding)
# autosave_min_length = 20
# Use structured anchored summaries for context compaction (experimental, off by default)
Expand Down Expand Up @@ -264,11 +264,14 @@ recall_limit = 5
vector_weight = 0.7
keyword_weight = 0.3
# Temporal decay: penalize older memories by age
# temporal_decay_enabled = false
temporal_decay_enabled = true
# temporal_decay_half_life_days = 30
# MMR re-ranking: diversify recall results
# mmr_enabled = false
mmr_enabled = true
# mmr_lambda = 0.7
# Write-time importance scoring: boost recall rank for messages with explicit markers (#2021)
importance_enabled = true
importance_weight = 0.15

# Code RAG: AST-based code indexing and hybrid retrieval
# Requires Qdrant for semantic retrieval; tree-sitter grammars are always available
Expand Down Expand Up @@ -334,9 +337,9 @@ max_dynamic_servers = 10

[cost]
# Track LLM API costs and enforce daily budget
enabled = false
enabled = true
# Maximum daily spend in cents (0 = unlimited)
max_daily_cents = 500
max_daily_cents = 0

[observability]
# Tracing exporter: "" (disabled) or "otlp" (requires otel feature)
Expand Down Expand Up @@ -432,7 +435,7 @@ max_overflow_bytes = 10485760

[tools.audit]
# Enable audit logging for tool executions
enabled = false
enabled = true
# Audit destination: "stdout" or file path (e.g., "./data/audit.jsonl")
destination = "stdout"

Expand All @@ -446,7 +449,7 @@ default_effect = "deny"

[tools.anomaly]
# Enable sliding-window anomaly detection for tool execution errors
enabled = false
enabled = true
# Number of recent tool calls to track in the window
window_size = 10
# Error ratio threshold for warning alerts (0.0-1.0)
Expand Down
6 changes: 3 additions & 3 deletions crates/zeph-config/src/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn default_vault_backend() -> String {
}

fn default_max_daily_cents() -> u32 {
500
0
}

fn default_otlp_endpoint() -> String {
Expand Down Expand Up @@ -180,7 +180,7 @@ impl Default for VaultConfig {

#[derive(Debug, Deserialize, Serialize)]
pub struct CostConfig {
#[serde(default)]
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_max_daily_cents")]
pub max_daily_cents: u32,
Expand All @@ -189,7 +189,7 @@ pub struct CostConfig {
impl Default for CostConfig {
fn default() -> Self {
Self {
enabled: false,
enabled: true,
max_daily_cents: default_max_daily_cents(),
}
}
Expand Down
18 changes: 9 additions & 9 deletions crates/zeph-config/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use serde::{Deserialize, Serialize};

use crate::defaults::default_sqlite_path_field;
use crate::defaults::{default_sqlite_path_field, default_true};

fn default_sqlite_pool_size() -> u32 {
5
Expand Down Expand Up @@ -504,8 +504,8 @@ impl Default for NoteLinkingConfig {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum VectorBackend {
#[default]
Qdrant,
#[default]
Sqlite,
}

Expand Down Expand Up @@ -558,7 +558,7 @@ pub struct MemoryConfig {
pub token_safety_margin: f32,
#[serde(default = "default_redact_credentials")]
pub redact_credentials: bool,
#[serde(default)]
#[serde(default = "default_true")]
pub autosave_assistant: bool,
#[serde(default = "default_autosave_min_length")]
pub autosave_min_length: usize,
Expand Down Expand Up @@ -674,15 +674,15 @@ pub struct SemanticConfig {
pub vector_weight: f64,
#[serde(default = "default_keyword_weight")]
pub keyword_weight: f64,
#[serde(default)]
#[serde(default = "default_true")]
pub temporal_decay_enabled: bool,
#[serde(default = "default_temporal_decay_half_life_days")]
pub temporal_decay_half_life_days: u32,
#[serde(default)]
#[serde(default = "default_true")]
pub mmr_enabled: bool,
#[serde(default = "default_mmr_lambda")]
pub mmr_lambda: f32,
#[serde(default)]
#[serde(default = "default_true")]
pub importance_enabled: bool,
#[serde(
default = "default_importance_weight",
Expand All @@ -698,11 +698,11 @@ impl Default for SemanticConfig {
recall_limit: default_recall_limit(),
vector_weight: default_vector_weight(),
keyword_weight: default_keyword_weight(),
temporal_decay_enabled: false,
temporal_decay_enabled: true,
temporal_decay_half_life_days: default_temporal_decay_half_life_days(),
mmr_enabled: false,
mmr_enabled: true,
mmr_lambda: default_mmr_lambda(),
importance_enabled: false,
importance_enabled: true,
importance_weight: default_importance_weight(),
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/zeph-config/src/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ impl Default for Config {
vector_backend: VectorBackend::default(),
token_safety_margin: 1.0,
redact_credentials: true,
autosave_assistant: false,
autosave_assistant: true,
autosave_min_length: 20,
tool_call_cutoff: 6,
sqlite_pool_size: 5,
Expand Down
3 changes: 2 additions & 1 deletion crates/zeph-core/src/agent/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1229,7 +1229,8 @@ mod tests {
fn apply_session_config_skips_anomaly_detector_when_disabled() {
use crate::config::Config;

let config = Config::default(); // anomaly.enabled defaults to false
let mut config = Config::default();
config.tools.anomaly.enabled = false; // explicitly disable to test the disabled path
let session_cfg = AgentSessionConfig::from_config(&config, 100_000);
assert!(!session_cfg.anomaly_config.enabled);

Expand Down
2 changes: 1 addition & 1 deletion crates/zeph-core/src/cost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ impl CostTracker {
state.spent_cents = 0.0;
state.day = today;
}
if state.spent_cents >= self.max_daily_cents {
if self.max_daily_cents > 0.0 && state.spent_cents >= self.max_daily_cents {
return Err(BudgetExhausted {
spent_cents: state.spent_cents,
budget_cents: self.max_daily_cents,
Expand Down
14 changes: 7 additions & 7 deletions crates/zeph-tools/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ fn default_anomaly_critical_threshold() -> f64 {
/// Configuration for the sliding-window anomaly detector.
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct AnomalyConfig {
#[serde(default)]
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_anomaly_window")]
pub window_size: usize,
Expand All @@ -102,7 +102,7 @@ pub struct AnomalyConfig {
impl Default for AnomalyConfig {
fn default() -> Self {
Self {
enabled: false,
enabled: true,
window_size: default_anomaly_window(),
error_threshold: default_anomaly_error_threshold(),
critical_threshold: default_anomaly_critical_threshold(),
Expand Down Expand Up @@ -284,7 +284,7 @@ pub struct ShellConfig {
/// Configuration for audit logging of tool executions.
#[derive(Debug, Deserialize, Serialize)]
pub struct AuditConfig {
#[serde(default)]
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_audit_destination")]
pub destination: String,
Expand Down Expand Up @@ -327,7 +327,7 @@ impl Default for ShellConfig {
impl Default for AuditConfig {
fn default() -> Self {
Self {
enabled: false,
enabled: true,
destination: default_audit_destination(),
}
}
Expand Down Expand Up @@ -401,7 +401,7 @@ mod tests {
assert!(config.summarize_output);
assert_eq!(config.shell.timeout, 30);
assert!(config.shell.blocked_commands.is_empty());
assert!(!config.audit.enabled);
assert!(config.audit.enabled);
}

#[test]
Expand Down Expand Up @@ -440,7 +440,7 @@ mod tests {
assert!(!config.shell.confirm_patterns.is_empty());
assert_eq!(config.scrape.timeout, 15);
assert_eq!(config.scrape.max_body_bytes, 4_194_304);
assert!(!config.audit.enabled);
assert!(config.audit.enabled);
assert_eq!(config.audit.destination, "stdout");
assert!(config.summarize_output);
}
Expand Down Expand Up @@ -521,7 +521,7 @@ mod tests {
#[test]
fn default_audit_config() {
let config = AuditConfig::default();
assert!(!config.enabled);
assert!(config.enabled);
assert_eq!(config.destination, "stdout");
}

Expand Down
Loading