import type { Message, Tool } from 'ollama';
import type { ChatResult, IChatClient, StreamChunk } from './chatClient';
export interface FallbackChatClientEntry {
    backend: string;
    client: IChatClient;
    supportsTools: boolean;
}
export interface RemoteProviderFallbackEvent {
    type: 'provider_fallback';
    fromBackend: string;
    toBackend: string;
    reason: string;
    cooldownSec: number;
}
export declare function drainRemoteProviderFallbackEvents(): RemoteProviderFallbackEvent[];
/** Cooldown window in ms. A backend that just hit a limit is skipped for
 * this long before being retried. Env override: HARNESS_REMOTE_FALLBACK_COOLDOWN_MS.
 */
export declare const FALLBACK_COOLDOWN_MS: number;
/**
 * Cycles across configured remote providers only for quota/rate/request-size
 * failures. Provider-specific clients still handle their own key pools first.
 *
 * After a backend hits a limit error it enters a cooldown window and is
 * temporarily skipped on subsequent calls, similar to LiteLLM's per-deployment
 * cooldown model. The primary backend (index 0) is always attempted.
 *
 * Request timestamps are tracked per backend so `availableEntries` can prefer
 * the least-recently-used provider when multiple are available.
 */
export declare class FallbackChatClient implements IChatClient {
    private readonly entries;
    private readonly cooldowns;
    private readonly requestLog;
    constructor(entries: FallbackChatClientEntry[]);
    chat(messages: Message[], tools?: Tool[], abortSignal?: AbortSignal): Promise<ChatResult>;
    chatOnce(messages: Message[], tools?: Tool[]): Promise<ChatResult>;
    chatStream(messages: Message[], tools?: Tool[], abortSignal?: AbortSignal): AsyncGenerator<StreamChunk>;
    listModels(): Promise<string[]>;
    getContextWindow(): Promise<number | null>;
    healthCheck(): Promise<{
        ok: boolean;
        error?: string;
    }>;
    getModel(): string;
    private tryClients;
    private availableEntries;
    /** Record a request timestamp for a backend. Keeps only the last 60s. */
    private recordRequest;
    /** Count requests in the last 60s for a backend. */
    private recentRequestCount;
    /** Sort candidates by least-recently-used (fewest requests in the last 60s),
     *  keeping the primary (index-0) at the front when it's not cooled down. */
    private sortByLeastLoaded;
    private warnFallback;
}
/**
 * Detect errors that warrant trying a different remote provider.
 *
 * HTTP 429 (rate limit), quota exhaustion, and HTTP 413 (request too
 * large) are good candidates because another provider may have higher
 * limits.  A 413 from a free-tier backend (e.g. Groq 6 K TPM) doesn't
 * mean the payload is universally too big — paid / higher-tier backends
 * routinely accept 50 K+ tokens.
 */
export declare function isRemoteLimitError(error: unknown): boolean;
//# sourceMappingURL=fallbackChatClient.d.ts.map