agent

package
v0.0.0-...-1a28f28 Latest Latest
Warning

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

Go to latest
Published: Jan 22, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package agent provides the agent plugin system for Deputy.

The agent plugin architecture supports three types of plugins:

  • Builtin: Compiled into the Deputy binary (Claude, Codex)
  • External: Separate processes discovered via PATH (deputy-agent-<name>)
  • Remote: gRPC/Connect servers at configured endpoints

Plugin Interface

All agent plugins implement the AgentPlugin gRPC service defined in api/deputy/agent/v1/agent.proto. This includes:

  • GetInfo: Returns plugin metadata and capabilities
  • Execute: Runs the agent with streaming events
  • Resume: Continues a previous session
  • Approve: Handles approval requests
  • Cancel: Gracefully terminates execution

Registry

The Registry manages plugin discovery and lifecycle:

registry := agent.NewRegistry()
registry.RegisterBuiltin(claude.NewPlugin())
registry.DiscoverExternal() // finds deputy-agent-* in PATH

Builtin Plugins

Builtin plugins wrap existing ai.Provider implementations:

plugin := agent.WrapProvider(aiProvider)

External Plugins

External plugins are discovered by searching PATH for executables matching the pattern "deputy-agent-<name>". When executed, they must serve the AgentPlugin gRPC service on a Unix socket or TCP port.

Sandboxed Execution

Plugins can be run in sandboxed environments:

registry := agent.NewRegistry()
_ = registry.RegisterSandboxed("claude", agent.SandboxOptions{
    Runtime: agent.RuntimeDocker,
    Image:   "deputy-agent:latest",
})

Package agent provides a plugin registry for AI agent implementations.

Plugins implement the generated agentv1connect.AgentPluginHandler interface.

Index

Constants

View Source
const PluginPrefix = "deputy-plugin-"

PluginPrefix is the prefix for external plugin executables.

Variables

View Source
var DefaultRegistry = NewRegistry()

DefaultRegistry is the global plugin registry.

Functions

func CheckRuntime

func CheckRuntime(runtime SandboxRuntime) error

CheckRuntime verifies the container runtime is available.

func DefaultSandboxImage

func DefaultSandboxImage(agentName string) string

DefaultSandboxImage returns a suggested image for sandboxed agent execution.

func DiscoverExternal

func DiscoverExternal(ctx context.Context) ([]string, error)

DiscoverExternal discovers external plugins and adds them to the default registry.

func FindPluginInPath

func FindPluginInPath(name string) string

FindPluginInPath searches PATH for a plugin executable by name. It looks for "deputy-plugin-<name>" in PATH and returns the full path if found. Returns empty string if not found.

func Get

Get retrieves a plugin from the default registry.

func GetOrDiscover

func GetOrDiscover(ctx context.Context, name string) (agentv1connect.AgentPluginHandler, error)

GetOrDiscover retrieves a plugin from the default registry, discovering from PATH if needed.

func List

func List() []string

List returns all registered plugin names from the default registry.

func ListAvailable

func ListAvailable() []string

ListAvailable returns all available plugins from the default registry and PATH.

func MustRegisterBuiltin

func MustRegisterBuiltin(name string, handler agentv1connect.AgentPluginHandler)

MustRegisterBuiltin registers a builtin plugin, panicking on error.

func MustRegisterSandboxed

func MustRegisterSandboxed(name string, opts SandboxOptions)

MustRegisterSandboxed registers a sandboxed plugin to the default registry, panicking on error.

func NewExternalPluginHandler

func NewExternalPluginHandler(ctx context.Context, name, execPath string) (agentv1connect.AgentPluginHandler, func() error, error)

NewExternalPluginHandler creates a handler from an external executable. It starts the plugin process and verifies it implements the protocol. Returns the handler and a closer function to clean up resources.

func Register

func Register(entry *PluginEntry) error

Register adds a plugin to the default registry.

func RegisterBuiltin

func RegisterBuiltin(name string, handler agentv1connect.AgentPluginHandler) error

RegisterBuiltin registers a builtin plugin to the default registry.

func RegisterSandboxed

func RegisterSandboxed(name string, opts SandboxOptions) error

RegisterSandboxed registers a sandboxed plugin to the default registry.

Types

type ClaudeHandler

type ClaudeHandler struct {
	agentv1connect.UnimplementedAgentPluginHandler
}

ClaudeHandler implements AgentPluginHandler using the Claude CLI.

func NewClaudeHandler

func NewClaudeHandler() *ClaudeHandler

NewClaudeHandler creates a new Claude agent plugin handler.

func (*ClaudeHandler) Approve

Approve handles approval requests.

func (*ClaudeHandler) Cancel

Cancel requests graceful termination.

func (*ClaudeHandler) Execute

Execute runs the Claude CLI with the given request and streams events.

func (*ClaudeHandler) ExecuteIter

ExecuteIter implements Executor for in-process execution without a connect.ServerStream.

func (*ClaudeHandler) GetInfo

GetInfo returns metadata about the Claude plugin.

func (*ClaudeHandler) Resume

Resume continues a previous Claude session.

func (*ClaudeHandler) ResumeIter

ResumeIter implements Executor for resuming sessions without a connect.ServerStream.

type CodexHandler

type CodexHandler struct {
	agentv1connect.UnimplementedAgentPluginHandler
}

CodexHandler implements AgentPluginHandler using the OpenAI Codex CLI.

func NewCodexHandler

func NewCodexHandler() *CodexHandler

NewCodexHandler creates a new Codex agent plugin handler.

func (*CodexHandler) Approve

Approve handles approval requests.

func (*CodexHandler) Cancel

Cancel requests graceful termination.

func (*CodexHandler) Execute

Execute runs the Codex CLI with the given request and streams events.

func (*CodexHandler) ExecuteIter

ExecuteIter implements Executor for in-process execution without a connect.ServerStream.

func (*CodexHandler) GetInfo

GetInfo returns metadata about the Codex plugin.

func (*CodexHandler) Resume

Resume continues a previous Codex session.

func (*CodexHandler) ResumeIter

ResumeIter implements Executor for resuming sessions without a connect.ServerStream.

type Executor

type Executor interface {
	// ExecuteIter executes the agent and returns an iterator over events.
	ExecuteIter(ctx context.Context, req *agentv1.ExecuteRequest) iter.Seq2[*agentv1.ExecuteEvent, error]

	// ResumeIter resumes a session and returns an iterator over events.
	ResumeIter(ctx context.Context, req *agentv1.ResumeRequest) iter.Seq2[*agentv1.ExecuteEvent, error]
}

Executor is an optional interface that agent handlers can implement to support in-process execution without requiring a connect.ServerStream.

func AsExecutor

func AsExecutor(handler agentv1connect.AgentPluginHandler) Executor

AsExecutor attempts to cast an AgentPluginHandler to an Executor. Returns nil if the handler doesn't implement Executor.

type PluginEntry

type PluginEntry struct {
	Name    string
	Type    PluginType
	Handler agentv1connect.AgentPluginHandler
	Path    string // For external plugins, the executable path
	Address string // For remote plugins, the server address
	// contains filtered or unexported fields
}

PluginEntry describes a registered plugin.

func (*PluginEntry) Close

func (e *PluginEntry) Close() error

Close releases resources held by this plugin entry.

type PluginType

type PluginType string

PluginType identifies the type of plugin.

const (
	// PluginTypeBuiltin is a plugin compiled into the Deputy binary.
	PluginTypeBuiltin PluginType = "builtin"

	// PluginTypeExternal is a plugin discovered via PATH.
	PluginTypeExternal PluginType = "external"

	// PluginTypeRemote is a plugin accessed via gRPC/Connect.
	PluginTypeRemote PluginType = "remote"

	// PluginTypeSandboxed is a plugin running in a container.
	PluginTypeSandboxed PluginType = "sandboxed"
)

type Registry

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

Registry manages agent plugin discovery and lifecycle.

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates an empty plugin registry.

func (*Registry) Close

func (r *Registry) Close() error

Close closes all registered plugins.

func (*Registry) DiscoverExternal

func (r *Registry) DiscoverExternal(ctx context.Context) ([]string, error)

DiscoverExternal searches PATH for external agent plugins. External plugins are executables matching the pattern "deputy-plugin-<name>". This performs eager discovery - plugins are started and registered immediately.

func (*Registry) Entries

func (r *Registry) Entries() []*PluginEntry

Entries returns all registered plugin entries.

func (*Registry) Get

Get retrieves a plugin handler by name.

func (*Registry) GetEntry

func (r *Registry) GetEntry(name string) (*PluginEntry, error)

GetEntry retrieves a plugin entry by name.

func (*Registry) GetOrDiscover

func (r *Registry) GetOrDiscover(ctx context.Context, name string) (agentv1connect.AgentPluginHandler, error)

GetOrDiscover retrieves a plugin by name, discovering it from PATH if not already registered. This enables natural usage like Get("gemini") which will auto-discover deputy-plugin-gemini.

func (*Registry) List

func (r *Registry) List() []string

List returns all registered plugin names, sorted alphabetically.

func (*Registry) ListAvailable

func (r *Registry) ListAvailable() []string

ListAvailable returns all available plugins: registered and discoverable from PATH. This combines registered plugin names with plugin names found in PATH.

func (*Registry) MustRegisterBuiltin

func (r *Registry) MustRegisterBuiltin(name string, handler agentv1connect.AgentPluginHandler)

MustRegisterBuiltin registers a builtin plugin, panicking on error.

func (*Registry) MustRegisterSandboxed

func (r *Registry) MustRegisterSandboxed(name string, opts SandboxOptions)

MustRegisterSandboxed registers a sandboxed plugin, panicking on error.

func (*Registry) Register

func (r *Registry) Register(entry *PluginEntry) error

Register adds a plugin to the registry.

func (*Registry) RegisterBuiltin

func (r *Registry) RegisterBuiltin(name string, handler agentv1connect.AgentPluginHandler) error

RegisterBuiltin registers a builtin plugin handler.

func (*Registry) RegisterRemote

func (r *Registry) RegisterRemote(ctx context.Context, name, address string) error

RegisterRemote registers a remote plugin at the given address.

func (*Registry) RegisterSandboxed

func (r *Registry) RegisterSandboxed(name string, opts SandboxOptions) error

RegisterSandboxed registers a sandboxed plugin handler.

func (*Registry) Unregister

func (r *Registry) Unregister(name string) error

Unregister removes a plugin from the registry.

type SandboxOptions

type SandboxOptions struct {
	// Runtime is the container runtime to use.
	Runtime SandboxRuntime

	// Image is the container image to run.
	Image string

	// NetworkMode controls network access ("none", "host", "bridge").
	NetworkMode string

	// ReadOnlyRoot makes the root filesystem read-only.
	ReadOnlyRoot bool

	// MemoryLimit is the memory limit (e.g., "512m", "2g").
	MemoryLimit string

	// CPULimit is the CPU limit (e.g., "1.0", "0.5").
	CPULimit string

	// Timeout is the maximum execution duration.
	Timeout time.Duration

	// WorkDir is the working directory to mount inside the container.
	WorkDir string

	// SocketPath is where to expose the plugin's gRPC socket.
	SocketPath string
}

SandboxOptions configures sandboxed plugin execution.

type SandboxRuntime

type SandboxRuntime string

SandboxRuntime identifies the container runtime for sandboxed execution.

const (
	// RuntimeDocker uses Docker for sandboxing.
	RuntimeDocker SandboxRuntime = "docker"

	// RuntimeGVisor uses gVisor (runsc) for sandboxing.
	RuntimeGVisor SandboxRuntime = "gvisor"

	// RuntimePodman uses Podman for sandboxing.
	RuntimePodman SandboxRuntime = "podman"
)

func AvailableRuntimes

func AvailableRuntimes() []SandboxRuntime

AvailableRuntimes returns which container runtimes are available.

type SandboxedHandler

type SandboxedHandler struct {
	agentv1connect.UnimplementedAgentPluginHandler
	// contains filtered or unexported fields
}

SandboxedHandler implements AgentPluginHandler by running agents in containers.

func NewSandboxedHandler

func NewSandboxedHandler(name string, opts SandboxOptions) (*SandboxedHandler, error)

NewSandboxedHandler creates a sandboxed handler for running agents in containers.

func (*SandboxedHandler) Approve

Approve handles approval requests.

func (*SandboxedHandler) Cancel

Cancel requests graceful termination.

func (*SandboxedHandler) Execute

Execute runs the agent in a sandboxed container.

func (*SandboxedHandler) GetInfo

GetInfo returns metadata about the sandboxed plugin.

func (*SandboxedHandler) Resume

Resume continues a previous session.

Jump to

Keyboard shortcuts

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