export interface BackoffOptions { /** Base delay in ms (default: 200) */ baseDelayMs?: number; /** Max delay in ms (default: 10_000) */ maxDelayMs?: number; } export type BackoffJitterMode = "full" | "none"; export interface ExponentialBackoffOptions extends BackoffOptions { /** Jitter strategy (default: full) */ jitter?: BackoffJitterMode; /** Random generator in [0, 1) (default: Math.random) */ rng?: () => number; } export declare function computeExponentialBackoffDelayMs(attempt: number, opts?: ExponentialBackoffOptions): number; export interface CircuitBreakerOptions { /** Open circuit after this many consecutive retryable failures (default: 3) */ failureThreshold?: number; /** How long the circuit stays open before allowing a single trial (default: 10_000) */ cooldownMs?: number; } type CircuitState = "closed" | "open" | "half_open"; export declare class CircuitBreakerOpenError extends Error { readonly provider: string; readonly waitMs: number; constructor(provider: string, waitMs: number); } export declare class CircuitBreaker { private state; private consecutiveFailures; private openUntil; private halfOpenInFlight; private failureThreshold; private cooldownMs; constructor(opts?: CircuitBreakerOptions); snapshot(now: number): { state: CircuitState; consecutiveFailures: number; openForMs: number; }; /** * Gate a request. If open, returns not allowed with waitMs. * If half-open, only allows a single in-flight probe. */ enter(now: number): { allowed: boolean; waitMs?: number; }; onSuccess(): void; onFailure(now: number): void; } export interface RetryBudgetOptions { /** Max retries per provider per interval (default: 20) */ maxRetries?: number; /** Interval for budget reset (default: 60_000) */ intervalMs?: number; } export declare class RetryBudgetExceededError extends Error { readonly provider: string; constructor(provider: string); } export declare class RetryBudget { private maxRetries; private intervalMs; private state; constructor(opts?: RetryBudgetOptions); trySpend(provider: string, cost?: number): boolean; } export interface RetryDecision { retryable: boolean; /** HTTP status code when available */ status?: number; /** Retry-After when available */ retryAfterMs?: number; } export declare function parseRetryAfterMs(value: string, now: number): number | undefined; export declare function classifyRetryableError(err: unknown, now?: number): RetryDecision; export interface AdaptiveRetryOptions { /** Max total attempts including the first attempt (default: 4) */ maxAttempts?: number; /** Backoff options (default: base 200, max 10_000) */ backoff?: ExponentialBackoffOptions; /** Cap any retry-after delays to this max (default: 30_000) */ maxRetryAfterMs?: number; /** Treat this classifier result as authoritative (default: classifyRetryableError) */ classify?: (err: unknown, now: number) => RetryDecision; /** Sleep function used for delays (default: setTimeout) */ sleep?: (ms: number) => Promise; /** Time source (default: Date.now) */ now?: () => number; } export declare function adaptiveRetry(provider: string, fn: () => Promise, breaker: CircuitBreaker, budget: RetryBudget, opts?: AdaptiveRetryOptions): Promise; export interface ProviderResilienceOptions { breaker?: CircuitBreakerOptions; retryBudget?: RetryBudgetOptions; retry?: AdaptiveRetryOptions; } export declare class ProviderResilience { private breakers; private budgets; private opts; constructor(opts?: ProviderResilienceOptions); private getBreaker; private getBudget; run(provider: string, fn: () => Promise, retryOverrides?: AdaptiveRetryOptions): Promise; snapshot(provider: string, now?: number): { breaker: ReturnType; }; } export {};