Files
codex/codex-rs/codex-api/src/safety_buffering.rs
Francis Chalissery be33f80bc6 [codex] Read buffering metadata from response events (#31064)
## Summary

- read optional faster-model metadata from streamed buffering payloads
- use the buffering payload itself to determine whether buffering UI
should be shown
- retain the existing header value as a compatibility fallback when the
payload omits the field

## Behavior

An object-valued buffering signal now enables the buffering UI. The
response event's faster-model field takes precedence when present, while
omitted fields fall back to existing response metadata. An explicit null
leaves the retry target unset.

## Validation

- `just test -p codex-api`
- `just fix -p codex-api`
- `cargo fmt --all -- --check`
- `git diff --check`
2026-07-05 00:07:53 +00:00

68 lines
2.1 KiB
Rust

use crate::common::SafetyBufferingTreatment;
use http::HeaderMap;
pub(crate) const X_CODEX_SAFETY_BUFFERING_ENABLED_HEADER: &str = "x-codex-safety-buffering-enabled";
pub(crate) const X_CODEX_SAFETY_BUFFERING_FASTER_MODEL_HEADER: &str =
"x-codex-safety-buffering-faster-model";
pub(crate) fn treatment_from_headers(headers: &HeaderMap) -> Option<SafetyBufferingTreatment> {
if !headers.contains_key(X_CODEX_SAFETY_BUFFERING_ENABLED_HEADER)
&& !headers.contains_key(X_CODEX_SAFETY_BUFFERING_FASTER_MODEL_HEADER)
{
return None;
}
let faster_model = headers
.get(X_CODEX_SAFETY_BUFFERING_FASTER_MODEL_HEADER)
.and_then(|value| value.to_str().ok())
.map(str::to_string);
Some(SafetyBufferingTreatment { faster_model })
}
#[cfg(test)]
mod tests {
use super::*;
use http::HeaderValue;
use pretty_assertions::assert_eq;
#[test]
fn reads_treatment_from_http_headers() {
let mut headers = HeaderMap::new();
headers.insert(
X_CODEX_SAFETY_BUFFERING_ENABLED_HEADER,
HeaderValue::from_static("true"),
);
headers.insert(
X_CODEX_SAFETY_BUFFERING_FASTER_MODEL_HEADER,
HeaderValue::from_static("faster-model"),
);
assert_eq!(
treatment_from_headers(&headers),
Some(SafetyBufferingTreatment {
faster_model: Some("faster-model".to_string()),
})
);
}
#[test]
fn buffering_enabled_header_does_not_gate_the_faster_model_fallback() {
let mut headers = HeaderMap::new();
headers.insert(
X_CODEX_SAFETY_BUFFERING_ENABLED_HEADER,
HeaderValue::from_static("false"),
);
headers.insert(
X_CODEX_SAFETY_BUFFERING_FASTER_MODEL_HEADER,
HeaderValue::from_static("faster-model"),
);
assert_eq!(
treatment_from_headers(&headers),
Some(SafetyBufferingTreatment {
faster_model: Some("faster-model".to_string()),
})
);
}
}