mirror of
https://github.com/openai/codex.git
synced 2026-11-10 21:00:47 +00:00
## Why Agent messages that arrive after a model request starts must survive compaction until a normal inference request includes them. Compactor output alone does not establish that those messages were delivered. ## What changed - Persist history sequences and sampling checkpoints in harness metadata, capturing the input prefix for each normal inference request. - Retain pending agent messages within existing size budgets during local and remote compaction, placing the summary before pending messages and subsequent caller input. - Preserve sampling progress across history replacement and resume, and drain queued mail after interrupted sampling even when compaction leaves context above the token limit. ## Testing Add regression coverage for request-boundary sampling checkpoints, pending messages across local compaction and repeated remote compaction with resume, and injected messages that interrupt sampling before mid-turn compaction. GitOrigin-RevId: 26c04ab96b5a1c3cc1d6625ccc74a0f00201d14c
50 lines
1.8 KiB
Rust
50 lines
1.8 KiB
Rust
//! Retains bounded unsampled mail and positions summaries before it and subsequent caller input.
|
|
//! Delivery is proven only by a regular inference checkpoint, never by compactor output.
|
|
|
|
use codex_history::ResponseItemEnvelope;
|
|
use codex_protocol::models::ResponseItem;
|
|
|
|
use crate::context_manager::estimate_item_token_count;
|
|
use crate::context_manager::sampled_through;
|
|
|
|
pub(crate) const MAX_RETAINED_AGENT_MESSAGE_TOKENS: i64 = 10_000;
|
|
|
|
pub(crate) fn pending_mail_sequence(history: &[ResponseItemEnvelope]) -> Option<u64> {
|
|
let sampled_through = sampled_through(history);
|
|
history
|
|
.iter()
|
|
.filter(|envelope| matches!(envelope.item, ResponseItem::AgentMessage { .. }))
|
|
.filter_map(|envelope| envelope.metadata.as_ref()?.history_sequence)
|
|
.find(|sequence| *sequence > sampled_through)
|
|
}
|
|
|
|
pub(crate) fn is_retained_pending_mail(envelope: &ResponseItemEnvelope, first: u64) -> bool {
|
|
matches!(envelope.item, ResponseItem::AgentMessage { .. })
|
|
&& envelope
|
|
.metadata
|
|
.as_ref()
|
|
.and_then(|metadata| metadata.history_sequence)
|
|
.is_some_and(|sequence| sequence >= first)
|
|
&& estimate_item_token_count(&envelope.item) <= MAX_RETAINED_AGENT_MESSAGE_TOKENS
|
|
}
|
|
|
|
pub(crate) fn insert_summary(
|
|
mut retained: Vec<ResponseItemEnvelope>,
|
|
summary: ResponseItemEnvelope,
|
|
pending_sequence: Option<u64>,
|
|
) -> Vec<ResponseItemEnvelope> {
|
|
let position = pending_sequence
|
|
.and_then(|first| {
|
|
retained.iter().position(|envelope| {
|
|
envelope
|
|
.metadata
|
|
.as_ref()
|
|
.and_then(|metadata| metadata.history_sequence)
|
|
.is_some_and(|sequence| sequence >= first)
|
|
})
|
|
})
|
|
.unwrap_or(retained.len());
|
|
retained.insert(position, summary);
|
|
retained
|
|
}
|