Summary
When using the OpenAI Codex OAuth provider against the ChatGPT backend (https://chatgpt.com/backend-api/codex), assistant responses come back empty. I see picoclaw's "The model returned an empty response. This may indicate a provider error or token limit." fallback even when the model actually produced output.
Environment
- picoclaw v0.2.7 (launcher image
sipeed/picoclaw:launcher)
- ChatGPT Business plan, OAuth login through the launcher
- Tried
openai/gpt-5.4, openai/gpt-5.3-codex — same symptom
- Reproduces on every prompt, including a one-word
test
Path to discovery
- First suspect was
split_on_marker: true (à la Qwen <think> parsing). Setting it false had no effect.
- Enabled
log_level: debug. Gateway log showed prompt_tokens: 7637, completion_tokens: 95, content_chars: 0, tool_calls: 0 — HTTP 200 with billed tokens but nothing visible.
- Patched
parseResponse in pkg/providers/openai_responses_common to dump the raw responses.Response. Result: output: [], status: "completed", output_tokens: 95, reasoning.effort: "none". No items at all in the final response.
- Patched
CodexProvider.Chat to log every stream event type. Real items DID arrive — response.output_item.added, multiple response.output_text.delta chunks with actual text, response.output_text.done, then response.output_item.done with the completed item — followed by response.completed carrying an empty output array.
Root cause
The ChatGPT Codex backend streams completed items via response.output_item.done events, but its terminal response.completed event ships a Response with an empty Output slice. The current code only captures evt.Response from the completed/failed/incomplete events, so the streamed items are dropped on the floor.
Fix
#2581 (by @astrada-c) does exactly the right thing: accumulate items from response.output_item.done events and graft them onto the completed Response when its Output is empty. Includes regression tests and a fallback-fired warning log. Filing this issue so there's a single place for other affected users to gather; please consider prioritizing #2581.
Summary
When using the OpenAI Codex OAuth provider against the ChatGPT backend (
https://chatgpt.com/backend-api/codex), assistant responses come back empty. I see picoclaw's"The model returned an empty response. This may indicate a provider error or token limit."fallback even when the model actually produced output.Environment
sipeed/picoclaw:launcher)openai/gpt-5.4,openai/gpt-5.3-codex— same symptomtestPath to discovery
split_on_marker: true(à la Qwen<think>parsing). Setting itfalsehad no effect.log_level: debug. Gateway log showedprompt_tokens: 7637, completion_tokens: 95, content_chars: 0, tool_calls: 0— HTTP 200 with billed tokens but nothing visible.parseResponseinpkg/providers/openai_responses_commonto dump the rawresponses.Response. Result:output: [],status: "completed",output_tokens: 95,reasoning.effort: "none". No items at all in the final response.CodexProvider.Chatto log every stream event type. Real items DID arrive —response.output_item.added, multipleresponse.output_text.deltachunks with actual text,response.output_text.done, thenresponse.output_item.donewith the completed item — followed byresponse.completedcarrying an emptyoutputarray.Root cause
The ChatGPT Codex backend streams completed items via
response.output_item.doneevents, but its terminalresponse.completedevent ships aResponsewith an emptyOutputslice. The current code only capturesevt.Responsefrom the completed/failed/incomplete events, so the streamed items are dropped on the floor.Fix
#2581 (by @astrada-c) does exactly the right thing: accumulate items from
response.output_item.doneevents and graft them onto the completedResponsewhen itsOutputis empty. Includes regression tests and a fallback-fired warning log. Filing this issue so there's a single place for other affected users to gather; please consider prioritizing #2581.