loop

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 15, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

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

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

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

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

type InnerLoopConfig struct {
	MaxTurns       int
	MaxToolCalls   int
	MaxTurnRuntime time.Duration
}

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

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

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

type OuterLoopConfig struct {
	MaxWorkflowSteps  int
	MaxSessionRuntime time.Duration
}

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.

Jump to

Keyboard shortcuts

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