/** * LLM PRICING + MODEL REGISTRY (LiteLLM-keyed). * * Scope split (locked 2026-05-25, slice #43 close-out): * * - `MODEL_REGISTRY` here = LiteLLM-keyed pricing + capability * metadata. Keys are LiteLLM strings (`"gemini/gemini-3.5-flash"`, * `"openai/gpt-5.4-mini"`, …). Read by: * - a hosted deployment's pricing-drift test (vendored * LiteLLM JSON pricing table) * - `oss/misc/benchmark` runner (bench harness; picks model * configs by LiteLLM key) * - `scripts/check-litellm-pricing-drift.ts` (CI guard) * This registry's keys MUST stay in LiteLLM format because the * vendored pricing JSON they cross-reference is LiteLLM-shaped. * * - LLM routing lives in {@link ./llm-route} — typed `LlmRoute` * discriminated union (`provider:model` canonical or * `provider/model` LiteLLM-compat). Every LLM call site threads * `LlmRoute`; the registry KEY equals the wire-canonical id the * provider's API expects. See * `docs/principles/model-string-convention.md`. * * The old routing helpers (`getProviderForModel`, `isValidLiteLLMFormat`, * `LLMProvider` (capital)) were deleted in the slice #43 close-out — * routing went through `parseAnyLlmRoute` + typed dispatch. * * Pricing last verified: 2026-09-02 — Anthropic 5-family + Haiku 4.5 (and the * new Fable 5.1 row) against platform.claude.com, quoted on ggui#706; the * Anthropic 4.x legacy rows and the Google/OpenAI rows keep their 2026-08-04 * re-vendor verification (not re-checked on 2026-09-02 — no source quoted). * Sources: * https://docs.anthropic.com/en/docs/about-claude/pricing * https://developers.openai.com/api/docs/pricing/ * https://ai.google.dev/gemini-api/docs/pricing * * KEEPING THIS HONEST: `costs` here is what the benchmark harness and * every cost read price against, and until 2026-07-31 nothing compared * it to anything — the vendored-snapshot test only asserted a row * EXISTS, and `scripts/check-litellm-pricing-drift.ts` compares the * snapshot against upstream, never the registry. That gap let this * table sit four months stale while production routed to models it did * not even list. A hosted deployment's `pricing-tables.test.ts` now asserts every * entry's `costs` match the vendored rate (with an explicit, dated * PENDING_UPSTREAM allowlist for prices we learn before LiteLLM does). * Add a model here and you MUST re-vendor the snapshot in the same * slice. */ import type { LlmProvider } from "./llm-route.js"; export type ModelTier = "fast" | "balanced" | "premium"; /** * Registry state of a row (ggui#707). `legacy` = still available and * routable, no longer the current generation (Anthropic's deprecations * page lists it Active with no retirement date); a retired model is * DELETED from the registry, never marked. Required on every row so a * consumer branches on a discriminant, never on an optional flag. */ export type ModelState = "active" | "legacy"; /** Every registry fact except the id, which the key supplies. */ export interface ModelConfigBase { provider: LlmProvider; displayName: string; tier: ModelTier; /** See {@link ModelState}. */ state: ModelState; /** * Member of the curated "current lineup" a picker shows up front * (ggui#707 / #711: Fable 5.1 · Opus 5 · Sonnet 5 · Haiku 4.5 as the * pool default). A registry fact, never a console array. Required so * a new row cannot silently fall out of both groups. */ lineup: boolean; /** * Earliest date the vendor's deprecation page guarantees the model is * still available (ISO date; the page's "≥ date" floor). Present only * when quoted from the vendor (ggui#706). */ retireNotBefore?: string; costs: { inputPer1M: number; outputPer1M: number; /** * Cache-write token rate (Anthropic prices a cache WRITE at ~1.25× * the input rate). Omit if the provider doesn't bill prompt caching * separately — consumers fall back to {@link inputPer1M}. */ cacheWritePer1M?: number; /** * Cache-read token rate (Anthropic prices a cache READ at ~0.1× the * input rate). Omit if the provider doesn't bill prompt caching * separately — consumers fall back to {@link inputPer1M}. */ cacheReadPer1M?: number; }; maxTokens: number; supportsTools: boolean; supportsCaching?: boolean; supportsThinking?: boolean; } declare const MODEL_ROWS: { readonly "anthropic/claude-fable-5-1": { readonly id: "anthropic/claude-fable-5-1"; readonly provider: "anthropic"; readonly displayName: "Claude Fable 5.1"; readonly tier: "premium"; readonly state: "active"; readonly lineup: true; readonly retireNotBefore: "2027-09-01"; readonly costs: { readonly inputPer1M: 10; readonly outputPer1M: 50; readonly cacheWritePer1M: 12.5; readonly cacheReadPer1M: 0.25; }; readonly maxTokens: 1000000; readonly supportsTools: true; }; readonly "anthropic/claude-fable-5": { readonly id: "anthropic/claude-fable-5"; readonly provider: "anthropic"; readonly displayName: "Claude Fable 5"; readonly tier: "premium"; readonly state: "legacy"; readonly lineup: false; readonly retireNotBefore: "2027-06-09"; readonly costs: { readonly inputPer1M: 10; readonly outputPer1M: 50; readonly cacheWritePer1M: 12.5; readonly cacheReadPer1M: 1; }; readonly maxTokens: 1000000; readonly supportsTools: true; }; readonly "anthropic/claude-opus-5": { readonly id: "anthropic/claude-opus-5"; readonly provider: "anthropic"; readonly displayName: "Claude Opus 5"; readonly tier: "premium"; readonly state: "active"; readonly lineup: true; readonly retireNotBefore: "2027-07-24"; readonly costs: { readonly inputPer1M: 5; readonly outputPer1M: 25; readonly cacheWritePer1M: 6.25; readonly cacheReadPer1M: 0.5; }; readonly maxTokens: 1000000; readonly supportsTools: true; }; readonly "anthropic/claude-sonnet-5": { readonly id: "anthropic/claude-sonnet-5"; readonly provider: "anthropic"; readonly displayName: "Claude Sonnet 5"; readonly tier: "balanced"; readonly state: "active"; readonly lineup: true; readonly retireNotBefore: "2027-06-30"; readonly costs: { readonly inputPer1M: 2; readonly outputPer1M: 10; readonly cacheWritePer1M: 2.5; readonly cacheReadPer1M: 0.2; }; readonly maxTokens: 1000000; readonly supportsTools: true; }; readonly "anthropic/claude-haiku-4-5": { readonly id: "anthropic/claude-haiku-4-5"; readonly provider: "anthropic"; readonly displayName: "Claude Haiku 4.5"; readonly tier: "fast"; readonly state: "active"; readonly lineup: true; readonly retireNotBefore: "2026-10-15"; readonly costs: { readonly inputPer1M: 1; readonly outputPer1M: 5; readonly cacheWritePer1M: 1.25; readonly cacheReadPer1M: 0.1; }; readonly maxTokens: 200000; readonly supportsTools: true; }; readonly "anthropic/claude-sonnet-4-6": { readonly id: "anthropic/claude-sonnet-4-6"; readonly provider: "anthropic"; readonly displayName: "Claude Sonnet 4.6"; readonly tier: "balanced"; readonly state: "legacy"; readonly lineup: false; readonly costs: { readonly inputPer1M: 3; readonly outputPer1M: 15; readonly cacheWritePer1M: 3.75; readonly cacheReadPer1M: 0.3; }; readonly maxTokens: 200000; readonly supportsTools: true; }; readonly "anthropic/claude-opus-4-7": { readonly id: "anthropic/claude-opus-4-7"; readonly provider: "anthropic"; readonly displayName: "Claude Opus 4.7"; readonly tier: "premium"; readonly state: "legacy"; readonly lineup: false; readonly costs: { readonly inputPer1M: 5; readonly outputPer1M: 25; readonly cacheWritePer1M: 6.25; readonly cacheReadPer1M: 0.5; }; readonly maxTokens: 1000000; readonly supportsTools: true; }; readonly "anthropic/claude-opus-4-6": { readonly id: "anthropic/claude-opus-4-6"; readonly provider: "anthropic"; readonly displayName: "Claude Opus 4.6"; readonly tier: "premium"; readonly state: "legacy"; readonly lineup: false; readonly costs: { readonly inputPer1M: 5; readonly outputPer1M: 25; readonly cacheWritePer1M: 6.25; readonly cacheReadPer1M: 0.5; }; readonly maxTokens: 1000000; readonly supportsTools: true; }; readonly "gemini/gemini-3.7-flash": { readonly id: "gemini/gemini-3.7-flash"; readonly provider: "google"; readonly displayName: "Gemini 3.7 Flash"; readonly tier: "balanced"; readonly state: "active"; readonly lineup: false; readonly costs: { readonly inputPer1M: 0.75; readonly outputPer1M: 3.75; readonly cacheReadPer1M: 0.075; }; readonly maxTokens: 1048576; readonly supportsTools: true; readonly supportsCaching: true; }; readonly "gemini/gemini-3.6-flash": { readonly id: "gemini/gemini-3.6-flash"; readonly provider: "google"; readonly displayName: "Gemini 3.6 Flash"; readonly tier: "fast"; readonly state: "active"; readonly lineup: false; readonly costs: { readonly inputPer1M: 0.75; readonly outputPer1M: 3.75; readonly cacheReadPer1M: 0.075; }; readonly maxTokens: 1048576; readonly supportsTools: true; readonly supportsCaching: true; }; readonly "gemini/gemini-3.5-flash": { readonly id: "gemini/gemini-3.5-flash"; readonly provider: "google"; readonly displayName: "Gemini 3.5 Flash"; readonly tier: "fast"; readonly state: "active"; readonly lineup: false; readonly costs: { readonly inputPer1M: 1.5; readonly outputPer1M: 9; }; readonly maxTokens: 1048576; readonly supportsTools: true; readonly supportsCaching: true; }; readonly "gemini/gemini-3.5-flash-lite": { readonly id: "gemini/gemini-3.5-flash-lite"; readonly provider: "google"; readonly displayName: "Gemini 3.5 Flash Lite"; readonly tier: "fast"; readonly state: "active"; readonly lineup: false; readonly costs: { readonly inputPer1M: 0.3; readonly outputPer1M: 2.5; readonly cacheReadPer1M: 0.03; }; readonly maxTokens: 1048576; readonly supportsTools: true; readonly supportsCaching: true; }; readonly "gemini/gemini-3.1-flash-lite": { readonly id: "gemini/gemini-3.1-flash-lite"; readonly provider: "google"; readonly displayName: "Gemini 3.1 Flash Lite"; readonly tier: "fast"; readonly state: "active"; readonly lineup: false; readonly costs: { readonly inputPer1M: 0.25; readonly outputPer1M: 1.5; }; readonly maxTokens: 1000000; readonly supportsTools: true; }; readonly "gemini/gemini-3-flash-preview": { readonly id: "gemini/gemini-3-flash-preview"; readonly provider: "google"; readonly displayName: "Gemini 3 Flash"; readonly tier: "fast"; readonly state: "active"; readonly lineup: false; readonly costs: { readonly inputPer1M: 0.5; readonly outputPer1M: 3; }; readonly maxTokens: 1000000; readonly supportsTools: true; }; readonly "gemini/gemini-3.1-pro-preview": { readonly id: "gemini/gemini-3.1-pro-preview"; readonly provider: "google"; readonly displayName: "Gemini 3.1 Pro"; readonly tier: "balanced"; readonly state: "active"; readonly lineup: false; readonly costs: { readonly inputPer1M: 2; readonly outputPer1M: 12; }; readonly maxTokens: 1000000; readonly supportsTools: true; }; readonly "openai/gpt-6-astra": { readonly id: "openai/gpt-6-astra"; readonly provider: "openai"; readonly displayName: "GPT-6 Astra"; readonly tier: "premium"; readonly state: "active"; readonly lineup: false; readonly costs: { readonly inputPer1M: 10; readonly outputPer1M: 50; readonly cacheWritePer1M: 12.5; readonly cacheReadPer1M: 1; }; readonly maxTokens: 922000; readonly supportsTools: true; }; readonly "openai/gpt-5.6-sol": { readonly id: "openai/gpt-5.6-sol"; readonly provider: "openai"; readonly displayName: "GPT-5.6 Sol"; readonly tier: "premium"; readonly state: "active"; readonly lineup: false; readonly costs: { readonly inputPer1M: 4; readonly outputPer1M: 20; readonly cacheWritePer1M: 5; readonly cacheReadPer1M: 0.4; }; readonly maxTokens: 1050000; readonly supportsTools: true; }; readonly "openai/gpt-5.6-terra": { readonly id: "openai/gpt-5.6-terra"; readonly provider: "openai"; readonly displayName: "GPT-5.6 Terra"; readonly tier: "balanced"; readonly state: "active"; readonly lineup: false; readonly costs: { readonly inputPer1M: 2; readonly outputPer1M: 12; readonly cacheReadPer1M: 0.2; }; readonly maxTokens: 1050000; readonly supportsTools: true; }; readonly "openai/gpt-5.6-luna": { readonly id: "openai/gpt-5.6-luna"; readonly provider: "openai"; readonly displayName: "GPT-5.6 Luna"; readonly tier: "fast"; readonly state: "active"; readonly lineup: false; readonly costs: { readonly inputPer1M: 0.2; readonly outputPer1M: 1.2; readonly cacheReadPer1M: 0.02; }; readonly maxTokens: 1050000; readonly supportsTools: true; }; readonly "openai/gpt-5.3-codex": { readonly id: "openai/gpt-5.3-codex"; readonly provider: "openai"; readonly displayName: "GPT-5.3 Codex"; readonly tier: "balanced"; readonly state: "active"; readonly lineup: false; readonly costs: { readonly inputPer1M: 1.75; readonly outputPer1M: 14; }; readonly maxTokens: 200000; readonly supportsTools: true; }; readonly "openai/gpt-5.4": { readonly id: "openai/gpt-5.4"; readonly provider: "openai"; readonly displayName: "GPT-5.4"; readonly tier: "premium"; readonly state: "active"; readonly lineup: false; readonly costs: { readonly inputPer1M: 2.5; readonly outputPer1M: 15; }; readonly maxTokens: 1050000; readonly supportsTools: true; }; readonly "openai/gpt-5.4-mini": { readonly id: "openai/gpt-5.4-mini"; readonly provider: "openai"; readonly displayName: "GPT-5.4 Mini"; readonly tier: "fast"; readonly state: "active"; readonly lineup: false; readonly costs: { readonly inputPer1M: 0.75; readonly outputPer1M: 4.5; }; readonly maxTokens: 400000; readonly supportsTools: true; }; readonly "openai/gpt-5.4-nano": { readonly id: "openai/gpt-5.4-nano"; readonly provider: "openai"; readonly displayName: "GPT-5.4 Nano"; readonly tier: "fast"; readonly state: "active"; readonly lineup: false; readonly costs: { readonly inputPer1M: 0.2; readonly outputPer1M: 1.25; }; readonly maxTokens: 400000; readonly supportsTools: true; }; }; /** A model id = a registry key. Derived; never a second list. */ export type ModelId = keyof typeof MODEL_ROWS; /** A registry row, as consumers read it. */ export interface ModelConfig extends ModelConfigBase { id: ModelId; } /** * The registry consumers read. Typed by the normalized {@link ModelConfig} * (not the literal row types) so `MODEL_REGISTRY[id]` for any `ModelId` * exposes every optional field as `T | undefined` rather than a union in * which some rows lack the property. The literal rows above still derive * {@link ModelId} and enforce `id === key`. */ export declare const MODEL_REGISTRY: Readonly>; /** Whether `value` is a registry model id — provider-qualified, e.g. `anthropic/claude-haiku-4-5`. */ export declare function isModelId(value: string): value is ModelId; /** Every registry model id, in registry order (ggui#924: the blueprint record's `model` is one of these). */ export declare const MODEL_IDS: readonly ModelId[]; /** * The curated "current lineup" — derived once from the rows' `lineup` * fact, in registry order. Pickers render this up front and put the * rest of the ACTIVE registry (legacy rows inside, marked) behind a * "see all models" door (ggui#707 / #711). */ export declare const MODEL_LINEUP: readonly ModelId[]; /** Whether `id` is in {@link MODEL_LINEUP}. */ export declare function isLineupModel(id: ModelId): boolean; /** * Default model for generation. Stays Haiku 4.5 until the founder rules * ggui#706 decision 1 (Fable 5.1 is 10× the per-render cost). */ export declare const DEFAULT_MODEL: ModelId; export {}; //# sourceMappingURL=llm.d.ts.map