Repository navigation
[bug] A workflow step on OpenCode does not run as its agent #1193
Description
Description
A local workflow step with agent: on OpenCode launches opencode run --format json <prompt> --agent <name>. Neither OpenCode major runs the definition that teamai pull deploys for that agent:
- OpenCode 1 replaces it with the default agent. Pull writes every OpenCode agent with
mode: subagent, unlesstool_extras.opencode.modesets another mode.opencode run --agentdoes not run a subagent. It prints! agent "reviewer" is a subagent, not a primary agent. Falling back to default agent. The step then runs without the definition's prompt, model, or variant. - OpenCode 2 applies the prompt but not the file's
model:orvariant:. The step runs on the configured default model at its default effort.
The step still counts as run by the definition. The driver reports the file's model as the step's model when the tool reports none. On #1184, the record would also say agent.definition.applied: main, with the file's model as agent.model.requested.
Reproduction
The project's opencode.json sets "model": "anthropic/claude-haiku-4-5" as the default. It also points provider.anthropic.options.baseURL at a local server, which logs each request body. The agent file is the one pull deploys for an agent with model: strong, where strong maps OpenCode to { model: anthropic/claude-sonnet-4-5, effort: high }. A marker is appended to its prompt.
---
description: Reviews a change and answers with a JSON verdict.
mode: subagent
model: anthropic/claude-sonnet-4-5
variant: high
---
You review changes. Never edit files. PROBE-MARKER
Each run is opencode run --format json <flags> hi, and OpenCode 2 also gets --standalone. The table shows the request that carries the message. Each run also sends a title request on a small model.
| OpenCode | Flags | Model sent | Thinking | Agent prompt sent |
|---|---|---|---|---|
| 1.18.23 | --agent reviewer |
claude-haiku-4-5 | none | no |
| 1.18.23 | --agent reviewer --model anthropic/claude-sonnet-4-5 |
claude-sonnet-4-5 | none | no |
1.18.23, the same file with mode: all |
--agent reviewer |
claude-sonnet-4-5 | enabled, 16000 | yes |
1.18.23, the same file with mode: all |
--agent reviewer --model anthropic/claude-sonnet-4-5 |
claude-sonnet-4-5 | enabled, 16000 | yes |
2.0.30, mode: subagent or mode: all |
--agent reviewer |
claude-haiku-4-5 | none | yes |
2.0.30, mode: subagent or mode: all |
--agent reviewer --model anthropic/claude-sonnet-4-5 |
claude-sonnet-4-5 | none | yes |
| 1.18.23, no agent | --model anthropic/claude-sonnet-4-5 --variant high |
claude-sonnet-4-5 | enabled, 16000 | n/a |
| 2.0.30, no agent | --model anthropic/claude-sonnet-4-5#high |
claude-sonnet-4-5 | enabled, 16000 | n/a |
The last two rows are controls. They show that each version sends the high variant when it applies it.
Environment
- OS: macOS 27.0
- Node.js: v24.21.0
- teamai: 0.22.0, main at fe3b906
- Provider: git
- AI tool(s): OpenCode 1.18.23 (the pinned devDependency) and OpenCode 2.0.30
Notes
- I don't know why OpenCode 2 ignores the file's
model:andvariant:. Itsrun --helptakes a variant only inside--model provider/model#variant. - Not measured: whether an interactive OpenCode session, which starts these agents as subagents, applies their model and variant.
- A possible fix is to launch OpenCode with the definition's model and variant on argv, as the Codex launch already passes the definition's model:
--model m --variant von 1 and--model m#von 2. OpenCode 1 also needs the definition to run at all. That could mean a primary-capable mode for the agents a workflow runs, or the instructions in the prompt, as Codex gets them. - feat(workflow): let a prompt step choose its model (#1177) #1192 (for [feat] Let a workflow choose the model of its prompt steps #1177) fails a step whose
modelis its agent's own model with no effort, while the agent file setsvariantand a mode other thansubagent. That is the one case where OpenCode 1 brings the agent's variant back. A fix here should revisit that check. OpenCode 2 never brings the variant back.
Activity
fix(workflow): record no definition handoff or file model for an Open…
SaulMoro commentedon Oct 16, 2026
#1184 no longer records what this issue describes. On OpenCode, a pass records only the definition's name, with no
appliedand no model taken from the file. The step's flatmodelis the model the tool reported, or none, so the file's model is no longer used as a fallback. A real run on OpenCode 1.18.23 shows the entry before and after.The fix for this issue goes into #1192, which will close it. Once OpenCode runs the definition, the record can say how again. That is
promptwhen the instructions are prepended, andmainwhen--agentapplies. The requested model and effort come from what the launch passes on argv. Whichever of #1184 and #1192 merges second wires that in.kittimzhe commentedon Oct 17, 2026
Taking this — with the mechanism verified on both ends before proposing a shape.
Reproduced the OpenCode 1 half against the pinned devDependency (1.18.23), with the agent file exactly as
pulldeploys it (mode: subagent, mapped model, marker in the prompt):Both ends are in the repo, and they disagree about what a workflow step means:
renderForOpencodewritesmode: 'subagent'for every OpenCode agent (resources/agent-format.ts:439), documented as deliberate ("teamai only syncs subagents"), overridable viatool_extras.opencode.mode.['run', '--format', 'json', prompt, '--agent', name]and nothing else (workflow/local-tool-adapter.ts:79) — the codex family in the same function passes--modelwhen the step's agent maps one, the OpenCode family never does, so even the explicit---modelescape the report's table proves honored never happens.Proposed split:
--model. Per the table, OpenCode 1 honors the flag (even in fallback), OpenCode 2 honorsprov#variant— so the variant rides inside the model flag for 2 and as--variantfor 1. The driver needs to know which shape to emit; I'd probe once per run unless there's a preferred existing version gate.mode: subagentis pull's documented decision, and the fallback means the definition's prompt never runs on OpenCode 1 either. Flipping the write toallchanges the interactive agent picker for everyone, so I don't want to pick unilaterally: keepsubagent+ documenttool_extras.opencode.mode: allas the workflow escape (mechanism already exists), or write a primary-mode copy for workflow-destined agents?I'll start with the model half — red test first against the pinned devDependency — and the mode half follows whichever you call.
SaulMoro commentedon Oct 17, 2026
Thanks for picking this up, and for the careful repro. This is already fixed in #1192, which closes this issue. It is open with CI green and waiting for review, so please don't spend time on a separate fix.
What #1192 does, against both halves of your split:
modelwhen the step sets one. That is--model M --variant Von OpenCode 1 and--model M#Von OpenCode 2. The version comes from the existingopencodeMajorVersion, asked of the executable the step actually launches and cached per path.mode: subagent. On OpenCode 1, a subagent step gets the agent's instructions in the prompt with no--agent, as Codex does, and a warning names the file settings that then don't apply, such aspermission.tool_extras.opencode.mode: allstill runs through--agent. OpenCode 2 runs every agent through--agent.The PR body has the request bodies from real OpenCode 1.18.23 and 2.0.30 runs. A review of #1192 would be very welcome, especially on the mode-half choice.
feat(workflow): record the agent each step pass ran as (#1184)