acpagent

package
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: May 6, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package acpagent adapts Agentic Computing Protocol (ACP) runtimes to the Google ADK [agent.Agent] interface.

The package starts an ACP-compatible subprocess and maps each ADK session to a remote ACP session. By default, ACP session creation uses [Config.WorkingDir] as the ACP session cwd.

Per-session overrides via ADK state

Callers can override ACP session creation per ADK session by setting sessionstate.CWDKey before the first invocation in that ADK session:

map[string]any{
  sessionstate.CWDKey: "/absolute/path", // optional
}

ACP-specific session/new metadata may be provided under SessionStateKey:

map[string]any{
  acpagent.SessionStateKey: map[string]any{
    "meta": map[string]any{ // optional; forwarded to ACP session/new _meta
      "codex": map[string]any{"approvalMode": "manual"},
    },
  },
}

Behavior:

  • If `state[sessionstate.CWDKey]` is set, it overrides [Config.WorkingDir] for ACP session creation.
  • If `state[SessionStateKey].meta` is set, it is passed through to ACP session/new._meta.
  • Overrides are read when the ACP session is first created for the ADK session. Subsequent changes do not rebind that existing ACP session.

Invalid override values (for example, non-string `state[sessionstate.CWDKey]`, non-object `state[SessionStateKey]`, non-object `state[SessionStateKey].meta`, or a cwd that is not a valid existing directory) cause invocation failure before ACP session creation.

ACP plan updates

ACP `session/update.plan` notifications are projected into ADK event state under PlanStateKey. Each event carries the full replacement snapshot at `event.Actions.StateDelta[PlanStateKey]` with an `entries` field containing the current ACP plan entries. Plan updates do not appear as content parts.

Index

Examples

Constants

View Source
const (
	// SessionStateKey is the reserved ADK session-state key for ACP-specific
	// per-session settings.
	//
	// The value at this key must be an object with optional fields:
	//   - "meta" (object): forwarded to ACP session/new._meta
	//
	// Set it before the first invocation in a given ADK session; once that ADK
	// session is bound to an ACP session, later changes do not rebind.
	SessionStateKey = "acp_session"
	// PlanStateKey is the ADK session-state key used for ACP plan snapshots.
	//
	// Each ACP session/update.plan notification is projected into
	// event.Actions.StateDelta[PlanStateKey] as the authoritative full plan
	// replacement snapshot.
	PlanStateKey = "acp_plan"
)

Variables

View Source
var (
	// ErrPromptAlreadyActive is returned when a prompt is already in progress for
	// the same ACP session ID.
	ErrPromptAlreadyActive = errors.New("acp prompt already active")
)

Functions

This section is empty.

Types

type Agent

type Agent struct {
	adkagent.Agent
	// contains filtered or unexported fields
}

Agent adapts an Agentic Computing Protocol (ACP) runtime to the ADK agent interface. It manages the lifecycle of an ACP subprocess and maps ACP sessions to ADK sessions.

func New

func New(cfg Config) (*Agent, error)

New creates an ADK agent backed by an ACP client process.

It starts the ACP process, performs ACP initialization, and creates ACP sessions lazily per ADK session.

Per ADK session, callers may provide state overrides:

If no override is provided, Config.WorkingDir is used as ACP session cwd. The first ACP session created for an ADK session is reused for subsequent invocations in that same ADK session.

The caller is responsible for calling Close() to shut down the subprocess.

func (*Agent) Close

func (a *Agent) Close() error

Close shuts down the underlying ACP client process.

type Client

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

Client manages a single Agentic Computing Protocol (ACP) subprocess and its communication over standard input/output. It implements the acp.Client interface to handle protocol-level callbacks and manages multiple concurrent prompt sessions.

func NewClient

func NewClient(ctx context.Context, cfg ClientConfig) (*Client, error)

NewClient starts an ACP subprocess and returns a protocol client over stdio.

Example
previous := os.Getenv("GO_WANT_ACP_HELPER")
_ = os.Setenv("GO_WANT_ACP_HELPER", "1")
defer func() {
	if previous == "" {
		_ = os.Unsetenv("GO_WANT_ACP_HELPER")
		return
	}
	_ = os.Setenv("GO_WANT_ACP_HELPER", previous)
}()

workingDir, err := os.MkdirTemp("", "runtime-acpagent-example-*")
if err != nil {
	fmt.Println(err)
	return
}
defer func() { _ = os.RemoveAll(workingDir) }()

client, err := NewClient(context.Background(), ClientConfig{
	Command: []string{os.Args[0], "-test.run=TestACPHelperProcess", "--"},
})
if err != nil {
	fmt.Println(err)
	return
}
defer func() { _ = client.Close() }()

if _, err := client.Initialize(context.Background()); err != nil {
	fmt.Println(err)
	return
}
sessionResp, err := client.NewSession(context.Background(), workingDir, nil)
if err != nil {
	fmt.Println(err)
	return
}

fmt.Println(string(sessionResp.SessionId) != "")
Output:
true

func (*Client) Authenticate

func (c *Client) Authenticate(ctx context.Context, methodID string) error

Authenticate requests ACP authentication for a specific method.

func (*Client) Close

func (c *Client) Close() error

Close stops the ACP subprocess and waits for cleanup to finish.

func (*Client) CreateSession

func (c *Client) CreateSession(ctx context.Context, cwd, model, mode string, mcpServers []acp.McpServer) (acp.NewSessionResponse, error)

CreateSession creates a new ACP session and applies configured session model/mode when requested.

func (*Client) CreateSessionWithMeta

func (c *Client) CreateSessionWithMeta(
	ctx context.Context,
	cwd,
	model,
	mode string,
	mcpServers []acp.McpServer,
	meta map[string]any,
) (acp.NewSessionResponse, error)

CreateSessionWithMeta creates a new ACP session with optional session/new _meta and applies configured session model/mode when requested.

This helper is equivalent to:

  1. NewSessionWithMeta(ctx, cwd, mcpServers, meta)
  2. optionally SetSessionModel(...)
  3. optionally SetSessionMode(...)

The ACP protocol requires cwd to be an absolute path.

func (*Client) CreateTerminal

CreateTerminal reports unsupported terminal creation for this ACP client.

func (*Client) Initialize

func (c *Client) Initialize(ctx context.Context) (acp.InitializeResponse, error)

Initialize performs ACP protocol initialization and validates protocol compatibility.

func (*Client) KillTerminal

KillTerminal reports unsupported terminal command control for this ACP client.

func (*Client) NewSession

func (c *Client) NewSession(ctx context.Context, cwd string, mcpServers []acp.McpServer) (acp.NewSessionResponse, error)

NewSession creates a new ACP session in the provided working directory.

The ACP protocol requires cwd to be an absolute path.

func (*Client) NewSessionWithMeta

func (c *Client) NewSessionWithMeta(
	ctx context.Context,
	cwd string,
	mcpServers []acp.McpServer,
	meta map[string]any,
) (acp.NewSessionResponse, error)

NewSessionWithMeta creates a new ACP session in the provided working directory and sends optional _meta extensions with the session request.

The ACP protocol requires cwd to be an absolute path.

func (*Client) Prompt

func (c *Client) Prompt(ctx context.Context, sessionID, prompt string) (<-chan ExtendedSessionNotification, <-chan PromptResult, error)

Prompt sends a prompt to an ACP session and streams session updates.

func (*Client) PromptWithContent

func (c *Client) PromptWithContent(ctx context.Context, sessionID string, prompt []acp.ContentBlock) (<-chan ExtendedSessionNotification, <-chan PromptResult, error)

PromptWithContent sends a prompt composed of ACP content blocks and streams session updates.

func (*Client) ReadTextFile

ReadTextFile reports unsupported file read for this ACP client.

func (*Client) ReleaseTerminal

ReleaseTerminal reports unsupported terminal release for this ACP client.

func (*Client) RequestPermission

RequestPermission handles ACP permission callbacks.

func (*Client) SessionUpdate

func (c *Client) SessionUpdate(ctx context.Context, params acp.SessionNotification) error

SessionUpdate is part of the ACP client callback contract.

func (*Client) SetSessionMode

func (c *Client) SetSessionMode(ctx context.Context, sessionID, mode string) error

SetSessionMode selects the active mode for an ACP session.

func (*Client) SetSessionModel

func (c *Client) SetSessionModel(ctx context.Context, sessionID, model string) error

SetSessionModel selects the active model for an ACP session.

func (*Client) TerminalOutput

TerminalOutput reports unsupported terminal output streaming for this ACP client.

func (*Client) WaitForTerminalExit

WaitForTerminalExit reports unsupported terminal wait operations for this ACP client.

func (*Client) WriteTextFile

WriteTextFile reports unsupported file write for this ACP client.

type ClientConfig

type ClientConfig struct {
	// Command is the argv array used to start the ACP subprocess.
	Command []string
	// WorkingDir is the directory where the ACP subprocess is executed
	// (cmd.Dir). It is independent from ACP session/new.cwd, which is provided
	// per session creation call.
	WorkingDir string
	// ClientName is the name reported to the ACP server. Defaults to "runtime-acpagent".
	ClientName string
	// ClientVersion is the version reported to the ACP server. Defaults to "dev".
	ClientVersion string
	// Stderr is an optional writer for the ACP subprocess's standard error.
	Stderr io.Writer
	// PermissionHandler decides how to respond to ACP permission requests.
	PermissionHandler PermissionHandler
	// Logger is the zerolog logger to use for this client.
	Logger *zerolog.Logger
	// SessionID is an optional desired session ID to request when creating ACP sessions.
	// It is sent via session/new _meta.sessionId and may be ignored by some ACP runtimes.
	SessionID string
}

ClientConfig configures an ACP subprocess client.

type Config

type Config struct {
	// Context is the base context for the agent's lifecycle.
	Context context.Context
	// Name is the display name of the agent. Defaults to "ACPAgent".
	Name string
	// Description describes the agent's purpose.
	Description string
	// BeforeAgentCallbacks are standard ADK lifecycle callbacks invoked before
	// the ACP-backed run starts.
	BeforeAgentCallbacks []adkagent.BeforeAgentCallback
	// AfterAgentCallbacks are standard ADK lifecycle callbacks invoked after
	// the ACP-backed run completes.
	AfterAgentCallbacks []adkagent.AfterAgentCallback
	// Model is the specific LLM model identifier to use.
	Model string
	// Mode is the ACP session mode identifier to use.
	Mode string
	// Instruction is the optional instruction applied to each invocation.
	Instruction string
	// GlobalInstruction is the optional global instruction applied before
	// Instruction.
	GlobalInstruction string
	// InstructionProvider dynamically provides [Config.Instruction] content.
	// When set, this takes precedence over [Config.Instruction].
	InstructionProvider InstructionProvider
	// GlobalInstructionProvider dynamically provides
	// [Config.GlobalInstruction] content. When set, this takes precedence over
	// [Config.GlobalInstruction].
	GlobalInstructionProvider InstructionProvider
	// SystemInstructions is deprecated and kept for backward compatibility.
	// Use Instruction instead.
	SystemInstructions string
	// ClientName is the name reported to the ACP server during initialization.
	ClientName string
	// ClientVersion is the version reported to the ACP server during initialization.
	ClientVersion string
	// Command is the argv array used to start the ACP subprocess.
	Command []string
	// WorkingDir is the default directory for ACP execution:
	//   - the ACP subprocess is started with this directory as cmd.Dir.
	//   - ACP session/new uses this as cwd unless overridden per ADK session
	//     via session state key [sessionstate.CWDKey].
	//
	// When session state override is present, the override takes precedence for
	// ACP session cwd selection.
	WorkingDir string
	// Stderr is an optional writer for the ACP subprocess's standard error.
	Stderr io.Writer
	// PermissionHandler decides how to respond to ACP permission requests.
	PermissionHandler PermissionHandler
	// Logger is the zerolog logger to use for this agent.
	Logger *zerolog.Logger
	// MCPServers is the map of MCP server configurations.
	MCPServers map[string]MCPServerConfig
	// SessionID is an optional desired session ID to request when creating ACP sessions.
	// It is sent via session/new _meta.sessionId and may be ignored by some ACP runtimes.
	SessionID string
}

Config configures an ACP-backed ADK agent.

type ExtendedSessionNotification

type ExtendedSessionNotification struct {
	acp.SessionNotification
	Raw json.RawMessage
}

ExtendedSessionNotification wraps an ACP notification with its raw JSON representation to allow access to fields not yet supported by the SDK.

type InstructionProvider

type InstructionProvider func(ctx adkagent.ReadonlyContext) (string, error)

InstructionProvider allows ACP instructions to be created dynamically using invocation context, mirroring llmagent semantics.

type MCPServerConfig

type MCPServerConfig struct {
	// Type selects the MCP transport implementation.
	Type MCPServerType
	// Cmd is the stdio server executable path or argv prefix.
	Cmd []string
	// Args appends additional stdio server arguments after Cmd.
	Args []string
	// Env defines environment variables for stdio server execution.
	Env map[string]string
	// WorkingDir sets the stdio server process working directory.
	WorkingDir string
	// URL is the base endpoint for HTTP and SSE MCP transports.
	URL string
	// Headers provides additional request headers for HTTP and SSE transports.
	Headers map[string]string
}

MCPServerConfig describes how to connect to an MCP server.

type MCPServerType

type MCPServerType string

MCPServerType represents the transport type for an MCP server.

const (
	// MCPServerTypeStdio is the stdio transport type.
	MCPServerTypeStdio MCPServerType = "stdio"
	// MCPServerTypeHTTP is the HTTP transport type.
	MCPServerTypeHTTP MCPServerType = "http"
	// MCPServerTypeSSE is the SSE (Server-Sent Events) transport type.
	MCPServerTypeSSE MCPServerType = "sse"
)

type PermissionHandler

PermissionHandler decides how ACP permission requests should be handled. It returns a response with the selected outcome or an error if the request could not be processed.

type PromptResult

type PromptResult struct {
	Response acp.PromptResponse
	Usage    *acp.Usage
	Err      error
}

PromptResult contains the terminal Prompt RPC response, usage metadata, or an error.

Jump to

Keyboard shortcuts

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