use rig::agent::{AgentHook, CompletionCallAction, HookContext, RequestPatch};
use tokio::sync::mpsc::Sender;
use crate::{
llm::{
compactors::{
Compactor, ObservationMaskingCompactor, ReasoningCapCompactor, SharedObservations,
SlidingWindowCompactor,
},
estimators::Estimator,
},
session::SessionMessage,
};
pub struct CompactionHook<E: Estimator + Clone + Send + Sync> {
session_tx: Sender<SessionMessage>,
compactors: (
ObservationMaskingCompactor,
ReasoningCapCompactor<E>,
SlidingWindowCompactor<E>,
),
context_window: u64,
estimator: E,
}
impl<E: Estimator + Clone + Send + Sync> AgentHook for CompactionHook<E> {
async fn on_completion_call(
&self,
_ctx: &HookContext,
event: rig::agent::CompletionCallEvent<'_>,
) -> CompletionCallAction {
let prompt = event.prompt;
let mut effective_history = event.history.to_owned();
let inital_pressure = self.estimator.context_pressure(prompt, &effective_history);
effective_history = self.compactors.0.compact(prompt, &effective_history);
effective_history = self.compactors.1.compact(prompt, &effective_history);
effective_history = self.compactors.2.compact(prompt, &effective_history);
let updated_pressure = self.estimator.context_pressure(prompt, &effective_history);
self.session_tx
.send(SessionMessage::ContextPressure {
initial: inital_pressure,
updated: updated_pressure,
window: self.context_window,
})
.await
.unwrap();
CompletionCallAction::patch(RequestPatch::new().history(effective_history))
}
}
impl<E: Estimator + Clone + Send + Sync> CompactionHook<E> {
pub fn new(
session_tx: Sender<SessionMessage>,
context_window: u64,
estimator: E,
max_tokens: u64,
max_tool_observations: u64,
min_reasoning_observations: u64,
observations: SharedObservations,
) -> Self {
let context_limit = (context_window - max_tokens) * 9 / 10; Self {
session_tx,
compactors: (
ObservationMaskingCompactor::new(max_tool_observations, observations),
ReasoningCapCompactor::new(
estimator.clone(),
context_limit,
min_reasoning_observations,
),
SlidingWindowCompactor::new(estimator.clone(), context_limit),
),
context_window,
estimator,
}
}
}