Documentation
¶
Overview ¶
Package opencode provides an OpenCode CLI backend for agentrun.
This backend implements cli.Spawner, cli.Parser, and cli.Resumer to drive OpenCode as a subprocess, translating its nd-JSON output into agentrun.Message values. It does NOT implement cli.Streamer or cli.InputFormatter — OpenCode uses resume-per-turn for multi-turn conversation.
Resume-per-turn pattern ¶
OpenCode's run command is single-shot: provide a message, get a response, process exits. For multi-turn, each Send() spawns a new process with --session <id> to resume the conversation. The session ID is auto-captured from the first step_start event and stored in the Backend (one instance per session).
Callers relying on auto-capture must wait for MessageInit before calling Send, or supply OptionResumeID upfront.
Supported options ¶
Cross-cutting (root package):
- Session.Model → --model provider/model
- OptionAgentID → --agent <id>
- OptionThinkingBudget → --thinking (boolean: any non-empty value)
Cross-cutting (root package — session resume):
- OptionResumeID → --session (auto-captured or explicit cold resume) Consumers capture the session ID from MessageInit.ResumeID.
Backend-specific (namespaced with "opencode." prefix):
- OptionVariant → --variant (VariantHigh, VariantMax, VariantMinimal, VariantLow)
- OptionFork → --fork (fork session on resume)
- OptionTitle → --title (session title, max 512 bytes)
Event types ¶
OpenCode emits 6 JSON event types: step_start, text, tool_use, step_finish, reasoning, error. All events include a top-level "timestamp" field (millisecond Unix epoch) and "sessionID".
Unlike Claude, OpenCode emits complete blocks (no streaming deltas) and reports tool_use after completion (input + output together). Tool events are mapped to MessageToolResult with both Input and Output populated on the ToolCall.
Index ¶
Constants ¶
const ( // OptionVariant sets the OpenCode --variant flag. // Values should be Variant constants. OptionVariant = "opencode.variant" // OptionFork enables forking when resuming an OpenCode session. // Any non-empty value adds the --fork flag. OptionFork = "opencode.fork" // OptionTitle sets the OpenCode --title flag for session naming. // Values exceeding maxTitleLen bytes are silently skipped. OptionTitle = "opencode.title" )
Session option keys specific to the OpenCode backend. Namespaced with "opencode." to prevent collision across backends. Cross-cutting options (OptionThinkingBudget, OptionMode, OptionHITL, OptionResumeID) are defined in the root agentrun package.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Backend ¶
type Backend struct {
// contains filtered or unexported fields
}
Backend is an OpenCode CLI backend for agentrun. It implements cli.Spawner, cli.Parser, and cli.Resumer.
OpenCode does NOT support streaming input (no cli.Streamer or cli.InputFormatter). Multi-turn conversation uses resume-per-turn: each Send() spawns a new subprocess with --session <id>.
One Backend instance per session. The session ID is auto-captured from the first step_start event via atomic write-once.
func New ¶
New creates an OpenCode CLI backend with the given options. The default binary is "opencode".
func (*Backend) ParseLine ¶
ParseLine parses a single nd-JSON output line from OpenCode into a Message. Returns cli.ErrSkipLine for blank or whitespace-only lines.
OpenCode emits 6 event types: step_start, text, tool_use, step_finish, reasoning, error. All events include a top-level "timestamp" field (millisecond Unix epoch) and "sessionID".
func (*Backend) ResumeArgs ¶
func (b *Backend) ResumeArgs(session agentrun.Session, initialPrompt string) (string, []string, error)
ResumeArgs builds exec.Cmd arguments to resume an existing OpenCode session. The session ID is resolved from:
- The atomic write-once ID captured from step_start (auto-capture)
- session.Options[OptionResumeID] (explicit fallback)
Returns an error if no session ID is available or if the message contains null bytes.
Note on HITL: OptionHITL=off requires OPENCODE_AUTO_APPROVE=1 env var on the subprocess. Use Session.Env to pass this per-session:
session.Env = map[string]string{"OPENCODE_AUTO_APPROVE": "1"}
func (*Backend) SessionID ¶
SessionID returns the auto-captured session ID, or empty string if not yet captured.
type Option ¶
type Option func(*Backend)
Option configures a Backend at construction time.
func WithBinary ¶
WithBinary overrides the OpenCode CLI binary path. Empty values are ignored; the default is "opencode".