fix(providers/opencode): OpenCode workflow tool calls lose arguments after a pending event
Problem
When a workflow AI node uses the opencode provider, Archon records tool calls but loses their arguments.
In the affected run, OpenCode itself knew the arguments:
evaluated permission=glob pattern=aidd_docs/**/*
evaluated permission=bash pattern="git status"
evaluated permission=read pattern=.codex/skills/aidd-dev-01-plan/SKILL.mdBut the corresponding Archon per-run JSONL transcript recorded empty input objects:
{"type":"tool","tool_name":"glob","tool_input":{}}
{"type":"tool","tool_name":"bash","tool_input":{}}
{"type":"tool","tool_name":"read","tool_input":{}}
{"type":"tool","tool_name":"grep","tool_input":{}}The Web Console receives that same empty object and consequently shows a visible tool row whose expanded details are empty.
This is upstream of transcript persistence and console rendering: logTool() persists the toolInput it receives, while the provider adapter omits it.
Why
The per-run transcript is intended to be an execution record. Empty inputs make it impossible to determine which file was read, glob matched, command ran, or pattern was searched.
The Console symptom is therefore not merely presentational. Operators and downstream debugging tooling lose the information at the provider boundary.
Desired outcome
For OpenCode workflow nodes, each normalized tool invocation retains its real input whenever OpenCode supplies one. The same input then reaches:
- the workflow JSONL transcript as
tool_input; - the Web Console tool-call details; and
- any consumer of normalized
MessageChunkevents.
Tool calls whose legitimate input is {} must remain supported, and later results must continue to correlate through toolCallId.
Acceptance
- A single-agent OpenCode event sequence beginning with
pending/input: {}and followed byrunningwith real input produces one normalized tool invocation containing that real input. - The resulting workflow JSONL row persists the same value in
tool_input. - The Console can display that value through its existing tool-call rendering path.
- Later updates do not introduce duplicate tool rows.
-
tool_resultevents retain the originaltoolCallIdcorrelation. - The multi-agent OpenCode path is covered or changed if it has the same defect.
- A tool whose real input is
{}remains representable.
Evidence
Reproduction
- Run Archon
v0.10.1with an AI workflow node usingopencodeandgoogle/gemini-3.6-flash. - Have the node invoke tools such as
read,glob,grep, orbash. - Inspect
~/.archon/workspaces/<project>/logs/<runId>.jsonl. - Compare its
tool_input: {}records with OpenCode's runtime log for the same run.
Affected example run: ce02d925-fd19-4053-88aa-cb057c937b68.
Confirmed event lifecycle
This is verified against OpenCode v1.18.30, not inferred from its log output.
OpenCode creates a tool part on the early input-start path with:
state: { status: "pending", input: {}, raw: "" }When the later tool-call event arrives, OpenCode updates that same call to running and supplies the real input.
Archon's single-agent adapter emits the first tool event and immediately stores its callID in seenToolCalls; later updates for that call are ignored.
The multi-agent adapter follows the same first-event-wins pattern using scoped IDs.
The existing test only covers a first pending event that already has input, so it cannot detect this lifecycle.
Environment
- Archon:
v0.10.1,linux-x64 - Database: SQLite
- OpenCode:
1.18.30 - Provider/model:
opencode/google/gemini-3.6-flash
Logs or screenshots
The affected JSONL transcript and matching OpenCode runtime-log excerpts are included above. They contain no credentials or tokens.
Constraints and related work
- Must remain true: preserve one tool row per call; preserve result correlation; support legitimately empty inputs.
- Known prerequisites or blockers: none identified.
- Related issues or PRs: #2614 makes transcripts discoverable, but does not repair their contents. #2396 added tool-call correlation IDs, but does not preserve omitted inputs. #1909 concerns provider-agnostic node attribution in the Console, not tool-input loss. #1916 only capped the display height of tool input.
- Solution steering: Hint — preserve the latest meaningful tool input at the OpenCode provider boundary. Do not change transcript or Console consumers if correcting normalized
MessageChunk.toolInputfixes the chain.
Source: coleam00/Archon