mirror of
https://github.com/openai/codex.git
synced 2026-08-23 13:09:46 +00:00
[codex] Read retry model from buffering events (#31262)
## Summary - deserialize `retry_model` from streamed `safety_buffering` payloads - preserve the existing downstream faster-model API and legacy header fallback - update SSE, WebSocket, and end-to-end safety-buffering coverage ## Root cause Follow-up to #31064. The Responses API emits the retry target as `retry_model`, but the client was looking for `faster_model`, so the payload value was ignored in favor of the compatibility fallback. ## Behavior A non-null `retry_model` from the buffering payload takes precedence. An explicit null leaves the retry target unset, while an omitted field continues to fall back to the existing response header. ## Validation - `just test -p codex-api` (135 tests) - `just test -p codex-core safety_buffering` (2 tests) - `just fix -p codex-api` - `just fmt` - `git diff --check`
This commit is contained in:
committed by
GitHub
parent
8917244f7d
commit
7094fa467e
@@ -123,6 +123,7 @@ pub struct SafetyBuffering {
|
||||
pub reasons: Vec<String>,
|
||||
#[serde(skip)]
|
||||
pub show_buffering_ui: bool,
|
||||
#[serde(rename = "retry_model")]
|
||||
pub faster_model: Option<String>,
|
||||
}
|
||||
|
||||
|
||||
@@ -1061,7 +1061,7 @@ mod tests {
|
||||
"safety_buffering": {
|
||||
"use_cases": ["cyber"],
|
||||
"reasons": ["user_risk"],
|
||||
"faster_model": "gpt-fast-wire"
|
||||
"retry_model": "gpt-fast-wire"
|
||||
}
|
||||
}))
|
||||
.expect("deserialize safety buffering event");
|
||||
|
||||
@@ -236,10 +236,10 @@ impl ResponsesStreamEvent {
|
||||
treatment: &SafetyBufferingTreatment,
|
||||
) -> Option<SafetyBuffering> {
|
||||
let value = self.safety_buffering.as_ref()?;
|
||||
let faster_model_present = value.as_object()?.contains_key("faster_model");
|
||||
let retry_model_present = value.as_object()?.contains_key("retry_model");
|
||||
let mut buffering: SafetyBuffering = serde_json::from_value(value.clone()).ok()?;
|
||||
buffering.show_buffering_ui = true;
|
||||
if !faster_model_present {
|
||||
if !retry_model_present {
|
||||
buffering.faster_model.clone_from(&treatment.faster_model);
|
||||
}
|
||||
Some(buffering)
|
||||
@@ -1405,7 +1405,7 @@ mod tests {
|
||||
"safety_buffering": {
|
||||
"use_cases": ["cyber"],
|
||||
"reasons": ["user_risk"],
|
||||
"faster_model": "gpt-fast-wire"
|
||||
"retry_model": "gpt-fast-wire"
|
||||
}
|
||||
}),
|
||||
json!({
|
||||
@@ -1453,12 +1453,12 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn safety_buffering_prefers_wire_faster_model_and_only_falls_back_when_omitted() {
|
||||
fn safety_buffering_prefers_wire_retry_model_and_only_falls_back_when_omitted() {
|
||||
let treatment = SafetyBufferingTreatment {
|
||||
faster_model: Some("gpt-fast-header".to_string()),
|
||||
};
|
||||
|
||||
for (faster_model, expected_faster_model) in [
|
||||
for (retry_model, expected_faster_model) in [
|
||||
(None, Some("gpt-fast-header")),
|
||||
(Some(Value::Null), None),
|
||||
(Some(json!("gpt-fast-wire")), Some("gpt-fast-wire")),
|
||||
@@ -1470,8 +1470,8 @@ mod tests {
|
||||
"reasons": ["user_risk"]
|
||||
}
|
||||
});
|
||||
if let Some(faster_model) = faster_model {
|
||||
event["safety_buffering"]["faster_model"] = faster_model;
|
||||
if let Some(retry_model) = retry_model {
|
||||
event["safety_buffering"]["retry_model"] = retry_model;
|
||||
}
|
||||
let event: ResponsesStreamEvent =
|
||||
serde_json::from_value(event).expect("deserialize safety buffering event");
|
||||
|
||||
Reference in New Issue
Block a user