Documentation
¶
Overview ¶
Package executor provides the core autonomous agent execution loop.
Index ¶
- func EstimateTokens(messages []provider.Message) int
- type Action
- type ApprovalRecord
- type ApprovalStatus
- type Approver
- type Config
- type ContainerExecutor
- type ContextManager
- func (cm *ContextManager) Compact(ctx context.Context, messages []provider.Message, aiProvider provider.Provider) []provider.Message
- func (cm *ContextManager) Compactions() int
- func (cm *ContextManager) ContextLimitTokens() int
- func (cm *ContextManager) NeedsCompaction(messages []provider.Message) bool
- func (cm *ContextManager) SetModelLimit(model string, limit int)
- func (cm *ContextManager) TokenUsage(messages []provider.Message) (estimated, limit int)
- type DenyAllTrustEvaluator
- type Event
- type EventType
- type HumanRequest
- type HumanRequester
- type LoopDetector
- type LoopDetectorConfig
- type LoopStatus
- type MemoryEntry
- type MemoryStore
- type NullApprover
- type NullHumanRequester
- type NullMemoryStore
- type NullSecretRedactor
- type NullTranscript
- type NullTrustEvaluator
- type PolicyTrustBridge
- type RequestStatus
- type RequestType
- type Result
- type SandboxConfig
- type SandboxMount
- type SecretRedactor
- type TranscriptEntry
- type TranscriptRecorder
- type TrustEvaluator
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func EstimateTokens ¶
EstimateTokens estimates the number of tokens in a message slice. Uses a rough heuristic of 4 characters per token (standard for English text).
Types ¶
type Action ¶ added in v0.7.1
Action is a type alias for policy.Action, providing compile-time parity between the executor and policy packages with no string duplication.
type ApprovalRecord ¶
type ApprovalRecord struct {
ID string
Status ApprovalStatus
ReviewerComment string
}
ApprovalRecord is a resolved approval request.
type ApprovalStatus ¶
type ApprovalStatus string
ApprovalStatus represents the resolution state of an approval.
const ( ApprovalPending ApprovalStatus = "pending" ApprovalApproved ApprovalStatus = "approved" ApprovalRejected ApprovalStatus = "rejected" ApprovalTimeout ApprovalStatus = "timeout" )
type Approver ¶
type Approver interface {
// Request creates a pending approval for the given tool call and returns its ID.
// Implementers should persist the pending approval so WaitForResolution can query it.
Request(ctx context.Context, toolName string, args map[string]any) (approvalID string, err error)
// WaitForResolution blocks until the approval with the given ID is resolved
// or the timeout elapses.
WaitForResolution(ctx context.Context, approvalID string, timeout time.Duration) (*ApprovalRecord, error)
}
Approver manages approval gate blocking.
type Config ¶
type Config struct {
// Provider is the AI backend. Required.
Provider provider.Provider
// ToolRegistry provides tool definitions and execution. Optional.
ToolRegistry *tools.Registry
// Approver handles approval gates. Defaults to NullApprover.
Approver Approver
// HumanRequester handles blocking human-request gates. Defaults to NullHumanRequester.
HumanRequester HumanRequester
// SecretRedactor redacts secrets from messages. Defaults to NullSecretRedactor.
SecretRedactor SecretRedactor
// Transcript records conversation entries. Defaults to NullTranscript.
Transcript TranscriptRecorder
// Memory provides persistent agent memory. Defaults to NullMemoryStore.
Memory MemoryStore
// MaxIterations caps the agent loop. Default: 10.
MaxIterations int
// ApprovalTimeout is how long to wait for human approval. Default: 30m.
ApprovalTimeout time.Duration
// RequestTimeout is how long to wait for human request response. Default: 60m.
RequestTimeout time.Duration
// LoopDetector config. Zero values use defaults.
LoopDetection LoopDetectorConfig
// CompactionThreshold is the fraction of context limit at which compaction triggers. Default: 0.80.
CompactionThreshold float64
// TaskID and ProjectID are used for transcript recording.
TaskID string
ProjectID string
// Inbox receives external messages injected into the conversation
// between loop iterations. Nil means no external messages.
Inbox <-chan provider.Message
// OnEvent is called for each executor event. Nil means no events emitted.
// The callback must not block — use a buffered channel internally if needed.
OnEvent func(Event)
// ShouldStop is called after each tool execution round. If it returns
// a non-empty string, the loop exits with status "completed" and that
// string as the Result.Content. Nil means no custom termination.
ShouldStop func() (reason string)
// TrustEngine evaluates trust rules before tool execution. Nil = no trust enforcement.
TrustEngine TrustEvaluator
// SandboxMode routes bash and file tool calls through ContainerManager.
SandboxMode bool
// ContainerMgr provides Docker container execution. Required when SandboxMode is true.
ContainerMgr ContainerExecutor
// SandboxSpec is the container configuration for sandbox mode.
SandboxSpec *SandboxConfig
}
Config holds all dependencies for the executor. Nil interface fields are replaced with their Null* implementations.
type ContainerExecutor ¶ added in v0.7.1
type ContainerExecutor interface {
IsAvailable() bool
EnsureContainer(ctx context.Context, projectID, workspacePath string, spec SandboxConfig) (string, error)
ExecInContainer(ctx context.Context, projectID, command, workDir string, timeout int) (stdout, stderr string, exitCode int, err error)
}
ContainerExecutor can run commands inside a Docker container.
type ContextManager ¶
type ContextManager struct {
// contains filtered or unexported fields
}
ContextManager tracks token usage across a message array and compacts the conversation when it approaches the model's context limit.
func NewContextManager ¶
func NewContextManager(providerName string, compactionThreshold float64) *ContextManager
NewContextManager creates a ContextManager for the given provider. The model name is used to look up the context window size. compactionThreshold sets the fraction of the context limit that triggers compaction; pass 0 to use the default (0.80).
func (*ContextManager) Compact ¶
func (cm *ContextManager) Compact( ctx context.Context, messages []provider.Message, aiProvider provider.Provider, ) []provider.Message
Compact compresses the conversation history by:
- Keeping the system message (index 0) and the most recent 2 exchanges.
- Summarising the middle portion using the LLM provider.
- Injecting the summary as a system-level context note.
If summarisation fails, the middle messages are replaced with a placeholder rather than aborting. Returns the compacted message slice.
func (*ContextManager) Compactions ¶
func (cm *ContextManager) Compactions() int
Compactions returns how many times compaction has been applied.
func (*ContextManager) ContextLimitTokens ¶
func (cm *ContextManager) ContextLimitTokens() int
ContextLimitTokens returns the model's context window size in tokens.
func (*ContextManager) NeedsCompaction ¶
func (cm *ContextManager) NeedsCompaction(messages []provider.Message) bool
NeedsCompaction returns true if the estimated token count exceeds the threshold.
func (*ContextManager) SetModelLimit ¶
func (cm *ContextManager) SetModelLimit(model string, limit int)
SetModelLimit overrides the context token limit for a specific model name pattern. This allows module config to adjust limits without modifying the built-in defaults.
func (*ContextManager) TokenUsage ¶
func (cm *ContextManager) TokenUsage(messages []provider.Message) (estimated, limit int)
TokenUsage returns the current estimated tokens and the context limit.
type DenyAllTrustEvaluator ¶ added in v0.7.1
type DenyAllTrustEvaluator struct{}
DenyAllTrustEvaluator denies every tool call. Used as the default when no TrustEngine is configured, so missing configuration fails closed rather than open.
func (*DenyAllTrustEvaluator) EvaluateCommand ¶ added in v0.7.1
func (d *DenyAllTrustEvaluator) EvaluateCommand(_ string) Action
func (*DenyAllTrustEvaluator) EvaluatePath ¶ added in v0.7.1
func (d *DenyAllTrustEvaluator) EvaluatePath(_ string) Action
type Event ¶ added in v0.5.9
type Event struct {
Type EventType `json:"type"`
AgentID string `json:"agent_id,omitempty"`
Iteration int `json:"iteration,omitempty"`
Content string `json:"content,omitempty"` // text content or thinking trace
ToolName string `json:"tool_name,omitempty"` // for tool_call_start/result
ToolCallID string `json:"tool_call_id,omitempty"` // for tool_call_start/result
ToolArgs map[string]any `json:"tool_args,omitempty"` // for tool_call_start
ToolResult string `json:"tool_result,omitempty"` // for tool_call_result
ToolError bool `json:"tool_error,omitempty"` // for tool_call_result
Error string `json:"error,omitempty"` // for failed events
}
Event is emitted during execution for real-time observation.
type EventType ¶ added in v0.5.9
type EventType string
EventType identifies what happened in the executor loop.
type HumanRequest ¶
type HumanRequest struct {
ID string
RequestType RequestType
Status RequestStatus
ResponseData string
ResponseComment string
Metadata string // JSON
}
HumanRequest is a resolved human request record.
type HumanRequester ¶
type HumanRequester interface {
// WaitForResolution blocks until the request with the given ID is resolved
// or the timeout elapses.
WaitForResolution(ctx context.Context, requestID string, timeout time.Duration) (*HumanRequest, error)
}
HumanRequester manages blocking human-request gates.
type LoopDetector ¶
type LoopDetector struct {
// contains filtered or unexported fields
}
LoopDetector detects agent execution loops using multiple heuristics.
func NewLoopDetector ¶
func NewLoopDetector(cfg LoopDetectorConfig) *LoopDetector
NewLoopDetector creates a LoopDetector with the given config. Zero values in cfg are replaced with defaults (MaxConsecutive=3, MaxErrors=2, MaxAlternating=3, MaxNoProgress=3).
func (*LoopDetector) Check ¶
func (ld *LoopDetector) Check() (LoopStatus, string)
Check evaluates the recorded history for loop patterns and returns the current status along with a human-readable explanation. Checks are evaluated in priority order: hard breaks take precedence over warnings.
type LoopDetectorConfig ¶
type LoopDetectorConfig struct {
// MaxConsecutive is the number of identical consecutive tool calls before a loop is detected.
// Default: 3.
MaxConsecutive int
// MaxErrors is the number of times the same tool call can return the same error before a loop is detected.
// Default: 2.
MaxErrors int
// MaxAlternating is the number of A/B alternating cycles before a loop is detected.
// Default: 3.
MaxAlternating int
// MaxNoProgress is the number of identical (same args + same result) non-error calls before a loop is detected.
// Default: 3.
MaxNoProgress int
}
LoopDetectorConfig holds configurable thresholds for loop detection.
type LoopStatus ¶
type LoopStatus int
LoopStatus represents the result of a loop check.
const ( // LoopStatusOK means no loop detected. LoopStatusOK LoopStatus = iota // LoopStatusWarning means a potential loop pattern is forming. LoopStatusWarning // LoopStatusBreak means a definitive loop is detected; execution should stop. LoopStatusBreak )
type MemoryEntry ¶
MemoryEntry is a single piece of persistent agent memory.
type MemoryStore ¶
type MemoryStore interface {
// Search finds relevant memories for agentID using query text.
Search(ctx context.Context, agentID, query string, limit int) ([]MemoryEntry, error)
// Save persists a memory entry.
Save(ctx context.Context, entry MemoryEntry) error
// ExtractAndSave extracts facts from a transcript and saves them.
ExtractAndSave(ctx context.Context, agentID, transcript string, embedder provider.Embedder) error
}
MemoryStore provides persistent memory storage and retrieval.
type NullApprover ¶
type NullApprover struct{}
NullApprover is a no-op Approver for dev/testing — auto-approves every request.
func (*NullApprover) WaitForResolution ¶
func (n *NullApprover) WaitForResolution(_ context.Context, _ string, _ time.Duration) (*ApprovalRecord, error)
type NullHumanRequester ¶
type NullHumanRequester struct{}
NullHumanRequester is a no-op HumanRequester — always returns expired.
func (*NullHumanRequester) WaitForResolution ¶
func (n *NullHumanRequester) WaitForResolution(_ context.Context, _ string, _ time.Duration) (*HumanRequest, error)
type NullMemoryStore ¶
type NullMemoryStore struct{}
NullMemoryStore is a no-op MemoryStore.
func (*NullMemoryStore) ExtractAndSave ¶
func (*NullMemoryStore) Save ¶
func (n *NullMemoryStore) Save(_ context.Context, _ MemoryEntry) error
func (*NullMemoryStore) Search ¶
func (n *NullMemoryStore) Search(_ context.Context, _, _ string, _ int) ([]MemoryEntry, error)
type NullSecretRedactor ¶
type NullSecretRedactor struct{}
NullSecretRedactor is a no-op SecretRedactor.
func (*NullSecretRedactor) CheckAndRedact ¶
func (n *NullSecretRedactor) CheckAndRedact(_ *provider.Message)
func (*NullSecretRedactor) Redact ¶
func (n *NullSecretRedactor) Redact(text string) string
type NullTranscript ¶
type NullTranscript struct{}
NullTranscript is a no-op TranscriptRecorder.
func (*NullTranscript) Record ¶
func (n *NullTranscript) Record(_ context.Context, _ TranscriptEntry) error
type NullTrustEvaluator ¶ added in v0.7.1
type NullTrustEvaluator struct{}
NullTrustEvaluator allows everything — intended for dev/testing only. In production, configure a real TrustEvaluator. When Config.TrustEngine is nil, the executor defaults to DenyAllTrustEvaluator for fail-safe behavior.
func (*NullTrustEvaluator) EvaluateCommand ¶ added in v0.7.1
func (n *NullTrustEvaluator) EvaluateCommand(_ string) Action
func (*NullTrustEvaluator) EvaluatePath ¶ added in v0.7.1
func (n *NullTrustEvaluator) EvaluatePath(_ string) Action
type PolicyTrustBridge ¶ added in v0.7.1
type PolicyTrustBridge struct {
// contains filtered or unexported fields
}
PolicyTrustBridge adapts policy.TrustEngine to executor.TrustEvaluator. It provides a compile-time-safe mapping between policy.Action and executor.Action.
func (*PolicyTrustBridge) EvaluateCommand ¶ added in v0.7.1
func (b *PolicyTrustBridge) EvaluateCommand(cmd string) Action
func (*PolicyTrustBridge) EvaluatePath ¶ added in v0.7.1
func (b *PolicyTrustBridge) EvaluatePath(path string) Action
type RequestStatus ¶
type RequestStatus string
RequestStatus represents the resolution state of a human request.
const ( RequestPending RequestStatus = "pending" RequestResolved RequestStatus = "resolved" RequestCancelled RequestStatus = "cancelled" RequestExpired RequestStatus = "expired" )
type RequestType ¶
type RequestType string
RequestType categorizes what the agent needs from the human.
const ( RequestTypeToken RequestType = "token" RequestTypeBinary RequestType = "binary" RequestTypeAccess RequestType = "access" RequestTypeInfo RequestType = "info" RequestTypeCustom RequestType = "custom" )
type Result ¶
type Result struct {
Content string
Thinking string
Iterations int
Status string // "completed", "failed", "loop_detected", "approval_timeout", "request_expired"
Error string
}
Result is the outcome of an Execute call.
func Execute ¶
func Execute(ctx context.Context, cfg Config, systemPrompt, userTask, agentID string) (*Result, error)
Execute runs the autonomous agent loop with the given config. systemPrompt is the agent's system instructions; userTask is the task to complete; agentID is the agent's identifier used for memory and transcript recording.
type SandboxConfig ¶ added in v0.7.1
type SandboxConfig struct {
Enabled bool `json:"enabled" yaml:"enabled"`
Image string `json:"image" yaml:"image"`
Network string `json:"network" yaml:"network"`
Memory string `json:"memory" yaml:"memory"`
CPU float64 `json:"cpu" yaml:"cpu"`
Mounts []SandboxMount `json:"mounts" yaml:"mounts"`
InitCommands []string `json:"init" yaml:"init"`
}
SandboxConfig holds per-agent Docker sandbox settings.
type SandboxMount ¶ added in v0.7.1
type SandboxMount struct {
Src string `json:"src" yaml:"src"`
Dst string `json:"dst" yaml:"dst"`
ReadOnly bool `json:"readonly" yaml:"readonly"`
}
SandboxMount is a bind mount for a sandbox container.
type SecretRedactor ¶
type SecretRedactor interface {
// Redact returns the text with known secrets replaced.
Redact(text string) string
// CheckAndRedact redacts secrets from a message in place.
CheckAndRedact(msg *provider.Message)
}
SecretRedactor redacts secrets from text.
type TranscriptEntry ¶
type TranscriptEntry struct {
ID string
AgentID string
TaskID string
ProjectID string
Iteration int
Role provider.Role
Content string
Thinking string
ToolCalls []provider.ToolCall
ToolCallID string
}
TranscriptEntry is a single recorded message in the agent conversation.
type TranscriptRecorder ¶
type TranscriptRecorder interface {
Record(ctx context.Context, entry TranscriptEntry) error
}
TranscriptRecorder records agent interactions.
type TrustEvaluator ¶ added in v0.7.1
type TrustEvaluator interface {
// Evaluate returns the trust action for a tool call.
Evaluate(ctx context.Context, toolName string, args map[string]any) Action
// EvaluateCommand returns the trust action for a bash command.
EvaluateCommand(cmd string) Action
// EvaluatePath returns the trust action for a file path.
EvaluatePath(path string) Action
}
TrustEvaluator checks whether a tool call is permitted.
func NewPolicyTrustBridge ¶ added in v0.7.1
func NewPolicyTrustBridge(te *policy.TrustEngine) TrustEvaluator
NewPolicyTrustBridge creates a TrustEvaluator backed by a policy.TrustEngine.