Documentation
¶
Overview ¶
Package loop implements the dual bounded loop kernel for OpenBotStack.
The kernel consists of two nested, bounded loops:
- Outer Loop: task/workflow orchestration (INIT → TASK_SELECT → TASK_EXECUTE → CHECKPOINT → NEXT_TASK → DONE)
- Inner Loop: reasoning turn loop (TURN_INIT → PLAN → ACT → OBSERVE → CHECK_STOP → NEXT_TURN → DONE)
All loops are bounded by explicit step/turn counters and wall-clock timeouts. See ADR-012 for design rationale.
Index ¶
- type Checkpoint
- type CompositeCheckpoint
- type ContextCompactor
- type DefaultContextCompactor
- type DefaultInnerLoop
- type DefaultOuterLoop
- type InnerLoop
- type InnerLoopConfig
- type InnerState
- type InnerStopEvaluator
- type LoopMetrics
- type NoOpCheckpoint
- type NoOpCompactor
- type NoOpPolicyCheckpoint
- type OuterLoop
- type OuterLoopConfig
- type OuterState
- type OuterStopEvaluator
- type PolicyCheckpoint
- type StopCondition
- type StopReason
- type TaskInput
- type TaskResult
- type TurnResult
- type WorkflowResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Checkpoint ¶
type Checkpoint interface {
Save(ctx context.Context, taskIndex int, taskResult *TaskResult, metrics *LoopMetrics) error
}
Checkpoint persists intermediate state after each task execution in the outer loop.
type CompositeCheckpoint ¶
type CompositeCheckpoint struct {
// contains filtered or unexported fields
}
CompositeCheckpoint chains multiple Checkpoint implementations. Executes in order; stops and returns the first error encountered.
func NewCompositeCheckpoint ¶
func NewCompositeCheckpoint(cps ...Checkpoint) *CompositeCheckpoint
NewCompositeCheckpoint creates a composite from the given checkpoints.
func (*CompositeCheckpoint) Save ¶
func (c *CompositeCheckpoint) Save(ctx context.Context, taskIndex int, taskResult *TaskResult, metrics *LoopMetrics) error
Save implements Checkpoint by calling each checkpoint in sequence.
type ContextCompactor ¶
type ContextCompactor interface {
// Compact reduces the turn results slice while preserving essential context.
Compact(ctx context.Context, turnResults []TurnResult) ([]TurnResult, error)
}
ContextCompactor compresses turn history to keep the context window bounded.
type DefaultContextCompactor ¶
type DefaultContextCompactor struct {
// contains filtered or unexported fields
}
DefaultContextCompactor implements truncation-based compaction. It retains the first turn (for initial context) and the last N-1 turns (for recency), dropping intermediate turns when the total exceeds maxRetainedTurns.
func NewDefaultContextCompactor ¶
func NewDefaultContextCompactor(maxRetained int) *DefaultContextCompactor
NewDefaultContextCompactor creates a compactor that retains at most maxRetained turns.
func (*DefaultContextCompactor) Compact ¶
func (c *DefaultContextCompactor) Compact(ctx context.Context, turnResults []TurnResult) ([]TurnResult, error)
Compact implements ContextCompactor.
type DefaultInnerLoop ¶
type DefaultInnerLoop struct {
// contains filtered or unexported fields
}
DefaultInnerLoop implements the reasoning turn loop.
func NewDefaultInnerLoop ¶
func NewDefaultInnerLoop( config InnerLoopConfig, plannerExec planner.ExecutionPlanner, toolRunner toolrunner.ToolRunner, compactor ContextCompactor, logger execution.ExecutionLogger, ) *DefaultInnerLoop
NewDefaultInnerLoop creates a new DefaultInnerLoop.
func (*DefaultInnerLoop) Run ¶
func (l *DefaultInnerLoop) Run(ctx context.Context, task TaskInput, ec *execution.ExecutionContext) (*TaskResult, error)
Run executes the iterative reasoning loop until a stop condition is met.
type DefaultOuterLoop ¶
type DefaultOuterLoop struct {
// contains filtered or unexported fields
}
DefaultOuterLoop implements the workflow/task orchestration loop.
func NewDefaultOuterLoop ¶
func NewDefaultOuterLoop( config OuterLoopConfig, innerLoop InnerLoop, checkpoint Checkpoint, policy PolicyCheckpoint, logger execution.ExecutionLogger, ) *DefaultOuterLoop
NewDefaultOuterLoop creates a new DefaultOuterLoop.
func (*DefaultOuterLoop) Run ¶
func (l *DefaultOuterLoop) Run(ctx context.Context, tasks []TaskInput, ec *execution.ExecutionContext) (*WorkflowResult, error)
Run executes the task sequence via the outer loop state machine.
type InnerLoop ¶
type InnerLoop interface {
Run(ctx context.Context, task TaskInput, ec *execution.ExecutionContext) (*TaskResult, error)
}
InnerLoop executes a single task through iterative reasoning turns.
type InnerLoopConfig ¶
InnerLoopConfig holds bounds for the inner reasoning turn loop.
func DefaultInnerConfig ¶
func DefaultInnerConfig() InnerLoopConfig
DefaultInnerConfig returns the standard inner loop configuration.
type InnerState ¶
type InnerState string
InnerState represents a state in the inner reasoning turn loop.
const ( InnerTurnInit InnerState = "turn_init" InnerPlan InnerState = "plan" InnerAct InnerState = "act" InnerObserve InnerState = "observe" InnerCheckStop InnerState = "check_stop" InnerNextTurn InnerState = "next_turn" InnerDone InnerState = "done" )
type InnerStopEvaluator ¶
type InnerStopEvaluator struct {
// contains filtered or unexported fields
}
InnerStopEvaluator evaluates stop conditions for the inner reasoning turn loop.
func NewInnerStopEvaluator ¶
func NewInnerStopEvaluator(config InnerLoopConfig) *InnerStopEvaluator
NewInnerStopEvaluator creates a new evaluator with the given configuration.
func (*InnerStopEvaluator) Evaluate ¶
func (e *InnerStopEvaluator) Evaluate(turnsElapsed int, toolCallsUsed int, startTime time.Time, plannerStopped bool, ctx context.Context) StopCondition
Evaluate checks all inner loop stop conditions in priority order: 1. Context cancellation (highest priority — external signal) 2. Planner stopped (cooperative stop from LLM) 3. Max runtime exceeded 4. Max turns reached 5. Max tool calls reached
type LoopMetrics ¶
type LoopMetrics struct {
WorkflowSteps int
TotalTurns int
TotalToolCalls int
TotalRuntime time.Duration
}
LoopMetrics tracks aggregate counters across the entire dual-loop execution.
type NoOpCheckpoint ¶
type NoOpCheckpoint struct{}
NoOpCheckpoint is a Checkpoint that does nothing. Suitable for testing.
func (*NoOpCheckpoint) Save ¶
func (c *NoOpCheckpoint) Save(_ context.Context, _ int, _ *TaskResult, _ *LoopMetrics) error
Save implements Checkpoint as a no-op.
type NoOpCompactor ¶
type NoOpCompactor struct{}
NoOpCompactor retains all turn results without compaction. Suitable for testing or workloads with few turns.
func (*NoOpCompactor) Compact ¶
func (c *NoOpCompactor) Compact(_ context.Context, turnResults []TurnResult) ([]TurnResult, error)
Compact implements ContextCompactor by returning a copy of the input unchanged.
type NoOpPolicyCheckpoint ¶
type NoOpPolicyCheckpoint struct{}
NoOpPolicyCheckpoint is a PolicyCheckpoint that always allows continuation.
func (*NoOpPolicyCheckpoint) Check ¶
func (c *NoOpPolicyCheckpoint) Check(_ context.Context, _ int, _ *LoopMetrics) error
Check implements PolicyCheckpoint as a no-op.
type OuterLoop ¶
type OuterLoop interface {
Run(ctx context.Context, tasks []TaskInput, ec *execution.ExecutionContext) (*WorkflowResult, error)
}
OuterLoop orchestrates tasks using the Dual-Loop architecture.
type OuterLoopConfig ¶
OuterLoopConfig holds bounds for the outer task/workflow loop.
func DefaultOuterConfig ¶
func DefaultOuterConfig() OuterLoopConfig
DefaultOuterConfig returns the standard outer loop configuration.
type OuterState ¶
type OuterState string
OuterState represents a state in the outer task/workflow loop.
const ( OuterInit OuterState = "init" OuterTaskSelect OuterState = "task_select" OuterTaskExecute OuterState = "task_execute" OuterCheckpoint OuterState = "checkpoint" OuterNextTask OuterState = "next_task" OuterDone OuterState = "done" )
type OuterStopEvaluator ¶
type OuterStopEvaluator struct {
// contains filtered or unexported fields
}
OuterStopEvaluator evaluates stop conditions for the outer task/workflow loop.
func NewOuterStopEvaluator ¶
func NewOuterStopEvaluator(config OuterLoopConfig) *OuterStopEvaluator
NewOuterStopEvaluator creates a new evaluator with the given configuration.
func (*OuterStopEvaluator) Evaluate ¶
func (e *OuterStopEvaluator) Evaluate(stepsElapsed int, startTime time.Time, ctx context.Context) StopCondition
Evaluate checks all outer loop stop conditions in priority order: 1. Context cancellation (highest priority — external signal) 2. Max session runtime exceeded 3. Max workflow steps reached
type PolicyCheckpoint ¶
type PolicyCheckpoint interface {
Check(ctx context.Context, taskIndex int, metrics *LoopMetrics) error
}
PolicyCheckpoint enforces governance gates between task executions in the outer loop.
type StopCondition ¶
type StopCondition struct {
Stopped bool
Reason StopReason
Detail string
}
StopCondition represents the result of evaluating whether a loop should stop.
type StopReason ¶
type StopReason string
StopReason identifies why a loop stopped.
const ( StopReasonMaxTurns StopReason = "max_turns" StopReasonMaxToolCalls StopReason = "max_tool_calls" StopReasonMaxRuntime StopReason = "max_runtime" StopReasonMaxWorkflowSteps StopReason = "max_workflow_steps" StopReasonMaxSessionRuntime StopReason = "max_session_runtime" StopReasonGoalAchieved StopReason = "goal_achieved" StopReasonPlannerStopped StopReason = "planner_stopped" StopReasonContextCanceled StopReason = "context_canceled" StopReasonError StopReason = "error" )
type TaskInput ¶
type TaskInput struct {
TaskDescription string
PlannerContext *planner.PlannerContext
}
TaskInput provides the input for a single task in the outer loop.
type TaskResult ¶
type TaskResult struct {
TurnCount int
ToolCallsUsed int
FinalOutput any
Error error
StopReason StopReason
Duration time.Duration
TurnResults []TurnResult
}
TaskResult captures the outcome of executing a single task via the inner loop.
type TurnResult ¶
type TurnResult struct {
TurnNumber int
PlanText string
ActionsExecuted []string
Observations []string
StopReason StopReason
ToolCallsUsed int
Duration time.Duration
}
TurnResult captures the outcome of a single reasoning turn in the inner loop.
type WorkflowResult ¶
type WorkflowResult struct {
TaskResults []*TaskResult
Metrics LoopMetrics
StopCondition StopCondition
}
WorkflowResult captures the outcome of the entire outer loop execution.