| 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; |
|
|
| |
| pub(crate) fn should_retry_with_current_model(error: &CodexErr) -> bool { |
| matches!( |
| error.details(), |
| CodexErrorDetails::InvalidRequest(_) |
| | CodexErrorDetails::UnexpectedStatus(_) |
| | CodexErrorDetails::ContextWindowExceeded |
| | CodexErrorDetails::UsageLimitReached(_) |
| | CodexErrorDetails::ServerOverloaded |
| | CodexErrorDetails::InternalServerError |
| | CodexErrorDetails::RetryLimit(_) |
| ) |
| } |
|
|
| 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", |
| 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" |
| ); |
| } |
|
|