diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs index bc6f926d9f..6c8fdc7c89 100644 --- a/codex-rs/core/src/codex.rs +++ b/codex-rs/core/src/codex.rs @@ -4533,7 +4533,7 @@ pub(crate) async fn run_turn( &sess, &turn_context, AutoCompactCallsite::MidTurnContinuation, - TurnContextReinjection::ReinjectAboveLastRealUser, + TurnContextReinjection::Skip, None, ) .await @@ -4687,8 +4687,7 @@ async fn maybe_run_previous_model_inline_compact( // We use previous turn context here because we compact with the previous model &previous_turn_context, AutoCompactCallsite::PreTurnExcludingIncomingUserMessage, - // User message and turn context diff is injected in the pre-compaction NotNeeded case later - TurnContextReinjection::ReinjectAboveLastRealUser, + TurnContextReinjection::Skip, None, ) .await @@ -4738,11 +4737,28 @@ async fn persist_pre_turn_items_for_compaction_outcome( response_item: ResponseItem, ) { match outcome { - PreTurnCompactionOutcome::CompactedWithIncomingItems - | PreTurnCompactionOutcome::NotNeeded => { - // Pre-turn compaction includes incoming items only for the compaction model's request. - // We always persist canonical pre-turn updates and the current user item after the - // compaction summary so model-visible layout is stable regardless of compaction mode. + PreTurnCompactionOutcome::CompactedWithIncomingItems => { + // Pre-turn compaction includes incoming items only for the compaction request itself. + // Persist canonical turn context directly above the incoming user item so context + // applies to the latest user message in post-compaction history. + let initial_context = sess.build_initial_context(turn_context.as_ref()).await; + if !initial_context.is_empty() { + sess.record_conversation_items(turn_context, &initial_context) + .await; + } + let model_switch_updates: Vec = pre_turn_context_items + .iter() + .filter(|item| Session::is_model_switch_developer_message(item)) + .cloned() + .collect(); + if !model_switch_updates.is_empty() { + sess.record_conversation_items(turn_context, &model_switch_updates) + .await; + } + sess.record_user_prompt_and_emit_turn_item(turn_context.as_ref(), input, response_item) + .await; + } + PreTurnCompactionOutcome::NotNeeded => { if !pre_turn_context_items.is_empty() { sess.record_conversation_items(turn_context, pre_turn_context_items) .await; @@ -4795,7 +4811,7 @@ async fn run_pre_turn_auto_compaction_if_needed( sess, turn_context, AutoCompactCallsite::PreTurnIncludingIncomingUserMessage, - TurnContextReinjection::ReinjectAboveLastRealUser, + TurnContextReinjection::Skip, Some(incoming_turn_items.to_vec()), ) .await; diff --git a/codex-rs/core/src/compact.rs b/codex-rs/core/src/compact.rs index c649c01566..fdc76109c3 100644 --- a/codex-rs/core/src/compact.rs +++ b/codex-rs/core/src/compact.rs @@ -55,6 +55,7 @@ pub(crate) enum AutoCompactCallsite { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum TurnContextReinjection { /// Insert canonical context immediately above the last real user message in compacted history. + #[allow(dead_code)] ReinjectAboveLastRealUser, /// Do not reinsert canonical context while processing compacted history. Skip, diff --git a/codex-rs/core/tests/suite/snapshots/all__suite__compact__mid_turn_compaction_shapes.snap b/codex-rs/core/tests/suite/snapshots/all__suite__compact__mid_turn_compaction_shapes.snap index c13f78aff9..000d483778 100644 --- a/codex-rs/core/tests/suite/snapshots/all__suite__compact__mid_turn_compaction_shapes.snap +++ b/codex-rs/core/tests/suite/snapshots/all__suite__compact__mid_turn_compaction_shapes.snap @@ -1,6 +1,5 @@ --- source: core/tests/suite/compact.rs -assertion_line: 2646 expression: "format_labeled_requests_snapshot(\"True mid-turn continuation compaction after tool output: compact request includes tool artifacts, and the continuation request includes the summary in the same turn.\",\n&[(\"Local Compaction Request\", &auto_compact_mock.single_request()),\n(\"Local Post-Compaction History Layout\",\n&post_auto_compact_mock.single_request()),])" --- Scenario: True mid-turn continuation compaction after tool output: compact request includes tool artifacts, and the continuation request includes the summary in the same turn. @@ -15,8 +14,5 @@ Scenario: True mid-turn continuation compaction after tool output: compact reque 06:message/user: ## Local Post-Compaction History Layout -00:message/developer: -01:message/user: -02:message/user:> -03:message/user:function call limit push -04:message/user:\nAUTO_SUMMARY +00:message/user:function call limit push +01:message/user:\nAUTO_SUMMARY diff --git a/codex-rs/core/tests/suite/snapshots/all__suite__compact__pre_turn_compaction_including_incoming_shapes.snap b/codex-rs/core/tests/suite/snapshots/all__suite__compact__pre_turn_compaction_including_incoming_shapes.snap index c30d304879..ccafe8237a 100644 --- a/codex-rs/core/tests/suite/snapshots/all__suite__compact__pre_turn_compaction_including_incoming_shapes.snap +++ b/codex-rs/core/tests/suite/snapshots/all__suite__compact__pre_turn_compaction_including_incoming_shapes.snap @@ -1,6 +1,5 @@ --- source: core/tests/suite/compact.rs -assertion_line: 3138 expression: "format_labeled_requests_snapshot(\"Pre-turn auto-compaction with a context override includes incoming user content in the compact request and preserves it after compaction.\",\n&[(\"Local Compaction Request\", &requests[2]),\n(\"Local Post-Compaction History Layout\", &requests[3]),])" --- Scenario: Pre-turn auto-compaction with a context override includes incoming user content in the compact request and preserves it after compaction. @@ -19,10 +18,9 @@ Scenario: Pre-turn auto-compaction with a context override includes incoming use ## Local Post-Compaction History Layout 00:message/user:USER_ONE -01:message/developer: -02:message/user: -03:message/user: -04:message/user:USER_TWO -05:message/user:\nPRE_TURN_SUMMARY -06:message/user: -07:message/user: | | | USER_THREE +01:message/user:USER_TWO +02:message/user:\nPRE_TURN_SUMMARY +03:message/developer: +04:message/user: +05:message/user: +06:message/user: | | | USER_THREE diff --git a/codex-rs/core/tests/suite/snapshots/all__suite__compact__pre_turn_compaction_strips_incoming_model_switch_shapes.snap b/codex-rs/core/tests/suite/snapshots/all__suite__compact__pre_turn_compaction_strips_incoming_model_switch_shapes.snap index fcbad1059b..03b58b11f0 100644 --- a/codex-rs/core/tests/suite/snapshots/all__suite__compact__pre_turn_compaction_strips_incoming_model_switch_shapes.snap +++ b/codex-rs/core/tests/suite/snapshots/all__suite__compact__pre_turn_compaction_strips_incoming_model_switch_shapes.snap @@ -1,6 +1,5 @@ --- source: core/tests/suite/compact.rs -assertion_line: 3288 expression: "format_labeled_requests_snapshot(\"Pre-turn compaction during model switch (without pre-sampling model-switch compaction): current behavior strips incoming from the compact request and restores it in the post-compaction follow-up request.\",\n&[(\"Initial Request (Previous Model)\", &requests[0]),\n(\"Local Compaction Request\", &requests[1]),\n(\"Local Post-Compaction History Layout\", &requests[2]),])" --- Scenario: Pre-turn compaction during model switch (without pre-sampling model-switch compaction): current behavior strips incoming from the compact request and restores it in the post-compaction follow-up request. @@ -23,11 +22,11 @@ Scenario: Pre-turn compaction during model switch (without pre-sampling model-sw 07:message/user: ## Local Post-Compaction History Layout -00:message/developer: -01:message/developer: The user has requested a new communication st... -02:message/user: -03:message/user:> -04:message/user:BEFORE_SWITCH_USER -05:message/user:\nPRETURN_SWITCH_SUMMARY +00:message/user:BEFORE_SWITCH_USER +01:message/user:\nPRETURN_SWITCH_SUMMARY +02:message/developer: +03:message/developer: The user has requested a new communication st... +04:message/user: +05:message/user:> 06:message/developer:\nThe user was previously using a different model.... 07:message/user:AFTER_SWITCH_USER diff --git a/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_mid_turn_compaction_multi_summary_reinjects_above_last_summary_shapes.snap b/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_mid_turn_compaction_multi_summary_reinjects_above_last_summary_shapes.snap index 9ea6233a0a..f8b97f47d9 100644 --- a/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_mid_turn_compaction_multi_summary_reinjects_above_last_summary_shapes.snap +++ b/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_mid_turn_compaction_multi_summary_reinjects_above_last_summary_shapes.snap @@ -1,17 +1,17 @@ --- source: core/tests/suite/compact_remote.rs -expression: "format_labeled_requests_snapshot(\"Remote mid-turn compaction after an earlier summary compaction: the older summary remains in model-visible history and round-trips into the next compact request.\",\n&[(\"Second Turn Request (Before Mid-Turn Compaction)\", &requests[1]),\n(\"Remote Compaction Request\", &compact_request),])" +expression: "format_labeled_requests_snapshot(\"Remote mid-turn compaction after an earlier summary compaction: the older summary remains in model-visible history and round-trips into the next compact request.\",\n&[(\"Second Turn Request (Before Mid-Turn Compaction)\", &second_turn_request),\n(\"Remote Compaction Request\", &compact_request),])" --- Scenario: Remote mid-turn compaction after an earlier summary compaction: the older summary remains in model-visible history and round-trips into the next compact request. ## Second Turn Request (Before Mid-Turn Compaction) 00:message/user:USER_ONE 01:message/user:\nREMOTE_OLDER_SUMMARY -02:message/developer: -03:message/user: -04:message/user:> -05:message/user:USER_TWO -06:message/user:\nREMOTE_LATEST_SUMMARY +02:message/user:\nREMOTE_LATEST_SUMMARY +03:message/developer: +04:message/user: +05:message/user:> +06:message/user:USER_TWO ## Remote Compaction Request 00:message/user:USER_ONE diff --git a/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_mid_turn_compaction_shapes.snap b/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_mid_turn_compaction_shapes.snap index 488bee0bef..879c7fa7c6 100644 --- a/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_mid_turn_compaction_shapes.snap +++ b/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_mid_turn_compaction_shapes.snap @@ -13,8 +13,5 @@ Scenario: Remote mid-turn continuation compaction after tool output: compact req 05:function_call_output:unsupported call: test_tool ## Remote Post-Compaction History Layout -00:message/developer: -01:message/user: -02:message/user:> -03:message/user:USER_ONE -04:message/user:\nREMOTE_MID_TURN_SUMMARY +00:message/user:USER_ONE +01:message/user:\nREMOTE_MID_TURN_SUMMARY diff --git a/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_mid_turn_compaction_summary_only_reinjects_context_shapes.snap b/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_mid_turn_compaction_summary_only_reinjects_context_shapes.snap index 4ede5c3cad..e99aa788e4 100644 --- a/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_mid_turn_compaction_summary_only_reinjects_context_shapes.snap +++ b/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_mid_turn_compaction_summary_only_reinjects_context_shapes.snap @@ -1,6 +1,6 @@ --- source: core/tests/suite/compact_remote.rs -expression: "format_labeled_requests_snapshot(\"Remote mid-turn compaction where compact output has only summary user content: continuation layout reinjects canonical context before that summary.\",\n&[(\"Remote Compaction Request\", &compact_request),\n(\"Remote Post-Compaction History Layout\", &requests[1]),])" +expression: "format_labeled_requests_snapshot(\"Remote mid-turn compaction where compact output has only summary user content: continuation layout reinjects canonical context before that summary.\",\n&[(\"Remote Compaction Request\", &compact_request),\n(\"Remote Post-Compaction History Layout\", &post_compact_turn_request),])" --- Scenario: Remote mid-turn compaction where compact output has only summary user content: continuation layout reinjects canonical context before that summary. @@ -13,7 +13,4 @@ Scenario: Remote mid-turn compaction where compact output has only summary user 05:function_call_output:unsupported call: test_tool ## Remote Post-Compaction History Layout -00:message/developer: -01:message/user: -02:message/user:> -03:message/user:\nREMOTE_SUMMARY_ONLY +00:message/user:\nREMOTE_SUMMARY_ONLY diff --git a/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_pre_turn_compaction_including_incoming_shapes.snap b/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_pre_turn_compaction_including_incoming_shapes.snap index 7b28f8151a..7476a2db8f 100644 --- a/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_pre_turn_compaction_including_incoming_shapes.snap +++ b/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_pre_turn_compaction_including_incoming_shapes.snap @@ -1,6 +1,5 @@ --- source: core/tests/suite/compact_remote.rs -assertion_line: 1390 expression: "format_labeled_requests_snapshot(\"Remote pre-turn auto-compaction with a context override includes incoming user content in the compact request and preserves it after compaction.\",\n&[(\"Remote Compaction Request\", &compact_request),\n(\"Remote Post-Compaction History Layout\", &requests[2]),])" --- Scenario: Remote pre-turn auto-compaction with a context override includes incoming user content in the compact request and preserves it after compaction. @@ -19,9 +18,8 @@ Scenario: Remote pre-turn auto-compaction with a context override includes incom ## Remote Post-Compaction History Layout 00:message/user:USER_ONE 01:message/user:USER_TWO -02:message/developer: -03:message/user: -04:message/user: -05:message/user:\nREMOTE_PRE_TURN_SUMMARY -06:message/user: -07:message/user:USER_THREE +02:message/user:\nREMOTE_PRE_TURN_SUMMARY +03:message/developer: +04:message/user: +05:message/user: +06:message/user:USER_THREE diff --git a/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_pre_turn_compaction_strips_incoming_model_switch_shapes.snap b/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_pre_turn_compaction_strips_incoming_model_switch_shapes.snap index 2b03802b7f..85d8073913 100644 --- a/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_pre_turn_compaction_strips_incoming_model_switch_shapes.snap +++ b/codex-rs/core/tests/suite/snapshots/all__suite__compact_remote__remote_pre_turn_compaction_strips_incoming_model_switch_shapes.snap @@ -1,6 +1,5 @@ --- source: core/tests/suite/compact_remote.rs -assertion_line: 1538 expression: "format_labeled_requests_snapshot(\"Remote pre-turn compaction during model switch strips incoming from the compact request and restores it in the post-compaction follow-up request.\",\n&[(\"Initial Request (Previous Model)\", &initial_turn_request),\n(\"Remote Compaction Request\", &compact_request),\n(\"Remote Post-Compaction History Layout\", &post_compact_turn_request),])" --- Scenario: Remote pre-turn compaction during model switch strips incoming from the compact request and restores it in the post-compaction follow-up request. @@ -21,10 +20,10 @@ Scenario: Remote pre-turn compaction during model switch strips incoming -02:message/developer: The user has requested a new communication st... -03:message/user: -04:message/user:> -05:message/user:\nREMOTE_SWITCH_SUMMARY +01:message/user:\nREMOTE_SWITCH_SUMMARY +02:message/developer: +03:message/developer: The user has requested a new communication st... +04:message/user: +05:message/user:> 06:message/developer:\nThe user was previously using a different model.... 07:message/user:AFTER_SWITCH_USER