Documentation
¶
Index ¶
- Constants
- Variables
- func NewClaudeStore(projectsDir string) (common.SessionStore, error)
- func NewControlledHandle(bufferSize int, responseFn func(reqID string, resp ControlResponse) error, ...) (ExecutionHandle, *HandleControls)
- type Agent
- type AgentBoot
- func (ab *AgentBoot) GetAgent(agentType AgentType) (Agent, error)
- func (ab *AgentBoot) GetConfig() Config
- func (ab *AgentBoot) GetDefaultAgent() (Agent, error)
- func (ab *AgentBoot) GetSessionSummary(ctx context.Context, sessionID string, firstN, lastM int) (*common.SessionSummary, error)
- func (ab *AgentBoot) ListAgents() []AgentType
- func (ab *AgentBoot) ListRecentSessions(ctx context.Context, projectPath string, limit int) ([]common.SessionMetadata, error)
- func (ab *AgentBoot) MustGetAgent(agentType AgentType) Agent
- func (ab *AgentBoot) RegisterAgent(agentType AgentType, agent Agent)
- func (ab *AgentBoot) ResumeSession(sessionID string) ExecutionOptions
- func (ab *AgentBoot) SetDefaultAgent(agentType AgentType) error
- type AgentDriver
- type AgentMessage
- type AgentTransport
- type AgentType
- type ApprovalHandler
- type ApprovalRequestEvent
- type ApprovalResponse
- type AskHandler
- type AskRequest
- type AskRequestEvent
- type AskResponse
- type AskResult
- type AssistantMessage
- type BaseMessage
- type CompletionCallback
- type CompletionResult
- type CompositeHandler
- func (h *CompositeHandler) OnApproval(ctx context.Context, req PermissionRequest) (PermissionResult, error)
- func (h *CompositeHandler) OnAsk(ctx context.Context, req AskRequest) (AskResult, error)
- func (h *CompositeHandler) OnComplete(result *CompletionResult)
- func (h *CompositeHandler) OnError(err error)
- func (h *CompositeHandler) OnMessage(msg interface{}) error
- func (h *CompositeHandler) SetApprovalHandler(a ApprovalHandler) *CompositeHandler
- func (h *CompositeHandler) SetAskHandler(a AskHandler) *CompositeHandler
- func (h *CompositeHandler) SetCompletionCallback(c CompletionCallback) *CompositeHandler
- func (h *CompositeHandler) SetStreamer(s MessageStreamer) *CompositeHandler
- func (h *CompositeHandler) WithCompletionFunc(f func(result *CompletionResult)) *CompositeHandler
- func (h *CompositeHandler) WithErrorFunc(f func(err error)) *CompositeHandler
- func (h *CompositeHandler) WithMessageFunc(f func(msg interface{}) error) *CompositeHandler
- type Config
- type ContentBlock
- type ControlResponse
- type ErrorEvent
- type Event
- type EventKind
- type ExecutionHandle
- type ExecutionOptions
- type HandleControls
- type InitMessage
- type LaunchSpec
- type MessageEvent
- type MessageHandler
- type MessageSink
- type MessageStreamer
- type OutputFormat
- type PermissionConfig
- type PermissionMode
- type PermissionRequest
- type PermissionRequestMessage
- type PermissionResponse
- type PermissionResult
- type PermissionResultMessage
- type Prompter
- type Result
- func (r *Result) GetAssistantMessages() []Event
- func (r *Result) GetCostUSD() float64
- func (r *Result) GetMessageChain() []Event
- func (r *Result) GetMessagesByType(messageType string) []Event
- func (r *Result) GetSessionID() string
- func (r *Result) GetStatus() string
- func (r *Result) GetToolResultMessages() []Event
- func (r *Result) GetToolUseMessages() []Event
- func (r *Result) GetUserMessages() []Event
- func (r *Result) IsSuccess() bool
- func (r *Result) TextOutput() string
- type ResultMessage
- type Runner
- type StreamDeltaMessage
- type StreamEvent
Constants ¶
const ( // EventTypeInit indicates agent initialization EventTypeInit = "init" // EventTypeSystem indicates system-level messages EventTypeSystem = "system" // EventTypeAssistant indicates assistant/agent response messages EventTypeAssistant = "assistant" // EventTypeUser indicates user messages (echoed back) EventTypeUser = "user" // EventTypeToolUse indicates a tool is being invoked EventTypeToolUse = "tool_use" // EventTypeToolResult indicates the result of a tool invocation EventTypeToolResult = "tool_result" // EventTypePermissionRequest indicates a permission request is pending EventTypePermissionRequest = "permission_request" // EventTypePermissionResult indicates the result of a permission request EventTypePermissionResult = "permission_result" // EventTypeResult indicates the final result of execution EventTypeResult = "result" // EventTypeError indicates an error occurred EventTypeError = "error" // EventTypeStreamDelta indicates incremental streaming content EventTypeStreamDelta = "stream_delta" )
EventType constants for unified agent events All agents should map their internal events to these standard types
Variables ¶
var ( // ErrHandleClosed is returned when the handle's event stream has already // closed (process exited, Cancel called, or ctx canceled). ErrHandleClosed = errors.New("agentboot: execution handle closed") // ErrUnknownRequestID is returned when reqID does not correspond to a // pending control request, either because the ID is wrong or because // the runner already received a response for it. ErrUnknownRequestID = errors.New("agentboot: unknown request id") )
Sentinel errors returned by [ExecutionHandle.Respond].
Functions ¶
func NewClaudeStore ¶ added in v0.260414.2000
func NewClaudeStore(projectsDir string) (common.SessionStore, error)
NewClaudeStore creates a new Claude session store
func NewControlledHandle ¶ added in v0.260507.1
func NewControlledHandle( bufferSize int, responseFn func(reqID string, resp ControlResponse) error, cancelFn func(), waitFn func() (*Result, error), ) (ExecutionHandle, *HandleControls)
NewControlledHandle builds an ExecutionHandle whose lifecycle is driven directly by the caller via the returned HandleControls.
Use this from Agent implementations that do not go through the process+protocol pipeline (e.g. in-process mocks).
The supplied closures define:
- responseFn: how [ExecutionHandle.Respond] routes a ControlResponse back to the in-flight execution. For an in-process agent this is typically a channel send to a goroutine waiting for the response.
- cancelFn: how [ExecutionHandle.Cancel] requests cooperative shutdown.
- waitFn: how [ExecutionHandle.Wait] gathers the final Result and error.
Types ¶
type Agent ¶
type Agent interface {
Execute(ctx context.Context, prompt string, opts ExecutionOptions) (ExecutionHandle, error)
IsAvailable() bool
Type() AgentType
SetDefaultFormat(format OutputFormat)
GetDefaultFormat() OutputFormat
}
Agent is the interface for all agent types.
Execute returns an ExecutionHandle; the caller iterates handle.Events() to consume the totally-ordered event stream, calls handle.Respond(...) to answer Approval/Ask requests, and calls handle.Wait() to obtain the aggregated Result. See the ExecutionHandle docs for lifecycle details.
type AgentBoot ¶
type AgentBoot struct {
// contains filtered or unexported fields
}
AgentBoot manages agent instances
func New ¶
New creates a new AgentBoot instance. Returns an error only if ClaudeProjectsDir is set but cannot be initialized.
func (*AgentBoot) GetDefaultAgent ¶
GetDefaultAgent returns the default agent
func (*AgentBoot) GetSessionSummary ¶ added in v0.260507.1
func (ab *AgentBoot) GetSessionSummary(ctx context.Context, sessionID string, firstN, lastM int) (*common.SessionSummary, error)
GetSessionSummary returns a summary of a session
func (*AgentBoot) ListAgents ¶
ListAgents returns all registered agent types
func (*AgentBoot) ListRecentSessions ¶ added in v0.260507.1
func (ab *AgentBoot) ListRecentSessions(ctx context.Context, projectPath string, limit int) ([]common.SessionMetadata, error)
ListRecentSessions returns recent sessions for a project
func (*AgentBoot) MustGetAgent ¶
MustGetAgent returns an agent by type or panics
func (*AgentBoot) RegisterAgent ¶
RegisterAgent registers a new agent type
func (*AgentBoot) ResumeSession ¶ added in v0.260507.1
func (ab *AgentBoot) ResumeSession(sessionID string) ExecutionOptions
ResumeSession creates ExecutionOptions to resume a session
func (*AgentBoot) SetDefaultAgent ¶
SetDefaultAgent sets the default agent type
type AgentDriver ¶ added in v0.260507.1
type AgentDriver interface {
// Prepare returns a LaunchSpec describing how to start the agent.
// The spec is consumed by a Runner; the Driver itself does not start anything.
Prepare(ctx context.Context, prompt string, opts ExecutionOptions) (*LaunchSpec, error)
// IsAvailable reports whether the agent binary is present and usable.
IsAvailable() bool
// Type returns the agent type this driver handles.
Type() AgentType
}
AgentDriver knows how to prepare the launch of an agent process. Each agent type (Claude, Codex, opencode, …) provides its own Driver.
A Driver is responsible for:
- Binary discovery
- CLI argument construction
- Environment setup
- Initial prompt injection (stdin bootstrap)
A Driver does NOT manage the running process or the communication protocol.
type AgentMessage ¶
type AgentMessage interface {
// GetType returns the message type (one of EventType constants)
GetType() string
// GetTimestamp returns when the message was created
GetTimestamp() time.Time
// GetSessionID returns the session ID if available
GetSessionID() string
// GetAgentType returns the source agent type
GetAgentType() AgentType
// GetRawData returns the raw message data as a map
GetRawData() map[string]interface{}
// ToEvent converts the message to an Event
ToEvent() Event
}
AgentMessage is the unified interface for all agent messages All agent implementations should convert their messages to this interface
func MessageFromEvent ¶
func MessageFromEvent(event Event, agentType AgentType) AgentMessage
MessageFromEvent converts an Event to an AgentMessage if possible
type AgentTransport ¶ added in v0.260507.1
type AgentTransport interface {
// Classify reports the kind of the event. For control events it also
// returns the parsed StreamEvent (ApprovalRequestEvent or
// AskRequestEvent) ready to emit on the handle.
//
// The execution-context fields (sessionID, chatID, platform, botUUID)
// previously set via SetExecutionContext are stamped onto the StreamEvent
// during Classify.
Classify(ev common.Event) (kind EventKind, parsed StreamEvent)
// AccumulateMessage feeds the event to the per-agent message accumulator
// and returns 0+ rich message values to emit as [MessageEvent.Raw]. The
// concrete type of each value is agent-specific (e.g.
// *claude.AssistantMessage). The runner does not introspect them.
AccumulateMessage(ev common.Event) []any
// EncodeControlResponse converts a [ControlResponse] into the wire value
// sent to the agent process's stdin via [protocol.Encoder].
//
// originalInput is the Input field of the corresponding
// ApprovalRequestEvent / AskRequestEvent; some agents (e.g. claude) use
// it when constructing the "allow" reply if the response did not supply
// an UpdatedInput.
EncodeControlResponse(reqID string, resp ControlResponse, originalInput map[string]any) any
// SetExecutionContext injects per-execution routing metadata that is
// stamped onto Approval/Ask events during Classify.
SetExecutionContext(sessionID, chatID, platform, botUUID string)
}
AgentTransport is the per-agent protocol parser. It is pure: it consumes common.Event values and produces classifications and encoded responses, but performs no IO and owns no goroutines.
Each agent type (Claude, Codex, …) provides its own AgentTransport.
type ApprovalHandler ¶
type ApprovalHandler interface {
OnApproval(ctx context.Context, req PermissionRequest) (PermissionResult, error)
}
ApprovalHandler handles permission confirmations
type ApprovalRequestEvent ¶ added in v0.260507.1
type ApprovalRequestEvent struct {
ID string
AgentType AgentType
ToolName string
Input map[string]any
Reason string
SessionID string
ChatID string
Platform string
BotUUID string
}
ApprovalRequestEvent is emitted when the agent requests permission to use a tool. Callers must call [ExecutionHandle.Respond] with ApprovalResponse to unblock the agent.
type ApprovalResponse ¶ added in v0.260507.1
ApprovalResponse responds to an ApprovalRequestEvent.
type AskHandler ¶
type AskHandler interface {
OnAsk(ctx context.Context, req AskRequest) (AskResult, error)
}
AskHandler handles user questions/selections
type AskRequest ¶
type AskRequest struct {
ID string `json:"id"`
Type string `json:"type"` // "permission", "question", "confirmation", "text_input"
Platform string `json:"platform"`
ChatID string `json:"chat_id"`
BotUUID string `json:"bot_uuid"`
SessionID string `json:"session_id,omitempty"`
AgentType AgentType `json:"agent_type"`
ToolName string `json:"tool_name,omitempty"`
Input map[string]interface{} `json:"input,omitempty"`
Message string `json:"message,omitempty"`
CallID string `json:"call_id,omitempty"`
Reason string `json:"reason,omitempty"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
}
AskRequest represents a request to ask the user something This is a simplified version of ask.Request to avoid circular imports
type AskRequestEvent ¶ added in v0.260507.1
type AskRequestEvent struct {
ID string
AgentType AgentType
Type string
ToolName string
Input map[string]any
CallID string
Message string
Reason string
SessionID string
ChatID string
Platform string
BotUUID string
}
AskRequestEvent is emitted for AskUserQuestion-style interactive prompts. Callers respond via [ExecutionHandle.Respond] with AskResponse.
type AskResponse ¶ added in v0.260507.1
type AskResponse struct {
Approved bool
UpdatedInput map[string]any
Reason string
Response string
Selection map[string]any
}
AskResponse responds to an AskRequestEvent.
type AskResult ¶
type AskResult struct {
ID string `json:"id"`
Approved bool `json:"approved,omitempty"`
Response string `json:"response,omitempty"`
Selection map[string]interface{} `json:"selection,omitempty"`
Remember bool `json:"remember,omitempty"`
Reason string `json:"reason,omitempty"`
UpdatedInput map[string]interface{} `json:"updated_input,omitempty"`
}
AskResult represents the user's response to an ask request
type AssistantMessage ¶
type AssistantMessage struct {
BaseMessage
Text string `json:"text,omitempty"`
Content []ContentBlock `json:"content,omitempty"`
Extra map[string]interface{} `json:"extra,omitempty"`
}
AssistantMessage represents an assistant response
func NewAssistantMessage ¶
func NewAssistantMessage(agentType AgentType, sessionID, text string) *AssistantMessage
NewAssistantMessage creates a new assistant message
func (*AssistantMessage) GetRawData ¶
func (m *AssistantMessage) GetRawData() map[string]interface{}
GetRawData returns raw data
func (*AssistantMessage) GetText ¶
func (m *AssistantMessage) GetText() string
GetText returns the text content
func (*AssistantMessage) ToEvent ¶
func (m *AssistantMessage) ToEvent() Event
ToEvent converts AssistantMessage to Event
type BaseMessage ¶
type BaseMessage struct {
Type string `json:"type"`
AgentType AgentType `json:"agent_type"`
SessionID string `json:"session_id,omitempty"`
Timestamp time.Time `json:"timestamp"`
}
BaseMessage provides common fields for message implementations
func (*BaseMessage) GetAgentType ¶
func (m *BaseMessage) GetAgentType() AgentType
GetAgentType returns the agent type
func (*BaseMessage) GetRawData ¶
func (m *BaseMessage) GetRawData() map[string]interface{}
GetRawData returns the raw data - should be overridden by embedders
func (*BaseMessage) GetSessionID ¶
func (m *BaseMessage) GetSessionID() string
GetSessionID returns the session ID
func (*BaseMessage) GetTimestamp ¶
func (m *BaseMessage) GetTimestamp() time.Time
GetTimestamp returns the timestamp
func (*BaseMessage) GetType ¶
func (m *BaseMessage) GetType() string
GetType returns the message type
func (*BaseMessage) ToEvent ¶
func (m *BaseMessage) ToEvent() Event
ToEvent converts BaseMessage to Event - should be overridden by embedders
type CompletionCallback ¶
type CompletionCallback interface {
OnComplete(result *CompletionResult)
}
CompletionCallback handles completion notification
type CompletionResult ¶
type CompletionResult struct {
Success bool
DurationMS int64
SessionID string
Error string
ExtraFields map[string]any
}
CompletionResult contains the final result information
type CompositeHandler ¶
type CompositeHandler struct {
// contains filtered or unexported fields
}
CompositeHandler combines multiple handler interfaces into one MessageHandler. It allows composing different handlers for streaming, approval, ask, and completion.
func NewCompositeHandler ¶
func NewCompositeHandler() *CompositeHandler
NewCompositeHandler creates a new empty CompositeHandler. Use Set* methods to configure individual handlers.
func (*CompositeHandler) OnApproval ¶
func (h *CompositeHandler) OnApproval(ctx context.Context, req PermissionRequest) (PermissionResult, error)
OnApproval implements MessageHandler. Forwards to the ApprovalHandler if set, otherwise auto-approves.
func (*CompositeHandler) OnAsk ¶
func (h *CompositeHandler) OnAsk(ctx context.Context, req AskRequest) (AskResult, error)
OnAsk implements MessageHandler. Forwards to the AskHandler if set, otherwise auto-approves.
func (*CompositeHandler) OnComplete ¶
func (h *CompositeHandler) OnComplete(result *CompletionResult)
OnComplete implements MessageHandler. Forwards to the CompletionCallback if set.
func (*CompositeHandler) OnError ¶
func (h *CompositeHandler) OnError(err error)
OnError implements MessageHandler. Forwards to the MessageStreamer if set.
func (*CompositeHandler) OnMessage ¶
func (h *CompositeHandler) OnMessage(msg interface{}) error
OnMessage implements MessageHandler. Forwards to the MessageStreamer if set.
func (*CompositeHandler) SetApprovalHandler ¶
func (h *CompositeHandler) SetApprovalHandler(a ApprovalHandler) *CompositeHandler
SetApprovalHandler sets the approval handler. Returns self for chaining.
func (*CompositeHandler) SetAskHandler ¶
func (h *CompositeHandler) SetAskHandler(a AskHandler) *CompositeHandler
SetAskHandler sets the ask handler. Returns self for chaining.
func (*CompositeHandler) SetCompletionCallback ¶
func (h *CompositeHandler) SetCompletionCallback(c CompletionCallback) *CompositeHandler
SetCompletionCallback sets the completion callback. Returns self for chaining.
func (*CompositeHandler) SetStreamer ¶
func (h *CompositeHandler) SetStreamer(s MessageStreamer) *CompositeHandler
SetStreamer sets the message streamer handler. Returns self for chaining.
func (*CompositeHandler) WithCompletionFunc ¶ added in v0.260507.1
func (h *CompositeHandler) WithCompletionFunc(f func(result *CompletionResult)) *CompositeHandler
WithCompletionFunc sets a function to be called on completion. Convenience method that wraps f in a CompletionCallback.
func (*CompositeHandler) WithErrorFunc ¶ added in v0.260507.1
func (h *CompositeHandler) WithErrorFunc(f func(err error)) *CompositeHandler
WithErrorFunc sets a function to be called on error. If a streamer is already set, the function is layered on top; otherwise a no-op streamer is created so only the error hook fires.
func (*CompositeHandler) WithMessageFunc ¶ added in v0.260507.1
func (h *CompositeHandler) WithMessageFunc(f func(msg interface{}) error) *CompositeHandler
WithMessageFunc sets a function to be called for each message. Convenience method that wraps f in a MessageStreamer.
type Config ¶
type Config struct {
DefaultAgent AgentType `json:"default_agent"`
DefaultFormat OutputFormat `json:"default_format"`
EnableStreamJSON bool `json:"enable_stream_json"`
StreamBufferSize int `json:"stream_buffer_size"`
DefaultExecutionTimeout time.Duration `json:"default_execution_timeout"`
// Session configuration
ClaudeProjectsDir string `json:"claude_projects_dir,omitempty"` // Path to Claude projects directory
}
Config holds the AgentBoot configuration
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns the default AgentBoot configuration
type ContentBlock ¶
type ContentBlock struct {
Type string `json:"type"`
Text string `json:"text,omitempty"`
// For tool_use
ToolID string `json:"tool_id,omitempty"`
ToolName string `json:"tool_name,omitempty"`
Input map[string]interface{} `json:"input,omitempty"`
}
ContentBlock represents a block of content
type ControlResponse ¶ added in v0.260507.1
type ControlResponse interface {
// contains filtered or unexported methods
}
ControlResponse is the sum type passed to [ExecutionHandle.Respond].
The interface is sealed; agentboot owns the closed set of response shapes.
type ErrorEvent ¶ added in v0.260507.1
type ErrorEvent struct {
Err error
}
ErrorEvent reports a non-fatal error noticed during execution. The runner continues processing after emitting an ErrorEvent. Fatal errors are surfaced via [ExecutionHandle.Wait]'s returned error instead.
type Event ¶
Event represents a generic agent event. Alias of common.Event — the two types are identical and interchangeable.
type EventKind ¶ added in v0.260507.1
type EventKind int
EventKind is the classification result returned by [AgentTransport.Classify].
const ( // EventKindIgnore: the event is fully consumed by the transport (e.g. // internal-only system pings); the runner does not emit anything. EventKindIgnore EventKind = iota // EventKindMessage: a streamable agent message. The runner calls // [AgentTransport.AccumulateMessage] and emits a [MessageEvent] for each // rich message returned. EventKindMessage // EventKindControl: an interactive control request (permission/ask). // The corresponding parsed [StreamEvent] is returned alongside this // kind by Classify; the runner emits it on the handle and waits for a // response via [ExecutionHandle.Respond]. EventKindControl // EventKindTerminalSuccess: the agent emitted a successful terminal // event. The runner records success and stops processing further events. EventKindTerminalSuccess // EventKindTerminalError: the agent emitted a failed terminal event. // The runner records failure and stops processing further events. EventKindTerminalError )
type ExecutionHandle ¶ added in v0.260507.1
type ExecutionHandle interface {
Events() <-chan StreamEvent
Respond(reqID string, resp ControlResponse) error
Wait() (*Result, error)
Cancel()
}
ExecutionHandle is the per-execution result of [Agent.Execute].
Lifecycle:
- Caller iterates Events() to consume the totally-ordered event stream.
- For ApprovalRequestEvent / AskRequestEvent, caller computes a response and calls Respond(req.ID, response). The runner encodes the response and forwards it to the agent process's stdin.
- The channel closes after the underlying process has exited AND every decoded event has been delivered to the channel.
- After the channel closes, Wait() returns immediately with the aggregated Result.
Cancellation:
- Cancel() requests cooperative shutdown; idempotent. The runner kills the process and joins all goroutines; the channel then closes.
- The Context passed to Execute can also be canceled to the same effect.
Concurrency:
- Events() may be consumed by exactly one goroutine.
- Respond / Cancel / Wait are safe to call concurrently from any goroutine.
type ExecutionOptions ¶
type ExecutionOptions struct {
ProjectPath string
OutputFormat OutputFormat
Timeout time.Duration
Env []string
// SessionID is the session ID to use or resume
// If Resume is true, --resume <session_id> is used to continue an existing session
// If Resume is false, --session-id <session_id> is used to create a new session with specific ID
SessionID string
// Resume indicates whether to resume an existing session (true) or create a new one (false)
Resume bool
// ChatID is the chat ID for permission requests (used by mock agent)
ChatID string
// Platform is the platform for permission requests (used by mock agent)
Platform string
// BotUUID is the bot UUID for permission callbacks
BotUUID string
// Model selection (per-execution override)
Model string
FallbackModel string
// Execution control
MaxTurns int
// Tool filtering (per-execution override)
AllowedTools []string
DisallowedTools []string
// MCP servers (per-execution override)
MCPServers map[string]interface{}
StrictMcpConfig bool
// System prompts (per-execution override)
CustomSystemPrompt string
AppendSystemPrompt string
// Permission mode (per-execution override)
PermissionMode string
// Settings path (per-execution override)
SettingsPath string
// PermissionPromptTool specifies the tool for permission prompts (e.g., "stdio")
// When set to "stdio", permission requests are sent via stdin/stdout for callback handling
PermissionPromptTool string
// Store, if set, receives session lifecycle events driven by the runner.
// When non-nil and SessionID is non-empty the runner calls:
// SetRunning — after the process starts successfully
// SetFailed — if the process fails to start or Wait returns an error
// SetCompleted — if Wait returns without error
Store agentsession.Store
}
ExecutionOptions controls agent execution
type HandleControls ¶ added in v0.260507.1
type HandleControls struct {
// contains filtered or unexported fields
}
HandleControls bundles the operations a custom Agent implementation uses to drive an ExecutionHandle it created via NewControlledHandle.
Emit and Close are the inverse of Events() and channel-close that the consumer observes: the producer pushes events with Emit and signals completion with Close.
func (*HandleControls) Close ¶ added in v0.260507.1
func (c *HandleControls) Close()
Close closes the handle's Events channel exactly once. After Close, [ExecutionHandle.Respond] returns ErrHandleClosed.
func (*HandleControls) Emit ¶ added in v0.260507.1
func (c *HandleControls) Emit(ctx context.Context, ev StreamEvent)
Emit pushes a stream event to the handle's Events channel. It blocks until the consumer reads the event, or until ctx is canceled — in which case the event is dropped and any pending control registration is cleaned up automatically.
type InitMessage ¶
type InitMessage struct {
BaseMessage
MaxIterations int `json:"max_iterations,omitempty"`
}
InitMessage represents agent initialization
func NewInitMessage ¶
func NewInitMessage(agentType AgentType, sessionID string, maxIterations int) *InitMessage
NewInitMessage creates a new init message
func (*InitMessage) GetRawData ¶
func (m *InitMessage) GetRawData() map[string]interface{}
GetRawData returns raw data
func (*InitMessage) ToEvent ¶
func (m *InitMessage) ToEvent() Event
ToEvent converts InitMessage to Event
type LaunchSpec ¶ added in v0.260507.1
type LaunchSpec struct {
// Command is the binary and arguments (e.g. ["claude", "--output-format", "stream-json", ...])
Command []string
// Env is the process environment. nil inherits the current process environment.
Env []string
// WorkDir is the working directory for the agent process. Empty means current directory.
WorkDir string
// InitialInput is an optional channel that feeds initial messages into the agent's stdin.
// Close the channel to signal EOF. May be nil.
InitialInput <-chan any
}
LaunchSpec describes how to start an agent process. It is pure data: no business logic.
type MessageEvent ¶ added in v0.260507.1
type MessageEvent struct {
Raw any
}
MessageEvent wraps a streamable agent message after the per-agent accumulator has consumed the raw common.Event. The concrete type of Raw is agent-specific (e.g. *claude.AssistantMessage, *claude.ToolUseMessage, or agentboot.AgentMessage); consumers type-switch.
In addition to emitting MessageEvents, the runner appends the raw underlying common.Event values to [Result.Events] for callers that prefer the aggregated form returned from [ExecutionHandle.Wait].
type MessageHandler ¶
type MessageHandler interface {
OnMessage(msg interface{}) error
OnError(err error)
OnComplete(result *CompletionResult)
OnApproval(ctx context.Context, req PermissionRequest) (PermissionResult, error)
OnAsk(ctx context.Context, req AskRequest) (AskResult, error)
}
MessageHandler is the primary interface for handling agent callbacks This interface is defined here to avoid circular dependencies
type MessageSink ¶ added in v0.260507.1
type MessageSink func(any)
MessageSink receives the [MessageEvent.Raw] value of each message event, in order. Pass nil to drop message events (e.g. when only completion matters).
type MessageStreamer ¶
MessageStreamer handles streaming messages (subset of MessageHandler)
type OutputFormat ¶
type OutputFormat string
OutputFormat defines agent output format
const ( OutputFormatText OutputFormat = "text" OutputFormatStreamJSON OutputFormat = "stream-json" )
func (OutputFormat) String ¶
func (f OutputFormat) String() string
String returns the string representation of OutputFormat
type PermissionConfig ¶
type PermissionConfig struct {
DefaultMode PermissionMode `json:"default_mode"`
Timeout time.Duration `json:"timeout"`
EnableWhitelist bool `json:"enable_whitelist"`
Whitelist []string `json:"whitelist"`
Blacklist []string `json:"blacklist"`
RememberDecisions bool `json:"remember_decisions"`
DecisionDuration time.Duration `json:"decision_duration"`
}
PermissionConfig holds permission handler configuration
func DefaultPermissionConfig ¶
func DefaultPermissionConfig() PermissionConfig
DefaultPermissionConfig returns the default permission handler configuration
type PermissionMode ¶
type PermissionMode string
PermissionMode defines how permission requests are handled. Use ask.Mode for the ask-subsystem-specific mode values.
const ( PermissionModeAuto PermissionMode = "auto" // Auto-approve all requests PermissionModeManual PermissionMode = "manual" // Require user approval PermissionModeSkip PermissionMode = "skip" // Skip permission prompts )
func (PermissionMode) String ¶
func (m PermissionMode) String() string
String returns the string representation of PermissionMode
type PermissionRequest ¶
type PermissionRequest struct {
RequestID string `json:"request_id"`
AgentType AgentType `json:"agent_type"`
ToolName string `json:"tool_name"`
Input map[string]interface{} `json:"input"`
Reason string `json:"reason,omitempty"`
Timestamp time.Time `json:"timestamp"`
SessionID string `json:"session_id,omitempty"`
BotUUID string `json:"bot_uuid,omitempty"` // Bot UUID for routing permission requests
ChatID string `json:"chat_id,omitempty"` // Chat ID for routing
Platform string `json:"platform,omitempty"` // Platform for routing
}
PermissionRequest represents a permission request from an agent
type PermissionRequestMessage ¶
type PermissionRequestMessage struct {
BaseMessage
RequestID string `json:"request_id"`
ToolName string `json:"tool_name"`
Input map[string]interface{} `json:"input"`
Reason string `json:"reason,omitempty"`
Step int `json:"step,omitempty"`
Total int `json:"total,omitempty"`
}
PermissionRequestMessage represents a permission request
func NewPermissionRequestMessage ¶
func NewPermissionRequestMessage(agentType AgentType, sessionID, requestID, toolName string, input map[string]interface{}, reason string) *PermissionRequestMessage
NewPermissionRequestMessage creates a new permission request message
func (*PermissionRequestMessage) GetRawData ¶
func (m *PermissionRequestMessage) GetRawData() map[string]interface{}
GetRawData returns raw data
func (*PermissionRequestMessage) ToEvent ¶
func (m *PermissionRequestMessage) ToEvent() Event
ToEvent converts PermissionRequestMessage to Event
type PermissionResponse ¶
type PermissionResponse struct {
RequestID string `json:"request_id"`
Approved bool `json:"approved"`
Reason string `json:"reason,omitempty"`
Timestamp time.Time `json:"timestamp"`
}
PermissionResponse represents the response to a permission request
type PermissionResult ¶
type PermissionResult struct {
Approved bool `json:"approved"`
Reason string `json:"reason,omitempty"`
UpdatedInput map[string]interface{} `json:"updated_input,omitempty"`
Remember bool `json:"remember,omitempty"`
}
PermissionResult represents the result of a permission check
type PermissionResultMessage ¶
type PermissionResultMessage struct {
BaseMessage
RequestID string `json:"request_id"`
Approved bool `json:"approved"`
Reason string `json:"reason,omitempty"`
Remember bool `json:"remember,omitempty"`
}
PermissionResultMessage represents the result of a permission request
func NewPermissionResultMessage ¶
func NewPermissionResultMessage(agentType AgentType, sessionID, requestID string, approved bool, reason string) *PermissionResultMessage
NewPermissionResultMessage creates a new permission result message
func (*PermissionResultMessage) GetRawData ¶
func (m *PermissionResultMessage) GetRawData() map[string]interface{}
GetRawData returns raw data
func (*PermissionResultMessage) ToEvent ¶
func (m *PermissionResultMessage) ToEvent() Event
ToEvent converts PermissionResultMessage to Event
type Prompter ¶ added in v0.260507.1
type Prompter interface {
OnApproval(ctx context.Context, req PermissionRequest) (PermissionResult, error)
OnAsk(ctx context.Context, req AskRequest) (AskResult, error)
}
Prompter is the consumer-supplied callback the bot layer (or any caller of RunWithPrompter) provides to satisfy approval and ask requests during agent execution.
Contract:
Timeout / cancellation. The caller's ctx carries the deadline. On ctx.Done() the Prompter MUST return promptly with Approved=false (i.e., default-deny). Implementations are free to enforce an additional internal timeout (IMPrompter uses 5min by default) but ctx is authoritative.
AlwaysAllow caching. If the user previously approved a tool with "remember", subsequent OnApproval calls for the same tool MUST short-circuit to Approved=true without prompting again. The Prompter owns this cache; executors do not maintain per-tool allowlists.
No partial failures. On internal error the Prompter returns the error AND a deny result (Approved=false), so RunWithPrompter always has a safe response to send to the agent.
Implementations: IMPrompter (production) and prompt.FakePrompter (tests).
type Result ¶
type Result struct {
Output string // Agent output (text mode)
ExitCode int // Process exit code
Error string // Error message if failed
Duration time.Duration
Format OutputFormat // Output format used
Events []Event // Stream events (stream-json mode)
Metadata map[string]interface{} // Additional metadata
}
Result represents the result of an agent execution
func RunWithPrompter ¶ added in v0.260507.1
func RunWithPrompter(ctx context.Context, h ExecutionHandle, prompter Prompter, sink MessageSink) (*Result, error)
RunWithPrompter is the convenience consumer of an ExecutionHandle.
It iterates handle.Events() in order, dispatching:
- MessageEvent → sink (if non-nil)
- ApprovalRequestEvent → prompter.OnApproval, then handle.Respond
- AskRequestEvent → prompter.OnAsk, then handle.Respond
- ErrorEvent → logged and ignored
Approval/ask invocations are synchronous within the loop (matching the existing IMPrompter blocking semantics — Claude waits for a response before emitting more events, so back-pressure is not a concern).
Once the channel closes, RunWithPrompter calls handle.Wait() and returns its result.
Use this from executor code that does not need event-level visibility. Tests and executors that DO want fine-grained control should iterate handle.Events() directly.
func (*Result) GetAssistantMessages ¶
GetAssistantMessages returns all assistant message events
func (*Result) GetCostUSD ¶
GetCostUSD extracts the total cost from result events if available
func (*Result) GetMessageChain ¶
GetMessageChain returns all events in order, excluding result/system events
func (*Result) GetMessagesByType ¶
GetMessagesByType returns all events of a specific type
func (*Result) GetSessionID ¶
GetSessionID extracts the session ID from metadata or events
func (*Result) GetToolResultMessages ¶
GetToolResultMessages returns all tool_result message events
func (*Result) GetToolUseMessages ¶
GetToolUseMessages returns all tool_use message events
func (*Result) GetUserMessages ¶
GetUserMessages returns all user message events
func (*Result) TextOutput ¶
TextOutput returns the full text output from the result
type ResultMessage ¶
type ResultMessage struct {
BaseMessage
Status string `json:"status"` // "success", "error", "cancelled", "permission_denied"
Message string `json:"message,omitempty"`
CostUSD float64 `json:"cost_usd,omitempty"`
Duration int64 `json:"duration_ms,omitempty"`
Steps int `json:"steps_completed,omitempty"`
IsError bool `json:"is_error,omitempty"`
ErrorMsg string `json:"error,omitempty"`
}
ResultMessage represents the final result
func NewResultMessage ¶
func NewResultMessage(agentType AgentType, sessionID, status, message string) *ResultMessage
NewResultMessage creates a new result message
func (*ResultMessage) GetRawData ¶
func (m *ResultMessage) GetRawData() map[string]interface{}
GetRawData returns raw data
func (*ResultMessage) IsSuccess ¶
func (m *ResultMessage) IsSuccess() bool
IsSuccess returns true if result is successful
func (*ResultMessage) ToEvent ¶
func (m *ResultMessage) ToEvent() Event
ToEvent converts ResultMessage to Event
type Runner ¶ added in v0.260507.1
type Runner struct {
// contains filtered or unexported fields
}
Runner is a generic agent executor that composes an AgentDriver (process setup) with an AgentTransport (protocol parsing) and a process.Factory (process supervision) to implement the Agent interface.
The default Runner uses process.NewOSExecFactory to spawn real processes. Tests inject process.NewFakeFactory via NewRunnerWithFactory to substitute the binary while exercising the same driver and transport.
func NewRunner ¶ added in v0.260507.1
func NewRunner(driver AgentDriver, transport AgentTransport) *Runner
NewRunner creates a Runner backed by process.NewOSExecFactory.
func NewRunnerWithFactory ¶ added in v0.260507.1
func NewRunnerWithFactory(driver AgentDriver, transport AgentTransport, factory process.Factory) *Runner
NewRunnerWithFactory creates a Runner with a custom process factory. Use process.NewFakeFactory in tests.
func (*Runner) Execute ¶ added in v0.260507.1
func (r *Runner) Execute(ctx context.Context, prompt string, opts ExecutionOptions) (ExecutionHandle, error)
Execute starts the agent and returns an ExecutionHandle for the caller to consume events from and respond to control requests via.
The returned handle's Events channel closes after the underlying process has exited and all decoded events have been delivered. Wait then returns the aggregated Result.
func (*Runner) GetDefaultFormat ¶ added in v0.260507.1
func (r *Runner) GetDefaultFormat() OutputFormat
func (*Runner) IsAvailable ¶ added in v0.260507.1
func (*Runner) SetDefaultFormat ¶ added in v0.260507.1
func (r *Runner) SetDefaultFormat(f OutputFormat)
type StreamDeltaMessage ¶
type StreamDeltaMessage struct {
BaseMessage
Delta string `json:"delta"`
}
StreamDeltaMessage represents incremental streaming content
func NewStreamDeltaMessage ¶
func NewStreamDeltaMessage(agentType AgentType, sessionID, delta string) *StreamDeltaMessage
NewStreamDeltaMessage creates a new stream delta message
func (*StreamDeltaMessage) GetRawData ¶
func (m *StreamDeltaMessage) GetRawData() map[string]interface{}
GetRawData returns raw data
func (*StreamDeltaMessage) ToEvent ¶
func (m *StreamDeltaMessage) ToEvent() Event
ToEvent converts StreamDeltaMessage to Event
type StreamEvent ¶ added in v0.260507.1
type StreamEvent interface {
// contains filtered or unexported methods
}
StreamEvent is the sum type of events flowing on [ExecutionHandle.Events]. Callers type-switch to specific event types.
The interface is sealed (its sentinel method is unexported) so that agentboot owns the closed set of event types that runners may emit.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
examples/session
command
|
|
|
fixture
Package fixture provides a Claude wire-format scripted process.Factory for testing.
|
Package fixture provides a Claude wire-format scripted process.Factory for testing. |
|
Package process provides the seam between agentboot and the OS process that implements an agent (e.g.
|
Package process provides the seam between agentboot and the OS process that implements an agent (e.g. |
|
Package prompt holds test doubles and helpers for the agentboot.Prompter contract.
|
Package prompt holds test doubles and helpers for the agentboot.Prompter contract. |
|
Package protocol is the pure stream-protocol layer of agentboot.
|
Package protocol is the pure stream-protocol layer of agentboot. |