import type { BaseProvider } from '../providers/base.js'; import type { RetryConfig } from '../types/config.js'; import type { ProviderCallContext } from '../types/lifecycle.js'; import type { CompletionRequest } from '../types/messages.js'; import type { NexusResponse, NexusStream } from '../types/response.js'; import type { RouteDecision } from './types.js'; export interface ExecutionOptions { timeoutMs?: number; retry?: RetryConfig; onAttemptSuccess?: (providerName: string, latencyMs: number) => void; onAttemptFailure?: (providerName: string, error: unknown) => void; /** * Asked before every attempt, retries included. Returning false skips the provider and moves to * the next fallback — how an open circuit, or a half-open one whose probe slots are taken, keeps * a request away from a provider the router chose before the circuit changed. */ allowAttempt?: (providerName: string) => boolean; /** * What every attempt hands its provider besides the request: the operation's id, its trace * headers, and its idempotency key. Each attempt adds its own signal and deadline. */ callContext?: Omit; /** * Resolves a provider's credential again after the provider refused it. Resolving to true makes * the attempt once more, without counting it as a retry: how a rotated key reaches a call already * under way. */ refreshCredential?: (providerName: string) => Promise; /** Removes resolved credentials from an attempt's error before anything records it. */ scrub?: (error: E) => E; } /** * Runs a routing decision: the primary provider, then each fallback, honouring per-attempt * timeouts, rate limits, and circuits. */ export declare class FailoverExecutor { /** * Completes through the first attempt that succeeds. Throws with every attempt's error when none * does. */ complete(request: CompletionRequest, decision: RouteDecision, providers: Map, options?: ExecutionOptions): Promise; /** Streams through the first attempt that starts successfully. */ stream(request: CompletionRequest, decision: RouteDecision, providers: Map, options?: ExecutionOptions): NexusStream; private streamAttempts; /** * Whether an attempt is worth making once more because the provider refused its credential and a * fresh one was resolved: once per provider per operation, and only with a resolver. */ private refreshAfterRefusal; private waitForCompletion; private waitForAttempt; private createAttemptContext; private stopProviderStream; private abortProviderStream; private waitForSettlement; private createUnsettledAttemptError; private resolveTimeout; private mergeRetry; private shouldRetry; private categorizeError; private retryDelay; private delay; private throwIfAborted; private createLinkedAbortController; }