Skip to main content

cookie_agent_engine/runtime/
get_history.rs

1use cookie_agent_protocol::SessionId;
2
3use super::{Engine, EngineError, Event, compaction::active_compaction_binding};
4use crate::model_history;
5
6/// Selects the history projection returned by [`Engine::get_history`].
7#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
8pub enum EngineHistoryView {
9    /// History turns assembled after the latest checkpoint, as for a normal model request.
10    ///
11    /// Native provider context and replay-decision metadata are not history turns and are omitted
12    /// from this projection.
13    #[default]
14    Assembled,
15    /// Replayable history turns from the start of the visible event log, without checkpoint
16    /// truncation.
17    Full,
18}
19
20impl Engine {
21    /// Returns a live history projection for the given session.
22    ///
23    /// Callable by anything holding an engine reference. The result reflects state at query time
24    /// and may include events appended after the current model request started, such as earlier
25    /// tool results from the same in-flight turn. Tool providers needing history should retain an
26    /// [`Engine`] handle, following the delegate-provider pattern; the engine is deliberately not
27    /// injected into every tool context.
28    pub async fn get_history(
29        &self,
30        session: SessionId,
31        view: EngineHistoryView,
32    ) -> Result<Vec<oven_sdk::HistoryTurn>, EngineError> {
33        let events = self.inner.store.get(session)?.log.event_snapshot();
34        let run = events
35            .iter()
36            .rev()
37            .find_map(|event| {
38                matches!(event.payload, Event::RunStarted { .. })
39                    .then_some(event.run_id)
40                    .flatten()
41            })
42            .ok_or(EngineError::NoRunnableModel)?;
43        let policy = self.historical_title_policy(&events, run)?;
44        let binding = active_compaction_binding(&policy, &events, run)?;
45        let composed_prompt = self.run_agent_prompt(session, run)?;
46        match view {
47            EngineHistoryView::Assembled => Ok(model_history::assemble_model_context(
48                &events,
49                &self.inner.artifacts,
50                binding,
51                &composed_prompt,
52            )?
53            .history),
54            EngineHistoryView::Full => Ok(model_history::assemble_full_history(
55                &events,
56                &self.inner.artifacts,
57                binding,
58                &composed_prompt,
59            )?),
60        }
61    }
62}