mirror of
https://github.com/openai/codex.git
synced 2026-11-14 21:40:39 +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
66 lines
2.2 KiB
Rust
66 lines
2.2 KiB
Rust
use crate::session::tests::make_session_and_context_with_rx;
|
|
use codex_features::Feature;
|
|
use codex_history::CodexHarnessMetadata;
|
|
use codex_history::ResponseItemEnvelope;
|
|
use codex_history::RolloutItem;
|
|
use codex_protocol::models::ConfigurationReasoning;
|
|
use codex_protocol::models::ResponseItem;
|
|
use codex_protocol::openai_models::ReasoningEffort;
|
|
use codex_protocol::protocol::EventMsg;
|
|
use pretty_assertions::assert_eq;
|
|
|
|
#[tokio::test]
|
|
async fn harness_authored_configuration_updates_preserve_metadata_and_resume() {
|
|
let (session, turn_context, rx_event) = make_session_and_context_with_rx().await;
|
|
assert!(!session.enabled(Feature::RetainClientDeveloperMessages));
|
|
|
|
let mut expected = ResponseItemEnvelope {
|
|
item: ResponseItem::ConfigurationUpdate {
|
|
reasoning: ConfigurationReasoning {
|
|
effort: ReasoningEffort::High,
|
|
},
|
|
},
|
|
metadata: Some(CodexHarnessMetadata {
|
|
harness_authored_configuration: true,
|
|
..Default::default()
|
|
}),
|
|
};
|
|
session
|
|
.record_annotated_conversation_items(
|
|
&turn_context,
|
|
turn_context.model_info(),
|
|
vec![expected.clone()],
|
|
)
|
|
.await;
|
|
|
|
let metadata = expected.metadata.as_mut().unwrap();
|
|
metadata.history_sequence = Some(1);
|
|
metadata.sampled_through_sequence = Some(0);
|
|
metadata.mcp_attribution = Some(
|
|
session
|
|
.services
|
|
.executed_tool_calls
|
|
.mcp_attribution_snapshot(),
|
|
);
|
|
|
|
let recorded = session.clone_history().await.into_annotated_items();
|
|
assert_eq!(recorded, vec![expected.clone()]);
|
|
let mut raw_items = Vec::new();
|
|
while let Ok(event) = rx_event.try_recv() {
|
|
if let EventMsg::RawResponseItem(event) = event.msg {
|
|
raw_items.push(event.item);
|
|
}
|
|
}
|
|
assert_eq!(raw_items, vec![expected.item]);
|
|
|
|
let rollout_items = recorded
|
|
.iter()
|
|
.cloned()
|
|
.map(RolloutItem::ResponseItem)
|
|
.collect::<Vec<_>>();
|
|
let reconstructed = session
|
|
.reconstruct_history_from_rollout(&turn_context, &rollout_items)
|
|
.await;
|
|
assert_eq!(reconstructed.history, recorded);
|
|
}
|