zeph_context/input.rs
1// SPDX-FileCopyrightText: 2026 Andrei G <bug-ops>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Input types for context assembly.
5//!
6//! [`ContextAssemblyInput`] collects all references needed for one assembly turn.
7//! [`ContextMemoryView`] is a snapshot of memory-subsystem configuration that the
8//! assembler reads but never mutates — callers in `zeph-core` populate it from
9//! `MemoryState` before each assembly pass.
10
11use std::borrow::Cow;
12use std::sync::Arc;
13
14use zeph_config::{DocumentConfig, GraphConfig, PersonaConfig, TrajectoryConfig, TreeConfig};
15use zeph_memory::semantic::SemanticMemory;
16use zeph_memory::{ConversationId, TokenCounter};
17
18use crate::manager::ContextManager;
19
20/// All borrowed data needed to assemble context for one agent turn.
21///
22/// All fields are shared references — `ContextAssembler::gather` never mutates any state.
23/// The caller (in `zeph-core`) is responsible for populating this struct and passing it to
24/// [`crate::assembler::ContextAssembler::gather`].
25pub struct ContextAssemblyInput<'a> {
26 /// Snapshot of memory subsystem configuration for this turn.
27 pub memory: &'a ContextMemoryView,
28 /// Context lifecycle state machine.
29 pub context_manager: &'a ContextManager,
30 /// Token counter for budget enforcement.
31 pub token_counter: &'a TokenCounter,
32 /// Text of the skills prompt injected in the last turn (used for budget calculation).
33 pub skills_prompt: &'a str,
34 /// Index RAG accessor. `None` when code-index is disabled.
35 pub index: Option<&'a dyn IndexAccess>,
36 /// Learning engine corrections config. `None` when self-learning is disabled.
37 pub correction_config: Option<CorrectionConfig>,
38 /// Current value of the sidequest turn counter, for adaptive strategy selection.
39 pub sidequest_turn_counter: u64,
40 /// Message window snapshot used for strategy resolution and system-prompt extraction.
41 pub messages: &'a [zeph_llm::provider::Message],
42 /// The user query for the current turn, used as the search query for all memory lookups.
43 pub query: &'a str,
44 /// Content scrubber for PII removal. Passed as a function pointer to avoid a dependency
45 /// on `zeph-core`'s redact module.
46 pub scrub: fn(&str) -> Cow<'_, str>,
47}
48
49/// Configuration extracted from `LearningEngine` needed by correction recall.
50///
51/// Populated from `LearningEngine::config` in `zeph-core` and passed into
52/// [`ContextAssemblyInput`].
53#[derive(Debug, Clone, Copy)]
54pub struct CorrectionConfig {
55 /// Whether correction detection is active.
56 pub correction_detection: bool,
57 /// Maximum number of corrections to recall per turn.
58 pub correction_recall_limit: u32,
59 /// Minimum similarity score for a correction to be considered relevant.
60 pub correction_min_similarity: f32,
61}
62
63/// Read-only snapshot of memory subsystem state needed for context assembly.
64///
65/// This struct is populated by the caller (`zeph-core`) from `MemoryState` before each
66/// assembly pass. It contains only the fields that [`crate::assembler::ContextAssembler`]
67/// actually reads — no `Agent` methods, no mutation.
68pub struct ContextMemoryView {
69 // ── persistence fields ────────────────────────────────────────────────────
70 /// Semantic memory backend. `None` when memory is disabled.
71 pub memory: Option<Arc<SemanticMemory>>,
72 /// Active conversation ID. `None` before the first message is persisted.
73 pub conversation_id: Option<ConversationId>,
74 /// Maximum number of semantic recall hits injected per turn.
75 pub recall_limit: usize,
76 /// Minimum semantic similarity score for cross-session recall (0.0–1.0).
77 pub cross_session_score_threshold: f32,
78
79 // ── compaction fields ─────────────────────────────────────────────────────
80 /// Context assembly strategy (`FullHistory` / `MemoryFirst` / `Adaptive`).
81 pub context_strategy: zeph_config::ContextStrategy,
82 /// Turn threshold for `Adaptive` strategy crossover.
83 pub crossover_turn_threshold: u32,
84 /// Cached session digest text and token count, loaded at session start.
85 pub cached_session_digest: Option<(String, usize)>,
86
87 // ── extraction fields ─────────────────────────────────────────────────────
88 /// Knowledge graph configuration.
89 pub graph_config: GraphConfig,
90 /// Document RAG configuration.
91 pub document_config: DocumentConfig,
92 /// Persona memory configuration.
93 pub persona_config: PersonaConfig,
94 /// Trajectory-informed memory configuration.
95 pub trajectory_config: TrajectoryConfig,
96
97 // ── subsystem fields ──────────────────────────────────────────────────────
98 /// `TiMem` temporal-hierarchical memory tree configuration.
99 pub tree_config: TreeConfig,
100}
101
102/// Read-only access to a code-index retriever.
103///
104/// Implemented by `IndexState` in `zeph-core`. The assembler calls only `fetch_code_rag`
105/// to populate the `code_context` slot.
106///
107/// The return type uses `Pin<Box<dyn Future>>` rather than `async fn` to preserve
108/// dyn-compatibility: the trait is used as `&dyn IndexAccess` in `ContextAssemblyInput`.
109pub trait IndexAccess: Send + Sync {
110 /// Retrieve up to `budget_tokens` of code context for the given `query`.
111 ///
112 /// Returns `None` when no relevant context is found or when code-index is disabled.
113 ///
114 /// # Errors
115 ///
116 /// Propagates errors from the underlying code retriever.
117 fn fetch_code_rag<'a>(
118 &'a self,
119 query: &'a str,
120 budget_tokens: usize,
121 ) -> std::pin::Pin<
122 Box<
123 dyn std::future::Future<Output = Result<Option<String>, crate::error::ContextError>>
124 + Send
125 + 'a,
126 >,
127 >;
128}