Loop Engine
The LoopEngine class is the iteration executor that drives autonomous task completion with progress streaming and safety integration.
Interface
interface LoopEngine {
execute(task: LoopTask): Promise<LoopResult>
streamProgress(callback: (event: ProgressEvent) => void): void
getStatus(): LoopStatus
abort(): void
}
interface LoopTask {
id: string
description: string
maxIterations: number
exitStrategy: ExitStrategy
context: string
}
interface LoopResult {
status: 'completed' | 'failed' | 'circuit_open' | 'max_iterations' | 'aborted'
iterations: number
workSummary: string
confidence: number
exitReason: string
circuitBreakerState: string
}
interface LoopStatus {
currentIteration: number
maxIterations: number
circuitBreakerState: string
lastAnalysis: AnalysisResult | null
running: boolean
}
interface ProgressEvent {
type: 'iteration_start' | 'iteration_end' | 'analysis' | 'circuit_update' | 'exit'
iteration: number
data: Record<string, unknown>
timestamp: Date
}Execution Flow
execute(task)
├── initialize circuit breaker
├── initialize response analyzer
│
└── for iteration = 1 to maxIterations:
├── emit 'iteration_start'
├── run iteration (adapter call)
├── emit 'iteration_end'
├── analyze response
├── emit 'analysis'
├── check circuit breaker
│ ├── record progress/error
│ └── emit 'circuit_update'
├── evaluate exit strategy
│ └── if shouldExit → emit 'exit' → return
└── continue
└── maxIterations reached → return 'max_iterations'Progress Streaming
The engine streams progress events in real-time, enabling the TUI and external clients to observe loop execution:
engine.streamProgress((event) => {
switch (event.type) {
case 'iteration_start':
console.log(`Iteration ${event.iteration}/${task.maxIterations}`)
break
case 'circuit_update':
console.log(`Circuit: ${event.data.state}`)
break
case 'exit':
console.log(`Exit: ${event.data.reason}`)
break
}
})Progress events are the primary integration point between the loop engine and the TUI surfaces. The loop-status TUI component consumes these events to render real-time progress.
Integration
Circuit Breaker
Each iteration records metrics and errors to the circuit breaker. The engine checks the circuit breaker state before continuing:
const decision = circuitBreaker.check()
if (!decision.allowContinue) {
return {
status: 'circuit_open',
iterations: currentIteration,
exitReason: decision.reason,
circuitBreakerState: decision.state
}
}Response Analyzer
Each iteration response is analyzed for completion signals, stuck patterns, and confidence:
const analysis = analyzer.analyze(response, {
iteration: currentIteration,
maxIterations: task.maxIterations,
previousResponses,
errorHistory,
taskDescription: task.description
})
if (exitStrategy.shouldExit(analysis)) {
return buildResult(analysis)
}Exit Strategy
The engine delegates exit decisions to the configured exit strategy. See Exit Strategies for details on the four available strategies.
Max Iteration Handling
When maxIterations is reached without an exit signal, the engine returns status: 'max_iterations'. This is treated as a failure by default but can be configured:
if (currentIteration >= task.maxIterations) {
return {
status: 'max_iterations',
iterations: currentIteration,
exitReason: `Reached maximum iterations (${task.maxIterations})`,
circuitBreakerState: circuitBreaker.state
}
}