Skip to main content

ContextService

Struct ContextService 

Source
pub struct ContextService;
Expand description

Stateless façade for agent context-assembly operations.

This struct has no fields. All state flows through method parameters, which allows the borrow checker to see disjoint &mut borrows at the call site without hiding them inside an opaque bundle.

Methods are &self — the type exists only to namespace the operations and give callers a single import.

§Examples

use zeph_agent_context::service::ContextService;

let svc = ContextService::new();
// call svc.prepare_context(...) or svc.clear_history(...)

Implementations§

Source§

impl ContextService

Source

pub fn new() -> Self

Create a new stateless ContextService.

This is a zero-cost constructor — the struct has no fields.

Source

pub fn clear_history(&self, window: &mut MessageWindowView<'_>)

Clear the message history, preserving the system prompt.

Keeps the first message (system prompt), clears the rest, and clears completed_tool_ids — session-scoped dependency state resets with the history. Recomputes cached_prompt_tokens inline after clearing.

Source

pub fn remove_recall_messages(&self, window: &mut MessageWindowView<'_>)

Remove semantic recall messages from the window.

Source

pub fn remove_correction_messages(&self, window: &mut MessageWindowView<'_>)

Remove past-correction messages from the window.

Source

pub fn remove_graph_facts_messages(&self, window: &mut MessageWindowView<'_>)

Remove knowledge-graph fact messages from the window.

Source

pub fn remove_persona_facts_messages(&self, window: &mut MessageWindowView<'_>)

Remove persona-facts messages from the window.

Source

pub fn remove_trajectory_hints_messages( &self, window: &mut MessageWindowView<'_>, )

Remove trajectory-hint messages from the window.

Source

pub fn remove_tree_memory_messages(&self, window: &mut MessageWindowView<'_>)

Remove tree-memory summary messages from the window.

Source

pub fn remove_reasoning_strategies_messages( &self, window: &mut MessageWindowView<'_>, )

Remove reasoning-strategy messages from the window.

Source

pub fn remove_lsp_messages(&self, window: &mut MessageWindowView<'_>)

Remove previously injected LSP context notes from the window.

Called before injecting fresh notes each turn so stale diagnostics/hover data from the previous tool call do not accumulate across iterations.

Source

pub fn remove_code_context_messages(&self, window: &mut MessageWindowView<'_>)

Remove code-context (repo-map / file context) messages from the window.

Source

pub fn remove_summary_messages(&self, window: &mut MessageWindowView<'_>)

Remove session-summary messages from the window.

Source

pub fn remove_cross_session_messages(&self, window: &mut MessageWindowView<'_>)

Remove cross-session context messages from the window.

Source

pub fn remove_session_digest_message(&self, window: &mut MessageWindowView<'_>)

Remove the session-digest user message from the window.

Source

pub fn remove_document_rag_messages(&self, window: &mut MessageWindowView<'_>)

Remove document-RAG messages from the window.

Source

pub fn trim_messages_to_budget( &self, window: &mut MessageWindowView<'_>, token_budget: usize, )

Trim the non-system message tail to fit within token_budget tokens.

Keeps the system prefix intact and the most recent messages, removing older messages from the start of the conversation history until the token count fits the budget. Recomputes cached_prompt_tokens after trimming.

No-op when token_budget is zero.

Source

pub async fn inject_semantic_recall( &self, query: &str, token_budget: usize, window: &mut MessageWindowView<'_>, view: &ContextAssemblyView<'_>, ) -> Result<(), ContextError>

Inject semantic recall messages into the window for the given query.

Removes any existing recall messages first, fetches fresh recall up to token_budget tokens, and inserts the result at position 1 (immediately after the system prompt).

§Errors

Returns ContextError::Memory if the recall backend returns an error.

Source

pub async fn inject_cross_session_context( &self, query: &str, token_budget: usize, window: &mut MessageWindowView<'_>, view: &ContextAssemblyView<'_>, ) -> Result<(), ContextError>

Inject cross-session context messages into the window for the given query.

Removes any existing cross-session messages first, fetches fresh cross-session context for the current conversation, and inserts the result at position 1.

§Errors

Returns ContextError::Memory if the memory backend returns an error.

Source

pub async fn inject_summaries( &self, token_budget: usize, window: &mut MessageWindowView<'_>, view: &ContextAssemblyView<'_>, ) -> Result<(), ContextError>

Inject conversation-summary messages into the window.

Removes any existing summary messages first, fetches stored summaries for the current conversation, and inserts the result at position 1.

§Errors

Returns ContextError::Memory if the memory backend returns an error.

Source

pub async fn disambiguate_skills( &self, query: &str, all_meta: &[&SkillMeta], scored: &[ScoredMatch], providers: &ProviderHandles, ) -> Option<Vec<usize>>

Select the best-matching skill among ambiguous candidates via an LLM classification call.

Returns the reordered index list with the most likely skill first, or None if the LLM call fails (caller falls back to original score order).

Source

pub async fn prepare_context( &self, query: &str, window: &mut MessageWindowView<'_>, view: &mut ContextAssemblyView<'_>, _providers: &ProviderHandles, ) -> Result<ContextDelta, ContextError>

Prepare the context window for the current turn.

Removes stale injection messages, runs proactive skill exploration, gathers semantic recall and graph facts via the concurrent assembler, applies the retrieval policy, and injects fresh context. Returns a ContextDelta whose code_context field must be applied by the caller (via inject_code_context).

§Errors

Returns ContextError::Memory if recall fails or ContextError::Assembler if the context assembler encounters an internal error.

Source

pub async fn reset_conversation( &self, window: &mut MessageWindowView<'_>, _view: &mut ContextAssemblyView<'_>, ) -> Result<(), ContextError>

Reset the conversation history.

Clears all messages except the system prompt and resets the cached token count. The caller (Agent<C>) is responsible for resetting compaction state, orchestration, focus, and sidequest state — those fields are outside the context-service scope.

§Errors

Returns ContextError::Memory if creating a new conversation in SQLite fails.

Source

pub async fn maybe_compact( &self, summ: &mut ContextSummarizationView<'_>, _providers: &ProviderHandles, status: &(impl StatusSink + ?Sized), ) -> Result<(), ContextError>

Run tiered compaction if the token budget is exhausted.

Dispatches to the appropriate compaction tier based on the current context manager state:

  • None — context is within budget; no-op.
  • Soft — apply deferred summaries + prune tool outputs (no LLM).
  • Hard — Soft steps first, then LLM full summarization if pruning is insufficient.

Increments the turns_since_last_hard_compaction counter unconditionally so pressure is tracked regardless of whether compaction fires. Respects the cooldown guard: when cooling, Hard-tier LLM summarization is skipped.

§Errors

Returns ContextError::Memory if SQLite persistence fails during Hard compaction.

Source

pub async fn maybe_summarize_tool_pair( &self, summ: &mut ContextSummarizationView<'_>, providers: &ProviderHandles, )

Summarize the most recent tool-use/result pair if it exceeds the cutoff.

Drains the backlog of unsummarized tool-use/result pairs in a single pass, storing results as deferred_summary on message metadata. Applied lazily by Self::maybe_apply_deferred_summaries when context pressure rises.

Source

pub fn apply_deferred_summaries( &self, summ: &mut ContextSummarizationView<'_>, ) -> usize

Apply any deferred tool-pair summaries to the message window.

Processes all pending deferred summaries in reverse order so insertions do not invalidate lower indices. Returns the number of summaries applied.

Source

pub async fn flush_deferred_summaries( &self, summ: &mut ContextSummarizationView<'_>, )

Flush all deferred summary IDs to the database.

Calls apply_tool_pair_summaries to soft-delete the original tool pairs and persist the summaries. Always clears both deferred queues regardless of outcome.

Source

pub fn maybe_apply_deferred_summaries( &self, summ: &mut ContextSummarizationView<'_>, )

Apply deferred summaries if context usage exceeds the soft compaction threshold.

Two triggers: token pressure (above the soft threshold) and count pressure (pending summaries >= tool_call_cutoff). This is Tier 0 — no LLM call. Does NOT set compacted_this_turn so proactive/reactive compaction may still fire.

Source

pub async fn compact_context( &self, summ: &mut ContextSummarizationView<'_>, max_summary_tokens: Option<usize>, ) -> Result<CompactionOutcome, ContextError>

Run unconditional LLM-based context compaction with an optional token budget.

Bypasses tier and cooldown checks — always drains the oldest messages and inserts a compact summary. Use this in tests or when the caller has already determined that compaction is warranted. Production code should prefer Self::maybe_compact.

Invokes the optional callbacks wired into summ in this order: archive → LLM summarization → probe → finalize → persistence.

Returns crate::state::CompactionOutcome::NoChange when there is nothing to compact.

§Errors

Returns ContextError if summarization fails (LLM error or timeout).

Source

pub fn maybe_soft_compact_mid_iteration( &self, summ: &mut ContextSummarizationView<'_>, )

Apply a soft compaction pass mid-iteration if required.

Applies deferred summaries and prunes tool outputs down to the soft threshold. Never triggers a Hard tier LLM call. Returns immediately if compacted_this_turn is set or context is below the soft threshold.

Source

pub async fn maybe_proactive_compress( &self, summ: &mut ContextSummarizationView<'_>, _providers: &ProviderHandles, status: &(impl StatusSink + ?Sized), )

Run proactive compression if token usage crosses the configured threshold.

Uses the compact_context_with_budget path (LLM summarization with an optional token cap). Skips when server compaction is active unless context exceeds 95% of the budget. Does not impose a post-compaction cooldown.

Source

pub fn maybe_refresh_task_goal(&self, summ: &mut ContextSummarizationView<'_>)

Refresh the task goal when the last user message has changed.

Two-phase non-blocking: applies any completed background result from the previous turn, then schedules a new extraction if the user message hash has changed. Only active for TaskAware and Mig pruning strategies.

Source

pub fn maybe_refresh_subgoal(&self, summ: &mut ContextSummarizationView<'_>)

Refresh the subgoal registry when the last user message has changed.

Mirrors the two-phase maybe_refresh_task_goal pattern. Only active for Subgoal and SubgoalMig pruning strategies.

Trait Implementations§

Source§

impl Debug for ContextService

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ContextService

Source§

fn default() -> ContextService

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more