mirror of
https://github.com/openai/codex.git
synced 2026-11-07 20:30:33 +00:00
Enable uploaded audio with durable rejection recovery (#59234)
## Why Uploaded audio was rejected even for audio-capable models. Invalid or expired recordings also need to be excluded from later requests so users can continue the conversation. ## What changed - Accept uploaded audio when the selected model supports audio; otherwise, preserve valid sibling input and report the unsupported attachment before inference. - Track successful audio decoding by model and provider, and attribute provider rejections against the exact submitted request. Preserve attachments when attribution is ambiguous. - Persist confirmed rejected file IDs across compaction and resume, omitting them from future requests without rewriting retained user history. - Check audio availability before remote compaction and retry once without an unambiguously rejected recording. Include guidance to remove or replace affected attachments in audio errors. ## Testing Add unit and scenario coverage for uploaded audio across follow-up turns, compaction, cold and paginated resume, model switching, ambiguous rejections, expired files, and queued or interrupted input. GitOrigin-RevId: e701901e7b1c0865c9f2a5918197215f549b06c0
This commit is contained in:
@@ -86,9 +86,13 @@ fn map_api_error_details(err: ApiError) -> CodexErr {
|
||||
})
|
||||
}
|
||||
ApiError::InvalidRequest { message } => CodexErr::InvalidRequest(message),
|
||||
ApiError::InvalidAudioInput { message } => {
|
||||
CodexErr::new(CodexErrorDetails::InvalidAudioInput { message })
|
||||
}
|
||||
ApiError::InvalidAudioInput {
|
||||
message,
|
||||
per_recording,
|
||||
} => CodexErr::new(CodexErrorDetails::InvalidAudioInput {
|
||||
message,
|
||||
per_recording,
|
||||
}),
|
||||
ApiError::ModelNotFound { message, status } => {
|
||||
CodexErr::new(CodexErrorDetails::ModelNotFound { message, status })
|
||||
}
|
||||
|
||||
@@ -42,7 +42,11 @@ pub enum ApiError {
|
||||
#[error("invalid request: {message}")]
|
||||
InvalidRequest { message: String },
|
||||
#[error("{message}")]
|
||||
InvalidAudioInput { message: String },
|
||||
InvalidAudioInput {
|
||||
message: String,
|
||||
/// True when the provider rejected an individual clip, independent of request size.
|
||||
per_recording: bool,
|
||||
},
|
||||
#[error("{message}")]
|
||||
ModelNotFound {
|
||||
message: String,
|
||||
@@ -93,6 +97,7 @@ pub(crate) fn parse_terminal_provider_error(
|
||||
| "missing_audio_sample_rate",
|
||||
None | Some(StatusCode::BAD_REQUEST),
|
||||
) => Some(ApiError::InvalidAudioInput {
|
||||
per_recording: code != "audio_too_large",
|
||||
message: error
|
||||
.get("message")
|
||||
.and_then(Value::as_str)
|
||||
|
||||
Reference in New Issue
Block a user