Skip to content

OpenCode ​

OpenCode is fullsend's fourth agent runtime, opt-in per repo or per agent. It runs in the same sandbox, with the same credentials and egress policy as Claude Code and pi. Choosing between runtimes is in Agent runtimes.

Planned: sandbox tool hooks and write-capable agents (#7824). Until they land, OpenCode is experimental:

  • Use it only for read-only agents (triage, prioritize) on a disposable repo. fullsend does not enforce this, so do not select it for code or fix.
  • The harness must set security.enabled: false. That also turns off the content scans of the agent, skills and repo context, and the secret redaction of outputs and transcripts.

Run it locally ​

Complete Running agents locally first. The CLI, OpenShell, credentials and the agents clone are the same. The fleet sandbox image includes the pinned OpenCode (1.19.1).

1. Write the tool policy. OpenCode reads its global config, including the tool-permission policy, from OPENCODE_CONFIG_CONTENT. A run fails before it starts when the variable is empty or has no permission block. Put it in an env file:

bash
# fullsend-opencode.env
OPENCODE_CONFIG_CONTENT='{"provider":{"google-vertex-anthropic":{"id":"google-vertex-anthropic"}},"permission":{"*":"deny","read":"allow","glob":"allow","grep":"allow","list":"allow","skill":"allow","bash":{"*":"allow","rm *":"deny"},"write":"deny","edit":"deny","webfetch":"deny","task":"deny"}}'

Allow every tool the agent needs. OpenCode runs without a TTY here, so it rejects any tool call the policy does not allow. The agent's own tools: list can narrow this policy but never widen it.

2. Set up the harness. In the agent's harness (harness/triage.yaml), turn security off and add the variable to the existing env.sandbox block:

yaml
security:
  enabled: false
env:
  sandbox:
    # ...existing entries...
    OPENCODE_CONFIG_CONTENT: ${OPENCODE_CONFIG_CONTENT}

fullsend agent new --runtime opencode adds the env.sandbox entry for you.

3. Run the agent:

bash
fullsend run triage \
  --fullsend-dir /tmp/fullsend-agents/ \
  --target-repo /tmp/target-repo/ \
  --env-file fullsend-gcp.env \
  --env-file fullsend-triage.env \
  --env-file fullsend-opencode.env \
  --runtime opencode \
  --model google-vertex-anthropic/claude-sonnet-4-6@default

Output from a triage run (trimmed):

text
    Model: google-vertex-anthropic/claude-sonnet-4-6@default (from --model flag)
    Runtime: opencode (from --runtime flag)
runtime: selected "opencode" from --runtime flag
  • Bootstrapping sandbox
Skill "github": uploaded to sandbox
Skill "issue-labels": uploaded to sandbox
Agent Bash allowlist (gh, curl, jq) is recorded but not enforced on opencode — ...
→ Iteration 1 of 2
→ Agent: claude-sonnet-4-6@default
  ⚙ bash: gh issue view 1 --repo <owner>/<repo> --json number,title,body,...
  ⚙ bash: gh label list --repo <owner>/<repo> --json name,description --limit 100
  ✓ Validation passed: Validating: output/agent-result.json against .../triage-result.schema.json
    Agent exit code: 0
    Validation: passed

metrics.json records runtime: opencode. To keep an agent on OpenCode without the flag, set runtime: on its agents: entry in config.yaml (see per-agent settings).

Models ​

A model is provider/model. The aliases resolve to ids in OpenCode's built-in model catalog:

You giveOpenCode gets
opus (default)google-vertex-anthropic/claude-opus-5-5@default
sonnetgoogle-vertex-anthropic/claude-sonnet-5-5@default
haikugoogle-vertex-anthropic/claude-haiku-5-5@default
fablegoogle-vertex-anthropic/claude-fable-5-1@default
A bare idthe id, prefixed with FULLSEND_OPENCODE_PROVIDER (default google-vertex-anthropic); on google-vertex-anthropic, @default is appended when the id has no @ suffix
provider/modelunchanged

The harness or --model wins over the agent's model: frontmatter. models.aliases in .fullsend/config.yaml can retarget an alias. A bare id there gets @default: sonnet: claude-sonnet-5 becomes google-vertex-anthropic/claude-sonnet-5@default. That matches the catalog for 4.6 and later models only. Older models are listed under a dated id, so give it in full (sonnet: claude-sonnet-4-5@20250929); an id with an @ suffix is left as is. An explicit google-vertex-anthropic/... spec passes through unchanged, so it must carry the catalog suffix too.

There is no fallback chain. Vertex enables models per project. On a project that does not serve 5.5, Claude Code falls back to 4.6, but OpenCode fails. Name a model your project serves, as in the example above.

At a glance ​

RolesRead-only agents (triage, prioritize)
CredentialsSame Vertex WIF credentials as Claude Code and pi
InstructionsReads AGENTS.md; no CLAUDE.md bridge
Effort--effort maps to OpenCode's --variant
Artifactsoutput.jsonl, transcripts/<agent>-output.jsonl, metrics.json, and opencode-debug.log with --debug='*'
Not supportedFallback chains, plugins:, sandbox tool hooks (#7824)

Behaviour differences worth knowing ​

  • Bash allowlists are not enforced. Bash(gh:*) in the agent's tools: becomes plain bash, with a warning. To restrict commands, give bash a pattern map in the policy ("bash": {"*": "deny", "gh *": "allow"}). An agent that declares Bash gets that same map.
  • The agent is reset before every iteration. The runner removes agent, tool and config overrides the previous iteration could have written, re-uploads the agent, and checks that OpenCode loads it. skills/ in the config directory stays agent-writable until #7824.
  • Repo config is ignored. OpenCode does not load the target repo's .opencode/ config or skills.

Troubleshooting ​

You seeCause and fix
OPENCODE_CONFIG_CONTENT is emptyThe env file or the harness env.sandbox entry is missing (steps 1 and 2)
OPENCODE_CONFIG_CONTENT ... invalid JSON or ... permission policyThe JSON is invalid, or its permission block is missing or invalid (step 1)
hooks adapter not yet availableThe harness still has security.enabled: true (step 2)
ProviderModelNotFoundErrorThe id is not in OpenCode's built-in catalog. Use an id from the table above
Vertex 404 NOT_FOUND for the modelYour project does not serve it. Name one it serves
Falling back to default agentOpenCode could not load the agent, and the iteration fails. Rerun with --debug='*' and read opencode-debug.log
Tool calls fail with a permission errorThe policy does not allow that tool (step 1)

See also ​