fix(codex): preserve explicit service tiers and adapt usage badges

This commit is contained in:
ZheFox
2026-09-22 22:19:52 +08:00
parent 0b7c7f94ac
commit 69930a6059
7 changed files with 127 additions and 43 deletions
@@ -229,7 +229,7 @@ fn validate_final_openai_provider_request_contract(
#[cfg(test)]
mod tests {
use serde_json::json;
use serde_json::{json, Value};
use super::{
finalize_openai_provider_request,
@@ -587,6 +587,61 @@ mod tests {
}
}
#[test]
fn codex_finalization_preserves_explicit_service_tiers() {
let capabilities = CodexResponsesModelCapabilities {
use_responses_lite: false,
supports_reasoning_summary_parameter: false,
default_reasoning_effort: None,
default_reasoning_summary: None,
supported_reasoning_efforts: Vec::new(),
supports_parallel_tool_calls: true,
support_verbosity: false,
default_verbosity: None,
supported_service_tiers: vec!["priority".to_string()],
};
for source_api_format in ["openai:responses", "openai:chat"] {
for provider_api_format in ["openai:responses", "openai:responses:compact"] {
for model_capabilities in [None, Some(&capabilities)] {
for service_tier in [
Some("ultrafast"),
Some("priority"),
Some("default"),
Some("auto"),
Some("flex"),
Some("future-tier"),
None,
] {
let mut body = json!({"model": "gpt-5.6-sol", "input": []});
if let Some(service_tier) = service_tier {
body["service_tier"] = json!(service_tier);
}
finalize_openai_provider_request_with_codex_model_capabilities(
&mut body,
OpenAiProviderRequestFinalization {
source_api_format,
provider_api_format,
provider_type: "codex",
provider_model: "gpt-5.6-sol",
source_model: "gpt-5.6-sol",
body_rules: None,
upstream_is_stream: true,
require_body_stream_field: true,
},
model_capabilities,
)
.expect("explicit service tiers should be validated by the upstream");
assert_eq!(
body.get("service_tier").and_then(Value::as_str),
service_tier,
"{source_api_format} -> {provider_api_format}",
);
}
}
}
}
}
#[test]
fn dynamic_codex_card_preserves_default_effort_and_keeps_mode_model_specific() {
let finalization = OpenAiProviderRequestFinalization {
@@ -91,12 +91,6 @@ impl CodexResponsesModelCapabilities {
.iter()
.any(|candidate| candidate == effort.trim())
}
fn supports_service_tier(&self, service_tier: &str) -> bool {
self.supported_service_tiers
.iter()
.any(|candidate| candidate == service_tier)
}
}
fn codex_namespaced_model_suffix(model: &str) -> Option<&str> {
@@ -1214,18 +1208,6 @@ fn apply_codex_model_request_capabilities(
}
}
}
if !body_rules_handle_path(body_rules, "service_tier") {
let service_tier = body_object
.get("service_tier")
.and_then(Value::as_str)
.map(str::to_string);
if !service_tier.as_deref().is_some_and(|service_tier| {
service_tier != "default" && capabilities.supports_service_tier(service_tier)
}) {
body_object.remove("service_tier");
}
}
}
fn ensure_codex_reasoning_defaults(
@@ -2654,7 +2636,7 @@ mod tests {
assert_eq!(body["reasoning"]["effort"], "high");
assert_eq!(body["include"], json!(["reasoning.encrypted_content"]));
assert_eq!(body["parallel_tool_calls"], false);
assert!(body.get("service_tier").is_none());
assert_eq!(body["service_tier"], "priority");
assert!(body["text"].get("verbosity").is_none());
assert_eq!(body["text"]["format"]["type"], "json_schema");