/** * Server-suggested retry delay extraction. Merges the patterns historically used * by the OpenAI code provider and Google Gemini retry helpers. * * Header sources (checked in order): * - `Retry-After` (numeric seconds, or HTTP date) * - `x-ratelimit-reset` (Unix epoch seconds) * - `x-ratelimit-reset-after` (seconds) * * Body patterns: * - `Your quota will reset after 18h31m10s` / `10m15s` / `39s` * - `Please retry in 250ms` / `Please retry in 12s` * - `"retryDelay": "34.074824224s"` (JSON error detail field) * - `try again in 250ms` / `try again in 12s` / `try again in 12sec` * * Returns `undefined` if no signal is found. */ export declare function extractRetryHint(source: Response | Headers | null | undefined, body?: string): number | undefined; export interface FetchWithRetryOptions extends RequestInit { /** Total fetch attempts (initial + retries). Default `5`. */ maxAttempts?: number; /** * Per-delay cap. Server-provided `Retry-After` hints exceeding this return * the current response immediately — caller deals with the `!response.ok`. * Scheduled values are also capped at the platform timer ceiling. Default * `60_000`. */ maxDelayMs?: number; /** * Fallback delay schedule when no server hint is present. Number, array * (indexed by attempt, clamped to last), or function. Default exponential * `500ms * 2 ** attempt` capped at `maxDelayMs` and the platform timer * ceiling. Values that remain negative or non-finite after capping retry * immediately. */ defaultDelayMs?: number | readonly number[] | ((attempt: number) => number); /** * Optional per-attempt overlay merged into the base `RequestInit` each try. * Headers from the overlay shallow-merge over the base. Useful for auth * token refresh or user-agent rotation. */ prepareInit?: (attempt: number) => RequestInit | Promise; /** * Optional `fetch` implementation override. Defaults to `globalThis.fetch`. * Useful for routing requests through a proxy, instrumented transport, or * mock during tests. */ fetch?: (input: string | URL | Request, init?: RequestInit) => Promise; } /** * Fetch with bounded retries and sensible defaults. Retries on any * `isRetryableStatus` (5xx, 408, 429) and on transient network errors. Server * `Retry-After`/quota hints are honoured up to `maxDelayMs`; a hint that exceeds * the cap returns the current response so the caller can fail fast. Aborts on * `init.signal` propagate as `"Request was aborted"`. * * The caller is responsible for inspecting `!response.ok` once the call returns. */ export declare function fetchWithRetry(url: string | URL | ((attempt: number) => string | URL), options?: FetchWithRetryOptions): Promise; /** * Inspect an arbitrary error value (or its `cause` chain, up to depth 2) for an * HTTP status code. Reads `status`, `statusCode`, and `response.status` fields, * coerces string values, and falls back to scanning the error message for * common patterns like `Error: 401`, `error (429)`, or `HTTP 503`. */ export declare function extractHttpStatusFromError(error: unknown): number | undefined; /** * `true` if the given HTTP status code is one we treat as transient: 408 * (Request Timeout), 429 (Too Many Requests), or any 5xx (server error). */ export declare function isRetryableStatus(status: number): boolean; /** * `true` if the message describes an unexpected socket closure — Bun and some * proxies surface these for any HTTP/2 stream reset. */ export declare function isUnexpectedSocketCloseMessage(message: string): boolean; /** * Identify errors that should be retried: aborts/timeouts in the error name or * message, retryable HTTP statuses (see `isRetryableStatus`), unexpected socket * closes, and the standard transient phrases. 4xx statuses other than 408/429 * and validation-shaped messages short-circuit to `false`. */ export declare function isRetryableError(error: unknown): boolean;