Circuit Breaker And Resilience

Last updated: April 25, 2026

Assistant: Circuit Breaker & Resilience

The circuit breaker pattern was extended across all adaptive planner LLM call sites in April 2026, providing graceful degradation when LLM providers experience failures, timeouts, or rate limits.

Motivation

The adaptive planner makes many sequential LLM calls (task decomposition, replanning, result evaluation). A single provider outage could cascade through the entire planning pipeline, wasting tokens on doomed requests and producing incoherent partial plans. The circuit breaker prevents this by:

  1. Fast-failing after consecutive errors (no waiting on a dead provider)
  2. Falling back to alternative models/providers automatically
  3. Self-healing by transitioning from open → half-open → closed after a cooldown

Circuit Breaker States

stateDiagram-v2
    [*] --> Closed
    Closed --> Open : N consecutive failures
    Open --> HalfOpen : cooldown elapsed
    HalfOpen --> Closed : success
    HalfOpen --> Open : failure
State Behavior
Closed Normal operation — all LLM requests proceed
Open All requests immediately fail — no LLM calls attempted
Half-Open One probe request allowed; if it succeeds → Closed, if it fails → Open

Configuration

Parameter Default Description
FailureThreshold 3 Consecutive failures before opening
CooldownDuration 60s Time in Open state before transitioning to Half-Open
HalfOpenMaxProbes 1 Requests allowed in Half-Open state

Integration Points

Adaptive Planner

The circuit breaker wraps every LLM call in the adaptive planner:

  • decomposeTask() — Task breakdown calls
  • evaluateResult() — Result evaluation calls
  • replanIfNeeded() — Replanning calls

When a call hits an open circuit breaker, the planner falls back to:

  1. Alternative provider — If the primary model has a fallback configured (e.g., openrouter/z-ai/glm-4.5-air:free as fallback for llama/qwen3:30b)
  2. Reduced model — A cheaper/faster model that may produce less optimal but functional output
  3. Cached result — If the same query type was recently successful, reuse that approach

Session Counter Reset

On a new user message, session error counters are reset with a 2-second delay before LLM retries. This gives transient issues time to resolve without carrying over stale failure state:

// Reset on new user message
session.ErrorCount = 0
time.AfterFunc(2*time.Second, func() {
    // Allow retries after brief cooldown
})

Error Classification

The circuit breaker distinguishes between error types to avoid opening on non-provider issues:

Error Type Counts as Failure Example
Provider timeout Yes 5-minute HTTP timeout
Rate limit (429) Yes OpenRouter rate limit
Auth failure (401/403) Yes Invalid API key
Context length exceeded No Prompt too long (fix the prompt)
Invalid request (400) No Malformed request (fix the code)
Network DNS failure Yes Provider endpoint unreachable

Monitoring

Circuit breaker state changes are logged with the [CIRCUIT] prefix:

[CIRCUIT] Open: provider=openrouter model=glm-4.5-air failures=3 last_error="429 rate limit"
[CIRCUIT] HalfOpen: provider=openrouter model=glm-4.5-air cooldown=60s
[CIRCUIT] Closed: provider=openrouter model=glm-4.5-air probe_success=true

Mission Control displays circuit breaker status in the agent health panel.

Key Files

File Purpose
assistant/adaptive_planner.go Circuit breaker integration at all LLM call sites
assistant/circuit_breaker.go Circuit breaker implementation (states, transitions, cooldown)
assistant/assutils.go Fallback model configuration, session counter reset

Cross-References