1use std::collections::HashMap;
5
6use serde::{Deserialize, Serialize};
7use zeph_common::secret::Secret;
8use zeph_tools::ToolsConfig;
9
10use crate::agent::{AgentConfig, FocusConfig, SubAgentConfig};
11use crate::channels::{A2aServerConfig, DiscordConfig, McpConfig, SlackConfig, TelegramConfig};
12use crate::classifiers::ClassifiersConfig;
13use crate::cli::CliConfig;
14use crate::defaults::{default_skill_paths, default_sqlite_path_field};
15use crate::experiment::{ExperimentConfig, OrchestrationConfig};
16use crate::features::{
17 CostConfig, DaemonConfig, DebugConfig, GatewayConfig, IndexConfig, SchedulerConfig,
18 SkillPromptMode, SkillsConfig, VaultConfig,
19};
20use crate::hooks::HooksConfig;
21use crate::learning::LearningConfig;
22use crate::logging::LoggingConfig;
23use crate::memory::{
24 CompressionConfig, DocumentConfig, GraphConfig, MagicDocsConfig, MemoryConfig, SemanticConfig,
25 SessionsConfig, SidequestConfig, TierConfig, VectorBackend,
26};
27use crate::metrics::MetricsConfig;
28use crate::notifications::NotificationsConfig;
29use crate::providers::{
30 LlmConfig, get_default_embedding_model, get_default_response_cache_ttl_secs,
31 get_default_router_ema_alpha, get_default_router_reorder_interval,
32};
33use crate::security::TrustConfig;
34use crate::security::{SecurityConfig, TimeoutConfig};
35use crate::telemetry::TelemetryConfig;
36use crate::ui::LspConfig;
37use crate::ui::{AcpConfig, TuiConfig};
38
39#[derive(Debug, Deserialize, Serialize)]
45pub struct Config {
46 pub agent: AgentConfig,
47 pub llm: LlmConfig,
48 pub skills: SkillsConfig,
49 pub memory: MemoryConfig,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 pub telegram: Option<TelegramConfig>,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub discord: Option<DiscordConfig>,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub slack: Option<SlackConfig>,
56 #[serde(default)]
57 pub tools: ToolsConfig,
58 #[serde(default)]
59 pub a2a: A2aServerConfig,
60 #[serde(default)]
61 pub mcp: McpConfig,
62 #[serde(default)]
63 pub index: IndexConfig,
64 #[serde(default)]
65 pub vault: VaultConfig,
66 #[serde(default)]
67 pub security: SecurityConfig,
68 #[serde(default)]
69 pub timeouts: TimeoutConfig,
70 #[serde(default)]
71 pub cost: CostConfig,
72 #[serde(default)]
73 pub gateway: GatewayConfig,
74 #[serde(default)]
75 pub daemon: DaemonConfig,
76 #[serde(default)]
77 pub scheduler: SchedulerConfig,
78 #[serde(default)]
79 pub tui: TuiConfig,
80 #[serde(default)]
81 pub acp: AcpConfig,
82 #[serde(default)]
83 pub agents: SubAgentConfig,
84 #[serde(default)]
85 pub orchestration: OrchestrationConfig,
86 #[serde(default)]
87 pub classifiers: ClassifiersConfig,
88 #[serde(default)]
89 pub experiments: ExperimentConfig,
90 #[serde(default)]
91 pub debug: DebugConfig,
92 #[serde(default)]
93 pub logging: LoggingConfig,
94 #[serde(default)]
95 pub hooks: HooksConfig,
96 #[serde(default)]
97 pub lsp: LspConfig,
98 #[serde(default)]
100 pub magic_docs: MagicDocsConfig,
101 #[serde(default)]
103 pub telemetry: TelemetryConfig,
104 #[serde(default)]
106 pub metrics: MetricsConfig,
107 #[serde(default)]
109 pub session: crate::session::SessionConfig,
110 #[serde(default)]
112 pub cli: CliConfig,
113 #[serde(default)]
115 pub quality: crate::quality::QualityConfig,
116 #[serde(default)]
118 pub notifications: NotificationsConfig,
119 #[serde(skip)]
121 pub secrets: ResolvedSecrets,
122}
123
124#[derive(Debug, Default)]
129pub struct ResolvedSecrets {
130 pub claude_api_key: Option<Secret>,
131 pub openai_api_key: Option<Secret>,
132 pub gemini_api_key: Option<Secret>,
133 pub compatible_api_keys: HashMap<String, Secret>,
134 pub discord_token: Option<Secret>,
135 pub slack_bot_token: Option<Secret>,
136 pub slack_signing_secret: Option<Secret>,
137 pub custom: HashMap<String, Secret>,
140}
141
142impl Default for Config {
143 #[allow(clippy::too_many_lines)] fn default() -> Self {
145 Self {
146 agent: AgentConfig {
147 name: "Zeph".into(),
148 max_tool_iterations: 10,
149 auto_update_check: true,
150 instruction_files: Vec::new(),
151 instruction_auto_detect: true,
152 max_tool_retries: 2,
153 tool_repeat_threshold: 2,
154 max_retry_duration_secs: 30,
155 focus: FocusConfig::default(),
156 tool_filter: crate::agent::ToolFilterConfig::default(),
157 budget_hint_enabled: true,
158 supervisor: crate::agent::TaskSupervisorConfig::default(),
159 },
160 llm: LlmConfig {
161 providers: Vec::new(),
162 routing: crate::providers::LlmRoutingStrategy::None,
163 embedding_model: get_default_embedding_model(),
164 candle: None,
165 stt: None,
166 response_cache_enabled: false,
167 response_cache_ttl_secs: get_default_response_cache_ttl_secs(),
168 semantic_cache_enabled: false,
169 semantic_cache_threshold: 0.95,
170 semantic_cache_max_candidates: 10,
171 router_ema_enabled: false,
172 router_ema_alpha: get_default_router_ema_alpha(),
173 router_reorder_interval: get_default_router_reorder_interval(),
174 router: None,
175 instruction_file: None,
176 summary_model: None,
177 summary_provider: None,
178 complexity_routing: None,
179 coe: None,
180 },
181 skills: SkillsConfig {
182 paths: default_skill_paths(),
183 max_active_skills: 5,
184 disambiguation_threshold: 0.20,
185 min_injection_score: 0.20,
186 cosine_weight: 0.7,
187 hybrid_search: true,
188 learning: LearningConfig::default(),
189 trust: TrustConfig::default(),
190 prompt_mode: SkillPromptMode::Auto,
191 two_stage_matching: false,
192 confusability_threshold: 0.0,
193 rl_routing_enabled: false,
194 rl_learning_rate: 0.01,
195 rl_weight: 0.3,
196 rl_persist_interval: 10,
197 rl_warmup_updates: 50,
198 rl_embed_dim: None,
199 generation_provider: crate::providers::ProviderName::default(),
200 generation_output_dir: None,
201 mining: crate::features::SkillMiningConfig::default(),
202 evaluation: crate::features::SkillEvaluationConfig::default(),
203 proactive_exploration: crate::features::ProactiveExplorationConfig::default(),
204 },
205 memory: MemoryConfig {
206 sqlite_path: default_sqlite_path_field(),
207 history_limit: 50,
208 qdrant_url: "http://localhost:6334".into(),
209 semantic: SemanticConfig::default(),
210 summarization_threshold: 50,
211 context_budget_tokens: 0,
212 soft_compaction_threshold: 0.60,
213 hard_compaction_threshold: 0.90,
214 compaction_preserve_tail: 6,
215 compaction_cooldown_turns: 2,
216 auto_budget: true,
217 prune_protect_tokens: 40_000,
218 cross_session_score_threshold: 0.35,
219 vector_backend: VectorBackend::default(),
220 token_safety_margin: 1.0,
221 redact_credentials: true,
222 autosave_assistant: true,
223 autosave_min_length: 20,
224 tool_call_cutoff: 6,
225 sqlite_pool_size: 5,
226 sessions: SessionsConfig::default(),
227 documents: DocumentConfig::default(),
228 eviction: zeph_memory::EvictionConfig::default(),
229 compression: CompressionConfig::default(),
230 sidequest: SidequestConfig::default(),
231 graph: GraphConfig::default(),
232 compression_guidelines: zeph_memory::CompressionGuidelinesConfig::default(),
233 shutdown_summary: true,
234 shutdown_summary_min_messages: 4,
235 shutdown_summary_max_messages: 20,
236 shutdown_summary_timeout_secs: 10,
237 structured_summaries: false,
238 tiers: TierConfig::default(),
239 admission: crate::memory::AdmissionConfig::default(),
240 digest: crate::memory::DigestConfig::default(),
241 context_strategy: crate::memory::ContextStrategy::default(),
242 crossover_turn_threshold: 20,
243 consolidation: crate::memory::ConsolidationConfig::default(),
244 forgetting: crate::memory::ForgettingConfig::default(),
245 database_url: None,
246 store_routing: crate::memory::StoreRoutingConfig::default(),
247 persona: crate::memory::PersonaConfig::default(),
248 trajectory: crate::memory::TrajectoryConfig::default(),
249 category: crate::memory::CategoryConfig::default(),
250 tree: crate::memory::TreeConfig::default(),
251 microcompact: crate::memory::MicrocompactConfig::default(),
252 autodream: crate::memory::AutoDreamConfig::default(),
253 key_facts_dedup_threshold: 0.95,
254 compression_spectrum: crate::features::CompressionSpectrumConfig::default(),
255 retrieval: crate::memory::RetrievalConfig::default(),
256 reasoning: crate::memory::ReasoningConfig::default(),
257 hebbian: crate::memory::HebbianConfig::default(),
258 },
259 telegram: None,
260 discord: None,
261 slack: None,
262 tools: ToolsConfig::default(),
263 a2a: A2aServerConfig::default(),
264 mcp: McpConfig::default(),
265 index: IndexConfig::default(),
266 vault: VaultConfig::default(),
267 security: SecurityConfig::default(),
268 timeouts: TimeoutConfig::default(),
269 cost: CostConfig::default(),
270 gateway: GatewayConfig::default(),
271 daemon: DaemonConfig::default(),
272 scheduler: SchedulerConfig::default(),
273 tui: TuiConfig::default(),
274 acp: AcpConfig::default(),
275 agents: SubAgentConfig::default(),
276 orchestration: OrchestrationConfig::default(),
277 classifiers: ClassifiersConfig::default(),
278 experiments: ExperimentConfig::default(),
279 debug: DebugConfig::default(),
280 logging: LoggingConfig::default(),
281 lsp: LspConfig::default(),
282 hooks: HooksConfig::default(),
283 magic_docs: MagicDocsConfig::default(),
284 telemetry: TelemetryConfig::default(),
285 metrics: MetricsConfig::default(),
286 session: crate::session::SessionConfig::default(),
287 cli: CliConfig::default(),
288 quality: crate::quality::QualityConfig::default(),
289 notifications: NotificationsConfig::default(),
290 secrets: ResolvedSecrets::default(),
291 }
292 }
293}