/** * Rate-limit header parser + optional client-side token bucket. * * - `parseRateLimitHeaders(headers)` reads OpenAI-style and IETF-draft * `x-ratelimit-*` headers; returns null when none recognized. * - `withRateLimit(misina, opts)` adds an in-process limiter that gates * each request before dispatch, learns the real budget from response * headers, and backs off on 429. */ import type { MisinaPlugin } from "../types.mjs"; export interface RateLimitBucket { limit: number | undefined; remaining: number | undefined; resetAt: Date | undefined; } export interface RateLimitInfo { requests: RateLimitBucket | undefined; tokens: RateLimitBucket | undefined; } export declare function parseRateLimitHeaders(headers: Headers): RateLimitInfo | null; export interface RateLimitOptions { /** Initial requests-per-minute budget. Default: Infinity (unlimited). */ rpm?: number; /** Initial tokens-per-minute budget. Default: Infinity (unlimited). */ tpm?: number; /** * Estimate token cost for a request before dispatch. Used to acquire * tokens from the TPM bucket. Return 0 to skip the TPM gate for a * request. Default: () => 0 (no TPM accounting). */ estimateTokens?: (request: Request) => number; /** * Override the source of "now" — useful in tests with fake timers. * Default: `() => Date.now()`. */ now?: () => number; } /** * Token-bucket rate limiter wired into a `Misina` instance via hooks. * Two buckets — requests-per-minute and tokens-per-minute — refill * linearly. `beforeRequest` waits until both buckets cover the cost. * `onComplete` reads `x-ratelimit-remaining-*` and adjusts the bucket * to the real budget the server reports. 429 responses drain both * buckets aggressively so subsequent calls back off. */ export declare function rateLimit(options?: RateLimitOptions): MisinaPlugin;