control

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: May 26, 2026 License: MIT Imports: 7 Imported by: 0

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

View Source
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

type StallEntry struct {
	ToolName   string
	ArgsHash   string
	OutputHash string
	Timestamp  time.Time
}

StallEntry represents a single recorded tool invocation in the stall detection window.

type StallResult

type StallResult struct {
	IsStalled   bool
	Level       string // "none", "soft", "hard"
	RepeatCount int
	Pattern     string
	Suggestion  string
}

StallResult describes the outcome of a stall analysis.

Jump to

Keyboard shortcuts

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