Skip to content

fix(codex): trust response.status for reasoning-only turns on unrecognized Responses backends - #64764

Merged
teknium1 merged 3 commits into
mainfrom
fix/64434-reasoning-only-finish-reason
Jul 15, 2026
Merged

fix(codex): trust response.status for reasoning-only turns on unrecognized Responses backends#64764
teknium1 merged 3 commits into
mainfrom
fix/64434-reasoning-only-finish-reason

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Reasoning-only completed turns on api_mode: codex_responses no longer get force-classified as incomplete for unrecognized Responses backends — the provider's own response.status="completed" is trusted, eliminating ~12-minute silent continuation stalls (3 retries × up to 240s stale timeout each).

Salvages #64449 (@webtecnica, fixes #64434) with authorship preserved, plus one follow-up.

Root cause: _normalize_codex_response inferred "still thinking" purely from item-type composition (only a reasoning item present). That heuristic is correct for Codex/xAI backends where reasoning-only is a documented degeneration mode, but wrong for generic Responses-compatible relays (other:<base_url>), where a completed reasoning-only turn is a valid final state. The misfire drove the continuation path repeatedly and could burn the whole 150-iteration budget while showing only "Working — N min".

Changes

  • agent/codex_responses_adapter.py: when response.status == "completed", only the specially-handled backends (codex_backend, xai_responses, github_responses) keep the reasoning-only → incomplete continuation heuristic; all other issuers get stop (@webtecnica)
  • Follow-up (ours): added github_responses to the continuation set — the contributor's diff silently flipped Copilot to the stop side, but Copilot fronts the same OpenAI model family as codex_backend and shows the same reasoning-only degeneration; plus a pinning test

Validation

issuer_kind status=completed, reasoning-only Before After
other:<relay> incomplete (3×240s stall) stop
codex_backend incomplete incomplete (unchanged)
xai_responses incomplete incomplete (unchanged)
github_responses incomplete incomplete (preserved by follow-up)
other:<relay> status=in_progress incomplete incomplete (status trusted both ways)
  • scripts/run_tests.sh tests/run_agent/test_run_agent_codex_responses.py: 90/90 passed
  • E2E repro of the issue's exact SimpleNamespace scenario with real imports: all five rows above verified

Infographic

finish-reason-trust-provider-status

webtecnica and others added 2 commits July 14, 2026 21:50
…nuation path

Follow-up to the salvaged #64449: the status-trusting branch flipped
github_responses to 'stop' alongside unknown relays. Copilot fronts the
same OpenAI model family as codex_backend and shows the same
reasoning-only 'still thinking' degeneration, so it stays on the
continuation path. Only unrecognized (other:*) backends trust
response.status='completed' as terminal.
@teknium1
teknium1 force-pushed the fix/64434-reasoning-only-finish-reason branch from ddbd9db to 7d8ce88 Compare July 15, 2026 04:50
@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint codex provider/openai OpenAI / Codex Responses API P2 Medium — degraded but workaround exists labels Jul 15, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Salvage of #64449 (fixes #64434) with authorship preserved, plus a github_responses follow-up. Related to the Codex-Responses incomplete-misclassification family (#51628, #51512). Not a duplicate — this is the active salvaged version; #64449 is the predecessor. Flagging the cluster (#64764 / #64449 / #64434) so a maintainer can pick the canonical PR.

…ng test

The #64434 change makes unrecognized issuers trust
response.status='completed' for reasoning-only turns, so this sibling
test (which exercised the old default-path behavior) now pins the Codex
backend explicitly — the surface where reasoning-only still means
'still thinking'.
@teknium1
teknium1 merged commit 07443ea into main Jul 15, 2026
31 checks passed
@teknium1
teknium1 deleted the fix/64434-reasoning-only-finish-reason branch July 15, 2026 07:12
teknium1 added a commit that referenced this pull request Jul 15, 2026
)

test_normalize_codex_response_salvage_is_xai_scoped broke on main when
two same-day merges crossed: #64764 (#64434 — trust response.status for
reasoning-only turns on UNRECOGNIZED Responses backends) changed what a
bare _normalize_codex_response(response) call returns for
status='completed' reasoning-only output (now 'stop'), while #64768
added this test calling with no issuer_kind and expecting 'incomplete'.

The test's intent is that the xAI reasoning-channel salvage does not
leak into other special-cased backends — pin issuer_kind='codex_backend'
so it exercises exactly that (same pattern as
test_normalize_codex_response_treats_summary_only_reasoning_as_incomplete,
which was already pinned for #64434).
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…sResearch#64844)

test_normalize_codex_response_salvage_is_xai_scoped broke on main when
two same-day merges crossed: NousResearch#64764 (NousResearch#64434 — trust response.status for
reasoning-only turns on UNRECOGNIZED Responses backends) changed what a
bare _normalize_codex_response(response) call returns for
status='completed' reasoning-only output (now 'stop'), while NousResearch#64768
added this test calling with no issuer_kind and expecting 'incomplete'.

The test's intent is that the xAI reasoning-channel salvage does not
leak into other special-cased backends — pin issuer_kind='codex_backend'
so it exercises exactly that (same pattern as
test_normalize_codex_response_treats_summary_only_reasoning_as_incomplete,
which was already pinned for NousResearch#64434).
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
…sResearch#64844)

test_normalize_codex_response_salvage_is_xai_scoped broke on main when
two same-day merges crossed: NousResearch#64764 (NousResearch#64434 — trust response.status for
reasoning-only turns on UNRECOGNIZED Responses backends) changed what a
bare _normalize_codex_response(response) call returns for
status='completed' reasoning-only output (now 'stop'), while NousResearch#64768
added this test calling with no issuer_kind and expecting 'incomplete'.

The test's intent is that the xAI reasoning-channel salvage does not
leak into other special-cased backends — pin issuer_kind='codex_backend'
so it exercises exactly that (same pattern as
test_normalize_codex_response_treats_summary_only_reasoning_as_incomplete,
which was already pinned for NousResearch#64434).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

codex comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists provider/openai OpenAI / Codex Responses API type/bug Something isn't working

Projects

None yet

3 participants