client

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 23, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package client wraps acp-go-sdk's low-level Connection for ACP relays. It manages a single stdio child agent process (e.g. fir --mode acp) and dispatches inbound server-initiated ACP calls — session updates, permission requests, fs reads/writes — back to the relay.

One AgentProc runs one ACP child process. It can serve many sessions concurrently — each NewSession/ResumeSession registers a per-session sink that receives the stream of session/update notifications.

We talk to acp.Connection directly (rather than acp.ClientSideConnection) so we can issue the unstable session/list and session/resume methods that the SDK doesn't model. The standard methods are sent via acp.SendRequest with the SDK's typed request/response structs.

Security: the fs methods (ReadTextFile / WriteTextFile) currently require absolute paths but do not sandbox to the session cwd. That is adequate for trusted-agent relay deployments; do not expose this client to untrusted agents.

Package client: defensive helpers for agent-spawn paths the production caller cannot trigger. Excluded from coverage via the `_must.go` suffix rule in .covignore.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AllowAllPermissions

AllowAllPermissions approves a request by selecting an allow-shaped option, falling back to the first option when no option advertises allow/approve.

func DenyAllPermissions

DenyAllPermissions rejects a request by selecting a reject-shaped option, falling back to the first option when no option advertises reject/deny.

func ReadOnlyPermissions

ReadOnlyPermissions allows read-like tool calls and rejects everything else. Heuristic: if the tool call title contains a write/exec-shaped verb (write, edit, bash, exec, run, delete, rm), the request is rejected; otherwise it is allowed.

Types

type AgentProc

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

AgentProc wraps a single stdio-connected ACP agent process and the ACP connection driving it.

func Start

func Start(ctx context.Context, cfg Config) (*AgentProc, error)

Start launches the agent process, performs Initialize (capturing caps), and returns a ready-to-use AgentProc.

func (*AgentProc) AuthMethods

func (a *AgentProc) AuthMethods() []AuthMethod

AuthMethods returns the auth methods the agent advertised at Initialize. Empty if the agent didn't advertise any (or initialize hasn't run yet).

func (*AgentProc) Authenticate

func (a *AgentProc) Authenticate(ctx context.Context, methodID, id, redirect string, cancel bool) (AuthResult, error)

Authenticate invokes the ACP authenticate RPC. Modes:

  • id == "" && redirect == "" && !cancel : start an interactive login. The agent returns a fresh id (and URL) in AuthResult.
  • id != "" && redirect != "" : submit the pasted redirect.
  • id != "" && cancel == true : cancel that pending login.

methodID must match the id advertised in the initialize response (e.g. "oauth-anthropic"). Requires an agent that supports the _meta.auth.interactive extension; older agents will run the legacy blocking flow and may return an empty AuthResult.

func (*AgentProc) Cancel

func (a *AgentProc) Cancel(ctx context.Context, sid acp.SessionId) error

Cancel requests cancellation of an in-flight prompt for a session.

func (*AgentProc) Caps

func (a *AgentProc) Caps() Caps

Caps returns the agent's advertised capabilities (parsed at Initialize).

func (*AgentProc) Close

func (a *AgentProc) Close() error

Close terminates the agent process. Returns after the process has exited (or been force-killed).

func (*AgentProc) DropSession

func (a *AgentProc) DropSession(sid acp.SessionId)

DropSession removes the sink for a session.

func (*AgentProc) ListSessions

func (a *AgentProc) ListSessions(ctx context.Context, cwd string) ([]SessionInfo, error)

ListSessions calls the unstable session/list. Caller must check Caps().ListSessions first.

func (*AgentProc) Models

func (a *AgentProc) Models() (models []ModelInfo, currentID string)

Models returns a snapshot of the agent's last-seen available models. Empty until a session has been created (or ProbeModels has run).

func (*AgentProc) NewSession

func (a *AgentProc) NewSession(ctx context.Context, cwd string, sink SessionUpdateSink, systemPromptBlocks []acp.ContentBlock) (acp.SessionId, error)

NewSession creates a new ACP session and wires the given sink to receive its updates. Returns the ACP session id.

systemPromptBlocks, when non-nil, is sent in the request's _meta under "session.systemPrompt".blocks. Callers should only pass it when Caps().SystemPrompt is true; agents that haven't advertised the cap will simply ignore the unknown _meta key, but skipping it keeps the wire clean.

func (*AgentProc) ProbeModels

func (a *AgentProc) ProbeModels(ctx context.Context) error

ProbeModels creates a throwaway session in the agent's cwd to read its available-models list, then cancels it. The cached snapshot is returned from Models() afterwards. Idempotent: a no-op if Models() already has a list.

func (*AgentProc) Prompt

func (a *AgentProc) Prompt(ctx context.Context, sid acp.SessionId, prompt []acp.ContentBlock) (acp.StopReason, error)

Prompt sends a user message to the session. Returns the stop reason. The prompt is a sequence of ACP content blocks; callers build these from the latest user text plus any attachments.

func (*AgentProc) RebindSink

func (a *AgentProc) RebindSink(sid acp.SessionId, sink SessionUpdateSink)

RebindSink replaces the sink for an existing session id.

func (*AgentProc) ResumeSession

func (a *AgentProc) ResumeSession(ctx context.Context, cwd string, sid acp.SessionId, sink SessionUpdateSink) error

ResumeSession calls the unstable session/resume and registers the sink for the resumed session. Caller must check Caps().ResumeSession first. The given sid is the agent-returned identifier (as listed by ListSessions).

func (*AgentProc) SetConfigOption

func (a *AgentProc) SetConfigOption(ctx context.Context, sid acp.SessionId, configID, value string) error

func (*AgentProc) SetModel

func (a *AgentProc) SetModel(ctx context.Context, sid acp.SessionId, modelID string) error

SetModel calls the unstable session/set_model RPC.

type AuthMethod

type AuthMethod = auth.Method

AuthMethod is an alias for auth.Method kept on client.AgentProc's surface.

type AuthResult

type AuthResult = auth.Result

AuthResult is an alias for auth.Result kept on client.AgentProc's surface.

type Caps

type Caps struct {
	// LoadSession is the standard agentCapabilities.loadSession bool.
	LoadSession bool
	// ListSessions reflects agentCapabilities.sessionCapabilities.list
	// (unstable RFD).
	ListSessions bool
	// ResumeSession reflects agentCapabilities.sessionCapabilities.resume
	// (unstable RFD).
	ResumeSession bool
	// EmbeddedContext reflects
	// agentCapabilities.promptCapabilities.embeddedContext: when true,
	// the relay may emit ContentBlock::Resource (with TextResourceContents)
	// in prompt requests instead of a bare ResourceLink, avoiding an
	// agent-side fetch.
	EmbeddedContext bool
	// SystemPrompt reflects agentCapabilities._meta["session.systemPrompt"].
	// When true the consumer may pass a system-prompt block list via
	// session/new._meta and the agent will treat it as durable across
	// compaction. When false the consumer must fall back to inlining the
	// same content on first prompt (and re-arm on resume).
	SystemPrompt bool
}

Caps captures the agent capabilities the relay cares about, parsed from the initialize response.

type Config

type Config struct {
	// Command is the argv used to spawn the agent (e.g. []string{"fir", "--mode", "acp"}).
	Command []string
	// Cwd is the working directory for the child process.
	Cwd string
	// Env is the environment for the child. If nil, os.Environ() is used.
	Env []string
	// Policy decides permission responses. If nil, AllowAllPermissions is used.
	Policy PermissionPolicy
	// CloseGrace is how long Close waits after SIGINT before SIGKILL. Default 2s.
	CloseGrace time.Duration
	// Stderr is where the child's stderr is forwarded. If nil, os.Stderr.
	Stderr io.Writer
}

Config configures an AgentProc.

type ModelInfo

type ModelInfo struct {
	ID   string // "provider/modelID"
	Name string // human-readable label
}

ModelInfo is one entry in the agent's available-models list.

type PermissionFunc

PermissionFunc adapts a function into a PermissionPolicy.

func (PermissionFunc) Decide

Decide implements PermissionPolicy.

type PermissionPolicy

type PermissionPolicy interface {
	Decide(ctx context.Context, req acp.RequestPermissionRequest) acp.RequestPermissionResponse
}

PermissionPolicy decides how to respond to session/request_permission.

type SessionInfo

type SessionInfo struct {
	SessionId string  `json:"sessionId"`
	Cwd       string  `json:"cwd,omitempty"`
	Title     *string `json:"title,omitempty"`
	UpdatedAt string  `json:"updatedAt,omitempty"`
}

SessionInfo is one entry from a session/list response.

type SessionUpdateSink

type SessionUpdateSink interface {
	OnUpdate(ctx context.Context, n acp.SessionNotification) error
}

SessionUpdateSink receives streaming updates for a single ACP session. Each consumer (e.g. a relay) implements this to forward the stream to its own transport (SSE, WebSocket, IM channel, ...).

Directories

Path Synopsis
Package auth contains the small auth schema used by ACP authenticate extensions.
Package auth contains the small auth schema used by ACP authenticate extensions.

Jump to

Keyboard shortcuts

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