/** * API key rotation for voice / media-understanding providers. * * Ported from openclaw/src/agents/api-key-rotation.ts (commit baseline 2026-05-08). * * DECISION (per docs/voice-rearchitecture.md §7): * - Scope is voice / media-understanding only; LLM rotation is out of scope (see §7.5). * - Retry decision is delegated to caller via shouldRetry callback. Default policy: * rotate on 401 / 403 / 429 / "rate limit" / "quota" / "invalid api key" textual signals. * - Network errors and 5xx are NOT rotated (treated as transient infra issues; let * the outer fallback chain switch to a different provider instead of burning keys). * - Keys are deduplicated and trimmed before iteration; empty strings are dropped. */ export interface ApiKeyRetryParams { apiKey: string; error: unknown; attempt: number; message: string; } export interface ExecuteWithApiKeyRotationOptions { /** Provider id (used only for error messages and logs). */ provider: string; /** All candidate keys; primary first. Caller usually obtains via collectProviderApiKeys. */ apiKeys: string[]; /** Per-key execution. Returned value is propagated when any key succeeds. */ execute: (apiKey: string) => Promise; /** Decide whether to rotate to the next key. Defaults to isRotatableAuthFailure. */ shouldRetry?: (params: ApiKeyRetryParams) => boolean; /** Optional observation hook fired before rotating to the next key. */ onRetry?: (params: ApiKeyRetryParams) => void; } /** * Default retry classifier: rotate on auth / quota signals (401/403/429 + textual hints). * Network errors and 5xx are intentionally NOT rotated (see file-level DECISION). */ export declare function isRotatableAuthFailure(message: string): boolean; /** * Run `execute(apiKey)` with each candidate key in turn until one succeeds or all * keys are exhausted. The last error is rethrown when no key succeeds. * * Throws synchronously when no usable keys are configured (caller should detect * this via NotConfiguredError semantics in the upstream provider plugin). */ export declare function executeWithApiKeyRotation(options: ExecuteWithApiKeyRotationOptions): Promise; /** * Collect candidate keys for a provider from a primary slot + an optional list of * extras (typically read from config under e.g. `apiKeys: string[]`). * * Empty / duplicate values are dropped. The primary key (when set) always comes * first so that single-key callers see no behavioral change. */ export declare function collectProviderApiKeysForExecution(input: { primaryApiKey?: string | null; extraApiKeys?: readonly string[]; }): string[];