1use std::collections::{HashMap, HashSet, VecDeque};
10use std::path::PathBuf;
11use std::sync::Arc;
12
13use parking_lot::RwLock;
14use std::time::Instant;
15
16use tokio::sync::{Notify, mpsc, watch};
17use tokio::task::JoinHandle;
18use tokio_util::sync::CancellationToken;
19use zeph_llm::any::AnyProvider;
20use zeph_llm::provider::Message;
21use zeph_llm::stt::SpeechToText;
22
23use crate::config::{ProviderEntry, SecurityConfig, SkillPromptMode, TimeoutConfig};
24use crate::config_watcher::ConfigEvent;
25use crate::context::EnvironmentContext;
26use crate::cost::CostTracker;
27use crate::file_watcher::FileChangedEvent;
28use crate::instructions::{InstructionBlock, InstructionEvent, InstructionReloadState};
29use crate::metrics::MetricsSnapshot;
30use crate::vault::Secret;
31use zeph_config;
32use zeph_memory::TokenCounter;
33use zeph_memory::semantic::SemanticMemory;
34use zeph_sanitizer::ContentSanitizer;
35use zeph_sanitizer::quarantine::QuarantinedSummarizer;
36use zeph_skills::matcher::SkillMatcherBackend;
37use zeph_skills::registry::SkillRegistry;
38use zeph_skills::watcher::SkillEvent;
39
40use super::message_queue::QueuedMessage;
41
42pub(crate) struct MemoryState {
43 pub(crate) memory: Option<Arc<SemanticMemory>>,
44 pub(crate) conversation_id: Option<zeph_memory::ConversationId>,
45 pub(crate) history_limit: u32,
46 pub(crate) recall_limit: usize,
47 pub(crate) summarization_threshold: usize,
48 pub(crate) cross_session_score_threshold: f32,
49 pub(crate) autosave_assistant: bool,
50 pub(crate) autosave_min_length: usize,
51 pub(crate) tool_call_cutoff: usize,
52 pub(crate) unsummarized_count: usize,
53 pub(crate) document_config: crate::config::DocumentConfig,
54 pub(crate) graph_config: crate::config::GraphConfig,
55 pub(crate) compression_guidelines_config: zeph_memory::CompressionGuidelinesConfig,
56 pub(crate) shutdown_summary: bool,
57 pub(crate) shutdown_summary_min_messages: usize,
58 pub(crate) shutdown_summary_max_messages: usize,
59 pub(crate) shutdown_summary_timeout_secs: u64,
60 pub(crate) structured_summaries: bool,
63 pub(crate) last_recall_confidence: Option<f32>,
67 pub(crate) digest_config: crate::config::DigestConfig,
69 pub(crate) cached_session_digest: Option<(String, usize)>,
71 pub(crate) context_strategy: crate::config::ContextStrategy,
73 pub(crate) crossover_turn_threshold: u32,
75 pub(crate) rpe_router: Option<std::sync::Mutex<zeph_memory::RpeRouter>>,
78 pub(crate) goal_text: Option<String>,
82 pub(crate) persona_config: zeph_config::PersonaConfig,
84 pub(crate) trajectory_config: zeph_config::TrajectoryConfig,
86 pub(crate) category_config: zeph_config::CategoryConfig,
88 pub(crate) tree_config: zeph_config::TreeConfig,
90 pub(crate) microcompact_config: zeph_config::MicrocompactConfig,
92 pub(crate) autodream_config: zeph_config::AutoDreamConfig,
94 pub(crate) magic_docs_config: zeph_config::MagicDocsConfig,
96 pub(crate) tree_consolidation_handle: Option<tokio::task::JoinHandle<()>>,
99 pub(crate) autodream: super::autodream::AutoDreamState,
101 pub(crate) magic_docs: super::magic_docs::MagicDocsState,
103}
104
105pub(crate) struct SkillState {
106 pub(crate) registry: Arc<RwLock<SkillRegistry>>,
107 pub(crate) skill_paths: Vec<PathBuf>,
108 pub(crate) managed_dir: Option<PathBuf>,
109 pub(crate) trust_config: crate::config::TrustConfig,
110 pub(crate) matcher: Option<SkillMatcherBackend>,
111 pub(crate) max_active_skills: usize,
112 pub(crate) disambiguation_threshold: f32,
113 pub(crate) min_injection_score: f32,
114 pub(crate) embedding_model: String,
115 pub(crate) skill_reload_rx: Option<mpsc::Receiver<SkillEvent>>,
116 pub(crate) active_skill_names: Vec<String>,
117 pub(crate) last_skills_prompt: String,
118 pub(crate) prompt_mode: SkillPromptMode,
119 pub(crate) available_custom_secrets: HashMap<String, Secret>,
121 pub(crate) cosine_weight: f32,
122 pub(crate) hybrid_search: bool,
123 pub(crate) bm25_index: Option<zeph_skills::bm25::Bm25Index>,
124 pub(crate) two_stage_matching: bool,
125 pub(crate) confusability_threshold: f32,
127 pub(crate) rl_head: Option<zeph_skills::rl_head::RoutingHead>,
130 pub(crate) rl_weight: f32,
132 pub(crate) rl_warmup_updates: u32,
134 pub(crate) generation_output_dir: Option<std::path::PathBuf>,
137 pub(crate) generation_provider_name: String,
139}
140
141pub(crate) struct McpState {
142 pub(crate) tools: Vec<zeph_mcp::McpTool>,
143 pub(crate) registry: Option<zeph_mcp::McpToolRegistry>,
144 pub(crate) manager: Option<std::sync::Arc<zeph_mcp::McpManager>>,
145 pub(crate) allowed_commands: Vec<String>,
146 pub(crate) max_dynamic: usize,
147 pub(crate) elicitation_rx: Option<tokio::sync::mpsc::Receiver<zeph_mcp::ElicitationEvent>>,
151 pub(crate) shared_tools: Option<Arc<RwLock<Vec<zeph_mcp::McpTool>>>>,
163 pub(crate) tool_rx: Option<tokio::sync::watch::Receiver<Vec<zeph_mcp::McpTool>>>,
165 pub(crate) server_outcomes: Vec<zeph_mcp::ServerConnectOutcome>,
167 pub(crate) pruning_cache: zeph_mcp::PruningCache,
172 pub(crate) pruning_provider: Option<zeph_llm::any::AnyProvider>,
178 pub(crate) pruning_enabled: bool,
180 pub(crate) pruning_params: zeph_mcp::PruningParams,
182 pub(crate) semantic_index: Option<zeph_mcp::SemanticToolIndex>,
187 pub(crate) discovery_strategy: zeph_mcp::ToolDiscoveryStrategy,
189 pub(crate) discovery_params: zeph_mcp::DiscoveryParams,
191 pub(crate) discovery_provider: Option<zeph_llm::any::AnyProvider>,
194 pub(crate) elicitation_warn_sensitive_fields: bool,
197}
198
199pub(crate) struct IndexState {
200 pub(crate) retriever: Option<std::sync::Arc<zeph_index::retriever::CodeRetriever>>,
201 pub(crate) repo_map_tokens: usize,
202 pub(crate) cached_repo_map: Option<(String, std::time::Instant)>,
203 pub(crate) repo_map_ttl: std::time::Duration,
204}
205
206#[derive(Debug, Clone)]
208pub struct AdversarialPolicyInfo {
209 pub provider: String,
210 pub policy_count: usize,
211 pub fail_open: bool,
212}
213
214pub(crate) struct RuntimeConfig {
215 pub(crate) security: SecurityConfig,
216 pub(crate) timeouts: TimeoutConfig,
217 pub(crate) model_name: String,
218 pub(crate) active_provider_name: String,
221 pub(crate) permission_policy: zeph_tools::PermissionPolicy,
222 pub(crate) redact_credentials: bool,
223 pub(crate) rate_limiter: super::rate_limiter::ToolRateLimiter,
224 pub(crate) semantic_cache_enabled: bool,
225 pub(crate) semantic_cache_threshold: f32,
226 pub(crate) semantic_cache_max_candidates: u32,
227 pub(crate) dependency_config: zeph_tools::DependencyConfig,
229 pub(crate) adversarial_policy_info: Option<AdversarialPolicyInfo>,
231 pub(crate) spawn_depth: u32,
234 pub(crate) budget_hint_enabled: bool,
236 pub(crate) channel_skills: zeph_config::ChannelSkillsConfig,
239 pub(crate) layers: Vec<std::sync::Arc<dyn crate::runtime_layer::RuntimeLayer>>,
243}
244
245pub(crate) struct FeedbackState {
247 pub(crate) detector: super::feedback_detector::FeedbackDetector,
248 pub(crate) judge: Option<super::feedback_detector::JudgeDetector>,
249 pub(crate) llm_classifier: Option<zeph_llm::classifier::llm::LlmClassifier>,
252}
253
254pub(crate) struct SecurityState {
256 pub(crate) sanitizer: ContentSanitizer,
257 pub(crate) quarantine_summarizer: Option<QuarantinedSummarizer>,
258 pub(crate) is_acp_session: bool,
262 pub(crate) exfiltration_guard: zeph_sanitizer::exfiltration::ExfiltrationGuard,
263 pub(crate) flagged_urls: HashSet<String>,
264 pub(crate) user_provided_urls: Arc<RwLock<HashSet<String>>>,
268 pub(crate) pii_filter: zeph_sanitizer::pii::PiiFilter,
269 #[cfg(feature = "classifiers")]
273 pub(crate) pii_ner_backend: Option<std::sync::Arc<dyn zeph_llm::classifier::ClassifierBackend>>,
274 #[cfg(feature = "classifiers")]
276 pub(crate) pii_ner_timeout_ms: u64,
277 #[cfg(feature = "classifiers")]
282 pub(crate) pii_ner_max_chars: usize,
283 #[cfg(feature = "classifiers")]
286 pub(crate) pii_ner_circuit_breaker_threshold: u32,
287 #[cfg(feature = "classifiers")]
289 pub(crate) pii_ner_consecutive_timeouts: u32,
290 #[cfg(feature = "classifiers")]
292 pub(crate) pii_ner_tripped: bool,
293 pub(crate) memory_validator: zeph_sanitizer::memory_validation::MemoryWriteValidator,
294 pub(crate) guardrail: Option<zeph_sanitizer::guardrail::GuardrailFilter>,
296 pub(crate) response_verifier: zeph_sanitizer::response_verifier::ResponseVerifier,
298 pub(crate) causal_analyzer: Option<zeph_sanitizer::causal_ipi::TurnCausalAnalyzer>,
300}
301
302pub(crate) struct DebugState {
304 pub(crate) debug_dumper: Option<crate::debug_dump::DebugDumper>,
305 pub(crate) dump_format: crate::debug_dump::DumpFormat,
306 pub(crate) trace_collector: Option<crate::debug_dump::trace::TracingCollector>,
307 pub(crate) iteration_counter: usize,
310 pub(crate) anomaly_detector: Option<zeph_tools::AnomalyDetector>,
311 pub(crate) reasoning_model_warning: bool,
314 pub(crate) logging_config: crate::config::LoggingConfig,
315 pub(crate) dump_dir: Option<PathBuf>,
317 pub(crate) trace_service_name: String,
319 pub(crate) trace_redact: bool,
321 pub(crate) current_iteration_span_id: Option<[u8; 8]>,
324}
325
326pub(crate) struct LifecycleState {
328 pub(crate) shutdown: watch::Receiver<bool>,
329 pub(crate) start_time: Instant,
330 pub(crate) cancel_signal: Arc<Notify>,
331 pub(crate) cancel_token: CancellationToken,
332 pub(crate) cancel_bridge_handle: Option<JoinHandle<()>>,
335 pub(crate) config_path: Option<PathBuf>,
336 pub(crate) config_reload_rx: Option<mpsc::Receiver<ConfigEvent>>,
337 pub(crate) warmup_ready: Option<watch::Receiver<bool>>,
338 pub(crate) update_notify_rx: Option<mpsc::Receiver<String>>,
339 pub(crate) custom_task_rx: Option<mpsc::Receiver<String>>,
340 pub(crate) last_known_cwd: PathBuf,
342 pub(crate) file_changed_rx: Option<mpsc::Receiver<FileChangedEvent>>,
344 pub(crate) file_watcher: Option<crate::file_watcher::FileChangeWatcher>,
346}
347
348pub struct ProviderConfigSnapshot {
353 pub claude_api_key: Option<String>,
354 pub openai_api_key: Option<String>,
355 pub gemini_api_key: Option<String>,
356 pub compatible_api_keys: std::collections::HashMap<String, String>,
357 pub llm_request_timeout_secs: u64,
358 pub embedding_model: String,
359}
360
361pub(crate) struct ProviderState {
363 pub(crate) summary_provider: Option<AnyProvider>,
364 pub(crate) provider_override: Option<Arc<RwLock<Option<AnyProvider>>>>,
366 pub(crate) judge_provider: Option<AnyProvider>,
367 pub(crate) probe_provider: Option<AnyProvider>,
370 pub(crate) compress_provider: Option<AnyProvider>,
373 pub(crate) cached_prompt_tokens: u64,
374 pub(crate) server_compaction_active: bool,
377 pub(crate) stt: Option<Box<dyn SpeechToText>>,
378 pub(crate) provider_pool: Vec<ProviderEntry>,
380 pub(crate) provider_config_snapshot: Option<ProviderConfigSnapshot>,
382}
383
384pub(crate) struct MetricsState {
386 pub(crate) metrics_tx: Option<watch::Sender<MetricsSnapshot>>,
387 pub(crate) cost_tracker: Option<CostTracker>,
388 pub(crate) token_counter: Arc<TokenCounter>,
389 pub(crate) extended_context: bool,
392 pub(crate) classifier_metrics: Option<Arc<zeph_llm::ClassifierMetrics>>,
395}
396
397#[derive(Default)]
399pub(crate) struct OrchestrationState {
400 pub(crate) planner_provider: Option<AnyProvider>,
403 pub(crate) verify_provider: Option<AnyProvider>,
406 pub(crate) pending_graph: Option<zeph_orchestration::TaskGraph>,
408 pub(crate) plan_cancel_token: Option<CancellationToken>,
417 pub(crate) subagent_manager: Option<zeph_subagent::SubAgentManager>,
419 pub(crate) subagent_config: crate::config::SubAgentConfig,
420 pub(crate) orchestration_config: crate::config::OrchestrationConfig,
421 pub(crate) plan_cache: Option<zeph_orchestration::PlanCache>,
424 pub(crate) pending_goal_embedding: Option<Vec<f32>>,
427}
428
429#[derive(Default)]
431pub(crate) struct InstructionState {
432 pub(crate) blocks: Vec<InstructionBlock>,
433 pub(crate) reload_rx: Option<mpsc::Receiver<InstructionEvent>>,
434 pub(crate) reload_state: Option<InstructionReloadState>,
435}
436
437pub(crate) struct ExperimentState {
439 pub(crate) config: crate::config::ExperimentConfig,
440 pub(crate) cancel: Option<tokio_util::sync::CancellationToken>,
442 pub(crate) baseline: zeph_experiments::ConfigSnapshot,
444 pub(crate) eval_provider: Option<AnyProvider>,
447 pub(crate) notify_rx: Option<tokio::sync::mpsc::Receiver<String>>,
450 pub(crate) notify_tx: tokio::sync::mpsc::Sender<String>,
452}
453
454pub(crate) struct SubgoalExtractionResult {
456 pub(crate) current: String,
458 pub(crate) completed: Option<String>,
460}
461
462#[derive(Default)]
464pub(crate) struct CompressionState {
465 pub(crate) current_task_goal: Option<String>,
468 pub(crate) task_goal_user_msg_hash: Option<u64>,
470 pub(crate) pending_task_goal: Option<tokio::task::JoinHandle<Option<String>>>,
473 pub(crate) pending_sidequest_result: Option<tokio::task::JoinHandle<Option<Vec<usize>>>>,
476 pub(crate) subgoal_registry: crate::agent::compaction_strategy::SubgoalRegistry,
478 pub(crate) pending_subgoal: Option<tokio::task::JoinHandle<Option<SubgoalExtractionResult>>>,
480 pub(crate) subgoal_user_msg_hash: Option<u64>,
482}
483
484#[derive(Default)]
486pub(crate) struct ToolState {
487 pub(crate) tool_schema_filter: Option<zeph_tools::ToolSchemaFilter>,
489 pub(crate) cached_filtered_tool_ids: Option<HashSet<String>>,
491 pub(crate) dependency_graph: Option<zeph_tools::ToolDependencyGraph>,
493 pub(crate) dependency_always_on: HashSet<String>,
495 pub(crate) completed_tool_ids: HashSet<String>,
497 pub(crate) current_tool_iteration: usize,
499}
500
501pub(crate) struct SessionState {
503 pub(crate) env_context: EnvironmentContext,
504 pub(crate) last_assistant_at: Option<Instant>,
508 pub(crate) response_cache: Option<std::sync::Arc<zeph_memory::ResponseCache>>,
509 pub(crate) parent_tool_use_id: Option<String>,
513 pub(crate) status_tx: Option<tokio::sync::mpsc::UnboundedSender<String>>,
515 pub(crate) lsp_hooks: Option<crate::lsp_hooks::LspHookRunner>,
518 pub(crate) policy_config: Option<zeph_tools::PolicyConfig>,
520 pub(crate) hooks_config: HooksConfigSnapshot,
522}
523
524#[derive(Default)]
526pub(crate) struct HooksConfigSnapshot {
527 pub(crate) cwd_changed: Vec<zeph_config::HookDef>,
529 pub(crate) file_changed_hooks: Vec<zeph_config::HookDef>,
531}
532
533pub(crate) struct MessageState {
535 pub(crate) messages: Vec<Message>,
536 #[allow(private_interfaces)]
538 pub(crate) message_queue: VecDeque<QueuedMessage>,
539 pub(crate) pending_image_parts: Vec<zeph_llm::provider::MessagePart>,
541 pub(crate) last_persisted_message_id: Option<i64>,
544 pub(crate) deferred_db_hide_ids: Vec<i64>,
546 pub(crate) deferred_db_summaries: Vec<String>,
548}
549
550impl McpState {
551 pub(crate) fn sync_executor_tools(&self) {
558 if let Some(ref shared) = self.shared_tools {
559 shared.write().clone_from(&self.tools);
560 }
561 }
562
563 pub(crate) fn apply_pruned_tools(&self, pruned: Vec<zeph_mcp::McpTool>) {
571 debug_assert!(
572 pruned.iter().all(|p| self
573 .tools
574 .iter()
575 .any(|t| t.server_id == p.server_id && t.name == p.name)),
576 "pruned set must be a subset of self.tools"
577 );
578 if let Some(ref shared) = self.shared_tools {
579 *shared.write() = pruned;
580 }
581 }
582
583 #[cfg(test)]
584 pub(crate) fn tool_count(&self) -> usize {
585 self.tools.len()
586 }
587}
588
589impl IndexState {
590 pub(crate) async fn fetch_code_rag(
591 &self,
592 query: &str,
593 token_budget: usize,
594 ) -> Result<Option<String>, crate::agent::error::AgentError> {
595 let Some(retriever) = &self.retriever else {
596 return Ok(None);
597 };
598 if token_budget == 0 {
599 return Ok(None);
600 }
601
602 let result = retriever
603 .retrieve(query, token_budget)
604 .await
605 .map_err(|e| crate::agent::error::AgentError::Other(format!("{e:#}")))?;
606 let context_text = zeph_index::retriever::format_as_context(&result);
607
608 if context_text.is_empty() {
609 Ok(None)
610 } else {
611 tracing::debug!(
612 strategy = ?result.strategy,
613 chunks = result.chunks.len(),
614 tokens = result.total_tokens,
615 "code context fetched"
616 );
617 Ok(Some(context_text))
618 }
619 }
620}
621
622impl DebugState {
623 pub(crate) fn start_iteration_span(&mut self, iteration_index: usize, text: &str) {
624 if let Some(ref mut tc) = self.trace_collector {
625 tc.begin_iteration(iteration_index, text);
626 self.current_iteration_span_id = tc.current_iteration_span_id(iteration_index);
627 }
628 }
629
630 pub(crate) fn end_iteration_span(
631 &mut self,
632 iteration_index: usize,
633 status: crate::debug_dump::trace::SpanStatus,
634 ) {
635 if let Some(ref mut tc) = self.trace_collector {
636 tc.end_iteration(iteration_index, status);
637 }
638 self.current_iteration_span_id = None;
639 }
640
641 pub(crate) fn switch_format(&mut self, new_format: crate::debug_dump::DumpFormat) {
642 let was_trace = self.dump_format == crate::debug_dump::DumpFormat::Trace;
643 let now_trace = new_format == crate::debug_dump::DumpFormat::Trace;
644
645 if now_trace
646 && !was_trace
647 && let Some(ref dump_dir) = self.dump_dir.clone()
648 {
649 let service_name = self.trace_service_name.clone();
650 let redact = self.trace_redact;
651 match crate::debug_dump::trace::TracingCollector::new(
652 dump_dir.as_path(),
653 &service_name,
654 redact,
655 None,
656 ) {
657 Ok(collector) => {
658 self.trace_collector = Some(collector);
659 }
660 Err(e) => {
661 tracing::warn!(error = %e, "failed to create TracingCollector on format switch");
662 }
663 }
664 }
665 if was_trace
666 && !now_trace
667 && let Some(mut tc) = self.trace_collector.take()
668 {
669 tc.finish();
670 }
671
672 self.dump_format = new_format;
673 }
674
675 pub(crate) fn write_chat_debug_dump(
676 &self,
677 dump_id: Option<u32>,
678 result: &zeph_llm::provider::ChatResponse,
679 pii_filter: &zeph_sanitizer::pii::PiiFilter,
680 ) {
681 let Some((d, id)) = self.debug_dumper.as_ref().zip(dump_id) else {
682 return;
683 };
684 let raw = match result {
685 zeph_llm::provider::ChatResponse::Text(t) => t.clone(),
686 zeph_llm::provider::ChatResponse::ToolUse {
687 text, tool_calls, ..
688 } => {
689 let calls = serde_json::to_string_pretty(tool_calls).unwrap_or_default();
690 format!(
691 "{}\n\n---TOOL_CALLS---\n{calls}",
692 text.as_deref().unwrap_or("")
693 )
694 }
695 };
696 let text = if pii_filter.is_enabled() {
697 pii_filter.scrub(&raw).into_owned()
698 } else {
699 raw
700 };
701 d.dump_response(id, &text);
702 }
703}
704
705impl Default for MemoryState {
706 fn default() -> Self {
707 Self {
708 memory: None,
709 conversation_id: None,
710 history_limit: 50,
711 recall_limit: 5,
712 summarization_threshold: 50,
713 cross_session_score_threshold: 0.35,
714 autosave_assistant: false,
715 autosave_min_length: 20,
716 tool_call_cutoff: 6,
717 unsummarized_count: 0,
718 document_config: crate::config::DocumentConfig::default(),
719 graph_config: crate::config::GraphConfig::default(),
720 compression_guidelines_config: zeph_memory::CompressionGuidelinesConfig::default(),
721 shutdown_summary: true,
722 shutdown_summary_min_messages: 4,
723 shutdown_summary_max_messages: 20,
724 shutdown_summary_timeout_secs: 10,
725 structured_summaries: false,
726 last_recall_confidence: None,
727 digest_config: crate::config::DigestConfig::default(),
728 cached_session_digest: None,
729 context_strategy: crate::config::ContextStrategy::default(),
730 crossover_turn_threshold: 20,
731 rpe_router: None,
732 goal_text: None,
733 persona_config: crate::config::PersonaConfig::default(),
734 trajectory_config: crate::config::TrajectoryConfig::default(),
735 category_config: crate::config::CategoryConfig::default(),
736 tree_config: crate::config::TreeConfig::default(),
737 tree_consolidation_handle: None,
738 microcompact_config: crate::config::MicrocompactConfig::default(),
739 autodream_config: crate::config::AutoDreamConfig::default(),
740 magic_docs_config: crate::config::MagicDocsConfig::default(),
741 autodream: super::autodream::AutoDreamState::new(),
742 magic_docs: super::magic_docs::MagicDocsState::new(),
743 }
744 }
745}
746
747impl MemoryState {
748 pub(crate) fn apply_graph_config(&mut self, config: crate::config::GraphConfig) {
749 if config.enabled {
750 tracing::warn!(
751 "graph-memory is enabled: extracted entities are stored without PII redaction. \
752 Do not use with sensitive personal data until redaction is implemented."
753 );
754 }
755 if config.rpe.enabled {
756 self.rpe_router = Some(std::sync::Mutex::new(zeph_memory::RpeRouter::new(
757 config.rpe.threshold,
758 config.rpe.max_skip_turns,
759 )));
760 } else {
761 self.rpe_router = None;
762 }
763 self.graph_config = config;
764 }
765}
766
767impl Default for McpState {
768 fn default() -> Self {
769 Self {
770 tools: Vec::new(),
771 registry: None,
772 manager: None,
773 allowed_commands: Vec::new(),
774 max_dynamic: 10,
775 elicitation_rx: None,
776 shared_tools: None,
777 tool_rx: None,
778 server_outcomes: Vec::new(),
779 pruning_cache: zeph_mcp::PruningCache::new(),
780 pruning_provider: None,
781 pruning_enabled: false,
782 pruning_params: zeph_mcp::PruningParams::default(),
783 semantic_index: None,
784 discovery_strategy: zeph_mcp::ToolDiscoveryStrategy::default(),
785 discovery_params: zeph_mcp::DiscoveryParams::default(),
786 discovery_provider: None,
787 elicitation_warn_sensitive_fields: true,
788 }
789 }
790}
791
792impl Default for IndexState {
793 fn default() -> Self {
794 Self {
795 retriever: None,
796 repo_map_tokens: 0,
797 cached_repo_map: None,
798 repo_map_ttl: std::time::Duration::from_secs(300),
799 }
800 }
801}
802
803impl Default for DebugState {
804 fn default() -> Self {
805 Self {
806 debug_dumper: None,
807 dump_format: crate::debug_dump::DumpFormat::default(),
808 trace_collector: None,
809 iteration_counter: 0,
810 anomaly_detector: None,
811 reasoning_model_warning: true,
812 logging_config: crate::config::LoggingConfig::default(),
813 dump_dir: None,
814 trace_service_name: String::new(),
815 trace_redact: true,
816 current_iteration_span_id: None,
817 }
818 }
819}
820
821impl Default for FeedbackState {
822 fn default() -> Self {
823 Self {
824 detector: super::feedback_detector::FeedbackDetector::new(0.6),
825 judge: None,
826 llm_classifier: None,
827 }
828 }
829}
830
831impl Default for RuntimeConfig {
832 fn default() -> Self {
833 Self {
834 security: SecurityConfig::default(),
835 timeouts: TimeoutConfig::default(),
836 model_name: String::new(),
837 active_provider_name: String::new(),
838 permission_policy: zeph_tools::PermissionPolicy::default(),
839 redact_credentials: true,
840 rate_limiter: super::rate_limiter::ToolRateLimiter::new(
841 super::rate_limiter::RateLimitConfig::default(),
842 ),
843 semantic_cache_enabled: false,
844 semantic_cache_threshold: 0.95,
845 semantic_cache_max_candidates: 10,
846 dependency_config: zeph_tools::DependencyConfig::default(),
847 adversarial_policy_info: None,
848 spawn_depth: 0,
849 budget_hint_enabled: true,
850 channel_skills: zeph_config::ChannelSkillsConfig::default(),
851 layers: Vec::new(),
852 }
853 }
854}
855
856impl SessionState {
857 pub(crate) fn new() -> Self {
858 Self {
859 env_context: EnvironmentContext::gather(""),
860 last_assistant_at: None,
861 response_cache: None,
862 parent_tool_use_id: None,
863 status_tx: None,
864 lsp_hooks: None,
865 policy_config: None,
866 hooks_config: HooksConfigSnapshot::default(),
867 }
868 }
869}
870
871impl SkillState {
872 pub(crate) fn new(
873 registry: Arc<RwLock<SkillRegistry>>,
874 matcher: Option<SkillMatcherBackend>,
875 max_active_skills: usize,
876 last_skills_prompt: String,
877 ) -> Self {
878 Self {
879 registry,
880 skill_paths: Vec::new(),
881 managed_dir: None,
882 trust_config: crate::config::TrustConfig::default(),
883 matcher,
884 max_active_skills,
885 disambiguation_threshold: 0.20,
886 min_injection_score: 0.20,
887 embedding_model: String::new(),
888 skill_reload_rx: None,
889 active_skill_names: Vec::new(),
890 last_skills_prompt,
891 prompt_mode: crate::config::SkillPromptMode::Auto,
892 available_custom_secrets: HashMap::new(),
893 cosine_weight: 0.7,
894 hybrid_search: false,
895 bm25_index: None,
896 two_stage_matching: false,
897 confusability_threshold: 0.0,
898 rl_head: None,
899 rl_weight: 0.3,
900 rl_warmup_updates: 50,
901 generation_output_dir: None,
902 generation_provider_name: String::new(),
903 }
904 }
905}
906
907impl LifecycleState {
908 pub(crate) fn new() -> Self {
909 let (_tx, rx) = watch::channel(false);
910 Self {
911 shutdown: rx,
912 start_time: Instant::now(),
913 cancel_signal: Arc::new(tokio::sync::Notify::new()),
914 cancel_token: tokio_util::sync::CancellationToken::new(),
915 cancel_bridge_handle: None,
916 config_path: None,
917 config_reload_rx: None,
918 warmup_ready: None,
919 update_notify_rx: None,
920 custom_task_rx: None,
921 last_known_cwd: std::env::current_dir().unwrap_or_default(),
922 file_changed_rx: None,
923 file_watcher: None,
924 }
925 }
926}
927
928impl ProviderState {
929 pub(crate) fn new(initial_prompt_tokens: u64) -> Self {
930 Self {
931 summary_provider: None,
932 provider_override: None,
933 judge_provider: None,
934 probe_provider: None,
935 compress_provider: None,
936 cached_prompt_tokens: initial_prompt_tokens,
937 server_compaction_active: false,
938 stt: None,
939 provider_pool: Vec::new(),
940 provider_config_snapshot: None,
941 }
942 }
943}
944
945impl MetricsState {
946 pub(crate) fn new(token_counter: Arc<zeph_memory::TokenCounter>) -> Self {
947 Self {
948 metrics_tx: None,
949 cost_tracker: None,
950 token_counter,
951 extended_context: false,
952 classifier_metrics: None,
953 }
954 }
955}
956
957impl ExperimentState {
958 pub(crate) fn new() -> Self {
959 let (notify_tx, notify_rx) = tokio::sync::mpsc::channel::<String>(4);
960 Self {
961 config: crate::config::ExperimentConfig::default(),
962 cancel: None,
963 baseline: zeph_experiments::ConfigSnapshot::default(),
964 eval_provider: None,
965 notify_rx: Some(notify_rx),
966 notify_tx,
967 }
968 }
969}
970
971pub(super) mod security;
972pub(super) mod skill;
973
974#[cfg(test)]
975mod tests;