Repository navigation
feat(model): add the opencode_exec backend - #364
Open
Ivan Berlin (g0dm0d) wants to merge 1 commit into
Open
Ivan Berlin (g0dm0d) wants to merge 1 commit into
Ivan Berlin (g0dm0d) wants to merge 1 commit into
Conversation
…n exec target Run SkillOpt through the OpenCode CLI (2.x) with the user's existing OpenCode login. `--backend opencode` fills both roles; `--optimizer_backend opencode_exec` or `--target_backend opencode_exec` selects one. Aliases: `opencode`, `opencode_chat`, `opencode_cli`. Wired through common.py, backend_config.py, the dispatcher, config.py, train.py, eval_only.py and the trainer, per docs/guide/new-backend.md. Every call runs `opencode run --standalone --format json` with a private XDG config home: a global deny-all permission list plus only what the run needs, none of the user's MCP servers, and the OPENCODE_DISABLE_* switches so project AGENTS.md files and Claude Code rules and skills stay out. The data directory with the credentials is untouched. OpenCode 1.x is refused before any call. - Optimizer: text only, in an empty temporary directory, every tool denied. Tool calls through the message API raise NotImplementedError. - Target: runs in the task workspace with read tools. allow_file_edits adds the edit tool; a shell only with model.opencode_exec_allow_shell, since OpenCode has no OS sandbox. Outside the workspace only data_dirs and image directories are reachable. Tool steps go to opencode_trace_steps.txt. Checked against OpenCode 2.2.5: - the project directory comes from PWD, not the process cwd, so PWD is set for both roles; - a per-agent `permissions` list is dropped, so the global list is the gate; - a parent AGENTS.md up to the git root and the user's global skills reach the agent unless the switches are set and the skill tool is denied. Tests use a fake CLI replaying real 2.2.5 JSONL. Live smoke tests are opt-in with SKILLOPT_TEST_REAL_OPENCODE_EXEC=1. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Author
@microsoft-github-policy-service agree |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds OpenCode as a core SkillOpt backend,
opencode_exec, for the optimizer and as an exec target, alongside the existing codex/claude/cursor/copilot harnesses. It uses the user's existing OpenCode login, so any provider configured in OpenCode can run a full train/eval loop with no separate provider API key.--backend opencodeselects it for both roles;--optimizer_backendor--target_backend opencode_execselects one.OpenCode support so far lived only in SkillOpt-Sleep (#218). That backend targets OpenCode 1.x flags; this one targets OpenCode 2.x, which drops
--pure,--dirandOPENCODE_CONFIG_CONTENT.Changes
opencode_execwithopencode,opencode_chatandopencode_clialiases, wired throughcommon.py,backend_config.py, the model dispatcher,config.py,scripts/train.py,scripts/eval_only.pyand the traineropencode run --standalone --format jsonwith a privateXDG_CONFIG_HOME; the credentials stay in the user's data directorychat_optimizer_messages(..., tools=...)raisesNotImplementedErrorallow_file_editsadds the edit tooldata_dirsand image directories are reachable; tool steps are written toopencode_trace_steps.txtmodel.opencode_exec_pathandmodel.opencode_exec_allow_shell(blank ornullin the base config, soOPENCODE_EXEC_PATH/OPENCODE_EXEC_ALLOW_SHELLstay in control)Safety: every call starts from a global deny-all permission list and allows only what the run needs. Calls carry none of the user's MCP servers, global rules or skills, and the
OPENCODE_DISABLE_*switches keep projectAGENTS.mdand Claude Code files out. Unlikecodex_execandcursor_exec, OpenCode has no OS sandbox, so file-edit rollouts get no shell unlessopencode_exec_allow_shellis set explicitly.Checked against OpenCode 2.2.5:
PWD, not the process cwd. Without settingPWD, a target ran in the caller's directory and wrote its file there.permissionslist is dropped, so only the global list gates tools.AGENTS.mdup to the git root reached the agent, and with the skill tool enabled the user's global skills grew the system prompt from ~1.4k to ~13.6k tokens.Both roles now guard against all three, with regression tests.
Two caveats worth knowing before use: each call starts a private OpenCode server, which adds roughly 1–3 s; and ChatGPT logins reject some older model ids, for example
openai/gpt-5.5("not supported when using Codex with a ChatGPT account"), so setmodel.optimizer/model.targetexplicitly.Validation
python -m pytest tests/test_opencode_exec_backend.py tests/test_opencode_exec_target.py -q: 33 passed, with a fake CLI replaying real OpenCode 2.2.5 JSONLSKILLOPT_TEST_REAL_OPENCODE_EXEC=1 python -m pytest tests/test_opencode_exec_live.py -q: 4 passed on macOS with OpenCode 2.2.5 andopenai/gpt-6.1-solthrough a ChatGPT login. The tests check that:python -m pytest -qon Python 3.11 and 3.12: 2067 passed, 15 skipped and 2055 passed, 27 skippedpython -m pytest -qon Python 3.10: 2066 passed, 1 failed. The failure istest_officeqa_parallel_search.py::test_whole_mcp_request_has_a_deadline; it fails the same way on a cleanmainlocally and passes on its own.python -m mkdocs build --strict: passedruff check .: no new findings compared withmaingit diff --check: passedNot verified on Windows:
external_directorypatterns are built withos.path.join(dir, "*"), and I could not check how OpenCode matches backslash paths.Scope and follow-ups
This PR covers the core backend for both roles and does not change the SkillOpt-Sleep OpenCode backend.
Follow-up work:
opencode_trace_steps.txtinto reflection, likeREFLACT_CODEX_TRACE_TO_OPTIMIZERdoes for Codex