Files
bench/manager/core/adapters/opencode/run
T
istosandClaude Fable 5 9fed08d174 Let the board choose agent models, per launch intent
BOARD_AGENT_MODEL picks one model for every headless launch;
BOARD_AGENT_MODEL_WORK / _ACT_PR / _REVIEW beat it per intent (review
covers PR reviews and relevance checks). Empty — the default — means
the variable never reaches the adapter and the vendor's own resolution
applies, exactly today's behaviour; a stray AGENT_MODEL in the board's
own environment is stripped rather than inherited silently.

Core carries the name as an opaque string: config resolves intent →
model, _launch passes it as AGENT_MODEL, and each adapter renders it
natively — claude appends --model, opencode sets the generated
config's model key ("provider/model-id", per its docs). The resolved
model (or its absence) is recorded on the agent record, so the
Sessions and Focus views state what a run actually rode instead of
leaving it to whoever's machine the board happens to run on.

Stub-binary tests pin the byte-identical-when-unset guarantee, the
per-intent resolution, the launch-env seam and the record.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 07:37:39 +02:00

41 lines
2.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# opencode adapter: run one headless job to completion.
#
# Contract (same for every adapter):
# env in: AGENT_PROMPT the full prompt
# AGENT_MODE work | act-pr | review — the launch intent
# (see core/adapters/README.md)
# AGENT_COMMANDS comma-separated neutral command prefixes the
# project lets agents run (tests/checks)
# AGENT_MODEL optional; opencode's "provider/model-id" form,
# set as the generated config's model key.
# Absent = opencode's own resolution, untouched.
# AGENT_CWD working directory (already set as cwd by the board)
# BOARD_* passthrough for the event bridge
# stdout: captured by the board as the job log; `opencode run` prints
# the agent's final text there, so the closing report's marker
# lines (NOT READY:, PR REVIEW:, ...) parse unchanged
# exit: passes through from opencode; 0 = completed
#
# permission_config.py renders the intent as an opencode config —
# last-match-wins glob rules over bash, edit allow/deny — handed to the
# launch via OPENCODE_CONFIG so nothing is written into the worktree.
#
# Events: opencode loads project plugins from .opencode/plugin/, so a
# worktree of a repo wired by this adapter (`wire` installs the shim,
# committed to the repo) reports events with the BOARD_* env forwarded
# through the process environment. An unwired repo just runs silently.
#
# BOARD_OPENCODE_BIN overrides the binary (used by the test stubs).
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BIN="${BOARD_OPENCODE_BIN:-opencode}"
MODE="${AGENT_MODE:-work}"
CONFIG_FILE="$(mktemp "${TMPDIR:-/tmp}/bench-opencode-XXXXXX.json")"
trap 'rm -f "$CONFIG_FILE"' EXIT
python3 "$HERE/permission_config.py" "$MODE" > "$CONFIG_FILE"
export OPENCODE_CONFIG="$CONFIG_FILE"
"$BIN" run "$AGENT_PROMPT"