Skip to content

OpenCode Agent

Built-in Agent provider

opencodeAgent()

A native OpenCode ACP profile that translates AML's model, system, filesystem, shell, and network requests into a private per-evaluation OpenCode configuration.

Best for
OpenCode deployments that need AML orchestration and OpenCode's coding tools.
Know before using
The executable and model-provider credentials are external prerequisites. OpenCode permissions are useful policy controls, but the enclosing Sandbox remains the hard boundary.
Built-in Native ACP Private state

The profile starts OpenCode with an ACP server command equivalent to:

opencode acp --pure --cwd <effective-sandbox-cwd> <your args>

command changes the executable; AML always supplies the ACP arguments before your additional args. The profile injects OPENCODE_CONFIG_CONTENT with an AML-owned aml primary agent, then gives every acquired session private database, cache, config, and state directories. Its data directory is private by default and may be replaced only through an explicit env.XDG_DATA_HOME setting.

The XDG directories isolate OpenCode-native user state. XDG_DATA_HOME, which contains OpenCode’s auth.json, is invocation-private by default. A caller may explicitly point it at a staged data directory through env, while AML still owns the invocation’s session database and every other XDG directory. Prefer a dedicated request-local data directory or an environment credential over sharing the operator’s complete interactive OpenCode data directory.

OpenCode still loads project rules from AGENTS.md, or CLAUDE.md when no project AGENTS.md exists. It can also fall back to ~/.claude/CLAUDE.md because this profile does not replace HOME; set OPENCODE_DISABLE_CLAUDE_CODE_PROMPT=1 in env when that compatibility behavior is unwanted. Loaded rules remain OpenCode system instructions. AML-authored System content is delivered separately as a first-turn prelude.

Authored <Skill /> packages use OpenCode’s native discovery. AML preserves any configured skills.paths entries and appends each invocation-private staged package directory. It does not inline the Skill body or mutate the source package.

OpenCode executable

Install the opencode executable or provide an equivalent ACP-capable launcher with command. AML does not install it.

Model provider

Configure the model provider and credentials that OpenCode expects. Pass environment values with env or use the host/Sandbox environment.

Working directory

Use an existing Workspace or a trusted directory. When a Sandbox is active, its effective guest cwd wins over the factory directory.

Install OpenCode through its published CLI package, verify the executable, and configure at least one model provider:

Terminal
npm install --global opencode-ai@1.18.18
opencode --version
opencode auth login
opencode auth list

opencode auth login stores provider credentials in OpenCode’s own data directory. opencode auth list also reports provider credentials discovered through environment variables. AML does not copy those credentials into a Workspace or infer which model provider you intended.

For an isolated invocation, pass the provider credential through env or stage the required OpenCode data into a dedicated directory and set env.XDG_DATA_HOME to it. OPENCODE_DB remains invocation-private even when the data directory is explicitly staged, so the Agent does not import or persist interactive session history.

The AML repository currently pins opencode-ai@1.18.18 for its integration toolchain and @opencode-ai/sdk@1.18.5 for the typed provider configuration. These versions are the repository’s verification baseline, not a claim that every newer OpenCode release is compatible. Re-run the provider integration path when changing either side.

For container execution, the OpenCode image variant includes this baseline. The default full image includes it too. The alternative image guide also documents Cloudflare’s OpenCode-specific image.

The example below chooses the explicit environment path for the opencode-go model provider; it does not depend on opencode auth login state. If you use native login instead, omit the key guard and env mapping and select a model attached to that account.

import { Agent, AmlRuntime, Sandbox, Workspace, localSandbox, localWorkspace, opencodeAgent } from "@aml-jsx/sdk"
const apiKey = process.env.OPENCODE_API_KEY
if (!apiKey) throw new Error("OPENCODE_API_KEY is required")
const provider = opencodeAgent({
model: "opencode-go/deepseek-v4-flash",
// Provider-native variables are forwarded to the OpenCode process.
env: { OPENCODE_API_KEY: apiKey },
})
const result = await new AmlRuntime({ agentProvider: provider }).evaluate(
<Workspace
id="opencode-review"
provider={localWorkspace({ directory: "/absolute/path/to/repository" })}
load={false}
save={false}
>
<Sandbox provider={localSandbox()} access="read-write">
<Agent system="Keep changes scoped to the requested review.">
Review the repository and explain the three most important risks.
</Agent>
</Sandbox>
</Workspace>
)
console.log(result)

Do not use an empty credential value as a production configuration. The example keeps the environment shape visible; your deployment should fail early or inject a real provider credential according to OpenCode’s documentation.

Z.ai officially supports OpenCode as a GLM Coding Plan client, which makes this profile the officially supported route to GLM models in AML — unlike the community GLM agent adapter. Create a Coding Plan API key at z.ai and pass an OpenCode provider configuration through the typed config option. The key bills against your plan quota (including free tiers), not pay-as-you-go API credit:

import { Agent, AmlRuntime, opencodeAgent } from "@aml-jsx/sdk"
const provider = opencodeAgent({
config: {
provider: {
"zai-coding": {
npm: "@ai-sdk/openai-compatible",
options: {
baseURL: "https://api.z.ai/api/coding/paas/v4",
apiKey: "{env:Z_AI_API_KEY}",
},
models: {
"glm-5.3": { name: "GLM-5.3" },
"glm-5-turbo": { name: "GLM-5-Turbo" },
"glm-4.7": { name: "GLM-4.7" },
},
},
},
},
model: "zai-coding/glm-5.3",
})
const answer = await new AmlRuntime({ agentProvider: provider }).evaluate(
<Agent system="Be concise and cite the files you inspected.">Summarize the highest-risk module.</Agent>
)

Z_AI_API_KEY must be present in the environment that launches OpenCode; the {env:…} reference is OpenCode’s own interpolation. Confirm the current endpoint, model ids, and key management on Z.ai’s Coding Plan documentation when upgrading either side.

OptionTypeDefaultSemantics
commandstring"opencode"OpenCode executable or launcher. Must be non-empty, trimmed, and free of null bytes.
argsreadonly string[][]Appended after AML’s acp --pure --cwd <cwd> arguments.
configOpenCodeConfig{}JSON-compatible OpenCode configuration captured before process acquisition.
directorystringFallback launch directory when no Sandbox supplies one.
envRecord<string, string>{}Provider credentials and environment configuration.
modelstringFactory-level model fallback.

Model precedence is:

  1. <Agent model="..." />
  2. opencodeAgent({ model: "..." })
  3. opencodeAgent({ config: { model: "..." } })

AML sets default_agent to aml and merges the existing config.agent table, replacing the aml profile with the session-specific profile. This profile is mode: "primary" and exposes only the tools allowed by AML’s normalized permission request. AML also merges its deny rules into the top-level OpenCode permission policy, which OpenCode applies to every native agent profile. Native task subagents therefore inherit the parent AML restrictions without disabling delegation.

OpenCode replaces its model-specific base coding prompt when a custom Agent has a non-empty prompt, so AML does not set that field. ACP has no system-message field; when the effective AML System text is non-empty, AML prepends it to the first user turn inside literal <SYSTEM> tags. Empty System content adds no prelude. This preserves OpenCode’s native model-specific prompt, but the ACP protocol still carries the prelude as user-role content.

AML permissionOpenCode toolsOpenCode permissions
filesystem: "read-only"Disables edit and writeDenies edit and write
shell: falseDisables bashDenies bash
network: falseDisables webfetch and websearchDenies both network tools
Default permissionKeeps tools enabledUses the AML profile’s allow policy

These mappings are provider-native controls. They do not grant access beyond the enclosing Sandbox, and an OpenCode policy cannot make a read-only Sandbox writable. Conversely, a writable host Sandbox is not made safe merely because an Agent prompt asks it to be careful.

Configured top-level permissions are preserved, but AML deny rules take precedence for a restricted evaluation. Child agents may narrow that policy further; they cannot regain filesystem, shell, or network tools denied by the parent AML request.

For each acquired session AML sets:

OPENCODE_DB <state>/opencode.db
XDG_CACHE_HOME <state>/cache
XDG_CONFIG_HOME <state>/config
XDG_DATA_HOME <state>/data (default) or an explicit env.XDG_DATA_HOME
XDG_STATE_HOME <state>/state

The profile creates the launch configuration after AML has resolved the effective Sandbox cwd and capabilities. OPENCODE_DB, cache, config, and state always remain invocation-owned. AML then starts the ACP session, streams turns, validates the response, and releases provider-owned state through the shared lifecycle. Do not persist these temporary directories as a Workspace artifact unless you intentionally want OpenCode session state in your application.

  1. opencode is missing

    Run opencode --version in the same host, container, or remote image that AML uses. A host installation is invisible to a remote Sandbox unless the image contains the executable.

  2. OpenCode starts but cannot select a model

    Check the effective model identifier and the model provider’s credentials. Remember the precedence order: <Agent /> prop, factory option, then config.model.

  3. Network, shell, or edit operations still fail

    Inspect both OpenCode’s translated policy and the Sandbox’s access. AML does not claim that the compatibility handshake verifies credentials, image utilities, model availability, network policy, or hostile-code isolation.

  4. OpenCode follows unexpected project guidance

    Inspect the nearest project AGENTS.md or fallback CLAUDE.md, plus the operator’s ~/.claude/CLAUDE.md when Claude Code compatibility is enabled. Session-private XDG directories isolate OpenCode-native global rules, not repository rules or the home-directory Claude fallback.

  5. Configuration validation fails before launch

    command, directory, and model must be normalized strings. args must contain strings without null bytes. config must contain finite JSON values without cycles.

OpenCode uses the same AML capability and evaluation contracts as the other built-in ACP profiles: