1use serde::{Deserialize, Serialize};
5
6use crate::defaults::{default_skill_paths, default_true};
7use crate::learning::LearningConfig;
8use crate::security::TrustConfig;
9
10fn default_disambiguation_threshold() -> f32 {
11 0.05
12}
13
14fn default_cosine_weight() -> f32 {
15 0.7
16}
17
18fn default_hybrid_search() -> bool {
19 true
20}
21
22fn default_max_active_skills() -> usize {
23 5
24}
25
26fn default_index_watch() -> bool {
27 true
28}
29
30fn default_index_search_enabled() -> bool {
31 true
32}
33
34fn default_index_max_chunks() -> usize {
35 12
36}
37
38fn default_index_score_threshold() -> f32 {
39 0.25
40}
41
42fn default_index_budget_ratio() -> f32 {
43 0.40
44}
45
46fn default_index_repo_map_tokens() -> usize {
47 500
48}
49
50fn default_repo_map_ttl_secs() -> u64 {
51 300
52}
53
54fn default_vault_backend() -> String {
55 "env".into()
56}
57
58fn default_max_daily_cents() -> u32 {
59 0
60}
61
62fn default_otlp_endpoint() -> String {
63 "http://localhost:4317".into()
64}
65
66fn default_pid_file() -> String {
67 "~/.zeph/zeph.pid".into()
68}
69
70fn default_health_interval() -> u64 {
71 30
72}
73
74fn default_max_restart_backoff() -> u64 {
75 60
76}
77
78fn default_scheduler_tick_interval() -> u64 {
79 60
80}
81
82fn default_scheduler_max_tasks() -> usize {
83 100
84}
85
86fn default_gateway_bind() -> String {
87 "127.0.0.1".into()
88}
89
90fn default_gateway_port() -> u16 {
91 8090
92}
93
94fn default_gateway_rate_limit() -> u32 {
95 120
96}
97
98fn default_gateway_max_body() -> usize {
99 1_048_576
100}
101
102#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Deserialize, Serialize)]
104#[serde(rename_all = "lowercase")]
105pub enum SkillPromptMode {
106 Full,
107 Compact,
108 #[default]
109 Auto,
110}
111
112#[derive(Debug, Deserialize, Serialize)]
113pub struct SkillsConfig {
114 #[serde(default = "default_skill_paths")]
115 pub paths: Vec<String>,
116 #[serde(default = "default_max_active_skills")]
117 pub max_active_skills: usize,
118 #[serde(default = "default_disambiguation_threshold")]
119 pub disambiguation_threshold: f32,
120 #[serde(default = "default_cosine_weight")]
121 pub cosine_weight: f32,
122 #[serde(default = "default_hybrid_search")]
123 pub hybrid_search: bool,
124 #[serde(default)]
125 pub learning: LearningConfig,
126 #[serde(default)]
127 pub trust: TrustConfig,
128 #[serde(default)]
129 pub prompt_mode: SkillPromptMode,
130}
131
132#[derive(Debug, Deserialize, Serialize)]
133pub struct IndexConfig {
134 #[serde(default)]
135 pub enabled: bool,
136 #[serde(default = "default_index_search_enabled")]
137 pub search_enabled: bool,
138 #[serde(default = "default_index_watch")]
139 pub watch: bool,
140 #[serde(default = "default_index_max_chunks")]
141 pub max_chunks: usize,
142 #[serde(default = "default_index_score_threshold")]
143 pub score_threshold: f32,
144 #[serde(default = "default_index_budget_ratio")]
145 pub budget_ratio: f32,
146 #[serde(default = "default_index_repo_map_tokens")]
147 pub repo_map_tokens: usize,
148 #[serde(default = "default_repo_map_ttl_secs")]
149 pub repo_map_ttl_secs: u64,
150}
151
152impl Default for IndexConfig {
153 fn default() -> Self {
154 Self {
155 enabled: false,
156 search_enabled: default_index_search_enabled(),
157 watch: default_index_watch(),
158 max_chunks: default_index_max_chunks(),
159 score_threshold: default_index_score_threshold(),
160 budget_ratio: default_index_budget_ratio(),
161 repo_map_tokens: default_index_repo_map_tokens(),
162 repo_map_ttl_secs: default_repo_map_ttl_secs(),
163 }
164 }
165}
166
167#[derive(Debug, Deserialize, Serialize)]
168pub struct VaultConfig {
169 #[serde(default = "default_vault_backend")]
170 pub backend: String,
171}
172
173impl Default for VaultConfig {
174 fn default() -> Self {
175 Self {
176 backend: default_vault_backend(),
177 }
178 }
179}
180
181#[derive(Debug, Deserialize, Serialize)]
182pub struct CostConfig {
183 #[serde(default = "default_true")]
184 pub enabled: bool,
185 #[serde(default = "default_max_daily_cents")]
186 pub max_daily_cents: u32,
187}
188
189impl Default for CostConfig {
190 fn default() -> Self {
191 Self {
192 enabled: true,
193 max_daily_cents: default_max_daily_cents(),
194 }
195 }
196}
197
198#[derive(Debug, Deserialize, Serialize)]
199pub struct ObservabilityConfig {
200 #[serde(default)]
201 pub exporter: String,
202 #[serde(default = "default_otlp_endpoint")]
203 pub endpoint: String,
204}
205
206impl Default for ObservabilityConfig {
207 fn default() -> Self {
208 Self {
209 exporter: String::new(),
210 endpoint: default_otlp_endpoint(),
211 }
212 }
213}
214
215#[derive(Debug, Clone, Deserialize, Serialize)]
216pub struct GatewayConfig {
217 #[serde(default)]
218 pub enabled: bool,
219 #[serde(default = "default_gateway_bind")]
220 pub bind: String,
221 #[serde(default = "default_gateway_port")]
222 pub port: u16,
223 #[serde(default)]
224 pub auth_token: Option<String>,
225 #[serde(default = "default_gateway_rate_limit")]
226 pub rate_limit: u32,
227 #[serde(default = "default_gateway_max_body")]
228 pub max_body_size: usize,
229}
230
231impl Default for GatewayConfig {
232 fn default() -> Self {
233 Self {
234 enabled: false,
235 bind: default_gateway_bind(),
236 port: default_gateway_port(),
237 auth_token: None,
238 rate_limit: default_gateway_rate_limit(),
239 max_body_size: default_gateway_max_body(),
240 }
241 }
242}
243
244#[derive(Debug, Clone, Deserialize, Serialize)]
245pub struct DaemonConfig {
246 #[serde(default)]
247 pub enabled: bool,
248 #[serde(default = "default_pid_file")]
249 pub pid_file: String,
250 #[serde(default = "default_health_interval")]
251 pub health_interval_secs: u64,
252 #[serde(default = "default_max_restart_backoff")]
253 pub max_restart_backoff_secs: u64,
254}
255
256impl Default for DaemonConfig {
257 fn default() -> Self {
258 Self {
259 enabled: false,
260 pid_file: default_pid_file(),
261 health_interval_secs: default_health_interval(),
262 max_restart_backoff_secs: default_max_restart_backoff(),
263 }
264 }
265}
266
267#[derive(Debug, Clone, Deserialize, Serialize)]
268pub struct SchedulerConfig {
269 #[serde(default)]
270 pub enabled: bool,
271 #[serde(default = "default_scheduler_tick_interval")]
272 pub tick_interval_secs: u64,
273 #[serde(default = "default_scheduler_max_tasks")]
274 pub max_tasks: usize,
275 #[serde(default)]
276 pub tasks: Vec<ScheduledTaskConfig>,
277}
278
279impl Default for SchedulerConfig {
280 fn default() -> Self {
281 Self {
282 enabled: true,
283 tick_interval_secs: default_scheduler_tick_interval(),
284 max_tasks: default_scheduler_max_tasks(),
285 tasks: Vec::new(),
286 }
287 }
288}
289
290#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
294#[serde(rename_all = "snake_case")]
295pub enum ScheduledTaskKind {
296 MemoryCleanup,
297 SkillRefresh,
298 HealthCheck,
299 UpdateCheck,
300 Experiment,
301 Custom(String),
302}
303
304#[derive(Debug, Clone, Deserialize, Serialize)]
305pub struct ScheduledTaskConfig {
306 pub name: String,
307 #[serde(default, skip_serializing_if = "Option::is_none")]
308 pub cron: Option<String>,
309 #[serde(default, skip_serializing_if = "Option::is_none")]
310 pub run_at: Option<String>,
311 pub kind: ScheduledTaskKind,
312 #[serde(default)]
313 pub config: serde_json::Value,
314}
315
316fn default_trace_service_name() -> String {
317 "zeph".into()
318}
319
320#[derive(Debug, Clone, Deserialize, Serialize)]
327#[serde(default)]
328pub struct TraceConfig {
329 #[serde(default = "default_otlp_endpoint")]
332 pub otlp_endpoint: String,
333 #[serde(default = "default_trace_service_name")]
335 pub service_name: String,
336 #[serde(default = "default_true")]
338 pub redact: bool,
339}
340
341impl Default for TraceConfig {
342 fn default() -> Self {
343 Self {
344 otlp_endpoint: default_otlp_endpoint(),
345 service_name: default_trace_service_name(),
346 redact: true,
347 }
348 }
349}
350
351#[derive(Debug, Clone, Deserialize, Serialize)]
352#[serde(default)]
353pub struct DebugConfig {
354 pub enabled: bool,
356 #[serde(default = "crate::defaults::default_debug_output_dir")]
358 pub output_dir: std::path::PathBuf,
359 pub format: crate::dump_format::DumpFormat,
361 pub traces: TraceConfig,
363}
364
365impl Default for DebugConfig {
366 fn default() -> Self {
367 Self {
368 enabled: false,
369 output_dir: super::defaults::default_debug_output_dir(),
370 format: crate::dump_format::DumpFormat::default(),
371 traces: TraceConfig::default(),
372 }
373 }
374}