Files
oh-my-opencode/src/hooks/runtime-fallback/AGENTS.md
T
YeonGyu-Kim 9f6d0d2281 docs(agents-md): refresh hierarchical knowledge base for v4.1.2
- Bump root AGENTS.md header: 2026-05-14 → 2026-05-15, commit 5ffbe0e2453a740636, release v4.1.1 → v4.1.2
- Update file counts: 2034 (1337+697) → 2041 (1340+701), LOC ~292k → ~294k
- Fix STRUCTURE: openclaw lives at src/openclaw/ (not src/features/); list more accurate feature modules in the parenthetical
- Clarify interactive_bash gate: tmux binary on PATH via isInteractiveBashEnabled() (not 'tmux enabled')
- Fix docs/reference/features.md hook counts: Tool Guard 14→16, Total base 52→54, total with team-mode 59→61
- Bump 'Generated' date on all 43 subdir AGENTS.md files to 2026-05-15
- Preserve promptAsync injection cautions verbatim (per request)
2026-05-15 13:48:11 +09:00

4.4 KiB

src/hooks/runtime-fallback/ — Reactive Provider Error Recovery

Generated: 2026-05-15

OVERVIEW

32 files. Session Tier hook that reactively switches to fallback models when API providers return errors at runtime (429, 503, quota exhausted, cooldown signals). Distinct from model-fallback (which applies preemptively at chat.params).

RUNTIME-FALLBACK vs MODEL-FALLBACK

Aspect runtime-fallback model-fallback
Trigger Reactive — after error occurs Proactive — at request time
Event session.error, message.updated, session.status chat.params
Config source categories[].fallback_models, agents[].fallback_models AGENT_MODEL_REQUIREMENTS hardcoded chains
State Per-session FallbackState + cooldown tracking Module-global pendingModelFallbacks
Use case Provider errors during execution Pre-configured agent fallback chains

They operate independently — no direct integration.

ERROR DETECTION

HTTP Status Codes (configurable)

Default retry codes: 429, 500, 502, 503, 504

Error Message Patterns (constants.ts)

/rate.?limit/i, /too.?many.?requests/i, /quota.*reset.*after/i,
/exhausted.*capacity/i, /all.*credentials.*for.*model/i,
/cool(?:ing)?.?down/i, /model.*not.*supported/i,
/service.?unavailable/i, /overloaded/i, /temporarily.?unavailable/i

Error Type Classification (error-classifier.ts)

  • missing_api_key — provider rejects auth
  • model_not_found — model unavailable
  • quota_exceeded — billing/quota hit
  • Auto-retry signal detection via auto-retry-signal.ts — extracts "retrying in ~2 weeks" style signals, triggers immediate fallback

FALLBACK STATE MACHINE

interface FallbackState {
  originalModel: string
  currentModel: string
  fallbackIndex: number
  failedModels: Map<string, number>  // model → cooldown-until timestamp
  attemptCount: number
  pendingFallbackModel?: string
}

FALLBACK CHAIN RESOLUTION (fallback-models.ts)

Priority order:

  1. Session category (via SessionCategoryRegistry)
  2. Agent config fallback_models
  3. Agent's category fallback_models
  4. Session ID pattern match (detect agent from session ID format)

RETRY FLOW

session.error / message.updated (with error) / session.status (retry signal)
  → isRetryableError(error)?
  → getFallbackModelsForSession(sessionID, agent)
  → findNextAvailableFallback() — skip cooldown models
  → prepareFallback() — update state, mark current failed
  → dispatchFallbackRetry() — toast notification + promptAsync with new model
  → 30s timeout — abort and try next if exceeded

COOLDOWN MECHANISM

Failed models enter 60s cooldown. findNextAvailableFallback() skips models in cooldown, preventing thrashing on persistently failing models.

KEY FILES

File Purpose
hook.ts createRuntimeFallbackHook() — composes all handlers
event-handler.ts Route session lifecycle (created, error, stop, idle)
message-update-handler.ts Handle error parts in message.updated
session-status-handler.ts Handle provider retry signals in session.status
chat-message-handler.ts Apply fallback model override on chat.message
error-classifier.ts isRetryableError(), classifyErrorType()
auto-retry-signal.ts Extract "retrying in..." signals
fallback-state.ts State machine: createFallbackState, prepareFallback, findNextAvailableFallback, isModelInCooldown
fallback-models.ts Resolve chain from config hierarchy (strings + raw objects)
fallback-bootstrap-model.ts Derive initial model when state missing
fallback-retry-dispatcher.ts Toast + dispatch retry orchestration
auto-retry.ts Abort, timeout scheduling, cleanup
agent-resolver.ts Session → agent name normalization
retry-model-payload.ts Build model payload (providerID/modelID/variant/reasoningEffort)
visible-assistant-response.ts Detect if assistant produced real output vs just errors
last-user-retry-parts.ts Extract last user message parts for retry

NOTES

  • Cooldown and failure tracking are per-session — concurrent sessions don't share state
  • visible-assistant-response.ts prevents retry if the assistant already produced a partial valid response
  • Runtime-fallback is registered in the Session Tier via create-session-hooks.ts