/**
 * Shared retry helper for LLMClient adapters.
 *
 * Bounded exponential backoff with optional `Retry-After` honoring and
 * symmetric jitter. Treats 429 / 5xx as retryable and any other HTTP error
 * as terminal.
 *
 * Errors carry the full response body on the instance for callers that need
 * to inspect it; the message is intentionally short and body-free so it's
 * safe to include in user-facing logs and stack traces.
 */
export interface RetryPolicy {
    /** Total attempts including the initial call. Default 3. */
    maxAttempts: number;
    /** Initial backoff in ms. Default 500. */
    baseDelayMs: number;
    /** Multiplier per attempt. Default 2. */
    backoffFactor: number;
    /** Cap on a single delay in ms. Default 10_000. */
    maxDelayMs: number;
    /**
     * Symmetric jitter as a fraction of the computed delay, in `[0, 1)`. The
     * actual delay is `delay * (1 + (rng() - 0.5) * 2 * jitter)`. Default 0.3.
     * Set to 0 to disable.
     */
    jitter: number;
}
export declare const DEFAULT_RETRY_POLICY: RetryPolicy;
export declare class LLMHttpError extends Error {
    readonly status: number;
    readonly attempts: number;
    /** Full upstream response body (kept on the instance, NOT in `message`). */
    readonly body: string;
    constructor(status: number, body: string, attempts: number);
}
/**
 * Sanitized error raised when an LLM adapter receives an HTTP-200 response
 * whose body is not valid JSON. The raw response body (which may echo back
 * user prompt content or even API-key fragments from prompts) is kept on the
 * instance for callers that opt in via `.raw`, NOT in the message string.
 *
 * Mirrors the LLMHttpError pattern verified by the
 * "does not leak the response body" test in openai-llm-client.test.ts.
 */
export declare class LLMParseError extends Error {
    /** Full raw response body (kept on the instance, NOT in `message`). */
    readonly raw: string;
    /** Byte length of `raw` — safe to include in the message. */
    readonly rawLength: number;
    constructor(message: string, raw: string, options?: {
        cause?: unknown;
    });
}
export declare function isRetryableStatus(status: number): boolean;
export interface RunWithRetryArgs<T> {
    policy: RetryPolicy;
    /** Per-attempt callable. Resolves to {result} on success, or returns ok:false to fail. */
    attempt: () => Promise<{
        ok: true;
        value: T;
    } | {
        ok: false;
        status: number;
        body: string;
        retryAfterSeconds?: number;
    }>;
    /** Sleeps for `ms`. Injectable for tests. */
    sleep?: (ms: number) => Promise<void>;
    /** Random source in `[0, 1)`. Injectable for tests. Defaults to `Math.random`. */
    rng?: () => number;
}
export declare function runWithRetry<T>(args: RunWithRetryArgs<T>): Promise<T>;
/** Parses a `Retry-After` header (seconds-only form). */
export declare function parseRetryAfterSeconds(header: null | string): number | undefined;
