[codex] Use compaction_trigger item for remote compaction v2 (#22809)

## Why

Remote compaction v2 was still using `context_compaction` as both the
request trigger and the compacted output shape. The Responses API now
has the landed contract for this flow: Codex sends a dedicated `{
"type": "compaction_trigger" }` input item, and the backend returns the
standard `compaction` output item with encrypted content.

This aligns the v2 path with that wire contract while preserving the
existing local compacted-history post-processing behavior.

## What changed

- Add `ResponseItem::CompactionTrigger` and regenerate the app-server
protocol schema fixtures.
- Send `compaction_trigger` from `remote_compaction_v2` instead of a
payload-less `context_compaction`.
- Collect exactly one backend `compaction` output item, then reuse the
existing compacted-history rebuilding path.
- Treat the trigger item as a transient request marker rather than model
output or persisted rollout/memory content.

## Verification

- `cargo test -p codex-protocol compaction_trigger`
- `cargo test -p codex-core remote_compact_v2`
- `cargo test -p codex-core compact_remote_v2`
- `cargo test -p codex-core
responses_websocket_sends_response_processed_after_remote_compaction_v2`
- `just write-app-server-schema`
- `cargo test -p codex-app-server-protocol schema_fixtures`
This commit is contained in:
jif-oai
2026-05-15 11:40:35 +02:00
committed by GitHub
parent a5e5faf216
commit 0322ac3df8
18 changed files with 145 additions and 59 deletions
+17 -6
View File
@@ -887,7 +887,10 @@ pub enum ResponseItem {
result: String,
},
#[serde(alias = "compaction_summary")]
Compaction { encrypted_content: String },
Compaction {
encrypted_content: String,
},
CompactionTrigger,
ContextCompaction {
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
@@ -2407,20 +2410,28 @@ mod tests {
}
#[test]
fn serializes_context_compaction_trigger_without_payload() -> Result<()> {
let item = ResponseItem::ContextCompaction {
encrypted_content: None,
};
fn serializes_compaction_trigger_without_payload() -> Result<()> {
let item = ResponseItem::CompactionTrigger;
assert_eq!(
serde_json::to_value(item)?,
serde_json::json!({
"type": "context_compaction",
"type": "compaction_trigger",
})
);
Ok(())
}
#[test]
fn deserializes_compaction_trigger_without_payload() -> Result<()> {
let json = r#"{"type":"compaction_trigger"}"#;
let item: ResponseItem = serde_json::from_str(json)?;
assert_eq!(item, ResponseItem::CompactionTrigger);
Ok(())
}
#[test]
fn deserializes_legacy_ghost_snapshot_as_other() -> Result<()> {
let json = r#"{