/** * Model pricing catalog — USD per 1k tokens, snapshot-dated per entry. * * Used by: * - `@gemstack/ai-sdk/eval` to populate the cost column on eval reports * - `@gemstack/ai-sdk`'s budget enforcement middleware (A6 phase 3) to debit * per-user spend against caps * * # Pricing drift * * Provider list pricing changes monthly. Each entry carries `_snapshotDate` * indicating when the rate was captured. Apps with negotiated rates should * pass an override map: * * ```ts * import { ModelPricing, withBudget } from '@gemstack/ai-sdk' * * withBudget({ * pricing: { * ...ModelPricing, * 'anthropic/claude-opus-4-7': { * inputPer1k: 0.012, * outputPer1k: 0.060, * _snapshotDate: '2026-01-15', * }, * }, * // ... * }) * ``` * * # Cache rates * * Anthropic, OpenAI, and Google all offer reduced rates for cache reads * (and Anthropic charges a small premium for cache writes). The optional * `cacheReadPer1k` / `cacheWritePer1k` fields capture those. The budget * middleware uses them when `TokenUsage` carries cache deltas; when absent * (today's `TokenUsage` shape), input rate applies to all input tokens. */ /** Pricing for a single `/` id, USD per 1k tokens. */ export interface ModelPriceEntry { /** Cost per 1k input (prompt) tokens, USD. */ inputPer1k: number; /** Cost per 1k output (completion) tokens, USD. */ outputPer1k: number; /** * Optional cost per 1k cached-read input tokens, USD. Set when the * provider exposes a discounted rate for cache hits (Anthropic ephemeral * cache, OpenAI prefix cache, Google cachedContent). When omitted, * `inputPer1k` applies to all input tokens. */ cacheReadPer1k?: number; /** * Optional cost per 1k cache-write input tokens, USD. Anthropic charges * a small premium on the first write that primes an ephemeral cache; * other providers don't. When omitted, `inputPer1k` applies. */ cacheWritePer1k?: number; /** * ISO date string indicating when this rate was captured from the * provider's published pricing. Surfaced in * {@link UnknownModelPricingError} messages and useful when auditing * stale catalogs. */ _snapshotDate: string; } /** * `/` → {@link ModelPriceEntry}. Override entries by * spreading: `{ ...ModelPricing, 'anthropic/claude-opus-4-7': {...} }`. * * Snapshot date: 2026-05-11. */ export declare const ModelPricing: Record; /** * Compute USD cost for an agent call given prompt + completion token * counts and a pricing catalog. * * Returns `0` when the model id isn't in `pricing` — eval cost columns * shouldn't crash on a fresh model. The budget middleware (A6 phase 3) * uses {@link assertKnownModelPricing} to fail loud at config time * instead. * * @param model `/` id * @param promptTokens Input tokens charged at `inputPer1k` * @param completionTokens Output tokens charged at `outputPer1k` * @param pricing Catalog override (defaults to {@link ModelPricing}) */ export declare function estimateCost(model: string, promptTokens: number, completionTokens: number, pricing?: Record): number; /** * Budget enforcement uses this — fail loud at agent-construction time * if the configured model isn't priced. Call from `withBudget(...)` in * phase 3. * * @throws {UnknownModelPricingError} when `pricing[model]` is missing */ export declare function assertKnownModelPricing(model: string, pricing?: Record): ModelPriceEntry; /** * Thrown by `assertKnownModelPricing` when a model id has no pricing * entry. The budget middleware throws this at construction so apps * fail at boot, not on first prompt. */ export declare class UnknownModelPricingError extends Error { readonly model: string; readonly snapshotDate: string | null; constructor(model: string, pricing: Record); } /** * Thrown by the budget middleware (A6 phase 3) when a request would * exceed a user's daily or monthly cap. Apps that want a different * error type can intercept via `withBudget({ onExceeded })` and throw * their own. */ export declare class BudgetExceededError extends Error { readonly userId: string; readonly period: 'daily' | 'monthly'; readonly spent: number; readonly cap: number; constructor(opts: { userId: string; period: 'daily' | 'monthly'; spent: number; cap: number; }); } //# sourceMappingURL=pricing.d.ts.map