mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
## Why Manual, pre-turn, and post-turn compaction previously deferred rebuilding initial context until the next turn. Their saved replacement history could omit refreshed instructions and skill catalogs. ## What changed - Install initial context during local and remote compaction, before the last real user message or summary, keeping the compaction summary last. - Persist matching full world-state and turn-context baselines with every replacement instead of retaining only partial extension metadata. - Build replacement context and recompute token usage for the current model even when the previous model performs compaction. Reuse that captured context for eligible current-model retries. - Capture manual compaction context centrally and propagate preparation errors to the task runner. ## Testing Update assertions and snapshots for context ordering, refreshed instructions, resume and fork history, current-model checkpoint baselines, and cloud skill catalog retention across compaction and resume. GitOrigin-RevId: 8572a76c31c6884a3c580b3bbb350d49af876bd1
76 lines
2.4 KiB
Rust
76 lines
2.4 KiB
Rust
use crate::session::turn_context::TurnContext;
|
|
use codex_analytics::CompactionImplementation;
|
|
use codex_analytics::CompactionReason;
|
|
use codex_otel::SessionTelemetry;
|
|
use codex_protocol::error::CodexErr;
|
|
use codex_protocol::error::CodexErrorDetails;
|
|
use tracing::warn;
|
|
|
|
/// Returns whether a failed compaction attempt should use the current model.
|
|
pub(crate) fn should_retry_with_current_model(
|
|
error: &CodexErr,
|
|
previous: &TurnContext,
|
|
current: &TurnContext,
|
|
) -> bool {
|
|
if matches!(
|
|
error.details(),
|
|
CodexErrorDetails::TurnAborted
|
|
| CodexErrorDetails::Interrupted
|
|
| CodexErrorDetails::SessionBudgetExceeded
|
|
) || (previous.model_info().slug == current.model_info().slug
|
|
&& previous.cyber_access_program == current.cyber_access_program)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
current.provider.info().is_openai()
|
|
&& current
|
|
.auth_manager
|
|
.as_deref()
|
|
.and_then(codex_login::AuthManager::auth_cached)
|
|
.is_some_and(|auth| auth.uses_codex_backend() || auth.is_api_key_auth())
|
|
}
|
|
|
|
pub(crate) fn record_model_fallback(
|
|
session_telemetry: &SessionTelemetry,
|
|
previous_model: &str,
|
|
current_model: &str,
|
|
reason: CompactionReason,
|
|
implementation: CompactionImplementation,
|
|
fallback_error: Option<&CodexErr>,
|
|
) {
|
|
let reason_tag = match reason {
|
|
CompactionReason::UserRequested => "user_requested",
|
|
CompactionReason::ContextLimit => "context_limit",
|
|
CompactionReason::ModelDownshift => "model_downshift",
|
|
CompactionReason::CompHashChanged => "comp_hash_changed",
|
|
};
|
|
let implementation_tag = match implementation {
|
|
CompactionImplementation::Responses => "responses",
|
|
CompactionImplementation::ResponsesCompactionV2 => "responses_compaction_v2",
|
|
};
|
|
let outcome = if fallback_error.is_none() {
|
|
"succeeded"
|
|
} else {
|
|
"failed"
|
|
};
|
|
session_telemetry.counter(
|
|
"codex.compaction.model_fallback",
|
|
/*inc*/ 1,
|
|
&[
|
|
("reason", reason_tag),
|
|
("implementation", implementation_tag),
|
|
("outcome", outcome),
|
|
],
|
|
);
|
|
warn!(
|
|
previous_model,
|
|
current_model,
|
|
?reason,
|
|
?implementation,
|
|
outcome,
|
|
?fallback_error,
|
|
"previous-model compaction failed; retried with current model"
|
|
);
|
|
}
|