#3321·Archon

fix(providers/opencode): OpenCode workflow tool calls lose arguments after a pending event

Author: waewooCreated Sep 12, 2026Updated Sep 17, 2026
Labelsbug

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.md

But the corresponding Archon per-run JSONL transcript recorded empty input objects:

json
{"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:

  1. the workflow JSONL transcript as tool_input;
  2. the Web Console tool-call details; and
  3. any consumer of normalized MessageChunk events.

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 by running with 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_result events retain the original toolCallId correlation.
  • 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

  1. Run Archon v0.10.1 with an AI workflow node using opencode and google/gemini-3.6-flash.
  2. Have the node invoke tools such as read, glob, grep, or bash.
  3. Inspect ~/.archon/workspaces/<project>/logs/<runId>.jsonl.
  4. 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:

typescript
state: { status: "pending", input: {}, raw: "" }

OpenCode source

When the later tool-call event arrives, OpenCode updates that same call to running and supplies the real input.

OpenCode source

Archon's single-agent adapter emits the first tool event and immediately stores its callID in seenToolCalls; later updates for that call are ignored.

Archon single-agent adapter

The multi-agent adapter follows the same first-event-wins pattern using scoped IDs.

Archon multi-agent adapter

The existing test only covers a first pending event that already has input, so it cannot detect this lifecycle.

Current provider test

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.toolInput fixes the chain.