Documentation
¶
Overview ¶
Package control provides engine control-flow safety types — loop detection, stall detection, and backtracking.
Public types: LoopDetector, StallEntry, StallResult, StallDetector, DecisionPoint, BacktrackEngine.
Public functions: NewLoopDetector, NewStallDetector, NewBacktrackEngine. Public constants: DoomLoopThreshold.
Index ¶
- Constants
- type BacktrackEngine
- func (be *BacktrackEngine) FindBacktrackPoint() *DecisionPoint
- func (be *BacktrackEngine) GenerateRetryPrompt(dp *DecisionPoint) string
- func (be *BacktrackEngine) MarkOutcome(turnIdx int, outcome string)
- func (be *BacktrackEngine) RecordDecision(turnIdx int, desc string, alternatives []string, msgs []types.EyrieMessage)
- func (be *BacktrackEngine) RestoreState(dp *DecisionPoint) []types.EyrieMessage
- func (be *BacktrackEngine) Size() int
- type DecisionPoint
- type LoopDetector
- func (ld *LoopDetector) DoomLoopWarning() string
- func (ld *LoopDetector) Escalated() bool
- func (ld *LoopDetector) IsDoomLoop() bool
- func (ld *LoopDetector) IsLooping() bool
- func (ld *LoopDetector) LoopWarning() string
- func (ld *LoopDetector) MarkEscalated()
- func (ld *LoopDetector) RecordStep(toolNames []string, inputs []string, outputs []string)
- func (ld *LoopDetector) Reset()
- type StallDetector
- func (sd *StallDetector) BuildEscalation(result *StallResult) string
- func (sd *StallDetector) Check() *StallResult
- func (sd *StallDetector) DetectErrorLoop() bool
- func (sd *StallDetector) DetectOscillation() bool
- func (sd *StallDetector) DetectRepetition() (int, string)
- func (sd *StallDetector) FormatWindow() string
- func (sd *StallDetector) Record(toolName string, args map[string]interface{}, output string)
- func (sd *StallDetector) Reset()
- type StallEntry
- type StallResult
Constants ¶
const DoomLoopThreshold = 3
DoomLoopThreshold is the number of repeated patterns before escalation (matches OpenCode).
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BacktrackEngine ¶
type BacktrackEngine struct {
// contains filtered or unexported fields
}
BacktrackEngine records decision points during agent execution and provides the ability to identify the most recent failure and generate a retry prompt with alternative approaches.
func NewBacktrackEngine ¶
func NewBacktrackEngine() *BacktrackEngine
NewBacktrackEngine creates a new backtrack engine that retains at most 50 decision points.
func (*BacktrackEngine) FindBacktrackPoint ¶
func (be *BacktrackEngine) FindBacktrackPoint() *DecisionPoint
FindBacktrackPoint returns the most recent failed decision point that has alternative approaches available, or nil if none exists.
func (*BacktrackEngine) GenerateRetryPrompt ¶
func (be *BacktrackEngine) GenerateRetryPrompt(dp *DecisionPoint) string
GenerateRetryPrompt builds a prompt that tells the agent what failed and suggests alternative approaches.
func (*BacktrackEngine) MarkOutcome ¶
func (be *BacktrackEngine) MarkOutcome(turnIdx int, outcome string)
MarkOutcome sets the outcome ("success" or "failure") for the decision at the given turn index. If multiple decisions exist at the same turn index, the most recent one is updated.
func (*BacktrackEngine) RecordDecision ¶
func (be *BacktrackEngine) RecordDecision(turnIdx int, desc string, alternatives []string, msgs []types.EyrieMessage)
RecordDecision saves a decision point with the current conversation state. If the number of recorded points exceeds the maximum, the oldest point is removed.
func (*BacktrackEngine) RestoreState ¶
func (be *BacktrackEngine) RestoreState(dp *DecisionPoint) []types.EyrieMessage
RestoreState returns the conversation messages captured at the given decision point, representing the state just before (not including) the failed decision. This allows the agent to retry from that point.
func (*BacktrackEngine) Size ¶
func (be *BacktrackEngine) Size() int
Size returns the number of recorded decision points.
type DecisionPoint ¶
type DecisionPoint struct {
TurnIndex int
Description string // what was decided
Alternatives []string // other options available
Outcome string // "success", "failure", or "" (pending)
Messages []types.EyrieMessage // conversation state at this point
}
DecisionPoint captures a point in the conversation where the agent made a choice that can potentially be rolled back if it leads to failure.
type LoopDetector ¶
type LoopDetector struct {
// contains filtered or unexported fields
}
LoopDetector detects repeated identical tool call patterns using SHA-256 signatures. Supports two severity levels: warning (soft) and doom loop (hard escalation).
func NewLoopDetector ¶
func NewLoopDetector(windowSize, maxRepeats int) *LoopDetector
NewLoopDetector creates a detector with a sliding window.
func (*LoopDetector) DoomLoopWarning ¶
func (ld *LoopDetector) DoomLoopWarning() string
DoomLoopWarning returns the hard escalation message (repeated loops).
func (*LoopDetector) Escalated ¶
func (ld *LoopDetector) Escalated() bool
Escalated returns whether the detector has already fired a warning.
func (*LoopDetector) IsDoomLoop ¶
func (ld *LoopDetector) IsDoomLoop() bool
IsDoomLoop returns true when the agent has been stuck for DoomLoopThreshold consecutive escalation attempts — it should hard-stop and ask the user.
func (*LoopDetector) IsLooping ¶
func (ld *LoopDetector) IsLooping() bool
IsLooping returns true if any signature appears more than maxRepeats times in the window.
func (*LoopDetector) LoopWarning ¶
func (ld *LoopDetector) LoopWarning() string
LoopWarning returns the soft warning message (first detection).
func (*LoopDetector) MarkEscalated ¶
func (ld *LoopDetector) MarkEscalated()
MarkEscalated records that a warning was shown.
func (*LoopDetector) RecordStep ¶
func (ld *LoopDetector) RecordStep(toolNames []string, inputs []string, outputs []string)
RecordStep hashes the tool calls and results from a single agent step.
func (*LoopDetector) Reset ¶
func (ld *LoopDetector) Reset()
Reset clears the escalation state (e.g., after user provides new direction).
type StallDetector ¶
type StallDetector struct {
Window []StallEntry
WindowSize int
SoftThreshold int // repeats before a warning
HardThreshold int // repeats before escalation
// contains filtered or unexported fields
}
StallDetector monitors recent tool calls for repetition patterns that indicate the agent is stuck. Inspired by goose's repetition inspector and cline's loop detection.
func NewStallDetector ¶
func NewStallDetector() *StallDetector
NewStallDetector creates a StallDetector with sensible defaults.
func (*StallDetector) BuildEscalation ¶
func (sd *StallDetector) BuildEscalation(result *StallResult) string
BuildEscalation formats a human-readable escalation message from a StallResult.
func (*StallDetector) Check ¶
func (sd *StallDetector) Check() *StallResult
Check analyzes the window for stall patterns and returns the result.
func (*StallDetector) DetectErrorLoop ¶
func (sd *StallDetector) DetectErrorLoop() bool
DetectErrorLoop returns true if the same output hash appears 3+ times in the window.
func (*StallDetector) DetectOscillation ¶
func (sd *StallDetector) DetectOscillation() bool
DetectOscillation returns true if the window shows an A→B→A→B pattern.
func (*StallDetector) DetectRepetition ¶
func (sd *StallDetector) DetectRepetition() (int, string)
DetectRepetition finds the longest run of identical (tool+args) entries in the window. Returns the count and a human-readable pattern description.
func (*StallDetector) FormatWindow ¶
func (sd *StallDetector) FormatWindow() string
FormatWindow returns a human-readable representation of the current window for debugging.
func (*StallDetector) Record ¶
func (sd *StallDetector) Record(toolName string, args map[string]interface{}, output string)
Record adds a tool invocation to the sliding window.
func (*StallDetector) Reset ¶
func (sd *StallDetector) Reset()
Reset clears the window after successful unstalling.
type StallEntry ¶
StallEntry represents a single recorded tool invocation in the stall detection window.