diff --git a/agent/auxiliary_client.py b/agent/auxiliary_client.py index 365ecc57f1..54fda40aa6 100644 --- a/agent/auxiliary_client.py +++ b/agent/auxiliary_client.py @@ -1155,12 +1155,10 @@ def _parse_codex_final_response( ) # Aux consumers speak Chat Completions: "length" activates their existing # partial-summary rejection/fallback, whereas Codex's "incomplete" does not. - # A final_answer phase cannot override the provider's incomplete status, but completed - # tool calls stay "tool_calls" so dispatchers (e.g. MCP sampling) still run them. - status = _lower_or_none(normalized_final.status) - reason = str(_field(normalized_final.incomplete_details, "reason", "") or "").strip().lower() + # Any provider-incomplete response (token cap or content_filter) is a partial no aux consumer + # may commit; completed tool calls stay "tool_calls" so dispatchers (e.g. MCP sampling) still run them. if finish_reason != "tool_calls" and ( - finish_reason == "incomplete" or (status == "incomplete" and reason != "content_filter") + finish_reason == "incomplete" or _lower_or_none(normalized_final.status) == "incomplete" ): finish_reason = "length" text_parts = [message.content] if message.content else [] diff --git a/tests/agent/test_auxiliary_codex_completion_status.py b/tests/agent/test_auxiliary_codex_completion_status.py index 6121d7d470..4128131a86 100644 --- a/tests/agent/test_auxiliary_codex_completion_status.py +++ b/tests/agent/test_auxiliary_codex_completion_status.py @@ -99,6 +99,8 @@ _CODEX_REASONING_ONLY = SimpleNamespace( id="tool-call-like-output-text-beside-commentary"), pytest.param("", "incomplete", [_message("PARTIAL")], "max_output_tokens", "PARTIAL", "length", id="token-cap"), pytest.param("", "incomplete", [_TOOL_CALL], "max_output_tokens", None, "tool_calls", id="token-cap-after-tool-call"), + # Compressor only rejects "length": a content-filtered partial must not be committed as a summary. + pytest.param("", "incomplete", [_message("CF")], "content_filter", "CF", "length", id="content-filter"), # Commentary + unphased text is incomplete whether or not the unphased text looks like a tool call. pytest.param("", "completed", [_message("NOTE", phase="commentary"), _message(_LEAK_LIKE_ANSWER, phase=None)], None, _LEAK_LIKE_ANSWER, "length", id="tool-call-like-beside-commentary"),