fix(codex): restore session_id/x-client-request-id HTTP headers for cache routing (#47335)

This commit is contained in:
kyssta-exe 2026-06-16 18:32:27 +00:00 committed by Teknium
parent 435c706e8e
commit 4d39a603d1
2 changed files with 44 additions and 7 deletions

View file

@ -218,10 +218,28 @@ class ResponsesApiTransport(ProviderTransport):
kwargs.pop("timeout", None)
if is_codex_backend:
# chatgpt.com/backend-api/codex rejects body-level
# ``extra_headers`` with HTTP 400. Correlation/cache routing for
# this backend must not be sent through the Responses payload.
kwargs.pop("extra_headers", None)
# The Codex backend rejects body-level ``extra_headers`` with
# HTTP 400, but the OpenAI SDK's ``extra_headers`` kwarg maps
# to actual HTTP request headers (not body fields). We need
# these headers for cache-scope routing so prompt cache hits
# remain high. Send session_id / x-client-request-id as HTTP
# headers while keeping ``prompt_cache_key`` in the body for
# standard OpenAI routing as a belt-and-braces fallback.
cache_scope_id = str(session_id or "").strip()
if cache_scope_id:
existing_extra_headers = kwargs.get("extra_headers")
merged_extra_headers: Dict[str, str] = {}
if isinstance(existing_extra_headers, dict):
merged_extra_headers.update(
{
str(key): str(value)
for key, value in existing_extra_headers.items()
if key and value is not None
}
)
merged_extra_headers["session_id"] = cache_scope_id
merged_extra_headers["x-client-request-id"] = cache_scope_id
kwargs["extra_headers"] = merged_extra_headers
max_tokens = params.get("max_tokens")
if max_tokens is not None and not is_codex_backend:

View file

@ -155,7 +155,9 @@ class TestCodexBuildKwargs:
)
assert "max_output_tokens" not in kw
def test_codex_backend_does_not_set_extra_headers(self, transport):
def test_codex_backend_sets_cache_routing_headers(self, transport):
"""Codex backend sends session_id / x-client-request-id as HTTP
headers (via extra_headers) for cache-scope routing."""
messages = [{"role": "user", "content": "Hi"}]
kw = transport.build_kwargs(
@ -166,9 +168,23 @@ class TestCodexBuildKwargs:
is_codex_backend=True,
)
headers = kw.get("extra_headers", {})
assert headers.get("session_id") == "conv-codex-1"
assert headers.get("x-client-request-id") == "conv-codex-1"
def test_codex_backend_no_headers_without_session_id(self, transport):
messages = [{"role": "user", "content": "Hi"}]
kw = transport.build_kwargs(
model="gpt-5.4",
messages=messages,
tools=[],
is_codex_backend=True,
)
assert "extra_headers" not in kw
def test_codex_backend_strips_caller_extra_headers(self, transport):
def test_codex_backend_preserves_caller_extra_headers(self, transport):
messages = [{"role": "user", "content": "Hi"}]
kw = transport.build_kwargs(
@ -180,7 +196,10 @@ class TestCodexBuildKwargs:
request_overrides={"extra_headers": {"x-test": "1"}},
)
assert "extra_headers" not in kw
headers = kw.get("extra_headers", {})
assert headers.get("x-test") == "1"
assert headers.get("session_id") == "conv-codex-1"
assert headers.get("x-client-request-id") == "conv-codex-1"
def test_non_codex_responses_preserves_caller_extra_headers(self, transport):
messages = [{"role": "user", "content": "Hi"}]