Uh oh!
There was an error while loading. Please reload this page.
feat: enable tool-input-delta streaming in processor - #14945
Conversation
Wire up the tool-input-delta and tool-input-start handlers in the session processor to stream tool call arguments to clients in real-time. Previously, tool-input-delta events from the AI SDK were silently discarded (break with no logic). This meant clients had to wait for the complete tool-call event before showing any tool arguments. Changes: - tool-input-start: resolve toolCallId via value.toolCallId ?? value.id to handle both fullStream field naming conventions - tool-input-delta: accumulate streaming text into state.raw and publish PartDelta events using the existing updatePartDelta infrastructure (same pattern as text-delta streaming) This enables frontends to show tool arguments (file paths, commands, search queries, etc.) as they stream in from the LLM, providing much better UX for long tool calls. Requires the fine-grained-tool-streaming beta header which is already set in provider.ts.
This PR doesn't fully meet our contributing guidelines and PR template. What needs to be fixed:
Please edit this PR description to address the above within 2 hours, or it will be automatically closed. If you believe this was flagged incorrectly, please let a maintainer know. |
The following comment was made by an LLM, it may be inaccurate: Based on my search, I found two potentially related PRs:
These should be reviewed to ensure there's no duplicate work or conflicting implementations around tool argument streaming. |
Enable real-time streaming of tool call arguments from the LLM to the frontend, so users see file paths, commands, and search queries as they are being generated — not after the full JSON is parsed. Backend (binary patch): - patch-opencode-streaming.js: binary find-and-replace on the compiled Bun binary to wire up tool-input-start (toolCallId resolution) and tool-input-delta (accumulate raw text + publish PartDelta events) - Runs during Docker build (Dockerfile), bun install (postinstall), and live updates (postinstall.sh). Idempotent and version-safe. Frontend (tool-renderers.tsx): - parsePartialJSON(): robust partial JSON parser (try full parse, try closing braces, regex key extraction fallback) - partStreamingInput(): returns parsed input from state.raw during pending state - Updated 6 tool renderers: Bash, Edit, Write, Read, Glob, Grep Infrastructure: - next.config.ts: /v1 rewrite proxy for local dev CORS - Removed dev overlay (docker-compose.dev.yml, dev/) — no longer needed now that the patch is baked into the default build Upstream PR: anomalyco/opencode#14945
Summary
Enable real-time streaming of tool call arguments to clients by wiring up the previously no-op
tool-input-deltahandler in the session processor.Problem
The
tool-input-deltaevents from the AI SDK (backed by Anthropic'sfine-grained-tool-streamingbeta header, which is already set inprovider.ts) were being silently discarded:This forced clients to wait for the complete
tool-callevent before showing any tool arguments — creating a noticeable lag for tools with large inputs (file writes, long commands, etc.).Solution
tool-input-start: ResolvetoolCallIdviavalue.toolCallId ?? value.idto handle bothfullStreamfield naming conventions from the AI SDKtool-input-delta: Accumulate streaming argument text intostate.rawand publishPartDeltaevents using the existingupdatePartDeltainfrastructure (same pattern astext-deltastreaming)The
rawfield onToolStatePendingalready exists in the schema (message-v2.ts:265) — it was always initialized to""but never populated.How it works
Frontend impact
Frontends can now use
part.state.raw(duringstatus: "pending") to parse and display partial tool arguments as they stream in. Thedeltafield on PartDelta events allows efficient incremental updates.Changes
packages/opencode/src/session/processor.ts— Wire uptool-input-start(toolCallId resolution) andtool-input-delta(accumulate raw + publish PartDelta)No schema changes needed — the
rawfield andPartDeltaevent infrastructure already exist.