Bug: Web UI multi-turn sessions drop reasoning blocks — 400 "reasoning_text must be passed back" (openai-responses custom provider) #231
hiro-nikaitou
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Bug: Web UI multi-turn sessions drop reasoning blocks — multi-turn requests fail with 400 "The
reasoning_textin the thinking mode must be passed back to the API"dsh 0.1.0-rc.6 (npm global), Node 22, Windows. Custom provider configured as
openai-responsesagainst an OpenAI-compatible gateway (OpenCode Go, baseURL.../v1). Models are hand-declared (noreasoningEffortsfield).Symptom
OpenAI API error (400): invalid_request_error: Error from provider (Console Go): Upstream request failed: [invalid_request_error] Thereasoning_textin the thinking mode must be passed back to the API.dsh --profile headlessworks, including tool-call turns.Evidence that the gateway and pi-ai are NOT at fault
response.output_item.added(item typereasoning), 35×response.reasoning_text.delta,response.output_item.done, andresponse.completedusage includesoutput_tokens_details.reasoning_tokens. Also returns reasoning in non-streaming mode.streamSimple,openai-responses) yieldthinking_start → thinking_delta… → thinking_endfor: single-turn, multi-turn, with tools, withoutreasoningEffort, and withreasoning: "max". The model (deepseek-v4-pro) even produces thinking with no effort param and no tools.session.jsonl.zstdcontainsreasoning-chunksstorage rows,assistant/messagecontent includes{"type": "reasoning", "text": …}blocks, andsource.replayState.blocksincludes thereasoningsignature.assistant/messagerecords havecontentwith onlytext/tool-callblocks,reasoning-chunksrows = 0, andreplayState.blockshas noreasoningentry. (Verified in the raw.zstdlog, not just the export.)Mechanism
Because the reasoning block (and its
thinkingSignature) never reaches the message layer in Web UI sessions, the multi-turn conversion (replayedAssistant/ pi-aiconvertResponsesMessages) has nothing to pass back —reasoning_textis absent from the next request, and the gateway rejects it.Direct reproduction of the mechanism with pi-ai: multi-turn request without the previous reasoning item passed back → request fails; with the reasoning item → succeeds.
Suggested focus
Web UI session path vs headless path diverge somewhere between the adapter stream and the persisted
assistant/message— headless persists reasoning blocks, Web UI does not, on the same build.Related: #199 (adapter drops thinking for vLLM
delta.reasoningformat — same family, different wire shape).All reactions