Repository navigation
feat(workflow): let a prompt step choose its model (#1177) - #1192
Conversation
Testing documentation is sufficient: the description records representative real-CLI runs on this branch, including Claude model/default selection. The explicitly deferred provider and agent coverage is not blocking. No PR code was run, built, or installed. |
…unches The version probe ran `opencode --version` from the process PATH, while the launch resolves opencode through a login shell first. When the two found different installs, the step got the other version's effort form and OpenCode rejected it. Resolve the executable first and probe that path, cached per path.
…when the agent is not a subagent opencode run --agent runs the default agent in place of a subagent, so a subagent's variant never comes back. teamai writes every OpenCode agent as a subagent unless tool_extras.opencode sets mode, so the refusal fired on launches that run as the step asks.
The earlier executable-probe finding is resolved: the adapter resolves the executable first and caches its version by path. Testing documentation is sufficient; representative real-CLI runs are recorded, and additional coverage is explicitly deferred. No PR code was run, built, or installed. |
OpenCode 2 reads neither the model nor the variant from the agent file, and OpenCode 1 does not start a subagent under opencode run --agent, which is how pull deploys every OpenCode agent. The launch now passes the definition's model and variant on argv, and on OpenCode 1 hands a subagent its instructions in the prompt, warning about the file settings that then do not apply. OpenCode 2 warns about a variant it cannot take, one set with no model. The own-model refusal moves into the adapter, which knows the launched version: only OpenCode 1 on --agent brings the file's variant back. Every tool now starts with stdin ignored. OpenCode 1 and 2 wait for the end of a piped stdin, so every OpenCode step hung.
|
Fixed in d09263d. The check moved from |
|
No new findings in the specified PR diff. Both earlier findings are resolved:
Testing documentation is sufficient: the description records representative real-CLI runs, including runs on the current head. Explicitly deferred provider and agent coverage is not blocking. No PR code was run, built, or installed. |
Resolve the overlap with Tencent#1184. The observation now records the model and effort the launch passes on argv. The alias comes from chooseStepModel when the step or defaults.model chose the model, and from the pull record when the definition did. The adapter reports the OpenCode handoff it used.
|
No new findings in the specified PR diff. Both earlier findings are resolved:
Testing documentation is sufficient: the description records representative real-CLI verification. Older tested commits are a note, not blocking; explicitly deferred provider and agent coverage is also not blocking. No PR code was run, built, or installed. |
|
No new findings in the specified PR diff. Both earlier findings are resolved:
Testing documentation is sufficient: the description records representative real-CLI verification, including Claude default-model selection on the current head. Older OpenCode test records and explicitly deferred provider/agent coverage are not blocking. No PR code was run, built, or installed. |
Summary
Closes #1177.
Closes #1193.
A prompt step can set
model, and a workflow file can setdefaults.model. Each takes an alias frommodels/aliases.yamlor a model name. The lease carries both as written, and the local driver resolves them with the member's aliases for the step's tool.A workflow step with
agent:on OpenCode now runs as its agent on OpenCode 1 and 2 (#1193). Before, it hung on both, and once started it would not have run as the definition.On Claude and Codex, a step whose model comes from its definition, or from nothing, launches with the same arguments as before.
Calls the issues left open:
${{. Templates here are{{ … }}, and${{ … }}in prompt text stays literal. Pull rejects any{{inmodel, which covers both.--agent. Claude Code 2.1.301 sends the--modeland--effortit is given over the agent file's, and never sends the file'seffort:under--agent. I read the request bodies through a localANTHROPIC_BASE_URL: an agent file witheffort: maxand--effort lowsentlow; with no--effortit sent the model's default, as a file with no effort does. So Claude needs nomodel_unavailableforagentwithmodel, and an alias with no effort runs at Claude's default effort.--variant. OpenCode 2 has none, rejects it (Unrecognized flag: --variant), and reads the effort from--model provider/model#variant. The adapter resolves the executable it will launch and asks that path for its version (opencodeMajorVersion(path), the probe pull and doctor already use, now cached per path). Then it picks the form.modelreplaces them.mode: subagentagent underopencode run --agent, and pull writes every OpenCode agent that way. So on OpenCode 1 a subagent gets its instructions in the prompt, as Codex does, with no--agent. A warning names the file settings that then do not apply, such aspermission.mode: allwould put every team agent into the primary agent cycle of every member's interactive OpenCode.--agentapplies the file'svariantto a launch on the agent's own model that passes none. So that step, with no effort, fails withmodel_unavailablebefore launch. Only the adapter knows the launched version, so the check runs there. OpenCode 2 never applies the file's variant, and the OpenCode 1 prompt route does not read it.~ordefault, andteamai models switch. Each gives the tool no model, so each fails withmodel_unavailableand a message of its own.Evidence
Before (main, real CLI):
teamai pullrefuses the workflow.After, criterion 9 (real CLI, Claude 2.1.301, a build of b0a73d5). The deployed
reviewer.mdhasmodel: haiku.models/aliases.yamlmapsstrongtoclaude: { model: sonnet, effort: low }. Stepreviewhasagent: reviewerandmodel: strong.teamai pull, thenteamai workflow start review --driver local. The launch:The
initevent has"model":"claude-sonnet-5-5". Thereviewentry onteamai-reports:{ "step": "review", "pass": 1, "agent": { "v": 1, "definition": { "name": "reviewer", "applied": "main" }, "tool": { "name": "claude", "version": "2.1.301" }, "model": { "requested": "sonnet", "reported": "claude-sonnet-5-5", "alias": "strong" }, "effort": { "requested": "low" }, "team": { "revision": "094af633eff84f054c6854c1957310f04f4f1f24", "localChanges": false }, "project": { "commit": "094af633eff84f054c6854c1957310f04f4f1f24", "dirty": false }, "teamai": "0.22.0", "driver": "local", "fingerprint": "635e56a38a3612488545dac0aab01f1d9c6e5e31944b46e10773fa6071a5bd9e" }, "tool": "claude", "model": "claude-sonnet-5-5", "outcome": "success", "tokens": { "input": 2, "output": 81, "cachedInput": 0 } }The result event's
modelUsagekeysclaude-haiku-5-5andclaude-sonnet-5-5, which is why the reported model comes frominit.Criterion 10, real CLI with Claude (d376feb). The workflow sets
defaults: { model: strong }. Stepplainhas no agent, and stepreviewrunsreviewer, whose file hasmodel: haiku. The launches:The entries on
teamai-reports:reviewruns on its file's model, so it carries nostrong, althoughdefaults.modelis set for it.[bug] A workflow step on OpenCode does not run as its agent #1193, real CLI on OpenCode 1.18.23 and 2.0.30. The team agent
reviewerhasmodel: strong, an alias toopencode: { model: anthropic/claude-sonnet-4-5, effort: high }, andtool_extras.opencode.permission. A marker is in its instructions. The deployed.opencode/agents/reviewer.mdhasmode: subagent,model: anthropic/claude-sonnet-4-5,variant: high, andpermission. The step hasagent: reviewerand nomodel. OpenCode'santhropicprovider points at a local server that logs each request body. Its config default model isanthropic/claude-haiku-4-5.--agent reviewer--agent reviewer--model anthropic/claude-sonnet-4-5 --variant high--agent reviewer --model anthropic/claude-sonnet-4-5#highOn OpenCode 1 the driver warned:
Agent "reviewer" runs on opencode 1 from the prompt, since opencode run does not start a subagent there, so it does not apply permission from the deployed agent file. The step is not blocked.The steps then fail withtool_failed, because the server answers each request with an error. On its first run, OpenCode 1 installednode_modulesandpackage*.jsoninto the fresh.opencode/. It also wrote a.gitignorethere that ignores them and itself, so the read-only check did not trip.With a definition that sets
variant: highand no model, OpenCode 2.0.30 on d09263d launched--agent reviewerand sent the config default, haiku-4-5, with the agent prompt. The driver warned:Agent "reviewer" sets a variant with no model, and opencode 2 takes a variant only with a model, so it does not apply variant from the deployed agent file. The step is not blocked.OpenCode version of the launched path, real CLI (OpenCode 2.0.30, no login). The process
PATHfinds OpenCode 1.18.23 first, and the login shell the launch resolves through finds OpenCode 2.0.30. A step withmodel: mid(opencode: { model: anthropic/claude-sonnet-4-5, effort: low }):Tests. Criteria 1 and 2 in
workflow-parse.test.tsandworkflow-cache.test.ts. Criteria 3 to 8 and 10, and the OpenCode launches for both majors, inworkflow-local-driver.test.ts. They run through the real adapter and an executable that answers--version, reads stdin to its end, and writes its argv to a file. The leases through the scope chain inworkflow-engine.test.ts, and a conformance scenario formodelanddefaultModel.The run record fields:
workflow-local-driver.test.ts("the agent a local pass ran as") covers the alias ofdefaults.modelonly for a step it chose, and an OpenCode pass with the handoff its launch used. The per-major OpenCode test assertsappliedfrom the real adapter.On d376feb,
npx vitest runpasses 465 files and 10985 tests.npm run test:e2epasses 28 tests on the e2e files with a fake tool or the OpenCode version probe:workflow-prompt,workflow-conformance,workflow-records-reports-branch-1083, andopencode-versions-915.npx tsc --noEmitandnpm run lintexit 0. The OpenCode runs above are on d09263d, before the merge, which changed no OpenCode argv. The criterion 9 run is on b0a73d5. The criterion 10 run, repeated on d376feb, published the same entries.Not covered locally. A real Codex run, an OpenCode step that completes against a real provider, and the
gitlabandgithubproviders. Left to CI.Known limits:
permissionortemperature. The warning names them.variantand no model gets no variant on the command line, since OpenCode 2 takes one only inside--model. OpenCode 2 and the OpenCode 1 prompt route then warn about it.--variantit gets, a definition's included, and the step fails withtool_failed.-reaches the tool's argv as its own token, after--model. OpenCode would read it as a flag. Only the team repo and the member's own aliases file set these values.~ordefault), the deployed agent file has no model, sodefaults.modelapplies to that step, as for any definition that sets no model for the tool.model: inheritcounts as a definition that sets a model, sodefaults.modeldoes not apply to it.model_reasoning_effortwhen the step's effort replaces it.With #1175
#1175 also edits
promptReportand the Claude and Codex launch arguments. Whichever merges second resolves the overlap.Merge Danger
Door: two-way.
Workflows that use neither key lease and launch as before on Claude and Codex. An OpenCode step with an agent now passes the definition's model and variant, and on OpenCode 1 a subagent runs from the prompt. Before, those steps hung. An older teamai refuses a workflow file that uses
modelordefaultsat pull, as it does any key it does not know.Blast Radius: workflows.