mirror of
https://github.com/openai/codex.git
synced 2026-09-05 15:18:41 +00:00
## What changed - Wrap `CodexErrorDetails` and an optional retry delay in `CodexErr`, allowing any mapped error to preserve server-provided retry timing. - Generate the payload-free `CodexErrKind` classification alongside the error details and reuse it for analytics. - Update error handling sites to inspect `CodexErr::details()` while preserving existing display, debug, protocol mapping, and retryability behavior. ## Testing - Add coverage for legacy debug formatting, error-specific retryability, and retry-delay propagation through API error mapping. GitOrigin-RevId: d3ab8a305f2a2ee21d0c0a8c8c388b06dda9c59a
65 lines
2.1 KiB
Rust
65 lines
2.1 KiB
Rust
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;
|
|
|
|
/// Retries failures that may be model-specific and succeed with a different model.
|
|
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",
|
|
CompactionImplementation::ResponsesCompact => "responses_compact",
|
|
};
|
|
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"
|
|
);
|
|
}
|