Rename compaction callsite enum and exhaustively match reinjection

This commit is contained in:
Charles Cunningham
2026-02-18 01:34:11 -08:00
parent 7ed3d3f9aa
commit c6d63129c1
3 changed files with 58 additions and 37 deletions
+6 -6
View File
@@ -19,7 +19,7 @@ use crate::analytics_client::build_track_events_context;
use crate::apps::render_apps_section;
use crate::commit_attribution::commit_message_trailer_instruction;
use crate::compact;
use crate::compact::AutoCompactCallsite;
use crate::compact::CompactCallsite;
use crate::compact::run_inline_auto_compact_task;
use crate::compact::should_use_remote_compact_task;
use crate::compact_remote::run_inline_remote_auto_compact_task;
@@ -4517,7 +4517,7 @@ pub(crate) async fn run_turn(
if let Err(err) = run_auto_compact(
&sess,
&turn_context,
AutoCompactCallsite::MidTurnContinuation,
CompactCallsite::MidTurnContinuation,
None,
)
.await
@@ -4670,7 +4670,7 @@ async fn maybe_run_previous_model_inline_compact(
sess,
// We use previous turn context here because we compact with the previous model
&previous_turn_context,
AutoCompactCallsite::PreSamplingModelSwitch,
CompactCallsite::PreSamplingModelSwitch,
None,
)
.await
@@ -4784,7 +4784,7 @@ async fn run_pre_turn_auto_compaction_if_needed(
let compact_result = run_auto_compact(
sess,
turn_context,
AutoCompactCallsite::PreTurnIncludingIncomingUserMessage,
CompactCallsite::PreTurnIncludingIncomingUserMessage,
Some(incoming_turn_items.to_vec()),
)
.await;
@@ -4803,7 +4803,7 @@ async fn run_pre_turn_auto_compaction_if_needed(
CodexErr::ContextWindowExceeded => {
error!(
turn_id = %turn_context.sub_id,
auto_compact_callsite = ?AutoCompactCallsite::PreTurnIncludingIncomingUserMessage,
auto_compact_callsite = ?CompactCallsite::PreTurnIncludingIncomingUserMessage,
incoming_items_tokens_estimate,
auto_compact_limit,
reason = "pre-turn compaction exceeded context window",
@@ -4859,7 +4859,7 @@ fn is_projected_submission_over_auto_compact_limit(
async fn run_auto_compact(
sess: &Arc<Session>,
turn_context: &Arc<TurnContext>,
auto_compact_callsite: AutoCompactCallsite,
auto_compact_callsite: CompactCallsite,
incoming_items: Option<Vec<ResponseItem>>,
) -> CodexResult<()> {
let result = if should_use_remote_compact_task(&turn_context.provider) {
+30 -13
View File
@@ -35,7 +35,9 @@ pub const SUMMARY_PREFIX: &str = include_str!("../templates/compact/summary_pref
const COMPACT_USER_MESSAGE_MAX_TOKENS: usize = 20_000;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum AutoCompactCallsite {
pub(crate) enum CompactCallsite {
/// Manual `/compact` task.
ManualCompact,
/// Pre-turn auto-compaction where the incoming turn context + user message are included in
/// the compaction request.
PreTurnIncludingIncomingUserMessage,
@@ -94,7 +96,7 @@ pub(crate) fn extract_latest_model_switch_update_from_items(
pub(crate) async fn run_inline_auto_compact_task(
sess: Arc<Session>,
turn_context: Arc<TurnContext>,
auto_compact_callsite: AutoCompactCallsite,
auto_compact_callsite: CompactCallsite,
incoming_items: Option<Vec<ResponseItem>>,
) -> CodexResult<()> {
let prompt = turn_context.compact_prompt().to_string();
@@ -108,7 +110,7 @@ pub(crate) async fn run_inline_auto_compact_task(
sess,
turn_context,
input,
Some(auto_compact_callsite),
auto_compact_callsite,
incoming_items,
)
.await?;
@@ -126,14 +128,21 @@ pub(crate) async fn run_compact_task(
collaboration_mode_kind: turn_context.collaboration_mode.mode,
});
sess.send_event(&turn_context, start_event).await;
run_compact_task_inner(sess, turn_context, input, None, None).await
run_compact_task_inner(
sess,
turn_context,
input,
CompactCallsite::ManualCompact,
None,
)
.await
}
async fn run_compact_task_inner(
sess: Arc<Session>,
turn_context: Arc<TurnContext>,
input: Vec<UserInput>,
auto_compact_callsite: Option<AutoCompactCallsite>,
auto_compact_callsite: CompactCallsite,
incoming_items: Option<Vec<ResponseItem>>,
) -> CodexResult<()> {
let compaction_item = TurnItem::ContextCompaction(ContextCompactionItem::new());
@@ -285,14 +294,22 @@ async fn run_compact_task_inner(
COMPACT_USER_MESSAGE_MAX_TOKENS,
);
let mut new_history = process_compacted_history(compacted_history);
if matches!(
auto_compact_callsite,
Some(
AutoCompactCallsite::MidTurnContinuation | AutoCompactCallsite::PreSamplingModelSwitch
)
) {
let initial_context = sess.build_initial_context(turn_context.as_ref()).await;
insert_initial_context_before_last_real_user(&mut new_history, initial_context);
match auto_compact_callsite {
CompactCallsite::MidTurnContinuation | CompactCallsite::PreSamplingModelSwitch => {
// Mid-turn and pre-sampling model-switch compaction continue the in-flight turn and
// therefore must keep canonical context anchored above the latest real user turn.
let initial_context = sess.build_initial_context(turn_context.as_ref()).await;
insert_initial_context_before_last_real_user(&mut new_history, initial_context);
}
CompactCallsite::ManualCompact => {
// Manual `/compact` intentionally rewrites transcript history without reseeding turn
// context here; the task marks initial context unseeded for the next user turn.
}
CompactCallsite::PreTurnIncludingIncomingUserMessage
| CompactCallsite::PreTurnExcludingIncomingUserMessage => {
// Pre-turn compaction persists canonical context directly above the incoming user
// message in `run_turn`, not inside compacted replacement history.
}
}
// Reattach stripped model-switch updates into replacement history so post-compaction
// sampling keeps model-switch guidance regardless of compaction callsite.
+22 -18
View File
@@ -3,7 +3,7 @@ use std::sync::Arc;
use crate::Prompt;
use crate::codex::Session;
use crate::codex::TurnContext;
use crate::compact::AutoCompactCallsite;
use crate::compact::CompactCallsite;
use crate::compact::extract_latest_model_switch_update_from_items;
use crate::compact::extract_trailing_model_switch_update_for_compaction_request;
use crate::compact::insert_initial_context_before_last_real_user;
@@ -32,7 +32,7 @@ use tracing::info;
pub(crate) async fn run_inline_remote_auto_compact_task(
sess: Arc<Session>,
turn_context: Arc<TurnContext>,
auto_compact_callsite: AutoCompactCallsite,
auto_compact_callsite: CompactCallsite,
incoming_items: Option<Vec<ResponseItem>>,
) -> CodexResult<()> {
run_remote_compact_task_inner(&sess, &turn_context, auto_compact_callsite, incoming_items)
@@ -51,19 +51,13 @@ pub(crate) async fn run_remote_compact_task(
});
sess.send_event(&turn_context, start_event).await;
run_remote_compact_task_inner(
&sess,
&turn_context,
AutoCompactCallsite::PreTurnExcludingIncomingUserMessage,
None,
)
.await
run_remote_compact_task_inner(&sess, &turn_context, CompactCallsite::ManualCompact, None).await
}
async fn run_remote_compact_task_inner(
sess: &Arc<Session>,
turn_context: &Arc<TurnContext>,
auto_compact_callsite: AutoCompactCallsite,
auto_compact_callsite: CompactCallsite,
incoming_items: Option<Vec<ResponseItem>>,
) -> CodexResult<()> {
if let Err(err) = run_remote_compact_task_inner_impl(
@@ -88,7 +82,7 @@ async fn run_remote_compact_task_inner(
async fn run_remote_compact_task_inner_impl(
sess: &Arc<Session>,
turn_context: &Arc<TurnContext>,
auto_compact_callsite: AutoCompactCallsite,
auto_compact_callsite: CompactCallsite,
incoming_items: Option<Vec<ResponseItem>>,
) -> CodexResult<()> {
let compaction_item = TurnItem::ContextCompaction(ContextCompactionItem::new());
@@ -168,12 +162,22 @@ async fn run_remote_compact_task_inner_impl(
})
.await?;
new_history = process_compacted_history(new_history);
if matches!(
auto_compact_callsite,
AutoCompactCallsite::MidTurnContinuation | AutoCompactCallsite::PreSamplingModelSwitch
) {
let initial_context = sess.build_initial_context(turn_context.as_ref()).await;
insert_initial_context_before_last_real_user(&mut new_history, initial_context);
match auto_compact_callsite {
CompactCallsite::MidTurnContinuation | CompactCallsite::PreSamplingModelSwitch => {
// Mid-turn and pre-sampling model-switch compaction continue the in-flight turn and
// therefore must keep canonical context anchored above the latest real user turn.
let initial_context = sess.build_initial_context(turn_context.as_ref()).await;
insert_initial_context_before_last_real_user(&mut new_history, initial_context);
}
CompactCallsite::ManualCompact => {
// Manual `/compact` intentionally rewrites transcript history without reseeding turn
// context here; the task marks initial context unseeded for the next user turn.
}
CompactCallsite::PreTurnIncludingIncomingUserMessage
| CompactCallsite::PreTurnExcludingIncomingUserMessage => {
// Pre-turn compaction persists canonical context directly above the incoming user
// message in `run_turn`, not inside compacted replacement history.
}
}
if let Some(incoming_items) = incoming_items.as_ref() {
let incoming_history_items: Vec<ResponseItem> = incoming_items
@@ -271,7 +275,7 @@ fn remove_incoming_echoes_from_compacted_history(
fn log_remote_compact_failure(
turn_context: &TurnContext,
auto_compact_callsite: AutoCompactCallsite,
auto_compact_callsite: CompactCallsite,
log_data: &CompactRequestLogData,
total_usage_breakdown: TotalTokenUsageBreakdown,
err: &CodexErr,