acp

package module
v0.7.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: 15 Imported by: 0

README

acp-go

A small, standard-library-only Go client for Agent Client Protocol v1, extracted from release-bot for reuse by release-bot and issue-bot.

go get github.com/BrokkAi/acp-go@master

The generated-schema API below is the v0.2 surface.

connection := acp.Connect(stdout, stdin, handleRequest, handleNotification)
defer connection.Close()
_, err := connection.InitializeWithInfo(ctx, acp.Capabilities{}, acp.ClientInfo{
    Name: "my-app", Version: "1.0.0",
})
// Handle err, then create a session and send prompts.
session, err := connection.NewSession(ctx, absoluteWorkingDirectory)
reason, err := connection.Prompt(ctx, session, "Inspect the project")

The import path is github.com/BrokkAi/acp-go; its package name is acp. The runtime now uses the generated schema types directly: Capabilities, Initialization, Session, Content, Update, and ClientInfo are aliases into that package. This is an intentional v0.x API break. Use acp.WorkspaceCapabilities(readFiles, writeFiles, terminal) for the former boolean FS/terminal fields, Session.SessionID instead of Session.ID, and the content constructors (for example acp.NewTextContent) instead of hand-written discriminator fields.

The caller owns launching the process and implementing the filesystem, terminal, and permission handlers it advertises. Capabilities default to disabled. Authentication, modes (including generated mode state), model and boolean config selection, reasoning effort, prompt content blocks, MCP servers, additional directories, session load/resume/list/close/delete, logout, and typed error classification are supported. Optional methods and prompt content are checked against the agent's advertised capabilities before a request is sent. Use SetModel before SetEffort: models may expose different effort choices. Explicit selections must be acknowledged by the agent; they never silently fall back.

acp.SessionUpdates adapts session/update notifications to the generated discriminated union. acp.HandleElicitation, the elicitation response constructors, ElicitationComplete, and CombineNotifications provide typed form/URL host support, including the agent's URL-completion notification. NewSessionWithOptions, LoadSession, and ResumeSession validate MCP transports and additional workspace roots against initialization capabilities.

Connect owns and closes both streams. Notifications run in wire order before responses and must return promptly without calling back into the connection. Requests run concurrently and must honor cancellation. Frames are bounded at 8 MiB and incoming requests at 32. Close cancels and joins handlers. Generic Call, CallBatch, and Notify permit extensions. Inbound and outgoing JSON-RPC batches retain member order where Rust does; request-bearing inbound batches receive one grouped response array, response batches route by ID, and malformed response-shaped members are ignored. This root transport is also used by the draft-v2 package, while its typed v1 facade remains v1-only.

Run go test -race ./... and go vet ./.... No agent credentials are needed. The fuzz seed corpus runs as part of that command; see CONTRIBUTING.md for longer campaigns and opt-in tests against real ACP agents.

Agent runtime

github.com/BrokkAi/acp-go/agent serves an agent over stdio. Implement the mandatory agent.Agent interface (Initialize, NewSession, and Prompt); optional lifecycle and config methods are discovered as narrow interfaces such as SessionLoader, SessionCloser, and ConfigOptionSetter. During a prompt, call SessionUpdater.Update to emit typed session/update notifications. The runtime enforces protocol initialization, dispatches generated request/response types, maps session/cancel to prompt-context cancellation, and rejects optional methods omitted from the agent's advertised capabilities.

The same package gives agents typed agent.Client methods for filesystem, permission, terminal, and elicitation callbacks. Client applications can compose typed hosts with agent.HandleFilesystem, HandleTerminal, HandlePermissions, and HandleElicitation. github.com/BrokkAi/acp-go/clienthost is the reference workspace-confined host used by the runner: rooted filesystem access, process-group terminals, bounded output, opt-in auto-approval, slog streaming, and JSONL transcripts.

Runnable examples are included:

go run ./examples/minimal-client -agent-command 'go run ./examples/minimal-agent' -prompt hello
go run ./examples/drive-cli -command 'go run ./examples/minimal-agent' -prompt hello

drive-cli accepts the same mode/model/effort/auth options commonly needed by external CLI adapters; substitute the real agent command for the minimal agent.

Wire schema

github.com/BrokkAi/acp-go/schema provides typed constants, request and response structs, notifications, and a method registry for every message in the pinned ACP JSON Schema release (schema-v1.21.0 at the time of writing), including session updates, content blocks, tool calls, permissions, terminals, elicitation, and config options. The package is generated by cmd/acpgen and guarded by round-trip parity tests, so tracking a new schema release is a reviewed regeneration rather than hand transcription. See CONTRIBUTING.md for the update workflow.

Draft ACP v2

github.com/BrokkAi/acp-go/v2 is a separate draft client for ACP v2, pinned to the official schema-v2.0.0-alpha.3 artifacts in schema/v2. It supports initialization and version selection, auth/login/auth/logout, session creation/resume/list/delete/close, prompt acceptance, cancellation, additional-directory capability checks, and typed session/update dispatch. There is intentionally no v1/v2 conversion layer. The artifacts match Rust schema crate 1.7.0 byte for byte. The generated v2 types use Nullable[T] where the draft distinguishes omitted fields from explicit JSON null, such as message-content patches.

ACP v2 changes prompt semantics: session/prompt returns after the agent accepts the turn, while completion is reported later through an idle state_update. The v1 runner and agent runtime remain under the root package for stable applications. Draft v2 agents can use github.com/BrokkAi/acp-go/v2/agent; its Agent interface covers the baseline session methods, prompt acceptance, cancellation, and typed permission and elicitation callbacks.

go run ./examples/minimal-agent-v2

github.com/BrokkAi/acp-go/v2 also provides typed host adapters with HandlePermissions, HandleElicitation, and HandleClientHost; install them before session/new because updates and interactive requests can arrive before setup responses. github.com/BrokkAi/acp-go/v2/runner mirrors the reference SDK's one-shot client: it ignores queued updates until the matching session reports running, projects subsequent agent-message chunks and patch snapshots, completes at the next idle update, and cancels permission requests by default. Run the reference-shaped example with:

go run ./examples/v2-one-shot-client \
  -command 'go run ./examples/minimal-agent-v2' \
  -prompt 'Say hello using draft ACP v2.'

MCP-over-ACP remains an explicit draft opt-in through github.com/BrokkAi/acp-go/v2/mcp, matching the Rust SDK's separately gated unstable_mcp_over_acp feature. Generated protocol versions and error codes use the schema's exact integer widths; in particular, ProtocolVersion is a uint16, so strings and values above 65535 fail to decode.

github.com/BrokkAi/acp-go/agentrouter serves one endpoint with explicit v1 and v2 implementations. It selects the highest configured implementation compatible with the first initialize request, canonicalizes only that initialize frame, and does not convert subsequent traffic.

Draft-v2 sessions can use acpv2.NewSessionHandle for Rust-shaped prompt, configuration, cancellation, and close commands. acpv2.SessionTracker owns connection-scoped update projections and active-work state; install it before session setup. acpv2.CancellablePermissions resolves pending permission requests as cancelled when active work is cancelled. ResumeSessionFromStart requires handlers to be installed before the resume request and returns only after replay updates have been applied in wire order.

Process runner

github.com/BrokkAi/acp-go/runner adds a process lifecycle, confined client file operations, terminal callbacks, streaming slog output and private JSONL transcripts. Runner.Execute(ctx, prompt) returns the complete agent text; applications own receipt parsing and workflow policy. Set Config.AutoApprove explicitly to allow permission requests for unattended operation. It defaults to false. This is not an OS sandbox: agents and terminal commands inherit the caller's permissions. SetupError distinguishes failures before a prompt from failures during work.

Contributing

See CONTRIBUTING.md and our Code of Conduct. Report vulnerabilities privately using SECURITY.md.

License

Licensed under Apache-2.0. See NOTICE for project attribution and licenses/README.md for dependency terms, third-party notices, and the license review process.

Documentation

Overview

Package acp implements the ACP v1 stdio client protocol using only Go's standard library. Specification: https://agentclientprotocol.com/protocol/v1/overview

Index

Constants

View Source
const (
	ErrorCodeAuthRequired     = -32000
	ErrorCodeResourceNotFound = -32002
)

ACP-specific JSON-RPC error codes.

View Source
const Version = schema.ProtocolVersion(1)

Version is the ACP protocol version implemented by this module.

Variables

This section is empty.

Functions

func AcceptElicitation added in v0.2.0

func CancelElicitation added in v0.2.0

func CancelElicitation() schema.CreateElicitationResponse

func ConfigOptionsClientCapabilities added in v0.2.0

func ConfigOptionsClientCapabilities(boolean bool) *schema.ClientSessionCapabilities

ConfigOptionsClientCapabilities advertises support for session config options. Boolean support is an extension beyond flat selectors.

func DeclineElicitation added in v0.2.0

func DeclineElicitation() schema.CreateElicitationResponse

func ElicitationClientCapabilities added in v0.2.0

func ElicitationClientCapabilities(form, url bool) *schema.ElicitationCapabilities

ElicitationClientCapabilities advertises support for form and URL modes.

func IsAuthRequired added in v0.2.0

func IsAuthRequired(err error) bool

func IsResourceNotFound added in v0.2.0

func IsResourceNotFound(err error) bool

func NewHTTPMCPServer added in v0.2.0

func NewHTTPMCPServer(name, url string, headers ...schema.HttpHeader) schema.McpServer

func NewSSEMCPServer added in v0.2.0

func NewSSEMCPServer(name, url string, headers ...schema.HttpHeader) schema.McpServer

func NewStdioMCPServer added in v0.2.0

func NewStdioMCPServer(name, command string, args []string, env map[string]string) schema.McpServer

Types

type BatchCall added in v0.6.0

type BatchCall struct {
	Method string
	Params any
	Result any
}

BatchCall is one request in an outgoing JSON-RPC batch.

type Capabilities

type Capabilities = schema.ClientCapabilities

The exported names below are intentional aliases into the generated schema package. Client code can use the small acp facade without losing access to fields introduced by future pinned schema releases.

func WorkspaceCapabilities added in v0.2.0

func WorkspaceCapabilities(readFiles, writeFiles, terminal bool) Capabilities

WorkspaceCapabilities advertises the filesystem and terminal host methods used by unattended clients. Every argument defaults to disabled when false.

type ClientInfo

type ClientInfo = schema.Implementation

The exported names below are intentional aliases into the generated schema package. Client code can use the small acp facade without losing access to fields introduced by future pinned schema releases.

type Connection

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

func Connect

func Connect(in io.ReadCloser, out io.WriteCloser, h Handler, n Notifications) *Connection

Connect owns both streams until Close. Frames are limited to 8 MiB; at most 32 incoming requests run concurrently. Unknown notifications can be ignored.

func (*Connection) Authenticate

func (c *Connection) Authenticate(ctx context.Context, init Initialization, method string) error

func (*Connection) Call

func (c *Connection) Call(ctx context.Context, method string, params, result any) error

func (*Connection) CallBatch added in v0.6.0

func (c *Connection) CallBatch(ctx context.Context, calls []BatchCall) []error

CallBatch sends requests as one JSON-RPC array and waits for their matching responses. Responses may be returned individually or in a response batch.

func (*Connection) CancelSession added in v0.2.0

func (c *Connection) CancelSession(ctx context.Context, sessionID SessionID) error

func (*Connection) Close

func (c *Connection) Close() error

func (*Connection) CloseSession added in v0.2.0

func (c *Connection) CloseSession(ctx context.Context, init Initialization, sessionID SessionID) error

func (*Connection) DeleteSession added in v0.2.0

func (c *Connection) DeleteSession(ctx context.Context, init Initialization, sessionID SessionID) error

func (*Connection) Done

func (c *Connection) Done() <-chan struct{}

func (*Connection) Err

func (c *Connection) Err() error

func (*Connection) Initialize

func (c *Connection) Initialize(ctx context.Context, caps Capabilities) (Initialization, error)

func (*Connection) InitializeWithInfo

func (c *Connection) InitializeWithInfo(ctx context.Context, caps Capabilities, info ClientInfo) (Initialization, error)

InitializeWithInfo negotiates ACP v1 with the calling application's identity.

func (*Connection) ListSessions added in v0.2.0

func (*Connection) LoadSession added in v0.2.0

func (*Connection) Logout added in v0.2.0

func (c *Connection) Logout(ctx context.Context, init Initialization) error

func (*Connection) NewSession

func (c *Connection) NewSession(ctx context.Context, directory string) (Session, error)

func (*Connection) NewSessionWithOptions added in v0.2.0

func (c *Connection) NewSessionWithOptions(ctx context.Context, init Initialization, directory string, options NewSessionOptions) (Session, error)

func (*Connection) Notify

func (c *Connection) Notify(ctx context.Context, method string, params any) error

func (*Connection) Prompt

func (c *Connection) Prompt(ctx context.Context, session Session, text string) (schema.StopReason, error)

func (*Connection) PromptContent added in v0.2.0

func (c *Connection) PromptContent(ctx context.Context, init Initialization, session Session, prompt []Content) (schema.StopReason, error)

func (*Connection) ResumeSession added in v0.2.0

func (*Connection) SetBooleanConfig added in v0.2.0

func (c *Connection) SetBooleanConfig(ctx context.Context, session *Session, configID string, value bool) error

SetBooleanConfig sets an advertised boolean session configuration option and verifies the agent's returned current value.

func (*Connection) SetEffort

func (c *Connection) SetEffort(ctx context.Context, session *Session, effort string) error

SetEffort uses the current model's advertised reasoning levels. Call after SetModel because model selection may replace the available effort options.

func (*Connection) SetMode

func (c *Connection) SetMode(ctx context.Context, session *Session, mode string) error

func (*Connection) SetModel

func (c *Connection) SetModel(ctx context.Context, session *Session, model string) error

SetModel selects an advertised model and verifies the agent acknowledged it. A rejected or unavailable selection must not silently use the default model.

type Content

type Content = schema.ContentBlock

The exported names below are intentional aliases into the generated schema package. Client code can use the small acp facade without losing access to fields introduced by future pinned schema releases.

func NewAudioContent added in v0.2.0

func NewAudioContent(mimeType, base64Data string) Content

func NewBlobResourceContent added in v0.2.0

func NewBlobResourceContent(uri, base64Data string) Content

func NewImageContent added in v0.2.0

func NewImageContent(mimeType, base64Data string) Content

func NewResourceLinkContent added in v0.2.0

func NewResourceLinkContent(name, uri string) Content

func NewTextContent added in v0.2.0

func NewTextContent(text string) Content

func NewTextResourceContent added in v0.2.0

func NewTextResourceContent(uri, text string) Content

type ElicitationHandler added in v0.2.0

ElicitationHandler serves typed elicitation/create requests.

type Handler

type Handler func(context.Context, string, json.RawMessage) (any, error)

Handler serves agent-to-client requests. It must honor cancellation.

func HandleElicitation added in v0.2.0

func HandleElicitation(next Handler, elicitation ElicitationHandler) Handler

HandleElicitation composes typed elicitation support with another agent-to-client request handler. Pass nil for next when elicitation is the only hosted method.

type Initialization

type Initialization = schema.InitializeResponse

The exported names below are intentional aliases into the generated schema package. Client code can use the small acp facade without losing access to fields introduced by future pinned schema releases.

type NewSessionOptions added in v0.2.0

type NewSessionOptions struct {
	AdditionalDirectories []string
	MCPServers            []schema.McpServer
}

NewSessionOptions carries optional fields for session/new.

type Notifications

type Notifications func(string, json.RawMessage) error

Notifications run in wire order, before a subsequent response is delivered. They must return promptly and must not call back into this Connection.

func CombineNotifications added in v0.2.0

func CombineNotifications(callbacks ...Notifications) Notifications

CombineNotifications fans an incoming notification out to typed adapters in order. The first error terminates the connection, matching Connection semantics.

func ElicitationComplete added in v0.2.0

func ElicitationComplete(handler func(schema.CompleteElicitationNotification) error) Notifications

ElicitationComplete adapts the agent's elicitation/complete notification to the generated notification type. Other notifications are ignored.

func SessionUpdates added in v0.2.0

func SessionUpdates(handler func(Update) error) Notifications

SessionUpdates adapts the raw connection notification callback to the generated, discriminated-union SessionNotification type. Other ACP notifications are ignored, as required by the transport layer.

type RPCError

type RPCError struct {
	Code    int             `json:"code"`
	Message string          `json:"message"`
	Data    json.RawMessage `json:"data,omitempty"`
}

RPCError preserves the peer's JSON-RPC error, including extension data.

func (*RPCError) Error

func (e *RPCError) Error() string

type Session

type Session = schema.NewSessionResponse

The exported names below are intentional aliases into the generated schema package. Client code can use the small acp facade without losing access to fields introduced by future pinned schema releases.

type SessionID added in v0.2.0

type SessionID = schema.SessionId

The exported names below are intentional aliases into the generated schema package. Client code can use the small acp facade without losing access to fields introduced by future pinned schema releases.

type Update

type Update = schema.SessionNotification

The exported names below are intentional aliases into the generated schema package. Client code can use the small acp facade without losing access to fields introduced by future pinned schema releases.

func NewAgentMessageChunkUpdate added in v0.2.0

func NewAgentMessageChunkUpdate(sessionID SessionID, chunk schema.ContentChunk) Update

func NewAgentThoughtChunkUpdate added in v0.2.0

func NewAgentThoughtChunkUpdate(sessionID SessionID, chunk schema.ContentChunk) Update

func NewAvailableCommandsUpdate added in v0.2.0

func NewAvailableCommandsUpdate(sessionID SessionID, commands []schema.AvailableCommand) Update

func NewConfigOptionUpdate added in v0.2.0

func NewConfigOptionUpdate(sessionID SessionID, options []schema.SessionConfigOption) Update

func NewCurrentModeUpdate added in v0.2.0

func NewCurrentModeUpdate(sessionID SessionID, modeID schema.SessionModeId) Update

func NewPlanUpdate added in v0.2.0

func NewPlanUpdate(sessionID SessionID, plan schema.Plan) Update

func NewSessionInfoUpdate added in v0.2.0

func NewSessionInfoUpdate(sessionID SessionID, info schema.SessionInfoUpdate) Update

func NewToolCallChangedUpdate added in v0.2.0

func NewToolCallChangedUpdate(sessionID SessionID, update schema.ToolCallUpdate) Update

func NewToolCallUpdate added in v0.2.0

func NewToolCallUpdate(sessionID SessionID, call schema.ToolCall) Update

func NewUsageUpdate added in v0.2.0

func NewUsageUpdate(sessionID SessionID, used, size uint64) Update

func NewUserMessageChunkUpdate added in v0.2.0

func NewUserMessageChunkUpdate(sessionID SessionID, chunk schema.ContentChunk) Update

Directories

Path Synopsis
Package agent serves ACP agents over stdio while giving them typed access to editor-provided client capabilities.
Package agent serves ACP agents over stdio while giving them typed access to editor-provided client capabilities.
Package agentrouter selects an explicit ACP v1 or draft-v2 agent implementation from the first initialize request.
Package agentrouter selects an explicit ACP v1 or draft-v2 agent implementation from the first initialize request.
Package clienthost provides the SDK's reference implementation of the host capabilities that an ACP agent may invoke in a client.
Package clienthost provides the SDK's reference implementation of the host capabilities that an ACP agent may invoke in a client.
cmd
acpgen command
Command acpgen generates the schema package from a pinned ACP JSON Schema release.
Command acpgen generates the schema package from a pinned ACP JSON Schema release.
examples
drive-cli command
Command drive-cli runs one unattended prompt through an external ACP CLI.
Command drive-cli runs one unattended prompt through an external ACP CLI.
minimal-agent command
Command minimal-agent is the smallest useful ACP agent.
Command minimal-agent is the smallest useful ACP agent.
minimal-agent-v2 command
Command minimal-agent-v2 demonstrates the baseline draft ACP v2 agent surface over stdio.
Command minimal-agent-v2 demonstrates the baseline draft ACP v2 agent surface over stdio.
minimal-client command
Command minimal-client launches an ACP agent command, sends one prompt, and streams agent message chunks to stdout.
Command minimal-client launches an ACP agent command, sends one prompt, and streams agent message chunks to stdout.
v2-one-shot-client command
Command v2-one-shot-client sends one ACP v2 prompt and waits for idle.
Command v2-one-shot-client sends one ACP v2 prompt and waits for idle.
internal
osrun
Package osrun supplies bounded command output for the Unix daemon.
Package osrun supplies bounded command output for the Unix daemon.
Package schema provides Go types for every message in Agent Client Protocol v1, generated from the official JSON Schema release.
Package schema provides Go types for every message in Agent Client Protocol v1, generated from the official JSON Schema release.
v2
Package v2 provides Go types for every message in the draft Agent Client Protocol v2 schema, generated from the official JSON Schema artifacts.
Package v2 provides Go types for every message in the draft Agent Client Protocol v2 schema, generated from the official JSON Schema artifacts.
v2
Package v2 is an explicit, draft-quality Go client for Agent Client Protocol v2.
Package v2 is an explicit, draft-quality Go client for Agent Client Protocol v2.
agent
Package agent serves draft ACP v2 agents over stdio and gives them typed access to editor-provided client methods.
Package agent serves draft ACP v2 agents over stdio and gives them typed access to editor-provided client methods.
mcp
Package mcp provides the draft MCP-over-ACP session options.
Package mcp provides the draft MCP-over-ACP session options.
runner
Package runner runs one draft ACP v2 agent process, submits a prompt, and waits for that session's foreground work to become idle.
Package runner runs one draft ACP v2 agent process, submits a prompt, and waits for that session's foreground work to become idle.

Jump to

Keyboard shortcuts

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