/** * withFallback — provider decorator that falls back to a secondary * on error. * * Pattern: Decorator (GoF) — composes two `LLMProvider`s into one. * Role: Outer ring (Hexagonal). Stacks with `withRetry`: * `withRetry(withFallback(primary, fallback))` first retries * the primary, then on exhaustion falls back to the secondary. * * Common pairings: * • Anthropic primary, OpenAI fallback (vendor outage tolerance) * • Real provider primary, Mock fallback (degrade gracefully in dev) * • Premium model primary, cheaper model fallback (cost ceiling) * * `stream()` falls back too — if the primary's stream errors before * yielding any chunks, we restart on the fallback. Once the primary * has yielded chunks the stream is committed — fallback would * duplicate the partial output. * * **Status: contract-shaped and tested — independently reproduced against a * local harness, 2026-08-13.** Somebody who is not this library's author called * a failed primary once and a healthy fallback once, with * `agentfootprint.fallback.triggered` on the typed stream; a stream that failed * BEFORE its first chunk moved to the fallback, and one that failed AFTER a * chunk did not — the stream-pinning law, measured rather than asserted, and * the reason no output was duplicated. Both providers were SCRIPTED doubles and * the run was deterministic and local (the trial's own words: it *"consumed no * GCP credit"*). **No failover between two live providers has been exercised * from this repository**, so this is not the field-validated rung. */ import type { LLMProvider } from '../adapters/types.js'; export interface WithFallbackOptions { /** * Predicate to decide whether an error from the primary should * trigger fallback. Default: every error except AbortError. * Override to gate on specific status codes or error types. */ readonly shouldFallback?: (error: unknown) => boolean; /** * Hook invoked when the primary fails and we're about to call the * fallback. Useful for logging in standalone (non-agentfootprint) use. * * You do NOT need this to get fallback telemetry inside a run: since * v7.8 the in-run LLM call sites hand this decorator an `LLMCallHooks` * and translate its reports into `agentfootprint.fallback.triggered` * events, stamped with the real `runId`/`runtimeStageId`. This hook is * the consumer-owned escape hatch and its contract is unchanged. */ readonly onFallback?: (error: unknown) => void; } /** * Wrap a primary provider with a fallback. Tries primary first; on * error matching the policy, calls the fallback. * * @example * const provider = withFallback( * anthropic({ apiKey: A }), * openai({ apiKey: O }), * { onFallback: (err) => console.warn('primary failed, falling back:', err) }, * ); */ export declare function withFallback(primary: LLMProvider, fallback: LLMProvider, options?: WithFallbackOptions): LLMProvider; //# sourceMappingURL=withFallback.d.ts.map