opencode

package
v0.156.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

Documentation

Overview

Package opencode implements an llm.LLMProvider for the OpenCode CLI driven over the Agent Client Protocol (ACP). A ready OpenCode contributes a live model catalog discovered from the local CLI through the same catalog, discovery, context-window, and cost interfaces the other providers use, so its backend models participate in routing, provider-grouped model lists, and as a co-equal default selection. A failed refresh can use a previously discovered cache with a warning; no accessible backend is invented. Models are always expressed in OpenCode's native "provider/model" form: the "opencode:" routing prefix and Agentico's "[<window>]" context-window suffix are both stripped before a model string is handed to the CLI.

Index

Constants

View Source
const (
	StopReasonEndTurn         = "end_turn"
	StopReasonMaxTokens       = "max_tokens"
	StopReasonMaxTurnRequests = "max_turn_requests"
	StopReasonRefusal         = "refusal"
	StopReasonCancelled       = "cancelled"
)

ACP stop reasons returned by session/prompt.

View Source
const (
	UpdateAgentMessageChunk = "agent_message_chunk"
	UpdateAgentThoughtChunk = "agent_thought_chunk"
	UpdateToolCall          = "tool_call"
	UpdateToolCallUpdate    = "tool_call_update"
	UpdateUsage             = "usage_update"
	UpdateAvailableCommands = "available_commands_update"
)

session/update discriminator values handled by the tracer.

View Source
const (
	ToolKindExecute  = "execute"
	ToolKindEdit     = "edit"
	ToolKindFetch    = "fetch"
	ToolKindSearch   = "search"
	ToolKindRead     = "read"
	ToolKindThink    = "think" // OpenCode's kind for the task (subagent-spawn) tool
	ToolKindOther    = "other"
	ToolKindQuestion = "question"
)

ACP tool-call kinds the tracer recognizes. Unknown kinds still surface as a permission prompt (the user decides) rather than failing closed; only the "question" kind diverts to the AskUserQuestion flow.

View Source
const (
	OptionKindAllowOnce    = "allow_once"
	OptionKindAllowAlways  = "allow_always"
	OptionKindRejectOnce   = "reject_once"
	OptionKindRejectAlways = "reject_always"
)

ACP permission option kinds. The allow_* kinds approve the action; the reject_* kinds decline it.

View Source
const (
	OutcomeSelected  = "selected"
	OutcomeCancelled = "cancelled"
)

ACP permission outcome discriminators.

View Source
const RoutingPrefix = providerName + ":"

RoutingPrefix is the Agentico-only model prefix that explicitly selects the OpenCode provider, e.g. "opencode:anthropic/claude-sonnet-4-5". It is purely a routing artifact: the prefix is stripped before the backend model string is handed to OpenCode.

Variables

View Source
var Module = fx.Module("llm-opencode",
	fx.Provide(func(cfg *config.Config) *Provider {
		return NewWithBinary(cfg.ProviderCLI(providerName, defaultBinary))
	}),
	fx.Invoke(func(r *llm.Registry, p *Provider) {
		r.Register(p)
	}),
)

Module registers the OpenCode provider in the LLM registry. It is included only when OpenCode is explicitly requested (`--providers opencode`) or auto-registered because the config already selects an `opencode:` model; OpenCode is not part of the unconditional default provider set. Once registered and ready it discovers and contributes a model catalog like the other providers.

Functions

func BackendModel

func BackendModel(model string) string

BackendModel returns the OpenCode-native "provider/model" string for a model selection. It strips the two Agentico-only routing artifacts so OpenCode never sees them: the "opencode:" routing prefix (removed exactly once) and the trailing "[<window>]" context-window suffix (selection metadata, never part of a backend model name). The remaining slash-form id — including any colon-form tag such as an ollama "model:tag" — is preserved verbatim.

Types

type AgentCapabilities

type AgentCapabilities struct {
	LoadSession bool `json:"loadSession"`
}

AgentCapabilities is the subset of the ACP initialize result that gates which optional protocol surfaces Agentico may use for this OpenCode session. Only the fields the tracer acts on are decoded; unknown capability fields are ignored. loadSession reports whether the agent supports session/load, the ACP-standard mechanism Agentico uses to resume a prior session identity.

type AgentInfo

type AgentInfo struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

AgentInfo identifies the OpenCode agent.

type AuthMethod

type AuthMethod struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	Description string `json:"description"`
}

AuthMethod describes an authentication method OpenCode offers.

type ClientCapabilities

type ClientCapabilities struct {
	FS FSCapability `json:"fs"`
	// Terminal is intentionally false — Agentico does not host an ACP terminal
	// for OpenCode.
	Terminal bool `json:"terminal"`
}

ClientCapabilities declares which client-side capabilities Agentico supports. Agentico hosts the client filesystem surface (fs/read_text_file, fs/write_text_file) because OpenCode delegates I/O for paths outside its session workspace to the client; without it, an out-of-workspace artifact write (knowledge-base graph, feature-state artifact) would fail closed. The terminal surface stays unhosted, so terminal/* requests still fail closed.

type ClientInfo

type ClientInfo struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

ClientInfo identifies the Agentico client to OpenCode.

type ContentBlock

type ContentBlock struct {
	Type string `json:"type"`
	Text string `json:"text,omitempty"`
}

ContentBlock is an ACP content block. Agentico sends only text blocks.

type ErrorResponse

type ErrorResponse struct {
	JSONRPC string          `json:"jsonrpc"`
	ID      json.RawMessage `json:"id"`
	Error   RPCError        `json:"error"`
}

ErrorResponse is an outbound JSON-RPC 2.0 error response to a server-initiated (agent-to-client) request. Agentico fails closed with this response whenever OpenCode asks for a client capability that is not implemented.

type FSCapability

type FSCapability struct {
	ReadTextFile  bool `json:"readTextFile"`
	WriteTextFile bool `json:"writeTextFile"`
}

FSCapability declares client filesystem capabilities. Both true: Agentico hosts fs/read_text_file and fs/write_text_file (see clientfs.go).

type FSResultResponse

type FSResultResponse struct {
	JSONRPC string          `json:"jsonrpc"`
	ID      json.RawMessage `json:"id"`
	Result  any             `json:"result"`
}

FSResultResponse is an outbound JSON-RPC result for a hosted fs/* request: Result is null for a successful write and a ReadTextFileResult for a read.

type InitializeParams

type InitializeParams struct {
	ProtocolVersion    int                `json:"protocolVersion"`
	ClientCapabilities ClientCapabilities `json:"clientCapabilities"`
	ClientInfo         *ClientInfo        `json:"clientInfo,omitempty"`
}

InitializeParams are the parameters for the ACP initialize request.

type InitializeResult

type InitializeResult struct {
	ProtocolVersion   int               `json:"protocolVersion"`
	AgentInfo         *AgentInfo        `json:"agentInfo,omitempty"`
	AuthMethods       []AuthMethod      `json:"authMethods,omitempty"`
	AgentCapabilities AgentCapabilities `json:"agentCapabilities"`
}

InitializeResult is OpenCode's response to initialize.

type Notification

type Notification struct {
	JSONRPC string      `json:"jsonrpc"`
	Method  string      `json:"method"`
	Params  interface{} `json:"params,omitempty"`
}

Notification is an outbound JSON-RPC 2.0 notification (no id, no response).

type PermissionOption

type PermissionOption struct {
	OptionID    string   `json:"optionId"`
	Name        string   `json:"name"`
	Kind        string   `json:"kind,omitempty"`
	Description string   `json:"description,omitempty"`
	Recommended bool     `json:"recommended,omitempty"`
	Confidence  *float64 `json:"confidence,omitempty"`
}

PermissionOption is one selectable response to a session/request_permission request. For a tool permission, Kind is one of the allow_*/reject_* values and Name is the human label ("Allow", "Reject"). For a question (Kind=="question" on the tool call), each option is an answer choice: Name is the answer label, and the optional Description/Recommended/Confidence enrich the surfaced AskUserQuestion when OpenCode provides them.

type PermissionOutcome

type PermissionOutcome struct {
	Outcome  string `json:"outcome"`
	OptionID string `json:"optionId,omitempty"`
}

PermissionOutcome is the user's decision. Outcome is "selected" with the chosen OptionID, or "cancelled" when no option applies (e.g. a denial with no reject option, or a free-form answer that matched no listed choice).

type PermissionOutcomeResult

type PermissionOutcomeResult struct {
	Outcome PermissionOutcome `json:"outcome"`
}

PermissionOutcomeResult wraps the outcome in the ACP result envelope.

type PermissionResponse

type PermissionResponse struct {
	JSONRPC string                  `json:"jsonrpc"`
	ID      int                     `json:"id"`
	Result  PermissionOutcomeResult `json:"result"`
}

PermissionResponse is the outbound JSON-RPC result for a session/request_permission request. It carries the user's outcome so OpenCode either runs the gated action / records the answer or skips it.

type PermissionToolCall

type PermissionToolCall struct {
	ToolCallID string          `json:"toolCallId,omitempty"`
	Title      string          `json:"title,omitempty"`
	Kind       string          `json:"kind,omitempty"`
	RawInput   json.RawMessage `json:"rawInput,omitempty"`
}

PermissionToolCall describes the action OpenCode wants permission for, or the question it wants answered. Kind classifies the surface (execute, edit, fetch, search, read, question); RawInput carries the tool's native input so the permission prompt and cache can show and match concrete detail; Title is a human summary used as the question stem and as a detail fallback.

type PromptParams

type PromptParams struct {
	SessionID string         `json:"sessionId"`
	Prompt    []ContentBlock `json:"prompt"`
}

PromptParams are the parameters for session/prompt.

type PromptResult

type PromptResult struct {
	StopReason string       `json:"stopReason"`
	Usage      *PromptUsage `json:"usage,omitempty"`
}

PromptResult is OpenCode's response to session/prompt. The end-turn token accounting rides in Usage (the ACP end-turn-token-usage shape OpenCode builds via UsageService.buildUsage); StopReason classifies the outcome. When present, Usage folds into the terminal result's normalized usage.

type PromptUsage

type PromptUsage struct {
	TotalTokens       int `json:"totalTokens"`
	InputTokens       int `json:"inputTokens"`
	OutputTokens      int `json:"outputTokens"`
	ThoughtTokens     int `json:"thoughtTokens"`
	CachedReadTokens  int `json:"cachedReadTokens"`
	CachedWriteTokens int `json:"cachedWriteTokens"`
}

PromptUsage is OpenCode's end-turn token accounting attached to the session/prompt result, matching the real ACP wire shape (camelCase, verified against packages/opencode/src/acp/usage.ts and the ACP end-turn-token-usage RFD). thoughtTokens/cachedReadTokens/cachedWriteTokens are omitted when zero.

This is the ONLY carrier of the input/output/cache token split — the streamed usage_update notification reports context and cost but no per-token breakdown. Each result's tokens are summed once into the protocol's cumulative totals, so a multi-turn session (e.g. a question/answer follow-up) accumulates without double-counting. When OpenCode emits nothing, usage stays zero (no context %).

type Protocol

type Protocol struct {
	// contains filtered or unexported fields
}

Protocol implements llm.Protocol for the OpenCode ACP (Agent Client Protocol) JSON-RPC stdio transport. One instance is created per session.

func NewProtocol

func NewProtocol(opts llm.ProtocolOpts) *Protocol

NewProtocol creates a new OpenCode ACP protocol handler.

func (*Protocol) ACPSessionID

func (p *Protocol) ACPSessionID() string

ACPSessionID returns the internal ACP session id created during the handshake.

func (*Protocol) AdditionalSessionCost added in v0.147.0

func (p *Protocol) AdditionalSessionCost(ctx context.Context) (llm.SessionCostAdjustment, error)

AdditionalSessionCost returns costs for OpenCode-managed child sessions, such as Task subagents. OpenCode reports the parent ACP session cost separately from those rows, so Agentico has to add descendants explicitly.

func (*Protocol) BackendModelForTest

func (p *Protocol) BackendModelForTest() string

BackendModelForTest returns the backend "provider/model" the protocol selected.

func (*Protocol) Close

func (p *Protocol) Close() error

Close performs no cleanup; the session layer owns process teardown.

func (*Protocol) Handshake

func (p *Protocol) Handshake(ctx context.Context) error

Handshake performs the ACP bootstrap:

  1. initialize — negotiate the protocol version and read agent capabilities.
  2. session/new (or session/load when resuming) — establish the session, rooted at the resolved work directory, the prompt is delivered to.
  3. session/prompt — deliver the rendered Agentico phase prompt as the first user turn. The prompt response arrives asynchronously and is surfaced as a terminal result by ParseLine.

func (*Protocol) InitialPromptForTest

func (p *Protocol) InitialPromptForTest() string

InitialPromptForTest returns the rendered phase prompt the protocol will send as the first user turn.

func (*Protocol) Interrupt

func (p *Protocol) Interrupt() error

Interrupt cancels the in-flight turn using the ACP session/cancel notification, which OpenCode answers by completing the pending session/prompt with stopReason "cancelled" (mapped to a terminal non-success result). It returns llm.ErrNotSupported only before a session exists (no stdin or no session id yet), so the session layer's process-group SIGINT fallback still applies in that window.

func (*Protocol) NegotiatedVersion

func (p *Protocol) NegotiatedVersion() int

NegotiatedVersion returns the ACP protocol version OpenCode negotiated.

func (*Protocol) ParseLine

func (p *Protocol) ParseLine(line []byte) ([]llm.SDKMessage, error)

ParseLine translates one JSON-RPC line from OpenCode's stdout into SDKMessages. Returns a nil slice for lines that produce no Agentico message (handshake responses, ignored notifications, blank framing lines). OpenCode's stdout is contractually clean newline-delimited JSON-RPC — its logs go to stderr — so a line that is not a valid JSON-RPC envelope is genuine protocol corruption and fails the tracer closed with a terminal non-success result rather than being silently dropped.

func (*Protocol) RespondToAskUser

func (p *Protocol) RespondToAskUser(requestID string, questions json.RawMessage, answers map[string]string, _ map[string]llm.AskUserAnnotation) error

RespondToAskUser delivers the user's answer to an OpenCode question. A structured question with a native pending request is answered through that request's ACP outcome (selecting the option whose label the user chose); a synthetic question parsed from plain text — and a structured answer that matched no listed option — is delivered as a framed follow-up turn so the agent still receives the user's intent. annotations are accepted for interface parity; OpenCode carries no per-question note side-channel.

func (*Protocol) RespondToControl

func (p *Protocol) RespondToControl(requestID string, allow bool, _ json.RawMessage, _ string) error

RespondToControl answers a permission request as an ACP outcome: approval selects an allow-kind option and denial selects a reject-kind option. A denial with no reject option (or an unknown request) is answered "cancelled" so the action does not run and OpenCode still unblocks. originalInput and reason are accepted for interface parity; OpenCode's outcome carries neither.

func (*Protocol) RespondToHook

func (p *Protocol) RespondToHook(string) error

RespondToHook is a no-op — OpenCode ACP has no PreToolUse hook callbacks.

func (*Protocol) SendUserMessage

func (p *Protocol) SendUserMessage(text string) error

SendUserMessage delivers a follow-up user turn as a new session/prompt.

func (*Protocol) SessionID

func (p *Protocol) SessionID() string

SessionID returns the captured ACP session id so Agentico can scope session views, PID-file identity, and the permission cache to this OpenCode session, and so a later run can request a resume of it. It is empty until the handshake establishes (or resumes) a session.

func (*Protocol) SetLogFunc

func (p *Protocol) SetLogFunc(f func(string, ...interface{}))

SetLogFunc sets a logging function for debug output.

func (*Protocol) SetRequestIDsForTest

func (p *Protocol) SetRequestIDsForTest(initID, sessionNewID, sessionLoadID, promptID int)

SetRequestIDsForTest pins the handshake request ids (including session/load) so other packages can drive a real protocol through session establishment and prompt responses without running the full ACP handshake. Test-only.

func (*Protocol) SetStdin

func (p *Protocol) SetStdin(w io.Writer)

func (*Protocol) TranscriptPath

func (p *Protocol) TranscriptPath() string

TranscriptPath returns a concrete OpenCode transcript path only when the provider has proven one over ACP. OpenCode exposes no transcript path through the ACP surface Agentico uses, so this is empty (best-effort) rather than a fabricated path; it never panics.

func (*Protocol) WorkDirForTest

func (p *Protocol) WorkDirForTest() string

WorkDirForTest returns the resolved work directory used for session/new.

type Provider

type Provider struct {
	// contains filtered or unexported fields
}

Provider implements llm.LLMProvider for the OpenCode CLI (ACP stdio mode).

runner is injectable so version/readiness/discovery probes can be exercised in tests without a real OpenCode binary; production code falls back to clirun helpers. catalog holds the model catalog discovered at startup (empty until discovery runs); rates holds the per-model pricing parsed alongside it. Both are guarded by mu because discovery, startup enrichment, and routing lookups touch them from different goroutines.

func New

func New() *Provider

New returns a Provider with the default (production) command runner and the default CLI binary name.

func NewWithBinary added in v0.149.0

func NewWithBinary(binary string) *Provider

NewWithBinary returns a Provider that invokes the supplied CLI binary name (or the default when empty). It is the constructor used by the FX module to honor the providers.opencode.cli config override.

func NewWithRunner

func NewWithRunner(runner clirun.CommandRunner) *Provider

NewWithRunner returns a Provider that uses the supplied command runner for its version, readiness, and model-discovery probes instead of shelling out to the real OpenCode binary. It is a dependency-injection seam for tests that drive the provider through the shared startup discovery and cache path; production code uses New.

func (*Provider) AskingQuestionsClause

func (p *Provider) AskingQuestionsClause() string

AskingQuestionsClause provides the provider-specific asking-questions prompt section. OpenCode questions surface through Agentico's shared AskUserQuestion flow: the protocol parses the agent's numbered text alternatives into a formal AskUserQuestion that pauses the session for the user, so the clause directs the agent to express any question in exactly that numbered, confidence-qualified format (the structure the plain-text parser reads). A question phrased this way becomes a help-waiting pause, not a phase completion.

func (*Provider) AvailableModels

func (p *Provider) AvailableModels() []string

AvailableModels returns only discovered or cached model IDs.

func (*Provider) BuildCommand

func (p *Provider) BuildCommand(opts llm.CommandBuildOpts) ([]string, []string, error)

BuildCommand returns the args and environment needed to launch OpenCode in ACP stdio mode with a deterministic, Agentico-owned managed session configuration.

The backend model is validated as a data value before any command is constructed: empty selections, CLI-flag-shaped values, and values carrying shell/interpolation metacharacters fail closed so a malformed or hostile selection can never reach a launchable command (and an empty selection never silently falls back to OpenCode's default model). Valid slash-form "provider/model" ids pass through unchanged.

The command itself is the bare `opencode acp`: it speaks newline-delimited JSON-RPC on stdout while sending its own logs to stderr, so stdout stays valid for the protocol reader. Managed configuration is generated under the provider-managed state directory and delivered through the OPENCODE_CONFIG file plus the highest-precedence OPENCODE_CONFIG_CONTENT inline channel, while inherited compatibility/config sources are scrubbed through environment flags — none of which mutates the user's global OpenCode configuration. Any build failure aborts before a launchable command exists. See buildManagedSession.

func (*Provider) CheckReadiness

func (p *Provider) CheckReadiness(ctx context.Context) llm.ProviderReadiness

CheckReadiness probes whether OpenCode is configured with usable provider access, beyond mere binary presence. It runs the non-interactive `opencode models`, which lists the models reachable from configured providers, and distinguishes ready / installed-but-unconfigured / command-failed / timed-out states with actionable remedies.

func (*Provider) ComputeCost

func (p *Provider) ComputeCost(model string, inputTokens, outputTokens int64) float64

ComputeCost computes token cost from the pricing parsed during catalog discovery. When pricing was exposed for the model in a stable numeric shape it is applied (per million tokens); otherwise — unknown model, no pricing, or a a catalog without advertised pricing — it returns 0 so the session falls back to the cost OpenCode reports over ACP without corrupting usage summaries.

func (*Provider) ContextWindowForModel

func (p *Provider) ContextWindowForModel(model string) int

ContextWindowForModel returns the context window for a model from the discovered or cached catalog, matching by canonical id or alias (so suffixed IDs, unsuffixed aliases, and the canonicalized form of an explicit "opencode:" selection all resolve). It returns 0 only when no catalog metadata exists for the model, which callers treat as "unknown" without corrupting behavior.

func (*Provider) DetectCLI

func (p *Provider) DetectCLI() bool

DetectCLI reports whether the OpenCode CLI binary is available in PATH.

func (*Provider) DiscoverModelCatalog

func (p *Provider) DiscoverModelCatalog(ctx context.Context) ([]llm.ModelInfo, error)

DiscoverModelCatalog refreshes OpenCode's model catalog from the local CLI.

func (*Provider) DiscoverModelCatalogWithProgress

func (p *Provider) DiscoverModelCatalogWithProgress(ctx context.Context, report llm.ModelDiscoveryReporter) ([]llm.ModelInfo, error)

DiscoverModelCatalogWithProgress refreshes OpenCode's model catalog and, on success, reports each parsed model in catalog order before returning. Pricing parsed alongside the catalog is stored on the provider for ComputeCost. The returned error is sanitized so a failed discovery cannot leak credential-like or terminal-control content into a startup warning, log, or cache diagnostic.

func (*Provider) EnablesPendingToolWatchdog

func (p *Provider) EnablesPendingToolWatchdog() bool

EnablesPendingToolWatchdog opts this adapter into the generic session watchdog for providers that can report tool lifecycle updates without necessarily completing the enclosing turn or surfacing a permission request. The historical capability name is retained for compatibility; it enables both the running-tool and post-tool turn-completion safety rails.

func (*Provider) EnforcesMinVersion

func (p *Provider) EnforcesMinVersion() bool

EnforcesMinVersion reports that OpenCode must meet MinVersion() to be ready at startup. Because its ACP wire behavior is only verified at or above 1.17.9, a too-old CLI is filtered out of the ready provider set — and thus out of routing, catalog discovery, and model lists — rather than left selectable with only a warning.

func (*Provider) EnvVarsToExclude

func (p *Provider) EnvVarsToExclude() []string

EnvVarsToExclude returns nil — OpenCode needs no env stripping.

func (*Provider) InstallHint

func (p *Provider) InstallHint() string

InstallHint returns the supported OpenCode install command.

func (*Provider) MatchesModel

func (p *Provider) MatchesModel(model string) bool

MatchesModel reports whether this provider handles the given model string.

An explicit "opencode:" routing prefix always matches when a backend model follows it (the bare prefix "opencode:" with no backend is not a valid selection). A bare model string matches only when it names an entry in the effective catalog — a discovered or cached catalog — by canonical id or alias. Catalog IDs are slash-form "provider/model" values, so a ready OpenCode never captures a bare name (e.g. "sonnet", "gpt-5.4") meant for another provider.

func (*Provider) MinVersion

func (p *Provider) MinVersion() [3]int

MinVersion returns the minimum OpenCode CLI version required. 1.17.9 is the earliest version against which the OpenCode ACP behavior (initialize with protocolVersion 1, session/new, session/prompt, session/update streaming) and the `opencode models` discovery surface have been verified.

func (*Provider) ModelCatalog

func (p *Provider) ModelCatalog() []llm.ModelInfo

ModelCatalog returns an isolated snapshot of discovered or cached metadata. No models or capabilities are fabricated when discovery is unavailable.

func (*Provider) Name

func (p *Provider) Name() string

func (*Provider) NewProtocol

func (p *Provider) NewProtocol(opts llm.ProtocolOpts) llm.Protocol

NewProtocol creates a per-session ACP protocol handler.

func (*Provider) RefreshCatalogOnStartup added in v0.156.0

func (p *Provider) RefreshCatalogOnStartup() bool

RefreshCatalogOnStartup prevents a CLI-version cache from hiding changes to user-defined provider models or variants. A failed refresh can use a stale cache with the startup warning, but no model catalog is fabricated.

func (*Provider) ReviewPreferenceBand added in v0.149.0

func (p *Provider) ReviewPreferenceBand(model llm.ModelInfo) (int, bool)

ReviewPreferenceBand admits discovered text models for native toolless review without guessing quality or cost from family names.

func (*Provider) SetModelCatalog

func (p *Provider) SetModelCatalog(models []llm.ModelInfo)

SetModelCatalog installs an isolated metadata snapshot and restores its advertised pricing, including when the catalog was loaded from cache.

func (*Provider) SupportsNativeToollessReview added in v0.149.0

func (p *Provider) SupportsNativeToollessReview() bool

SupportsNativeToollessReview attests that the provider's isolated managed configuration and ACP protocol implement Agentico's complete hidden-review contract. BuildCommand activates that boundary only when all three native isolation options are requested; ordinary OpenCode sessions are unchanged.

func (*Provider) SupportsSessionResume added in v0.149.0

func (p *Provider) SupportsSessionResume() bool

SupportsSessionResume reports that a prior ACP session can be resumed via ProtocolOpts.ResumeSessionID (session/load). Agents that do not advertise the loadSession capability fail the resume handshake with a clear error, which callers treat as "resume unavailable" and fall back.

func (*Provider) UsesBoundedHelperSandbox

func (p *Provider) UsesBoundedHelperSandbox() bool

UsesBoundedHelperSandbox opts bounded helper sessions into OS-level worktree sandboxing so helper shell probes fail as process errors rather than provider permission denials.

func (*Provider) VersionInfo

func (p *Provider) VersionInfo() (string, error)

VersionInfo runs `opencode --version` (through the injectable runner) and returns the parsed semver string (e.g. "1.17.9"), matching the Claude and Codex providers. Parsing — rather than returning the raw command output — guarantees the value the startup discovery path uses as the catalog cache key, cache filename, and persisted cache metadata is a clean version token that cannot carry trailing credential-like or terminal-control content from a malformed or hostile `opencode --version` line. On unparseable output it returns a generic error that does not echo the raw output, so no untrusted content reaches the startup version diagnostic either. It shares the same runner seam as discovery.

type RPCError

type RPCError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

RPCError is the JSON-RPC error object.

type ReadTextFileParams

type ReadTextFileParams struct {
	SessionID string `json:"sessionId"`
	Path      string `json:"path"`
	Line      *int   `json:"line,omitempty"`
	Limit     *int   `json:"limit,omitempty"`
}

ReadTextFileParams is the params of an fs/read_text_file request. Line is an optional 1-based start line and Limit an optional maximum number of lines.

type ReadTextFileResult

type ReadTextFileResult struct {
	Content string `json:"content"`
}

ReadTextFileResult is the result of a hosted fs/read_text_file request.

type Request

type Request struct {
	JSONRPC string      `json:"jsonrpc"`
	ID      int         `json:"id"`
	Method  string      `json:"method"`
	Params  interface{} `json:"params,omitempty"`
}

Request is an outbound JSON-RPC 2.0 request (has id, expects a response).

type RequestPermissionParams

type RequestPermissionParams struct {
	SessionID string             `json:"sessionId"`
	ToolCall  PermissionToolCall `json:"toolCall"`
	Options   []PermissionOption `json:"options"`
}

RequestPermissionParams is the params object of a session/request_permission request. OpenCode describes the gated action in ToolCall and offers the selectable Options the user picks among.

type SessionCancelParams

type SessionCancelParams struct {
	SessionID string `json:"sessionId"`
}

SessionCancelParams are the parameters for the session/cancel notification.

type SessionLoadParams

type SessionLoadParams struct {
	SessionID  string        `json:"sessionId"`
	Cwd        string        `json:"cwd"`
	MCPServers []interface{} `json:"mcpServers"`
}

SessionLoadParams are the parameters for session/load. The sessionId names the prior session to resume; cwd and mcpServers mirror session/new so the resumed session is rooted at the same work directory.

type SessionNewParams

type SessionNewParams struct {
	Cwd        string        `json:"cwd"`
	MCPServers []interface{} `json:"mcpServers"`
}

SessionNewParams are the parameters for session/new.

type SessionNewResult

type SessionNewResult struct {
	SessionID string `json:"sessionId"`
}

SessionNewResult is OpenCode's response to session/new.

type SessionUpdate

type SessionUpdate struct {
	SessionUpdate string `json:"sessionUpdate"`

	// agent_message_chunk / agent_thought_chunk carry an object content block;
	// tool_call_update may carry an array of output content blocks. Keep it raw
	// so the polymorphic shape cannot make the whole session/update fail to
	// decode.
	MessageID string          `json:"messageId,omitempty"`
	Content   json.RawMessage `json:"content,omitempty"`

	// tool_call / tool_call_update
	ToolCallID string             `json:"toolCallId,omitempty"`
	Title      string             `json:"title,omitempty"`
	Kind       string             `json:"kind,omitempty"`
	Status     string             `json:"status,omitempty"`
	Locations  []ToolCallLocation `json:"locations,omitempty"`
	RawInput   json.RawMessage    `json:"rawInput,omitempty"`
	RawOutput  json.RawMessage    `json:"rawOutput,omitempty"`

	// usage_update: Used is the tokens currently in context (input + cache read),
	// Size is the model's total context window, and Cost is the cumulative
	// session cost. These drive context-% reporting and cost; they carry no
	// per-token (input/output/cache) split — that lives only on the prompt result.
	Used int        `json:"used,omitempty"`
	Size int        `json:"size,omitempty"`
	Cost *UsageCost `json:"cost,omitempty"`
}

SessionUpdate is the polymorphic body of a session/update; SessionUpdate (the discriminator) selects which fields are populated.

type SessionUpdateParams

type SessionUpdateParams struct {
	SessionID string        `json:"sessionId"`
	Update    SessionUpdate `json:"update"`
}

SessionUpdateParams is the params object of a session/update notification.

type ToolCallLocation

type ToolCallLocation struct {
	Path string `json:"path,omitempty"`
	Line int    `json:"line,omitempty"`
}

ToolCallLocation is an ACP source/file location attached to a tool call. OpenCode uses it for edit targets and, for some shell commands, the directory context where the command ran.

type UpdateContent

type UpdateContent struct {
	Type string `json:"type"`
	Text string `json:"text,omitempty"`
}

UpdateContent is the content block carried by message-chunk updates.

type UsageCost

type UsageCost struct {
	Amount   float64 `json:"amount"`
	Currency string  `json:"currency"`
}

UsageCost is the cumulative session cost carried on a usage_update. Amount is the running total in Currency (ISO-4217). OpenCode omits it (or sends zero) when the backend has no pricing, in which case Agentico keeps its zero-cost fallback rather than inventing a figure.

type WriteTextFileParams

type WriteTextFileParams struct {
	SessionID string `json:"sessionId"`
	Path      string `json:"path"`
	Content   string `json:"content"`
}

WriteTextFileParams is the params of an fs/write_text_file request: OpenCode asks the client to write Content to Path. ACP fs paths are absolute; a relative path is resolved against the session working directory.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL