fix(agent): recover Codex streams with null final output#32884
fix(agent): recover Codex streams with null final output#32884serejaris wants to merge 3 commits into
Conversation
|
Thanks, this was a real remaining path. I cherry-picked your follow-up as 9a9d46f, preserving authorship. Re-ran targeted canonical validation: |
|
Linux 修复命令,直接终端运行即可,然后重启gateway ` 0. 备份cp venv/lib/python3.11/site-packages/openai/lib/_parsing/_responses.py cp agent/transports/codex.py 1. Patch OpenAI SDK:给 response.output 加空值保护python3 - <<'PY' p = Path("venv/lib/python3.11/site-packages/openai/lib/_parsing/_responses.py") old = "for output in response.output:" if new in src: 2. Patch Hermes transport:避免 tools=None 传进 SDKpython3 - <<'PY' p = Path("agent/transports/codex.py") old = ( new = ( if new in src: 3. 验证关键行grep -n "for output in (response.output or [])" grep -n '"tools": response_tools' agent/transports/codex.py || true |
|
Thank you @serejaris ! I applied this patch with 2 Hermes installs and I'm back up and running with Hermes on codex again. |
|
For the SDK-level root cause isolated here, I opened an upstream OpenAI Python SDK follow-up: The Hermes-side canonical fix in this PR recovers usable streamed output when the final Codex Responses parse hits Terminology note: this is the OpenAI Python SDK ( |
|
Non-blocking suggestion: it may be worth adding one regression for the post-SDK-fix path where The implementation already handles This should keep #32884 explicitly covered for the SDK-layer follow-up in openai/openai-python#3315. |
|
Added the regression in 21503a9: test_run_codex_stream_recovers_when_final_response_output_is_empty_after_deltas covers both output=None and output=[] after streamed text deltas when get_final_response() succeeds. Validation: scripts/run_tests.sh tests/run_agent/test_run_agent_codex_responses.py -- -q -> 73 passed. |
|
Closing as duplicate — the Codex null-output fix has been merged via #32963 (cherry-picked from @carltonawong's PR #32890, the one Gille reviewed). Thanks for jumping on the outage so quickly; appreciate the help. Closes #11179. |
What does this PR do?
Fixes a Codex Responses streaming crash where the ChatGPT Codex backend can emit valid streamed output and then trip openai-python final parsing with:
Observed repro shape:
openai-codex/gpt-5.5onhttps://chatgpt.com/backend-api/codexstreamedresponse.output_text.deltachunks spelling the expected answer, then openai-python raised while parsing a final response whoseoutputwas null.This PR preserves already-received streamed content instead of treating that SDK finalization failure as a fatal empty response. It handles both observed SDK failure points: during stream iteration and during
stream.get_final_response().Related Issue
Related to #21444, #19981, and #22986.
Type of Change
Changes Made
agent/codex_runtime.pyresponse.output_item.doneitems first.TypeErrorboth from stream iteration and fromstream.get_final_response().tests/run_agent/test_run_agent_codex_responses.pyHow to Test
Result in CT216 after the test follow-up commit:
73 tests passed.Result in CT216:
70 passed, 1 warning.hermes chat -Q --provider openai-codex -m gpt-5.5 -q "Reply exactly: LATEST_GPT55_FINAL_OK"Result in CT216 after the earlier code follow-up commit:
Stopped after confirming early progress because the full suite is 1205 files / 26435 tests in this CT. Progress before stop:
669 passed, 0 failed.Checklist
Code
fix(agent): ...)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — N/Acli-config.yaml.exampleif I added/changed config keys — N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — N/AScreenshots / Logs
Live validation output after the follow-up commit: