import type { DescribedModel } from '../spi/model-provider.js';
import { type AgentPricingStore, type ModelPriceInput } from '../spi/pricing-store.js';
import { type ModelsDevOptions } from './models-dev.js';
/** How long the boot check waits for the models.dev catalog when no `signal` is given. */
export declare const CATALOG_TIMEOUT_MS = 15000;
/** Where boot pricing logs. Both are one line each, at most once per boot. */
export interface BootPricingLog {
    info(message: string): void;
    warn(message: string): void;
}
/**
 * One app-supplied price, as a rate card states it. `input`/`output`/`cacheRead`/`cacheWrite` are in
 * `currency` per `unit` of tokens. Only USD is recorded (the ledger column is `cost_usd`); a row in
 * another currency is refused with a warning rather than recorded as dollars.
 */
export interface PriceCatalogEntry {
    /**
     * The model id the price is for. A Bedrock id matches by normalized candidates, so one entry for the
     * base id (`anthropic.claude-sonnet-4-5-20250929-v1:0`) or the profile id (`us-gov.anthropic.…`)
     * also prices the ARN a turn reports (`arn:aws-us-gov:bedrock:…:inference-profile/us-gov.anthropic.…`).
     */
    model: string;
    input: number;
    output: number;
    /** Cache-read (prompt-cache hit) input tokens. Omit → priced at `input`. */
    cacheRead?: number;
    /** Cache-write input tokens. Omit → priced at `input`. */
    cacheWrite?: number;
    /** Default `'USD'`, the only one accepted. */
    currency?: 'USD';
    /** Default `'1M tokens'`. */
    unit?: '1M tokens' | '1K tokens';
}
/** The `priceCatalog` option: where boot seeds missing price rows from. */
export interface PriceCatalogOptions extends ModelsDevOptions {
    /**
     * Prices the app supplies. Seeded at boot for any model that has NO row yet (an existing row is
     * never overwritten), and before models.dev or the built-in Bedrock table are consulted — so they
     * win over both. Use it for GovCloud / China Bedrock, negotiated rates, or a model models.dev lacks.
     */
    prices?: readonly PriceCatalogEntry[];
    /**
     * The AWS region Bedrock runs in, for a Bedrock model id that does not name one (a base or `us.`
     * profile id; an ARN or a `us-gov.` id already does). Omit → `AWS_REGION` / `AWS_DEFAULT_REGION`.
     * A GovCloud (`us-gov-*`) or China (`cn-*`) region is never seeded with models.dev's commercial price.
     */
    region?: string;
    /** `false` → never fetch models.dev (app prices and the built-in Bedrock table still apply). */
    modelsDev?: boolean;
}
export interface EnsureModelPricingArgs {
    /** The configured models (`ModelProvider.describeModels()`). */
    models: readonly DescribedModel[];
    /** The bound pricing store; `undefined` → nothing to seed, every non-gateway model is unpriced. */
    pricingStore: AgentPricingStore | undefined;
    /** Where to seed missing rows from; `false` → no app prices, never fetch models.dev. */
    catalog: PriceCatalogOptions | false;
    log: BootPricingLog;
}
export interface EnsureModelPricingResult {
    /** Models a price row was written for (from app prices, the built-in Bedrock table or models.dev). */
    seeded: string[];
    /** Models that will record a `null` cost: no gateway cost and no price row. */
    unpriced: string[];
}
/**
 * Make sure every configured model records a cost, and say so when one will not.
 *
 * A model needs nothing when its provider reports the real cost (a gateway: OpenRouter, the Vercel AI
 * Gateway) — that figure always wins. Every other model is priced off the pricing store, so a model
 * with no row there would record `cost_usd = NULL` on every turn, silently. For each such model a row
 * is written — only when it has NONE, so a price an operator set is never overwritten — from, in order:
 *
 * 1. the app's `priceCatalog.prices`;
 * 2. for a Bedrock model in GovCloud / China, the built-in table (`BEDROCK_BUILTIN_PRICES`) — never
 *    models.dev, whose Bedrock prices are the commercial ones;
 * 3. models.dev's current list price.
 *
 * The row is keyed by the exact id the model is configured with (an ARN stays an ARN), which is the id
 * a turn reports and is priced under. Gateway models are seeded too, as the estimate a call that comes
 * back without a cost falls back to.
 *
 * A model still unpriced after that gets one warning line naming it, why, and the `priceCatalog`
 * entry that fixes it. Never throws: this runs at boot, and pricing is bookkeeping, not a reason for
 * the app to stay down.
 */
export declare function ensureModelPricing(args: EnsureModelPricingArgs): Promise<EnsureModelPricingResult>;
/** `priceCatalog.prices` as per-1M USD rows, keyed by model. Invalid entries are warned about and skipped. */
export declare function normalizePriceEntries(entries: readonly PriceCatalogEntry[], log?: BootPricingLog): Map<string, ModelPriceInput>;
//# sourceMappingURL=boot-pricing.d.ts.map