libacp

package
v0.40.3 Latest Latest
Warning

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

Go to latest
Published: Aug 15, 2026 License: Apache-2.0, Apache-2.0 Imports: 15 Imported by: 0

README

libacp

libacp is a Go implementation of the Agent Client Protocol (ACP) — the JSON-RPC-over-NDJSON protocol editors and coding agents use to talk to each other. It implements ACP v1 (ProtocolVersion = 1).

It was extracted from contenox/contenox, where it is the one deliberately public library in an otherwise internal codebase.

What it provides

libacp implements both roles of the protocol:

  • Agent side — implement the Agent interface (or embed UnimplementedAgent and override only what you need) and serve it over a transport with NewAgentSideConnection.
  • Client side — implement the Client interface (or embed UnimplementedClient) and drive an agent over a transport with NewClientSideConnection.

Both roles share the same wire machinery:

  • NDJSON framing over any io.ReadWriteCloser
  • Request-id correlation
  • Per-request cancelable contexts honoring $/cancel_request
  • Panic-safe handler dispatch
  • Extension-method passthrough

The acpexec subpackage (github.com/contenox/contenox/libacp/acpexec) spawns an agent (or client) subprocess over stdio and wires its stdin/stdout together into the io.ReadWriteCloser a connection expects, plus a Supervisor for restart/backoff around a long-lived subprocess.

Install

go get github.com/contenox/contenox/libacp

It ships inside the contenox runtime repository rather than a separate module, so cloning that repository is enough to build and test it.

Usage

Client-role usage — spawn an agent subprocess, connect, initialize, open a session, and send a prompt:

proc, err := acpexec.Spawn(ctx, exec.Command("contenox", "acp"))
if err != nil {
	return err
}

conn := libacp.NewClientSideConnection(proc, func(*libacp.ClientSideConnection) libacp.Client {
	return myClient{} // embeds libacp.UnimplementedClient
})
go conn.Run(ctx)

if _, err := conn.Initialize(ctx, libacp.InitializeRequest{
	ProtocolVersion: libacp.ProtocolVersion,
	ClientInfo:      &libacp.Implementation{Name: "my-editor", Version: "1.0"},
}); err != nil {
	return err
}

sess, err := conn.NewSession(ctx, libacp.NewSessionRequest{Cwd: "/abs/path/to/project"})
if err != nil {
	return err
}

resp, err := conn.Prompt(ctx, libacp.PromptRequest{
	SessionID: sess.SessionID,
	Prompt:    []libacp.ContentBlock{libacp.NewTextContent("hello")},
})
_ = conn.CancelPrompt(sess.SessionID) // cancel the in-flight turn from another goroutine

Agent-role usage mirrors this: implement Agent (or embed UnimplementedAgent), and serve it over a transport with NewAgentSideConnection(rw, factory).

See the package doc and the *_test.go files for further detail on individual methods, session updates, permissions, terminals, and MCP wiring.

License

Apache License 2.0 — see LICENSE.

Documentation

Overview

Package libacp implements the Agent Client Protocol (ACP) v1, the JSON-RPC-over-NDJSON protocol editors and agents use to talk to each other. It supports both roles: the agent side, implementing Agent (or embedding UnimplementedAgent) and serving it via NewAgentSideConnection; and the client side, implementing Client (or embedding UnimplementedClient) and driving an agent via NewClientSideConnection. Both share the same wire machinery: NDJSON framing, request-id correlation, per-request cancelable contexts honoring "$/cancel_request", panic-safe handler dispatch, and extension-method passthrough.

Index

Examples

Constants

View Source
const (
	ErrParseError     = -32700
	ErrInvalidRequest = -32600
	ErrMethodNotFound = -32601
	ErrInvalidParams  = -32602
	ErrInternalError  = -32603

	ErrAuthRequired = -32000
	// ErrRequestTimeout is the wire signal that a peer's handler ran out of
	// time, matching the code MCP implementations use for the same condition.
	ErrRequestTimeout   = -32001
	ErrResourceNotFound = -32002
)
View Source
const (
	AuthMethodTypeTerminal = "terminal"
	AuthMethodTypeEnvVar   = "env_var"
)
View Source
const (
	MethodInitialize   = "initialize"
	MethodAuthenticate = "authenticate"
	MethodLogout       = "logout"

	MethodSessionNew             = "session/new"
	MethodSessionLoad            = "session/load"
	MethodSessionResume          = "session/resume"
	MethodSessionClose           = "session/close"
	MethodSessionDelete          = "session/delete"
	MethodSessionList            = "session/list"
	MethodSessionPrompt          = "session/prompt"
	MethodSessionCancel          = "session/cancel"
	MethodSessionUpdate          = "session/update"
	MethodSessionSetMode         = "session/set_mode"
	MethodSessionSetConfigOption = "session/set_config_option"
	// MethodSessionSetModel is the UNSTABLE, experimental model-picker method:
	// switch a session's active model (see SetSessionModelRequest / SessionModelState).
	MethodSessionSetModel = "session/set_model"

	MethodSessionRequestPermission = "session/request_permission"

	// MethodCancelRequest is the protocol-level "$/cancel_request"
	// notification: either side may signal it no longer awaits the response to
	// an in-flight request; "$/"-prefixed methods are always safe to ignore.
	MethodCancelRequest = "$/cancel_request"

	MethodFSReadTextFile  = "fs/read_text_file"
	MethodFSWriteTextFile = "fs/write_text_file"

	MethodTerminalCreate      = "terminal/create"
	MethodTerminalOutput      = "terminal/output"
	MethodTerminalWaitForExit = "terminal/wait_for_exit"
	MethodTerminalKill        = "terminal/kill"
	MethodTerminalRelease     = "terminal/release"
)
View Source
const (
	SessionConfigOptionTypeSelect  = "select"
	SessionConfigOptionTypeBoolean = "boolean"
)

Session configuration option type discriminators (SessionConfigOption.Type).

View Source
const ExtensionMethodPrefix = "_"

ExtensionMethodPrefix is the reserved namespace for custom "extension" methods and notifications (any method name starting with underscore); "$/"-prefixed methods (MethodCancelRequest) are never extension-eligible.

View Source
const HandlerDrainTimeout = 10 * time.Second

HandlerDrainTimeout bounds how long Run waits, after shutdown cancels everything, for in-flight handler goroutines to return; a backstop for a handler that ignores its cancelled context, which should never fire normally.

View Source
const ProtocolVersion = 1

Variables

View Source
var (
	// ErrAgentStartFailed marks a failure to launch or initialize the agent
	// subprocess; not retryable (see IsStartupError).
	ErrAgentStartFailed = errors.New("libacp: agent start failed")

	// ErrIdleTimeout marks a turn that produced no session/update or result
	// past a driver's idle deadline, distinct from an overall context deadline.
	ErrIdleTimeout = errors.New("libacp: agent idle timeout")

	// ErrNoDisplayableOutput marks a turn that stopped with a normal reason
	// but never produced a renderable agent message; detect via TurnTracker.
	ErrNoDisplayableOutput = errors.New("libacp: prompt turn produced no displayable output")
)

Client-side failure sentinels for a driver of a ClientSideConnection; classify with IsStartupError / IsTimeoutError / IsRetryableError rather than string-matching.

View Source
var (
	ErrConnectionClosed = errors.New("libacp: connection closed")
)
View Source
var ErrHandlerDrainTimeout = errors.New("libacp: timed out waiting for handler goroutines to return")

ErrHandlerDrainTimeout reports that Run gave up waiting for handler goroutines to return (see HandlerDrainTimeout), so the caller's teardown of shared state may be unsafe.

Functions

func AfterResponse added in v0.38.0

func AfterResponse(ctx context.Context, fn func())

AfterResponse schedules fn to run once the current request's result is on the wire (fn runs immediately outside a request handler) — use it to emit a session/update that must reach the client only after it can resolve the session (e.g. available_commands_update after session/new).

func AsNotExist added in v0.38.0

func AsNotExist(err error) error

AsNotExist normalizes a not-found failure (per IsNotFound) into an error satisfying errors.Is(err, os.ErrNotExist); any other error, including nil, is returned unchanged.

func FlattenContent added in v0.38.0

func FlattenContent(blocks []ContentBlock) (text string, dropped []string)

FlattenContent projects a content block list down to a single string for a consumer that can only accept flat text, dropping block types it cannot represent (image, audio, blob resources, unknown) and returning them, deduplicated in first-seen order, as dropped.

func IsExtensionMethod added in v0.38.0

func IsExtensionMethod(method string) bool

IsExtensionMethod reports whether method is eligible for dispatch through an ExtRequestHandler/ExtNotificationHandler: non-empty and starting with ExtensionMethodPrefix.

func IsNotFound added in v0.38.0

func IsNotFound(err error) bool

IsNotFound reports whether err is a peer's answer of "that resource does not exist" (file/resource sense, not lifecycle): only a typed *Error with Code == ErrResourceNotFound, or a subject-describing code whose message says "not found", counts — a raw error's text and protocol-level codes are never classified here.

func IsRetryableError added in v0.38.0

func IsRetryableError(err error) bool

IsRetryableError reports whether retrying the turn might succeed: timeouts, a dropped transport, and an empty turn are retryable; cancellation and startup failures are not.

func IsStartupError added in v0.38.0

func IsStartupError(err error) bool

IsStartupError reports whether err means the agent could not be started or is unusable as configured — not fixable by retrying.

func IsTimeoutError added in v0.38.0

func IsTimeoutError(err error) bool

IsTimeoutError reports whether err is a context deadline or idle-watchdog timeout, matched by ErrRequestTimeout code since a serialized deadline loses its Go identity crossing the wire.

func NegotiateProtocolVersion added in v0.38.0

func NegotiateProtocolVersion(theirs, ours int) int

NegotiateProtocolVersion returns the protocol version two peers will speak: theirs when this peer can speak it (1 <= theirs <= ours), otherwise ours, without requiring exact equality.

Types

type Agent

type Agent interface {
	Initialize(ctx context.Context, req InitializeRequest) (InitializeResponse, error)
	Authenticate(ctx context.Context, req AuthenticateRequest) (AuthenticateResponse, error)
	Logout(ctx context.Context, req LogoutRequest) (LogoutResponse, error)
	NewSession(ctx context.Context, req NewSessionRequest) (NewSessionResponse, error)
	LoadSession(ctx context.Context, req LoadSessionRequest) (LoadSessionResponse, error)
	ResumeSession(ctx context.Context, req ResumeSessionRequest) (ResumeSessionResponse, error)
	CloseSession(ctx context.Context, req CloseSessionRequest) (CloseSessionResponse, error)
	DeleteSession(ctx context.Context, req DeleteSessionRequest) (DeleteSessionResponse, error)
	ListSessions(ctx context.Context, req ListSessionsRequest) (ListSessionsResponse, error)
	SetSessionMode(ctx context.Context, req SetSessionModeRequest) (SetSessionModeResponse, error)
	// SetSessionModel switches a session's active model; this UNSTABLE Zed
	// model-picker method (session/set_model) returns MethodNotFound when the
	// agent advertises no `models` state.
	SetSessionModel(ctx context.Context, req SetSessionModelRequest) (SetSessionModelResponse, error)
	SetSessionConfigOption(ctx context.Context, req SetSessionConfigOptionRequest) (SetSessionConfigOptionResponse, error)
	Prompt(ctx context.Context, req PromptRequest) (PromptResponse, error)
	Cancel(ctx context.Context, req CancelNotification) error
}

type AgentAuthCapabilities added in v0.38.0

type AgentAuthCapabilities struct {
	Logout *LogoutCapabilities `json:"logout,omitempty"`
	Meta   json.RawMessage     `json:"_meta,omitempty"`
}

AgentAuthCapabilities describes agent auth capabilities — currently just whether it supports the `logout` method.

type AgentCapabilities

type AgentCapabilities struct {
	LoadSession         bool                  `json:"loadSession,omitempty"`
	PromptCapabilities  PromptCapabilities    `json:"promptCapabilities,omitempty"`
	McpCapabilities     McpCapabilities       `json:"mcpCapabilities,omitempty"`
	SessionCapabilities SessionCapabilities   `json:"sessionCapabilities,omitempty"`
	Auth                AgentAuthCapabilities `json:"auth,omitempty"`
	Meta                json.RawMessage       `json:"_meta,omitempty"`
}

type AgentFactory

type AgentFactory func(conn *AgentSideConnection) Agent

type AgentSideConnection

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

func NewAgentSideConnection

func NewAgentSideConnection(rw io.ReadWriteCloser, factory AgentFactory) *AgentSideConnection

func (*AgentSideConnection) CallExtMethod added in v0.38.0

func (c *AgentSideConnection) CallExtMethod(ctx context.Context, method string, params json.RawMessage) (json.RawMessage, error)

CallExtMethod sends a custom extension request (method must satisfy IsExtensionMethod) to the client and returns its raw result; a canceled ctx aborts the wait and best-effort notifies the client with "$/cancel_request".

func (*AgentSideConnection) CloseErr

func (c *AgentSideConnection) CloseErr() error

func (*AgentSideConnection) Closed

func (c *AgentSideConnection) Closed() <-chan struct{}

func (*AgentSideConnection) CreateTerminal

func (*AgentSideConnection) KillTerminal

func (*AgentSideConnection) ReadTextFile

func (*AgentSideConnection) ReleaseTerminal

func (*AgentSideConnection) RequestPermission

func (*AgentSideConnection) Run

func (c *AgentSideConnection) Run(ctx context.Context) (err error)

func (*AgentSideConnection) SendExtNotification added in v0.38.0

func (c *AgentSideConnection) SendExtNotification(method string, params json.RawMessage) error

SendExtNotification sends a custom, fire-and-forget extension notification (method must satisfy IsExtensionMethod) to the client.

func (*AgentSideConnection) SessionUpdate

func (c *AgentSideConnection) SessionUpdate(n SessionNotification) error

func (*AgentSideConnection) SetExtNotificationHandler added in v0.38.0

func (c *AgentSideConnection) SetExtNotificationHandler(h ExtNotificationHandler)

SetExtNotificationHandler installs h, called from the AgentFactory before Run starts reading, to handle inbound extension notifications; nil (the default) silently ignores them.

func (*AgentSideConnection) SetExtRequestHandler added in v0.38.0

func (c *AgentSideConnection) SetExtRequestHandler(h ExtRequestHandler)

SetExtRequestHandler installs h, called from the AgentFactory before Run starts reading, to handle inbound extension requests (method names starting with ExtensionMethodPrefix); nil (the default) answers them with MethodNotFound.

func (*AgentSideConnection) TerminalOutput

func (*AgentSideConnection) WaitForTerminalExit

func (*AgentSideConnection) WriteTextFile

type Annotations

type Annotations struct {
	Audience []string `json:"audience,omitempty"`
	// LastModified is an ISO 8601 timestamp of when the underlying resource was last modified.
	LastModified string          `json:"lastModified,omitempty"`
	Priority     *float64        `json:"priority,omitempty"`
	Meta         json.RawMessage `json:"_meta,omitempty"`
}

type AuthCapabilities added in v0.19.0

type AuthCapabilities struct {
	Terminal bool `json:"terminal,omitempty"`
}

AuthCapabilities is the client-side auth capability object (unstable spec surface): it gates which auth method types the client can handle.

type AuthEnvVar added in v0.38.0

type AuthEnvVar struct {
	Name     string          `json:"name"`
	Label    string          `json:"label,omitempty"`
	Secret   *bool           `json:"secret,omitempty"`
	Optional bool            `json:"optional,omitempty"`
	Meta     json.RawMessage `json:"_meta,omitempty"`
}

AuthEnvVar describes one variable of an env_var auth method; Secret is a pointer because the spec default is true, so an explicit false must reach the wire while nil emits nothing.

type AuthMethod

type AuthMethod struct {
	ID          string            `json:"id"`
	Name        string            `json:"name"`
	Description string            `json:"description,omitempty"`
	Type        string            `json:"type,omitempty"`
	Args        []string          `json:"args,omitempty"`
	Env         map[string]string `json:"env,omitempty"`
	Vars        []AuthEnvVar      `json:"vars,omitempty"`
	Link        string            `json:"link,omitempty"`
	Meta        json.RawMessage   `json:"_meta,omitempty"`
}

AuthMethod covers the spec's auth method union; Type discriminates on the wire between "" (stable default), "terminal" (unstable; Args/Env launch the agent binary for a TUI), and "env_var" (unstable; Vars lists env vars).

type AuthenticateRequest

type AuthenticateRequest struct {
	MethodID string          `json:"methodId"`
	Meta     json.RawMessage `json:"_meta,omitempty"`
}

type AuthenticateResponse

type AuthenticateResponse struct {
	Meta json.RawMessage `json:"_meta,omitempty"`
}

type AvailableCommand

type AvailableCommand struct {
	Name string `json:"name"`
	// Description is spec-required (strict clients reject commands without
	// it), so no omitempty: an empty string still reaches the wire.
	Description string                 `json:"description"`
	Input       *AvailableCommandInput `json:"input,omitempty"`
	Meta        json.RawMessage        `json:"_meta,omitempty"`
}

type AvailableCommandInput

type AvailableCommandInput struct {
	Hint string `json:"hint,omitempty"`
}

type CancelNotification

type CancelNotification struct {
	SessionID SessionID       `json:"sessionId"`
	Meta      json.RawMessage `json:"_meta,omitempty"`
}

type CancelRequestNotification added in v0.38.0

type CancelRequestNotification struct {
	RequestID RequestID       `json:"requestId"`
	Meta      json.RawMessage `json:"_meta,omitempty"`
}

CancelRequestNotification is the payload of "$/cancel_request": the JSON-RPC id of the request whose response is no longer awaited.

type Client added in v0.38.0

type Client interface {
	RequestPermission(ctx context.Context, req RequestPermissionRequest) (RequestPermissionResponse, error)
	ReadTextFile(ctx context.Context, req ReadTextFileRequest) (ReadTextFileResponse, error)
	WriteTextFile(ctx context.Context, req WriteTextFileRequest) (WriteTextFileResponse, error)
	CreateTerminal(ctx context.Context, req CreateTerminalRequest) (CreateTerminalResponse, error)
	TerminalOutput(ctx context.Context, req TerminalOutputRequest) (TerminalOutputResponse, error)
	WaitForTerminalExit(ctx context.Context, req WaitForTerminalExitRequest) (WaitForTerminalExitResponse, error)
	KillTerminal(ctx context.Context, req KillTerminalRequest) (KillTerminalResponse, error)
	ReleaseTerminal(ctx context.Context, req ReleaseTerminalRequest) (ReleaseTerminalResponse, error)
	// SessionUpdate handles an inbound "session/update" notification; it has no
	// wire response, and the returned error is reported to the implementation
	// only (e.g. for logging).
	SessionUpdate(ctx context.Context, n SessionNotification) error
}

Client is the editor-side counterpart to Agent (agent.go): the set of requests an agent may send to the client, plus the inbound session/update notification.

func FilterSessionUpdates added in v0.38.0

func FilterSessionUpdates(live SessionID, inner Client) Client

FilterSessionUpdates wraps a Client so session/update notifications for any session other than live are dropped before reaching inner.SessionUpdate, every other method passing through unchanged; construct a new wrapper with the updated live id whenever the driver's active session changes.

type ClientCapabilities

type ClientCapabilities struct {
	FS       FileSystemCapabilities     `json:"fs,omitempty"`
	Terminal bool                       `json:"terminal,omitempty"`
	Session  *ClientSessionCapabilities `json:"session,omitempty"`
	Auth     AuthCapabilities           `json:"auth,omitempty"`
	Meta     json.RawMessage            `json:"_meta,omitempty"`
}

func (ClientCapabilities) SupportsBooleanConfigOptions added in v0.38.0

func (c ClientCapabilities) SupportsBooleanConfigOptions() bool

SupportsBooleanConfigOptions reports whether the client advertised clientCapabilities.session.configOptions.boolean.

type ClientFactory added in v0.38.0

type ClientFactory func(conn *ClientSideConnection) Client

type ClientSessionCapabilities added in v0.38.0

type ClientSessionCapabilities struct {
	ConfigOptions *SessionConfigOptionsCapabilities `json:"configOptions,omitempty"`
	Meta          json.RawMessage                   `json:"_meta,omitempty"`
}

ClientSessionCapabilities mirrors the spec's clientCapabilities.session.

type ClientSideConnection added in v0.38.0

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

ClientSideConnection is the editor-side mirror of AgentSideConnection (conn.go): it dispatches incoming agent->client requests and the session/update notification to a Client, and exposes the client->agent methods as outbound calls.

func NewClientSideConnection added in v0.38.0

func NewClientSideConnection(rw io.ReadWriteCloser, factory ClientFactory) *ClientSideConnection

func (*ClientSideConnection) Authenticate added in v0.38.0

func (*ClientSideConnection) CallExtMethod added in v0.38.0

func (c *ClientSideConnection) CallExtMethod(ctx context.Context, method string, params json.RawMessage) (json.RawMessage, error)

CallExtMethod sends a custom extension request (method must satisfy IsExtensionMethod) to the agent and returns its raw result.

func (*ClientSideConnection) CancelPrompt added in v0.38.0

func (c *ClientSideConnection) CancelPrompt(sessionID SessionID) error

CancelPrompt cancels sessionID's in-flight prompt turn: sends "session/cancel" and, for as long as this session's Prompt call remains outstanding, auto-resolves every session/request_permission request for sessionID with the "cancelled" outcome instead of invoking Client.RequestPermission; with no outstanding Prompt call, behaves exactly like CancelSession.

func (*ClientSideConnection) CancelSession added in v0.38.0

func (c *ClientSideConnection) CancelSession(req CancelNotification) error

CancelSession sends "session/cancel" — a notification, not a request, per spec: the agent must resolve the in-flight session/prompt call itself with stop reason "cancelled"; use CancelPrompt for the pending-permission auto-cancel rule.

func (*ClientSideConnection) CloseErr added in v0.38.0

func (c *ClientSideConnection) CloseErr() error

func (*ClientSideConnection) CloseSession added in v0.38.0

func (*ClientSideConnection) Closed added in v0.38.0

func (c *ClientSideConnection) Closed() <-chan struct{}

func (*ClientSideConnection) DeleteSession added in v0.38.0

func (*ClientSideConnection) Initialize added in v0.38.0

func (*ClientSideConnection) ListSessions added in v0.38.0

func (*ClientSideConnection) LoadSession added in v0.38.0

func (*ClientSideConnection) Logout added in v0.38.0

Logout is only meaningful when the agent advertised AgentCapabilities.Auth.Logout during initialize.

func (*ClientSideConnection) NewSession added in v0.38.0

func (*ClientSideConnection) Prompt added in v0.38.0

Prompt registers req.SessionID's turn in promptTurns for the call's duration so CancelPrompt and promptCancelling can find it, removing only its own entry on return so it can't clobber a later overlapping call.

func (*ClientSideConnection) ResumeSession added in v0.38.0

func (*ClientSideConnection) Run added in v0.38.0

func (c *ClientSideConnection) Run(ctx context.Context) (err error)

func (*ClientSideConnection) SendExtNotification added in v0.38.0

func (c *ClientSideConnection) SendExtNotification(method string, params json.RawMessage) error

SendExtNotification sends a custom, fire-and-forget extension notification (method must satisfy IsExtensionMethod) to the agent.

func (*ClientSideConnection) SetExtNotificationHandler added in v0.38.0

func (c *ClientSideConnection) SetExtNotificationHandler(h ExtNotificationHandler)

SetExtNotificationHandler installs h, called from the ClientFactory before Run starts reading, to handle inbound extension notifications; nil (the default) silently ignores them.

func (*ClientSideConnection) SetExtRequestHandler added in v0.38.0

func (c *ClientSideConnection) SetExtRequestHandler(h ExtRequestHandler)

SetExtRequestHandler installs h, called from the ClientFactory before Run starts reading, to handle inbound extension requests; nil (the default) answers them with MethodNotFound.

func (*ClientSideConnection) SetSessionConfigOption added in v0.38.0

func (*ClientSideConnection) SetSessionMode added in v0.38.0

SetSessionMode switches a session to a different SessionMode.ID, one of the ids the session's SessionModeState.AvailableModes advertised.

func (*ClientSideConnection) SetSessionModel added in v0.38.0

SetSessionModel switches a session to a different ModelInfo.ID (one of the ids SessionModelState.AvailableModels advertised) via the unstable Zed model-picker method (session/set_model); on success the requested model is authoritative, and no session/update kind reconfirms it.

type CloseSessionRequest added in v0.38.0

type CloseSessionRequest struct {
	SessionID SessionID       `json:"sessionId"`
	Meta      json.RawMessage `json:"_meta,omitempty"`
}

type CloseSessionResponse added in v0.38.0

type CloseSessionResponse struct {
	Meta json.RawMessage `json:"_meta,omitempty"`
}

type ContentBlock

type ContentBlock struct {
	Type        string            `json:"type"`
	Text        string            `json:"text,omitempty"`
	Data        string            `json:"data,omitempty"`
	MimeType    string            `json:"mimeType,omitempty"`
	URI         string            `json:"uri,omitempty"`
	Name        string            `json:"name,omitempty"`
	Title       string            `json:"title,omitempty"`
	Description string            `json:"description,omitempty"`
	Size        *int64            `json:"size,omitempty"`
	Resource    *EmbeddedResource `json:"resource,omitempty"`
	Annotations *Annotations      `json:"annotations,omitempty"`
	Meta        json.RawMessage   `json:"_meta,omitempty"`
}

func NewAudioContent added in v0.40.0

func NewAudioContent(data, mimeType string) ContentBlock

NewAudioContent builds an audio content block; data is standard base64.

func NewImageContent

func NewImageContent(data, mimeType string) ContentBlock

func NewResourceContent

func NewResourceContent(resource EmbeddedResource) ContentBlock
func NewResourceLink(uri, name string) ContentBlock

func NewTextContent

func NewTextContent(text string) ContentBlock

type ContentKind

type ContentKind string
const (
	ContentKindText         ContentKind = "text"
	ContentKindImage        ContentKind = "image"
	ContentKindAudio        ContentKind = "audio"
	ContentKindResource     ContentKind = "resource"
	ContentKindResourceLink ContentKind = "resource_link"
)

type CreateTerminalRequest

type CreateTerminalRequest struct {
	SessionID       SessionID       `json:"sessionId"`
	Command         string          `json:"command"`
	Args            []string        `json:"args,omitempty"`
	Env             []EnvVariable   `json:"env,omitempty"`
	Cwd             string          `json:"cwd,omitempty"`
	OutputByteLimit *int64          `json:"outputByteLimit,omitempty"`
	Meta            json.RawMessage `json:"_meta,omitempty"`
}

type CreateTerminalResponse

type CreateTerminalResponse struct {
	TerminalID string          `json:"terminalId"`
	Meta       json.RawMessage `json:"_meta,omitempty"`
}

type DeleteSessionRequest added in v0.38.0

type DeleteSessionRequest struct {
	SessionID SessionID       `json:"sessionId"`
	Meta      json.RawMessage `json:"_meta,omitempty"`
}

type DeleteSessionResponse added in v0.38.0

type DeleteSessionResponse struct {
	Meta json.RawMessage `json:"_meta,omitempty"`
}

type EmbeddedResource

type EmbeddedResource struct {
	URI      string          `json:"uri"`
	MimeType string          `json:"mimeType,omitempty"`
	Text     string          `json:"text,omitempty"`
	Blob     string          `json:"blob,omitempty"`
	Meta     json.RawMessage `json:"_meta,omitempty"`
}

type EnvVariable

type EnvVariable struct {
	Name  string `json:"name"`
	Value string `json:"value"`
}

type Error

type Error struct {
	Code    int             `json:"code"`
	Message string          `json:"message"`
	Data    json.RawMessage `json:"data,omitempty"`
	// contains filtered or unexported fields
}

Error is a JSON-RPC error object; the exported fields are the entire wire contract, and cause is process-local and never serialized.

func AsError

func AsError(err error) *Error

AsError converts a handler error into the JSON-RPC error that goes on the wire, retaining err as cause and promoting a deadline to ErrRequestTimeout so a remote caller can tell "too slow, retry" from "broken, give up".

func InternalError

func InternalError(msg string) *Error

func InvalidParams

func InvalidParams(msg string) *Error

func InvalidRequest

func InvalidRequest(msg string) *Error

func MethodNotFound

func MethodNotFound(method string) *Error

func NewError

func NewError(code int, message string) *Error

func NewErrorf

func NewErrorf(code int, format string, args ...any) *Error

func ParseError

func ParseError(msg string) *Error

func (*Error) Error

func (e *Error) Error() string

func (*Error) Unwrap added in v0.38.0

func (e *Error) Unwrap() error

Unwrap exposes the originating handler error; an Error decoded from the wire has no cause and returns nil.

type ExtNotificationHandler added in v0.38.0

type ExtNotificationHandler func(ctx context.Context, method string, params json.RawMessage)

ExtNotificationHandler handles an inbound extension notification, fire-and-forget.

type ExtRequestHandler added in v0.38.0

type ExtRequestHandler func(ctx context.Context, method string, params json.RawMessage) (json.RawMessage, *Error)

ExtRequestHandler handles an inbound extension request (method not in the core ACP set but IsExtensionMethod), returning a raw JSON result or an *Error.

type FileSystemCapabilities

type FileSystemCapabilities struct {
	ReadTextFile  bool            `json:"readTextFile,omitempty"`
	WriteTextFile bool            `json:"writeTextFile,omitempty"`
	Meta          json.RawMessage `json:"_meta,omitempty"`
}

type HttpHeader

type HttpHeader struct {
	Name  string `json:"name"`
	Value string `json:"value"`
}

type Implementation

type Implementation struct {
	Name    string `json:"name"`
	Title   string `json:"title,omitempty"`
	Version string `json:"version,omitempty"`
}

type Incoming

type Incoming struct {
	Kind         IncomingKind
	Request      Request
	Notification Notification
	Response     Response
}

func ParseIncoming

func ParseIncoming(data []byte) (Incoming, error)

type IncomingKind

type IncomingKind uint8
const (
	IncomingKindUnknown IncomingKind = iota
	IncomingKindRequest
	IncomingKindNotification
	IncomingKindResponse
)

type InitializeRequest

type InitializeRequest struct {
	ProtocolVersion    int                `json:"protocolVersion"`
	ClientCapabilities ClientCapabilities `json:"clientCapabilities,omitempty"`
	ClientInfo         *Implementation    `json:"clientInfo,omitempty"`
	Meta               json.RawMessage    `json:"_meta,omitempty"`
}

type InitializeResponse

type InitializeResponse struct {
	ProtocolVersion   int               `json:"protocolVersion"`
	AgentCapabilities AgentCapabilities `json:"agentCapabilities,omitempty"`
	AgentInfo         *Implementation   `json:"agentInfo,omitempty"`
	AuthMethods       []AuthMethod      `json:"authMethods,omitempty"`
	Meta              json.RawMessage   `json:"_meta,omitempty"`
}

type KillTerminalRequest

type KillTerminalRequest struct {
	SessionID  SessionID       `json:"sessionId"`
	TerminalID string          `json:"terminalId"`
	Meta       json.RawMessage `json:"_meta,omitempty"`
}

type KillTerminalResponse

type KillTerminalResponse struct {
	Meta json.RawMessage `json:"_meta,omitempty"`
}

type ListSessionsRequest

type ListSessionsRequest struct {
	Cwd    string          `json:"cwd,omitempty"`
	Cursor string          `json:"cursor,omitempty"`
	Meta   json.RawMessage `json:"_meta,omitempty"`
}

type ListSessionsResponse

type ListSessionsResponse struct {
	Sessions   []SessionInfo   `json:"sessions"`
	NextCursor string          `json:"nextCursor,omitempty"`
	Meta       json.RawMessage `json:"_meta,omitempty"`
}

type LoadSessionRequest

type LoadSessionRequest struct {
	SessionID SessionID `json:"sessionId"`
	Cwd       string    `json:"cwd"`
	// AdditionalDirectories are extra workspace roots on top of Cwd; each path
	// must be absolute.
	AdditionalDirectories []string        `json:"additionalDirectories,omitempty"`
	McpServers            []McpServer     `json:"mcpServers"`
	Meta                  json.RawMessage `json:"_meta,omitempty"`
}

type LoadSessionResponse

type LoadSessionResponse struct {
	Modes         *SessionModeState     `json:"modes,omitempty"`
	Models        *SessionModelState    `json:"models,omitempty"`
	ConfigOptions []SessionConfigOption `json:"configOptions,omitempty"`
	Meta          json.RawMessage       `json:"_meta,omitempty"`
}

type LogoutCapabilities added in v0.38.0

type LogoutCapabilities struct {
	Meta json.RawMessage `json:"_meta,omitempty"`
}

LogoutCapabilities is present ({}) when the agent supports the `logout` method.

type LogoutRequest added in v0.38.0

type LogoutRequest struct {
	Meta json.RawMessage `json:"_meta,omitempty"`
}

LogoutRequest terminates the current authenticated session; only meaningful when the agent advertises AgentCapabilities.Auth.Logout.

type LogoutResponse added in v0.38.0

type LogoutResponse struct {
	Meta json.RawMessage `json:"_meta,omitempty"`
}

type McpCapabilities

type McpCapabilities struct {
	HTTP bool            `json:"http,omitempty"`
	SSE  bool            `json:"sse,omitempty"`
	Meta json.RawMessage `json:"_meta,omitempty"`
}

type McpServer

type McpServer struct {
	Type    string          `json:"type,omitempty"`
	Name    string          `json:"name"`
	Command string          `json:"command,omitempty"`
	Args    []string        `json:"args,omitempty"`
	Env     []EnvVariable   `json:"env,omitempty"`
	URL     string          `json:"url,omitempty"`
	Headers []HttpHeader    `json:"headers,omitempty"`
	Meta    json.RawMessage `json:"_meta,omitempty"`
}

func (McpServer) Kind

func (m McpServer) Kind() McpServerKind

func (McpServer) MarshalJSON added in v0.38.0

func (m McpServer) MarshalJSON() ([]byte, error)

MarshalJSON forces args/env (stdio) and headers (http/sse) onto the wire as `[]` rather than omitting them when empty, since the spec requires them always present.

func (McpServer) Validate

func (m McpServer) Validate() error

type McpServerKind

type McpServerKind string
const (
	McpServerKindStdio McpServerKind = ""
	McpServerKindHTTP  McpServerKind = "http"
	McpServerKindSSE   McpServerKind = "sse"
)

type ModelInfo added in v0.38.0

type ModelInfo struct {
	ID          string          `json:"modelId"`
	Name        string          `json:"name"`
	Description string          `json:"description,omitempty"`
	Meta        json.RawMessage `json:"_meta,omitempty"`
}

ModelInfo describes one selectable model in a SessionModelState (UNSTABLE model-picker surface); ID is the stable identifier passed back in SetSessionModelRequest.

type NewSessionRequest

type NewSessionRequest struct {
	Cwd string `json:"cwd"`
	// AdditionalDirectories are extra workspace roots on top of Cwd; each path
	// must be absolute.
	AdditionalDirectories []string        `json:"additionalDirectories,omitempty"`
	McpServers            []McpServer     `json:"mcpServers"`
	Meta                  json.RawMessage `json:"_meta,omitempty"`
}

type NewSessionResponse

type NewSessionResponse struct {
	SessionID SessionID         `json:"sessionId"`
	Modes     *SessionModeState `json:"modes,omitempty"`
	// Models is the UNSTABLE model-picker surface (see SessionModelState); nil
	// means the agent exposes no selectable model.
	Models        *SessionModelState    `json:"models,omitempty"`
	ConfigOptions []SessionConfigOption `json:"configOptions,omitempty"`
	Meta          json.RawMessage       `json:"_meta,omitempty"`
}

type Notification

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

func NewNotification

func NewNotification(method string, params json.RawMessage) Notification

type PermissionOption

type PermissionOption struct {
	OptionID string               `json:"optionId"`
	Name     string               `json:"name"`
	Kind     PermissionOptionKind `json:"kind"`
	Meta     json.RawMessage      `json:"_meta,omitempty"`
}

type PermissionOptionKind

type PermissionOptionKind string
const (
	PermissionAllowOnce    PermissionOptionKind = "allow_once"
	PermissionAllowAlways  PermissionOptionKind = "allow_always"
	PermissionRejectOnce   PermissionOptionKind = "reject_once"
	PermissionRejectAlways PermissionOptionKind = "reject_always"
)

type PermissionOutcomeKind

type PermissionOutcomeKind string
const (
	PermissionOutcomeCancelled PermissionOutcomeKind = "cancelled"
	PermissionOutcomeSelected  PermissionOutcomeKind = "selected"
)

type PermissionToolCall

type PermissionToolCall struct {
	ToolCallID string             `json:"toolCallId"`
	Title      string             `json:"title,omitempty"`
	Kind       ToolKind           `json:"kind,omitempty"`
	Status     ToolCallStatus     `json:"status,omitempty"`
	Content    []ToolCallContent  `json:"content,omitempty"`
	Locations  []ToolCallLocation `json:"locations,omitempty"`
	RawInput   json.RawMessage    `json:"rawInput,omitempty"`
	RawOutput  json.RawMessage    `json:"rawOutput,omitempty"`
	Meta       json.RawMessage    `json:"_meta,omitempty"`
}

type PlanEntry

type PlanEntry struct {
	Content  string            `json:"content"`
	Priority PlanEntryPriority `json:"priority"`
	Status   PlanEntryStatus   `json:"status"`
	Meta     json.RawMessage   `json:"_meta,omitempty"`
}

type PlanEntryPriority

type PlanEntryPriority string
const (
	PlanPriorityHigh   PlanEntryPriority = "high"
	PlanPriorityMedium PlanEntryPriority = "medium"
	PlanPriorityLow    PlanEntryPriority = "low"
)

type PlanEntryStatus

type PlanEntryStatus string
const (
	PlanStatusPending    PlanEntryStatus = "pending"
	PlanStatusInProgress PlanEntryStatus = "in_progress"
	PlanStatusCompleted  PlanEntryStatus = "completed"
)

type PromptCapabilities

type PromptCapabilities struct {
	Image           bool            `json:"image,omitempty"`
	Audio           bool            `json:"audio,omitempty"`
	EmbeddedContext bool            `json:"embeddedContext,omitempty"`
	Meta            json.RawMessage `json:"_meta,omitempty"`
}

type PromptRequest

type PromptRequest struct {
	SessionID SessionID       `json:"sessionId"`
	Prompt    []ContentBlock  `json:"prompt"`
	Meta      json.RawMessage `json:"_meta,omitempty"`
}

type PromptResponse

type PromptResponse struct {
	StopReason StopReason      `json:"stopReason"`
	Meta       json.RawMessage `json:"_meta,omitempty"`
}

PromptResponse is the result of a "session/prompt" request; per the ACP v1 schema it carries only stopReason and _meta, with per-turn usage/cost belonging on the "usage_update" SessionUpdate instead.

type ReadTextFileRequest

type ReadTextFileRequest struct {
	SessionID SessionID       `json:"sessionId"`
	Path      string          `json:"path"`
	Line      *int            `json:"line,omitempty"`
	Limit     *int            `json:"limit,omitempty"`
	Meta      json.RawMessage `json:"_meta,omitempty"`
}

type ReadTextFileResponse

type ReadTextFileResponse struct {
	Content string          `json:"content"`
	Meta    json.RawMessage `json:"_meta,omitempty"`
}

type ReleaseTerminalRequest

type ReleaseTerminalRequest struct {
	SessionID  SessionID       `json:"sessionId"`
	TerminalID string          `json:"terminalId"`
	Meta       json.RawMessage `json:"_meta,omitempty"`
}

type ReleaseTerminalResponse

type ReleaseTerminalResponse struct {
	Meta json.RawMessage `json:"_meta,omitempty"`
}

type Request

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

func NewRequest

func NewRequest(id RequestID, method string, params json.RawMessage) Request

type RequestID

type RequestID struct {
	Kind   RequestIDKind
	Number int64
	String string
}

func NewRequestIDNull

func NewRequestIDNull() RequestID

func NewRequestIDNumber

func NewRequestIDNumber(n int64) RequestID

func NewRequestIDString

func NewRequestIDString(s string) RequestID

func (RequestID) Equal

func (r RequestID) Equal(other RequestID) bool

func (RequestID) MarshalJSON

func (r RequestID) MarshalJSON() ([]byte, error)

func (RequestID) String_

func (r RequestID) String_() string

func (*RequestID) UnmarshalJSON

func (r *RequestID) UnmarshalJSON(data []byte) error

type RequestIDKind

type RequestIDKind uint8
const (
	RequestIDKindNull RequestIDKind = iota
	RequestIDKindNumber
	RequestIDKindString
)

type RequestPermissionOutcome

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

func (*RequestPermissionOutcome) UnmarshalJSON

func (o *RequestPermissionOutcome) UnmarshalJSON(data []byte) error

type RequestPermissionRequest

type RequestPermissionRequest struct {
	SessionID SessionID          `json:"sessionId"`
	ToolCall  PermissionToolCall `json:"toolCall"`
	Options   []PermissionOption `json:"options"`
	Meta      json.RawMessage    `json:"_meta,omitempty"`
}

type RequestPermissionResponse

type RequestPermissionResponse struct {
	Outcome RequestPermissionOutcome `json:"outcome"`
	Meta    json.RawMessage          `json:"_meta,omitempty"`
}

type Response

type Response struct {
	JSONRPC string          `json:"jsonrpc"`
	ID      RequestID       `json:"id"`
	Result  json.RawMessage `json:"result,omitempty"`
	Error   *Error          `json:"error,omitempty"`
}

func NewErrorResponse

func NewErrorResponse(id RequestID, err *Error) Response

func NewResultResponse

func NewResultResponse(id RequestID, result json.RawMessage) Response

type ResumeSessionRequest added in v0.38.0

type ResumeSessionRequest struct {
	SessionID SessionID `json:"sessionId"`
	Cwd       string    `json:"cwd"`
	// AdditionalDirectories are extra workspace roots on top of Cwd; each path
	// must be absolute.
	AdditionalDirectories []string        `json:"additionalDirectories,omitempty"`
	McpServers            []McpServer     `json:"mcpServers,omitempty"`
	Meta                  json.RawMessage `json:"_meta,omitempty"`
}

ResumeSessionRequest reconnects to an existing session without history replay (the client kept its transcript); McpServers is optional here, unlike session/new and session/load.

type ResumeSessionResponse added in v0.38.0

type ResumeSessionResponse struct {
	Modes         *SessionModeState     `json:"modes,omitempty"`
	Models        *SessionModelState    `json:"models,omitempty"`
	ConfigOptions []SessionConfigOption `json:"configOptions,omitempty"`
	Meta          json.RawMessage       `json:"_meta,omitempty"`
}

type SessionCapabilities

type SessionCapabilities struct {
	List   *struct{} `json:"list,omitempty"`
	Resume *struct{} `json:"resume,omitempty"`
	Close  *struct{} `json:"close,omitempty"`
	Delete *struct{} `json:"delete,omitempty"`
	// AdditionalDirectories present ({}) means the agent honors
	// additionalDirectories on session/new, session/load, and session/resume,
	// and may report SessionInfo.AdditionalDirectories from session/list.
	AdditionalDirectories *struct{}       `json:"additionalDirectories,omitempty"`
	Meta                  json.RawMessage `json:"_meta,omitempty"`
}

type SessionConfigGroup added in v0.38.0

type SessionConfigGroup struct {
	Group   string               `json:"group"`
	Name    string               `json:"name"`
	Options []SessionConfigValue `json:"options"`
	Meta    json.RawMessage      `json:"_meta,omitempty"`
}

type SessionConfigOption added in v0.38.0

type SessionConfigOption struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
	Category    string `json:"category,omitempty"`
	Type        string `json:"type"`
	// CurrentValue is always the Go-side string form: the selected
	// SessionConfigValue.Value id for Select, "true"/"false" for Boolean.
	CurrentValue string              `json:"currentValue"`
	Options      SessionConfigValues `json:"options"`
	Meta         json.RawMessage     `json:"_meta,omitempty"`
}

func (SessionConfigOption) MarshalJSON added in v0.38.0

func (o SessionConfigOption) MarshalJSON() ([]byte, error)

func (*SessionConfigOption) UnmarshalJSON added in v0.38.0

func (o *SessionConfigOption) UnmarshalJSON(data []byte) error

type SessionConfigOptionValue added in v0.38.0

type SessionConfigOptionValue struct {
	IsBool bool
	Str    string
	Bool   bool
}

SessionConfigOptionValue is the value union of session/set_config_option: a plain string value id (default) or a boolean (request Type "boolean").

Example
package main

import (
	"encoding/json"
	"fmt"

	"github.com/contenox/contenox/libacp"
)

func main() {
	var req libacp.SetSessionConfigOptionRequest
	_ = json.Unmarshal([]byte(`{"sessionId":"s","configId":"c","value":"model-x"}`), &req)
	fmt.Println(req.Value.AsString(), req.Value.IsBool)

	_ = json.Unmarshal([]byte(`{"sessionId":"s","configId":"c","type":"boolean","value":true}`), &req)
	fmt.Println(req.Value.AsString(), req.Value.IsBool)
}
Output:
model-x false
true true

func BoolConfigValue added in v0.38.0

func BoolConfigValue(b bool) SessionConfigOptionValue

func StringConfigValue added in v0.38.0

func StringConfigValue(s string) SessionConfigOptionValue

func (SessionConfigOptionValue) AsString added in v0.38.0

func (v SessionConfigOptionValue) AsString() string

AsString renders the value for consumers that key handling off strings; booleans become "true"/"false".

func (SessionConfigOptionValue) MarshalJSON added in v0.38.0

func (v SessionConfigOptionValue) MarshalJSON() ([]byte, error)

func (*SessionConfigOptionValue) UnmarshalJSON added in v0.38.0

func (v *SessionConfigOptionValue) UnmarshalJSON(data []byte) error

type SessionConfigOptionsCapabilities added in v0.38.0

type SessionConfigOptionsCapabilities struct {
	// Boolean present ({}) means the client accepts type:"boolean" config
	// options and may send boolean set_config_option values.
	Boolean *struct{}       `json:"boolean,omitempty"`
	Meta    json.RawMessage `json:"_meta,omitempty"`
}

type SessionConfigValue added in v0.38.0

type SessionConfigValue struct {
	Value       string          `json:"value"`
	Name        string          `json:"name"`
	Description string          `json:"description,omitempty"`
	Meta        json.RawMessage `json:"_meta,omitempty"`
}

type SessionConfigValues added in v0.38.0

type SessionConfigValues struct {
	Values []SessionConfigValue
	Groups []SessionConfigGroup
}

func NewGroupedSessionConfigValues added in v0.38.0

func NewGroupedSessionConfigValues(groups []SessionConfigGroup) SessionConfigValues

func NewSessionConfigValues added in v0.38.0

func NewSessionConfigValues(values []SessionConfigValue) SessionConfigValues

func (SessionConfigValues) AllValues added in v0.38.0

func (v SessionConfigValues) AllValues() []SessionConfigValue

func (SessionConfigValues) MarshalJSON added in v0.38.0

func (v SessionConfigValues) MarshalJSON() ([]byte, error)

func (*SessionConfigValues) UnmarshalJSON added in v0.38.0

func (v *SessionConfigValues) UnmarshalJSON(data []byte) error

type SessionID

type SessionID string

type SessionInfo

type SessionInfo struct {
	SessionID SessionID `json:"sessionId"`
	Cwd       string    `json:"cwd,omitempty"`
	// AdditionalDirectories is the ordered additional-root list, when tracked.
	AdditionalDirectories []string        `json:"additionalDirectories,omitempty"`
	Title                 string          `json:"title,omitempty"`
	UpdatedAt             string          `json:"updatedAt,omitempty"`
	Meta                  json.RawMessage `json:"_meta,omitempty"`
}

type SessionMode

type SessionMode struct {
	ID          string          `json:"id"`
	Name        string          `json:"name"`
	Description string          `json:"description,omitempty"`
	Meta        json.RawMessage `json:"_meta,omitempty"`
}

type SessionModeState added in v0.38.0

type SessionModeState struct {
	CurrentModeID  string          `json:"currentModeId"`
	AvailableModes []SessionMode   `json:"availableModes"`
	Meta           json.RawMessage `json:"_meta,omitempty"`
}

SessionModeState is the wire shape for `modes` in session/new and session/load responses: an object, not a bare array.

type SessionModelState added in v0.38.0

type SessionModelState struct {
	CurrentModelID  string          `json:"currentModelId"`
	AvailableModels []ModelInfo     `json:"availableModels"`
	Meta            json.RawMessage `json:"_meta,omitempty"`
}

SessionModelState is the UNSTABLE model-picker surface: the wire shape of the optional `models` field in session/new, session/load, and session/resume responses, mirroring SessionModeState for modes.

type SessionNotification

type SessionNotification struct {
	SessionID SessionID       `json:"sessionId"`
	Update    SessionUpdate   `json:"update"`
	Meta      json.RawMessage `json:"_meta,omitempty"`
}

type SessionUpdate

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

	Content *ContentBlock `json:"-"`

	ToolCallID  string             `json:"toolCallId,omitempty"`
	Title       string             `json:"title,omitempty"`
	Kind        ToolKind           `json:"kind,omitempty"`
	Status      ToolCallStatus     `json:"status,omitempty"`
	ToolContent []ToolCallContent  `json:"-"`
	Locations   []ToolCallLocation `json:"locations,omitempty"`
	RawInput    json.RawMessage    `json:"rawInput,omitempty"`
	RawOutput   json.RawMessage    `json:"rawOutput,omitempty"`

	Entries []PlanEntry `json:"entries,omitempty"`

	AvailableCommands []AvailableCommand `json:"availableCommands,omitempty"`

	CurrentModeID string `json:"currentModeId,omitempty"`

	ConfigOptions []SessionConfigOption `json:"configOptions,omitempty"`

	// Used, Size, Cost: usage_update fields (session context indicator).
	Used int        `json:"used,omitempty"`
	Size int        `json:"size,omitempty"`
	Cost *UsageCost `json:"cost,omitempty"`

	// MessageID groups streamed chunks into messages: all chunks of one message
	// share an id, and a change marks a new message.
	MessageID string `json:"messageId,omitempty"`

	// UpdatedAt is the session_info_update timestamp (ISO 8601); Title above is
	// shared with tool_call updates (same wire key).
	UpdatedAt string `json:"updatedAt,omitempty"`

	Meta json.RawMessage `json:"_meta,omitempty"`
}

func NewAgentMessageChunk

func NewAgentMessageChunk(text string) SessionUpdate

func NewAgentThoughtChunk

func NewAgentThoughtChunk(text string) SessionUpdate

func NewUserMessageChunk

func NewUserMessageChunk(text string) SessionUpdate

func (SessionUpdate) MarshalJSON

func (u SessionUpdate) MarshalJSON() ([]byte, error)

func (*SessionUpdate) UnmarshalJSON

func (u *SessionUpdate) UnmarshalJSON(data []byte) error

type SessionUpdateKind

type SessionUpdateKind string
const (
	SessionUpdateUserMessageChunk  SessionUpdateKind = "user_message_chunk"
	SessionUpdateAgentMessageChunk SessionUpdateKind = "agent_message_chunk"
	SessionUpdateAgentThoughtChunk SessionUpdateKind = "agent_thought_chunk"
	SessionUpdateToolCall          SessionUpdateKind = "tool_call"
	SessionUpdateToolCallUpdate    SessionUpdateKind = "tool_call_update"
	SessionUpdatePlan              SessionUpdateKind = "plan"
	SessionUpdateAvailableCommands SessionUpdateKind = "available_commands_update"
	SessionUpdateCurrentMode       SessionUpdateKind = "current_mode_update"
	SessionUpdateConfigOption      SessionUpdateKind = "config_option_update"
	SessionUpdateUsageUpdate       SessionUpdateKind = "usage_update"
	SessionUpdateSessionInfo       SessionUpdateKind = "session_info_update"
)

func AllSessionUpdateKinds added in v0.38.0

func AllSessionUpdateKinds() []SessionUpdateKind

AllSessionUpdateKinds returns every SessionUpdateKind the spec defines, in declaration order, so a consumer's translation table can be tested for completeness against the library.

type SetSessionConfigOptionRequest added in v0.38.0

type SetSessionConfigOptionRequest struct {
	SessionID SessionID `json:"sessionId"`
	ConfigID  string    `json:"configId"`
	// Type discriminates the value variant: absent/unknown means Value is a
	// string value id (the default), "boolean" means Value is a bool.
	Type  string                   `json:"type,omitempty"`
	Value SessionConfigOptionValue `json:"value"`
	Meta  json.RawMessage          `json:"_meta,omitempty"`
}

type SetSessionConfigOptionResponse added in v0.38.0

type SetSessionConfigOptionResponse struct {
	ConfigOptions []SessionConfigOption `json:"configOptions"`
	Meta          json.RawMessage       `json:"_meta,omitempty"`
}

type SetSessionModeRequest added in v0.38.0

type SetSessionModeRequest struct {
	SessionID SessionID       `json:"sessionId"`
	ModeID    string          `json:"modeId"`
	Meta      json.RawMessage `json:"_meta,omitempty"`
}

SetSessionModeRequest is session/set_mode's params: switch a session to one of the ids SessionModeState.AvailableModes advertised.

type SetSessionModeResponse added in v0.38.0

type SetSessionModeResponse struct {
	Meta json.RawMessage `json:"_meta,omitempty"`
}

type SetSessionModelRequest added in v0.38.0

type SetSessionModelRequest struct {
	SessionID SessionID       `json:"sessionId"`
	ModelID   string          `json:"modelId"`
	Meta      json.RawMessage `json:"_meta,omitempty"`
}

SetSessionModelRequest is session/set_model's (UNSTABLE model-picker surface) params: switch a session to one of the ids SessionModelState.AvailableModels advertised.

type SetSessionModelResponse added in v0.38.0

type SetSessionModelResponse struct {
	Meta json.RawMessage `json:"_meta,omitempty"`
}

SetSessionModelResponse is session/set_model's result: always empty — the requested modelId is authoritative on success, and no session/update kind exists to reconfirm it.

type StopReason

type StopReason string
const (
	StopReasonEndTurn         StopReason = "end_turn"
	StopReasonMaxTokens       StopReason = "max_tokens"
	StopReasonMaxTurnRequests StopReason = "max_turn_requests"
	StopReasonRefusal         StopReason = "refusal"
	StopReasonCancelled       StopReason = "cancelled"
)

type TerminalExitStatus

type TerminalExitStatus struct {
	ExitCode *int    `json:"exitCode,omitempty"`
	Signal   *string `json:"signal,omitempty"`
}

type TerminalOutputRequest

type TerminalOutputRequest struct {
	SessionID  SessionID       `json:"sessionId"`
	TerminalID string          `json:"terminalId"`
	Meta       json.RawMessage `json:"_meta,omitempty"`
}

type TerminalOutputResponse

type TerminalOutputResponse struct {
	Output     string              `json:"output"`
	Truncated  bool                `json:"truncated"`
	ExitStatus *TerminalExitStatus `json:"exitStatus,omitempty"`
	Meta       json.RawMessage     `json:"_meta,omitempty"`
}

type TerminalPeer added in v0.38.0

TerminalPeer is the subset of the ACP client side that RunTerminal drives; *AgentSideConnection satisfies it.

type TerminalResult added in v0.38.0

type TerminalResult struct {
	Output    string
	Truncated bool
	ExitCode  int
	Signal    *string
	Cancelled bool // ctx was cancelled; the terminal was killed
	TimedOut  bool // ctx hit its deadline; the terminal was killed
}

TerminalResult is the reconciled outcome of one command run over a peer terminal; Cancelled and TimedOut are kept distinct (deadline vs. an external stop, usually session/cancel), and either way the terminal was killed before the result was read.

func RunTerminal added in v0.38.0

func RunTerminal(ctx context.Context, p TerminalPeer, req CreateTerminalRequest, onCreated func(terminalID string)) (TerminalResult, error)

RunTerminal creates a terminal on the peer, waits for it to exit, collects its output, and always releases it before returning, invoking onCreated (if non-nil) once the terminal exists but before the wait begins.

type ToolCallContent

type ToolCallContent struct {
	Type       ToolCallContentKind `json:"type"`
	Content    *ContentBlock       `json:"content,omitempty"`
	Path       string              `json:"path,omitempty"`
	OldText    string              `json:"oldText,omitempty"`
	NewText    string              `json:"newText,omitempty"`
	TerminalID string              `json:"terminalId,omitempty"`
	Meta       json.RawMessage     `json:"_meta,omitempty"`
}

func (ToolCallContent) MarshalJSON added in v0.38.0

func (c ToolCallContent) MarshalJSON() ([]byte, error)

MarshalJSON forces path/newText onto the wire for the "diff" variant even when empty — newText:"" is the correct shape for a diff clearing a file's content, which plain omitempty can't distinguish from absent.

type ToolCallContentKind

type ToolCallContentKind string
const (
	ToolCallContentRegular  ToolCallContentKind = "content"
	ToolCallContentDiff     ToolCallContentKind = "diff"
	ToolCallContentTerminal ToolCallContentKind = "terminal"
)

type ToolCallLocation

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

type ToolCallStatus

type ToolCallStatus string
const (
	ToolCallStatusPending    ToolCallStatus = "pending"
	ToolCallStatusInProgress ToolCallStatus = "in_progress"
	ToolCallStatusCompleted  ToolCallStatus = "completed"
	ToolCallStatusFailed     ToolCallStatus = "failed"
)

type ToolKind

type ToolKind string
const (
	ToolKindRead       ToolKind = "read"
	ToolKindEdit       ToolKind = "edit"
	ToolKindDelete     ToolKind = "delete"
	ToolKindMove       ToolKind = "move"
	ToolKindSearch     ToolKind = "search"
	ToolKindExecute    ToolKind = "execute"
	ToolKindThink      ToolKind = "think"
	ToolKindFetch      ToolKind = "fetch"
	ToolKindSwitchMode ToolKind = "switch_mode"
	ToolKindOther      ToolKind = "other"
)

type TurnTracker added in v0.38.0

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

TurnTracker watches one prompt turn's session/update stream and tells a client-side driver whether the agent ever produced a renderable answer, via Observe per notification and Err at turn end; single-turn (construct fresh or Reset per turn) and not safe for concurrent use.

func (*TurnTracker) Err added in v0.38.0

func (t *TurnTracker) Err(stop StopReason) error

Err returns nil when the turn produced displayable output, otherwise an ErrNoDisplayableOutput enriched with the turn's stop reason and tool-update count; call it once the session/prompt result is in hand.

func (*TurnTracker) Observe added in v0.38.0

func (t *TurnTracker) Observe(n SessionNotification)

Observe records one inbound session/update; it only inspects the update payload, leaving session-id matching to FilterSessionUpdates.

func (*TurnTracker) Reset added in v0.38.0

func (t *TurnTracker) Reset()

Reset returns the tracker to its zero state so it can be reused for the next turn on the same session.

func (*TurnTracker) SawDisplayableOutput added in v0.38.0

func (t *TurnTracker) SawDisplayableOutput() bool

SawDisplayableOutput reports whether any agent_message_chunk carrying renderable content has been observed this turn.

func (*TurnTracker) ToolUpdateCount added in v0.38.0

func (t *TurnTracker) ToolUpdateCount() int

ToolUpdateCount reports how many tool_call / tool_call_update notifications were observed, so Err can let an operator tell "tool activity but no final text" from "literally nothing".

type UnimplementedAgent

type UnimplementedAgent struct{}

func (UnimplementedAgent) Authenticate

func (UnimplementedAgent) Cancel

func (UnimplementedAgent) CloseSession added in v0.38.0

func (UnimplementedAgent) DeleteSession added in v0.38.0

func (UnimplementedAgent) Initialize

func (UnimplementedAgent) ListSessions

func (UnimplementedAgent) LoadSession

func (UnimplementedAgent) Logout added in v0.38.0

func (UnimplementedAgent) NewSession

func (UnimplementedAgent) Prompt

func (UnimplementedAgent) ResumeSession added in v0.38.0

func (UnimplementedAgent) SetSessionConfigOption added in v0.38.0

func (UnimplementedAgent) SetSessionMode added in v0.38.0

func (UnimplementedAgent) SetSessionModel added in v0.38.0

type UnimplementedClient added in v0.38.0

type UnimplementedClient struct{}

UnimplementedClient rejects every request-shaped Client method with MethodNotFound and treats SessionUpdate as a no-op; embed it to implement only the methods a particular client cares about.

func (UnimplementedClient) CreateTerminal added in v0.38.0

func (UnimplementedClient) KillTerminal added in v0.38.0

func (UnimplementedClient) ReadTextFile added in v0.38.0

func (UnimplementedClient) ReleaseTerminal added in v0.38.0

func (UnimplementedClient) RequestPermission added in v0.38.0

func (UnimplementedClient) SessionUpdate added in v0.38.0

func (UnimplementedClient) TerminalOutput added in v0.38.0

func (UnimplementedClient) WaitForTerminalExit added in v0.38.0

func (UnimplementedClient) WriteTextFile added in v0.38.0

type UsageCost added in v0.38.0

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

type WaitForTerminalExitRequest

type WaitForTerminalExitRequest struct {
	SessionID  SessionID       `json:"sessionId"`
	TerminalID string          `json:"terminalId"`
	Meta       json.RawMessage `json:"_meta,omitempty"`
}

type WaitForTerminalExitResponse

type WaitForTerminalExitResponse struct {
	ExitCode *int            `json:"exitCode,omitempty"`
	Signal   *string         `json:"signal,omitempty"`
	Meta     json.RawMessage `json:"_meta,omitempty"`
}

type WriteTextFileRequest

type WriteTextFileRequest struct {
	SessionID SessionID       `json:"sessionId"`
	Path      string          `json:"path"`
	Content   string          `json:"content"`
	Meta      json.RawMessage `json:"_meta,omitempty"`
}

type WriteTextFileResponse

type WriteTextFileResponse struct {
	Meta json.RawMessage `json:"_meta,omitempty"`
}

Directories

Path Synopsis
Package acpexec spawns a subprocess and wires its stdin/stdout together as a single io.ReadWriteCloser — the transport shape libacp.NewAgentSideConnection and libacp.NewClientSideConnection expect — so an ACP peer (an editor, or a test driving a reference binary) can be reached over stdio without hand-rolled pipe/shutdown bookkeeping.
Package acpexec spawns a subprocess and wires its stdin/stdout together as a single io.ReadWriteCloser — the transport shape libacp.NewAgentSideConnection and libacp.NewClientSideConnection expect — so an ACP peer (an editor, or a test driving a reference binary) can be reached over stdio without hand-rolled pipe/shutdown bookkeeping.
cmd
acp-stub-agent command
Command acp-stub-agent is a hermetic ACP Agent used to validate libacp's agent-side wire dispatch against ACP conformance clients, without any LLM backend.
Command acp-stub-agent is a hermetic ACP Agent used to validate libacp's agent-side wire dispatch against ACP conformance clients, without any LLM backend.

Jump to

Keyboard shortcuts

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