fix(codex): harden Copilot replay classification

Require literal booleans for backend-specific replay policy and pin
non-default status and content preservation through both response paths.
This commit is contained in:
kshitijk4poor 2026-07-11 11:34:30 +05:30 committed by kshitij
parent 83b2a685cd
commit 22d5a35c16
3 changed files with 39 additions and 10 deletions

View file

@ -67,9 +67,9 @@ class ResponsesApiTransport(ProviderTransport):
"""Classify the current Responses endpoint from transport params."""
from agent.codex_responses_adapter import _classify_responses_issuer
return _classify_responses_issuer(
is_xai_responses=bool(params.get("is_xai_responses")),
is_github_responses=bool(params.get("is_github_responses")),
is_codex_backend=bool(params.get("is_codex_backend")),
is_xai_responses=params.get("is_xai_responses") is True,
is_github_responses=params.get("is_github_responses") is True,
is_codex_backend=params.get("is_codex_backend") is True,
base_url=params.get("base_url"),
)
@ -80,8 +80,8 @@ class ResponsesApiTransport(ProviderTransport):
self._last_issuer_kind = issuer
return _chat_messages_to_responses_input(
messages,
is_xai_responses=bool(kwargs.get("is_xai_responses")),
is_github_responses=bool(kwargs.get("is_github_responses")),
is_xai_responses=kwargs.get("is_xai_responses") is True,
is_github_responses=kwargs.get("is_github_responses") is True,
replay_encrypted_reasoning=bool(
kwargs.get("replay_encrypted_reasoning", True)
),
@ -138,9 +138,9 @@ class ResponsesApiTransport(ProviderTransport):
if not instructions:
instructions = DEFAULT_AGENT_IDENTITY
is_github_responses = params.get("is_github_responses", False)
is_codex_backend = params.get("is_codex_backend", False)
is_xai_responses = params.get("is_xai_responses", False)
is_github_responses = params.get("is_github_responses") is True
is_codex_backend = params.get("is_codex_backend") is True
is_xai_responses = params.get("is_xai_responses") is True
replay_encrypted_reasoning = bool(
params.get("replay_encrypted_reasoning", True)
)

View file

@ -4109,7 +4109,7 @@ class TestCodexAdapterGithubResponsesMessageIdDrop:
{
"type": "message",
"role": "assistant",
"status": "completed",
"status": "in_progress",
"content": [{"type": "output_text", "text": "pong"}],
"id": "msg_short_but_connection_scoped",
"phase": "final_answer",
@ -4127,6 +4127,8 @@ class TestCodexAdapterGithubResponsesMessageIdDrop:
)
assert "id" not in message_item
assert message_item["phase"] == "final_answer"
assert message_item["status"] == "in_progress"
assert message_item["content"] == [{"type": "output_text", "text": "pong"}]
def test_keeps_message_id_for_codex_backend_host(self):
adapter, captured = self._build_adapter(

View file

@ -138,7 +138,7 @@ class TestCodexBuildKwargs:
{
"type": "message",
"role": "assistant",
"status": "completed",
"status": "in_progress",
"content": [{"type": "output_text", "text": "pong"}],
"id": "msg_short_but_connection_scoped",
"phase": "final_answer",
@ -153,6 +153,33 @@ class TestCodexBuildKwargs:
message_item = next(item for item in kw["input"] if item.get("type") == "message")
assert "id" not in message_item
assert message_item["phase"] == "final_answer"
assert message_item["status"] == "in_progress"
assert message_item["content"] == [{"type": "output_text", "text": "pong"}]
def test_github_responses_requires_literal_true(self, transport):
messages = [
{
"role": "assistant",
"content": "pong",
"codex_message_items": [
{
"type": "message",
"role": "assistant",
"status": "completed",
"content": [{"type": "output_text", "text": "pong"}],
"id": "msg_short_id",
}
],
},
]
kw = transport.build_kwargs(
model="gpt-5.5", messages=messages, tools=[],
is_github_responses="false",
)
message_item = next(item for item in kw["input"] if item.get("type") == "message")
assert message_item["id"] == "msg_short_id"
def test_non_github_responses_keeps_message_item_id_end_to_end(self, transport):
messages = [