A thread-backed turn shows no reasoning and can call no tool #164
- AtlantisPleb opened this issue 3d ago
-
A Author 2d ago Server half landed on main as c26c188 (pushed, WAL receipt to follow this push; full mix precommit green: 4172 tests, 0 failures). Root causes and fixes:
- ProviderEvent gains a reasoning_delta member; the OpenRouter decoder emits it from delta.reasoning (the live ox-alpha coder path was silently discarding it) and the OpenAI decoder from response.reasoning_*_text.delta.
- The proxy now emits reasoning as choices[0].delta.reasoning (whole, since the proxy still buffers the SSE body), keeps assistant tool_calls on replayed history (previously dropped when content was empty), and both adapters replay faithful transcripts: OpenRouter as assistant tool_calls + role:"tool" messages, OpenAI as interleaved function_call/function_call_output items.
- Conversation lane verified unchanged (reasoning is a no-op in turn_server/job_server; persisted messages carry no reasoning). PROVIDER-001 prose updated in INVARIANTS.md.
Remaining half is CLI-side and is filed as OpenAgentsInc/openagents#31: parse delta.reasoning into the coder's reasoning entries and switch the client tool loop to faithful tool_calls replay instead of plain-turn feedback. This issue stays open until the coder session visibly shows both.
-
A Author 2d ago Both halves are now on main: the server half as c26c188 (reasoning member, faithful tool replay) and the CLI half as OpenAgentsInc/openagents cf1861c9cb (delta.reasoning parsed and rendered, faithful tool_calls history). The outcome is delivered in code end to end with tests on both sides. This issue can close once the deployed forge serves c26c188 or later (see #187 for the main-versus-deployed gap) and a coder session against production visibly shows reasoning and tool calls.
-
A Author 2d ago Fixed on main and proven live. OpenAgents.Providers.ProviderEvent carries a :reasoning_delta member, and a thread-lane turn streams it — probed against the dev server just now with a reasoning-inducing prompt on ox-alpha: 58 reasoning deltas over the thread grant.
The tool half is proven at scale rather than by inspection: tonight's whole delegation fleet ran on the thread lane, and those sessions read files, ran shell commands, and called their delegate tool throughout. A thread-backed session shows reasoning and calls tools, as the conversation-backed one did.
Production still has to deploy main for this to be true there — #187.
- closed this as completed 2d ago
Outcome
A thread-backed coder session shows the model's reasoning and its tool calls, as the conversation-backed one did.
Current behavior
5f36e4c839movedopenagents coderonto its own thread, which is what stops a terminal prompt from landing in the account's one conversation. Two things did not survive the move, and both were asked for explicitly.Reasoning is gone.
OpenAgents.Providers.ProviderEventhas no reasoning member. Its union is:lib/openagents_web/controllers/inference_proxy_controller.exdrops what it cannot name, so a grant-backed caller receives text and nothing else. Thereasoning_deltathe chat path emitted came fromOpenAgents.Chat.OpenRouterand the Gemini decoder — a different stack that the proxy does not use. The dim-italic reasoning entry the CLI renders now appears only under--offline.Tool calls do not occur. The chat lane executed tools server-side. The proxy is a bare completions surface that forwards whatever
toolsa caller declares; the CLI declares none and holds no runtime to execute them, so the mapping never fires.ProviderEventdoes carrytool_call, so the wire supports it — nothing produces one on this path.Neither is a defect in the CLI. Both live in
OpenAgents.Providersand the proxy.Why this matters more than it looks
The reasoning display was built deliberately. In a captured live turn, 163 reasoning deltas arrived against 234 text deltas — a large share of what a turn produces. Without it, a turn that thinks for twenty seconds shows an elapsed clock and nothing else, which is the exact complaint that produced the reasoning work in the first place.
Tool calls are the difference between a chat window and a coding agent. Their absence also removes the evidence a reader needs to understand a reply: two sentences either side of an invisible tool call read as one confused sentence, which is what the tool-call rendering was built to fix.
Work
ProviderEventand carry it through the proxy. The providers already parse reasoning —OpenAgents.Chat.OpenRouter.ResponsesStreamDecodersplits it, and the Gemini adapter reads parts flaggedthought: true(5375462). The gap is the neutral union in the middle, not the providers at either end.docs/2026-08-23-agent-tools-zero-base.md) and the reach work inTOOL-005both bear on this, and the answer should be consistent with them rather than a third mechanism.ReplyChunkin the CLI unchanged. It already carriestext | reasoning | tool_call | tool_result, and the interface renders all four today under--offline.Acceptance criteria
--offlinebehavior is unchanged.Verification
A proxy test asserting a reasoning event survives translation; an end-to-end thread turn showing reasoning in the terminal; a tool call executed and rendered;
mix precommitand the CLI'spnpm run verify.Dependencies
Follows #163 (
5f36e4c839). Audit stage 4 — chunked delivery, since the proxy currently builds the whole SSE body and sends it once — is independent but related: reasoning that arrives in one buffered frame is not the same feature as reasoning that streams.