mirror of
https://github.com/0xrsydn/idx-cli.git
synced 2026-11-07 09:45:36 +00:00
test(agents): run opencode 2 as well as opencode 1
opencode 2 (@opencode/cli) moved MCP servers to `mcp.servers`, turns Code Mode on by default, replaced `permission` with ordered `permissions` rules, and dropped `run --pure` for `--standalone` (runs otherwise go through a shared background service). Pick the config and flag from `opencode --version`. Its `execute` tool stays allowed: with it denied, opencode 2.0.30 never offers the idx tools to the model in `opencode run`, though the server connects before the first step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V3syn2fN2LNo5pvTSqc6eh
This commit is contained in:
parent
855ec0cdc3
commit
1049ff3155
2 changed files with 37 additions and 11 deletions
|
|
@ -106,9 +106,14 @@ each run keeps a copy next to its output as `<case>.<run>.mcp-stderr`.
|
||||||
output but still deletes every copied agent config.
|
output but still deletes every copied agent config.
|
||||||
- Tools are auto-approved for the run (Claude `dontAsk` with
|
- Tools are auto-approved for the run (Claude `dontAsk` with
|
||||||
`mcp__idx__*`, Codex `default_tools_approval_mode="approve"`); Claude and pi
|
`mcp__idx__*`, Codex `default_tools_approval_mode="approve"`); Claude and pi
|
||||||
also get no built-in tools, Hermes only the `idx` toolset, and opencode a
|
also get no built-in tools, Hermes only the `idx` toolset, and opencode
|
||||||
permission that denies everything but `idx_*`, so they can only answer
|
permissions that deny its shell, file, and web tools, so they can only
|
||||||
through MCP.
|
answer through MCP.
|
||||||
|
- opencode 1 (`opencode-ai`) and 2 (`@opencode/cli`) are both supported; the
|
||||||
|
harness reads `opencode --version` and writes the matching config. Version
|
||||||
|
2 runs with `--standalone`, off the shared background service. A wrapper
|
||||||
|
that pins `XDG_*` paths (such as a Nix `opencode2` wrapper) defeats the
|
||||||
|
isolated config dirs; put the plain binary first on PATH.
|
||||||
- `IDX_AGENT_MODEL_<AGENT>` picks a model (for example
|
- `IDX_AGENT_MODEL_<AGENT>` picks a model (for example
|
||||||
`IDX_AGENT_MODEL_CLAUDE=sonnet`). `IDX_AGENT_EXEC_PREFIX` prefixes every
|
`IDX_AGENT_MODEL_CLAUDE=sonnet`). `IDX_AGENT_EXEC_PREFIX` prefixes every
|
||||||
agent command, for hosts that inject API keys through a wrapper.
|
agent command, for hosts that inject API keys through a wrapper.
|
||||||
|
|
@ -118,4 +123,5 @@ each run keeps a copy next to its output as `<case>.<run>.mcp-stderr`.
|
||||||
measure pass rates. `--keep` keeps raw agent output and `results.jsonl`.
|
measure pass rates. `--keep` keeps raw agent output and `results.jsonl`.
|
||||||
- `nix develop .#agents` adds Claude Code, Codex, and opencode from nixpkgs
|
- `nix develop .#agents` adds Claude Code, Codex, and opencode from nixpkgs
|
||||||
after your PATH, so installed versions win. pi and Hermes Agent must be
|
after your PATH, so installed versions win. pi and Hermes Agent must be
|
||||||
installed on the host.
|
installed on the host. The nixpkgs opencode (1.2.17) lacks `run --pure`;
|
||||||
|
use a current opencode 1 or 2.
|
||||||
|
|
|
||||||
|
|
@ -273,19 +273,39 @@ run_hermes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_opencode() {
|
setup_opencode() {
|
||||||
|
local version
|
||||||
mkdir -p "$work/opencode/cwd"
|
mkdir -p "$work/opencode/cwd"
|
||||||
|
version="$("${exec_prefix[@]}" opencode --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)"
|
||||||
|
if [[ "${version%%.*}" -ge 2 ]]; then
|
||||||
|
# OpenCode 2 (@opencode/cli). A denied call ends the run, and models
|
||||||
|
# use Code Mode's `execute` while the server connects, so deny only
|
||||||
|
# the tools that could route around it. --standalone keeps the run
|
||||||
|
# off the shared background service.
|
||||||
|
jq -n --argjson s "$server_json" \
|
||||||
|
'{mcp: {servers: {idx: {type: "local", command: ([$s.command] + $s.args),
|
||||||
|
environment: $s.env, codemode: false}}},
|
||||||
|
permissions: ((["read", "edit", "glob", "grep", "shell", "subagent", "skill",
|
||||||
|
"question", "webfetch", "websearch", "external_directory"]
|
||||||
|
| map({action: ., resource: "*", effect: "deny"}))
|
||||||
|
+ [{action: "idx_*", resource: "*", effect: "allow"}])}' \
|
||||||
|
> "$work/opencode/cwd/opencode.json"
|
||||||
|
echo --standalone > "$work/opencode/run-flag"
|
||||||
|
else
|
||||||
jq -n --argjson s "$server_json" \
|
jq -n --argjson s "$server_json" \
|
||||||
'{"$schema": "https://opencode.ai/config.json",
|
'{"$schema": "https://opencode.ai/config.json",
|
||||||
mcp: {idx: {type: "local", command: ([$s.command] + $s.args), environment: $s.env, enabled: true}},
|
mcp: {idx: {type: "local", command: ([$s.command] + $s.args), environment: $s.env, enabled: true}},
|
||||||
permission: {"*": "deny", "idx_*": "allow"}}' \
|
permission: {"*": "deny", "idx_*": "allow"}}' \
|
||||||
> "$work/opencode/cwd/opencode.json"
|
> "$work/opencode/cwd/opencode.json"
|
||||||
|
echo --pure > "$work/opencode/run-flag"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
run_opencode() {
|
run_opencode() {
|
||||||
local prompt="$1" out="$2" model=() home="$work/opencode"
|
local prompt="$1" out="$2" model=() home="$work/opencode" flag
|
||||||
[[ -n "${IDX_AGENT_MODEL_OPENCODE:-}" ]] && model=(-m "$IDX_AGENT_MODEL_OPENCODE")
|
[[ -n "${IDX_AGENT_MODEL_OPENCODE:-}" ]] && model=(-m "$IDX_AGENT_MODEL_OPENCODE")
|
||||||
|
flag="$(< "$home/run-flag")"
|
||||||
(cd "$home/cwd" && XDG_CONFIG_HOME="$home/config" XDG_DATA_HOME="$home/data" \
|
(cd "$home/cwd" && XDG_CONFIG_HOME="$home/config" XDG_DATA_HOME="$home/data" \
|
||||||
XDG_CACHE_HOME="$home/cache" XDG_STATE_HOME="$home/state" \
|
XDG_CACHE_HOME="$home/cache" XDG_STATE_HOME="$home/state" \
|
||||||
"${exec_prefix[@]}" opencode run --pure --format json "${model[@]}" "$prompt" < /dev/null > "$out.raw")
|
"${exec_prefix[@]}" opencode run "$flag" --format json "${model[@]}" "$prompt" < /dev/null > "$out.raw")
|
||||||
jq -c 'select(.type=="tool_use") | .part | select(.tool | startswith("idx_"))
|
jq -c 'select(.type=="tool_use") | .part | select(.tool | startswith("idx_"))
|
||||||
| select(.state.status=="completed") | {name: (.tool | ltrimstr("idx_")), args: .state.input}' "$out.raw" > "$out.calls"
|
| select(.state.status=="completed") | {name: (.tool | ltrimstr("idx_")), args: .state.input}' "$out.raw" > "$out.calls"
|
||||||
jq -r 'select(.type=="text") | .part.text' "$out.raw" > "$out.answer"
|
jq -r 'select(.type=="text") | .part.text' "$out.raw" > "$out.answer"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue