Help us shape the future of Go! Take the 2026 Go Developer Survey

executor

package
v0.12.11 Latest Latest
Warning

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

Go to latest
Published: Oct 13, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package executor provides the core autonomous agent execution loop.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EstimateTokens

func EstimateTokens(messages []provider.Message) int

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.0

type Action = policy.Action

Action is a type alias for policy.Action, providing compile-time parity between the executor and policy packages with no string duplication.

const (
	ActionAllow Action = policy.Allow
	ActionDeny  Action = policy.Deny
	ActionAsk   Action = policy.Ask
)

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.0

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:

  1. Keeping the system message (index 0) and the most recent 2 exchanges.
  2. Summarising the middle portion using the LLM provider.
  3. 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.0

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) Evaluate added in v0.7.0

func (d *DenyAllTrustEvaluator) Evaluate(_ context.Context, _ string, _ map[string]any) Action

func (*DenyAllTrustEvaluator) EvaluateCommand added in v0.7.0

func (d *DenyAllTrustEvaluator) EvaluateCommand(_ string) Action

func (*DenyAllTrustEvaluator) EvaluatePath added in v0.7.0

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.

const (
	EventToolCallStart  EventType = "tool_call_start"
	EventToolCallResult EventType = "tool_call_result"
	EventThinking       EventType = "thinking"
	EventText           EventType = "text"
	EventIteration      EventType = "iteration"
	EventCompleted      EventType = "completed"
	EventFailed         EventType = "failed"
	EventTrustAllow     EventType = "trust_allow"
	EventTrustDeny      EventType = "trust_deny"
	EventTrustAsk       EventType = "trust_ask"
)

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.

func (*LoopDetector) Record

func (ld *LoopDetector) Record(toolName string, args map[string]any, result string, isError bool)

Record appends a tool invocation to the history.

func (*LoopDetector) Reset

func (ld *LoopDetector) Reset()

Reset clears recorded history.

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

type MemoryEntry struct {
	ID       string
	AgentID  string
	Content  string
	Category string
}

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) Request added in v0.7.0

func (n *NullApprover) Request(_ context.Context, _ string, _ map[string]any) (string, error)

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 (n *NullMemoryStore) ExtractAndSave(_ context.Context, _ string, _ string, _ provider.Embedder) error

func (*NullMemoryStore) Save

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

type NullTrustEvaluator added in v0.7.0

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) Evaluate added in v0.7.0

func (n *NullTrustEvaluator) Evaluate(_ context.Context, _ string, _ map[string]any) Action

func (*NullTrustEvaluator) EvaluateCommand added in v0.7.0

func (n *NullTrustEvaluator) EvaluateCommand(_ string) Action

func (*NullTrustEvaluator) EvaluatePath added in v0.7.0

func (n *NullTrustEvaluator) EvaluatePath(_ string) Action

type PolicyTrustBridge added in v0.7.0

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) Evaluate added in v0.7.0

func (b *PolicyTrustBridge) Evaluate(ctx context.Context, toolName string, args map[string]any) Action

func (*PolicyTrustBridge) EvaluateCommand added in v0.7.0

func (b *PolicyTrustBridge) EvaluateCommand(cmd string) Action

func (*PolicyTrustBridge) EvaluatePath added in v0.7.0

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.0

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.0

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.0

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.0

func NewPolicyTrustBridge(te *policy.TrustEngine) TrustEvaluator

NewPolicyTrustBridge creates a TrustEvaluator backed by a policy.TrustEngine.

Jump to

Keyboard shortcuts

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