/**
 * Backend preflight: verify the models a campaign is about to spend tokens
 * against are actually served by the router BEFORE the run starts. The PRE-hoc
 * complement to `assertRealBackend` (which inspects RunRecords AFTER the run to
 * catch a stub/unconfigured backend).
 *
 * Two checks, increasing in cost:
 *   - membership (free): GET `{baseUrl}/models` once; a model is `listed` when
 *     its id is in the served set.
 *   - probe (spends a tiny number of tokens): POST `{baseUrl}/chat/completions`
 *     per model with a 1-message, 5-token request; `served` is whether the
 *     router returns 2xx, with the HTTP `status` and the body's `error.message`
 *     captured in `detail`.
 *
 * A default model the router cannot serve is a config bug. Gate a campaign on
 * `assertModelsServed` and it surfaces every dead id with its status + detail
 * instead of silently producing a stub run.
 */
import { AgentEvalError } from '../errors';
export interface ModelPreflight {
    /** The model id as supplied by the caller. */
    model: string;
    /** Membership in the `{baseUrl}/models` served set. */
    listed: boolean;
    /** 2xx on a 1-token chat probe. `null` when `probe` was not requested. */
    served: boolean | null;
    /** HTTP status of the probe. `null` when not probed. */
    status: number | null;
    /** Probe body's `error.message` when present, else `null`. */
    detail: string | null;
}
export interface PreflightModelsOptions {
    /** Router base URL, e.g. `https://router.tangle.tools/v1`. Trailing slash tolerated. */
    baseUrl: string;
    /** Bearer token sent as `Authorization: Bearer <apiKey>`. */
    apiKey: string;
    /** Model ids to check. */
    models: string[];
    /** When true, additionally spend a 1-token chat probe per model. Default false. */
    probe?: boolean;
    /** Injectable fetch for tests; defaults to the global. */
    fetchImpl?: typeof fetch;
}
export interface PreflightOutcome {
    succeeded: boolean;
    value: ModelPreflight[] | null;
    error: string | null;
}
/**
 * Check that `models` are reachable on the router. Returns a typed outcome —
 * a network failure yields `{ succeeded: false, error }`, never a throw and
 * never a partial result silently reported as success. No retries, no
 * fallbacks.
 *
 * The membership check (one GET) always runs. When `probe` is true, each model
 * additionally gets a 1-token chat probe so a model that is listed but
 * unconfigured (a 401 `model_not_found` from the router) is caught.
 */
export declare function preflightModels(opts: PreflightModelsOptions): Promise<PreflightOutcome>;
export declare class ModelsUnreachableError extends AgentEvalError {
    readonly results: ReadonlyArray<ModelPreflight>;
    constructor(message: string, results: ReadonlyArray<ModelPreflight>);
}
/**
 * Throw `ModelsUnreachableError` naming EVERY model that is unlisted or (when
 * probed) failed its probe — with status + detail per model. A model is dead
 * if it is unlisted, or if `served === false`. Callers gate a campaign on this
 * before spending tokens. When the network call itself fails the underlying
 * outcome error is rethrown — there is no partial silent pass.
 */
export declare function assertModelsServed(opts: PreflightModelsOptions): Promise<ModelPreflight[]>;
//# sourceMappingURL=preflight.d.ts.map