From 0c5363772ba90eef0d65fdfd866aeaae6ae0a199 Mon Sep 17 00:00:00 2001 From: Charles Cunningham Date: Wed, 18 Feb 2026 02:11:25 -0800 Subject: [PATCH] nit --- codex-rs/core/src/codex.rs | 94 ++++++++++++++++++------------------ codex-rs/core/src/compact.rs | 8 --- 2 files changed, 48 insertions(+), 54 deletions(-) diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs index 5bdd1c60e2..af1d920629 100644 --- a/codex-rs/core/src/codex.rs +++ b/codex-rs/core/src/codex.rs @@ -4788,61 +4788,63 @@ async fn run_pre_turn_auto_compaction_if_needed( return Ok(PreTurnCompactionOutcome::NotNeeded); } - let compact_result = run_auto_compact( + match run_auto_compact( sess, turn_context, CompactCallsite::PreTurnIncludingIncomingUserMessage, Some(incoming_turn_items.to_vec()), ) - .await; + .await + { + Ok(()) => { + // If compaction no-oped because there was no user-turn boundary even after including + // incoming items, do not treat this as "compacted with incoming". The caller must + // persist incoming items explicitly in this case. + let has_user_turn_boundary_after_compaction = sess + .clone_history() + .await + .raw_items() + .iter() + .any(crate::context_manager::is_user_turn_boundary); + if !has_user_turn_boundary_after_compaction { + return Ok(PreTurnCompactionOutcome::NotNeeded); + } - if let Err(err) = compact_result { - if matches!(err, CodexErr::Interrupted) { - return Err(()); + Ok(PreTurnCompactionOutcome::CompactedWithIncomingItems) } - let event = match err { - CodexErr::ContextWindowExceeded => { - error!( - turn_id = %turn_context.sub_id, - compact_callsite = ?CompactCallsite::PreTurnIncludingIncomingUserMessage, - incoming_items_tokens_estimate, - auto_compact_limit, - reason = "pre-turn compaction exceeded context window", - "incoming user/context is too large for pre-turn auto-compaction flow" - ); - let message = format!( - "Incoming user message and/or turn context is too large to fit in context window. Please reduce the size of your message and try again. (incoming_items_tokens_estimate={incoming_items_tokens_estimate})" - ); - EventMsg::Error(CodexErr::ContextWindowExceeded.to_error_event(Some(message))) + Err(err) => { + if matches!(err, CodexErr::Interrupted) { + return Err(()); } - other => { - let compact_error_prefix = if should_use_remote_compact_task(&turn_context.provider) - { - "Error running remote compact task" - } else { - "Error running local compact task" - }; - EventMsg::Error(other.to_error_event(Some(compact_error_prefix.to_string()))) - } - }; - sess.send_event(turn_context, event).await; - return Err(()); + let event = match err { + CodexErr::ContextWindowExceeded => { + error!( + turn_id = %turn_context.sub_id, + compact_callsite = ?CompactCallsite::PreTurnIncludingIncomingUserMessage, + incoming_items_tokens_estimate, + auto_compact_limit, + reason = "pre-turn compaction exceeded context window", + "incoming user/context is too large for pre-turn auto-compaction flow" + ); + let message = format!( + "Incoming user message and/or turn context is too large to fit in context window. Please reduce the size of your message and try again. (incoming_items_tokens_estimate={incoming_items_tokens_estimate})" + ); + EventMsg::Error(CodexErr::ContextWindowExceeded.to_error_event(Some(message))) + } + other => { + let compact_error_prefix = + if should_use_remote_compact_task(&turn_context.provider) { + "Error running remote compact task" + } else { + "Error running local compact task" + }; + EventMsg::Error(other.to_error_event(Some(compact_error_prefix.to_string()))) + } + }; + sess.send_event(turn_context, event).await; + Err(()) + } } - - // If compaction no-oped because there was no user-turn boundary even after including incoming - // items, do not treat this as "compacted with incoming". The caller must persist incoming - // items explicitly in this case. - let has_user_turn_boundary_after_compaction = sess - .clone_history() - .await - .raw_items() - .iter() - .any(crate::context_manager::is_user_turn_boundary); - if !has_user_turn_boundary_after_compaction { - return Ok(PreTurnCompactionOutcome::NotNeeded); - } - - Ok(PreTurnCompactionOutcome::CompactedWithIncomingItems) } fn is_projected_submission_over_auto_compact_limit( diff --git a/codex-rs/core/src/compact.rs b/codex-rs/core/src/compact.rs index 0446e08f92..a4742aa7d1 100644 --- a/codex-rs/core/src/compact.rs +++ b/codex-rs/core/src/compact.rs @@ -53,14 +53,6 @@ pub(crate) enum CompactCallsite { MidTurnContinuation, } -// Canonical context reinjection policy for compacted replacement history: -// - `MidTurnContinuation` and `PreSamplingModelSwitch`: reinsert canonical initial context above -// the last real user message because those paths do not persist/reseed canonical context in a -// later post-compaction step. -// - `ManualCompact`: do not reinsert during compaction; `/compact` reseeds on the next user turn. -// - `PreTurn*`: do not reinsert into replacement history; `run_turn` persists canonical context -// directly above the incoming user message after compaction. - pub(crate) fn should_use_remote_compact_task(provider: &ModelProviderInfo) -> bool { provider.is_openai() }