Repository navigation
Keep OpenCode worker model selection separate from the default - #24768
Conversation
Allow supervised OpenCode workers to use per-launch model overrides through the existing launch-preference and receipt path. Preserve existing OpenCode agent arguments while replacing only model flags, and reject unsupported effort values explicitly. Keep Native Chat option exposure unchanged and update the worker CLI and orchestration guidance.
Reuse captured composer readiness on local and paired execution hosts and revoke launching-shell paste anchors. Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
…apability Co-authored-by: user141514 <user141514@users.noreply.github.com>
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Reviewed the delta since the prior pullfrog review (7c765fdef3 → 255cc87769). The PR's authored layer over its declared base (8f950320e5) is byte-identical to the code approved at 7c765fdef3; this head is a merge that carries that layer onto a newer base/main and brings in the base branch's startup-prompt location binding.
- Authored model-selection layer unchanged —
opencode-launch-model-config.ts,opencode-launch-model-context.ts, andopencode-model-startup-plan.tsdiff to empty between7c765fdef3and255cc87769, so the per-launchOPENCODE_CONFIG_CONTENToverride, the authenticated loopback probe, and the version-gated startup plan are exactly what was approved before. - Startup-prompt readiness now tracks the composer location — the base's
opencode-startup-prompt-source.tsreplaces the one-shotctx.data.location.sync(ctx.location)at setup with a loop keyed on[directory, workspaceID]: it re-syncs when the home location changes and re-checks that identity before claiming and before submitting. A missing or rejectingsyncstill fails closed. - Base/main integration — the sync also pulls in upstream OpenCode overlay GC and codex/jcode work that was reviewed elsewhere.
87 focused tests pass at this head (1 opt-in skip).
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Reviewed the delta since the prior pullfrog review (255cc87769 → 9c6e50ab27). The new commits harden the model-catalog probe against incomplete output, refuse new-worktree OpenCode model selection with an explicit message, and align the docs.
- Refused incomplete catalogs —
probeOpenCodeModelAvailabilitynow also requires!result.outputTruncatedand a trailing newline before matching the requested model; new tests cover the truncated head, the captured unterminated shape, and complete\n/\r\ncatalogs. - Refused new-worktree model selection up front —
resolveWorkerLaunchPreferencesthrowscapability_unsupported("requires an existing worktree") whencreatesWorktreeand the agent isopencode, threaded through both local and federated start validation, with tests asserting the message and that no probe or effect runs. - Aligned the documentation — the CLI docs, bundled skill guide, and coordinator-loop reference now state OpenCode accepts a per-launch model only in an existing worktree.
ℹ️ The catalog-completeness guard is only reached on the legacy version path
The new outputTruncated / trailing-newline gate lives in probeOpenCodeModelAvailability, which the startup plan calls only inside isVerifiedOpenCodeLegacyModelVersion (1.18.30 / 1.18.32); 2.0.16 takes the probeOpenCodeLaunchModelContext /api/model path instead. The test that pins the unterminated shape labels it as captured from OpenCode 2.0.16, so the guard's actual target is the legacy versions — worth confirming their opencode models output also always ends with a newline, since the gate is fail-closed and would reject a complete catalog that lacks one.
Technical details
# Guard scope vs. evidence source
## Affected sites
- `src/main/opencode/opencode-model-startup-plan.ts:84` — `probeOpenCodeModelAvailability` is called only when `isVerifiedOpenCodeLegacyModelVersion` (1.18.30 / 1.18.32).
- `src/main/opencode/opencode-model-startup-plan.ts:90` — version 2.0.16 instead uses `probeOpenCodeLaunchModelContext`, so it never reaches the new trailing-newline check.
- `src/main/opencode/opencode-model-availability.test.ts:77` — the unterminated shape is labelled as captured from OpenCode 2.0.16.
- `src/main/opencode/opencode-model-availability.ts:52` — `!result.outputTruncated` covers stdout OR stderr overflow, so a >1 MiB stderr stream would also refuse a complete catalog.
## Required outcome
- Confirm the legacy `opencode models` output always ends with a newline, so the fail-closed `endsWith('\n')` gate cannot reject a complete legacy catalog.deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Important Review skippedReview was skipped as selected files did not have any reviewable changes. ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 2 remain after this review. 📝 WalkthroughWalkthroughThe changes add OpenCode launch-context parsing and an authenticated loopback probe. They add a configuration resolver that preserves existing fields while setting the requested model. Startup planning uses these helpers to support model preferences for OpenCode 2.0.16, while retaining the existing legacy-version path. Tests cover response validation, probe cleanup, configuration handling, and startup acceptance and refusal cases. Priority: ➖ Normal Merge Risk: ⚪ Minimal · up to The reviewed startup path preserves the requested model for launch and the default configuration for resume. No actionable merge-blocking issue remains. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to Per-launch choices remain separate from shared defaults, and temporary validation uses authenticated local access. The remaining risk is failure cleanup: descendant processes may outlive a refused launch after their parent exits. Retained concerns
Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Reviewed the delta since the prior pullfrog review (9c6e50ab27 → 3f4af3542b, 1 commit). The new head is a clean merge of current main (8e5080c132, the merged OpenCode worker model gate #24624); the PR's authored OpenCode layer is byte-identical to the version approved at 9c6e50ab27.
- Synced current main — merged
mainat8e5080c132. The merge is conflict-free (git show <merge> --cc --name-onlylists no combined-diff paths), so nothing was resolved by hand. - Authored layer preserved —
opencode-model-startup-plan.ts,opencode-launch-model-config.ts,opencode-launch-model-context.ts, and the fetch audit are unchanged between9c6e50ab27and the merge; the onlysrc/main/opencodedifference is main's ownhook-service.ts.git diff <main> HEADstill reduces to this PR's 8 authored files. - Focused tests pass — 33 tests across the four model files pass at this head (1 opt-in real-CLI skip).
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Reviewed the delta since the prior pullfrog review (3f4af3542b → f153666141, 1 commit). The new head is a clean merge of current main (d9846e64fe); the PR's authored OpenCode layer is byte-identical to the version approved at 9c6e50ab27, and all prior review threads are resolved.
- Synced current main — merged
mainatd9846e64fe. The merge is conflict-free (git show <merge> --cc --name-onlylists no resolved paths), andgit diff d9846e64fe..f153666141reduces exactly to this PR's 8 authored files, so the merge result is main plus the authored layer. - Authored layer preserved —
opencode-model-startup-plan.ts,opencode-launch-model-config.ts,opencode-launch-model-context.ts, and the fetch audit are unchanged between3f4af3542band the merge (git diffover the 8 authored files is empty). - Focused tests pass — 34 tests across the five authored test files pass at this head (1 opt-in real-CLI skip), confirming the main integration did not disturb the authored layer.
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

ELI5
An OpenCode worker uses its requested model, while ordinary launches keep the configured default.
What Changed
Extend #24624's validation for verified OpenCode 2.0.16. Resolve the default
opencodecommand from the launch environment, then keep the model override in that worker's private launch configuration. Preserve the original configuration for resume and reuse existing probe and process cleanup.Why
A private launch configuration keeps a worker's choice from affecting shared defaults. Reusing the command resolver and process ownership keeps validation and cleanup with the execution host.
Linked Issue
Part of #19980; builds on merged #24624. Preserves #22134 and credits @user141514.
Visual Proof
Actual model B, later default-model A turns, and supervised completion. The real OpenCode shell tool sent
worker_doneand delivered one coordinator message. Fresh and nested startup completed their Unicode prompts. This evidence is pinned to sourcec8fdfdbe.The shared catalog correction also passed four actual installed-CLI checks: an unfinished 262,144-byte catalog was accepted before repair and refused after, while the complete small catalog remained accepted.
Testing
Earlier feature qualification passed 172 focused tests with one existing skip, all three typechecks, lint, format, and quality checks; its later integration passed 61 tests and all three typechecks. Review corrections passed 102 targeted tests and all three typechecks. The final shared catalog correction passed 10 tests, Node typechecks for both PRs, and affected lint, format, and quality checks.
After the gate merged, the remaining model-selection change passed 34 focused tests with one existing skip across five files, plus affected lint, format, and quality checks. The integration preserves the reviewed model code and current main.
Actual testing used a controlled local provider on macOS. Live Windows, WSL, and SSH model selection was not exercised.
Review
Independently reviewed. Eight actual unsupported requests left terminals, workers, tasks, settings, and configuration unchanged. Recorded processes and private ports closed. Cross-platform and remote boundaries have automated coverage.
Agent skill upstream boundary
Notes
#22134 remains open until its complete replacement is merged. Linked model-isolation screenshots retain their original source identity. A final newline catches visibly incomplete catalog output; a cut exactly at a line boundary cannot be detected this way.
Checklist