codetether_agent/session/context/
derive.rs1use std::sync::Arc;
4
5use anyhow::Result;
6use tokio::sync::mpsc;
7
8use crate::provider::ToolDefinition;
9use crate::session::ResidencyLevel;
10use crate::session::Session;
11use crate::session::SessionEvent;
12use crate::session::helper::compression::{CompressContext, compress_last_message_if_oversized};
13use crate::session::helper::experimental;
14
15use super::compress_step::run_compression_step;
16use super::helpers::{DerivedContext, messages_len_changed};
17
18pub async fn derive_context(
41 session: &Session,
42 provider: Arc<dyn crate::provider::Provider>,
43 model: &str,
44 system_prompt: &str,
45 tools: &[ToolDefinition],
46 event_tx: Option<&mpsc::Sender<SessionEvent>>,
47 force_keep_last: Option<usize>,
48) -> Result<DerivedContext> {
49 let origin_len = session.messages.len();
50 let mut messages = session.messages.clone();
51 let ctx = CompressContext::from_session(session);
52
53 let step0 =
54 compress_last_message_if_oversized(&mut messages, &ctx, Arc::clone(&provider), model)
55 .await?;
56
57 experimental::apply_all(&mut messages);
58
59 let before = messages.len();
60 let step1 = run_compression_step(
61 &mut messages,
62 &ctx,
63 provider,
64 model,
65 system_prompt,
66 tools,
67 event_tx,
68 force_keep_last,
69 )
70 .await?;
71
72 experimental::pairing::repair_orphans(&mut messages);
73
74 let compressed = step0 || step1 || messages_len_changed(before, &messages);
75 let mut provenance = vec!["legacy".to_string()];
76 if step0 {
77 provenance.push("oversized_last_message".to_string());
78 }
79 if step1 {
80 provenance.push("context_window".to_string());
81 }
82 if compressed && provenance.len() == 1 {
83 provenance.push("experimental".to_string());
84 }
85 Ok(DerivedContext {
86 resolutions: vec![ResidencyLevel::Full; messages.len()],
87 dropped_ranges: Vec::new(),
88 provenance,
89 messages,
90 origin_len,
91 compressed,
92 })
93}