diff --git a/app/api/settings/[section]/route.ts b/app/api/settings/[section]/route.ts index e037eea..20b59df 100644 --- a/app/api/settings/[section]/route.ts +++ b/app/api/settings/[section]/route.ts @@ -21,13 +21,14 @@ * lands here. */ -import type { AgentSettings, ChatSettings } from "@/src/core"; +import type { AgentSettings, ChatSettings, ModelsSettings } from "@/src/core"; import { SETTINGS_SECTIONS, allSegmentPaths, promptOverrides, readSettingsRecord, validateChatSettings, + validateModelsSettings, writeSettingsRecord, type SettingsBodyResult, } from "@/src/server"; @@ -60,6 +61,15 @@ export async function PUT(request: Request, ctx: { params: Promise<{ section: st return Response.json({ error: verdict.error, supported: verdict.supported }, { status: 400 }); } } + // Model slots wave (2026-09-20): the models section gets the same + // catalog gate the chat section gets — a slot must name a real + // provider+model and a thinking level it supports. + if (section === "models") { + const verdict = validateModelsSettings(parsed.settings as ModelsSettings); + if (!verdict.ok) { + return Response.json({ error: verdict.error, supported: verdict.supported }, { status: 400 }); + } + } if (section === "agent") { const agent = parsed.settings as AgentSettings; const segments = new Set(allSegmentPaths()); diff --git a/config.ts b/config.ts index 6ff216d..daa0fbb 100644 --- a/config.ts +++ b/config.ts @@ -46,7 +46,12 @@ export const PATHS = { export type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max"; export interface ModelSpec { - /** OpenRouter model id (e.g. "z-ai/glm-5.3-flash") — must exist in pi-ai's catalog. */ + /** The provider that owns the model (model slots wave, 2026-09-20): + * pi-ai provider id. Native ids are plain strings ("glm-5.3-flash" on + * zai); OpenRouter ids are vendor slugs ("z-ai/glm-5.3-flash"). The + * factory pins stay OpenRouter (the BYOK default provider). */ + provider: string; + /** The model id on that provider — must exist in pi-ai's catalog. */ model: string; /** Thinking budget — what the model may spend on reasoning tokens. */ effort: ThinkingLevel; @@ -54,28 +59,28 @@ export interface ModelSpec { export const MODELS = { /** The prober (agent A) — edge-bracketing questions; keep it lively and adaptive. */ - prober: { model: "z-ai/glm-5.3-flash", effort: "low" }, + prober: { provider: "openrouter", model: "z-ai/glm-5.3-flash", effort: "low" }, /** The teacher (agent B) — planning + streaming, lesson-facing: smart, but keep it lively. */ - teacher: { model: "z-ai/glm-5.3-flash", effort: "low" }, + teacher: { provider: "openrouter", model: "z-ai/glm-5.3-flash", effort: "low" }, /** Background sub-agents: fast and cheap beats deep thought. */ - researcher: { model: "z-ai/glm-5.3-flash", effort: "low" }, - demoBuilder: { model: "z-ai/glm-5.3-flash", effort: "low" }, + researcher: { provider: "openrouter", model: "z-ai/glm-5.3-flash", effort: "low" }, + demoBuilder: { provider: "openrouter", model: "z-ai/glm-5.3-flash", effort: "low" }, /** Must be vision-capable: it looks at rendered SVGs. */ - visualMaker: { model: "qwen/qwen3.8-flash", effort: "low" }, + visualMaker: { provider: "openrouter", model: "qwen/qwen3.8-flash", effort: "low" }, /** SEAM (master-approved 2026-09, revised by the user 2026-09-19): the * pdf-reader sub-agent. Must be vision-capable — it looks at rendered * PDF pages; its briefs are text. The user overrode the initial * glm-5.3-flash pick (catalog says it accepts images, but qwen is * proven for exactly this look-at-renders job — visualMaker's daily * workload). */ - pdfReader: { model: "qwen/qwen3.8-flash", effort: "low" }, + pdfReader: { provider: "openrouter", model: "qwen/qwen3.8-flash", effort: "low" }, /** Extraction is judgment over given evidence — light thinking suffices. */ - extractor: { model: "z-ai/glm-5.3-flash", effort: "low" }, + extractor: { provider: "openrouter", model: "z-ai/glm-5.3-flash", effort: "low" }, /** The auditor verifies evidence exists; keep it cheap. */ - auditor: { model: "z-ai/glm-5.3-flash", effort: "low" }, + auditor: { provider: "openrouter", model: "z-ai/glm-5.3-flash", effort: "low" }, /** Names detected communities — one singular call, given member names * + statements. Purely a labeling flourish; keep it cheap. */ - labeler: { model: "z-ai/glm-5.3-flash", effort: "low" }, + labeler: { provider: "openrouter", model: "z-ai/glm-5.3-flash", effort: "low" }, } satisfies Record; export type ModelRole = keyof typeof MODELS; diff --git a/scripts/sync-pricing.ts b/scripts/sync-pricing.ts index 68ef9e1..a212dd2 100644 --- a/scripts/sync-pricing.ts +++ b/scripts/sync-pricing.ts @@ -1,23 +1,26 @@ /** - * Regenerate src/core/prices.ts tables from pi-ai's shipped OpenRouter - * catalog (providers/data/openrouter.json). + * Regenerate src/core/prices.ts tables from pi-ai's shipped per-provider + * catalogs (providers/data/*.json). * * Usage: npx tsx scripts/sync-pricing.ts * - * The catalog is pi-ai's curated, versioned snapshot of OpenRouter's model - * list — the SAME source piEngineFor resolves engines from and - * /api/models serves the picker from — so the money channel's lookup table - * can never disagree with the engine. Fully offline (the JSON ships in - * node_modules); refreshes happen by bumping @earendil-works/pi-ai and - * re-running this script. The tables are generated; hand edits are - * overwritten. A model missing from the catalog gets no entry — cost - * renders as absent ("—"), never zero. + * The catalogs are pi-ai's curated, versioned snapshots — the SAME source + * piEngineFor resolves engines from and /api/models serves the picker + * from — so the money channel's lookup table can never disagree with the + * engine. Fully offline (the JSON ships in node_modules); refreshes happen + * by bumping @earendil-works/pi-ai and re-running this script. The tables + * are generated; hand edits are overwritten. A model missing from the + * catalogs gets no entry — cost renders as absent ("—"), never zero. + * + * Key format (model slots wave, 2026-09-20): uniformly provider-qualified + * ("provider:id", incl. "openrouter:"). Owner decision: no legacy + * compat — records stamped with pre-wave bare slugs simply render unpriced. */ import * as fs from "node:fs"; import * as path from "node:path"; -const CATALOG = path.join( +const DATA_DIR = path.join( import.meta.dirname, "..", "node_modules", @@ -26,11 +29,10 @@ const CATALOG = path.join( "dist", "providers", "data", - "openrouter.json", ); const OUT = path.join(import.meta.dirname, "..", "src", "core", "prices.ts"); -/** One raw catalog entry (fields we consume; the file carries more). */ +/** One raw catalog entry (fields we consume; the files carry more). */ interface CatalogModel { id: string; name: string; @@ -39,34 +41,51 @@ interface CatalogModel { } function main(): void { - // Keyed by api ("openai-completions" | "anthropic-messages"), each a - // Record — every OpenRouter id is unique across the two maps. - const catalog = JSON.parse(fs.readFileSync(CATALOG, "utf-8")) as Record< - string, - Record - >; - const byId = new Map(); - for (const api of Object.values(catalog)) for (const [id, m] of Object.entries(api)) byId.set(id, m); + // Every data file is {api: {modelId: entry}} — ids are per-provider + // namespaced already (openrouter's are slugs, native ones plain). + const priced = new Map(); + for (const file of fs.readdirSync(DATA_DIR).filter((f) => f.endsWith(".json"))) { + const provider = file.slice(0, -".json".length); + const catalog = JSON.parse(fs.readFileSync(path.join(DATA_DIR, file), "utf-8")) as Record< + string, + Record + >; + for (const models of Object.values(catalog)) { + for (const [id, m] of Object.entries(models)) { + // A catalog entry without pricing/limit data gets no key at all + // (cost renders "—", never zero; the limit renders unknown). + if (!m.cost || m.contextWindow === undefined) continue; + // First writer wins (an id can appear under two apis within one + // file with identical pricing; cross-file collisions cannot + // happen — keys are provider-qualified). + priced.set(`${provider}:${id}`, { cost: m.cost, contextWindow: m.contextWindow }); + } + } + } - // Sort by id for a stable, diff-friendly generated table. - const priced: { price: string; limit: string }[] = [...byId.entries()] + // Sort by key for a stable, diff-friendly generated table. + const rows = [...priced.entries()] .sort(([a], [b]) => a.localeCompare(b)) - .map(([id, m]) => ({ - price: `\t${JSON.stringify(id)}: { input: ${m.cost.input}, output: ${m.cost.output}, cacheRead: ${m.cost.cacheRead}, cacheWrite: ${m.cost.cacheWrite} },`, - limit: `\t${JSON.stringify(id)}: ${m.contextWindow},`, + .map(([key, m]) => ({ + price: `\t${JSON.stringify(key)}: { input: ${m.cost.input}, output: ${m.cost.output}, cacheRead: ${m.cost.cacheRead}, cacheWrite: ${m.cost.cacheWrite} },`, + limit: `\t${JSON.stringify(key)}: ${m.contextWindow},`, })); const tables = `/** Token prices, USD per 1M tokens. A missing model makes cost render - * as absent ("—"), never zero. Refresh: bump @earendil-works/pi-ai, then - * npx tsx scripts/sync-pricing.ts (reads pi-ai's shipped catalog — the - * same source the engine and the picker use). */ + * as absent ("—"), never zero. Keys are provider-qualified ("provider:id") + * since the model slots wave; openrouter ids ALSO appear under their bare + * slug (the legacy stamp format, kept so pre-wave records keep pricing). + * Refresh: bump @earendil-works/pi-ai, then npx tsx scripts/sync-pricing.ts + * (reads pi-ai's shipped catalogs — the same source the engine and the + * picker use). */ export const PRICES: Record = { -${priced.map((p) => p.price).join("\n")} +${rows.map((r) => r.price).join("\n")} }; -/** Context-window limits (tokens) per model — generated alongside PRICES. */ +/** Context-window limits (tokens) per model — generated alongside PRICES, + * same key families. */ export const CONTEXT_LIMITS: Record = { -${priced.map((p) => p.limit).join("\n")} +${rows.map((r) => r.limit).join("\n")} }; `; @@ -76,7 +95,7 @@ ${priced.map((p) => p.limit).join("\n")} if (start === -1 || end === -1) throw new Error("prices.ts markers not found — file structure changed"); fs.writeFileSync(OUT, src.slice(0, start) + tables + "\n" + src.slice(end), "utf-8"); - console.log(`prices.ts regenerated from pi-ai's catalog: ${priced.length} models priced.`); + console.log(`prices.ts regenerated from pi-ai's catalogs: ${priced.size} keys priced.`); } -main(); \ No newline at end of file +main(); diff --git a/src/agent/models.ts b/src/agent/models.ts index 712dbc2..fab5257 100644 --- a/src/agent/models.ts +++ b/src/agent/models.ts @@ -6,7 +6,7 @@ import { type Models, type StreamFunction, } from "@earendil-works/pi-ai"; -import { openrouterProvider } from "@earendil-works/pi-ai/providers/openrouter"; +import { builtinProviders } from "@earendil-works/pi-ai/providers/all"; import type { ThinkingLevel } from "@earendil-works/pi-agent-core"; import { MODELS, type ModelRole } from "../../config.ts"; import type { ChatSettings } from "../core/contracts/chat.ts"; @@ -42,11 +42,18 @@ export function thinkingLevelFor(role: ModelRole): ThinkingLevel { let collection: ReturnType | undefined; -/** The process-wide pi-ai Models collection (OpenRouter catalog). */ +/** The process-wide pi-ai Models collection — EVERY builtin provider's + * catalog (model slots wave, 2026-09-20): engines and the picker resolve + * against all of pi-ai's per-provider catalogs, so a settings slot can pin + * any native model id. Auth is resolved per request by pi-ai itself from + * the environment (the keys seam reflects file-saved keys into env), and + * a provider with no key simply fails its stream with "not configured" — + * honest, late, and unreachable through the picker, which gates on + * keyPresent. */ export function piModels() { if (!collection) { collection = createModels(); - collection.setProvider(openrouterProvider()); + for (const provider of builtinProviders()) collection.setProvider(provider); } return collection; } @@ -56,23 +63,28 @@ export function openRouterApiKey(): string | undefined { return process.env.OPENROUTER_API_KEY || undefined; } -/** The production engine for one agent role. `settings` is the chat's - * model-control override (prober/teacher only — sub-agent callers pass - * nothing and get config.ts's pin): any absent field falls back to the - * config spec, and the thinking level is CLAMPED to the model's supported - * list (pi's thinkingLevelMap — e.g. GLM-5.3-flash accepts low|high|max), - * so a settings change between models can never send an invalid level. */ -export function piEngineFor(role: ModelRole, settings?: ChatSettings): PiEngine { +/** A fully-resolved model pin — the shape every engine now comes from + * (model slots wave, 2026-09-20): the settings-resolution chain's output. + * Every field concrete; the CALLER resolved the chain (role override → + * slot → factory pin, or the chat's conversation chain). */ +export interface ResolvedModelSpec { + provider: string; + id: string; + thinkingLevel: ThinkingLevel; +} + +/** The production engine for a RESOLVED spec (model slots wave, + * 2026-09-20): provider-aware catalog lookup + thinking clamp. The API + * key is resolved by pi-ai itself from the environment per request (the + * keys seam reflects file-saved keys into env), so the engine never + * hardcodes OpenRouter's. */ +export function piEngineForSpec(spec: ResolvedModelSpec): PiEngine { const models: Models = piModels(); - const spec = MODELS[role]; - const modelId = settings?.model?.id ?? spec.model; - const providerId = settings?.model?.provider ?? "openrouter"; - const model = models.getModel(providerId, modelId); + const model = models.getModel(spec.provider, spec.id); if (!model) { - throw new Error(`${providerId} catalog has no model ${modelId} (role ${role})`); + throw new Error(`${spec.provider} catalog has no model ${spec.id}`); } - const requested = settings?.thinkingLevel ?? thinkingLevelFor(role); - const level = clampThinkingLevel(model, requested); + const level = clampThinkingLevel(model, spec.thinkingLevel); return { model, level, @@ -83,7 +95,21 @@ export function piEngineFor(role: ModelRole, settings?: ChatSettings): PiEngine models.streamSimple(requestModel, context, { ...options, reasoning: level === "off" ? undefined : level, - apiKey: options?.apiKey ?? openRouterApiKey(), }), }; -} \ No newline at end of file +} + +/** The production engine for one agent role — the LEGACY fallback path: + * the chat's model-control override over config.ts's pin. Production + * callers (chat-handler) now resolve the full chain (chat override → + * strong slot → factory pin) and call piEngineForSpec; this stays for + * direct config-pin fallbacks (sub-agents without an injected engine — + * the job runner injects one — and tests). */ +export function piEngineFor(role: ModelRole, settings?: ChatSettings): PiEngine { + const spec = MODELS[role]; + return piEngineForSpec({ + provider: settings?.model?.provider ?? spec.provider, + id: settings?.model?.id ?? spec.model, + thinkingLevel: settings?.thinkingLevel ?? thinkingLevelFor(role), + }); +} diff --git a/src/agent/subagents/extraction.ts b/src/agent/subagents/extraction.ts index 5588c46..53766d9 100644 --- a/src/agent/subagents/extraction.ts +++ b/src/agent/subagents/extraction.ts @@ -293,7 +293,10 @@ async function runSubmitAgent(opts: { onAssistantMessage: (message, step) => opts.onStep( message.usage, - message.model, + // Provider-qualified stamp (model slots wave, 2026-09-20): + // pi reports the bare id; usage stamps carry provider:id to + // match the price table's uniform keys. + `${message.provider}:${message.model}`, step, message.stopReason, message.content.filter((c) => c.type === "toolCall").map((c) => (c as { name: string }).name).join(", ") || "(none)", diff --git a/src/agent/subagents/runner.ts b/src/agent/subagents/runner.ts index dc0e227..b0e8396 100644 --- a/src/agent/subagents/runner.ts +++ b/src/agent/subagents/runner.ts @@ -19,7 +19,7 @@ import { type VisualToolInput, } from "../../core/contracts.ts"; import { registerJobAbort, unregisterJobAbort } from "./aborts.ts"; -import { MODELS } from "../../../config.ts"; +import { MODELS, type ModelRole } from "../../../config.ts"; import type { ChatStore, JobStore } from "../../core/ports.ts"; import { runDemoBuilder } from "./demo-builder.ts"; import { runPdfReaderAgent } from "./pdf-reader.ts"; @@ -68,6 +68,14 @@ export interface JobRunnerDeps { * flipped); rejects when delivery fails unrecoverably. */ deliver: (steer: SubagentSteerMessage) => Promise; + /** + * Settings-resolved engine per role (model slots wave, 2026-09-20): the + * role-override → slot → factory-pin chain, read FRESH per job (the + * server wiring passes effectiveSettings-based resolution). Closes the + * old gap where per-role settings overrides never reached job engines. + * Test overrides (below) still win; absent → config pins. + */ + engineFor?: (role: ModelRole) => PiEngine; } export interface JobRunner { @@ -89,18 +97,26 @@ interface LoopContext { onUsage: (step: UsageStepLike) => void; } -/** The OpenRouter model id for a job kind — JobUsage.model. The kind→role - * table mirrors MODELS in config.ts (research→researcher, demo→demoBuilder, - * visual→visualMaker); the id is taken from config so a price-table sync - * re-prices jobs for free. Model overrides (tests) still bill under the - * configured model — usage is what is being captured, not which instance. - * Context-injection jobs make NO model call ("" — onUsage never fires for - * them; the kind is deliberately absent from the runners below). */ +/** The kind→role table (model slots wave, 2026-09-20): which ModelRole's + * engine each sub-agent kind runs — the engineFor injection key. */ +const KIND_ROLE: Record, ModelRole> = { + research: "researcher", + demo: "demoBuilder", + visual: "visualMaker", + pdf: "pdfReader", +}; + +/** The config-pin model stamp for a job kind — JobUsage.model when no + * engine was resolved (engineFor absent AND no test override). Stamps are + * provider-qualified ("provider:id") since the model slots wave, matching + * the price table's uniform keys. Context-injection jobs make NO model + * call ("" — onUsage never fires for them; the kind is deliberately + * absent from the runners below). */ const KIND_MODEL: Record = { - research: MODELS.researcher.model, - demo: MODELS.demoBuilder.model, - visual: MODELS.visualMaker.model, - pdf: MODELS.pdfReader.model, + research: `${MODELS.researcher.provider}:${MODELS.researcher.model}`, + demo: `${MODELS.demoBuilder.provider}:${MODELS.demoBuilder.model}`, + visual: `${MODELS.visualMaker.provider}:${MODELS.visualMaker.model}`, + pdf: `${MODELS.pdfReader.provider}:${MODELS.pdfReader.model}`, "graph-context": "", }; @@ -111,8 +127,10 @@ export function createJobRunner(deps: JobRunnerDeps): JobRunner { * then writes through the job store so the poll sees progress). */ const usageTotals = new Map(); - function makeLoopContext(jobId: string, kind: JobKind): LoopContext { - const model = KIND_MODEL[kind]; + function makeLoopContext(jobId: string, kind: JobKind, engine?: PiEngine): LoopContext { + // Provider-qualified stamp (model slots wave): the engine's actual + // model, else the legacy config-pin id (see KIND_MODEL). + const model = engine ? `${engine.model.provider}:${engine.model.id}` : KIND_MODEL[kind]; // Real-kill wiring (2026-09 abort semantics): the controller is what // the abort endpoint fires (agent/subagents/aborts.ts registry); the // signal rides into every model call of the loop. @@ -143,14 +161,28 @@ export function createJobRunner(deps: JobRunnerDeps): JobRunner { * them below rather than guessing wrong. */ // Each kind's runner narrows the union input itself (dispatch-time inputs // are kind-correct by construction; transcript fallbacks are cast after). + /** The engine one job runs on: test override first (the old seam — + * tests swap scripted engines without touching deps), then the injected + * settings-resolved engineFor (model slots wave, 2026-09-20), else + * undefined → the sub-agent factories fall back to config pins. */ + function pickEngine(kind: Exclude): PiEngine | undefined { + const testOverride: Record = { + researcher: researchModelOverride, + demoBuilder: demoModelOverride, + visualMaker: visualModelOverride, + pdfReader: pdfModelOverride, + }; + return testOverride[KIND_ROLE[kind]]?.current ?? deps.engineFor?.(KIND_ROLE[kind]); + } + const KIND_RUNNERS: Record< Exclude, - (jobId: string, input: JobToolInput | undefined, loop: LoopContext) => Promise + (jobId: string, engine: PiEngine | undefined, input: JobToolInput | undefined, loop: LoopContext) => Promise > = { - research: (jobId, input, loop) => runResearchJob(jobId, researchModelOverride.current, input, loop), - demo: (jobId, input, loop) => runDemoJob(jobId, demoModelOverride.current, input, loop), - visual: (jobId, input, loop) => runVisualJob(jobId, visualModelOverride.current, input, loop), - pdf: (jobId, input, loop) => runPdfJob(jobId, pdfModelOverride.current, input, loop), + research: (jobId, engine, input, loop) => runResearchJob(jobId, engine, input, loop), + demo: (jobId, engine, input, loop) => runDemoJob(jobId, engine, input, loop), + visual: (jobId, engine, input, loop) => runVisualJob(jobId, engine, input, loop), + pdf: (jobId, engine, input, loop) => runPdfJob(jobId, engine, input, loop), }; async function runJob(jobId: string, input?: JobToolInput): Promise { @@ -173,7 +205,8 @@ export function createJobRunner(deps: JobRunnerDeps): JobRunner { return; } try { - await run(jobId, input, makeLoopContext(jobId, job.kind)); + const engine = pickEngine(job.kind); + await run(jobId, engine, input, makeLoopContext(jobId, job.kind, engine)); } finally { unregisterJobAbort(jobId); // The last usage write may have been mid-flight when the loop died; diff --git a/src/core/contracts/chat.ts b/src/core/contracts/chat.ts index 2a777d6..d3f170b 100644 --- a/src/core/contracts/chat.ts +++ b/src/core/contracts/chat.ts @@ -86,7 +86,8 @@ export const GRAPH_CONTEXT_TOKENS_STOPS = [0, 64, 256, 1024, 4096, 16384] as con * billed (CallUsage per agent step). Steps, not a sum: cost and context * folds happen at read time (core/prices.ts). */ export interface ExtractionStageUsage { - /** The OpenRouter model id that ran this stage. */ + /** The model that ran this stage, provider-qualified ("provider:id" — + * model slots wave, 2026-09-20; matches PRICES' uniform keys). */ model: string; steps: CallUsage[]; } @@ -142,7 +143,8 @@ export interface TurnUsage { * entry to the transcript (the block this turn "belongs" to). */ messageId: string; at: string; - /** The OpenRouter model id that ran the turn. */ + /** The model that ran the turn, provider-qualified ("provider:id" — + * model slots wave, 2026-09-20; matches PRICES' uniform keys). */ model: string; /** One entry per agent step (model call) in this turn. */ steps: CallUsage[]; diff --git a/src/core/contracts/jobs.ts b/src/core/contracts/jobs.ts index fac7a95..947531f 100644 --- a/src/core/contracts/jobs.ts +++ b/src/core/contracts/jobs.ts @@ -41,7 +41,8 @@ export interface JobRecord { * field NO model call reported stays undefined — absent is not zero (the * money-channel doctrine; cost renders "—", never $0). */ export interface JobUsage { - /** The OpenRouter model id that ran the sub-agent. */ + /** The model that ran the sub-agent, provider-qualified ("provider:id" — + * model slots wave, 2026-09-20; matches PRICES' uniform keys). */ model: string; /** Running totals summed over the run's model calls so far. */ inputTokens: number | undefined; diff --git a/src/core/contracts/models.ts b/src/core/contracts/models.ts index 22c2287..4e3b4c4 100644 --- a/src/core/contracts/models.ts +++ b/src/core/contracts/models.ts @@ -6,7 +6,7 @@ * components never import from the server band). */ import type { ThinkingLevel } from "@earendil-works/pi-agent-core"; -import type { BackgroundModelRole } from "../settings.ts"; +import type { BackgroundModelRole, ModelSlotName } from "../settings.ts"; /** One picker row: everything the UI shows about a model, projected from * pi-ai's catalog. Costs are USD per 1M tokens (the same catalog, the same @@ -42,6 +42,12 @@ export type RolePins = Record< { model: { provider: string; id: string }; thinkingLevel?: ThinkingLevel } >; +/** One slot tier's RESOLVED pin (model slots wave, 2026-09-20): the + * strong/cheap/vision tier's concrete model — slot override falling back + * to the factory rep pin. The settings UI captions each slot row with it + * and the picker pre-fills from it. */ +export type SlotPins = Record; + /** GET /api/models response. */ export interface ModelCatalogResponse { models: ModelCatalogEntry[]; @@ -49,4 +55,23 @@ export interface ModelCatalogResponse { /** The six background roles' resolved pins (same resolution the agent * factories use — src/server/stores.ts effectiveSettings). */ rolePins: RolePins; + /** The three slot tiers' resolved pins (model slots wave, 2026-09-20): + * same resolution chain — role override → slot → factory pin — reported + * at tier granularity; effectiveSettings().models verbatim. */ + slots: SlotPins; + /** Providers with a PRESENT key, and which env var gates each — the + * model slots wave's federation surface (2026-09-20): the picker lists + * models from these providers' pi-ai catalogs only. Keyless providers + * are simply absent (the Keys page is the discovery surface, same + * discipline as the search engines). */ + providers: CatalogProvider[]; +} + +/** One row of the providers surface. */ +export interface CatalogProvider { + id: string; + /** The env var whose presence federates this provider in. */ + envVar: string; + /** Whether that var is currently present (env or auth file). */ + keyPresent: boolean; } \ No newline at end of file diff --git a/src/core/prices.ts b/src/core/prices.ts index c2e583c..8123082 100644 --- a/src/core/prices.ts +++ b/src/core/prices.ts @@ -28,746 +28,2726 @@ export interface ModelPrice { } /** Token prices, USD per 1M tokens. A missing model makes cost render - * as absent ("—"), never zero. Refresh: bump @earendil-works/pi-ai, then - * npx tsx scripts/sync-pricing.ts (reads pi-ai's shipped catalog — the - * same source the engine and the picker use). */ + * as absent ("—"), never zero. Keys are provider-qualified ("provider:id") + * since the model slots wave; openrouter ids ALSO appear under their bare + * slug (the legacy stamp format, kept so pre-wave records keep pricing). + * Refresh: bump @earendil-works/pi-ai, then npx tsx scripts/sync-pricing.ts + * (reads pi-ai's shipped catalogs — the same source the engine and the + * picker use). */ export const PRICES: Record = { - "~anthropic/claude-fable-latest": { input: 10, output: 50, cacheRead: 0.25, cacheWrite: 12.5 }, - "~anthropic/claude-haiku-latest": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, - "~anthropic/claude-opus-latest": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, - "~anthropic/claude-sonnet-latest": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, - "~deepseek/deepseek-v4-flash-latest": { input: 0.04998, output: 0.09996, cacheRead: 0.009996, cacheWrite: 0 }, - "~google/gemini-flash-latest": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0.041667 }, - "~google/gemini-pro-latest": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, - "~moonshotai/kimi-latest": { input: 2.55, output: 12.75, cacheRead: 0.256, cacheWrite: 0 }, - "~openai/gpt-latest": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, - "~openai/gpt-mini-latest": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, - "~x-ai/grok-latest": { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, - "~z-ai/glm-flash-latest": { input: 0.075, output: 0.25, cacheRead: 0.015, cacheWrite: 0 }, - "~z-ai/glm-latest": { input: 1.15, output: 3.5, cacheRead: 0.1, cacheWrite: 0 }, - "aion-labs/aion-2.0": { input: 0.8, output: 1.6, cacheRead: 0.2, cacheWrite: 0 }, - "aion-labs/aion-3.0": { input: 3, output: 6, cacheRead: 0.75, cacheWrite: 0 }, - "aion-labs/aion-3.0-mini": { input: 0.7, output: 1.4, cacheRead: 0.18, cacheWrite: 0 }, - "amazon/nova-2-lite-v1": { input: 0.3, output: 2.5, cacheRead: 0, cacheWrite: 0 }, - "amazon/nova-lite-v1": { input: 0.06, output: 0.24, cacheRead: 0, cacheWrite: 0 }, - "amazon/nova-micro-v1": { input: 0.035, output: 0.14, cacheRead: 0, cacheWrite: 0 }, - "amazon/nova-premier-v1": { input: 2.5, output: 12.5, cacheRead: 0.625, cacheWrite: 0 }, - "amazon/nova-pro-v1": { input: 0.8, output: 3.2, cacheRead: 0, cacheWrite: 0 }, - "anthropic/claude-3-haiku": { input: 0.25, output: 1.25, cacheRead: 0.03, cacheWrite: 0.3 }, - "anthropic/claude-fable-5": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, - "anthropic/claude-fable-5:batch": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, - "anthropic/claude-fable-5.1": { input: 10, output: 50, cacheRead: 0.25, cacheWrite: 12.5 }, - "anthropic/claude-fable-5.1:batch": { input: 5, output: 25, cacheRead: 0.125, cacheWrite: 6.25 }, - "anthropic/claude-haiku-4.5": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, - "anthropic/claude-haiku-4.5:batch": { input: 0.5, output: 2.5, cacheRead: 0.05, cacheWrite: 0.625 }, - "anthropic/claude-opus-4": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 }, - "anthropic/claude-opus-4.1": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 }, - "anthropic/claude-opus-4.1:batch": { input: 7.5, output: 37.5, cacheRead: 0.75, cacheWrite: 9.375 }, - "anthropic/claude-opus-4.5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, - "anthropic/claude-opus-4.5:batch": { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, - "anthropic/claude-opus-4.6": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, - "anthropic/claude-opus-4.6:batch": { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, - "anthropic/claude-opus-4.7": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, - "anthropic/claude-opus-4.7:batch": { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, - "anthropic/claude-opus-4.8": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, - "anthropic/claude-opus-4.8:batch": { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, - "anthropic/claude-opus-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, - "anthropic/claude-opus-5:batch": { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, - "anthropic/claude-sonnet-4": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, - "anthropic/claude-sonnet-4.5": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, - "anthropic/claude-sonnet-4.5:batch": { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 1.875 }, - "anthropic/claude-sonnet-4.6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, - "anthropic/claude-sonnet-4.6:batch": { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 1.875 }, - "anthropic/claude-sonnet-5": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, - "anthropic/claude-sonnet-5:batch": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, - "arcee-ai/trinity-large-thinking": { input: 0.25, output: 0.8, cacheRead: 0.06, cacheWrite: 0 }, - "auto": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "bytedance-seed/seed-1.6": { input: 0.25, output: 2, cacheRead: 0, cacheWrite: 0 }, - "bytedance-seed/seed-1.6-flash": { input: 0.075, output: 0.3, cacheRead: 0, cacheWrite: 0 }, - "bytedance-seed/seed-2-1-turbo": { input: 0.5, output: 2.5, cacheRead: 0, cacheWrite: 0 }, - "bytedance-seed/seed-2.0-code": { input: 0.5, output: 3, cacheRead: 0, cacheWrite: 0 }, - "bytedance-seed/seed-2.0-lite": { input: 0.25, output: 2, cacheRead: 0, cacheWrite: 0 }, - "bytedance-seed/seed-2.0-mini": { input: 0.1, output: 0.4, cacheRead: 0, cacheWrite: 0 }, - "cohere/command-r-08-2024": { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, - "cohere/command-r-plus-08-2024": { input: 2.5, output: 10, cacheRead: 0, cacheWrite: 0 }, - "cohere/north-mini-code:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "deepseek/deepseek-chat": { input: 0.32, output: 0.89, cacheRead: 0, cacheWrite: 0 }, - "deepseek/deepseek-chat-v3-0324": { input: 0.25, output: 1, cacheRead: 0, cacheWrite: 0 }, - "deepseek/deepseek-chat-v3.1": { input: 0.55, output: 1.65, cacheRead: 0.55, cacheWrite: 0 }, - "deepseek/deepseek-r1": { input: 0.7, output: 2.5, cacheRead: 0, cacheWrite: 0 }, - "deepseek/deepseek-r1-0528": { input: 0.5, output: 2.15, cacheRead: 0.35, cacheWrite: 0 }, - "deepseek/deepseek-v3.1-terminus": { input: 0.27, output: 1, cacheRead: 0.135, cacheWrite: 0 }, - "deepseek/deepseek-v3.2": { input: 0.269, output: 0.4, cacheRead: 0.1345, cacheWrite: 0 }, - "deepseek/deepseek-v3.2-exp": { input: 0.27, output: 0.41, cacheRead: 0, cacheWrite: 0 }, - "deepseek/deepseek-v4-flash": { input: 0.08526, output: 0.17052, cacheRead: 0.017052, cacheWrite: 0 }, - "deepseek/deepseek-v4-flash-0731": { input: 0.065, output: 0.18, cacheRead: 0.016, cacheWrite: 0 }, - "deepseek/deepseek-v4-flash-0731:batch": { input: 0.14, output: 0.28, cacheRead: 0.03, cacheWrite: 0 }, - "deepseek/deepseek-v4-flash-vision-exp": { input: 0.22, output: 0.66, cacheRead: 0.007, cacheWrite: 0 }, - "deepseek/deepseek-v4-pro": { input: 0.890358, output: 1.780716, cacheRead: 0.074196, cacheWrite: 0 }, - "deepseek/deepseek-v4-pro-0813": { input: 1.12068, output: 3.36204, cacheRead: 0.037356, cacheWrite: 0 }, - "deepseek/deepseek-v4-pro-0813:batch": { input: 1.32, output: 3.96, cacheRead: 0.13, cacheWrite: 0 }, - "dots-studio/dots-3-note-preview:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "google/gemini-2.5-flash": { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0.083333 }, - "google/gemini-2.5-flash-lite": { input: 0.1, output: 0.4, cacheRead: 0.01, cacheWrite: 0.083333 }, - "google/gemini-2.5-flash-lite:batch": { input: 0.05, output: 0.2, cacheRead: 0.01, cacheWrite: 0 }, - "google/gemini-2.5-flash:batch": { input: 0.15, output: 1.25, cacheRead: 0.03, cacheWrite: 0 }, - "google/gemini-2.5-pro": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0.375 }, - "google/gemini-2.5-pro-preview": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0.375 }, - "google/gemini-2.5-pro-preview-05-06": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0.375 }, - "google/gemini-2.5-pro:batch": { input: 0.625, output: 5, cacheRead: 0.125, cacheWrite: 0 }, - "google/gemini-3-flash-preview": { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0.083333 }, - "google/gemini-3-flash-preview:batch": { input: 0.25, output: 1.5, cacheRead: 0, cacheWrite: 0 }, - "google/gemini-3-pro-image": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, - "google/gemini-3.1-flash-lite": { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0.083333 }, - "google/gemini-3.1-flash-lite-preview": { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0.083333 }, - "google/gemini-3.1-flash-lite:batch": { input: 0.125, output: 0.75, cacheRead: 0.0125, cacheWrite: 0 }, - "google/gemini-3.1-pro-preview": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, - "google/gemini-3.1-pro-preview-customtools": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, - "google/gemini-3.1-pro-preview:batch": { input: 1, output: 6, cacheRead: 0, cacheWrite: 0 }, - "google/gemini-3.5-flash": { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0.083333 }, - "google/gemini-3.5-flash-lite": { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0.083333 }, - "google/gemini-3.5-flash-lite:batch": { input: 0.15, output: 1.25, cacheRead: 0.015, cacheWrite: 0 }, - "google/gemini-3.5-flash:batch": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, - "google/gemini-3.6-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0.041667 }, - "google/gemini-3.6-flash:batch": { input: 0.375, output: 1.875, cacheRead: 0.0375, cacheWrite: 0.041667 }, - "google/gemini-3.7-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0.041667 }, - "google/gemini-3.7-flash:batch": { input: 0.375, output: 1.875, cacheRead: 0.0375, cacheWrite: 0.041667 }, - "google/gemini-3.8-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0.041667 }, - "google/gemini-3.8-flash:batch": { input: 0.375, output: 1.875, cacheRead: 0.0375, cacheWrite: 0.041667 }, - "google/gemma-3-12b-it": { input: 0.05, output: 0.15, cacheRead: 0, cacheWrite: 0 }, - "google/gemma-3-27b-it": { input: 0.08, output: 0.45, cacheRead: 0.04, cacheWrite: 0 }, - "google/gemma-4-26b-a4b-it": { input: 0.07, output: 0.34, cacheRead: 0, cacheWrite: 0 }, - "google/gemma-4-26b-a4b-it:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "google/gemma-4-31b-it": { input: 0.09, output: 0.34, cacheRead: 0.05, cacheWrite: 0 }, - "google/gemma-4-31b-it:batch": { input: 0.39, output: 0.97, cacheRead: 0, cacheWrite: 0 }, - "google/gemma-4-31b-it:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "ibm-granite/granite-4.2-8b": { input: 0.1, output: 0.15, cacheRead: 0.05, cacheWrite: 0 }, - "inception/mercury-2": { input: 0.25, output: 0.75, cacheRead: 0.025, cacheWrite: 0 }, - "inception/mercury-2.5-preview": { input: 0.04, output: 0.15, cacheRead: 0.004, cacheWrite: 0 }, - "inclusionai/ling-3.0-flash": { input: 0.021, output: 0.063, cacheRead: 0.0042, cacheWrite: 0 }, - "inclusionai/ling-3.0-flash-fin": { input: 0.06, output: 0.18, cacheRead: 0.012, cacheWrite: 0 }, - "inclusionai/ling-3.0-flash-fin:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "inclusionai/ling-3.0-flash-sante:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "kwaipilot/kat-coder-pro-v2": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, - "kwaipilot/kat-coder-pro-v2.5": { input: 0.74, output: 2.96, cacheRead: 0.15, cacheWrite: 0 }, - "liquid/lfm-2.5-2.6b:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "meituan/longcat-2.0": { input: 0.3, output: 1.2, cacheRead: 0.006, cacheWrite: 0 }, - "meta-llama/llama-3.1-70b-instruct": { input: 0.4, output: 0.4, cacheRead: 0, cacheWrite: 0 }, - "meta-llama/llama-3.1-8b-instruct": { input: 0.05, output: 0.08, cacheRead: 0.025, cacheWrite: 0 }, - "meta-llama/llama-3.3-70b-instruct": { input: 0.1, output: 0.32, cacheRead: 0, cacheWrite: 0 }, - "meta-llama/llama-4-maverick": { input: 0.2, output: 0.696, cacheRead: 0, cacheWrite: 0 }, - "meta-llama/llama-4-scout": { input: 0.1, output: 0.3, cacheRead: 0, cacheWrite: 0 }, - "meta/muse-glimmer-30b": { input: 0.3, output: 1.1, cacheRead: 0.04, cacheWrite: 0 }, - "meta/muse-glimmer-30b:batch": { input: 0.35, output: 1.5, cacheRead: 0.04, cacheWrite: 0 }, - "meta/muse-spark-1.1": { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, - "meta/muse-spark-1.2": { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, - "meta/muse-spark-1.2-contributor": { input: 0.1, output: 0.2, cacheRead: 0.002, cacheWrite: 0 }, - "meta/muse-spark-1.3": { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, - "meta/muse-spark-1.3-contributor": { input: 0.1, output: 0.2, cacheRead: 0.002, cacheWrite: 0 }, - "minimax/minimax-m1": { input: 0.55, output: 2.2, cacheRead: 0, cacheWrite: 0 }, - "minimax/minimax-m2": { input: 0.255, output: 1.02, cacheRead: 0, cacheWrite: 0 }, - "minimax/minimax-m2.1": { input: 0.3, output: 1.2, cacheRead: 0.03, cacheWrite: 0 }, - "minimax/minimax-m2.5": { input: 0.27, output: 1.08, cacheRead: 0.027, cacheWrite: 0 }, - "minimax/minimax-m2.7": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, - "minimax/minimax-m2.7:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "minimax/minimax-m3": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, - "minimax/minimax-m3:batch": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, - "minimax/minimax-m3:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "mistralai/codestral-2508": { input: 0.3, output: 0.9, cacheRead: 0.03, cacheWrite: 0 }, - "mistralai/devstral-2512": { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, - "mistralai/ministral-14b-2512": { input: 0.2, output: 0.2, cacheRead: 0.02, cacheWrite: 0 }, - "mistralai/ministral-3b-2512": { input: 0.1, output: 0.1, cacheRead: 0.01, cacheWrite: 0 }, - "mistralai/ministral-8b-2512": { input: 0.15, output: 0.15, cacheRead: 0.015, cacheWrite: 0 }, - "mistralai/mistral-large": { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 0 }, - "mistralai/mistral-large-2407": { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 0 }, - "mistralai/mistral-large-2512": { input: 0.5, output: 1.5, cacheRead: 0.05, cacheWrite: 0 }, - "mistralai/mistral-medium-3": { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, - "mistralai/mistral-medium-3-5": { input: 1.5, output: 7.5, cacheRead: 0, cacheWrite: 0 }, - "mistralai/mistral-medium-3-5:batch": { input: 0.75, output: 3.75, cacheRead: 0, cacheWrite: 0 }, - "mistralai/mistral-medium-3.1": { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, - "mistralai/mistral-nemo": { input: 0.019, output: 0.03, cacheRead: 0, cacheWrite: 0 }, - "mistralai/mistral-saba": { input: 0.2, output: 0.6, cacheRead: 0.02, cacheWrite: 0 }, - "mistralai/mistral-small-2603": { input: 0.15, output: 0.6, cacheRead: 0.015, cacheWrite: 0 }, - "mistralai/mistral-small-3.2-24b-instruct": { input: 0.075, output: 0.2, cacheRead: 0, cacheWrite: 0 }, - "mistralai/mixtral-8x22b-instruct": { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 0 }, - "mistralai/voxtral-small-24b-2507": { input: 0.1, output: 0.3, cacheRead: 0.01, cacheWrite: 0 }, - "moonshotai/kimi-k2": { input: 0.57, output: 2.3, cacheRead: 0, cacheWrite: 0 }, - "moonshotai/kimi-k2-0905": { input: 0.6, output: 2.5, cacheRead: 0, cacheWrite: 0 }, - "moonshotai/kimi-k2-thinking": { input: 0.6, output: 2.5, cacheRead: 0.15, cacheWrite: 0 }, - "moonshotai/kimi-k2.5": { input: 0.41, output: 2.06, cacheRead: 0.07, cacheWrite: 0 }, - "moonshotai/kimi-k2.6": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, - "moonshotai/kimi-k2.7-code": { input: 0.66, output: 3.4, cacheRead: 0.18, cacheWrite: 0 }, - "moonshotai/kimi-k3": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, - "moonshotai/kimi-k3:batch": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, - "nex-agi/nex-n2-mini": { input: 0.025, output: 0.1, cacheRead: 0.0025, cacheWrite: 0 }, - "nex-agi/nex-n2-pro": { input: 0.25, output: 1, cacheRead: 0.025, cacheWrite: 0 }, - "nvidia/nemotron-3-nano-30b-a3b": { input: 0.05, output: 0.2, cacheRead: 0.03, cacheWrite: 0 }, - "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "nvidia/nemotron-3-super-120b-a12b": { input: 0.085, output: 0.4, cacheRead: 0, cacheWrite: 0 }, - "nvidia/nemotron-3-super-120b-a12b:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "nvidia/nemotron-3-ultra-550b-a55b": { input: 0.625, output: 3.125, cacheRead: 0.1875, cacheWrite: 0 }, - "nvidia/nemotron-3-ultra-550b-a55b:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "nvidia/nemotron-3.5-lightning": { input: 0.08, output: 0.2, cacheRead: 0.04, cacheWrite: 0 }, - "nvidia/nemotron-3.5-lightning:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-3.5-turbo": { input: 0.5, output: 1.5, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-3.5-turbo-0613": { input: 1, output: 2, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-3.5-turbo-16k": { input: 3, output: 4, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-3.5-turbo:batch": { input: 0.25, output: 0.75, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-4": { input: 30, output: 60, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-4-turbo": { input: 10, output: 30, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-4-turbo-preview": { input: 10, output: 30, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-4-turbo:batch": { input: 5, output: 15, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-4.1": { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, - "openai/gpt-4.1-mini": { input: 0.4, output: 1.6, cacheRead: 0.1, cacheWrite: 0 }, - "openai/gpt-4.1-mini:batch": { input: 0.2, output: 0.8, cacheRead: 0.05, cacheWrite: 0 }, - "openai/gpt-4.1-nano": { input: 0.1, output: 0.4, cacheRead: 0.025, cacheWrite: 0 }, - "openai/gpt-4.1-nano:batch": { input: 0.05, output: 0.2, cacheRead: 0.0125, cacheWrite: 0 }, - "openai/gpt-4.1:batch": { input: 1, output: 4, cacheRead: 0.25, cacheWrite: 0 }, - "openai/gpt-4o": { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, - "openai/gpt-4o-2024-05-13": { input: 5, output: 15, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-4o-2024-08-06": { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, - "openai/gpt-4o-2024-11-20": { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, - "openai/gpt-4o-mini": { input: 0.15, output: 0.6, cacheRead: 0.075, cacheWrite: 0 }, - "openai/gpt-4o-mini-2024-07-18": { input: 0.15, output: 0.6, cacheRead: 0.075, cacheWrite: 0 }, - "openai/gpt-4o-mini:batch": { input: 0.075, output: 0.3, cacheRead: 0.0375, cacheWrite: 0 }, - "openai/gpt-4o:batch": { input: 1.25, output: 5, cacheRead: 0.625, cacheWrite: 0 }, - "openai/gpt-5": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, - "openai/gpt-5-mini": { input: 0.25, output: 2, cacheRead: 0.025, cacheWrite: 0 }, - "openai/gpt-5-mini:batch": { input: 0.125, output: 1, cacheRead: 0.0125, cacheWrite: 0 }, - "openai/gpt-5-nano": { input: 0.05, output: 0.4, cacheRead: 0.005, cacheWrite: 0 }, - "openai/gpt-5-nano:batch": { input: 0.025, output: 0.2, cacheRead: 0.0025, cacheWrite: 0 }, - "openai/gpt-5-pro": { input: 15, output: 120, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-5-pro:batch": { input: 7.5, output: 60, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-5:batch": { input: 0.625, output: 5, cacheRead: 0.0625, cacheWrite: 0 }, - "openai/gpt-5.1": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, - "openai/gpt-5.1-codex": { input: 1.25, output: 10, cacheRead: 0.13, cacheWrite: 0 }, - "openai/gpt-5.1-codex-max": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, - "openai/gpt-5.1-codex-mini": { input: 0.25, output: 2, cacheRead: 0.03, cacheWrite: 0 }, - "openai/gpt-5.1:batch": { input: 0.625, output: 5, cacheRead: 0.0625, cacheWrite: 0 }, - "openai/gpt-5.2": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, - "openai/gpt-5.2-chat": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, - "openai/gpt-5.2-codex": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, - "openai/gpt-5.2-pro": { input: 21, output: 168, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-5.2-pro:batch": { input: 10.5, output: 84, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-5.2:batch": { input: 0.875, output: 7, cacheRead: 0.0875, cacheWrite: 0 }, - "openai/gpt-5.3-codex": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, - "openai/gpt-5.4": { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, - "openai/gpt-5.4-mini": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, - "openai/gpt-5.4-mini:batch": { input: 0.375, output: 2.25, cacheRead: 0.0375, cacheWrite: 0 }, - "openai/gpt-5.4-nano": { input: 0.2, output: 1.25, cacheRead: 0.02, cacheWrite: 0 }, - "openai/gpt-5.4-nano:batch": { input: 0.1, output: 0.625, cacheRead: 0.01, cacheWrite: 0 }, - "openai/gpt-5.4-pro": { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-5.4-pro:batch": { input: 15, output: 90, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-5.4:batch": { input: 1.25, output: 7.5, cacheRead: 0.125, cacheWrite: 0 }, - "openai/gpt-5.5": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, - "openai/gpt-5.5-pro": { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-5.5-pro:batch": { input: 15, output: 90, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-5.5:batch": { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, - "openai/gpt-5.6-luna": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, - "openai/gpt-5.6-luna-pro": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, - "openai/gpt-5.6-luna-pro:batch": { input: 0.1, output: 0.6, cacheRead: 0.01, cacheWrite: 0 }, - "openai/gpt-5.6-luna:batch": { input: 0.1, output: 0.6, cacheRead: 0.01, cacheWrite: 0 }, - "openai/gpt-5.6-sol": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, - "openai/gpt-5.6-sol-pro": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, - "openai/gpt-5.6-sol-pro:batch": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, - "openai/gpt-5.6-sol:batch": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, - "openai/gpt-5.6-terra": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, - "openai/gpt-5.6-terra-pro": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, - "openai/gpt-5.6-terra-pro:batch": { input: 1, output: 6, cacheRead: 0.1, cacheWrite: 0 }, - "openai/gpt-5.6-terra:batch": { input: 1, output: 6, cacheRead: 0.1, cacheWrite: 0 }, - "openai/gpt-6-astra": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, - "openai/gpt-6-astra-pro": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, - "openai/gpt-6-astra-pro:batch": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, - "openai/gpt-6-astra:batch": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, - "openai/gpt-audio": { input: 2.5, output: 10, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-audio-mini": { input: 0.6, output: 2.4, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-chat-latest": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, - "openai/gpt-oss-120b": { input: 0.037, output: 0.17, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-oss-120b:batch": { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, - "openai/gpt-oss-20b": { input: 0.03, output: 0.13, cacheRead: 0.03, cacheWrite: 0 }, - "openai/gpt-oss-safeguard-20b": { input: 0.075, output: 0.3, cacheRead: 0.0375, cacheWrite: 0 }, - "openai/o1": { input: 15, output: 60, cacheRead: 7.5, cacheWrite: 0 }, - "openai/o3": { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, - "openai/o3-mini": { input: 1.1, output: 4.4, cacheRead: 0.55, cacheWrite: 0 }, - "openai/o3-mini-high": { input: 1.1, output: 4.4, cacheRead: 0.55, cacheWrite: 0 }, - "openai/o3-mini:batch": { input: 0.55, output: 2.2, cacheRead: 0.275, cacheWrite: 0 }, - "openai/o3-pro": { input: 20, output: 80, cacheRead: 0, cacheWrite: 0 }, - "openai/o3:batch": { input: 1, output: 4, cacheRead: 0.25, cacheWrite: 0 }, - "openai/o4-mini": { input: 1.1, output: 4.4, cacheRead: 0.275, cacheWrite: 0 }, - "openai/o4-mini-high": { input: 1.1, output: 4.4, cacheRead: 0.275, cacheWrite: 0 }, - "openai/o4-mini:batch": { input: 0.55, output: 2.2, cacheRead: 0.1375, cacheWrite: 0 }, - "openrouter/auto": { input: -1000000, output: -1000000, cacheRead: 0, cacheWrite: 0 }, - "openrouter/auto-beta": { input: -1000000, output: -1000000, cacheRead: 0, cacheWrite: 0 }, - "openrouter/free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "openrouter/fusion": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "poolside/laguna-s-2.1": { input: 0.09, output: 0.18, cacheRead: 0.009, cacheWrite: 0 }, - "poolside/laguna-s-2.1:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "poolside/laguna-xs-2.1": { input: 0.06, output: 0.12, cacheRead: 0.03, cacheWrite: 0 }, - "poolside/laguna-xs-2.1:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen-2.5-72b-instruct": { input: 0.36, output: 0.4, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen-2.5-7b-instruct": { input: 0.1, output: 0.2, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen-plus": { input: 0.26, output: 0.78, cacheRead: 0.052, cacheWrite: 0.325 }, - "qwen/qwen-plus-2025-07-28": { input: 0.26, output: 0.78, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-14b": { input: 0.12, output: 0.24, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-235b-a22b": { input: 0.455, output: 1.82, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-235b-a22b-2507": { input: 0.09, output: 0.55, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-235b-a22b-thinking-2507": { input: 0.23, output: 2.3, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-30b-a3b": { input: 0.12, output: 0.5, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-30b-a3b-instruct-2507": { input: 0.04815, output: 0.19305, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-30b-a3b-thinking-2507": { input: 0.2, output: 2.4, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-32b": { input: 0.08, output: 0.28, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-8b": { input: 0.117, output: 0.455, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-coder": { input: 0.3, output: 1, cacheRead: 0.1, cacheWrite: 0 }, - "qwen/qwen3-coder-30b-a3b-instruct": { input: 0.07, output: 0.28, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-coder-flash": { input: 0.195, output: 0.975, cacheRead: 0.039, cacheWrite: 0.24375 }, - "qwen/qwen3-coder-next": { input: 0.12, output: 0.8, cacheRead: 0.07, cacheWrite: 0 }, - "qwen/qwen3-coder-plus": { input: 0.65, output: 3.25, cacheRead: 0.13, cacheWrite: 0.8125 }, - "qwen/qwen3-max": { input: 0.78, output: 3.9, cacheRead: 0.156, cacheWrite: 0.975 }, - "qwen/qwen3-max-thinking": { input: 0.78, output: 3.9, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-next-80b-a3b-instruct": { input: 0.1, output: 1.1, cacheRead: 0.07, cacheWrite: 0 }, - "qwen/qwen3-next-80b-a3b-thinking": { input: 0.15, output: 1.2, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-vl-235b-a22b-instruct": { input: 0.21, output: 1.9, cacheRead: 0.1, cacheWrite: 0 }, - "qwen/qwen3-vl-235b-a22b-thinking": { input: 0.4, output: 4, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-vl-30b-a3b-instruct": { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-vl-30b-a3b-thinking": { input: 0.2, output: 2.4, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-vl-32b-instruct": { input: 0.104, output: 0.416, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-vl-8b-instruct": { input: 0.117, output: 0.455, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3-vl-8b-thinking": { input: 0.18, output: 2.1, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3.5-122b-a10b": { input: 0.29, output: 2.4, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3.5-27b": { input: 0.195, output: 1.56, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3.5-35b-a3b": { input: 0.08, output: 0.75, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3.5-397b-a17b": { input: 0.55, output: 3.5, cacheRead: 0.225, cacheWrite: 0 }, - "qwen/qwen3.5-9b": { input: 0.1, output: 0.15, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3.5-9b:batch": { input: 0.17, output: 0.25, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3.5-flash-02-23": { input: 0.065, output: 0.26, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3.5-plus-02-15": { input: 0.26, output: 1.56, cacheRead: 0, cacheWrite: 0 }, - "qwen/qwen3.5-plus-20260420": { input: 0.3, output: 1.8, cacheRead: 0, cacheWrite: 0.375 }, - "qwen/qwen3.6-27b": { input: 0.3, output: 2, cacheRead: 0.03, cacheWrite: 0 }, - "qwen/qwen3.6-35b-a3b": { input: 0.1, output: 0.9, cacheRead: 0.05, cacheWrite: 0 }, - "qwen/qwen3.6-flash": { input: 0.1875, output: 1.125, cacheRead: 0, cacheWrite: 0.234375 }, - "qwen/qwen3.6-max-preview": { input: 1.027, output: 6.162, cacheRead: 0, cacheWrite: 1.28375 }, - "qwen/qwen3.6-plus": { input: 0.325, output: 1.95, cacheRead: 0, cacheWrite: 0.40625 }, - "qwen/qwen3.7-flash": { input: 0.03, output: 0.13, cacheRead: 0.006, cacheWrite: 0.038 }, - "qwen/qwen3.7-max": { input: 1.475, output: 4.425, cacheRead: 0.295, cacheWrite: 1.84375 }, - "qwen/qwen3.7-plus": { input: 0.32, output: 1.28, cacheRead: 0.064, cacheWrite: 0.4 }, - "qwen/qwen3.8-2.4t-a95b": { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 0 }, - "qwen/qwen3.8-2.4t-a95b:batch": { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 0 }, - "qwen/qwen3.8-27b": { input: 0.42, output: 3, cacheRead: 0.085, cacheWrite: 0 }, - "qwen/qwen3.8-flash": { input: 0.15, output: 0.47, cacheRead: 0.016, cacheWrite: 0.2 }, - "qwen/qwen3.8-max-0902": { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 2.5 }, - "rekaai/reka-edge": { input: 0.1, output: 0.1, cacheRead: 0, cacheWrite: 0 }, - "relace/relace-search": { input: 1, output: 3, cacheRead: 0, cacheWrite: 0 }, - "sakana/fugu-ultra": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, - "sakana/sakana-namazu": { input: 0.95, output: 4, cacheRead: 0.15, cacheWrite: 0 }, - "sao10k/l3.1-euryale-70b": { input: 0.85, output: 0.85, cacheRead: 0, cacheWrite: 0 }, - "stepfun/step-3.5-flash": { input: 0.1, output: 0.3, cacheRead: 0, cacheWrite: 0 }, - "stepfun/step-3.7-flash": { input: 0.2, output: 1.15, cacheRead: 0.04, cacheWrite: 0 }, - "tencent/hy3": { input: 0.132, output: 0.528, cacheRead: 0.033, cacheWrite: 0 }, - "tencent/hy3-preview": { input: 0.18, output: 0.6, cacheRead: 0.06, cacheWrite: 0 }, - "tencent/hy4-preview": { input: 0.834, output: 2.501, cacheRead: 0.042, cacheWrite: 0 }, - "thedrummer/unslopnemo-12b": { input: 0.4, output: 0.4, cacheRead: 0, cacheWrite: 0 }, - "thinkingmachines/inkling": { input: 1, output: 4.05, cacheRead: 0.17, cacheWrite: 0 }, - "thinkingmachines/inkling-small": { input: 0.45, output: 1.2, cacheRead: 0.1, cacheWrite: 0 }, - "thinkingmachines/inkling-small:batch": { input: 0.5, output: 1.2, cacheRead: 0.1, cacheWrite: 0 }, - "thinkingmachines/inkling-small:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "thinkingmachines/inkling:batch": { input: 1, output: 4.05, cacheRead: 0.17, cacheWrite: 0 }, - "thinkingmachines/inkling:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "upstage/solar-pro-3": { input: 0.15, output: 0.6, cacheRead: 0.015, cacheWrite: 0 }, - "upstage/solar-pro4": { input: 0.03, output: 0.12, cacheRead: 0.006, cacheWrite: 0 }, - "x-ai/grok-4.20": { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, - "x-ai/grok-4.3": { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, - "x-ai/grok-4.3:batch": { input: 1, output: 2, cacheRead: 0.16, cacheWrite: 0 }, - "x-ai/grok-4.5": { input: 2, output: 6, cacheRead: 0.3, cacheWrite: 0 }, - "x-ai/grok-4.6": { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, - "x-ai/grok-build-0.1": { input: 1, output: 2, cacheRead: 0.2, cacheWrite: 0 }, - "xiaomi/mimo-v2.5": { input: 0.14, output: 0.28, cacheRead: 0.0028, cacheWrite: 0 }, - "xiaomi/mimo-v2.5-pro": { input: 0.435, output: 0.87, cacheRead: 0.0036, cacheWrite: 0 }, - "z-ai/glm-4.5": { input: 0.6, output: 2.2, cacheRead: 0.11, cacheWrite: 0 }, - "z-ai/glm-4.5-air": { input: 0.13, output: 0.85, cacheRead: 0.025, cacheWrite: 0 }, - "z-ai/glm-4.5v": { input: 0.6, output: 1.8, cacheRead: 0.11, cacheWrite: 0 }, - "z-ai/glm-4.6": { input: 0.55, output: 2.2, cacheRead: 0.11, cacheWrite: 0 }, - "z-ai/glm-4.6v": { input: 0.3, output: 0.9, cacheRead: 0.055, cacheWrite: 0 }, - "z-ai/glm-4.7": { input: 0.4, output: 1.75, cacheRead: 0.08, cacheWrite: 0 }, - "z-ai/glm-4.7-flash": { input: 0.06, output: 0.4, cacheRead: 0.01, cacheWrite: 0 }, - "z-ai/glm-5": { input: 0.6, output: 1.9, cacheRead: 0.119, cacheWrite: 0 }, - "z-ai/glm-5-turbo": { input: 1.2, output: 4, cacheRead: 0.24, cacheWrite: 0 }, - "z-ai/glm-5.1": { input: 0.966, output: 3.036, cacheRead: 0.1794, cacheWrite: 0 }, - "z-ai/glm-5.2": { input: 0.966, output: 3.036, cacheRead: 0.1932, cacheWrite: 0 }, - "z-ai/glm-5.2:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - "z-ai/glm-5.3": { input: 1.4, output: 4.4, cacheRead: 0.14, cacheWrite: 0 }, - "z-ai/glm-5.3-flash": { input: 0.075, output: 0.25, cacheRead: 0.015, cacheWrite: 0 }, - "z-ai/glm-5.3-flash:batch": { input: 0.15, output: 0.5, cacheRead: 0.03, cacheWrite: 0 }, - "z-ai/glm-5v-turbo": { input: 1.2, output: 4, cacheRead: 0.24, cacheWrite: 0 }, + "amazon-bedrock:amazon.nova-2-lite-v1:0": { input: 0.33, output: 2.75, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:amazon.nova-lite-v1:0": { input: 0.06, output: 0.24, cacheRead: 0.015, cacheWrite: 0 }, + "amazon-bedrock:amazon.nova-micro-v1:0": { input: 0.035, output: 0.14, cacheRead: 0.00875, cacheWrite: 0 }, + "amazon-bedrock:amazon.nova-pro-v1:0": { input: 0.8, output: 3.2, cacheRead: 0.2, cacheWrite: 0 }, + "amazon-bedrock:anthropic.claude-fable-5": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "amazon-bedrock:anthropic.claude-fable-5-1": { input: 10, output: 50, cacheRead: 0.25, cacheWrite: 12.5 }, + "amazon-bedrock:anthropic.claude-haiku-4-5-20251001-v1:0": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "amazon-bedrock:anthropic.claude-opus-4-1-20250805-v1:0": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 }, + "amazon-bedrock:anthropic.claude-opus-4-5-20251101-v1:0": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:anthropic.claude-opus-4-6-v1": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:anthropic.claude-opus-4-7": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:anthropic.claude-opus-4-8": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:anthropic.claude-sonnet-4-5-20250929-v1:0": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "amazon-bedrock:anthropic.claude-sonnet-4-6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "amazon-bedrock:anthropic.claude-sonnet-5": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "amazon-bedrock:au.anthropic.claude-haiku-4-5-20251001-v1:0": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "amazon-bedrock:au.anthropic.claude-opus-4-6-v1": { input: 16.5, output: 82.5, cacheRead: 1.65, cacheWrite: 20.625 }, + "amazon-bedrock:au.anthropic.claude-opus-4-8": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:au.anthropic.claude-opus-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:au.anthropic.claude-sonnet-4-5-20250929-v1:0": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "amazon-bedrock:au.anthropic.claude-sonnet-4-6": { input: 3.3, output: 16.5, cacheRead: 0.33, cacheWrite: 4.125 }, + "amazon-bedrock:au.anthropic.claude-sonnet-5": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "amazon-bedrock:deepseek.r1-v1:0": { input: 1.35, output: 5.4, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:deepseek.v3-v1:0": { input: 0.58, output: 1.68, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:deepseek.v3.2": { input: 0.62, output: 1.85, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:eu.anthropic.claude-fable-5": { input: 11, output: 55, cacheRead: 1.1, cacheWrite: 13.75 }, + "amazon-bedrock:eu.anthropic.claude-haiku-4-5-20251001-v1:0": { input: 1.1, output: 5.5, cacheRead: 0.11, cacheWrite: 1.375 }, + "amazon-bedrock:eu.anthropic.claude-opus-4-5-20251101-v1:0": { input: 5.5, output: 27.5, cacheRead: 0.55, cacheWrite: 6.875 }, + "amazon-bedrock:eu.anthropic.claude-opus-4-6-v1": { input: 5.5, output: 27.5, cacheRead: 0.55, cacheWrite: 6.875 }, + "amazon-bedrock:eu.anthropic.claude-opus-4-7": { input: 5.5, output: 27.5, cacheRead: 0.55, cacheWrite: 6.875 }, + "amazon-bedrock:eu.anthropic.claude-opus-4-8": { input: 5.5, output: 27.5, cacheRead: 0.55, cacheWrite: 6.875 }, + "amazon-bedrock:eu.anthropic.claude-opus-5": { input: 5.5, output: 27.5, cacheRead: 0.55, cacheWrite: 6.875 }, + "amazon-bedrock:eu.anthropic.claude-sonnet-4-5-20250929-v1:0": { input: 3.3, output: 16.5, cacheRead: 0.33, cacheWrite: 4.125 }, + "amazon-bedrock:eu.anthropic.claude-sonnet-4-6": { input: 3.3, output: 16.5, cacheRead: 0.33, cacheWrite: 4.125 }, + "amazon-bedrock:eu.anthropic.claude-sonnet-5": { input: 2.2, output: 11, cacheRead: 0.22, cacheWrite: 2.75 }, + "amazon-bedrock:global.anthropic.claude-fable-5": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "amazon-bedrock:global.anthropic.claude-fable-5-1": { input: 10, output: 50, cacheRead: 0.25, cacheWrite: 12.5 }, + "amazon-bedrock:global.anthropic.claude-haiku-4-5-20251001-v1:0": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "amazon-bedrock:global.anthropic.claude-opus-4-5-20251101-v1:0": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:global.anthropic.claude-opus-4-6-v1": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:global.anthropic.claude-opus-4-7": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:global.anthropic.claude-opus-4-8": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:global.anthropic.claude-opus-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:global.anthropic.claude-sonnet-4-5-20250929-v1:0": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "amazon-bedrock:global.anthropic.claude-sonnet-4-6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "amazon-bedrock:global.anthropic.claude-sonnet-5": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "amazon-bedrock:global.openai.gpt-5.6-luna": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, + "amazon-bedrock:global.openai.gpt-5.6-sol": { input: 4, output: 20, cacheRead: 0.4, cacheWrite: 5 }, + "amazon-bedrock:global.openai.gpt-5.6-terra": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, + "amazon-bedrock:google.gemma-3-27b-it": { input: 0.12, output: 0.2, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:google.gemma-3-4b-it": { input: 0.04, output: 0.08, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:jp.anthropic.claude-haiku-4-5-20251001-v1:0": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "amazon-bedrock:jp.anthropic.claude-opus-4-7": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:jp.anthropic.claude-opus-4-8": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:jp.anthropic.claude-opus-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:jp.anthropic.claude-sonnet-4-5-20250929-v1:0": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "amazon-bedrock:jp.anthropic.claude-sonnet-4-6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "amazon-bedrock:jp.anthropic.claude-sonnet-5": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "amazon-bedrock:meta.llama3-1-70b-instruct-v1:0": { input: 0.72, output: 0.72, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:meta.llama3-1-8b-instruct-v1:0": { input: 0.22, output: 0.22, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:meta.llama3-3-70b-instruct-v1:0": { input: 0.72, output: 0.72, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:meta.llama4-maverick-17b-instruct-v1:0": { input: 0.24, output: 0.97, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:meta.llama4-scout-17b-instruct-v1:0": { input: 0.17, output: 0.66, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:minimax.minimax-m2": { input: 0.3, output: 1.2, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:minimax.minimax-m2.1": { input: 0.3, output: 1.2, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:minimax.minimax-m2.5": { input: 0.3, output: 1.2, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:mistral.devstral-2-123b": { input: 0.4, output: 2, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:mistral.magistral-small-2509": { input: 0.5, output: 1.5, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:mistral.ministral-3-14b-instruct": { input: 0.2, output: 0.2, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:mistral.ministral-3-3b-instruct": { input: 0.1, output: 0.1, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:mistral.ministral-3-8b-instruct": { input: 0.15, output: 0.15, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:mistral.mistral-large-3-675b-instruct": { input: 0.5, output: 1.5, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:mistral.pixtral-large-2502-v1:0": { input: 2, output: 6, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:mistral.voxtral-mini-3b-2507": { input: 0.04, output: 0.04, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:mistral.voxtral-small-24b-2507": { input: 0.15, output: 0.35, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:moonshot.kimi-k2-thinking": { input: 0.6, output: 2.5, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:moonshotai.kimi-k2.5": { input: 0.6, output: 3, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:nvidia.nemotron-nano-12b-v2": { input: 0.2, output: 0.6, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:nvidia.nemotron-nano-3-30b": { input: 0.06, output: 0.24, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:nvidia.nemotron-nano-9b-v2": { input: 0.06, output: 0.23, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:nvidia.nemotron-super-3-120b": { input: 0.15, output: 0.65, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:openai.gpt-5.4": { input: 2.75, output: 16.5, cacheRead: 0.275, cacheWrite: 0 }, + "amazon-bedrock:openai.gpt-5.5": { input: 5.5, output: 33, cacheRead: 0.55, cacheWrite: 0 }, + "amazon-bedrock:openai.gpt-5.6-luna": { input: 0.22, output: 1.32, cacheRead: 0.022, cacheWrite: 0.275 }, + "amazon-bedrock:openai.gpt-5.6-sol": { input: 4.4, output: 22, cacheRead: 0.44, cacheWrite: 5.5 }, + "amazon-bedrock:openai.gpt-5.6-terra": { input: 2.2, output: 13.2, cacheRead: 0.22, cacheWrite: 2.75 }, + "amazon-bedrock:openai.gpt-oss-120b": { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:openai.gpt-oss-120b-1:0": { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:openai.gpt-oss-20b": { input: 0.07, output: 0.3, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:openai.gpt-oss-20b-1:0": { input: 0.07, output: 0.3, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:openai.gpt-oss-safeguard-120b": { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:openai.gpt-oss-safeguard-20b": { input: 0.07, output: 0.2, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:qwen.qwen3-235b-a22b-2507-v1:0": { input: 0.22, output: 0.88, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:qwen.qwen3-32b-v1:0": { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:qwen.qwen3-coder-30b-a3b-v1:0": { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:qwen.qwen3-coder-480b-a35b-v1:0": { input: 0.22, output: 1.8, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:qwen.qwen3-coder-next": { input: 0.22, output: 1.8, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:qwen.qwen3-next-80b-a3b": { input: 0.14, output: 1.4, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:qwen.qwen3-vl-235b-a22b": { input: 0.3, output: 1.5, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:us.anthropic.claude-fable-5": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "amazon-bedrock:us.anthropic.claude-fable-5-1": { input: 11, output: 55, cacheRead: 0.275, cacheWrite: 13.75 }, + "amazon-bedrock:us.anthropic.claude-haiku-4-5-20251001-v1:0": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "amazon-bedrock:us.anthropic.claude-opus-4-1-20250805-v1:0": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 }, + "amazon-bedrock:us.anthropic.claude-opus-4-5-20251101-v1:0": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:us.anthropic.claude-opus-4-6-v1": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:us.anthropic.claude-opus-4-7": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:us.anthropic.claude-opus-4-8": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:us.anthropic.claude-opus-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "amazon-bedrock:us.anthropic.claude-sonnet-4-5-20250929-v1:0": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "amazon-bedrock:us.anthropic.claude-sonnet-4-6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "amazon-bedrock:us.anthropic.claude-sonnet-5": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "amazon-bedrock:us.deepseek.r1-v1:0": { input: 1.35, output: 5.4, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:us.meta.llama4-maverick-17b-instruct-v1:0": { input: 0.24, output: 0.97, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:us.meta.llama4-scout-17b-instruct-v1:0": { input: 0.17, output: 0.66, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:writer.palmyra-x4-v1:0": { input: 2.5, output: 10, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:writer.palmyra-x5-v1:0": { input: 0.6, output: 6, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:xai.grok-4.3": { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, + "amazon-bedrock:xai.grok-4.6": { input: 2.2, output: 6.6, cacheRead: 0.55, cacheWrite: 0 }, + "amazon-bedrock:zai.glm-4.7": { input: 0.6, output: 2.2, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:zai.glm-4.7-flash": { input: 0.07, output: 0.4, cacheRead: 0, cacheWrite: 0 }, + "amazon-bedrock:zai.glm-5": { input: 1, output: 3.2, cacheRead: 0, cacheWrite: 0 }, + "ant-ling:Ling-2.6-1T": { input: 0.06, output: 0.25, cacheRead: 0, cacheWrite: 0 }, + "ant-ling:Ling-2.6-flash": { input: 0.01, output: 0.02, cacheRead: 0, cacheWrite: 0 }, + "ant-ling:Ring-2.6-1T": { input: 0.06, output: 0.25, cacheRead: 0, cacheWrite: 0 }, + "anthropic:claude-fable-5": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "anthropic:claude-fable-5-1": { input: 10, output: 50, cacheRead: 0.25, cacheWrite: 12.5 }, + "anthropic:claude-haiku-4-5": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "anthropic:claude-haiku-4-5-20251001": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "anthropic:claude-opus-4-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "anthropic:claude-opus-4-5-20251101": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "anthropic:claude-opus-4-6": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "anthropic:claude-opus-4-7": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "anthropic:claude-opus-4-8": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "anthropic:claude-opus-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "anthropic:claude-sonnet-4-5": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "anthropic:claude-sonnet-4-5-20250929": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "anthropic:claude-sonnet-4-6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "anthropic:claude-sonnet-5": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "azure-openai-responses:gpt-4": { input: 30, output: 60, cacheRead: 0, cacheWrite: 0 }, + "azure-openai-responses:gpt-4-turbo": { input: 10, output: 30, cacheRead: 0, cacheWrite: 0 }, + "azure-openai-responses:gpt-4.1": { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, + "azure-openai-responses:gpt-4.1-mini": { input: 0.4, output: 1.6, cacheRead: 0.1, cacheWrite: 0 }, + "azure-openai-responses:gpt-4.1-nano": { input: 0.1, output: 0.4, cacheRead: 0.025, cacheWrite: 0 }, + "azure-openai-responses:gpt-4o": { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, + "azure-openai-responses:gpt-4o-2024-05-13": { input: 5, output: 15, cacheRead: 0, cacheWrite: 0 }, + "azure-openai-responses:gpt-4o-2024-08-06": { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, + "azure-openai-responses:gpt-4o-2024-11-20": { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, + "azure-openai-responses:gpt-4o-mini": { input: 0.15, output: 0.6, cacheRead: 0.075, cacheWrite: 0 }, + "azure-openai-responses:gpt-5": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "azure-openai-responses:gpt-5-chat-latest": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "azure-openai-responses:gpt-5-mini": { input: 0.25, output: 2, cacheRead: 0.025, cacheWrite: 0 }, + "azure-openai-responses:gpt-5-nano": { input: 0.05, output: 0.4, cacheRead: 0.005, cacheWrite: 0 }, + "azure-openai-responses:gpt-5-pro": { input: 15, output: 120, cacheRead: 0, cacheWrite: 0 }, + "azure-openai-responses:gpt-5.1": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "azure-openai-responses:gpt-5.2": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "azure-openai-responses:gpt-5.2-chat-latest": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "azure-openai-responses:gpt-5.2-pro": { input: 21, output: 168, cacheRead: 0, cacheWrite: 0 }, + "azure-openai-responses:gpt-5.3-chat-latest": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "azure-openai-responses:gpt-5.3-codex": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "azure-openai-responses:gpt-5.3-codex-spark": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "azure-openai-responses:gpt-5.4": { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, + "azure-openai-responses:gpt-5.4-mini": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, + "azure-openai-responses:gpt-5.4-nano": { input: 0.2, output: 1.25, cacheRead: 0.02, cacheWrite: 0 }, + "azure-openai-responses:gpt-5.4-pro": { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, + "azure-openai-responses:gpt-5.5": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, + "azure-openai-responses:gpt-5.5-pro": { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, + "azure-openai-responses:gpt-5.6-luna": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, + "azure-openai-responses:gpt-5.6-sol": { input: 4, output: 20, cacheRead: 0.4, cacheWrite: 5 }, + "azure-openai-responses:gpt-5.6-terra": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, + "azure-openai-responses:gpt-6-astra": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "azure-openai-responses:gpt-realtime-2.1": { input: 4, output: 24, cacheRead: 0.4, cacheWrite: 0 }, + "azure-openai-responses:o1": { input: 15, output: 60, cacheRead: 7.5, cacheWrite: 0 }, + "azure-openai-responses:o1-pro": { input: 150, output: 600, cacheRead: 0, cacheWrite: 0 }, + "azure-openai-responses:o3": { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, + "azure-openai-responses:o3-mini": { input: 1.1, output: 4.4, cacheRead: 0.55, cacheWrite: 0 }, + "azure-openai-responses:o3-pro": { input: 20, output: 80, cacheRead: 0, cacheWrite: 0 }, + "azure-openai-responses:o4-mini": { input: 1.1, output: 4.4, cacheRead: 0.275, cacheWrite: 0 }, + "baseten:deepseek-ai/DeepSeek-V4-Flash-0731": { input: 0.13, output: 0.26, cacheRead: 0.028, cacheWrite: 0 }, + "baseten:deepseek-ai/DeepSeek-V4-Pro": { input: 1.74, output: 3.48, cacheRead: 0.145, cacheWrite: 0 }, + "baseten:deepseek-ai/DeepSeek-V4-Pro-0813": { input: 1.32, output: 3.96, cacheRead: 0, cacheWrite: 0 }, + "baseten:moonshotai/Kimi-K2.5": { input: 0.6, output: 3, cacheRead: 0.12, cacheWrite: 0 }, + "baseten:moonshotai/Kimi-K2.6": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, + "baseten:moonshotai/Kimi-K2.7-Code": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, + "baseten:moonshotai/Kimi-K3": { input: 3, output: 15, cacheRead: 0, cacheWrite: 0 }, + "baseten:nvidia/Nemotron-120B-A12B": { input: 0.3, output: 0.75, cacheRead: 0.06, cacheWrite: 0 }, + "baseten:nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B": { input: 0.6, output: 2.4, cacheRead: 0.12, cacheWrite: 0 }, + "baseten:openai/gpt-oss-120b": { input: 0.1, output: 0.5, cacheRead: 0, cacheWrite: 0 }, + "baseten:thinkingmachines/inkling": { input: 1, output: 4.05, cacheRead: 0, cacheWrite: 0 }, + "baseten:thinkingmachines/inkling-small": { input: 0.5, output: 1.2, cacheRead: 0.1, cacheWrite: 0 }, + "baseten:zai-org/GLM-4.7": { input: 0.6, output: 2.2, cacheRead: 0.12, cacheWrite: 0 }, + "baseten:zai-org/GLM-5": { input: 0.95, output: 3.15, cacheRead: 0.2, cacheWrite: 0 }, + "baseten:zai-org/GLM-5.1": { input: 1.3, output: 4.3, cacheRead: 0.26, cacheWrite: 0 }, + "baseten:zai-org/GLM-5.2": { input: 1.4, output: 4.4, cacheRead: 0.3, cacheWrite: 0 }, + "baseten:zai-org/GLM-5.2-Fast": { input: 2.1, output: 6.6, cacheRead: 0.21, cacheWrite: 0 }, + "baseten:zai-org/GLM-5.3": { input: 1.4, output: 4.4, cacheRead: 0.14, cacheWrite: 0 }, + "baseten:zai-org/GLM-5.3-Fast": { input: 2.1, output: 6.6, cacheRead: 0, cacheWrite: 0 }, + "baseten:zai-org/GLM-5.3-Flash": { input: 0.15, output: 0.5, cacheRead: 0, cacheWrite: 0 }, + "cerebras:gemma-4-31b": { input: 0.99, output: 1.49, cacheRead: 0, cacheWrite: 0 }, + "cerebras:gpt-oss-120b": { input: 0.35, output: 0.75, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-ai-gateway:claude-fable-5": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "cloudflare-ai-gateway:claude-fable-5.1": { input: 10, output: 50, cacheRead: 0.25, cacheWrite: 12.5 }, + "cloudflare-ai-gateway:claude-haiku-4.5": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "cloudflare-ai-gateway:claude-opus-4.5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "cloudflare-ai-gateway:claude-opus-4.6": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "cloudflare-ai-gateway:claude-opus-4.7": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "cloudflare-ai-gateway:claude-opus-4.8": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "cloudflare-ai-gateway:claude-opus-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "cloudflare-ai-gateway:claude-sonnet-4.5": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "cloudflare-ai-gateway:claude-sonnet-4.6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "cloudflare-ai-gateway:claude-sonnet-5": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "cloudflare-ai-gateway:gpt-4.1": { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, + "cloudflare-ai-gateway:gpt-4.1-mini": { input: 0.4, output: 1.6, cacheRead: 0.1, cacheWrite: 0 }, + "cloudflare-ai-gateway:gpt-4.1-nano": { input: 0.1, output: 0.4, cacheRead: 0.025, cacheWrite: 0 }, + "cloudflare-ai-gateway:gpt-4o": { input: 1.25, output: 5, cacheRead: 0.625, cacheWrite: 0 }, + "cloudflare-ai-gateway:gpt-4o-mini": { input: 0.075, output: 0.3, cacheRead: 0.0375, cacheWrite: 0 }, + "cloudflare-ai-gateway:gpt-5": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "cloudflare-ai-gateway:gpt-5-mini": { input: 0.25, output: 2, cacheRead: 0.025, cacheWrite: 0 }, + "cloudflare-ai-gateway:gpt-5-nano": { input: 0.05, output: 0.4, cacheRead: 0.005, cacheWrite: 0 }, + "cloudflare-ai-gateway:gpt-5.1": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "cloudflare-ai-gateway:gpt-5.4": { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, + "cloudflare-ai-gateway:gpt-5.4-mini": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, + "cloudflare-ai-gateway:gpt-5.4-nano": { input: 0.2, output: 1.25, cacheRead: 0.02, cacheWrite: 0 }, + "cloudflare-ai-gateway:gpt-5.4-pro": { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-ai-gateway:gpt-5.5": { input: 5, output: 30, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-ai-gateway:gpt-5.5-pro": { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-ai-gateway:gpt-5.6-luna": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, + "cloudflare-ai-gateway:gpt-5.6-sol": { input: 2, output: 10, cacheRead: 0.25, cacheWrite: 3.125 }, + "cloudflare-ai-gateway:gpt-5.6-terra": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, + "cloudflare-ai-gateway:o3": { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, + "cloudflare-ai-gateway:o3-mini": { input: 1.1, output: 4.4, cacheRead: 0.55, cacheWrite: 0 }, + "cloudflare-ai-gateway:o4-mini": { input: 1.1, output: 4.4, cacheRead: 0.275, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/deepseek-ai/deepseek-v4-flash-0731": { input: 0.44, output: 1.32, cacheRead: 0.014, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/deepseek-ai/deepseek-v4-pro-0813": { input: 1.32, output: 3.96, cacheRead: 0.044, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/google/gemma-4-26b-a4b-it": { input: 0.1, output: 0.3, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/ibm-granite/granite-4.0-h-micro": { input: 0.017, output: 0.112, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast": { input: 0.293, output: 2.253, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/meta/llama-4-scout-17b-16e-instruct": { input: 0.27, output: 0.85, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/mistralai/mistral-small-3.1-24b-instruct": { input: 0.351, output: 0.555, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/moonshotai/kimi-k2.6": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/moonshotai/kimi-k2.7-code": { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/nvidia/nemotron-3-120b-a12b": { input: 0.5, output: 1.5, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/openai/gpt-oss-120b": { input: 0.35, output: 0.75, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/openai/gpt-oss-20b": { input: 0.2, output: 0.3, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/qwen/qwen3-30b-a3b-fp8": { input: 0.0509, output: 0.335, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/qwen/qwen3.8-27b": { input: 0.45, output: 3.2, cacheRead: 0.05, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/zai-org/glm-4.7-flash": { input: 0.0605, output: 0.4, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/zai-org/glm-5.2": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/zai-org/glm-5.3": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "cloudflare-ai-gateway:workers-ai/@cf/zai-org/glm-5.3-flash": { input: 0.15, output: 0.5, cacheRead: 0.03, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/deepseek-ai/deepseek-v4-flash-0731": { input: 0.44, output: 1.32, cacheRead: 0.014, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/deepseek-ai/deepseek-v4-pro-0813": { input: 1.32, output: 3.96, cacheRead: 0.044, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/google/gemma-4-26b-a4b-it": { input: 0.1, output: 0.3, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/ibm-granite/granite-4.0-h-micro": { input: 0.017, output: 0.112, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/meta/llama-3.3-70b-instruct-fp8-fast": { input: 0.293, output: 2.253, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/meta/llama-4-scout-17b-16e-instruct": { input: 0.27, output: 0.85, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/mistralai/mistral-small-3.1-24b-instruct": { input: 0.351, output: 0.555, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/moonshotai/kimi-k2.6": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/moonshotai/kimi-k2.7-code": { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/nvidia/nemotron-3-120b-a12b": { input: 0.5, output: 1.5, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/openai/gpt-oss-120b": { input: 0.35, output: 0.75, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/openai/gpt-oss-20b": { input: 0.2, output: 0.3, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/qwen/qwen3-30b-a3b-fp8": { input: 0.0509, output: 0.335, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/qwen/qwen3.8-27b": { input: 0.45, output: 3.2, cacheRead: 0.05, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/zai-org/glm-4.7-flash": { input: 0.0605, output: 0.4, cacheRead: 0, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/zai-org/glm-5.2": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/zai-org/glm-5.3": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "cloudflare-workers-ai:@cf/zai-org/glm-5.3-flash": { input: 0.15, output: 0.5, cacheRead: 0.03, cacheWrite: 0 }, + "deepseek:deepseek-v4-flash": { input: 0.14, output: 0.28, cacheRead: 0.0028, cacheWrite: 0 }, + "deepseek:deepseek-v4-flash-vision-exp": { input: 0.14, output: 0.28, cacheRead: 0.0028, cacheWrite: 0 }, + "deepseek:deepseek-v4-pro": { input: 0.435, output: 0.87, cacheRead: 0.003625, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/deepseek-v4-flash-0731": { input: 0.22, output: 0.66, cacheRead: 0.007, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/deepseek-v4-flash-vision-exp": { input: 0.22, output: 0.66, cacheRead: 0.007, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/deepseek-v4-pro-0813": { input: 1.32, output: 3.96, cacheRead: 0.044, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/glm-5p2": { input: 1.4, output: 4.4, cacheRead: 0.14, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/glm-5p3": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/glm-5p3-flash": { input: 0.15, output: 0.5, cacheRead: 0.03, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/gpt-oss-120b": { input: 0.15, output: 0.6, cacheRead: 0.015, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/inkling": { input: 1, output: 4.05, cacheRead: 0.17, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/kimi-k2p6": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/kimi-k2p7-code": { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/kimi-k3": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/minimax-m3": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/muse-glimmer-30b": { input: 0.35, output: 1.5, cacheRead: 0.04, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/nemotron-3-ultra-nvfp4": { input: 0.6, output: 2.4, cacheRead: 0.119, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/nemotron-lightning-3p5-30b-a3b": { input: 0.05, output: 0.2, cacheRead: 0.01, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/qwen3p7-plus": { input: 0.4, output: 1.6, cacheRead: 0.08, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/qwen3p8-2p4t-a95b": { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 0 }, + "fireworks:accounts/fireworks/models/qwen3p8-max": { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 0 }, + "fireworks:accounts/fireworks/routers/glm-5p2-fast": { input: 2.1, output: 6.6, cacheRead: 0.21, cacheWrite: 0 }, + "fireworks:accounts/fireworks/routers/kimi-k3-fast": { input: 4.5, output: 22.5, cacheRead: 0.45, cacheWrite: 0 }, + "github-copilot:claude-fable-5": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "github-copilot:claude-fable-5.1": { input: 10, output: 50, cacheRead: 0.25, cacheWrite: 12.5 }, + "github-copilot:claude-haiku-4.5": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "github-copilot:claude-opus-4.7": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "github-copilot:claude-opus-4.8": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "github-copilot:claude-opus-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "github-copilot:claude-sonnet-4.6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "github-copilot:claude-sonnet-5": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "github-copilot:gemini-3.5-flash": { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0 }, + "github-copilot:gemini-3.6-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, + "github-copilot:gemini-3.7-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, + "github-copilot:gemini-3.8-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, + "github-copilot:gpt-5-mini": { input: 0.25, output: 2, cacheRead: 0.025, cacheWrite: 0 }, + "github-copilot:gpt-5.3-codex": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "github-copilot:gpt-5.4": { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, + "github-copilot:gpt-5.4-mini": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, + "github-copilot:gpt-5.4-nano": { input: 0.2, output: 1.25, cacheRead: 0.02, cacheWrite: 0 }, + "github-copilot:gpt-5.5": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, + "github-copilot:gpt-5.6-luna": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, + "github-copilot:gpt-5.6-sol": { input: 4, output: 20, cacheRead: 0.4, cacheWrite: 5 }, + "github-copilot:gpt-5.6-terra": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, + "github-copilot:gpt-6-astra": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "github-copilot:grok-4.5": { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, + "github-copilot:grok-4.6": { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, + "github-copilot:kimi-k2.7-code": { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, + "github-copilot:kimi-k3": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, + "github-copilot:mai-code-1-flash-picker": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, + "github-copilot:mai-code-1.1-flash": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0 }, + "google-vertex:gemini-2.5-flash": { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0 }, + "google-vertex:gemini-2.5-flash-lite": { input: 0.1, output: 0.4, cacheRead: 0.01, cacheWrite: 0 }, + "google-vertex:gemini-2.5-pro": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "google-vertex:gemini-3-flash-preview": { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0 }, + "google-vertex:gemini-3.1-flash-lite": { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0 }, + "google-vertex:gemini-3.1-pro-preview": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 }, + "google-vertex:gemini-3.1-pro-preview-customtools": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 }, + "google-vertex:gemini-3.5-flash": { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0 }, + "google-vertex:gemini-3.5-flash-lite": { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0 }, + "google-vertex:gemini-3.6-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, + "google-vertex:gemini-3.7-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, + "google-vertex:gemini-3.8-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, + "google-vertex:gemini-flash-latest": { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0 }, + "google-vertex:gemini-flash-lite-latest": { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0 }, + "google:deep-research-max-preview-04-2026": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 }, + "google:deep-research-preview-04-2026": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 }, + "google:gemini-2.5-computer-use-preview-10-2025": { input: 1.25, output: 10, cacheRead: 0, cacheWrite: 0 }, + "google:gemini-2.5-flash": { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0 }, + "google:gemini-2.5-flash-lite": { input: 0.1, output: 0.4, cacheRead: 0.01, cacheWrite: 0 }, + "google:gemini-2.5-pro": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "google:gemini-3-flash-preview": { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0 }, + "google:gemini-3.1-flash-lite": { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0 }, + "google:gemini-3.1-flash-lite-image": { input: 0.25, output: 30, cacheRead: 0, cacheWrite: 0 }, + "google:gemini-3.1-flash-lite-preview": { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0 }, + "google:gemini-3.1-flash-live-preview": { input: 0.75, output: 4.5, cacheRead: 0, cacheWrite: 0 }, + "google:gemini-3.1-pro-preview": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 }, + "google:gemini-3.1-pro-preview-customtools": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 }, + "google:gemini-3.5-flash": { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0 }, + "google:gemini-3.5-flash-lite": { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0 }, + "google:gemini-3.6-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, + "google:gemini-3.7-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, + "google:gemini-3.8-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, + "google:gemini-flash-latest": { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0 }, + "google:gemini-flash-lite-latest": { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0 }, + "google:gemma-4-26b-a4b-it": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "google:gemma-4-31b-it": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "groq:llama-3.1-8b-instant": { input: 0.05, output: 0.08, cacheRead: 0, cacheWrite: 0 }, + "groq:llama-3.3-70b-versatile": { input: 0.59, output: 0.79, cacheRead: 0, cacheWrite: 0 }, + "groq:openai/gpt-oss-120b": { input: 0.15, output: 0.6, cacheRead: 0.075, cacheWrite: 0 }, + "groq:openai/gpt-oss-20b": { input: 0.075, output: 0.3, cacheRead: 0.0375, cacheWrite: 0 }, + "groq:openai/gpt-oss-safeguard-20b": { input: 0.075, output: 0.3, cacheRead: 0, cacheWrite: 0 }, + "groq:qwen/qwen3.6-27b": { input: 0.6, output: 3, cacheRead: 0.3, cacheWrite: 0 }, + "groq:qwen/qwen3.8-27b": { input: 0.8, output: 4, cacheRead: 0, cacheWrite: 0 }, + "huggingface:deepseek-ai/DeepSeek-R1": { input: 0.7, output: 2.5, cacheRead: 0, cacheWrite: 0 }, + "huggingface:deepseek-ai/DeepSeek-R1-0528": { input: 3, output: 5, cacheRead: 0, cacheWrite: 0 }, + "huggingface:deepseek-ai/DeepSeek-V3": { input: 0.4, output: 1.3, cacheRead: 0, cacheWrite: 0 }, + "huggingface:deepseek-ai/DeepSeek-V3-0324": { input: 0.27, output: 1.12, cacheRead: 0, cacheWrite: 0 }, + "huggingface:deepseek-ai/DeepSeek-V3.1": { input: 0.27, output: 1, cacheRead: 0, cacheWrite: 0 }, + "huggingface:deepseek-ai/DeepSeek-V3.2": { input: 0.28, output: 0.4, cacheRead: 0, cacheWrite: 0 }, + "huggingface:deepseek-ai/DeepSeek-V4-Flash": { input: 0.14, output: 0.28, cacheRead: 0, cacheWrite: 0 }, + "huggingface:deepseek-ai/DeepSeek-V4-Flash-0731": { input: 0.14, output: 0.28, cacheRead: 0, cacheWrite: 0 }, + "huggingface:deepseek-ai/DeepSeek-V4-Flash-Vision-Exp": { input: 0.44, output: 1.32, cacheRead: 0, cacheWrite: 0 }, + "huggingface:deepseek-ai/DeepSeek-V4-Pro": { input: 0.435, output: 0.87, cacheRead: 0.003625, cacheWrite: 0 }, + "huggingface:deepseek-ai/DeepSeek-V4-Pro-0813": { input: 1.32, output: 3.96, cacheRead: 0, cacheWrite: 0 }, + "huggingface:google/gemma-4-26B-A4B-it": { input: 0.13, output: 0.4, cacheRead: 0, cacheWrite: 0 }, + "huggingface:google/gemma-4-31B-it": { input: 0.14, output: 0.4, cacheRead: 0, cacheWrite: 0 }, + "huggingface:meta-llama/Llama-3.1-8B-Instruct": { input: 0.06, output: 0.06, cacheRead: 0, cacheWrite: 0 }, + "huggingface:meta-llama/Llama-3.3-70B-Instruct": { input: 0.59, output: 0.79, cacheRead: 0, cacheWrite: 0 }, + "huggingface:MiniMaxAI/MiniMax-M2": { input: 0.3, output: 1.2, cacheRead: 0, cacheWrite: 0 }, + "huggingface:MiniMaxAI/MiniMax-M2.1": { input: 0.3, output: 1.2, cacheRead: 0, cacheWrite: 0 }, + "huggingface:MiniMaxAI/MiniMax-M2.5": { input: 0.3, output: 1.2, cacheRead: 0.03, cacheWrite: 0 }, + "huggingface:MiniMaxAI/MiniMax-M2.7": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "huggingface:MiniMaxAI/MiniMax-M3": { input: 0.3, output: 1.2, cacheRead: 0, cacheWrite: 0 }, + "huggingface:moonshotai/Kimi-K2-Instruct": { input: 1, output: 3, cacheRead: 0, cacheWrite: 0 }, + "huggingface:moonshotai/Kimi-K2-Instruct-0905": { input: 1, output: 3, cacheRead: 0, cacheWrite: 0 }, + "huggingface:moonshotai/Kimi-K2-Thinking": { input: 0.6, output: 2.5, cacheRead: 0.15, cacheWrite: 0 }, + "huggingface:moonshotai/Kimi-K2.5": { input: 0.6, output: 3, cacheRead: 0.1, cacheWrite: 0 }, + "huggingface:moonshotai/Kimi-K2.6": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, + "huggingface:moonshotai/Kimi-K2.7-Code": { input: 0.95, output: 4, cacheRead: 0, cacheWrite: 0 }, + "huggingface:moonshotai/Kimi-K3": { input: 3, output: 15, cacheRead: 0, cacheWrite: 0 }, + "huggingface:openai/gpt-oss-120b": { input: 0.25, output: 0.69, cacheRead: 0, cacheWrite: 0 }, + "huggingface:openai/gpt-oss-20b": { input: 0.1, output: 0.5, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen2.5-Coder-32B-Instruct": { input: 0.06, output: 0.2, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3-235B-A22B": { input: 0.2, output: 0.8, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3-235B-A22B-Instruct-2507": { input: 0.855, output: 2.565, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3-235B-A22B-Thinking-2507": { input: 0.3, output: 3, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3-30B-A3B": { input: 0.12, output: 0.5, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3-32B": { input: 0.29, output: 0.59, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3-Coder-30B-A3B-Instruct": { input: 0.07, output: 0.26, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3-Coder-480B-A35B-Instruct": { input: 2, output: 2, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3-Coder-Next": { input: 0.2, output: 1.5, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3-Next-80B-A3B-Instruct": { input: 0.25, output: 1, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3-Next-80B-A3B-Thinking": { input: 0.3, output: 2, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3-VL-235B-A22B-Instruct": { input: 0.3, output: 1.5, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3-VL-235B-A22B-Thinking": { input: 0.98, output: 3.95, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3.5-122B-A10B": { input: 0.4, output: 3.2, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3.5-27B": { input: 0.3, output: 2.4, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3.5-35B-A3B": { input: 0.25, output: 2, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3.5-397B-A17B": { input: 0.6, output: 3.6, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3.5-9B": { input: 0.17, output: 0.25, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3.6-27B": { input: 0.47, output: 3.19, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3.6-35B-A3B": { input: 0.15, output: 0.95, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3.8-2.4T-A95B": { input: 2.5, output: 6.25, cacheRead: 0, cacheWrite: 0 }, + "huggingface:Qwen/Qwen3.8-27B": { input: 0.4, output: 3, cacheRead: 0, cacheWrite: 0 }, + "huggingface:stepfun-ai/Step-3.5-Flash": { input: 0.1, output: 0.3, cacheRead: 0, cacheWrite: 0 }, + "huggingface:stepfun-ai/Step-3.7-Flash": { input: 0.2, output: 1.15, cacheRead: 0, cacheWrite: 0 }, + "huggingface:tencent/Hy3": { input: 0.14, output: 0.58, cacheRead: 0, cacheWrite: 0 }, + "huggingface:thinkingmachines/Inkling": { input: 1, output: 4.05, cacheRead: 0, cacheWrite: 0 }, + "huggingface:thinkingmachines/Inkling-Small": { input: 0.5, output: 1.2, cacheRead: 0, cacheWrite: 0 }, + "huggingface:XiaomiMiMo/MiMo-V2-Flash": { input: 0.1, output: 0.3, cacheRead: 0, cacheWrite: 0 }, + "huggingface:XiaomiMiMo/MiMo-V2.5": { input: 0.4, output: 2, cacheRead: 0, cacheWrite: 0 }, + "huggingface:XiaomiMiMo/MiMo-V2.5-Pro": { input: 1, output: 3, cacheRead: 0, cacheWrite: 0 }, + "huggingface:zai-org/GLM-4.5": { input: 0.6, output: 2.2, cacheRead: 0, cacheWrite: 0 }, + "huggingface:zai-org/GLM-4.5-Air": { input: 0.13, output: 0.85, cacheRead: 0, cacheWrite: 0 }, + "huggingface:zai-org/GLM-4.5V": { input: 0.6, output: 1.8, cacheRead: 0, cacheWrite: 0 }, + "huggingface:zai-org/GLM-4.6": { input: 0.55, output: 2.2, cacheRead: 0, cacheWrite: 0 }, + "huggingface:zai-org/GLM-4.6V-Flash": { input: 0.3, output: 0.9, cacheRead: 0, cacheWrite: 0 }, + "huggingface:zai-org/GLM-4.7": { input: 0.6, output: 2.2, cacheRead: 0.11, cacheWrite: 0 }, + "huggingface:zai-org/GLM-4.7-Flash": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "huggingface:zai-org/GLM-5": { input: 1, output: 3.2, cacheRead: 0.2, cacheWrite: 0 }, + "huggingface:zai-org/GLM-5.1": { input: 1, output: 3.2, cacheRead: 0.2, cacheWrite: 0 }, + "huggingface:zai-org/GLM-5.2": { input: 1.4, output: 4.4, cacheRead: 0, cacheWrite: 0 }, + "huggingface:zai-org/GLM-5.3": { input: 1.4, output: 4.4, cacheRead: 0, cacheWrite: 0 }, + "huggingface:zai-org/GLM-5.3-Flash": { input: 0.15, output: 0.5, cacheRead: 0, cacheWrite: 0 }, + "kimi-coding:k3": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, + "kimi-coding:k3-256k": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "kimi-coding:kimi-for-coding": { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, + "kimi-coding:kimi-for-coding-highspeed": { input: 1.9, output: 8, cacheRead: 0.38, cacheWrite: 0 }, + "minimax-cn:MiniMax-M2.7": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0.375 }, + "minimax-cn:MiniMax-M2.7-highspeed": { input: 0.6, output: 2.4, cacheRead: 0.06, cacheWrite: 0.375 }, + "minimax-cn:MiniMax-M3": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "minimax:MiniMax-M2.7": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0.375 }, + "minimax:MiniMax-M2.7-highspeed": { input: 0.6, output: 2.4, cacheRead: 0.06, cacheWrite: 0.375 }, + "minimax:MiniMax-M3": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "mistral:codestral-latest": { input: 0.3, output: 0.9, cacheRead: 0.03, cacheWrite: 0 }, + "mistral:devstral-2512": { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, + "mistral:devstral-latest": { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, + "mistral:devstral-medium-2507": { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, + "mistral:devstral-medium-latest": { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, + "mistral:devstral-small-2505": { input: 0.1, output: 0.3, cacheRead: 0.01, cacheWrite: 0 }, + "mistral:devstral-small-2507": { input: 0.1, output: 0.3, cacheRead: 0.01, cacheWrite: 0 }, + "mistral:labs-devstral-small-2512": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "mistral:magistral-medium-latest": { input: 2, output: 5, cacheRead: 0.2, cacheWrite: 0 }, + "mistral:magistral-small": { input: 0.5, output: 1.5, cacheRead: 0.05, cacheWrite: 0 }, + "mistral:ministral-3b-latest": { input: 0.04, output: 0.04, cacheRead: 0.004, cacheWrite: 0 }, + "mistral:ministral-8b-latest": { input: 0.1, output: 0.1, cacheRead: 0.01, cacheWrite: 0 }, + "mistral:mistral-large-2411": { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 0 }, + "mistral:mistral-large-2512": { input: 0.5, output: 1.5, cacheRead: 0.05, cacheWrite: 0 }, + "mistral:mistral-large-latest": { input: 0.5, output: 1.5, cacheRead: 0.05, cacheWrite: 0 }, + "mistral:mistral-medium-2505": { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, + "mistral:mistral-medium-2508": { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, + "mistral:mistral-medium-2604": { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 0 }, + "mistral:mistral-medium-3.5": { input: 1.5, output: 7.5, cacheRead: 0, cacheWrite: 0 }, + "mistral:mistral-medium-latest": { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 0 }, + "mistral:mistral-nemo": { input: 0.15, output: 0.15, cacheRead: 0.015, cacheWrite: 0 }, + "mistral:mistral-small-2506": { input: 0.1, output: 0.3, cacheRead: 0.01, cacheWrite: 0 }, + "mistral:mistral-small-2603": { input: 0.15, output: 0.6, cacheRead: 0.015, cacheWrite: 0 }, + "mistral:mistral-small-latest": { input: 0.15, output: 0.6, cacheRead: 0.015, cacheWrite: 0 }, + "mistral:open-mistral-7b": { input: 0.25, output: 0.25, cacheRead: 0.025, cacheWrite: 0 }, + "mistral:open-mistral-nemo": { input: 0.15, output: 0.15, cacheRead: 0.015, cacheWrite: 0 }, + "mistral:open-mixtral-8x22b": { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 0 }, + "mistral:open-mixtral-8x7b": { input: 0.7, output: 0.7, cacheRead: 0.07, cacheWrite: 0 }, + "mistral:pixtral-12b": { input: 0.15, output: 0.15, cacheRead: 0.015, cacheWrite: 0 }, + "mistral:pixtral-large-latest": { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 0 }, + "mistral:voxtral-small-latest": { input: 0.1, output: 0.3, cacheRead: 0.01, cacheWrite: 0 }, + "mistral:zai-glm-5-2": { input: 1.4, output: 4.4, cacheRead: 0.14, cacheWrite: 0 }, + "moonshotai-cn:kimi-k2-0711-preview": { input: 0.6, output: 2.5, cacheRead: 0.15, cacheWrite: 0 }, + "moonshotai-cn:kimi-k2-0905-preview": { input: 0.6, output: 2.5, cacheRead: 0.15, cacheWrite: 0 }, + "moonshotai-cn:kimi-k2-thinking": { input: 0.6, output: 2.5, cacheRead: 0.15, cacheWrite: 0 }, + "moonshotai-cn:kimi-k2-thinking-turbo": { input: 1.15, output: 8, cacheRead: 0.15, cacheWrite: 0 }, + "moonshotai-cn:kimi-k2-turbo-preview": { input: 2.4, output: 10, cacheRead: 0.6, cacheWrite: 0 }, + "moonshotai-cn:kimi-k2.5": { input: 0.6, output: 3, cacheRead: 0.1, cacheWrite: 0 }, + "moonshotai-cn:kimi-k2.6": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, + "moonshotai-cn:kimi-k2.7-code": { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, + "moonshotai-cn:kimi-k2.7-code-highspeed": { input: 1.9, output: 8, cacheRead: 0.38, cacheWrite: 0 }, + "moonshotai-cn:kimi-k3": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, + "moonshotai:kimi-k2-0711-preview": { input: 0.6, output: 2.5, cacheRead: 0.15, cacheWrite: 0 }, + "moonshotai:kimi-k2-0905-preview": { input: 0.6, output: 2.5, cacheRead: 0.15, cacheWrite: 0 }, + "moonshotai:kimi-k2-thinking": { input: 0.6, output: 2.5, cacheRead: 0.15, cacheWrite: 0 }, + "moonshotai:kimi-k2-thinking-turbo": { input: 1.15, output: 8, cacheRead: 0.15, cacheWrite: 0 }, + "moonshotai:kimi-k2-turbo-preview": { input: 2.4, output: 10, cacheRead: 0.6, cacheWrite: 0 }, + "moonshotai:kimi-k2.5": { input: 0.6, output: 3, cacheRead: 0.1, cacheWrite: 0 }, + "moonshotai:kimi-k2.6": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, + "moonshotai:kimi-k2.7-code": { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, + "moonshotai:kimi-k2.7-code-highspeed": { input: 1.9, output: 8, cacheRead: 0.38, cacheWrite: 0 }, + "moonshotai:kimi-k3": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, + "nvidia:deepseek-ai/deepseek-v4-flash-0731": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:deepseek-ai/deepseek-v4-pro-0813": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:google/gemma-3-12b-it": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:google/gemma-3-4b-it": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:meta/llama-3.2-11b-vision-instruct": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:meta/llama-3.2-90b-vision-instruct": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:meta/muse-glimmer-30b": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:minimaxai/minimax-m3": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:mistralai/mistral-7b-instruct-v0.3": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:moonshotai/kimi-k2.6": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:moonshotai/kimi-k3": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:nvidia/cosmos-reason2-8b": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:nvidia/llama-3.1-nemotron-70b-instruct": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:nvidia/llama-3.1-nemotron-ultra-253b-v1": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:nvidia/nemotron-3-nano-omni-30b-a3b-reasoning": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:nvidia/nemotron-3-super-120b-a12b": { input: 0.2, output: 0.8, cacheRead: 0, cacheWrite: 0 }, + "nvidia:nvidia/nemotron-3-ultra-550b-a55b": { input: 0.5, output: 2.5, cacheRead: 0.15, cacheWrite: 0 }, + "nvidia:nvidia/nemotron-3.5-lightning-30b-a3b": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:openai/gpt-oss-20b": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "nvidia:poolside/laguna-xs-2.1": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openai-codex:gpt-5.3-codex-spark": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "openai-codex:gpt-5.4": { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, + "openai-codex:gpt-5.4-mini": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, + "openai-codex:gpt-5.5": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, + "openai-codex:gpt-5.6-luna": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, + "openai-codex:gpt-5.6-sol": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 6.25 }, + "openai-codex:gpt-5.6-terra": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, + "openai-codex:gpt-6-astra": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "openai:gpt-4": { input: 30, output: 60, cacheRead: 0, cacheWrite: 0 }, + "openai:gpt-4-turbo": { input: 10, output: 30, cacheRead: 0, cacheWrite: 0 }, + "openai:gpt-4.1": { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, + "openai:gpt-4.1-mini": { input: 0.4, output: 1.6, cacheRead: 0.1, cacheWrite: 0 }, + "openai:gpt-4.1-nano": { input: 0.1, output: 0.4, cacheRead: 0.025, cacheWrite: 0 }, + "openai:gpt-4o": { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, + "openai:gpt-4o-2024-05-13": { input: 5, output: 15, cacheRead: 0, cacheWrite: 0 }, + "openai:gpt-4o-2024-08-06": { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, + "openai:gpt-4o-2024-11-20": { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, + "openai:gpt-4o-mini": { input: 0.15, output: 0.6, cacheRead: 0.075, cacheWrite: 0 }, + "openai:gpt-5": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "openai:gpt-5-chat-latest": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "openai:gpt-5-mini": { input: 0.25, output: 2, cacheRead: 0.025, cacheWrite: 0 }, + "openai:gpt-5-nano": { input: 0.05, output: 0.4, cacheRead: 0.005, cacheWrite: 0 }, + "openai:gpt-5-pro": { input: 15, output: 120, cacheRead: 0, cacheWrite: 0 }, + "openai:gpt-5.1": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "openai:gpt-5.2": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "openai:gpt-5.2-chat-latest": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "openai:gpt-5.2-pro": { input: 21, output: 168, cacheRead: 0, cacheWrite: 0 }, + "openai:gpt-5.3-chat-latest": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "openai:gpt-5.3-codex": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "openai:gpt-5.3-codex-spark": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "openai:gpt-5.4": { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, + "openai:gpt-5.4-mini": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, + "openai:gpt-5.4-nano": { input: 0.2, output: 1.25, cacheRead: 0.02, cacheWrite: 0 }, + "openai:gpt-5.4-pro": { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, + "openai:gpt-5.5": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, + "openai:gpt-5.5-pro": { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, + "openai:gpt-5.6-luna": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, + "openai:gpt-5.6-sol": { input: 4, output: 20, cacheRead: 0.4, cacheWrite: 5 }, + "openai:gpt-5.6-terra": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, + "openai:gpt-6-astra": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "openai:gpt-realtime-2.1": { input: 4, output: 24, cacheRead: 0.4, cacheWrite: 0 }, + "openai:o1": { input: 15, output: 60, cacheRead: 7.5, cacheWrite: 0 }, + "openai:o1-pro": { input: 150, output: 600, cacheRead: 0, cacheWrite: 0 }, + "openai:o3": { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, + "openai:o3-mini": { input: 1.1, output: 4.4, cacheRead: 0.55, cacheWrite: 0 }, + "openai:o3-pro": { input: 20, output: 80, cacheRead: 0, cacheWrite: 0 }, + "openai:o4-mini": { input: 1.1, output: 4.4, cacheRead: 0.275, cacheWrite: 0 }, + "opencode-go:deepseek-v4-flash": { input: 0.22, output: 0.66, cacheRead: 0.007, cacheWrite: 0 }, + "opencode-go:deepseek-v4-flash-vision-exp": { input: 0.22, output: 0.66, cacheRead: 0.007, cacheWrite: 0 }, + "opencode-go:deepseek-v4-pro": { input: 0.66, output: 1.98, cacheRead: 0.022, cacheWrite: 0 }, + "opencode-go:glm-5.1": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "opencode-go:glm-5.2": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "opencode-go:glm-5.3": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "opencode-go:glm-5.3-flash": { input: 0.075, output: 0.25, cacheRead: 0.015, cacheWrite: 0 }, + "opencode-go:gpt-5.6-luna": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, + "opencode-go:grok-4.6": { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, + "opencode-go:hy3": { input: 0.14, output: 0.58, cacheRead: 0.035, cacheWrite: 0 }, + "opencode-go:hy4-preview": { input: 0.834, output: 2.501, cacheRead: 0.042, cacheWrite: 0 }, + "opencode-go:kimi-k2.6": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, + "opencode-go:kimi-k2.7-code": { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, + "opencode-go:kimi-k3": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, + "opencode-go:longcat-2.0": { input: 0.3, output: 1.2, cacheRead: 0.006, cacheWrite: 0 }, + "opencode-go:mimo-v2.5": { input: 0.14, output: 0.28, cacheRead: 0.0028, cacheWrite: 0 }, + "opencode-go:mimo-v2.5-pro": { input: 0.435, output: 0.87, cacheRead: 0.003625, cacheWrite: 0 }, + "opencode-go:minimax-m2.7": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "opencode-go:minimax-m3": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "opencode-go:muse-spark-1.2-contributor": { input: 0.1, output: 0.2, cacheRead: 0.002, cacheWrite: 0 }, + "opencode-go:muse-spark-1.3-contributor": { input: 0.1, output: 0.2, cacheRead: 0.002, cacheWrite: 0 }, + "opencode-go:omen-alpha": { input: 0.2, output: 0.66, cacheRead: 0.04, cacheWrite: 0 }, + "opencode-go:qwen3.6-plus": { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0.625 }, + "opencode-go:qwen3.7-max": { input: 2.5, output: 7.5, cacheRead: 0.5, cacheWrite: 3.125 }, + "opencode-go:qwen3.7-plus": { input: 0.4, output: 1.6, cacheRead: 0.04, cacheWrite: 0.5 }, + "opencode-go:qwen3.8-flash": { input: 0.15, output: 0.47, cacheRead: 0.016, cacheWrite: 0.2 }, + "opencode-go:qwen3.8-max": { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 2.5 }, + "opencode:big-pickle": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "opencode:claude-fable-5": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "opencode:claude-fable-5-1": { input: 10, output: 50, cacheRead: 0.25, cacheWrite: 12.5 }, + "opencode:claude-haiku-4-5": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "opencode:claude-opus-4-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "opencode:claude-opus-4-6": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "opencode:claude-opus-4-7": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "opencode:claude-opus-4-8": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "opencode:claude-opus-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "opencode:claude-sonnet-4": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "opencode:claude-sonnet-4-5": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "opencode:claude-sonnet-4-6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "opencode:claude-sonnet-5": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "opencode:deepseek-v4-flash": { input: 0.14, output: 0.28, cacheRead: 0.028, cacheWrite: 0 }, + "opencode:deepseek-v4-flash-vision-exp": { input: 0.14, output: 0.28, cacheRead: 0.028, cacheWrite: 0 }, + "opencode:deepseek-v4-pro": { input: 1.74, output: 3.84, cacheRead: 0.145, cacheWrite: 0 }, + "opencode:gemini-3-flash": { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0 }, + "opencode:gemini-3.1-pro": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 }, + "opencode:gemini-3.5-flash": { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0 }, + "opencode:gemini-3.5-flash-lite": { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0 }, + "opencode:gemini-3.6-flash": { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 0 }, + "opencode:gemini-3.7-flash": { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 0 }, + "opencode:gemini-3.8-flash": { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 0 }, + "opencode:glm-5": { input: 1, output: 3.2, cacheRead: 0.2, cacheWrite: 0 }, + "opencode:glm-5.1": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "opencode:glm-5.2": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "opencode:glm-5.3": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "opencode:glm-5.3-flash": { input: 0.15, output: 0.5, cacheRead: 0.03, cacheWrite: 0 }, + "opencode:gpt-5": { input: 1.07, output: 8.5, cacheRead: 0.107, cacheWrite: 0 }, + "opencode:gpt-5-codex": { input: 1.07, output: 8.5, cacheRead: 0.107, cacheWrite: 0 }, + "opencode:gpt-5-nano": { input: 0.05, output: 0.4, cacheRead: 0.005, cacheWrite: 0 }, + "opencode:gpt-5.1": { input: 1.07, output: 8.5, cacheRead: 0.107, cacheWrite: 0 }, + "opencode:gpt-5.1-codex": { input: 1.07, output: 8.5, cacheRead: 0.107, cacheWrite: 0 }, + "opencode:gpt-5.1-codex-max": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "opencode:gpt-5.1-codex-mini": { input: 0.25, output: 2, cacheRead: 0.025, cacheWrite: 0 }, + "opencode:gpt-5.2": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "opencode:gpt-5.2-codex": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "opencode:gpt-5.3-codex": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "opencode:gpt-5.4": { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, + "opencode:gpt-5.4-mini": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, + "opencode:gpt-5.4-nano": { input: 0.2, output: 1.25, cacheRead: 0.02, cacheWrite: 0 }, + "opencode:gpt-5.4-pro": { input: 30, output: 180, cacheRead: 30, cacheWrite: 0 }, + "opencode:gpt-5.5": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, + "opencode:gpt-5.5-pro": { input: 30, output: 180, cacheRead: 30, cacheWrite: 0 }, + "opencode:gpt-5.6-luna": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, + "opencode:gpt-5.6-sol": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "opencode:gpt-5.6-terra": { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 3.125 }, + "opencode:gpt-6-astra": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "opencode:grok-4.5": { input: 2, output: 6, cacheRead: 0.3, cacheWrite: 0 }, + "opencode:grok-4.6": { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, + "opencode:grok-build-0.1": { input: 1, output: 2, cacheRead: 0.2, cacheWrite: 0 }, + "opencode:kimi-k2.5": { input: 0.6, output: 3, cacheRead: 0.08, cacheWrite: 0 }, + "opencode:kimi-k2.6": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, + "opencode:kimi-k2.7-code": { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, + "opencode:kimi-k3": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, + "opencode:ling-3.0-flash-fin-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "opencode:mimo-v2.5-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "opencode:minimax-m2.5": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "opencode:minimax-m2.7": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "opencode:minimax-m3": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "opencode:muse-spark-1.2": { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, + "opencode:muse-spark-1.2-contributor-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "opencode:muse-spark-1.3": { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, + "opencode:muse-spark-1.3-contributor-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "opencode:nemotron-3-ultra-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "opencode:nemotron-3.5-lightning-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "opencode:qwen3.5-plus": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, + "opencode:qwen3.6-plus": { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0.625 }, + "openrouter:~anthropic/claude-fable-latest": { input: 10, output: 50, cacheRead: 0.25, cacheWrite: 12.5 }, + "openrouter:~anthropic/claude-haiku-latest": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "openrouter:~anthropic/claude-opus-latest": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "openrouter:~anthropic/claude-sonnet-latest": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "openrouter:~deepseek/deepseek-v4-flash-latest": { input: 0.04998, output: 0.09996, cacheRead: 0.009996, cacheWrite: 0 }, + "openrouter:~google/gemini-flash-latest": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0.041667 }, + "openrouter:~google/gemini-pro-latest": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, + "openrouter:~moonshotai/kimi-latest": { input: 2.55, output: 12.75, cacheRead: 0.256, cacheWrite: 0 }, + "openrouter:~openai/gpt-latest": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "openrouter:~openai/gpt-mini-latest": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, + "openrouter:~x-ai/grok-latest": { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, + "openrouter:~z-ai/glm-flash-latest": { input: 0.075, output: 0.25, cacheRead: 0.015, cacheWrite: 0 }, + "openrouter:~z-ai/glm-latest": { input: 1.15, output: 3.5, cacheRead: 0.1, cacheWrite: 0 }, + "openrouter:aion-labs/aion-2.0": { input: 0.8, output: 1.6, cacheRead: 0.2, cacheWrite: 0 }, + "openrouter:aion-labs/aion-3.0": { input: 3, output: 6, cacheRead: 0.75, cacheWrite: 0 }, + "openrouter:aion-labs/aion-3.0-mini": { input: 0.7, output: 1.4, cacheRead: 0.18, cacheWrite: 0 }, + "openrouter:amazon/nova-2-lite-v1": { input: 0.3, output: 2.5, cacheRead: 0, cacheWrite: 0 }, + "openrouter:amazon/nova-lite-v1": { input: 0.06, output: 0.24, cacheRead: 0, cacheWrite: 0 }, + "openrouter:amazon/nova-micro-v1": { input: 0.035, output: 0.14, cacheRead: 0, cacheWrite: 0 }, + "openrouter:amazon/nova-premier-v1": { input: 2.5, output: 12.5, cacheRead: 0.625, cacheWrite: 0 }, + "openrouter:amazon/nova-pro-v1": { input: 0.8, output: 3.2, cacheRead: 0, cacheWrite: 0 }, + "openrouter:anthropic/claude-3-haiku": { input: 0.25, output: 1.25, cacheRead: 0.03, cacheWrite: 0.3 }, + "openrouter:anthropic/claude-fable-5": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "openrouter:anthropic/claude-fable-5:batch": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "openrouter:anthropic/claude-fable-5.1": { input: 10, output: 50, cacheRead: 0.25, cacheWrite: 12.5 }, + "openrouter:anthropic/claude-fable-5.1:batch": { input: 5, output: 25, cacheRead: 0.125, cacheWrite: 6.25 }, + "openrouter:anthropic/claude-haiku-4.5": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "openrouter:anthropic/claude-haiku-4.5:batch": { input: 0.5, output: 2.5, cacheRead: 0.05, cacheWrite: 0.625 }, + "openrouter:anthropic/claude-opus-4": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 }, + "openrouter:anthropic/claude-opus-4.1": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 }, + "openrouter:anthropic/claude-opus-4.1:batch": { input: 7.5, output: 37.5, cacheRead: 0.75, cacheWrite: 9.375 }, + "openrouter:anthropic/claude-opus-4.5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "openrouter:anthropic/claude-opus-4.5:batch": { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, + "openrouter:anthropic/claude-opus-4.6": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "openrouter:anthropic/claude-opus-4.6:batch": { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, + "openrouter:anthropic/claude-opus-4.7": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "openrouter:anthropic/claude-opus-4.7:batch": { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, + "openrouter:anthropic/claude-opus-4.8": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "openrouter:anthropic/claude-opus-4.8:batch": { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, + "openrouter:anthropic/claude-opus-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "openrouter:anthropic/claude-opus-5:batch": { input: 2.5, output: 12.5, cacheRead: 0.25, cacheWrite: 3.125 }, + "openrouter:anthropic/claude-sonnet-4": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "openrouter:anthropic/claude-sonnet-4.5": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "openrouter:anthropic/claude-sonnet-4.5:batch": { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 1.875 }, + "openrouter:anthropic/claude-sonnet-4.6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "openrouter:anthropic/claude-sonnet-4.6:batch": { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 1.875 }, + "openrouter:anthropic/claude-sonnet-5": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "openrouter:anthropic/claude-sonnet-5:batch": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "openrouter:arcee-ai/trinity-large-thinking": { input: 0.25, output: 0.8, cacheRead: 0.06, cacheWrite: 0 }, + "openrouter:auto": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:bytedance-seed/seed-1.6": { input: 0.25, output: 2, cacheRead: 0, cacheWrite: 0 }, + "openrouter:bytedance-seed/seed-1.6-flash": { input: 0.075, output: 0.3, cacheRead: 0, cacheWrite: 0 }, + "openrouter:bytedance-seed/seed-2-1-turbo": { input: 0.5, output: 2.5, cacheRead: 0, cacheWrite: 0 }, + "openrouter:bytedance-seed/seed-2.0-code": { input: 0.5, output: 3, cacheRead: 0, cacheWrite: 0 }, + "openrouter:bytedance-seed/seed-2.0-lite": { input: 0.25, output: 2, cacheRead: 0, cacheWrite: 0 }, + "openrouter:bytedance-seed/seed-2.0-mini": { input: 0.1, output: 0.4, cacheRead: 0, cacheWrite: 0 }, + "openrouter:cohere/command-r-08-2024": { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, + "openrouter:cohere/command-r-plus-08-2024": { input: 2.5, output: 10, cacheRead: 0, cacheWrite: 0 }, + "openrouter:cohere/north-mini-code:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:deepseek/deepseek-chat": { input: 0.32, output: 0.89, cacheRead: 0, cacheWrite: 0 }, + "openrouter:deepseek/deepseek-chat-v3-0324": { input: 0.25, output: 1, cacheRead: 0, cacheWrite: 0 }, + "openrouter:deepseek/deepseek-chat-v3.1": { input: 0.55, output: 1.65, cacheRead: 0.55, cacheWrite: 0 }, + "openrouter:deepseek/deepseek-r1": { input: 0.7, output: 2.5, cacheRead: 0, cacheWrite: 0 }, + "openrouter:deepseek/deepseek-r1-0528": { input: 0.5, output: 2.15, cacheRead: 0.35, cacheWrite: 0 }, + "openrouter:deepseek/deepseek-v3.1-terminus": { input: 0.27, output: 1, cacheRead: 0.135, cacheWrite: 0 }, + "openrouter:deepseek/deepseek-v3.2": { input: 0.269, output: 0.4, cacheRead: 0.1345, cacheWrite: 0 }, + "openrouter:deepseek/deepseek-v3.2-exp": { input: 0.27, output: 0.41, cacheRead: 0, cacheWrite: 0 }, + "openrouter:deepseek/deepseek-v4-flash": { input: 0.08526, output: 0.17052, cacheRead: 0.017052, cacheWrite: 0 }, + "openrouter:deepseek/deepseek-v4-flash-0731": { input: 0.065, output: 0.18, cacheRead: 0.016, cacheWrite: 0 }, + "openrouter:deepseek/deepseek-v4-flash-0731:batch": { input: 0.14, output: 0.28, cacheRead: 0.03, cacheWrite: 0 }, + "openrouter:deepseek/deepseek-v4-flash-vision-exp": { input: 0.22, output: 0.66, cacheRead: 0.007, cacheWrite: 0 }, + "openrouter:deepseek/deepseek-v4-pro": { input: 0.890358, output: 1.780716, cacheRead: 0.074196, cacheWrite: 0 }, + "openrouter:deepseek/deepseek-v4-pro-0813": { input: 1.12068, output: 3.36204, cacheRead: 0.037356, cacheWrite: 0 }, + "openrouter:deepseek/deepseek-v4-pro-0813:batch": { input: 1.32, output: 3.96, cacheRead: 0.13, cacheWrite: 0 }, + "openrouter:dots-studio/dots-3-note-preview:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:google/gemini-2.5-flash": { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0.083333 }, + "openrouter:google/gemini-2.5-flash-lite": { input: 0.1, output: 0.4, cacheRead: 0.01, cacheWrite: 0.083333 }, + "openrouter:google/gemini-2.5-flash-lite:batch": { input: 0.05, output: 0.2, cacheRead: 0.01, cacheWrite: 0 }, + "openrouter:google/gemini-2.5-flash:batch": { input: 0.15, output: 1.25, cacheRead: 0.03, cacheWrite: 0 }, + "openrouter:google/gemini-2.5-pro": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0.375 }, + "openrouter:google/gemini-2.5-pro-preview": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0.375 }, + "openrouter:google/gemini-2.5-pro-preview-05-06": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0.375 }, + "openrouter:google/gemini-2.5-pro:batch": { input: 0.625, output: 5, cacheRead: 0.125, cacheWrite: 0 }, + "openrouter:google/gemini-3-flash-preview": { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0.083333 }, + "openrouter:google/gemini-3-flash-preview:batch": { input: 0.25, output: 1.5, cacheRead: 0, cacheWrite: 0 }, + "openrouter:google/gemini-3-pro-image": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, + "openrouter:google/gemini-3.1-flash-lite": { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0.083333 }, + "openrouter:google/gemini-3.1-flash-lite-preview": { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0.083333 }, + "openrouter:google/gemini-3.1-flash-lite:batch": { input: 0.125, output: 0.75, cacheRead: 0.0125, cacheWrite: 0 }, + "openrouter:google/gemini-3.1-pro-preview": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, + "openrouter:google/gemini-3.1-pro-preview-customtools": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0.375 }, + "openrouter:google/gemini-3.1-pro-preview:batch": { input: 1, output: 6, cacheRead: 0, cacheWrite: 0 }, + "openrouter:google/gemini-3.5-flash": { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0.083333 }, + "openrouter:google/gemini-3.5-flash-lite": { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0.083333 }, + "openrouter:google/gemini-3.5-flash-lite:batch": { input: 0.15, output: 1.25, cacheRead: 0.015, cacheWrite: 0 }, + "openrouter:google/gemini-3.5-flash:batch": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, + "openrouter:google/gemini-3.6-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0.041667 }, + "openrouter:google/gemini-3.6-flash:batch": { input: 0.375, output: 1.875, cacheRead: 0.0375, cacheWrite: 0.041667 }, + "openrouter:google/gemini-3.7-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0.041667 }, + "openrouter:google/gemini-3.7-flash:batch": { input: 0.375, output: 1.875, cacheRead: 0.0375, cacheWrite: 0.041667 }, + "openrouter:google/gemini-3.8-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0.041667 }, + "openrouter:google/gemini-3.8-flash:batch": { input: 0.375, output: 1.875, cacheRead: 0.0375, cacheWrite: 0.041667 }, + "openrouter:google/gemma-3-12b-it": { input: 0.05, output: 0.15, cacheRead: 0, cacheWrite: 0 }, + "openrouter:google/gemma-3-27b-it": { input: 0.08, output: 0.45, cacheRead: 0.04, cacheWrite: 0 }, + "openrouter:google/gemma-4-26b-a4b-it": { input: 0.07, output: 0.34, cacheRead: 0, cacheWrite: 0 }, + "openrouter:google/gemma-4-26b-a4b-it:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:google/gemma-4-31b-it": { input: 0.09, output: 0.34, cacheRead: 0.05, cacheWrite: 0 }, + "openrouter:google/gemma-4-31b-it:batch": { input: 0.39, output: 0.97, cacheRead: 0, cacheWrite: 0 }, + "openrouter:google/gemma-4-31b-it:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:ibm-granite/granite-4.2-8b": { input: 0.1, output: 0.15, cacheRead: 0.05, cacheWrite: 0 }, + "openrouter:inception/mercury-2": { input: 0.25, output: 0.75, cacheRead: 0.025, cacheWrite: 0 }, + "openrouter:inception/mercury-2.5-preview": { input: 0.04, output: 0.15, cacheRead: 0.004, cacheWrite: 0 }, + "openrouter:inclusionai/ling-3.0-flash": { input: 0.021, output: 0.063, cacheRead: 0.0042, cacheWrite: 0 }, + "openrouter:inclusionai/ling-3.0-flash-fin": { input: 0.06, output: 0.18, cacheRead: 0.012, cacheWrite: 0 }, + "openrouter:inclusionai/ling-3.0-flash-fin:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:inclusionai/ling-3.0-flash-sante:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:kwaipilot/kat-coder-pro-v2": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "openrouter:kwaipilot/kat-coder-pro-v2.5": { input: 0.74, output: 2.96, cacheRead: 0.15, cacheWrite: 0 }, + "openrouter:liquid/lfm-2.5-2.6b:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:meituan/longcat-2.0": { input: 0.3, output: 1.2, cacheRead: 0.006, cacheWrite: 0 }, + "openrouter:meta-llama/llama-3.1-70b-instruct": { input: 0.4, output: 0.4, cacheRead: 0, cacheWrite: 0 }, + "openrouter:meta-llama/llama-3.1-8b-instruct": { input: 0.05, output: 0.08, cacheRead: 0.025, cacheWrite: 0 }, + "openrouter:meta-llama/llama-3.3-70b-instruct": { input: 0.1, output: 0.32, cacheRead: 0, cacheWrite: 0 }, + "openrouter:meta-llama/llama-4-maverick": { input: 0.2, output: 0.696, cacheRead: 0, cacheWrite: 0 }, + "openrouter:meta-llama/llama-4-scout": { input: 0.1, output: 0.3, cacheRead: 0, cacheWrite: 0 }, + "openrouter:meta/muse-glimmer-30b": { input: 0.3, output: 1.1, cacheRead: 0.04, cacheWrite: 0 }, + "openrouter:meta/muse-glimmer-30b:batch": { input: 0.35, output: 1.5, cacheRead: 0.04, cacheWrite: 0 }, + "openrouter:meta/muse-spark-1.1": { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, + "openrouter:meta/muse-spark-1.2": { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, + "openrouter:meta/muse-spark-1.2-contributor": { input: 0.1, output: 0.2, cacheRead: 0.002, cacheWrite: 0 }, + "openrouter:meta/muse-spark-1.3": { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, + "openrouter:meta/muse-spark-1.3-contributor": { input: 0.1, output: 0.2, cacheRead: 0.002, cacheWrite: 0 }, + "openrouter:minimax/minimax-m1": { input: 0.55, output: 2.2, cacheRead: 0, cacheWrite: 0 }, + "openrouter:minimax/minimax-m2": { input: 0.255, output: 1.02, cacheRead: 0, cacheWrite: 0 }, + "openrouter:minimax/minimax-m2.1": { input: 0.3, output: 1.2, cacheRead: 0.03, cacheWrite: 0 }, + "openrouter:minimax/minimax-m2.5": { input: 0.27, output: 1.08, cacheRead: 0.027, cacheWrite: 0 }, + "openrouter:minimax/minimax-m2.7": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "openrouter:minimax/minimax-m2.7:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:minimax/minimax-m3": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "openrouter:minimax/minimax-m3:batch": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "openrouter:minimax/minimax-m3:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:mistralai/codestral-2508": { input: 0.3, output: 0.9, cacheRead: 0.03, cacheWrite: 0 }, + "openrouter:mistralai/devstral-2512": { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, + "openrouter:mistralai/ministral-14b-2512": { input: 0.2, output: 0.2, cacheRead: 0.02, cacheWrite: 0 }, + "openrouter:mistralai/ministral-3b-2512": { input: 0.1, output: 0.1, cacheRead: 0.01, cacheWrite: 0 }, + "openrouter:mistralai/ministral-8b-2512": { input: 0.15, output: 0.15, cacheRead: 0.015, cacheWrite: 0 }, + "openrouter:mistralai/mistral-large": { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 0 }, + "openrouter:mistralai/mistral-large-2407": { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 0 }, + "openrouter:mistralai/mistral-large-2512": { input: 0.5, output: 1.5, cacheRead: 0.05, cacheWrite: 0 }, + "openrouter:mistralai/mistral-medium-3": { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, + "openrouter:mistralai/mistral-medium-3-5": { input: 1.5, output: 7.5, cacheRead: 0, cacheWrite: 0 }, + "openrouter:mistralai/mistral-medium-3-5:batch": { input: 0.75, output: 3.75, cacheRead: 0, cacheWrite: 0 }, + "openrouter:mistralai/mistral-medium-3.1": { input: 0.4, output: 2, cacheRead: 0.04, cacheWrite: 0 }, + "openrouter:mistralai/mistral-nemo": { input: 0.019, output: 0.03, cacheRead: 0, cacheWrite: 0 }, + "openrouter:mistralai/mistral-saba": { input: 0.2, output: 0.6, cacheRead: 0.02, cacheWrite: 0 }, + "openrouter:mistralai/mistral-small-2603": { input: 0.15, output: 0.6, cacheRead: 0.015, cacheWrite: 0 }, + "openrouter:mistralai/mistral-small-3.2-24b-instruct": { input: 0.075, output: 0.2, cacheRead: 0, cacheWrite: 0 }, + "openrouter:mistralai/mixtral-8x22b-instruct": { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 0 }, + "openrouter:mistralai/voxtral-small-24b-2507": { input: 0.1, output: 0.3, cacheRead: 0.01, cacheWrite: 0 }, + "openrouter:moonshotai/kimi-k2": { input: 0.57, output: 2.3, cacheRead: 0, cacheWrite: 0 }, + "openrouter:moonshotai/kimi-k2-0905": { input: 0.6, output: 2.5, cacheRead: 0, cacheWrite: 0 }, + "openrouter:moonshotai/kimi-k2-thinking": { input: 0.6, output: 2.5, cacheRead: 0.15, cacheWrite: 0 }, + "openrouter:moonshotai/kimi-k2.5": { input: 0.41, output: 2.06, cacheRead: 0.07, cacheWrite: 0 }, + "openrouter:moonshotai/kimi-k2.6": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, + "openrouter:moonshotai/kimi-k2.7-code": { input: 0.66, output: 3.4, cacheRead: 0.18, cacheWrite: 0 }, + "openrouter:moonshotai/kimi-k3": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, + "openrouter:moonshotai/kimi-k3:batch": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, + "openrouter:nex-agi/nex-n2-mini": { input: 0.025, output: 0.1, cacheRead: 0.0025, cacheWrite: 0 }, + "openrouter:nex-agi/nex-n2-pro": { input: 0.25, output: 1, cacheRead: 0.025, cacheWrite: 0 }, + "openrouter:nvidia/nemotron-3-nano-30b-a3b": { input: 0.05, output: 0.2, cacheRead: 0.03, cacheWrite: 0 }, + "openrouter:nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:nvidia/nemotron-3-super-120b-a12b": { input: 0.085, output: 0.4, cacheRead: 0, cacheWrite: 0 }, + "openrouter:nvidia/nemotron-3-super-120b-a12b:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:nvidia/nemotron-3-ultra-550b-a55b": { input: 0.625, output: 3.125, cacheRead: 0.1875, cacheWrite: 0 }, + "openrouter:nvidia/nemotron-3-ultra-550b-a55b:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:nvidia/nemotron-3.5-lightning": { input: 0.08, output: 0.2, cacheRead: 0.04, cacheWrite: 0 }, + "openrouter:nvidia/nemotron-3.5-lightning:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-3.5-turbo": { input: 0.5, output: 1.5, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-3.5-turbo-0613": { input: 1, output: 2, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-3.5-turbo-16k": { input: 3, output: 4, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-3.5-turbo:batch": { input: 0.25, output: 0.75, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-4": { input: 30, output: 60, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-4-turbo": { input: 10, output: 30, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-4-turbo-preview": { input: 10, output: 30, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-4-turbo:batch": { input: 5, output: 15, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-4.1": { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, + "openrouter:openai/gpt-4.1-mini": { input: 0.4, output: 1.6, cacheRead: 0.1, cacheWrite: 0 }, + "openrouter:openai/gpt-4.1-mini:batch": { input: 0.2, output: 0.8, cacheRead: 0.05, cacheWrite: 0 }, + "openrouter:openai/gpt-4.1-nano": { input: 0.1, output: 0.4, cacheRead: 0.025, cacheWrite: 0 }, + "openrouter:openai/gpt-4.1-nano:batch": { input: 0.05, output: 0.2, cacheRead: 0.0125, cacheWrite: 0 }, + "openrouter:openai/gpt-4.1:batch": { input: 1, output: 4, cacheRead: 0.25, cacheWrite: 0 }, + "openrouter:openai/gpt-4o": { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, + "openrouter:openai/gpt-4o-2024-05-13": { input: 5, output: 15, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-4o-2024-08-06": { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, + "openrouter:openai/gpt-4o-2024-11-20": { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, + "openrouter:openai/gpt-4o-mini": { input: 0.15, output: 0.6, cacheRead: 0.075, cacheWrite: 0 }, + "openrouter:openai/gpt-4o-mini-2024-07-18": { input: 0.15, output: 0.6, cacheRead: 0.075, cacheWrite: 0 }, + "openrouter:openai/gpt-4o-mini:batch": { input: 0.075, output: 0.3, cacheRead: 0.0375, cacheWrite: 0 }, + "openrouter:openai/gpt-4o:batch": { input: 1.25, output: 5, cacheRead: 0.625, cacheWrite: 0 }, + "openrouter:openai/gpt-5": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "openrouter:openai/gpt-5-mini": { input: 0.25, output: 2, cacheRead: 0.025, cacheWrite: 0 }, + "openrouter:openai/gpt-5-mini:batch": { input: 0.125, output: 1, cacheRead: 0.0125, cacheWrite: 0 }, + "openrouter:openai/gpt-5-nano": { input: 0.05, output: 0.4, cacheRead: 0.005, cacheWrite: 0 }, + "openrouter:openai/gpt-5-nano:batch": { input: 0.025, output: 0.2, cacheRead: 0.0025, cacheWrite: 0 }, + "openrouter:openai/gpt-5-pro": { input: 15, output: 120, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-5-pro:batch": { input: 7.5, output: 60, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-5:batch": { input: 0.625, output: 5, cacheRead: 0.0625, cacheWrite: 0 }, + "openrouter:openai/gpt-5.1": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "openrouter:openai/gpt-5.1-codex": { input: 1.25, output: 10, cacheRead: 0.13, cacheWrite: 0 }, + "openrouter:openai/gpt-5.1-codex-max": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "openrouter:openai/gpt-5.1-codex-mini": { input: 0.25, output: 2, cacheRead: 0.03, cacheWrite: 0 }, + "openrouter:openai/gpt-5.1:batch": { input: 0.625, output: 5, cacheRead: 0.0625, cacheWrite: 0 }, + "openrouter:openai/gpt-5.2": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "openrouter:openai/gpt-5.2-chat": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "openrouter:openai/gpt-5.2-codex": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "openrouter:openai/gpt-5.2-pro": { input: 21, output: 168, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-5.2-pro:batch": { input: 10.5, output: 84, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-5.2:batch": { input: 0.875, output: 7, cacheRead: 0.0875, cacheWrite: 0 }, + "openrouter:openai/gpt-5.3-codex": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "openrouter:openai/gpt-5.4": { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, + "openrouter:openai/gpt-5.4-mini": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, + "openrouter:openai/gpt-5.4-mini:batch": { input: 0.375, output: 2.25, cacheRead: 0.0375, cacheWrite: 0 }, + "openrouter:openai/gpt-5.4-nano": { input: 0.2, output: 1.25, cacheRead: 0.02, cacheWrite: 0 }, + "openrouter:openai/gpt-5.4-nano:batch": { input: 0.1, output: 0.625, cacheRead: 0.01, cacheWrite: 0 }, + "openrouter:openai/gpt-5.4-pro": { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-5.4-pro:batch": { input: 15, output: 90, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-5.4:batch": { input: 1.25, output: 7.5, cacheRead: 0.125, cacheWrite: 0 }, + "openrouter:openai/gpt-5.5": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, + "openrouter:openai/gpt-5.5-pro": { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-5.5-pro:batch": { input: 15, output: 90, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-5.5:batch": { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, + "openrouter:openai/gpt-5.6-luna": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, + "openrouter:openai/gpt-5.6-luna-pro": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, + "openrouter:openai/gpt-5.6-luna-pro:batch": { input: 0.1, output: 0.6, cacheRead: 0.01, cacheWrite: 0 }, + "openrouter:openai/gpt-5.6-luna:batch": { input: 0.1, output: 0.6, cacheRead: 0.01, cacheWrite: 0 }, + "openrouter:openai/gpt-5.6-sol": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "openrouter:openai/gpt-5.6-sol-pro": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "openrouter:openai/gpt-5.6-sol-pro:batch": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "openrouter:openai/gpt-5.6-sol:batch": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "openrouter:openai/gpt-5.6-terra": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, + "openrouter:openai/gpt-5.6-terra-pro": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, + "openrouter:openai/gpt-5.6-terra-pro:batch": { input: 1, output: 6, cacheRead: 0.1, cacheWrite: 0 }, + "openrouter:openai/gpt-5.6-terra:batch": { input: 1, output: 6, cacheRead: 0.1, cacheWrite: 0 }, + "openrouter:openai/gpt-6-astra": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "openrouter:openai/gpt-6-astra-pro": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "openrouter:openai/gpt-6-astra-pro:batch": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "openrouter:openai/gpt-6-astra:batch": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "openrouter:openai/gpt-audio": { input: 2.5, output: 10, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-audio-mini": { input: 0.6, output: 2.4, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-chat-latest": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, + "openrouter:openai/gpt-oss-120b": { input: 0.037, output: 0.17, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-oss-120b:batch": { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/gpt-oss-20b": { input: 0.03, output: 0.13, cacheRead: 0.03, cacheWrite: 0 }, + "openrouter:openai/gpt-oss-safeguard-20b": { input: 0.075, output: 0.3, cacheRead: 0.0375, cacheWrite: 0 }, + "openrouter:openai/o1": { input: 15, output: 60, cacheRead: 7.5, cacheWrite: 0 }, + "openrouter:openai/o3": { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, + "openrouter:openai/o3-mini": { input: 1.1, output: 4.4, cacheRead: 0.55, cacheWrite: 0 }, + "openrouter:openai/o3-mini-high": { input: 1.1, output: 4.4, cacheRead: 0.55, cacheWrite: 0 }, + "openrouter:openai/o3-mini:batch": { input: 0.55, output: 2.2, cacheRead: 0.275, cacheWrite: 0 }, + "openrouter:openai/o3-pro": { input: 20, output: 80, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openai/o3:batch": { input: 1, output: 4, cacheRead: 0.25, cacheWrite: 0 }, + "openrouter:openai/o4-mini": { input: 1.1, output: 4.4, cacheRead: 0.275, cacheWrite: 0 }, + "openrouter:openai/o4-mini-high": { input: 1.1, output: 4.4, cacheRead: 0.275, cacheWrite: 0 }, + "openrouter:openai/o4-mini:batch": { input: 0.55, output: 2.2, cacheRead: 0.1375, cacheWrite: 0 }, + "openrouter:openrouter/auto": { input: -1000000, output: -1000000, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openrouter/auto-beta": { input: -1000000, output: -1000000, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openrouter/free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:openrouter/fusion": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:poolside/laguna-s-2.1": { input: 0.09, output: 0.18, cacheRead: 0.009, cacheWrite: 0 }, + "openrouter:poolside/laguna-s-2.1:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:poolside/laguna-xs-2.1": { input: 0.06, output: 0.12, cacheRead: 0.03, cacheWrite: 0 }, + "openrouter:poolside/laguna-xs-2.1:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen-2.5-72b-instruct": { input: 0.36, output: 0.4, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen-2.5-7b-instruct": { input: 0.1, output: 0.2, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen-plus": { input: 0.26, output: 0.78, cacheRead: 0.052, cacheWrite: 0.325 }, + "openrouter:qwen/qwen-plus-2025-07-28": { input: 0.26, output: 0.78, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-14b": { input: 0.12, output: 0.24, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-235b-a22b": { input: 0.455, output: 1.82, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-235b-a22b-2507": { input: 0.09, output: 0.55, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-235b-a22b-thinking-2507": { input: 0.23, output: 2.3, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-30b-a3b": { input: 0.12, output: 0.5, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-30b-a3b-instruct-2507": { input: 0.04815, output: 0.19305, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-30b-a3b-thinking-2507": { input: 0.2, output: 2.4, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-32b": { input: 0.08, output: 0.28, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-8b": { input: 0.117, output: 0.455, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-coder": { input: 0.3, output: 1, cacheRead: 0.1, cacheWrite: 0 }, + "openrouter:qwen/qwen3-coder-30b-a3b-instruct": { input: 0.07, output: 0.28, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-coder-flash": { input: 0.195, output: 0.975, cacheRead: 0.039, cacheWrite: 0.24375 }, + "openrouter:qwen/qwen3-coder-next": { input: 0.12, output: 0.8, cacheRead: 0.07, cacheWrite: 0 }, + "openrouter:qwen/qwen3-coder-plus": { input: 0.65, output: 3.25, cacheRead: 0.13, cacheWrite: 0.8125 }, + "openrouter:qwen/qwen3-max": { input: 0.78, output: 3.9, cacheRead: 0.156, cacheWrite: 0.975 }, + "openrouter:qwen/qwen3-max-thinking": { input: 0.78, output: 3.9, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-next-80b-a3b-instruct": { input: 0.1, output: 1.1, cacheRead: 0.07, cacheWrite: 0 }, + "openrouter:qwen/qwen3-next-80b-a3b-thinking": { input: 0.15, output: 1.2, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-vl-235b-a22b-instruct": { input: 0.21, output: 1.9, cacheRead: 0.1, cacheWrite: 0 }, + "openrouter:qwen/qwen3-vl-235b-a22b-thinking": { input: 0.4, output: 4, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-vl-30b-a3b-instruct": { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-vl-30b-a3b-thinking": { input: 0.2, output: 2.4, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-vl-32b-instruct": { input: 0.104, output: 0.416, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-vl-8b-instruct": { input: 0.117, output: 0.455, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3-vl-8b-thinking": { input: 0.18, output: 2.1, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3.5-122b-a10b": { input: 0.29, output: 2.4, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3.5-27b": { input: 0.195, output: 1.56, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3.5-35b-a3b": { input: 0.08, output: 0.75, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3.5-397b-a17b": { input: 0.55, output: 3.5, cacheRead: 0.225, cacheWrite: 0 }, + "openrouter:qwen/qwen3.5-9b": { input: 0.1, output: 0.15, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3.5-9b:batch": { input: 0.17, output: 0.25, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3.5-flash-02-23": { input: 0.065, output: 0.26, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3.5-plus-02-15": { input: 0.26, output: 1.56, cacheRead: 0, cacheWrite: 0 }, + "openrouter:qwen/qwen3.5-plus-20260420": { input: 0.3, output: 1.8, cacheRead: 0, cacheWrite: 0.375 }, + "openrouter:qwen/qwen3.6-27b": { input: 0.3, output: 2, cacheRead: 0.03, cacheWrite: 0 }, + "openrouter:qwen/qwen3.6-35b-a3b": { input: 0.1, output: 0.9, cacheRead: 0.05, cacheWrite: 0 }, + "openrouter:qwen/qwen3.6-flash": { input: 0.1875, output: 1.125, cacheRead: 0, cacheWrite: 0.234375 }, + "openrouter:qwen/qwen3.6-max-preview": { input: 1.027, output: 6.162, cacheRead: 0, cacheWrite: 1.28375 }, + "openrouter:qwen/qwen3.6-plus": { input: 0.325, output: 1.95, cacheRead: 0, cacheWrite: 0.40625 }, + "openrouter:qwen/qwen3.7-flash": { input: 0.03, output: 0.13, cacheRead: 0.006, cacheWrite: 0.038 }, + "openrouter:qwen/qwen3.7-max": { input: 1.475, output: 4.425, cacheRead: 0.295, cacheWrite: 1.84375 }, + "openrouter:qwen/qwen3.7-plus": { input: 0.32, output: 1.28, cacheRead: 0.064, cacheWrite: 0.4 }, + "openrouter:qwen/qwen3.8-2.4t-a95b": { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 0 }, + "openrouter:qwen/qwen3.8-2.4t-a95b:batch": { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 0 }, + "openrouter:qwen/qwen3.8-27b": { input: 0.42, output: 3, cacheRead: 0.085, cacheWrite: 0 }, + "openrouter:qwen/qwen3.8-flash": { input: 0.15, output: 0.47, cacheRead: 0.016, cacheWrite: 0.2 }, + "openrouter:qwen/qwen3.8-max-0902": { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 2.5 }, + "openrouter:rekaai/reka-edge": { input: 0.1, output: 0.1, cacheRead: 0, cacheWrite: 0 }, + "openrouter:relace/relace-search": { input: 1, output: 3, cacheRead: 0, cacheWrite: 0 }, + "openrouter:sakana/fugu-ultra": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, + "openrouter:sakana/sakana-namazu": { input: 0.95, output: 4, cacheRead: 0.15, cacheWrite: 0 }, + "openrouter:sao10k/l3.1-euryale-70b": { input: 0.85, output: 0.85, cacheRead: 0, cacheWrite: 0 }, + "openrouter:stepfun/step-3.5-flash": { input: 0.1, output: 0.3, cacheRead: 0, cacheWrite: 0 }, + "openrouter:stepfun/step-3.7-flash": { input: 0.2, output: 1.15, cacheRead: 0.04, cacheWrite: 0 }, + "openrouter:tencent/hy3": { input: 0.132, output: 0.528, cacheRead: 0.033, cacheWrite: 0 }, + "openrouter:tencent/hy3-preview": { input: 0.18, output: 0.6, cacheRead: 0.06, cacheWrite: 0 }, + "openrouter:tencent/hy4-preview": { input: 0.834, output: 2.501, cacheRead: 0.042, cacheWrite: 0 }, + "openrouter:thedrummer/unslopnemo-12b": { input: 0.4, output: 0.4, cacheRead: 0, cacheWrite: 0 }, + "openrouter:thinkingmachines/inkling": { input: 1, output: 4.05, cacheRead: 0.17, cacheWrite: 0 }, + "openrouter:thinkingmachines/inkling-small": { input: 0.45, output: 1.2, cacheRead: 0.1, cacheWrite: 0 }, + "openrouter:thinkingmachines/inkling-small:batch": { input: 0.5, output: 1.2, cacheRead: 0.1, cacheWrite: 0 }, + "openrouter:thinkingmachines/inkling-small:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:thinkingmachines/inkling:batch": { input: 1, output: 4.05, cacheRead: 0.17, cacheWrite: 0 }, + "openrouter:thinkingmachines/inkling:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:upstage/solar-pro-3": { input: 0.15, output: 0.6, cacheRead: 0.015, cacheWrite: 0 }, + "openrouter:upstage/solar-pro4": { input: 0.03, output: 0.12, cacheRead: 0.006, cacheWrite: 0 }, + "openrouter:x-ai/grok-4.20": { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, + "openrouter:x-ai/grok-4.3": { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, + "openrouter:x-ai/grok-4.3:batch": { input: 1, output: 2, cacheRead: 0.16, cacheWrite: 0 }, + "openrouter:x-ai/grok-4.5": { input: 2, output: 6, cacheRead: 0.3, cacheWrite: 0 }, + "openrouter:x-ai/grok-4.6": { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, + "openrouter:x-ai/grok-build-0.1": { input: 1, output: 2, cacheRead: 0.2, cacheWrite: 0 }, + "openrouter:xiaomi/mimo-v2.5": { input: 0.14, output: 0.28, cacheRead: 0.0028, cacheWrite: 0 }, + "openrouter:xiaomi/mimo-v2.5-pro": { input: 0.435, output: 0.87, cacheRead: 0.0036, cacheWrite: 0 }, + "openrouter:z-ai/glm-4.5": { input: 0.6, output: 2.2, cacheRead: 0.11, cacheWrite: 0 }, + "openrouter:z-ai/glm-4.5-air": { input: 0.13, output: 0.85, cacheRead: 0.025, cacheWrite: 0 }, + "openrouter:z-ai/glm-4.5v": { input: 0.6, output: 1.8, cacheRead: 0.11, cacheWrite: 0 }, + "openrouter:z-ai/glm-4.6": { input: 0.55, output: 2.2, cacheRead: 0.11, cacheWrite: 0 }, + "openrouter:z-ai/glm-4.6v": { input: 0.3, output: 0.9, cacheRead: 0.055, cacheWrite: 0 }, + "openrouter:z-ai/glm-4.7": { input: 0.4, output: 1.75, cacheRead: 0.08, cacheWrite: 0 }, + "openrouter:z-ai/glm-4.7-flash": { input: 0.06, output: 0.4, cacheRead: 0.01, cacheWrite: 0 }, + "openrouter:z-ai/glm-5": { input: 0.6, output: 1.9, cacheRead: 0.119, cacheWrite: 0 }, + "openrouter:z-ai/glm-5-turbo": { input: 1.2, output: 4, cacheRead: 0.24, cacheWrite: 0 }, + "openrouter:z-ai/glm-5.1": { input: 0.966, output: 3.036, cacheRead: 0.1794, cacheWrite: 0 }, + "openrouter:z-ai/glm-5.2": { input: 0.966, output: 3.036, cacheRead: 0.1932, cacheWrite: 0 }, + "openrouter:z-ai/glm-5.2:free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "openrouter:z-ai/glm-5.3": { input: 1.4, output: 4.4, cacheRead: 0.14, cacheWrite: 0 }, + "openrouter:z-ai/glm-5.3-flash": { input: 0.075, output: 0.25, cacheRead: 0.015, cacheWrite: 0 }, + "openrouter:z-ai/glm-5.3-flash:batch": { input: 0.15, output: 0.5, cacheRead: 0.03, cacheWrite: 0 }, + "openrouter:z-ai/glm-5v-turbo": { input: 1.2, output: 4, cacheRead: 0.24, cacheWrite: 0 }, + "qwen-token-plan-cn:deepseek-v3.2": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:deepseek-v4-flash": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:deepseek-v4-flash-0731": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:deepseek-v4-pro": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:deepseek-v4-pro-0813": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:glm-5": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:glm-5.1": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:glm-5.2": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:kimi-k2.5": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:kimi-k2.6": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:kimi-k2.7-code": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:MiniMax-M2.5": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:qwen3.6-flash": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:qwen3.6-plus": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:qwen3.7-max": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:qwen3.7-plus": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:qwen3.8-flash": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-cn:qwen3.8-max": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-individual:deepseek-v4-flash-0731": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-individual:deepseek-v4-pro": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-individual:deepseek-v4-pro-0813": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-individual:glm-5.2": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-individual:qwen3.6-flash": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-individual:qwen3.7-max": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-individual:qwen3.7-plus": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-individual:qwen3.8-flash": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan-individual:qwen3.8-max": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:deepseek-v3.2": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:deepseek-v4-flash": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:deepseek-v4-flash-0731": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:deepseek-v4-pro": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:deepseek-v4-pro-0813": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:glm-5": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:glm-5.1": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:glm-5.2": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:kimi-k2.5": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:kimi-k2.6": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:kimi-k2.7-code": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:MiniMax-M2.5": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:qwen3.6-flash": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:qwen3.6-plus": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:qwen3.7-max": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:qwen3.7-plus": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:qwen3.8-flash": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "qwen-token-plan:qwen3.8-max": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "together:deepseek-ai/DeepSeek-V4-Flash-0731": { input: 0.14, output: 0.28, cacheRead: 0.03, cacheWrite: 0 }, + "together:deepseek-ai/DeepSeek-V4-Pro": { input: 1.74, output: 3.48, cacheRead: 0.2, cacheWrite: 0 }, + "together:deepseek-ai/DeepSeek-V4-Pro-0813": { input: 1.32, output: 3.96, cacheRead: 0.13, cacheWrite: 0 }, + "together:google/gemma-4-31B-it": { input: 0.39, output: 0.97, cacheRead: 0, cacheWrite: 0 }, + "together:meta-llama/Llama-3.3-70B-Instruct-Turbo": { input: 1.04, output: 1.04, cacheRead: 0, cacheWrite: 0 }, + "together:MiniMaxAI/MiniMax-M2.7": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "together:MiniMaxAI/MiniMax-M3": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "together:moonshotai/Kimi-K2.6": { input: 1.2, output: 4.5, cacheRead: 0.2, cacheWrite: 0 }, + "together:moonshotai/Kimi-K2.7-Code": { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, + "together:moonshotai/Kimi-K3": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, + "together:nvidia/nemotron-3-ultra-550b-a55b": { input: 0.6, output: 3.6, cacheRead: 0.2, cacheWrite: 0 }, + "together:openai/gpt-oss-120b": { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, + "together:openai/gpt-oss-20b": { input: 0.05, output: 0.2, cacheRead: 0, cacheWrite: 0 }, + "together:Qwen/Qwen2.5-7B-Instruct-Turbo": { input: 0.3, output: 0.3, cacheRead: 0, cacheWrite: 0 }, + "together:Qwen/Qwen3.5-9B": { input: 0.17, output: 0.25, cacheRead: 0, cacheWrite: 0 }, + "together:Qwen/Qwen3.6-Plus": { input: 0.5, output: 3, cacheRead: 0, cacheWrite: 0 }, + "together:Qwen/Qwen3.7-Max": { input: 1.25, output: 3.75, cacheRead: 0.125, cacheWrite: 0 }, + "together:thinkingmachines/Inkling": { input: 1, output: 4.05, cacheRead: 0.17, cacheWrite: 0 }, + "together:zai-org/GLM-5.2": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "together:zai-org/GLM-5.3": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "together:zai-org/GLM-5.3-Flash": { input: 0.15, output: 0.5, cacheRead: 0.03, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen-3-14b": { input: 0.12, output: 0.24, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen-3-235b": { input: 0.22, output: 0.88, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen-3-30b": { input: 0.12, output: 0.5, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen-3-32b": { input: 0.16, output: 0.64, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen-3.6-max-preview": { input: 1.3, output: 7.8, cacheRead: 0.26, cacheWrite: 1.625 }, + "vercel-ai-gateway:alibaba/qwen3-235b-a22b-thinking": { input: 0.4, output: 4, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3-coder": { input: 1.5, output: 7.5, cacheRead: 0.3, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3-coder-30b-a3b": { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3-coder-next": { input: 0.5, output: 1.2, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3-coder-plus": { input: 1, output: 5, cacheRead: 0.2, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3-max": { input: 1.2, output: 6, cacheRead: 0.24, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3-max-preview": { input: 1.2, output: 6, cacheRead: 0.24, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3-max-thinking": { input: 1.2, output: 6, cacheRead: 0.24, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3-next-80b-a3b-instruct": { input: 0.15, output: 1.2, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3-next-80b-a3b-thinking": { input: 0.15, output: 1.2, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3-vl-235b-a22b-instruct": { input: 0.4, output: 1.6, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3-vl-instruct": { input: 0.4, output: 1.6, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3-vl-thinking": { input: 0.4, output: 4, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3.5-flash": { input: 0.1, output: 0.4, cacheRead: 0.001, cacheWrite: 0.125 }, + "vercel-ai-gateway:alibaba/qwen3.5-plus": { input: 0.4, output: 2.4, cacheRead: 0.04, cacheWrite: 0.5 }, + "vercel-ai-gateway:alibaba/qwen3.6-27b": { input: 0.6, output: 3.6, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3.6-plus": { input: 0.5, output: 3, cacheRead: 0.1, cacheWrite: 0.625 }, + "vercel-ai-gateway:alibaba/qwen3.7-flash": { input: 0.03, output: 0.13, cacheRead: 0.006, cacheWrite: 0.038 }, + "vercel-ai-gateway:alibaba/qwen3.7-max": { input: 2.5, output: 7.5, cacheRead: 0.5, cacheWrite: 3.125 }, + "vercel-ai-gateway:alibaba/qwen3.7-plus": { input: 0.4, output: 1.6, cacheRead: 0.08, cacheWrite: 0.5 }, + "vercel-ai-gateway:alibaba/qwen3.8-2.4t-a95b": { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3.8-27b": { input: 0.5, output: 3, cacheRead: 0.1, cacheWrite: 0.625 }, + "vercel-ai-gateway:alibaba/qwen3.8-flash": { input: 0.16, output: 0.47, cacheRead: 0.016, cacheWrite: 0.2 }, + "vercel-ai-gateway:alibaba/qwen3.8-flash-next": { input: 0.12, output: 0.4, cacheRead: 0.01, cacheWrite: 0 }, + "vercel-ai-gateway:alibaba/qwen3.8-max": { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 2.5 }, + "vercel-ai-gateway:alibaba/qwen3.8-max-0902": { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 2.5 }, + "vercel-ai-gateway:amazon/nova-2-lite": { input: 0.3, output: 2.5, cacheRead: 0.075, cacheWrite: 0 }, + "vercel-ai-gateway:amazon/nova-lite": { input: 0.06, output: 0.24, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:amazon/nova-micro": { input: 0.035, output: 0.14, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:amazon/nova-pro": { input: 0.8, output: 3.2, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:anthropic/claude-3-haiku": { input: 0.25, output: 1.25, cacheRead: 0.03, cacheWrite: 0.3 }, + "vercel-ai-gateway:anthropic/claude-fable-5": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "vercel-ai-gateway:anthropic/claude-fable-5.1": { input: 10, output: 50, cacheRead: 0.25, cacheWrite: 12.5 }, + "vercel-ai-gateway:anthropic/claude-haiku-4.5": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, + "vercel-ai-gateway:anthropic/claude-opus-4": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 }, + "vercel-ai-gateway:anthropic/claude-opus-4.5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "vercel-ai-gateway:anthropic/claude-opus-4.6": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "vercel-ai-gateway:anthropic/claude-opus-4.7": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "vercel-ai-gateway:anthropic/claude-opus-4.8": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "vercel-ai-gateway:anthropic/claude-opus-4.8-fast": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "vercel-ai-gateway:anthropic/claude-opus-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, + "vercel-ai-gateway:anthropic/claude-opus-5-fast": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "vercel-ai-gateway:anthropic/claude-sonnet-4": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "vercel-ai-gateway:anthropic/claude-sonnet-4.5": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "vercel-ai-gateway:anthropic/claude-sonnet-4.6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, + "vercel-ai-gateway:anthropic/claude-sonnet-5": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "vercel-ai-gateway:arcee-ai/trinity-large-thinking": { input: 0.25, output: 0.9, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:bytedance/seed-1.6": { input: 0.25, output: 2, cacheRead: 0.05, cacheWrite: 0 }, + "vercel-ai-gateway:bytedance/seed-1.8": { input: 0.25, output: 2, cacheRead: 0.05, cacheWrite: 0 }, + "vercel-ai-gateway:cohere/command-a": { input: 2.5, output: 10, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:deepseek/deepseek-r1": { input: 1.35, output: 5.4, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:deepseek/deepseek-v3.1": { input: 0.25, output: 0.95, cacheRead: 0.13, cacheWrite: 0 }, + "vercel-ai-gateway:deepseek/deepseek-v3.1-terminus": { input: 0.27, output: 1, cacheRead: 0.135, cacheWrite: 0 }, + "vercel-ai-gateway:deepseek/deepseek-v3.2": { input: 0.28, output: 0.42, cacheRead: 0.028, cacheWrite: 0 }, + "vercel-ai-gateway:deepseek/deepseek-v3.2-thinking": { input: 0.62, output: 1.85, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:deepseek/deepseek-v4-flash": { input: 0.13, output: 0.26, cacheRead: 0.028, cacheWrite: 0 }, + "vercel-ai-gateway:deepseek/deepseek-v4-flash-0731": { input: 0.076, output: 0.153, cacheRead: 0.014, cacheWrite: 0 }, + "vercel-ai-gateway:deepseek/deepseek-v4-flash-vision-exp": { input: 0.22, output: 0.66, cacheRead: 0.007, cacheWrite: 0 }, + "vercel-ai-gateway:deepseek/deepseek-v4-pro": { input: 0.66, output: 1.98, cacheRead: 0.022, cacheWrite: 0 }, + "vercel-ai-gateway:deepseek/deepseek-v4-pro-0813": { input: 0.66, output: 1.98, cacheRead: 0.066, cacheWrite: 0 }, + "vercel-ai-gateway:google/gemini-2.5-flash": { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0 }, + "vercel-ai-gateway:google/gemini-2.5-flash-lite": { input: 0.1, output: 0.4, cacheRead: 0.01, cacheWrite: 0 }, + "vercel-ai-gateway:google/gemini-2.5-pro": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "vercel-ai-gateway:google/gemini-3-flash": { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0 }, + "vercel-ai-gateway:google/gemini-3.1-flash-lite": { input: 0.25, output: 1.5, cacheRead: 0.03, cacheWrite: 0 }, + "vercel-ai-gateway:google/gemini-3.1-pro-preview": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 }, + "vercel-ai-gateway:google/gemini-3.5-flash": { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0 }, + "vercel-ai-gateway:google/gemini-3.5-flash-lite": { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0 }, + "vercel-ai-gateway:google/gemini-3.6-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, + "vercel-ai-gateway:google/gemini-3.7-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, + "vercel-ai-gateway:google/gemini-3.8-flash": { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, + "vercel-ai-gateway:google/gemma-4-26b-a4b-it": { input: 0.15, output: 0.6, cacheRead: 0.015, cacheWrite: 0 }, + "vercel-ai-gateway:google/gemma-4-31b-it": { input: 0.14, output: 0.4, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:inception/mercury-2": { input: 0.25, output: 0.75, cacheRead: 0.025, cacheWrite: 0 }, + "vercel-ai-gateway:inception/mercury-coder-small": { input: 0.25, output: 1, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:inclusionai/ling-3.0-flash": { input: 0.06, output: 0.18, cacheRead: 0.012, cacheWrite: 0 }, + "vercel-ai-gateway:inclusionai/ling-3.0-flash-fin": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:inclusionai/ling-3.0-flash-fin-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:inclusionai/ling-3.0-flash-sante": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:inclusionai/ling-3.0-flash-sante-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:interfaze/interfaze-beta": { input: 1.5, output: 3.5, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:kwaipilot/kat-coder-air-v2.5": { input: 0.15, output: 0.6, cacheRead: 0.03, cacheWrite: 0 }, + "vercel-ai-gateway:kwaipilot/kat-coder-pro-v1": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "vercel-ai-gateway:kwaipilot/kat-coder-pro-v2": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "vercel-ai-gateway:kwaipilot/kat-coder-pro-v2.5": { input: 0.74, output: 2.96, cacheRead: 0.15, cacheWrite: 0 }, + "vercel-ai-gateway:meta/llama-3.1-70b": { input: 0.72, output: 0.72, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:meta/llama-3.1-8b": { input: 0.22, output: 0.22, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:meta/llama-3.3-70b": { input: 0.72, output: 0.72, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:meta/llama-4-maverick": { input: 0.24, output: 0.97, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:meta/llama-4-scout": { input: 0.17, output: 0.66, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:meta/muse-glimmer-30b": { input: 0.35, output: 1.5, cacheRead: 0.04, cacheWrite: 0 }, + "vercel-ai-gateway:meta/muse-spark-1.1": { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, + "vercel-ai-gateway:meta/muse-spark-1.2": { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, + "vercel-ai-gateway:meta/muse-spark-1.2-contributor": { input: 0.1, output: 0.2, cacheRead: 0.002, cacheWrite: 0 }, + "vercel-ai-gateway:meta/muse-spark-1.3": { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, + "vercel-ai-gateway:meta/muse-spark-1.3-contributor": { input: 0.1, output: 0.2, cacheRead: 0.002, cacheWrite: 0 }, + "vercel-ai-gateway:minimax/minimax-m2": { input: 0.3, output: 1.2, cacheRead: 0.03, cacheWrite: 0.375 }, + "vercel-ai-gateway:minimax/minimax-m2.1": { input: 0.3, output: 1.2, cacheRead: 0.03, cacheWrite: 0.375 }, + "vercel-ai-gateway:minimax/minimax-m2.1-lightning": { input: 0.3, output: 2.4, cacheRead: 0.03, cacheWrite: 0.375 }, + "vercel-ai-gateway:minimax/minimax-m2.5": { input: 0.3, output: 1.2, cacheRead: 0.03, cacheWrite: 0.375 }, + "vercel-ai-gateway:minimax/minimax-m2.5-highspeed": { input: 0.6, output: 2.4, cacheRead: 0.03, cacheWrite: 0.375 }, + "vercel-ai-gateway:minimax/minimax-m2.7": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0.375 }, + "vercel-ai-gateway:minimax/minimax-m2.7-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:minimax/minimax-m2.7-highspeed": { input: 0.6, output: 2.4, cacheRead: 0.06, cacheWrite: 0.375 }, + "vercel-ai-gateway:minimax/minimax-m3": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, + "vercel-ai-gateway:minimax/minimax-m3-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:mistral/codestral": { input: 0.3, output: 0.9, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:mistral/devstral-2": { input: 0.4, output: 2, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:mistral/devstral-small-2": { input: 0.1, output: 0.3, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:mistral/ministral-14b": { input: 0.2, output: 0.2, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:mistral/ministral-3b": { input: 0.1, output: 0.1, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:mistral/ministral-8b": { input: 0.15, output: 0.15, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:mistral/mistral-large-3": { input: 0.5, output: 1.5, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:mistral/mistral-medium": { input: 0.4, output: 2, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:mistral/mistral-medium-3.5": { input: 1.5, output: 7.5, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:mistral/mistral-nemo": { input: 0.15, output: 0.15, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:mistral/mistral-small": { input: 0.1, output: 0.3, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:mistral/pixtral-12b": { input: 0.15, output: 0.15, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:moonshotai/kimi-k2": { input: 0.57, output: 2.3, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:moonshotai/kimi-k2-thinking": { input: 0.47, output: 2, cacheRead: 0.141, cacheWrite: 0 }, + "vercel-ai-gateway:moonshotai/kimi-k2.5": { input: 0.6, output: 3, cacheRead: 0.1, cacheWrite: 0 }, + "vercel-ai-gateway:moonshotai/kimi-k2.6": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, + "vercel-ai-gateway:moonshotai/kimi-k2.7-code": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, + "vercel-ai-gateway:moonshotai/kimi-k2.7-code-highspeed": { input: 1.9, output: 8, cacheRead: 0.38, cacheWrite: 0 }, + "vercel-ai-gateway:moonshotai/kimi-k3": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, + "vercel-ai-gateway:moonshotai/kimi-k3-fast": { input: 4.5, output: 22.5, cacheRead: 0.45, cacheWrite: 0 }, + "vercel-ai-gateway:nvidia/nemotron-3-nano-30b-a3b": { input: 0.05, output: 0.24, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:nvidia/nemotron-3-super-120b-a12b": { input: 0.15, output: 0.65, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:nvidia/nemotron-3-ultra-550b-a55b": { input: 0.6, output: 2.4, cacheRead: 0.12, cacheWrite: 0 }, + "vercel-ai-gateway:nvidia/nemotron-3.5-lightning": { input: 0.05, output: 0.2, cacheRead: 0.01, cacheWrite: 0 }, + "vercel-ai-gateway:nvidia/nemotron-nano-12b-v2-vl": { input: 0.2, output: 0.6, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:nvidia/nemotron-nano-9b-v2": { input: 0.06, output: 0.23, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-3.5-turbo": { input: 0.5, output: 1.5, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-4-turbo": { input: 10, output: 30, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-4.1": { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-4.1-fast": { input: 3.5, output: 14, cacheRead: 0.875, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-4.1-mini": { input: 0.4, output: 1.6, cacheRead: 0.1, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-4.1-mini-fast": { input: 0.7, output: 2.8, cacheRead: 0.175, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-4.1-nano": { input: 0.1, output: 0.4, cacheRead: 0.025, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-4.1-nano-fast": { input: 0.2, output: 0.8, cacheRead: 0.05, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-4o": { input: 2.5, output: 10, cacheRead: 1.25, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-4o-fast": { input: 4.25, output: 17, cacheRead: 2.125, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-4o-mini": { input: 0.15, output: 0.6, cacheRead: 0.075, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-4o-mini-fast": { input: 0.25, output: 1, cacheRead: 0.125, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5-codex": { input: 1.25, output: 10, cacheRead: 0.13, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5-fast": { input: 2.5, output: 20, cacheRead: 0.25, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5-mini": { input: 0.25, output: 2, cacheRead: 0.025, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5-mini-fast": { input: 0.45, output: 3.6, cacheRead: 0.045, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5-nano": { input: 0.05, output: 0.4, cacheRead: 0.005, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5-pro": { input: 15, output: 120, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.1-codex": { input: 1.25, output: 10, cacheRead: 0.13, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.1-codex-max": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.1-codex-mini": { input: 0.25, output: 2, cacheRead: 0.03, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.1-thinking": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.1-thinking-fast": { input: 2.5, output: 20, cacheRead: 0.25, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.2": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.2-codex": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.2-fast": { input: 3.5, output: 28, cacheRead: 0.35, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.2-pro": { input: 21, output: 168, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.3-codex": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.3-codex-fast": { input: 3.5, output: 28, cacheRead: 0.35, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.4": { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.4-fast": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.4-mini": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.4-mini-fast": { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.4-nano": { input: 0.2, output: 1.25, cacheRead: 0.02, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.4-pro": { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.5": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.5-fast": { input: 12.5, output: 75, cacheRead: 1.25, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.5-pro": { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-5.6-luna": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, + "vercel-ai-gateway:openai/gpt-5.6-luna-fast": { input: 0.4, output: 2.4, cacheRead: 0.04, cacheWrite: 0.5 }, + "vercel-ai-gateway:openai/gpt-5.6-sol": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "vercel-ai-gateway:openai/gpt-5.6-sol-fast": { input: 4, output: 20, cacheRead: 0.4, cacheWrite: 5 }, + "vercel-ai-gateway:openai/gpt-5.6-terra": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, + "vercel-ai-gateway:openai/gpt-5.6-terra-fast": { input: 4, output: 24, cacheRead: 0.4, cacheWrite: 5 }, + "vercel-ai-gateway:openai/gpt-6-astra": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, + "vercel-ai-gateway:openai/gpt-6-astra-fast": { input: 20, output: 100, cacheRead: 2, cacheWrite: 25 }, + "vercel-ai-gateway:openai/gpt-oss-120b": { input: 0.1, output: 0.5, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-oss-20b": { input: 0.05, output: 0.2, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-oss-safeguard-120b": { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:openai/gpt-oss-safeguard-20b": { input: 0.07, output: 0.2, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:openai/o1": { input: 15, output: 60, cacheRead: 7.5, cacheWrite: 0 }, + "vercel-ai-gateway:openai/o3": { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, + "vercel-ai-gateway:openai/o3-fast": { input: 3.5, output: 14, cacheRead: 0.875, cacheWrite: 0 }, + "vercel-ai-gateway:openai/o3-mini": { input: 1.1, output: 4.4, cacheRead: 0.55, cacheWrite: 0 }, + "vercel-ai-gateway:openai/o3-pro": { input: 20, output: 80, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:openai/o4-mini": { input: 1.1, output: 4.4, cacheRead: 0.275, cacheWrite: 0 }, + "vercel-ai-gateway:openai/o4-mini-fast": { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, + "vercel-ai-gateway:poolside/laguna-s-2.1": { input: 0.1, output: 0.2, cacheRead: 0.01, cacheWrite: 0 }, + "vercel-ai-gateway:poolside/laguna-s-2.1-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:sakana/fugu-ultra": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, + "vercel-ai-gateway:sakana/namazu": { input: 0.95, output: 4, cacheRead: 0.15, cacheWrite: 0 }, + "vercel-ai-gateway:spacexai/grok-4.1-fast-non-reasoning": { input: 0.2, output: 0.5, cacheRead: 0.05, cacheWrite: 0 }, + "vercel-ai-gateway:spacexai/grok-4.1-fast-reasoning": { input: 0.2, output: 0.5, cacheRead: 0.05, cacheWrite: 0 }, + "vercel-ai-gateway:spacexai/grok-4.20-multi-agent": { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, + "vercel-ai-gateway:spacexai/grok-4.20-multi-agent-beta": { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, + "vercel-ai-gateway:spacexai/grok-4.20-non-reasoning": { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, + "vercel-ai-gateway:spacexai/grok-4.20-non-reasoning-beta": { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, + "vercel-ai-gateway:spacexai/grok-4.20-reasoning": { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, + "vercel-ai-gateway:spacexai/grok-4.20-reasoning-beta": { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, + "vercel-ai-gateway:spacexai/grok-4.3": { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, + "vercel-ai-gateway:spacexai/grok-4.5": { input: 2, output: 6, cacheRead: 0.3, cacheWrite: 0 }, + "vercel-ai-gateway:spacexai/grok-4.6": { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, + "vercel-ai-gateway:spacexai/grok-build-0.1": { input: 1, output: 2, cacheRead: 0.2, cacheWrite: 0 }, + "vercel-ai-gateway:stepfun/step-3.5-flash": { input: 0.09, output: 0.3, cacheRead: 0.02, cacheWrite: 0 }, + "vercel-ai-gateway:stepfun/step-3.7-flash": { input: 0.2, output: 1.15, cacheRead: 0.04, cacheWrite: 0 }, + "vercel-ai-gateway:tencent/hy3": { input: 0.14, output: 0.58, cacheRead: 0.035, cacheWrite: 0 }, + "vercel-ai-gateway:tencent/hy4-preview": { input: 0.834, output: 2.501, cacheRead: 0.042, cacheWrite: 0 }, + "vercel-ai-gateway:thinkingmachines/inkling": { input: 1, output: 4.05, cacheRead: 0.17, cacheWrite: 0 }, + "vercel-ai-gateway:thinkingmachines/inkling-small": { input: 0.5, output: 1.2, cacheRead: 0.1, cacheWrite: 0 }, + "vercel-ai-gateway:xiaomi/mimo-v2.5": { input: 0.14, output: 0.28, cacheRead: 0.0028, cacheWrite: 0 }, + "vercel-ai-gateway:xiaomi/mimo-v2.5-pro": { input: 0.435, output: 0.87, cacheRead: 0.0036, cacheWrite: 0 }, + "vercel-ai-gateway:xiaomi/mimo-v2.5-pro-ultraspeed": { input: 1.305, output: 2.61, cacheRead: 0.0108, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-4.5": { input: 0.6, output: 2.2, cacheRead: 0.11, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-4.5-air": { input: 0.2, output: 1.1, cacheRead: 0.03, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-4.5v": { input: 0.6, output: 1.8, cacheRead: 0.11, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-4.6": { input: 0.6, output: 2.2, cacheRead: 0.11, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-4.7": { input: 0.6, output: 2.2, cacheRead: 0.12, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-4.7-flash": { input: 0.07, output: 0.4, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-4.7-flashx": { input: 0.06, output: 0.4, cacheRead: 0.01, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-5": { input: 1, output: 3.2, cacheRead: 0, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-5-turbo": { input: 1.2, output: 4, cacheRead: 0.24, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-5.1": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-5.2": { input: 0.8, output: 2.55, cacheRead: 0.16, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-5.2-fast": { input: 2.1, output: 6.6, cacheRead: 0.21, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-5.3": { input: 0.7, output: 2.2, cacheRead: 0.13, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-5.3-fast": { input: 2.1, output: 6.6, cacheRead: 0.21, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-5.3-flash": { input: 0.15, output: 0.5, cacheRead: 0.03, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-5.3-promo-50": { input: 0.7, output: 2.2, cacheRead: 0.13, cacheWrite: 0 }, + "vercel-ai-gateway:zai/glm-5v-turbo": { input: 1.2, output: 4, cacheRead: 0.24, cacheWrite: 0 }, + "xai:grok-4.3": { input: 1.25, output: 2.5, cacheRead: 0.2, cacheWrite: 0 }, + "xai:grok-4.5": { input: 2, output: 6, cacheRead: 0.3, cacheWrite: 0 }, + "xai:grok-4.6": { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, + "xiaomi-token-plan-ams:mimo-v2.5": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "xiaomi-token-plan-ams:mimo-v2.5-pro": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "xiaomi-token-plan-cn:mimo-v2.5": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "xiaomi-token-plan-cn:mimo-v2.5-pro": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "xiaomi-token-plan-sgp:mimo-v2.5": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "xiaomi-token-plan-sgp:mimo-v2.5-pro": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "xiaomi:mimo-v2.5": { input: 0.14, output: 0.28, cacheRead: 0.0028, cacheWrite: 0 }, + "xiaomi:mimo-v2.5-pro": { input: 0.435, output: 0.87, cacheRead: 0.0036, cacheWrite: 0 }, + "xiaomi:mimo-v2.5-pro-ultraspeed": { input: 1.305, output: 2.61, cacheRead: 0.0108, cacheWrite: 0 }, + "zai-coding-cn:glm-4.6v": { input: 0.3, output: 0.9, cacheRead: 0, cacheWrite: 0 }, + "zai-coding-cn:glm-4.7": { input: 0.6, output: 2.2, cacheRead: 0.11, cacheWrite: 0 }, + "zai-coding-cn:glm-5-turbo": { input: 1.2, output: 4, cacheRead: 0.24, cacheWrite: 0 }, + "zai-coding-cn:glm-5.1": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "zai-coding-cn:glm-5.2": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "zai-coding-cn:glm-5.2-highspeed": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "zai-coding-cn:glm-5.3": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "zai-coding-cn:glm-5.3-flash": { input: 0.075, output: 0.25, cacheRead: 0.015, cacheWrite: 0 }, + "zai-coding-cn:glm-5.3-highspeed": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "zai-coding-cn:glm-5v-turbo": { input: 1.2, output: 4, cacheRead: 0.24, cacheWrite: 0 }, + "zai:glm-4.7": { input: 0.6, output: 2.2, cacheRead: 0.11, cacheWrite: 0 }, + "zai:glm-5-turbo": { input: 1.2, output: 4, cacheRead: 0.24, cacheWrite: 0 }, + "zai:glm-5.2": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "zai:glm-5.2-highspeed": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + "zai:glm-5.3": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, + "zai:glm-5.3-flash": { input: 0.075, output: 0.25, cacheRead: 0.015, cacheWrite: 0 }, + "zai:glm-5.3-highspeed": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, }; -/** Context-window limits (tokens) per model — generated alongside PRICES. */ +/** Context-window limits (tokens) per model — generated alongside PRICES, + * same key families. */ export const CONTEXT_LIMITS: Record = { - "~anthropic/claude-fable-latest": 1000000, - "~anthropic/claude-haiku-latest": 200000, - "~anthropic/claude-opus-latest": 1000000, - "~anthropic/claude-sonnet-latest": 1000000, - "~deepseek/deepseek-v4-flash-latest": 1048576, - "~google/gemini-flash-latest": 1048576, - "~google/gemini-pro-latest": 1048576, - "~moonshotai/kimi-latest": 1048576, - "~openai/gpt-latest": 1050000, - "~openai/gpt-mini-latest": 400000, - "~x-ai/grok-latest": 500000, - "~z-ai/glm-flash-latest": 1048576, - "~z-ai/glm-latest": 262144, - "aion-labs/aion-2.0": 131072, - "aion-labs/aion-3.0": 131072, - "aion-labs/aion-3.0-mini": 131072, - "amazon/nova-2-lite-v1": 1000000, - "amazon/nova-lite-v1": 300000, - "amazon/nova-micro-v1": 128000, - "amazon/nova-premier-v1": 1000000, - "amazon/nova-pro-v1": 300000, - "anthropic/claude-3-haiku": 200000, - "anthropic/claude-fable-5": 1000000, - "anthropic/claude-fable-5:batch": 1000000, - "anthropic/claude-fable-5.1": 1000000, - "anthropic/claude-fable-5.1:batch": 1000000, - "anthropic/claude-haiku-4.5": 200000, - "anthropic/claude-haiku-4.5:batch": 200000, - "anthropic/claude-opus-4": 200000, - "anthropic/claude-opus-4.1": 200000, - "anthropic/claude-opus-4.1:batch": 200000, - "anthropic/claude-opus-4.5": 200000, - "anthropic/claude-opus-4.5:batch": 200000, - "anthropic/claude-opus-4.6": 1000000, - "anthropic/claude-opus-4.6:batch": 1000000, - "anthropic/claude-opus-4.7": 1000000, - "anthropic/claude-opus-4.7:batch": 1000000, - "anthropic/claude-opus-4.8": 1000000, - "anthropic/claude-opus-4.8:batch": 1000000, - "anthropic/claude-opus-5": 1000000, - "anthropic/claude-opus-5:batch": 1000000, - "anthropic/claude-sonnet-4": 200000, - "anthropic/claude-sonnet-4.5": 1000000, - "anthropic/claude-sonnet-4.5:batch": 1000000, - "anthropic/claude-sonnet-4.6": 1000000, - "anthropic/claude-sonnet-4.6:batch": 1000000, - "anthropic/claude-sonnet-5": 1000000, - "anthropic/claude-sonnet-5:batch": 1000000, - "arcee-ai/trinity-large-thinking": 262144, - "auto": 2000000, - "bytedance-seed/seed-1.6": 262144, - "bytedance-seed/seed-1.6-flash": 262144, - "bytedance-seed/seed-2-1-turbo": 262144, - "bytedance-seed/seed-2.0-code": 262144, - "bytedance-seed/seed-2.0-lite": 262144, - "bytedance-seed/seed-2.0-mini": 262144, - "cohere/command-r-08-2024": 128000, - "cohere/command-r-plus-08-2024": 128000, - "cohere/north-mini-code:free": 256000, - "deepseek/deepseek-chat": 163840, - "deepseek/deepseek-chat-v3-0324": 163840, - "deepseek/deepseek-chat-v3.1": 161000, - "deepseek/deepseek-r1": 64000, - "deepseek/deepseek-r1-0528": 163840, - "deepseek/deepseek-v3.1-terminus": 131072, - "deepseek/deepseek-v3.2": 163840, - "deepseek/deepseek-v3.2-exp": 163840, - "deepseek/deepseek-v4-flash": 1024000, - "deepseek/deepseek-v4-flash-0731": 1048576, - "deepseek/deepseek-v4-flash-0731:batch": 1048576, - "deepseek/deepseek-v4-flash-vision-exp": 1048576, - "deepseek/deepseek-v4-pro": 1024000, - "deepseek/deepseek-v4-pro-0813": 1024000, - "deepseek/deepseek-v4-pro-0813:batch": 1048576, - "dots-studio/dots-3-note-preview:free": 512000, - "google/gemini-2.5-flash": 1048576, - "google/gemini-2.5-flash-lite": 1048576, - "google/gemini-2.5-flash-lite:batch": 1048576, - "google/gemini-2.5-flash:batch": 1048576, - "google/gemini-2.5-pro": 1048576, - "google/gemini-2.5-pro-preview": 1048576, - "google/gemini-2.5-pro-preview-05-06": 1048576, - "google/gemini-2.5-pro:batch": 1048576, - "google/gemini-3-flash-preview": 1048576, - "google/gemini-3-flash-preview:batch": 1048576, - "google/gemini-3-pro-image": 65536, - "google/gemini-3.1-flash-lite": 1048576, - "google/gemini-3.1-flash-lite-preview": 1048576, - "google/gemini-3.1-flash-lite:batch": 1048576, - "google/gemini-3.1-pro-preview": 1048576, - "google/gemini-3.1-pro-preview-customtools": 1048576, - "google/gemini-3.1-pro-preview:batch": 1048576, - "google/gemini-3.5-flash": 1048576, - "google/gemini-3.5-flash-lite": 1048576, - "google/gemini-3.5-flash-lite:batch": 1048576, - "google/gemini-3.5-flash:batch": 1048576, - "google/gemini-3.6-flash": 1048576, - "google/gemini-3.6-flash:batch": 1048576, - "google/gemini-3.7-flash": 1048576, - "google/gemini-3.7-flash:batch": 1048576, - "google/gemini-3.8-flash": 1048576, - "google/gemini-3.8-flash:batch": 1048576, - "google/gemma-3-12b-it": 131072, - "google/gemma-3-27b-it": 131072, - "google/gemma-4-26b-a4b-it": 262144, - "google/gemma-4-26b-a4b-it:free": 262144, - "google/gemma-4-31b-it": 262144, - "google/gemma-4-31b-it:batch": 262144, - "google/gemma-4-31b-it:free": 262144, - "ibm-granite/granite-4.2-8b": 131072, - "inception/mercury-2": 128000, - "inception/mercury-2.5-preview": 260000, - "inclusionai/ling-3.0-flash": 262144, - "inclusionai/ling-3.0-flash-fin": 262144, - "inclusionai/ling-3.0-flash-fin:free": 262144, - "inclusionai/ling-3.0-flash-sante:free": 262144, - "kwaipilot/kat-coder-pro-v2": 262144, - "kwaipilot/kat-coder-pro-v2.5": 262144, - "liquid/lfm-2.5-2.6b:free": 65536, - "meituan/longcat-2.0": 1048756, - "meta-llama/llama-3.1-70b-instruct": 131072, - "meta-llama/llama-3.1-8b-instruct": 131072, - "meta-llama/llama-3.3-70b-instruct": 131072, - "meta-llama/llama-4-maverick": 128000, - "meta-llama/llama-4-scout": 327680, - "meta/muse-glimmer-30b": 131072, - "meta/muse-glimmer-30b:batch": 131072, - "meta/muse-spark-1.1": 1048576, - "meta/muse-spark-1.2": 1048576, - "meta/muse-spark-1.2-contributor": 1048576, - "meta/muse-spark-1.3": 1048576, - "meta/muse-spark-1.3-contributor": 1048576, - "minimax/minimax-m1": 1000000, - "minimax/minimax-m2": 204800, - "minimax/minimax-m2.1": 204800, - "minimax/minimax-m2.5": 200000, - "minimax/minimax-m2.7": 204800, - "minimax/minimax-m2.7:free": 196608, - "minimax/minimax-m3": 524288, - "minimax/minimax-m3:batch": 524288, - "minimax/minimax-m3:free": 1048576, - "mistralai/codestral-2508": 256000, - "mistralai/devstral-2512": 262144, - "mistralai/ministral-14b-2512": 262144, - "mistralai/ministral-3b-2512": 131072, - "mistralai/ministral-8b-2512": 262144, - "mistralai/mistral-large": 128000, - "mistralai/mistral-large-2407": 131072, - "mistralai/mistral-large-2512": 262144, - "mistralai/mistral-medium-3": 131072, - "mistralai/mistral-medium-3-5": 262144, - "mistralai/mistral-medium-3-5:batch": 32768, - "mistralai/mistral-medium-3.1": 131072, - "mistralai/mistral-nemo": 131072, - "mistralai/mistral-saba": 32768, - "mistralai/mistral-small-2603": 262144, - "mistralai/mistral-small-3.2-24b-instruct": 128000, - "mistralai/mixtral-8x22b-instruct": 65536, - "mistralai/voxtral-small-24b-2507": 32768, - "moonshotai/kimi-k2": 131072, - "moonshotai/kimi-k2-0905": 262144, - "moonshotai/kimi-k2-thinking": 262144, - "moonshotai/kimi-k2.5": 262144, - "moonshotai/kimi-k2.6": 262144, - "moonshotai/kimi-k2.7-code": 262144, - "moonshotai/kimi-k3": 1048576, - "moonshotai/kimi-k3:batch": 1048576, - "nex-agi/nex-n2-mini": 262144, - "nex-agi/nex-n2-pro": 262144, - "nvidia/nemotron-3-nano-30b-a3b": 262144, - "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free": 256000, - "nvidia/nemotron-3-super-120b-a12b": 262144, - "nvidia/nemotron-3-super-120b-a12b:free": 262144, - "nvidia/nemotron-3-ultra-550b-a55b": 256000, - "nvidia/nemotron-3-ultra-550b-a55b:free": 1000000, - "nvidia/nemotron-3.5-lightning": 262144, - "nvidia/nemotron-3.5-lightning:free": 1000000, - "openai/gpt-3.5-turbo": 16385, - "openai/gpt-3.5-turbo-0613": 4095, - "openai/gpt-3.5-turbo-16k": 16385, - "openai/gpt-3.5-turbo:batch": 16385, - "openai/gpt-4": 8191, - "openai/gpt-4-turbo": 128000, - "openai/gpt-4-turbo-preview": 128000, - "openai/gpt-4-turbo:batch": 128000, - "openai/gpt-4.1": 1047576, - "openai/gpt-4.1-mini": 1047576, - "openai/gpt-4.1-mini:batch": 1047576, - "openai/gpt-4.1-nano": 1047576, - "openai/gpt-4.1-nano:batch": 1047576, - "openai/gpt-4.1:batch": 1047576, - "openai/gpt-4o": 128000, - "openai/gpt-4o-2024-05-13": 128000, - "openai/gpt-4o-2024-08-06": 128000, - "openai/gpt-4o-2024-11-20": 128000, - "openai/gpt-4o-mini": 128000, - "openai/gpt-4o-mini-2024-07-18": 128000, - "openai/gpt-4o-mini:batch": 128000, - "openai/gpt-4o:batch": 128000, - "openai/gpt-5": 400000, - "openai/gpt-5-mini": 400000, - "openai/gpt-5-mini:batch": 400000, - "openai/gpt-5-nano": 400000, - "openai/gpt-5-nano:batch": 400000, - "openai/gpt-5-pro": 400000, - "openai/gpt-5-pro:batch": 400000, - "openai/gpt-5:batch": 400000, - "openai/gpt-5.1": 400000, - "openai/gpt-5.1-codex": 400000, - "openai/gpt-5.1-codex-max": 400000, - "openai/gpt-5.1-codex-mini": 400000, - "openai/gpt-5.1:batch": 400000, - "openai/gpt-5.2": 400000, - "openai/gpt-5.2-chat": 128000, - "openai/gpt-5.2-codex": 400000, - "openai/gpt-5.2-pro": 400000, - "openai/gpt-5.2-pro:batch": 400000, - "openai/gpt-5.2:batch": 400000, - "openai/gpt-5.3-codex": 400000, - "openai/gpt-5.4": 1050000, - "openai/gpt-5.4-mini": 400000, - "openai/gpt-5.4-mini:batch": 400000, - "openai/gpt-5.4-nano": 400000, - "openai/gpt-5.4-nano:batch": 400000, - "openai/gpt-5.4-pro": 1050000, - "openai/gpt-5.4-pro:batch": 1050000, - "openai/gpt-5.4:batch": 1050000, - "openai/gpt-5.5": 1050000, - "openai/gpt-5.5-pro": 1050000, - "openai/gpt-5.5-pro:batch": 1050000, - "openai/gpt-5.5:batch": 1050000, - "openai/gpt-5.6-luna": 1050000, - "openai/gpt-5.6-luna-pro": 1050000, - "openai/gpt-5.6-luna-pro:batch": 1050000, - "openai/gpt-5.6-luna:batch": 1050000, - "openai/gpt-5.6-sol": 1050000, - "openai/gpt-5.6-sol-pro": 1050000, - "openai/gpt-5.6-sol-pro:batch": 1050000, - "openai/gpt-5.6-sol:batch": 1050000, - "openai/gpt-5.6-terra": 1050000, - "openai/gpt-5.6-terra-pro": 1050000, - "openai/gpt-5.6-terra-pro:batch": 1050000, - "openai/gpt-5.6-terra:batch": 1050000, - "openai/gpt-6-astra": 1050000, - "openai/gpt-6-astra-pro": 1050000, - "openai/gpt-6-astra-pro:batch": 1050000, - "openai/gpt-6-astra:batch": 1050000, - "openai/gpt-audio": 128000, - "openai/gpt-audio-mini": 128000, - "openai/gpt-chat-latest": 400000, - "openai/gpt-oss-120b": 131072, - "openai/gpt-oss-120b:batch": 131072, - "openai/gpt-oss-20b": 131072, - "openai/gpt-oss-safeguard-20b": 131072, - "openai/o1": 200000, - "openai/o3": 200000, - "openai/o3-mini": 200000, - "openai/o3-mini-high": 200000, - "openai/o3-mini:batch": 200000, - "openai/o3-pro": 200000, - "openai/o3:batch": 200000, - "openai/o4-mini": 200000, - "openai/o4-mini-high": 200000, - "openai/o4-mini:batch": 200000, - "openrouter/auto": 2000000, - "openrouter/auto-beta": 2000000, - "openrouter/free": 200000, - "openrouter/fusion": 1000000, - "poolside/laguna-s-2.1": 1048576, - "poolside/laguna-s-2.1:free": 262144, - "poolside/laguna-xs-2.1": 262144, - "poolside/laguna-xs-2.1:free": 262144, - "qwen/qwen-2.5-72b-instruct": 32768, - "qwen/qwen-2.5-7b-instruct": 32768, - "qwen/qwen-plus": 1000000, - "qwen/qwen-plus-2025-07-28": 1000000, - "qwen/qwen3-14b": 40960, - "qwen/qwen3-235b-a22b": 131072, - "qwen/qwen3-235b-a22b-2507": 262144, - "qwen/qwen3-235b-a22b-thinking-2507": 131072, - "qwen/qwen3-30b-a3b": 40960, - "qwen/qwen3-30b-a3b-instruct-2507": 128000, - "qwen/qwen3-30b-a3b-thinking-2507": 81920, - "qwen/qwen3-32b": 40960, - "qwen/qwen3-8b": 131072, - "qwen/qwen3-coder": 262144, - "qwen/qwen3-coder-30b-a3b-instruct": 262144, - "qwen/qwen3-coder-flash": 1000000, - "qwen/qwen3-coder-next": 262144, - "qwen/qwen3-coder-plus": 1000000, - "qwen/qwen3-max": 262144, - "qwen/qwen3-max-thinking": 262144, - "qwen/qwen3-next-80b-a3b-instruct": 262144, - "qwen/qwen3-next-80b-a3b-thinking": 131072, - "qwen/qwen3-vl-235b-a22b-instruct": 131072, - "qwen/qwen3-vl-235b-a22b-thinking": 131072, - "qwen/qwen3-vl-30b-a3b-instruct": 262144, - "qwen/qwen3-vl-30b-a3b-thinking": 131072, - "qwen/qwen3-vl-32b-instruct": 131072, - "qwen/qwen3-vl-8b-instruct": 131072, - "qwen/qwen3-vl-8b-thinking": 131072, - "qwen/qwen3.5-122b-a10b": 262144, - "qwen/qwen3.5-27b": 262144, - "qwen/qwen3.5-35b-a3b": 262144, - "qwen/qwen3.5-397b-a17b": 262144, - "qwen/qwen3.5-9b": 262144, - "qwen/qwen3.5-9b:batch": 262144, - "qwen/qwen3.5-flash-02-23": 1000000, - "qwen/qwen3.5-plus-02-15": 1000000, - "qwen/qwen3.5-plus-20260420": 1000000, - "qwen/qwen3.6-27b": 262144, - "qwen/qwen3.6-35b-a3b": 262144, - "qwen/qwen3.6-flash": 1000000, - "qwen/qwen3.6-max-preview": 262144, - "qwen/qwen3.6-plus": 1000000, - "qwen/qwen3.7-flash": 1000000, - "qwen/qwen3.7-max": 1000000, - "qwen/qwen3.7-plus": 1000000, - "qwen/qwen3.8-2.4t-a95b": 1000000, - "qwen/qwen3.8-2.4t-a95b:batch": 1010000, - "qwen/qwen3.8-27b": 1000000, - "qwen/qwen3.8-flash": 1000000, - "qwen/qwen3.8-max-0902": 1000000, - "rekaai/reka-edge": 16384, - "relace/relace-search": 256000, - "sakana/fugu-ultra": 1000000, - "sakana/sakana-namazu": 262144, - "sao10k/l3.1-euryale-70b": 131072, - "stepfun/step-3.5-flash": 262144, - "stepfun/step-3.7-flash": 256000, - "tencent/hy3": 262144, - "tencent/hy3-preview": 262144, - "tencent/hy4-preview": 1048576, - "thedrummer/unslopnemo-12b": 32768, - "thinkingmachines/inkling": 524288, - "thinkingmachines/inkling-small": 524288, - "thinkingmachines/inkling-small:batch": 524288, - "thinkingmachines/inkling-small:free": 1048576, - "thinkingmachines/inkling:batch": 524288, - "thinkingmachines/inkling:free": 1048576, - "upstage/solar-pro-3": 131072, - "upstage/solar-pro4": 524288, - "x-ai/grok-4.20": 2000000, - "x-ai/grok-4.3": 1000000, - "x-ai/grok-4.3:batch": 1000000, - "x-ai/grok-4.5": 500000, - "x-ai/grok-4.6": 500000, - "x-ai/grok-build-0.1": 256000, - "xiaomi/mimo-v2.5": 1048576, - "xiaomi/mimo-v2.5-pro": 1048576, - "z-ai/glm-4.5": 131072, - "z-ai/glm-4.5-air": 131072, - "z-ai/glm-4.5v": 65536, - "z-ai/glm-4.6": 204800, - "z-ai/glm-4.6v": 131072, - "z-ai/glm-4.7": 202752, - "z-ai/glm-4.7-flash": 202752, - "z-ai/glm-5": 198000, - "z-ai/glm-5-turbo": 202752, - "z-ai/glm-5.1": 200000, - "z-ai/glm-5.2": 1048576, - "z-ai/glm-5.2:free": 256000, - "z-ai/glm-5.3": 1048576, - "z-ai/glm-5.3-flash": 1048576, - "z-ai/glm-5.3-flash:batch": 1048575, - "z-ai/glm-5v-turbo": 202752, + "amazon-bedrock:amazon.nova-2-lite-v1:0": 128000, + "amazon-bedrock:amazon.nova-lite-v1:0": 300000, + "amazon-bedrock:amazon.nova-micro-v1:0": 128000, + "amazon-bedrock:amazon.nova-pro-v1:0": 300000, + "amazon-bedrock:anthropic.claude-fable-5": 1000000, + "amazon-bedrock:anthropic.claude-fable-5-1": 1000000, + "amazon-bedrock:anthropic.claude-haiku-4-5-20251001-v1:0": 200000, + "amazon-bedrock:anthropic.claude-opus-4-1-20250805-v1:0": 200000, + "amazon-bedrock:anthropic.claude-opus-4-5-20251101-v1:0": 200000, + "amazon-bedrock:anthropic.claude-opus-4-6-v1": 1000000, + "amazon-bedrock:anthropic.claude-opus-4-7": 1000000, + "amazon-bedrock:anthropic.claude-opus-4-8": 1000000, + "amazon-bedrock:anthropic.claude-sonnet-4-5-20250929-v1:0": 200000, + "amazon-bedrock:anthropic.claude-sonnet-4-6": 1000000, + "amazon-bedrock:anthropic.claude-sonnet-5": 1000000, + "amazon-bedrock:au.anthropic.claude-haiku-4-5-20251001-v1:0": 200000, + "amazon-bedrock:au.anthropic.claude-opus-4-6-v1": 1000000, + "amazon-bedrock:au.anthropic.claude-opus-4-8": 1000000, + "amazon-bedrock:au.anthropic.claude-opus-5": 1000000, + "amazon-bedrock:au.anthropic.claude-sonnet-4-5-20250929-v1:0": 200000, + "amazon-bedrock:au.anthropic.claude-sonnet-4-6": 1000000, + "amazon-bedrock:au.anthropic.claude-sonnet-5": 1000000, + "amazon-bedrock:deepseek.r1-v1:0": 128000, + "amazon-bedrock:deepseek.v3-v1:0": 163840, + "amazon-bedrock:deepseek.v3.2": 163840, + "amazon-bedrock:eu.anthropic.claude-fable-5": 1000000, + "amazon-bedrock:eu.anthropic.claude-haiku-4-5-20251001-v1:0": 200000, + "amazon-bedrock:eu.anthropic.claude-opus-4-5-20251101-v1:0": 200000, + "amazon-bedrock:eu.anthropic.claude-opus-4-6-v1": 1000000, + "amazon-bedrock:eu.anthropic.claude-opus-4-7": 1000000, + "amazon-bedrock:eu.anthropic.claude-opus-4-8": 1000000, + "amazon-bedrock:eu.anthropic.claude-opus-5": 1000000, + "amazon-bedrock:eu.anthropic.claude-sonnet-4-5-20250929-v1:0": 200000, + "amazon-bedrock:eu.anthropic.claude-sonnet-4-6": 1000000, + "amazon-bedrock:eu.anthropic.claude-sonnet-5": 1000000, + "amazon-bedrock:global.anthropic.claude-fable-5": 1000000, + "amazon-bedrock:global.anthropic.claude-fable-5-1": 1000000, + "amazon-bedrock:global.anthropic.claude-haiku-4-5-20251001-v1:0": 200000, + "amazon-bedrock:global.anthropic.claude-opus-4-5-20251101-v1:0": 200000, + "amazon-bedrock:global.anthropic.claude-opus-4-6-v1": 1000000, + "amazon-bedrock:global.anthropic.claude-opus-4-7": 1000000, + "amazon-bedrock:global.anthropic.claude-opus-4-8": 1000000, + "amazon-bedrock:global.anthropic.claude-opus-5": 1000000, + "amazon-bedrock:global.anthropic.claude-sonnet-4-5-20250929-v1:0": 200000, + "amazon-bedrock:global.anthropic.claude-sonnet-4-6": 1000000, + "amazon-bedrock:global.anthropic.claude-sonnet-5": 1000000, + "amazon-bedrock:global.openai.gpt-5.6-luna": 1050000, + "amazon-bedrock:global.openai.gpt-5.6-sol": 1050000, + "amazon-bedrock:global.openai.gpt-5.6-terra": 1050000, + "amazon-bedrock:google.gemma-3-27b-it": 202752, + "amazon-bedrock:google.gemma-3-4b-it": 128000, + "amazon-bedrock:jp.anthropic.claude-haiku-4-5-20251001-v1:0": 200000, + "amazon-bedrock:jp.anthropic.claude-opus-4-7": 1000000, + "amazon-bedrock:jp.anthropic.claude-opus-4-8": 1000000, + "amazon-bedrock:jp.anthropic.claude-opus-5": 1000000, + "amazon-bedrock:jp.anthropic.claude-sonnet-4-5-20250929-v1:0": 200000, + "amazon-bedrock:jp.anthropic.claude-sonnet-4-6": 1000000, + "amazon-bedrock:jp.anthropic.claude-sonnet-5": 1000000, + "amazon-bedrock:meta.llama3-1-70b-instruct-v1:0": 128000, + "amazon-bedrock:meta.llama3-1-8b-instruct-v1:0": 128000, + "amazon-bedrock:meta.llama3-3-70b-instruct-v1:0": 128000, + "amazon-bedrock:meta.llama4-maverick-17b-instruct-v1:0": 1000000, + "amazon-bedrock:meta.llama4-scout-17b-instruct-v1:0": 3500000, + "amazon-bedrock:minimax.minimax-m2": 204608, + "amazon-bedrock:minimax.minimax-m2.1": 204800, + "amazon-bedrock:minimax.minimax-m2.5": 196608, + "amazon-bedrock:mistral.devstral-2-123b": 256000, + "amazon-bedrock:mistral.magistral-small-2509": 128000, + "amazon-bedrock:mistral.ministral-3-14b-instruct": 128000, + "amazon-bedrock:mistral.ministral-3-3b-instruct": 256000, + "amazon-bedrock:mistral.ministral-3-8b-instruct": 128000, + "amazon-bedrock:mistral.mistral-large-3-675b-instruct": 256000, + "amazon-bedrock:mistral.pixtral-large-2502-v1:0": 128000, + "amazon-bedrock:mistral.voxtral-mini-3b-2507": 128000, + "amazon-bedrock:mistral.voxtral-small-24b-2507": 32000, + "amazon-bedrock:moonshot.kimi-k2-thinking": 262143, + "amazon-bedrock:moonshotai.kimi-k2.5": 262143, + "amazon-bedrock:nvidia.nemotron-nano-12b-v2": 128000, + "amazon-bedrock:nvidia.nemotron-nano-3-30b": 128000, + "amazon-bedrock:nvidia.nemotron-nano-9b-v2": 128000, + "amazon-bedrock:nvidia.nemotron-super-3-120b": 262144, + "amazon-bedrock:openai.gpt-5.4": 272000, + "amazon-bedrock:openai.gpt-5.5": 272000, + "amazon-bedrock:openai.gpt-5.6-luna": 1050000, + "amazon-bedrock:openai.gpt-5.6-sol": 1050000, + "amazon-bedrock:openai.gpt-5.6-terra": 1050000, + "amazon-bedrock:openai.gpt-oss-120b": 128000, + "amazon-bedrock:openai.gpt-oss-120b-1:0": 128000, + "amazon-bedrock:openai.gpt-oss-20b": 128000, + "amazon-bedrock:openai.gpt-oss-20b-1:0": 128000, + "amazon-bedrock:openai.gpt-oss-safeguard-120b": 128000, + "amazon-bedrock:openai.gpt-oss-safeguard-20b": 128000, + "amazon-bedrock:qwen.qwen3-235b-a22b-2507-v1:0": 262144, + "amazon-bedrock:qwen.qwen3-32b-v1:0": 16384, + "amazon-bedrock:qwen.qwen3-coder-30b-a3b-v1:0": 262144, + "amazon-bedrock:qwen.qwen3-coder-480b-a35b-v1:0": 131072, + "amazon-bedrock:qwen.qwen3-coder-next": 131072, + "amazon-bedrock:qwen.qwen3-next-80b-a3b": 262000, + "amazon-bedrock:qwen.qwen3-vl-235b-a22b": 262000, + "amazon-bedrock:us.anthropic.claude-fable-5": 1000000, + "amazon-bedrock:us.anthropic.claude-fable-5-1": 1000000, + "amazon-bedrock:us.anthropic.claude-haiku-4-5-20251001-v1:0": 200000, + "amazon-bedrock:us.anthropic.claude-opus-4-1-20250805-v1:0": 200000, + "amazon-bedrock:us.anthropic.claude-opus-4-5-20251101-v1:0": 200000, + "amazon-bedrock:us.anthropic.claude-opus-4-6-v1": 1000000, + "amazon-bedrock:us.anthropic.claude-opus-4-7": 1000000, + "amazon-bedrock:us.anthropic.claude-opus-4-8": 1000000, + "amazon-bedrock:us.anthropic.claude-opus-5": 1000000, + "amazon-bedrock:us.anthropic.claude-sonnet-4-5-20250929-v1:0": 200000, + "amazon-bedrock:us.anthropic.claude-sonnet-4-6": 1000000, + "amazon-bedrock:us.anthropic.claude-sonnet-5": 1000000, + "amazon-bedrock:us.deepseek.r1-v1:0": 128000, + "amazon-bedrock:us.meta.llama4-maverick-17b-instruct-v1:0": 1000000, + "amazon-bedrock:us.meta.llama4-scout-17b-instruct-v1:0": 3500000, + "amazon-bedrock:writer.palmyra-x4-v1:0": 122880, + "amazon-bedrock:writer.palmyra-x5-v1:0": 1040000, + "amazon-bedrock:xai.grok-4.3": 1000000, + "amazon-bedrock:xai.grok-4.6": 500000, + "amazon-bedrock:zai.glm-4.7": 204800, + "amazon-bedrock:zai.glm-4.7-flash": 200000, + "amazon-bedrock:zai.glm-5": 202752, + "ant-ling:Ling-2.6-1T": 262144, + "ant-ling:Ling-2.6-flash": 262144, + "ant-ling:Ring-2.6-1T": 262144, + "anthropic:claude-fable-5": 1000000, + "anthropic:claude-fable-5-1": 1000000, + "anthropic:claude-haiku-4-5": 200000, + "anthropic:claude-haiku-4-5-20251001": 200000, + "anthropic:claude-opus-4-5": 200000, + "anthropic:claude-opus-4-5-20251101": 200000, + "anthropic:claude-opus-4-6": 1000000, + "anthropic:claude-opus-4-7": 1000000, + "anthropic:claude-opus-4-8": 1000000, + "anthropic:claude-opus-5": 1000000, + "anthropic:claude-sonnet-4-5": 1000000, + "anthropic:claude-sonnet-4-5-20250929": 1000000, + "anthropic:claude-sonnet-4-6": 1000000, + "anthropic:claude-sonnet-5": 1000000, + "azure-openai-responses:gpt-4": 8192, + "azure-openai-responses:gpt-4-turbo": 128000, + "azure-openai-responses:gpt-4.1": 1047576, + "azure-openai-responses:gpt-4.1-mini": 1047576, + "azure-openai-responses:gpt-4.1-nano": 1047576, + "azure-openai-responses:gpt-4o": 128000, + "azure-openai-responses:gpt-4o-2024-05-13": 128000, + "azure-openai-responses:gpt-4o-2024-08-06": 128000, + "azure-openai-responses:gpt-4o-2024-11-20": 128000, + "azure-openai-responses:gpt-4o-mini": 128000, + "azure-openai-responses:gpt-5": 400000, + "azure-openai-responses:gpt-5-chat-latest": 128000, + "azure-openai-responses:gpt-5-mini": 400000, + "azure-openai-responses:gpt-5-nano": 400000, + "azure-openai-responses:gpt-5-pro": 400000, + "azure-openai-responses:gpt-5.1": 400000, + "azure-openai-responses:gpt-5.2": 400000, + "azure-openai-responses:gpt-5.2-chat-latest": 128000, + "azure-openai-responses:gpt-5.2-pro": 400000, + "azure-openai-responses:gpt-5.3-chat-latest": 128000, + "azure-openai-responses:gpt-5.3-codex": 400000, + "azure-openai-responses:gpt-5.3-codex-spark": 128000, + "azure-openai-responses:gpt-5.4": 1050000, + "azure-openai-responses:gpt-5.4-mini": 400000, + "azure-openai-responses:gpt-5.4-nano": 400000, + "azure-openai-responses:gpt-5.4-pro": 1050000, + "azure-openai-responses:gpt-5.5": 1050000, + "azure-openai-responses:gpt-5.5-pro": 1050000, + "azure-openai-responses:gpt-5.6-luna": 1050000, + "azure-openai-responses:gpt-5.6-sol": 1050000, + "azure-openai-responses:gpt-5.6-terra": 1050000, + "azure-openai-responses:gpt-6-astra": 272000, + "azure-openai-responses:gpt-realtime-2.1": 128000, + "azure-openai-responses:o1": 200000, + "azure-openai-responses:o1-pro": 200000, + "azure-openai-responses:o3": 200000, + "azure-openai-responses:o3-mini": 200000, + "azure-openai-responses:o3-pro": 200000, + "azure-openai-responses:o4-mini": 200000, + "baseten:deepseek-ai/DeepSeek-V4-Flash-0731": 1048576, + "baseten:deepseek-ai/DeepSeek-V4-Pro": 1048576, + "baseten:deepseek-ai/DeepSeek-V4-Pro-0813": 1048576, + "baseten:moonshotai/Kimi-K2.5": 262000, + "baseten:moonshotai/Kimi-K2.6": 262000, + "baseten:moonshotai/Kimi-K2.7-Code": 262000, + "baseten:moonshotai/Kimi-K3": 1048576, + "baseten:nvidia/Nemotron-120B-A12B": 202800, + "baseten:nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B": 202800, + "baseten:openai/gpt-oss-120b": 128072, + "baseten:thinkingmachines/inkling": 1048576, + "baseten:thinkingmachines/inkling-small": 1048576, + "baseten:zai-org/GLM-4.7": 200000, + "baseten:zai-org/GLM-5": 202800, + "baseten:zai-org/GLM-5.1": 202800, + "baseten:zai-org/GLM-5.2": 1048576, + "baseten:zai-org/GLM-5.2-Fast": 1048576, + "baseten:zai-org/GLM-5.3": 1048576, + "baseten:zai-org/GLM-5.3-Fast": 1048576, + "baseten:zai-org/GLM-5.3-Flash": 1048576, + "cerebras:gemma-4-31b": 131072, + "cerebras:gpt-oss-120b": 131072, + "cloudflare-ai-gateway:claude-fable-5": 1000000, + "cloudflare-ai-gateway:claude-fable-5.1": 1000000, + "cloudflare-ai-gateway:claude-haiku-4.5": 200000, + "cloudflare-ai-gateway:claude-opus-4.5": 200000, + "cloudflare-ai-gateway:claude-opus-4.6": 1000000, + "cloudflare-ai-gateway:claude-opus-4.7": 1000000, + "cloudflare-ai-gateway:claude-opus-4.8": 1000000, + "cloudflare-ai-gateway:claude-opus-5": 1000000, + "cloudflare-ai-gateway:claude-sonnet-4.5": 1000000, + "cloudflare-ai-gateway:claude-sonnet-4.6": 1000000, + "cloudflare-ai-gateway:claude-sonnet-5": 1000000, + "cloudflare-ai-gateway:gpt-4.1": 1047576, + "cloudflare-ai-gateway:gpt-4.1-mini": 1047576, + "cloudflare-ai-gateway:gpt-4.1-nano": 1000000, + "cloudflare-ai-gateway:gpt-4o": 128000, + "cloudflare-ai-gateway:gpt-4o-mini": 128000, + "cloudflare-ai-gateway:gpt-5": 128000, + "cloudflare-ai-gateway:gpt-5-mini": 128000, + "cloudflare-ai-gateway:gpt-5-nano": 128000, + "cloudflare-ai-gateway:gpt-5.1": 128000, + "cloudflare-ai-gateway:gpt-5.4": 1000000, + "cloudflare-ai-gateway:gpt-5.4-mini": 128000, + "cloudflare-ai-gateway:gpt-5.4-nano": 128000, + "cloudflare-ai-gateway:gpt-5.4-pro": 1000000, + "cloudflare-ai-gateway:gpt-5.5": 1000000, + "cloudflare-ai-gateway:gpt-5.5-pro": 1000000, + "cloudflare-ai-gateway:gpt-5.6-luna": 1050000, + "cloudflare-ai-gateway:gpt-5.6-sol": 1050000, + "cloudflare-ai-gateway:gpt-5.6-terra": 1050000, + "cloudflare-ai-gateway:o3": 200000, + "cloudflare-ai-gateway:o3-mini": 200000, + "cloudflare-ai-gateway:o4-mini": 200000, + "cloudflare-ai-gateway:workers-ai/@cf/deepseek-ai/deepseek-v4-flash-0731": 1310720, + "cloudflare-ai-gateway:workers-ai/@cf/deepseek-ai/deepseek-v4-pro-0813": 1048576, + "cloudflare-ai-gateway:workers-ai/@cf/google/gemma-4-26b-a4b-it": 256000, + "cloudflare-ai-gateway:workers-ai/@cf/ibm-granite/granite-4.0-h-micro": 131000, + "cloudflare-ai-gateway:workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast": 24000, + "cloudflare-ai-gateway:workers-ai/@cf/meta/llama-4-scout-17b-16e-instruct": 131000, + "cloudflare-ai-gateway:workers-ai/@cf/mistralai/mistral-small-3.1-24b-instruct": 128000, + "cloudflare-ai-gateway:workers-ai/@cf/moonshotai/kimi-k2.6": 262144, + "cloudflare-ai-gateway:workers-ai/@cf/moonshotai/kimi-k2.7-code": 262144, + "cloudflare-ai-gateway:workers-ai/@cf/nvidia/nemotron-3-120b-a12b": 256000, + "cloudflare-ai-gateway:workers-ai/@cf/openai/gpt-oss-120b": 128000, + "cloudflare-ai-gateway:workers-ai/@cf/openai/gpt-oss-20b": 128000, + "cloudflare-ai-gateway:workers-ai/@cf/qwen/qwen3-30b-a3b-fp8": 32768, + "cloudflare-ai-gateway:workers-ai/@cf/qwen/qwen3.8-27b": 262144, + "cloudflare-ai-gateway:workers-ai/@cf/zai-org/glm-4.7-flash": 131072, + "cloudflare-ai-gateway:workers-ai/@cf/zai-org/glm-5.2": 262144, + "cloudflare-ai-gateway:workers-ai/@cf/zai-org/glm-5.3": 1310720, + "cloudflare-ai-gateway:workers-ai/@cf/zai-org/glm-5.3-flash": 1310720, + "cloudflare-workers-ai:@cf/deepseek-ai/deepseek-v4-flash-0731": 1310720, + "cloudflare-workers-ai:@cf/deepseek-ai/deepseek-v4-pro-0813": 1048576, + "cloudflare-workers-ai:@cf/google/gemma-4-26b-a4b-it": 256000, + "cloudflare-workers-ai:@cf/ibm-granite/granite-4.0-h-micro": 131000, + "cloudflare-workers-ai:@cf/meta/llama-3.3-70b-instruct-fp8-fast": 24000, + "cloudflare-workers-ai:@cf/meta/llama-4-scout-17b-16e-instruct": 131000, + "cloudflare-workers-ai:@cf/mistralai/mistral-small-3.1-24b-instruct": 128000, + "cloudflare-workers-ai:@cf/moonshotai/kimi-k2.6": 262144, + "cloudflare-workers-ai:@cf/moonshotai/kimi-k2.7-code": 262144, + "cloudflare-workers-ai:@cf/nvidia/nemotron-3-120b-a12b": 256000, + "cloudflare-workers-ai:@cf/openai/gpt-oss-120b": 128000, + "cloudflare-workers-ai:@cf/openai/gpt-oss-20b": 128000, + "cloudflare-workers-ai:@cf/qwen/qwen3-30b-a3b-fp8": 32768, + "cloudflare-workers-ai:@cf/qwen/qwen3.8-27b": 262144, + "cloudflare-workers-ai:@cf/zai-org/glm-4.7-flash": 131072, + "cloudflare-workers-ai:@cf/zai-org/glm-5.2": 262144, + "cloudflare-workers-ai:@cf/zai-org/glm-5.3": 1310720, + "cloudflare-workers-ai:@cf/zai-org/glm-5.3-flash": 1310720, + "deepseek:deepseek-v4-flash": 1000000, + "deepseek:deepseek-v4-flash-vision-exp": 1000000, + "deepseek:deepseek-v4-pro": 1000000, + "fireworks:accounts/fireworks/models/deepseek-v4-flash-0731": 1000000, + "fireworks:accounts/fireworks/models/deepseek-v4-flash-vision-exp": 1000000, + "fireworks:accounts/fireworks/models/deepseek-v4-pro-0813": 1000000, + "fireworks:accounts/fireworks/models/glm-5p2": 1048575, + "fireworks:accounts/fireworks/models/glm-5p3": 1000000, + "fireworks:accounts/fireworks/models/glm-5p3-flash": 1000000, + "fireworks:accounts/fireworks/models/gpt-oss-120b": 131072, + "fireworks:accounts/fireworks/models/inkling": 1048576, + "fireworks:accounts/fireworks/models/kimi-k2p6": 262000, + "fireworks:accounts/fireworks/models/kimi-k2p7-code": 262000, + "fireworks:accounts/fireworks/models/kimi-k3": 1048576, + "fireworks:accounts/fireworks/models/minimax-m3": 512000, + "fireworks:accounts/fireworks/models/muse-glimmer-30b": 131072, + "fireworks:accounts/fireworks/models/nemotron-3-ultra-nvfp4": 262144, + "fireworks:accounts/fireworks/models/nemotron-lightning-3p5-30b-a3b": 262144, + "fireworks:accounts/fireworks/models/qwen3p7-plus": 262144, + "fireworks:accounts/fireworks/models/qwen3p8-2p4t-a95b": 262144, + "fireworks:accounts/fireworks/models/qwen3p8-max": 262144, + "fireworks:accounts/fireworks/routers/glm-5p2-fast": 1048575, + "fireworks:accounts/fireworks/routers/kimi-k3-fast": 1048576, + "github-copilot:claude-fable-5": 1000000, + "github-copilot:claude-fable-5.1": 1000000, + "github-copilot:claude-haiku-4.5": 200000, + "github-copilot:claude-opus-4.7": 1000000, + "github-copilot:claude-opus-4.8": 1000000, + "github-copilot:claude-opus-5": 1000000, + "github-copilot:claude-sonnet-4.6": 1000000, + "github-copilot:claude-sonnet-5": 1000000, + "github-copilot:gemini-3.5-flash": 200000, + "github-copilot:gemini-3.6-flash": 1000000, + "github-copilot:gemini-3.7-flash": 1000000, + "github-copilot:gemini-3.8-flash": 1000000, + "github-copilot:gpt-5-mini": 264000, + "github-copilot:gpt-5.3-codex": 1000000, + "github-copilot:gpt-5.4": 1000000, + "github-copilot:gpt-5.4-mini": 400000, + "github-copilot:gpt-5.4-nano": 400000, + "github-copilot:gpt-5.5": 1000000, + "github-copilot:gpt-5.6-luna": 1050000, + "github-copilot:gpt-5.6-sol": 1050000, + "github-copilot:gpt-5.6-terra": 1050000, + "github-copilot:gpt-6-astra": 1050000, + "github-copilot:grok-4.5": 500000, + "github-copilot:grok-4.6": 500000, + "github-copilot:kimi-k2.7-code": 256000, + "github-copilot:kimi-k3": 1048576, + "github-copilot:mai-code-1-flash-picker": 256000, + "github-copilot:mai-code-1.1-flash": 256000, + "google-vertex:gemini-2.5-flash": 1048576, + "google-vertex:gemini-2.5-flash-lite": 1048576, + "google-vertex:gemini-2.5-pro": 1048576, + "google-vertex:gemini-3-flash-preview": 1048576, + "google-vertex:gemini-3.1-flash-lite": 1048576, + "google-vertex:gemini-3.1-pro-preview": 1048576, + "google-vertex:gemini-3.1-pro-preview-customtools": 1048576, + "google-vertex:gemini-3.5-flash": 1048576, + "google-vertex:gemini-3.5-flash-lite": 1048576, + "google-vertex:gemini-3.6-flash": 1048576, + "google-vertex:gemini-3.7-flash": 1048576, + "google-vertex:gemini-3.8-flash": 1048576, + "google-vertex:gemini-flash-latest": 1048576, + "google-vertex:gemini-flash-lite-latest": 1048576, + "google:deep-research-max-preview-04-2026": 131072, + "google:deep-research-preview-04-2026": 131072, + "google:gemini-2.5-computer-use-preview-10-2025": 131072, + "google:gemini-2.5-flash": 1048576, + "google:gemini-2.5-flash-lite": 1048576, + "google:gemini-2.5-pro": 1048576, + "google:gemini-3-flash-preview": 1048576, + "google:gemini-3.1-flash-lite": 1048576, + "google:gemini-3.1-flash-lite-image": 65536, + "google:gemini-3.1-flash-lite-preview": 1048576, + "google:gemini-3.1-flash-live-preview": 131072, + "google:gemini-3.1-pro-preview": 1048576, + "google:gemini-3.1-pro-preview-customtools": 1048576, + "google:gemini-3.5-flash": 1048576, + "google:gemini-3.5-flash-lite": 1048576, + "google:gemini-3.6-flash": 1048576, + "google:gemini-3.7-flash": 1048576, + "google:gemini-3.8-flash": 1048576, + "google:gemini-flash-latest": 1048576, + "google:gemini-flash-lite-latest": 1048576, + "google:gemma-4-26b-a4b-it": 262144, + "google:gemma-4-31b-it": 262144, + "groq:llama-3.1-8b-instant": 131072, + "groq:llama-3.3-70b-versatile": 131072, + "groq:openai/gpt-oss-120b": 131072, + "groq:openai/gpt-oss-20b": 131072, + "groq:openai/gpt-oss-safeguard-20b": 131072, + "groq:qwen/qwen3.6-27b": 131072, + "groq:qwen/qwen3.8-27b": 131042, + "huggingface:deepseek-ai/DeepSeek-R1": 64000, + "huggingface:deepseek-ai/DeepSeek-R1-0528": 163840, + "huggingface:deepseek-ai/DeepSeek-V3": 64000, + "huggingface:deepseek-ai/DeepSeek-V3-0324": 163840, + "huggingface:deepseek-ai/DeepSeek-V3.1": 131072, + "huggingface:deepseek-ai/DeepSeek-V3.2": 163840, + "huggingface:deepseek-ai/DeepSeek-V4-Flash": 1048576, + "huggingface:deepseek-ai/DeepSeek-V4-Flash-0731": 1048576, + "huggingface:deepseek-ai/DeepSeek-V4-Flash-Vision-Exp": 1048576, + "huggingface:deepseek-ai/DeepSeek-V4-Pro": 1048576, + "huggingface:deepseek-ai/DeepSeek-V4-Pro-0813": 1000000, + "huggingface:google/gemma-4-26B-A4B-it": 262144, + "huggingface:google/gemma-4-31B-it": 262144, + "huggingface:meta-llama/Llama-3.1-8B-Instruct": 131072, + "huggingface:meta-llama/Llama-3.3-70B-Instruct": 131072, + "huggingface:MiniMaxAI/MiniMax-M2": 204800, + "huggingface:MiniMaxAI/MiniMax-M2.1": 204800, + "huggingface:MiniMaxAI/MiniMax-M2.5": 204800, + "huggingface:MiniMaxAI/MiniMax-M2.7": 204800, + "huggingface:MiniMaxAI/MiniMax-M3": 524288, + "huggingface:moonshotai/Kimi-K2-Instruct": 131072, + "huggingface:moonshotai/Kimi-K2-Instruct-0905": 262144, + "huggingface:moonshotai/Kimi-K2-Thinking": 262144, + "huggingface:moonshotai/Kimi-K2.5": 262144, + "huggingface:moonshotai/Kimi-K2.6": 262144, + "huggingface:moonshotai/Kimi-K2.7-Code": 262144, + "huggingface:moonshotai/Kimi-K3": 1000000, + "huggingface:openai/gpt-oss-120b": 131072, + "huggingface:openai/gpt-oss-20b": 131072, + "huggingface:Qwen/Qwen2.5-Coder-32B-Instruct": 131072, + "huggingface:Qwen/Qwen3-235B-A22B": 40960, + "huggingface:Qwen/Qwen3-235B-A22B-Instruct-2507": 262144, + "huggingface:Qwen/Qwen3-235B-A22B-Thinking-2507": 262144, + "huggingface:Qwen/Qwen3-30B-A3B": 40960, + "huggingface:Qwen/Qwen3-32B": 131072, + "huggingface:Qwen/Qwen3-Coder-30B-A3B-Instruct": 262144, + "huggingface:Qwen/Qwen3-Coder-480B-A35B-Instruct": 262144, + "huggingface:Qwen/Qwen3-Coder-Next": 262144, + "huggingface:Qwen/Qwen3-Next-80B-A3B-Instruct": 262144, + "huggingface:Qwen/Qwen3-Next-80B-A3B-Thinking": 262144, + "huggingface:Qwen/Qwen3-VL-235B-A22B-Instruct": 131072, + "huggingface:Qwen/Qwen3-VL-235B-A22B-Thinking": 131072, + "huggingface:Qwen/Qwen3.5-122B-A10B": 262144, + "huggingface:Qwen/Qwen3.5-27B": 262144, + "huggingface:Qwen/Qwen3.5-35B-A3B": 262144, + "huggingface:Qwen/Qwen3.5-397B-A17B": 262144, + "huggingface:Qwen/Qwen3.5-9B": 262144, + "huggingface:Qwen/Qwen3.6-27B": 262144, + "huggingface:Qwen/Qwen3.6-35B-A3B": 262144, + "huggingface:Qwen/Qwen3.8-2.4T-A95B": 262144, + "huggingface:Qwen/Qwen3.8-27B": 262144, + "huggingface:stepfun-ai/Step-3.5-Flash": 262144, + "huggingface:stepfun-ai/Step-3.7-Flash": 262144, + "huggingface:tencent/Hy3": 262144, + "huggingface:thinkingmachines/Inkling": 1048576, + "huggingface:thinkingmachines/Inkling-Small": 524288, + "huggingface:XiaomiMiMo/MiMo-V2-Flash": 262144, + "huggingface:XiaomiMiMo/MiMo-V2.5": 262144, + "huggingface:XiaomiMiMo/MiMo-V2.5-Pro": 1048576, + "huggingface:zai-org/GLM-4.5": 131072, + "huggingface:zai-org/GLM-4.5-Air": 131072, + "huggingface:zai-org/GLM-4.5V": 65536, + "huggingface:zai-org/GLM-4.6": 204800, + "huggingface:zai-org/GLM-4.6V-Flash": 131072, + "huggingface:zai-org/GLM-4.7": 204800, + "huggingface:zai-org/GLM-4.7-Flash": 200000, + "huggingface:zai-org/GLM-5": 202752, + "huggingface:zai-org/GLM-5.1": 202752, + "huggingface:zai-org/GLM-5.2": 262144, + "huggingface:zai-org/GLM-5.3": 1048576, + "huggingface:zai-org/GLM-5.3-Flash": 1048576, + "kimi-coding:k3": 1048576, + "kimi-coding:k3-256k": 262144, + "kimi-coding:kimi-for-coding": 262144, + "kimi-coding:kimi-for-coding-highspeed": 262144, + "minimax-cn:MiniMax-M2.7": 204800, + "minimax-cn:MiniMax-M2.7-highspeed": 204800, + "minimax-cn:MiniMax-M3": 1048576, + "minimax:MiniMax-M2.7": 204800, + "minimax:MiniMax-M2.7-highspeed": 204800, + "minimax:MiniMax-M3": 1048576, + "mistral:codestral-latest": 256000, + "mistral:devstral-2512": 262144, + "mistral:devstral-latest": 262144, + "mistral:devstral-medium-2507": 128000, + "mistral:devstral-medium-latest": 262144, + "mistral:devstral-small-2505": 128000, + "mistral:devstral-small-2507": 128000, + "mistral:labs-devstral-small-2512": 256000, + "mistral:magistral-medium-latest": 128000, + "mistral:magistral-small": 128000, + "mistral:ministral-3b-latest": 128000, + "mistral:ministral-8b-latest": 128000, + "mistral:mistral-large-2411": 131072, + "mistral:mistral-large-2512": 262144, + "mistral:mistral-large-latest": 262144, + "mistral:mistral-medium-2505": 131072, + "mistral:mistral-medium-2508": 262144, + "mistral:mistral-medium-2604": 262144, + "mistral:mistral-medium-3.5": 262144, + "mistral:mistral-medium-latest": 262144, + "mistral:mistral-nemo": 128000, + "mistral:mistral-small-2506": 128000, + "mistral:mistral-small-2603": 256000, + "mistral:mistral-small-latest": 256000, + "mistral:open-mistral-7b": 8000, + "mistral:open-mistral-nemo": 128000, + "mistral:open-mixtral-8x22b": 64000, + "mistral:open-mixtral-8x7b": 32000, + "mistral:pixtral-12b": 128000, + "mistral:pixtral-large-latest": 128000, + "mistral:voxtral-small-latest": 32000, + "mistral:zai-glm-5-2": 1000000, + "moonshotai-cn:kimi-k2-0711-preview": 131072, + "moonshotai-cn:kimi-k2-0905-preview": 262144, + "moonshotai-cn:kimi-k2-thinking": 262144, + "moonshotai-cn:kimi-k2-thinking-turbo": 262144, + "moonshotai-cn:kimi-k2-turbo-preview": 262144, + "moonshotai-cn:kimi-k2.5": 262144, + "moonshotai-cn:kimi-k2.6": 262144, + "moonshotai-cn:kimi-k2.7-code": 262144, + "moonshotai-cn:kimi-k2.7-code-highspeed": 262144, + "moonshotai-cn:kimi-k3": 1048576, + "moonshotai:kimi-k2-0711-preview": 131072, + "moonshotai:kimi-k2-0905-preview": 262144, + "moonshotai:kimi-k2-thinking": 262144, + "moonshotai:kimi-k2-thinking-turbo": 262144, + "moonshotai:kimi-k2-turbo-preview": 262144, + "moonshotai:kimi-k2.5": 262144, + "moonshotai:kimi-k2.6": 262144, + "moonshotai:kimi-k2.7-code": 262144, + "moonshotai:kimi-k2.7-code-highspeed": 262144, + "moonshotai:kimi-k3": 1048576, + "nvidia:deepseek-ai/deepseek-v4-flash-0731": 1000000, + "nvidia:deepseek-ai/deepseek-v4-pro-0813": 1000000, + "nvidia:google/gemma-3-12b-it": 131072, + "nvidia:google/gemma-3-4b-it": 131072, + "nvidia:meta/llama-3.2-11b-vision-instruct": 128000, + "nvidia:meta/llama-3.2-90b-vision-instruct": 128000, + "nvidia:meta/muse-glimmer-30b": 131072, + "nvidia:minimaxai/minimax-m3": 1000000, + "nvidia:mistralai/mistral-7b-instruct-v0.3": 65536, + "nvidia:moonshotai/kimi-k2.6": 262144, + "nvidia:moonshotai/kimi-k3": 1048576, + "nvidia:nvidia/cosmos-reason2-8b": 131072, + "nvidia:nvidia/llama-3.1-nemotron-70b-instruct": 128000, + "nvidia:nvidia/llama-3.1-nemotron-ultra-253b-v1": 128000, + "nvidia:nvidia/nemotron-3-nano-omni-30b-a3b-reasoning": 256000, + "nvidia:nvidia/nemotron-3-super-120b-a12b": 262144, + "nvidia:nvidia/nemotron-3-ultra-550b-a55b": 1000000, + "nvidia:nvidia/nemotron-3.5-lightning-30b-a3b": 262144, + "nvidia:openai/gpt-oss-20b": 131072, + "nvidia:poolside/laguna-xs-2.1": 262144, + "openai-codex:gpt-5.3-codex-spark": 128000, + "openai-codex:gpt-5.4": 272000, + "openai-codex:gpt-5.4-mini": 272000, + "openai-codex:gpt-5.5": 272000, + "openai-codex:gpt-5.6-luna": 272000, + "openai-codex:gpt-5.6-sol": 272000, + "openai-codex:gpt-5.6-terra": 272000, + "openai-codex:gpt-6-astra": 272000, + "openai:gpt-4": 8192, + "openai:gpt-4-turbo": 128000, + "openai:gpt-4.1": 1047576, + "openai:gpt-4.1-mini": 1047576, + "openai:gpt-4.1-nano": 1047576, + "openai:gpt-4o": 128000, + "openai:gpt-4o-2024-05-13": 128000, + "openai:gpt-4o-2024-08-06": 128000, + "openai:gpt-4o-2024-11-20": 128000, + "openai:gpt-4o-mini": 128000, + "openai:gpt-5": 400000, + "openai:gpt-5-chat-latest": 128000, + "openai:gpt-5-mini": 400000, + "openai:gpt-5-nano": 400000, + "openai:gpt-5-pro": 400000, + "openai:gpt-5.1": 400000, + "openai:gpt-5.2": 400000, + "openai:gpt-5.2-chat-latest": 128000, + "openai:gpt-5.2-pro": 400000, + "openai:gpt-5.3-chat-latest": 128000, + "openai:gpt-5.3-codex": 400000, + "openai:gpt-5.3-codex-spark": 128000, + "openai:gpt-5.4": 272000, + "openai:gpt-5.4-mini": 400000, + "openai:gpt-5.4-nano": 400000, + "openai:gpt-5.4-pro": 1050000, + "openai:gpt-5.5": 272000, + "openai:gpt-5.5-pro": 1050000, + "openai:gpt-5.6-luna": 272000, + "openai:gpt-5.6-sol": 272000, + "openai:gpt-5.6-terra": 272000, + "openai:gpt-6-astra": 272000, + "openai:gpt-realtime-2.1": 128000, + "openai:o1": 200000, + "openai:o1-pro": 200000, + "openai:o3": 200000, + "openai:o3-mini": 200000, + "openai:o3-pro": 200000, + "openai:o4-mini": 200000, + "opencode-go:deepseek-v4-flash": 1000000, + "opencode-go:deepseek-v4-flash-vision-exp": 1000000, + "opencode-go:deepseek-v4-pro": 1000000, + "opencode-go:glm-5.1": 202752, + "opencode-go:glm-5.2": 1000000, + "opencode-go:glm-5.3": 1000000, + "opencode-go:glm-5.3-flash": 1000000, + "opencode-go:gpt-5.6-luna": 1050000, + "opencode-go:grok-4.6": 500000, + "opencode-go:hy3": 256000, + "opencode-go:hy4-preview": 1024000, + "opencode-go:kimi-k2.6": 262144, + "opencode-go:kimi-k2.7-code": 262144, + "opencode-go:kimi-k3": 1048576, + "opencode-go:longcat-2.0": 1000000, + "opencode-go:mimo-v2.5": 1000000, + "opencode-go:mimo-v2.5-pro": 1048576, + "opencode-go:minimax-m2.7": 204800, + "opencode-go:minimax-m3": 1000000, + "opencode-go:muse-spark-1.2-contributor": 1048576, + "opencode-go:muse-spark-1.3-contributor": 1048576, + "opencode-go:omen-alpha": 500000, + "opencode-go:qwen3.6-plus": 1000000, + "opencode-go:qwen3.7-max": 1000000, + "opencode-go:qwen3.7-plus": 1000000, + "opencode-go:qwen3.8-flash": 1000000, + "opencode-go:qwen3.8-max": 1000000, + "opencode:big-pickle": 200000, + "opencode:claude-fable-5": 1000000, + "opencode:claude-fable-5-1": 1000000, + "opencode:claude-haiku-4-5": 200000, + "opencode:claude-opus-4-5": 200000, + "opencode:claude-opus-4-6": 1000000, + "opencode:claude-opus-4-7": 1000000, + "opencode:claude-opus-4-8": 1000000, + "opencode:claude-opus-5": 1000000, + "opencode:claude-sonnet-4": 200000, + "opencode:claude-sonnet-4-5": 200000, + "opencode:claude-sonnet-4-6": 1000000, + "opencode:claude-sonnet-5": 1000000, + "opencode:deepseek-v4-flash": 1000000, + "opencode:deepseek-v4-flash-vision-exp": 1000000, + "opencode:deepseek-v4-pro": 1000000, + "opencode:gemini-3-flash": 1048576, + "opencode:gemini-3.1-pro": 1048576, + "opencode:gemini-3.5-flash": 1048576, + "opencode:gemini-3.5-flash-lite": 1048576, + "opencode:gemini-3.6-flash": 1048576, + "opencode:gemini-3.7-flash": 1048576, + "opencode:gemini-3.8-flash": 1048576, + "opencode:glm-5": 204800, + "opencode:glm-5.1": 204800, + "opencode:glm-5.2": 1000000, + "opencode:glm-5.3": 1000000, + "opencode:glm-5.3-flash": 1000000, + "opencode:gpt-5": 400000, + "opencode:gpt-5-codex": 400000, + "opencode:gpt-5-nano": 400000, + "opencode:gpt-5.1": 400000, + "opencode:gpt-5.1-codex": 400000, + "opencode:gpt-5.1-codex-max": 400000, + "opencode:gpt-5.1-codex-mini": 400000, + "opencode:gpt-5.2": 400000, + "opencode:gpt-5.2-codex": 400000, + "opencode:gpt-5.3-codex": 400000, + "opencode:gpt-5.4": 272000, + "opencode:gpt-5.4-mini": 400000, + "opencode:gpt-5.4-nano": 400000, + "opencode:gpt-5.4-pro": 1050000, + "opencode:gpt-5.5": 1050000, + "opencode:gpt-5.5-pro": 1050000, + "opencode:gpt-5.6-luna": 1050000, + "opencode:gpt-5.6-sol": 1050000, + "opencode:gpt-5.6-terra": 1050000, + "opencode:gpt-6-astra": 1050000, + "opencode:grok-4.5": 500000, + "opencode:grok-4.6": 500000, + "opencode:grok-build-0.1": 256000, + "opencode:kimi-k2.5": 262144, + "opencode:kimi-k2.6": 262144, + "opencode:kimi-k2.7-code": 262144, + "opencode:kimi-k3": 1048576, + "opencode:ling-3.0-flash-fin-free": 262144, + "opencode:mimo-v2.5-free": 200000, + "opencode:minimax-m2.5": 204800, + "opencode:minimax-m2.7": 204800, + "opencode:minimax-m3": 512000, + "opencode:muse-spark-1.2": 1048576, + "opencode:muse-spark-1.2-contributor-free": 1048576, + "opencode:muse-spark-1.3": 1048576, + "opencode:muse-spark-1.3-contributor-free": 1048576, + "opencode:nemotron-3-ultra-free": 1000000, + "opencode:nemotron-3.5-lightning-free": 262144, + "opencode:qwen3.5-plus": 262144, + "opencode:qwen3.6-plus": 262144, + "openrouter:~anthropic/claude-fable-latest": 1000000, + "openrouter:~anthropic/claude-haiku-latest": 200000, + "openrouter:~anthropic/claude-opus-latest": 1000000, + "openrouter:~anthropic/claude-sonnet-latest": 1000000, + "openrouter:~deepseek/deepseek-v4-flash-latest": 1048576, + "openrouter:~google/gemini-flash-latest": 1048576, + "openrouter:~google/gemini-pro-latest": 1048576, + "openrouter:~moonshotai/kimi-latest": 1048576, + "openrouter:~openai/gpt-latest": 1050000, + "openrouter:~openai/gpt-mini-latest": 400000, + "openrouter:~x-ai/grok-latest": 500000, + "openrouter:~z-ai/glm-flash-latest": 1048576, + "openrouter:~z-ai/glm-latest": 262144, + "openrouter:aion-labs/aion-2.0": 131072, + "openrouter:aion-labs/aion-3.0": 131072, + "openrouter:aion-labs/aion-3.0-mini": 131072, + "openrouter:amazon/nova-2-lite-v1": 1000000, + "openrouter:amazon/nova-lite-v1": 300000, + "openrouter:amazon/nova-micro-v1": 128000, + "openrouter:amazon/nova-premier-v1": 1000000, + "openrouter:amazon/nova-pro-v1": 300000, + "openrouter:anthropic/claude-3-haiku": 200000, + "openrouter:anthropic/claude-fable-5": 1000000, + "openrouter:anthropic/claude-fable-5:batch": 1000000, + "openrouter:anthropic/claude-fable-5.1": 1000000, + "openrouter:anthropic/claude-fable-5.1:batch": 1000000, + "openrouter:anthropic/claude-haiku-4.5": 200000, + "openrouter:anthropic/claude-haiku-4.5:batch": 200000, + "openrouter:anthropic/claude-opus-4": 200000, + "openrouter:anthropic/claude-opus-4.1": 200000, + "openrouter:anthropic/claude-opus-4.1:batch": 200000, + "openrouter:anthropic/claude-opus-4.5": 200000, + "openrouter:anthropic/claude-opus-4.5:batch": 200000, + "openrouter:anthropic/claude-opus-4.6": 1000000, + "openrouter:anthropic/claude-opus-4.6:batch": 1000000, + "openrouter:anthropic/claude-opus-4.7": 1000000, + "openrouter:anthropic/claude-opus-4.7:batch": 1000000, + "openrouter:anthropic/claude-opus-4.8": 1000000, + "openrouter:anthropic/claude-opus-4.8:batch": 1000000, + "openrouter:anthropic/claude-opus-5": 1000000, + "openrouter:anthropic/claude-opus-5:batch": 1000000, + "openrouter:anthropic/claude-sonnet-4": 200000, + "openrouter:anthropic/claude-sonnet-4.5": 1000000, + "openrouter:anthropic/claude-sonnet-4.5:batch": 1000000, + "openrouter:anthropic/claude-sonnet-4.6": 1000000, + "openrouter:anthropic/claude-sonnet-4.6:batch": 1000000, + "openrouter:anthropic/claude-sonnet-5": 1000000, + "openrouter:anthropic/claude-sonnet-5:batch": 1000000, + "openrouter:arcee-ai/trinity-large-thinking": 262144, + "openrouter:auto": 2000000, + "openrouter:bytedance-seed/seed-1.6": 262144, + "openrouter:bytedance-seed/seed-1.6-flash": 262144, + "openrouter:bytedance-seed/seed-2-1-turbo": 262144, + "openrouter:bytedance-seed/seed-2.0-code": 262144, + "openrouter:bytedance-seed/seed-2.0-lite": 262144, + "openrouter:bytedance-seed/seed-2.0-mini": 262144, + "openrouter:cohere/command-r-08-2024": 128000, + "openrouter:cohere/command-r-plus-08-2024": 128000, + "openrouter:cohere/north-mini-code:free": 256000, + "openrouter:deepseek/deepseek-chat": 163840, + "openrouter:deepseek/deepseek-chat-v3-0324": 163840, + "openrouter:deepseek/deepseek-chat-v3.1": 161000, + "openrouter:deepseek/deepseek-r1": 64000, + "openrouter:deepseek/deepseek-r1-0528": 163840, + "openrouter:deepseek/deepseek-v3.1-terminus": 131072, + "openrouter:deepseek/deepseek-v3.2": 163840, + "openrouter:deepseek/deepseek-v3.2-exp": 163840, + "openrouter:deepseek/deepseek-v4-flash": 1024000, + "openrouter:deepseek/deepseek-v4-flash-0731": 1048576, + "openrouter:deepseek/deepseek-v4-flash-0731:batch": 1048576, + "openrouter:deepseek/deepseek-v4-flash-vision-exp": 1048576, + "openrouter:deepseek/deepseek-v4-pro": 1024000, + "openrouter:deepseek/deepseek-v4-pro-0813": 1024000, + "openrouter:deepseek/deepseek-v4-pro-0813:batch": 1048576, + "openrouter:dots-studio/dots-3-note-preview:free": 512000, + "openrouter:google/gemini-2.5-flash": 1048576, + "openrouter:google/gemini-2.5-flash-lite": 1048576, + "openrouter:google/gemini-2.5-flash-lite:batch": 1048576, + "openrouter:google/gemini-2.5-flash:batch": 1048576, + "openrouter:google/gemini-2.5-pro": 1048576, + "openrouter:google/gemini-2.5-pro-preview": 1048576, + "openrouter:google/gemini-2.5-pro-preview-05-06": 1048576, + "openrouter:google/gemini-2.5-pro:batch": 1048576, + "openrouter:google/gemini-3-flash-preview": 1048576, + "openrouter:google/gemini-3-flash-preview:batch": 1048576, + "openrouter:google/gemini-3-pro-image": 65536, + "openrouter:google/gemini-3.1-flash-lite": 1048576, + "openrouter:google/gemini-3.1-flash-lite-preview": 1048576, + "openrouter:google/gemini-3.1-flash-lite:batch": 1048576, + "openrouter:google/gemini-3.1-pro-preview": 1048576, + "openrouter:google/gemini-3.1-pro-preview-customtools": 1048576, + "openrouter:google/gemini-3.1-pro-preview:batch": 1048576, + "openrouter:google/gemini-3.5-flash": 1048576, + "openrouter:google/gemini-3.5-flash-lite": 1048576, + "openrouter:google/gemini-3.5-flash-lite:batch": 1048576, + "openrouter:google/gemini-3.5-flash:batch": 1048576, + "openrouter:google/gemini-3.6-flash": 1048576, + "openrouter:google/gemini-3.6-flash:batch": 1048576, + "openrouter:google/gemini-3.7-flash": 1048576, + "openrouter:google/gemini-3.7-flash:batch": 1048576, + "openrouter:google/gemini-3.8-flash": 1048576, + "openrouter:google/gemini-3.8-flash:batch": 1048576, + "openrouter:google/gemma-3-12b-it": 131072, + "openrouter:google/gemma-3-27b-it": 131072, + "openrouter:google/gemma-4-26b-a4b-it": 262144, + "openrouter:google/gemma-4-26b-a4b-it:free": 262144, + "openrouter:google/gemma-4-31b-it": 262144, + "openrouter:google/gemma-4-31b-it:batch": 262144, + "openrouter:google/gemma-4-31b-it:free": 262144, + "openrouter:ibm-granite/granite-4.2-8b": 131072, + "openrouter:inception/mercury-2": 128000, + "openrouter:inception/mercury-2.5-preview": 260000, + "openrouter:inclusionai/ling-3.0-flash": 262144, + "openrouter:inclusionai/ling-3.0-flash-fin": 262144, + "openrouter:inclusionai/ling-3.0-flash-fin:free": 262144, + "openrouter:inclusionai/ling-3.0-flash-sante:free": 262144, + "openrouter:kwaipilot/kat-coder-pro-v2": 262144, + "openrouter:kwaipilot/kat-coder-pro-v2.5": 262144, + "openrouter:liquid/lfm-2.5-2.6b:free": 65536, + "openrouter:meituan/longcat-2.0": 1048756, + "openrouter:meta-llama/llama-3.1-70b-instruct": 131072, + "openrouter:meta-llama/llama-3.1-8b-instruct": 131072, + "openrouter:meta-llama/llama-3.3-70b-instruct": 131072, + "openrouter:meta-llama/llama-4-maverick": 128000, + "openrouter:meta-llama/llama-4-scout": 327680, + "openrouter:meta/muse-glimmer-30b": 131072, + "openrouter:meta/muse-glimmer-30b:batch": 131072, + "openrouter:meta/muse-spark-1.1": 1048576, + "openrouter:meta/muse-spark-1.2": 1048576, + "openrouter:meta/muse-spark-1.2-contributor": 1048576, + "openrouter:meta/muse-spark-1.3": 1048576, + "openrouter:meta/muse-spark-1.3-contributor": 1048576, + "openrouter:minimax/minimax-m1": 1000000, + "openrouter:minimax/minimax-m2": 204800, + "openrouter:minimax/minimax-m2.1": 204800, + "openrouter:minimax/minimax-m2.5": 200000, + "openrouter:minimax/minimax-m2.7": 204800, + "openrouter:minimax/minimax-m2.7:free": 196608, + "openrouter:minimax/minimax-m3": 524288, + "openrouter:minimax/minimax-m3:batch": 524288, + "openrouter:minimax/minimax-m3:free": 1048576, + "openrouter:mistralai/codestral-2508": 256000, + "openrouter:mistralai/devstral-2512": 262144, + "openrouter:mistralai/ministral-14b-2512": 262144, + "openrouter:mistralai/ministral-3b-2512": 131072, + "openrouter:mistralai/ministral-8b-2512": 262144, + "openrouter:mistralai/mistral-large": 128000, + "openrouter:mistralai/mistral-large-2407": 131072, + "openrouter:mistralai/mistral-large-2512": 262144, + "openrouter:mistralai/mistral-medium-3": 131072, + "openrouter:mistralai/mistral-medium-3-5": 262144, + "openrouter:mistralai/mistral-medium-3-5:batch": 32768, + "openrouter:mistralai/mistral-medium-3.1": 131072, + "openrouter:mistralai/mistral-nemo": 131072, + "openrouter:mistralai/mistral-saba": 32768, + "openrouter:mistralai/mistral-small-2603": 262144, + "openrouter:mistralai/mistral-small-3.2-24b-instruct": 128000, + "openrouter:mistralai/mixtral-8x22b-instruct": 65536, + "openrouter:mistralai/voxtral-small-24b-2507": 32768, + "openrouter:moonshotai/kimi-k2": 131072, + "openrouter:moonshotai/kimi-k2-0905": 262144, + "openrouter:moonshotai/kimi-k2-thinking": 262144, + "openrouter:moonshotai/kimi-k2.5": 262144, + "openrouter:moonshotai/kimi-k2.6": 262144, + "openrouter:moonshotai/kimi-k2.7-code": 262144, + "openrouter:moonshotai/kimi-k3": 1048576, + "openrouter:moonshotai/kimi-k3:batch": 1048576, + "openrouter:nex-agi/nex-n2-mini": 262144, + "openrouter:nex-agi/nex-n2-pro": 262144, + "openrouter:nvidia/nemotron-3-nano-30b-a3b": 262144, + "openrouter:nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free": 256000, + "openrouter:nvidia/nemotron-3-super-120b-a12b": 262144, + "openrouter:nvidia/nemotron-3-super-120b-a12b:free": 262144, + "openrouter:nvidia/nemotron-3-ultra-550b-a55b": 256000, + "openrouter:nvidia/nemotron-3-ultra-550b-a55b:free": 1000000, + "openrouter:nvidia/nemotron-3.5-lightning": 262144, + "openrouter:nvidia/nemotron-3.5-lightning:free": 1000000, + "openrouter:openai/gpt-3.5-turbo": 16385, + "openrouter:openai/gpt-3.5-turbo-0613": 4095, + "openrouter:openai/gpt-3.5-turbo-16k": 16385, + "openrouter:openai/gpt-3.5-turbo:batch": 16385, + "openrouter:openai/gpt-4": 8191, + "openrouter:openai/gpt-4-turbo": 128000, + "openrouter:openai/gpt-4-turbo-preview": 128000, + "openrouter:openai/gpt-4-turbo:batch": 128000, + "openrouter:openai/gpt-4.1": 1047576, + "openrouter:openai/gpt-4.1-mini": 1047576, + "openrouter:openai/gpt-4.1-mini:batch": 1047576, + "openrouter:openai/gpt-4.1-nano": 1047576, + "openrouter:openai/gpt-4.1-nano:batch": 1047576, + "openrouter:openai/gpt-4.1:batch": 1047576, + "openrouter:openai/gpt-4o": 128000, + "openrouter:openai/gpt-4o-2024-05-13": 128000, + "openrouter:openai/gpt-4o-2024-08-06": 128000, + "openrouter:openai/gpt-4o-2024-11-20": 128000, + "openrouter:openai/gpt-4o-mini": 128000, + "openrouter:openai/gpt-4o-mini-2024-07-18": 128000, + "openrouter:openai/gpt-4o-mini:batch": 128000, + "openrouter:openai/gpt-4o:batch": 128000, + "openrouter:openai/gpt-5": 400000, + "openrouter:openai/gpt-5-mini": 400000, + "openrouter:openai/gpt-5-mini:batch": 400000, + "openrouter:openai/gpt-5-nano": 400000, + "openrouter:openai/gpt-5-nano:batch": 400000, + "openrouter:openai/gpt-5-pro": 400000, + "openrouter:openai/gpt-5-pro:batch": 400000, + "openrouter:openai/gpt-5:batch": 400000, + "openrouter:openai/gpt-5.1": 400000, + "openrouter:openai/gpt-5.1-codex": 400000, + "openrouter:openai/gpt-5.1-codex-max": 400000, + "openrouter:openai/gpt-5.1-codex-mini": 400000, + "openrouter:openai/gpt-5.1:batch": 400000, + "openrouter:openai/gpt-5.2": 400000, + "openrouter:openai/gpt-5.2-chat": 128000, + "openrouter:openai/gpt-5.2-codex": 400000, + "openrouter:openai/gpt-5.2-pro": 400000, + "openrouter:openai/gpt-5.2-pro:batch": 400000, + "openrouter:openai/gpt-5.2:batch": 400000, + "openrouter:openai/gpt-5.3-codex": 400000, + "openrouter:openai/gpt-5.4": 1050000, + "openrouter:openai/gpt-5.4-mini": 400000, + "openrouter:openai/gpt-5.4-mini:batch": 400000, + "openrouter:openai/gpt-5.4-nano": 400000, + "openrouter:openai/gpt-5.4-nano:batch": 400000, + "openrouter:openai/gpt-5.4-pro": 1050000, + "openrouter:openai/gpt-5.4-pro:batch": 1050000, + "openrouter:openai/gpt-5.4:batch": 1050000, + "openrouter:openai/gpt-5.5": 1050000, + "openrouter:openai/gpt-5.5-pro": 1050000, + "openrouter:openai/gpt-5.5-pro:batch": 1050000, + "openrouter:openai/gpt-5.5:batch": 1050000, + "openrouter:openai/gpt-5.6-luna": 1050000, + "openrouter:openai/gpt-5.6-luna-pro": 1050000, + "openrouter:openai/gpt-5.6-luna-pro:batch": 1050000, + "openrouter:openai/gpt-5.6-luna:batch": 1050000, + "openrouter:openai/gpt-5.6-sol": 1050000, + "openrouter:openai/gpt-5.6-sol-pro": 1050000, + "openrouter:openai/gpt-5.6-sol-pro:batch": 1050000, + "openrouter:openai/gpt-5.6-sol:batch": 1050000, + "openrouter:openai/gpt-5.6-terra": 1050000, + "openrouter:openai/gpt-5.6-terra-pro": 1050000, + "openrouter:openai/gpt-5.6-terra-pro:batch": 1050000, + "openrouter:openai/gpt-5.6-terra:batch": 1050000, + "openrouter:openai/gpt-6-astra": 1050000, + "openrouter:openai/gpt-6-astra-pro": 1050000, + "openrouter:openai/gpt-6-astra-pro:batch": 1050000, + "openrouter:openai/gpt-6-astra:batch": 1050000, + "openrouter:openai/gpt-audio": 128000, + "openrouter:openai/gpt-audio-mini": 128000, + "openrouter:openai/gpt-chat-latest": 400000, + "openrouter:openai/gpt-oss-120b": 131072, + "openrouter:openai/gpt-oss-120b:batch": 131072, + "openrouter:openai/gpt-oss-20b": 131072, + "openrouter:openai/gpt-oss-safeguard-20b": 131072, + "openrouter:openai/o1": 200000, + "openrouter:openai/o3": 200000, + "openrouter:openai/o3-mini": 200000, + "openrouter:openai/o3-mini-high": 200000, + "openrouter:openai/o3-mini:batch": 200000, + "openrouter:openai/o3-pro": 200000, + "openrouter:openai/o3:batch": 200000, + "openrouter:openai/o4-mini": 200000, + "openrouter:openai/o4-mini-high": 200000, + "openrouter:openai/o4-mini:batch": 200000, + "openrouter:openrouter/auto": 2000000, + "openrouter:openrouter/auto-beta": 2000000, + "openrouter:openrouter/free": 200000, + "openrouter:openrouter/fusion": 1000000, + "openrouter:poolside/laguna-s-2.1": 1048576, + "openrouter:poolside/laguna-s-2.1:free": 262144, + "openrouter:poolside/laguna-xs-2.1": 262144, + "openrouter:poolside/laguna-xs-2.1:free": 262144, + "openrouter:qwen/qwen-2.5-72b-instruct": 32768, + "openrouter:qwen/qwen-2.5-7b-instruct": 32768, + "openrouter:qwen/qwen-plus": 1000000, + "openrouter:qwen/qwen-plus-2025-07-28": 1000000, + "openrouter:qwen/qwen3-14b": 40960, + "openrouter:qwen/qwen3-235b-a22b": 131072, + "openrouter:qwen/qwen3-235b-a22b-2507": 262144, + "openrouter:qwen/qwen3-235b-a22b-thinking-2507": 131072, + "openrouter:qwen/qwen3-30b-a3b": 40960, + "openrouter:qwen/qwen3-30b-a3b-instruct-2507": 128000, + "openrouter:qwen/qwen3-30b-a3b-thinking-2507": 81920, + "openrouter:qwen/qwen3-32b": 40960, + "openrouter:qwen/qwen3-8b": 131072, + "openrouter:qwen/qwen3-coder": 262144, + "openrouter:qwen/qwen3-coder-30b-a3b-instruct": 262144, + "openrouter:qwen/qwen3-coder-flash": 1000000, + "openrouter:qwen/qwen3-coder-next": 262144, + "openrouter:qwen/qwen3-coder-plus": 1000000, + "openrouter:qwen/qwen3-max": 262144, + "openrouter:qwen/qwen3-max-thinking": 262144, + "openrouter:qwen/qwen3-next-80b-a3b-instruct": 262144, + "openrouter:qwen/qwen3-next-80b-a3b-thinking": 131072, + "openrouter:qwen/qwen3-vl-235b-a22b-instruct": 131072, + "openrouter:qwen/qwen3-vl-235b-a22b-thinking": 131072, + "openrouter:qwen/qwen3-vl-30b-a3b-instruct": 262144, + "openrouter:qwen/qwen3-vl-30b-a3b-thinking": 131072, + "openrouter:qwen/qwen3-vl-32b-instruct": 131072, + "openrouter:qwen/qwen3-vl-8b-instruct": 131072, + "openrouter:qwen/qwen3-vl-8b-thinking": 131072, + "openrouter:qwen/qwen3.5-122b-a10b": 262144, + "openrouter:qwen/qwen3.5-27b": 262144, + "openrouter:qwen/qwen3.5-35b-a3b": 262144, + "openrouter:qwen/qwen3.5-397b-a17b": 262144, + "openrouter:qwen/qwen3.5-9b": 262144, + "openrouter:qwen/qwen3.5-9b:batch": 262144, + "openrouter:qwen/qwen3.5-flash-02-23": 1000000, + "openrouter:qwen/qwen3.5-plus-02-15": 1000000, + "openrouter:qwen/qwen3.5-plus-20260420": 1000000, + "openrouter:qwen/qwen3.6-27b": 262144, + "openrouter:qwen/qwen3.6-35b-a3b": 262144, + "openrouter:qwen/qwen3.6-flash": 1000000, + "openrouter:qwen/qwen3.6-max-preview": 262144, + "openrouter:qwen/qwen3.6-plus": 1000000, + "openrouter:qwen/qwen3.7-flash": 1000000, + "openrouter:qwen/qwen3.7-max": 1000000, + "openrouter:qwen/qwen3.7-plus": 1000000, + "openrouter:qwen/qwen3.8-2.4t-a95b": 1000000, + "openrouter:qwen/qwen3.8-2.4t-a95b:batch": 1010000, + "openrouter:qwen/qwen3.8-27b": 1000000, + "openrouter:qwen/qwen3.8-flash": 1000000, + "openrouter:qwen/qwen3.8-max-0902": 1000000, + "openrouter:rekaai/reka-edge": 16384, + "openrouter:relace/relace-search": 256000, + "openrouter:sakana/fugu-ultra": 1000000, + "openrouter:sakana/sakana-namazu": 262144, + "openrouter:sao10k/l3.1-euryale-70b": 131072, + "openrouter:stepfun/step-3.5-flash": 262144, + "openrouter:stepfun/step-3.7-flash": 256000, + "openrouter:tencent/hy3": 262144, + "openrouter:tencent/hy3-preview": 262144, + "openrouter:tencent/hy4-preview": 1048576, + "openrouter:thedrummer/unslopnemo-12b": 32768, + "openrouter:thinkingmachines/inkling": 524288, + "openrouter:thinkingmachines/inkling-small": 524288, + "openrouter:thinkingmachines/inkling-small:batch": 524288, + "openrouter:thinkingmachines/inkling-small:free": 1048576, + "openrouter:thinkingmachines/inkling:batch": 524288, + "openrouter:thinkingmachines/inkling:free": 1048576, + "openrouter:upstage/solar-pro-3": 131072, + "openrouter:upstage/solar-pro4": 524288, + "openrouter:x-ai/grok-4.20": 2000000, + "openrouter:x-ai/grok-4.3": 1000000, + "openrouter:x-ai/grok-4.3:batch": 1000000, + "openrouter:x-ai/grok-4.5": 500000, + "openrouter:x-ai/grok-4.6": 500000, + "openrouter:x-ai/grok-build-0.1": 256000, + "openrouter:xiaomi/mimo-v2.5": 1048576, + "openrouter:xiaomi/mimo-v2.5-pro": 1048576, + "openrouter:z-ai/glm-4.5": 131072, + "openrouter:z-ai/glm-4.5-air": 131072, + "openrouter:z-ai/glm-4.5v": 65536, + "openrouter:z-ai/glm-4.6": 204800, + "openrouter:z-ai/glm-4.6v": 131072, + "openrouter:z-ai/glm-4.7": 202752, + "openrouter:z-ai/glm-4.7-flash": 202752, + "openrouter:z-ai/glm-5": 198000, + "openrouter:z-ai/glm-5-turbo": 202752, + "openrouter:z-ai/glm-5.1": 200000, + "openrouter:z-ai/glm-5.2": 1048576, + "openrouter:z-ai/glm-5.2:free": 256000, + "openrouter:z-ai/glm-5.3": 1048576, + "openrouter:z-ai/glm-5.3-flash": 1048576, + "openrouter:z-ai/glm-5.3-flash:batch": 1048575, + "openrouter:z-ai/glm-5v-turbo": 202752, + "qwen-token-plan-cn:deepseek-v3.2": 131072, + "qwen-token-plan-cn:deepseek-v4-flash": 1000000, + "qwen-token-plan-cn:deepseek-v4-flash-0731": 1000000, + "qwen-token-plan-cn:deepseek-v4-pro": 1000000, + "qwen-token-plan-cn:deepseek-v4-pro-0813": 1000000, + "qwen-token-plan-cn:glm-5": 202752, + "qwen-token-plan-cn:glm-5.1": 202752, + "qwen-token-plan-cn:glm-5.2": 1000000, + "qwen-token-plan-cn:kimi-k2.5": 262144, + "qwen-token-plan-cn:kimi-k2.6": 262144, + "qwen-token-plan-cn:kimi-k2.7-code": 262144, + "qwen-token-plan-cn:MiniMax-M2.5": 196608, + "qwen-token-plan-cn:qwen3.6-flash": 1000000, + "qwen-token-plan-cn:qwen3.6-plus": 1000000, + "qwen-token-plan-cn:qwen3.7-max": 1000000, + "qwen-token-plan-cn:qwen3.7-plus": 1000000, + "qwen-token-plan-cn:qwen3.8-flash": 1000000, + "qwen-token-plan-cn:qwen3.8-max": 1000000, + "qwen-token-plan-individual:deepseek-v4-flash-0731": 1000000, + "qwen-token-plan-individual:deepseek-v4-pro": 1000000, + "qwen-token-plan-individual:deepseek-v4-pro-0813": 1000000, + "qwen-token-plan-individual:glm-5.2": 1000000, + "qwen-token-plan-individual:qwen3.6-flash": 1000000, + "qwen-token-plan-individual:qwen3.7-max": 1000000, + "qwen-token-plan-individual:qwen3.7-plus": 1000000, + "qwen-token-plan-individual:qwen3.8-flash": 1000000, + "qwen-token-plan-individual:qwen3.8-max": 1000000, + "qwen-token-plan:deepseek-v3.2": 131072, + "qwen-token-plan:deepseek-v4-flash": 1000000, + "qwen-token-plan:deepseek-v4-flash-0731": 1000000, + "qwen-token-plan:deepseek-v4-pro": 1000000, + "qwen-token-plan:deepseek-v4-pro-0813": 1000000, + "qwen-token-plan:glm-5": 202752, + "qwen-token-plan:glm-5.1": 202752, + "qwen-token-plan:glm-5.2": 1000000, + "qwen-token-plan:kimi-k2.5": 262144, + "qwen-token-plan:kimi-k2.6": 262144, + "qwen-token-plan:kimi-k2.7-code": 262144, + "qwen-token-plan:MiniMax-M2.5": 196608, + "qwen-token-plan:qwen3.6-flash": 1000000, + "qwen-token-plan:qwen3.6-plus": 1000000, + "qwen-token-plan:qwen3.7-max": 1000000, + "qwen-token-plan:qwen3.7-plus": 1000000, + "qwen-token-plan:qwen3.8-flash": 1000000, + "qwen-token-plan:qwen3.8-max": 1000000, + "together:deepseek-ai/DeepSeek-V4-Flash-0731": 1000000, + "together:deepseek-ai/DeepSeek-V4-Pro": 512000, + "together:deepseek-ai/DeepSeek-V4-Pro-0813": 1048576, + "together:google/gemma-4-31B-it": 262144, + "together:meta-llama/Llama-3.3-70B-Instruct-Turbo": 131072, + "together:MiniMaxAI/MiniMax-M2.7": 202752, + "together:MiniMaxAI/MiniMax-M3": 524288, + "together:moonshotai/Kimi-K2.6": 262144, + "together:moonshotai/Kimi-K2.7-Code": 262144, + "together:moonshotai/Kimi-K3": 1048576, + "together:nvidia/nemotron-3-ultra-550b-a55b": 512300, + "together:openai/gpt-oss-120b": 131072, + "together:openai/gpt-oss-20b": 131072, + "together:Qwen/Qwen2.5-7B-Instruct-Turbo": 32768, + "together:Qwen/Qwen3.5-9B": 262144, + "together:Qwen/Qwen3.6-Plus": 1000000, + "together:Qwen/Qwen3.7-Max": 1000000, + "together:thinkingmachines/Inkling": 524288, + "together:zai-org/GLM-5.2": 512000, + "together:zai-org/GLM-5.3": 1048576, + "together:zai-org/GLM-5.3-Flash": 1048575, + "vercel-ai-gateway:alibaba/qwen-3-14b": 40960, + "vercel-ai-gateway:alibaba/qwen-3-235b": 262144, + "vercel-ai-gateway:alibaba/qwen-3-30b": 40960, + "vercel-ai-gateway:alibaba/qwen-3-32b": 128000, + "vercel-ai-gateway:alibaba/qwen-3.6-max-preview": 240000, + "vercel-ai-gateway:alibaba/qwen3-235b-a22b-thinking": 131072, + "vercel-ai-gateway:alibaba/qwen3-coder": 262144, + "vercel-ai-gateway:alibaba/qwen3-coder-30b-a3b": 262144, + "vercel-ai-gateway:alibaba/qwen3-coder-next": 256000, + "vercel-ai-gateway:alibaba/qwen3-coder-plus": 1000000, + "vercel-ai-gateway:alibaba/qwen3-max": 262144, + "vercel-ai-gateway:alibaba/qwen3-max-preview": 262144, + "vercel-ai-gateway:alibaba/qwen3-max-thinking": 256000, + "vercel-ai-gateway:alibaba/qwen3-next-80b-a3b-instruct": 131072, + "vercel-ai-gateway:alibaba/qwen3-next-80b-a3b-thinking": 131072, + "vercel-ai-gateway:alibaba/qwen3-vl-235b-a22b-instruct": 131072, + "vercel-ai-gateway:alibaba/qwen3-vl-instruct": 131072, + "vercel-ai-gateway:alibaba/qwen3-vl-thinking": 131072, + "vercel-ai-gateway:alibaba/qwen3.5-flash": 1000000, + "vercel-ai-gateway:alibaba/qwen3.5-plus": 1000000, + "vercel-ai-gateway:alibaba/qwen3.6-27b": 256000, + "vercel-ai-gateway:alibaba/qwen3.6-plus": 1000000, + "vercel-ai-gateway:alibaba/qwen3.7-flash": 991000, + "vercel-ai-gateway:alibaba/qwen3.7-max": 991000, + "vercel-ai-gateway:alibaba/qwen3.7-plus": 1000000, + "vercel-ai-gateway:alibaba/qwen3.8-2.4t-a95b": 262144, + "vercel-ai-gateway:alibaba/qwen3.8-27b": 1000000, + "vercel-ai-gateway:alibaba/qwen3.8-flash": 991000, + "vercel-ai-gateway:alibaba/qwen3.8-flash-next": 1048576, + "vercel-ai-gateway:alibaba/qwen3.8-max": 1000000, + "vercel-ai-gateway:alibaba/qwen3.8-max-0902": 991000, + "vercel-ai-gateway:amazon/nova-2-lite": 1000000, + "vercel-ai-gateway:amazon/nova-lite": 300000, + "vercel-ai-gateway:amazon/nova-micro": 128000, + "vercel-ai-gateway:amazon/nova-pro": 300000, + "vercel-ai-gateway:anthropic/claude-3-haiku": 200000, + "vercel-ai-gateway:anthropic/claude-fable-5": 1000000, + "vercel-ai-gateway:anthropic/claude-fable-5.1": 1000000, + "vercel-ai-gateway:anthropic/claude-haiku-4.5": 200000, + "vercel-ai-gateway:anthropic/claude-opus-4": 200000, + "vercel-ai-gateway:anthropic/claude-opus-4.5": 200000, + "vercel-ai-gateway:anthropic/claude-opus-4.6": 1000000, + "vercel-ai-gateway:anthropic/claude-opus-4.7": 1000000, + "vercel-ai-gateway:anthropic/claude-opus-4.8": 1000000, + "vercel-ai-gateway:anthropic/claude-opus-4.8-fast": 1000000, + "vercel-ai-gateway:anthropic/claude-opus-5": 1000000, + "vercel-ai-gateway:anthropic/claude-opus-5-fast": 1000000, + "vercel-ai-gateway:anthropic/claude-sonnet-4": 1000000, + "vercel-ai-gateway:anthropic/claude-sonnet-4.5": 1000000, + "vercel-ai-gateway:anthropic/claude-sonnet-4.6": 1000000, + "vercel-ai-gateway:anthropic/claude-sonnet-5": 1000000, + "vercel-ai-gateway:arcee-ai/trinity-large-thinking": 262100, + "vercel-ai-gateway:bytedance/seed-1.6": 256000, + "vercel-ai-gateway:bytedance/seed-1.8": 256000, + "vercel-ai-gateway:cohere/command-a": 256000, + "vercel-ai-gateway:deepseek/deepseek-r1": 128000, + "vercel-ai-gateway:deepseek/deepseek-v3.1": 163840, + "vercel-ai-gateway:deepseek/deepseek-v3.1-terminus": 131072, + "vercel-ai-gateway:deepseek/deepseek-v3.2": 128000, + "vercel-ai-gateway:deepseek/deepseek-v3.2-thinking": 128000, + "vercel-ai-gateway:deepseek/deepseek-v4-flash": 1000000, + "vercel-ai-gateway:deepseek/deepseek-v4-flash-0731": 1000000, + "vercel-ai-gateway:deepseek/deepseek-v4-flash-vision-exp": 1048576, + "vercel-ai-gateway:deepseek/deepseek-v4-pro": 1000000, + "vercel-ai-gateway:deepseek/deepseek-v4-pro-0813": 1000000, + "vercel-ai-gateway:google/gemini-2.5-flash": 1000000, + "vercel-ai-gateway:google/gemini-2.5-flash-lite": 1048576, + "vercel-ai-gateway:google/gemini-2.5-pro": 1048576, + "vercel-ai-gateway:google/gemini-3-flash": 1000000, + "vercel-ai-gateway:google/gemini-3.1-flash-lite": 1000000, + "vercel-ai-gateway:google/gemini-3.1-pro-preview": 1000000, + "vercel-ai-gateway:google/gemini-3.5-flash": 1000000, + "vercel-ai-gateway:google/gemini-3.5-flash-lite": 1000000, + "vercel-ai-gateway:google/gemini-3.6-flash": 1000000, + "vercel-ai-gateway:google/gemini-3.7-flash": 1000000, + "vercel-ai-gateway:google/gemini-3.8-flash": 1000000, + "vercel-ai-gateway:google/gemma-4-26b-a4b-it": 262144, + "vercel-ai-gateway:google/gemma-4-31b-it": 262144, + "vercel-ai-gateway:inception/mercury-2": 128000, + "vercel-ai-gateway:inception/mercury-coder-small": 32000, + "vercel-ai-gateway:inclusionai/ling-3.0-flash": 256000, + "vercel-ai-gateway:inclusionai/ling-3.0-flash-fin": 256000, + "vercel-ai-gateway:inclusionai/ling-3.0-flash-fin-free": 256000, + "vercel-ai-gateway:inclusionai/ling-3.0-flash-sante": 256000, + "vercel-ai-gateway:inclusionai/ling-3.0-flash-sante-free": 256000, + "vercel-ai-gateway:interfaze/interfaze-beta": 1000000, + "vercel-ai-gateway:kwaipilot/kat-coder-air-v2.5": 256000, + "vercel-ai-gateway:kwaipilot/kat-coder-pro-v1": 256000, + "vercel-ai-gateway:kwaipilot/kat-coder-pro-v2": 256000, + "vercel-ai-gateway:kwaipilot/kat-coder-pro-v2.5": 256000, + "vercel-ai-gateway:meta/llama-3.1-70b": 128000, + "vercel-ai-gateway:meta/llama-3.1-8b": 128000, + "vercel-ai-gateway:meta/llama-3.3-70b": 128000, + "vercel-ai-gateway:meta/llama-4-maverick": 128000, + "vercel-ai-gateway:meta/llama-4-scout": 128000, + "vercel-ai-gateway:meta/muse-glimmer-30b": 131072, + "vercel-ai-gateway:meta/muse-spark-1.1": 1048576, + "vercel-ai-gateway:meta/muse-spark-1.2": 1048576, + "vercel-ai-gateway:meta/muse-spark-1.2-contributor": 1048576, + "vercel-ai-gateway:meta/muse-spark-1.3": 1048576, + "vercel-ai-gateway:meta/muse-spark-1.3-contributor": 1048576, + "vercel-ai-gateway:minimax/minimax-m2": 205000, + "vercel-ai-gateway:minimax/minimax-m2.1": 204800, + "vercel-ai-gateway:minimax/minimax-m2.1-lightning": 204800, + "vercel-ai-gateway:minimax/minimax-m2.5": 204800, + "vercel-ai-gateway:minimax/minimax-m2.5-highspeed": 204800, + "vercel-ai-gateway:minimax/minimax-m2.7": 204800, + "vercel-ai-gateway:minimax/minimax-m2.7-free": 196608, + "vercel-ai-gateway:minimax/minimax-m2.7-highspeed": 204800, + "vercel-ai-gateway:minimax/minimax-m3": 512000, + "vercel-ai-gateway:minimax/minimax-m3-free": 1048576, + "vercel-ai-gateway:mistral/codestral": 128000, + "vercel-ai-gateway:mistral/devstral-2": 256000, + "vercel-ai-gateway:mistral/devstral-small-2": 256000, + "vercel-ai-gateway:mistral/ministral-14b": 256000, + "vercel-ai-gateway:mistral/ministral-3b": 128000, + "vercel-ai-gateway:mistral/ministral-8b": 128000, + "vercel-ai-gateway:mistral/mistral-large-3": 256000, + "vercel-ai-gateway:mistral/mistral-medium": 128000, + "vercel-ai-gateway:mistral/mistral-medium-3.5": 256000, + "vercel-ai-gateway:mistral/mistral-nemo": 128000, + "vercel-ai-gateway:mistral/mistral-small": 32000, + "vercel-ai-gateway:mistral/pixtral-12b": 128000, + "vercel-ai-gateway:moonshotai/kimi-k2": 131072, + "vercel-ai-gateway:moonshotai/kimi-k2-thinking": 216144, + "vercel-ai-gateway:moonshotai/kimi-k2.5": 262114, + "vercel-ai-gateway:moonshotai/kimi-k2.6": 262000, + "vercel-ai-gateway:moonshotai/kimi-k2.7-code": 256000, + "vercel-ai-gateway:moonshotai/kimi-k2.7-code-highspeed": 262144, + "vercel-ai-gateway:moonshotai/kimi-k3": 1000000, + "vercel-ai-gateway:moonshotai/kimi-k3-fast": 1000000, + "vercel-ai-gateway:nvidia/nemotron-3-nano-30b-a3b": 262144, + "vercel-ai-gateway:nvidia/nemotron-3-super-120b-a12b": 256000, + "vercel-ai-gateway:nvidia/nemotron-3-ultra-550b-a55b": 1000000, + "vercel-ai-gateway:nvidia/nemotron-3.5-lightning": 262144, + "vercel-ai-gateway:nvidia/nemotron-nano-12b-v2-vl": 131072, + "vercel-ai-gateway:nvidia/nemotron-nano-9b-v2": 131072, + "vercel-ai-gateway:openai/gpt-3.5-turbo": 16385, + "vercel-ai-gateway:openai/gpt-4-turbo": 128000, + "vercel-ai-gateway:openai/gpt-4.1": 1047576, + "vercel-ai-gateway:openai/gpt-4.1-fast": 1047576, + "vercel-ai-gateway:openai/gpt-4.1-mini": 1047576, + "vercel-ai-gateway:openai/gpt-4.1-mini-fast": 1047576, + "vercel-ai-gateway:openai/gpt-4.1-nano": 1047576, + "vercel-ai-gateway:openai/gpt-4.1-nano-fast": 1047576, + "vercel-ai-gateway:openai/gpt-4o": 128000, + "vercel-ai-gateway:openai/gpt-4o-fast": 128000, + "vercel-ai-gateway:openai/gpt-4o-mini": 128000, + "vercel-ai-gateway:openai/gpt-4o-mini-fast": 128000, + "vercel-ai-gateway:openai/gpt-5": 400000, + "vercel-ai-gateway:openai/gpt-5-codex": 400000, + "vercel-ai-gateway:openai/gpt-5-fast": 400000, + "vercel-ai-gateway:openai/gpt-5-mini": 400000, + "vercel-ai-gateway:openai/gpt-5-mini-fast": 400000, + "vercel-ai-gateway:openai/gpt-5-nano": 400000, + "vercel-ai-gateway:openai/gpt-5-pro": 400000, + "vercel-ai-gateway:openai/gpt-5.1-codex": 400000, + "vercel-ai-gateway:openai/gpt-5.1-codex-max": 400000, + "vercel-ai-gateway:openai/gpt-5.1-codex-mini": 400000, + "vercel-ai-gateway:openai/gpt-5.1-thinking": 400000, + "vercel-ai-gateway:openai/gpt-5.1-thinking-fast": 400000, + "vercel-ai-gateway:openai/gpt-5.2": 400000, + "vercel-ai-gateway:openai/gpt-5.2-codex": 400000, + "vercel-ai-gateway:openai/gpt-5.2-fast": 400000, + "vercel-ai-gateway:openai/gpt-5.2-pro": 400000, + "vercel-ai-gateway:openai/gpt-5.3-codex": 400000, + "vercel-ai-gateway:openai/gpt-5.3-codex-fast": 400000, + "vercel-ai-gateway:openai/gpt-5.4": 1050000, + "vercel-ai-gateway:openai/gpt-5.4-fast": 1050000, + "vercel-ai-gateway:openai/gpt-5.4-mini": 400000, + "vercel-ai-gateway:openai/gpt-5.4-mini-fast": 400000, + "vercel-ai-gateway:openai/gpt-5.4-nano": 400000, + "vercel-ai-gateway:openai/gpt-5.4-pro": 1050000, + "vercel-ai-gateway:openai/gpt-5.5": 1000000, + "vercel-ai-gateway:openai/gpt-5.5-fast": 1000000, + "vercel-ai-gateway:openai/gpt-5.5-pro": 1000000, + "vercel-ai-gateway:openai/gpt-5.6-luna": 1050000, + "vercel-ai-gateway:openai/gpt-5.6-luna-fast": 1050000, + "vercel-ai-gateway:openai/gpt-5.6-sol": 1050000, + "vercel-ai-gateway:openai/gpt-5.6-sol-fast": 1050000, + "vercel-ai-gateway:openai/gpt-5.6-terra": 1050000, + "vercel-ai-gateway:openai/gpt-5.6-terra-fast": 1050000, + "vercel-ai-gateway:openai/gpt-6-astra": 1050000, + "vercel-ai-gateway:openai/gpt-6-astra-fast": 1050000, + "vercel-ai-gateway:openai/gpt-oss-120b": 131072, + "vercel-ai-gateway:openai/gpt-oss-20b": 131072, + "vercel-ai-gateway:openai/gpt-oss-safeguard-120b": 128000, + "vercel-ai-gateway:openai/gpt-oss-safeguard-20b": 128000, + "vercel-ai-gateway:openai/o1": 200000, + "vercel-ai-gateway:openai/o3": 200000, + "vercel-ai-gateway:openai/o3-fast": 200000, + "vercel-ai-gateway:openai/o3-mini": 200000, + "vercel-ai-gateway:openai/o3-pro": 200000, + "vercel-ai-gateway:openai/o4-mini": 200000, + "vercel-ai-gateway:openai/o4-mini-fast": 200000, + "vercel-ai-gateway:poolside/laguna-s-2.1": 1000000, + "vercel-ai-gateway:poolside/laguna-s-2.1-free": 256000, + "vercel-ai-gateway:sakana/fugu-ultra": 1000000, + "vercel-ai-gateway:sakana/namazu": 256000, + "vercel-ai-gateway:spacexai/grok-4.1-fast-non-reasoning": 1000000, + "vercel-ai-gateway:spacexai/grok-4.1-fast-reasoning": 1000000, + "vercel-ai-gateway:spacexai/grok-4.20-multi-agent": 2000000, + "vercel-ai-gateway:spacexai/grok-4.20-multi-agent-beta": 2000000, + "vercel-ai-gateway:spacexai/grok-4.20-non-reasoning": 2000000, + "vercel-ai-gateway:spacexai/grok-4.20-non-reasoning-beta": 2000000, + "vercel-ai-gateway:spacexai/grok-4.20-reasoning": 2000000, + "vercel-ai-gateway:spacexai/grok-4.20-reasoning-beta": 2000000, + "vercel-ai-gateway:spacexai/grok-4.3": 1000000, + "vercel-ai-gateway:spacexai/grok-4.5": 500000, + "vercel-ai-gateway:spacexai/grok-4.6": 500000, + "vercel-ai-gateway:spacexai/grok-build-0.1": 256000, + "vercel-ai-gateway:stepfun/step-3.5-flash": 262114, + "vercel-ai-gateway:stepfun/step-3.7-flash": 256000, + "vercel-ai-gateway:tencent/hy3": 262144, + "vercel-ai-gateway:tencent/hy4-preview": 1024000, + "vercel-ai-gateway:thinkingmachines/inkling": 256000, + "vercel-ai-gateway:thinkingmachines/inkling-small": 1000000, + "vercel-ai-gateway:xiaomi/mimo-v2.5": 1050000, + "vercel-ai-gateway:xiaomi/mimo-v2.5-pro": 1050000, + "vercel-ai-gateway:xiaomi/mimo-v2.5-pro-ultraspeed": 1048576, + "vercel-ai-gateway:zai/glm-4.5": 128000, + "vercel-ai-gateway:zai/glm-4.5-air": 128000, + "vercel-ai-gateway:zai/glm-4.5v": 66000, + "vercel-ai-gateway:zai/glm-4.6": 200000, + "vercel-ai-gateway:zai/glm-4.7": 200000, + "vercel-ai-gateway:zai/glm-4.7-flash": 200000, + "vercel-ai-gateway:zai/glm-4.7-flashx": 200000, + "vercel-ai-gateway:zai/glm-5": 202800, + "vercel-ai-gateway:zai/glm-5-turbo": 202800, + "vercel-ai-gateway:zai/glm-5.1": 202800, + "vercel-ai-gateway:zai/glm-5.2": 1000000, + "vercel-ai-gateway:zai/glm-5.2-fast": 1000000, + "vercel-ai-gateway:zai/glm-5.3": 1000000, + "vercel-ai-gateway:zai/glm-5.3-fast": 1048576, + "vercel-ai-gateway:zai/glm-5.3-flash": 1000000, + "vercel-ai-gateway:zai/glm-5.3-promo-50": 1048576, + "vercel-ai-gateway:zai/glm-5v-turbo": 200000, + "xai:grok-4.3": 1000000, + "xai:grok-4.5": 500000, + "xai:grok-4.6": 500000, + "xiaomi-token-plan-ams:mimo-v2.5": 1048576, + "xiaomi-token-plan-ams:mimo-v2.5-pro": 1048576, + "xiaomi-token-plan-cn:mimo-v2.5": 1048576, + "xiaomi-token-plan-cn:mimo-v2.5-pro": 1048576, + "xiaomi-token-plan-sgp:mimo-v2.5": 1048576, + "xiaomi-token-plan-sgp:mimo-v2.5-pro": 1048576, + "xiaomi:mimo-v2.5": 1048576, + "xiaomi:mimo-v2.5-pro": 1048576, + "xiaomi:mimo-v2.5-pro-ultraspeed": 1048576, + "zai-coding-cn:glm-4.6v": 128000, + "zai-coding-cn:glm-4.7": 204800, + "zai-coding-cn:glm-5-turbo": 200000, + "zai-coding-cn:glm-5.1": 200000, + "zai-coding-cn:glm-5.2": 1000000, + "zai-coding-cn:glm-5.2-highspeed": 1000000, + "zai-coding-cn:glm-5.3": 1000000, + "zai-coding-cn:glm-5.3-flash": 1000000, + "zai-coding-cn:glm-5.3-highspeed": 1000000, + "zai-coding-cn:glm-5v-turbo": 200000, + "zai:glm-4.7": 204800, + "zai:glm-5-turbo": 200000, + "zai:glm-5.2": 1000000, + "zai:glm-5.2-highspeed": 1000000, + "zai:glm-5.3": 1000000, + "zai:glm-5.3-flash": 1000000, + "zai:glm-5.3-highspeed": 1000000, }; // ─── Pure helpers (folds + cost inference) ─────────────────────────────────── diff --git a/src/core/settings-resolution.ts b/src/core/settings-resolution.ts index 057b24b..6069b20 100644 --- a/src/core/settings-resolution.ts +++ b/src/core/settings-resolution.ts @@ -23,23 +23,40 @@ */ import type { ThinkingLevel } from "@earendil-works/pi-agent-core"; +import type { ModelRole } from "../../config.ts"; import type { ChatSettings } from "./contracts/chat.ts"; import type { SearchEngineId } from "./search.ts"; import { BACKGROUND_MODEL_ROLES, FACTORY_SETTINGS, + MODEL_SLOTS, + ROLE_SLOT, type AgentSettings, type BackgroundModelRole, type FactorySettings, type GeneralSettings, type GraphSettings, + type ModelSlot, + type ModelSlotName, type RoleModelOverride, type UserSettings, } from "./settings.ts"; /** The factory layer for model roles — config.ts's MODELS shape (types only - * here; the runtime object is threaded in by the caller). */ -export type ModelRoleSpecs = Record; + * here; the runtime object is threaded in by the caller). Model slots + * (2026-09-20): the factory map spans ALL nine roles (the strong slot's + * factory fallback is the prober pin), while per-role OVERRIDES stay + * background-only (the conversation pair is chat-settings-controlled). */ +export type ModelRoleSpecs = Record; + +/** A fully-resolved model slot: the tier's concrete model (slot over factory + * rep pin) — strong's factory rep is the prober pin, cheap's the researcher + * pin, vision's the visualMaker pin (owner-settled tier mapping). */ +export interface EffectiveSlot { + provider: string; + id: string; + thinkingLevel: ThinkingLevel; +} /** A fully-resolved model pin for one background role. */ export interface EffectiveModelSpec { @@ -68,23 +85,78 @@ export interface EffectiveSettings { * lives in server/search.ts, where keys are visible. */ search: { engine?: SearchEngineId }; }; + /** The resolved strong/cheap/vision slots (model slots wave, + * 2026-09-20): each tier's concrete model (slot over factory rep pin) + * — the per-role chain (override → slot → pin) is resolved into + * agent.models; these are the tier-level views the picker captions. */ + models: Record; appearance: EffectiveAppearance; graph: Required; } -/** Resolve one background role's spec: record override per field, - * config.ts pin per absent field (provider pinned to openrouter today). */ +/** Full-chain resolution for ANY role (model slots wave, 2026-09-20): + * per-role override (background roles only) → slot → factory pin. The + * conversation pair (prober/teacher) resolves the same chain MINUS the + * role override (their override is the chat's own settings — the + * chat-handler overlays it itself). This is the engine wiring's one call. */ +export function resolveRoleSpec( + role: ModelRole, + record: UserSettings | null, + factory: ModelRoleSpecs, +): EffectiveModelSpec { + const bg = BACKGROUND_MODEL_ROLES as readonly string[]; + const override = bg.includes(role) ? record?.agent?.models?.[role as BackgroundModelRole] : undefined; + return resolveModelSpec(role as BackgroundModelRole, override, factory, record?.models); +} + +/** The factory representative pin for a slot tier — the pin the slot + * falls back to when unset (owner-settled mapping: strong's rep is the + * prober pin — prober and teacher share the strong tier — cheap's the + * researcher pin, vision's the visualMaker pin). */ +export function factorySlotRep(slot: ModelSlotName, factory: ModelRoleSpecs): EffectiveSlot { + const rep = + slot === "strong" ? factory.prober : slot === "cheap" ? factory.researcher : factory.visualMaker; + // The factory contract spans all nine roles (stores.ts MODEL_PINS) — + // the rep lookup cannot miss; the cast is for the checker only. + const r = rep as { provider: string; model: string; effort: ThinkingLevel }; + return { provider: r.provider, id: r.model, thinkingLevel: r.effort }; +} + +/** Resolve one slot: the slot override per field, the factory rep pin per + * absent field (model slots wave, 2026-09-20). */ +export function resolveSlot( + slot: ModelSlotName, + override: ModelSlot | undefined, + factory: ModelRoleSpecs, +): EffectiveSlot { + const rep = factorySlotRep(slot, factory); + return { + provider: override?.model?.provider ?? rep.provider, + id: override?.model?.id ?? rep.id, + thinkingLevel: override?.thinkingLevel ?? rep.thinkingLevel, + }; +} + +/** Resolve one background role's spec — the model slots chain (owner + * decision 2026-09-20): role override → SLOT → factory pin, each field + * independent (a role can borrow only the slot's model, or only its + * thinking budget). An absent provider coordinate anywhere resolves to + * the factory pin's provider (the BYOK default, openrouter today) — + * legacy ids without a provider ride the factory provider. */ export function resolveModelSpec( role: BackgroundModelRole, override: RoleModelOverride | undefined, factory: ModelRoleSpecs, + slots?: Partial>, ): EffectiveModelSpec { - const spec = factory[role]; - const model = override?.model; + // The factory contract spans all nine roles; background roles always hit. + const spec = factory[role] as { provider: string; model: string; effort: ThinkingLevel }; + const slotName = ROLE_SLOT[role] as ModelSlotName | undefined; + const slot = slotName ? slots?.[slotName] : undefined; return { - provider: model?.provider ?? "openrouter", - id: model?.id ?? spec.model, - thinkingLevel: override?.thinkingLevel ?? spec.effort, + provider: override?.model?.provider ?? slot?.model?.provider ?? spec.provider, + id: override?.model?.id ?? slot?.model?.id ?? spec.model, + thinkingLevel: override?.thinkingLevel ?? slot?.thinkingLevel ?? spec.effort, }; } @@ -92,6 +164,7 @@ export function resolveModelSpec( * field then lands on its factory default. */ export function resolveSettings(record: UserSettings | null, factory: ModelRoleSpecs): EffectiveSettings { const agent = record?.agent ?? {}; + const modelsSection = record?.models ?? {}; const appearance = record?.appearance ?? {}; const md = appearance.mdRendering ?? {}; const graph = record?.graph ?? {}; @@ -99,7 +172,7 @@ export function resolveSettings(record: UserSettings | null, factory: ModelRoleS const factoryMd = factoryAppearance.mdRendering; const models = {} as Record; for (const role of BACKGROUND_MODEL_ROLES) { - models[role] = resolveModelSpec(role, agent.models?.[role], factory); + models[role] = resolveModelSpec(role, agent.models?.[role], factory, modelsSection); } return { general: { @@ -112,6 +185,11 @@ export function resolveSettings(record: UserSettings | null, factory: ModelRoleS prompts: agent.prompts ?? {}, search: agent.search ?? {}, }, + models: { + strong: resolveSlot("strong", modelsSection.strong, factory), + cheap: resolveSlot("cheap", modelsSection.cheap, factory), + vision: resolveSlot("vision", modelsSection.vision, factory), + }, appearance: { mode: appearance.mode ?? factoryAppearance.mode, background: appearance.background ?? factoryAppearance.background, diff --git a/src/core/settings.ts b/src/core/settings.ts index 85c4268..de6a965 100644 --- a/src/core/settings.ts +++ b/src/core/settings.ts @@ -57,6 +57,51 @@ export interface RoleModelOverride { thinkingLevel?: ThinkingLevel; } +// ─── Model slots (model slots wave, 2026-09-20) ────────────────────────────── + +/** The capability tiers a user can pin models into (owner-settled mapping): + * strong = prober + teacher (also the per-session default-teacher + * starting point); cheap = researcher, demo-builder, extractor, auditor, + * labeler; vision = visual-maker + pdf-reader. Resolution per role: + * ROLE OVERRIDE → slot → factory pin. */ +export const MODEL_SLOTS = ["strong", "cheap", "vision"] as const; +export type ModelSlotName = (typeof MODEL_SLOTS)[number]; + +/** One slot's override — same per-field independence as a role override: + * absent model keeps the tier's current model, absent thinkingLevel keeps + * its thinking budget. */ +export interface ModelSlot { + /** The model swap: both coordinates or neither. */ + model?: { provider: string; id: string }; + /** The thinking budget swap. */ + thinkingLevel?: ThinkingLevel; +} + +/** The `models` settings section (owner decision 2026-09-20: a dedicated + * section — slots are engine-level choices, not one session's). All slots + * optional: an absent slot means every role of its tier runs whatever the + * deeper tiers of the chain resolve to (per-role override → factory pin). */ +export interface ModelsSettings { + strong?: ModelSlot; + cheap?: ModelSlot; + vision?: ModelSlot; +} + +/** Which slot a role draws from (model slots wave, 2026-09-20). Includes the + * conversation pair and pdfReader (not BackgroundModelRoles — the slot + * tier spans every role; only background roles surface per-role overrides). */ +export const ROLE_SLOT: Readonly> = { + prober: "strong", + teacher: "strong", + researcher: "cheap", + demoBuilder: "cheap", + extractor: "cheap", + auditor: "cheap", + labeler: "cheap", + visualMaker: "vision", + pdfReader: "vision", +}; + /** General settings — app-level behavior. Version DISPLAY and plans login * live outside the record (package.json / auth.json) by owner decision. */ export interface GeneralSettings { @@ -140,6 +185,8 @@ export interface UserSettings { * controls. NOT shown in the settings panel (owner decision). */ chat?: ChatSettings; agent?: AgentSettings; + /** The strong/cheap/vision model slots (model slots wave, 2026-09-20). */ + models?: ModelsSettings; appearance?: AppearanceSettings; graph?: GraphSettings; [key: string]: unknown; @@ -244,6 +291,18 @@ function sanitizeRoleOverride(raw: unknown): RoleModelOverride | undefined { return Object.keys(out).length ? out : undefined; } +/** The models section (model slots wave, 2026-09-20): each slot keeps + * only well-formed parts — the same shape rules as a role override, so a + * stale client can't park junk in a slot. */ +function sanitizeModels(raw: Record): ModelsSettings { + const out: ModelsSettings = {}; + for (const slot of MODEL_SLOTS) { + const cleaned = sanitizeRoleOverride(raw[slot]); + if (cleaned) out[slot] = cleaned; + } + return out; +} + function sanitizeBooleanMap(raw: unknown): Record | undefined { if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return undefined; const out: Record = {}; @@ -348,6 +407,10 @@ export function sanitizeUserSettings(raw: unknown): UserSettings | null { if (r.appearance !== null && typeof r.appearance === "object" && !Array.isArray(r.appearance)) { out.appearance = sanitizeAppearance(r.appearance as Record); } + if (r.models !== null && typeof r.models === "object" && !Array.isArray(r.models)) { + const models = sanitizeModels(r.models as Record); + if (Object.keys(models).length) out.models = models; + } if (r.graph !== null && typeof r.graph === "object" && !Array.isArray(r.graph)) { out.graph = sanitizeGraph(r.graph as Record); } diff --git a/src/server/chat-handler.ts b/src/server/chat-handler.ts index 69e2414..21a3065 100644 --- a/src/server/chat-handler.ts +++ b/src/server/chat-handler.ts @@ -1,7 +1,7 @@ import type { UIMessage } from "ai"; import type { Usage } from "@earendil-works/pi-ai"; import { createProberAgent, createTeacherAgent, type AgentBuildOptions, type TeachingAgent } from "../agent/teacher-agent.ts"; -import { piEngineFor } from "../agent/models.ts"; +import { piEngineForSpec } from "../agent/models.ts"; import { createJobRunner } from "../agent/subagents/runner.ts"; import { createExtractionPipeline } from "../agent/subagents/extraction.ts"; import { runGraphContextJob, type GraphContextDeps } from "../agent/subagents/graph-context.ts"; @@ -10,8 +10,8 @@ import type { ModelRole } from "../../config.ts"; import { claimSteers, deliverJobResult, setContextRespawn, setJobRespawn, setTurnRunner } from "./jobs.ts"; import { recordToPiMessages } from "./pi/record-adapter.ts"; import { createPiTurnResponse } from "./pi/ui-stream.ts"; -import { effectiveSettings, stores } from "./stores.ts"; -import { extractionEnabled, graphContextEnabled } from "../core/settings-resolution.ts"; +import { effectiveSettings, MODEL_PINS, stores } from "./stores.ts"; +import { extractionEnabled, graphContextEnabled, resolveRoleSpec } from "../core/settings-resolution.ts"; import { beginTurn, endTurn } from "./turn-liveness.ts"; import { persistTurn, triggerExtraction, triggerGraphContext, withMessageIds } from "./turn-service.ts"; import type { CallUsage } from "../core/contracts.ts"; @@ -39,6 +39,12 @@ const jobRunner = createJobRunner({ chatStore: stores.chatStore, jobStore: stores.jobStore, deliver: deliverJobResult, + // Model slots wave (2026-09-20): job engines resolve the full chain — + // role override → slot → factory pin — read FRESH per job (a settings + // PUT between dispatch and spawn lands). Closes the old gap where + // per-role overrides reached rolePins but never the engines. + engineFor: (role) => + piEngineForSpec(resolveRoleSpec(role, stores.settingsStore.readSettings(), MODEL_PINS)), }); /** The app's ONE extraction pipeline instance — both front doors share it: * quiz-triggered session runs (turn-service) and notes imports @@ -205,8 +211,18 @@ export async function handleChatRequest( // for the conversation agents; piEngineFor falls back to config on absent // fields and clamps the thinking level to the model's supported list). const settings = stores.chatStore.getChat(chatId)?.settings; - const engine = piEngineFor(role, settings); - const modelId = engine.model.id; + // Model slots wave (2026-09-20): the conversation chain is the chat's + // own override over the STRONG slot (prober + teacher's tier) over the + // factory pin — each field independent, same discipline as the roles. + const strong = effective.models.strong; + const engine = piEngineForSpec({ + provider: settings?.model?.provider ?? strong.provider, + id: settings?.model?.id ?? strong.id, + thinkingLevel: settings?.thinkingLevel ?? strong.thinkingLevel, + }); + // Provider-qualified stamp (model slots wave): matches the price table's + // provider:id keys. + const modelId = `${engine.model.provider}:${engine.model.id}`; // Tests inject a factory: the agent is stateless per turn (docs/ // pi-engine-swap.md §2), so each request builds a fresh one off the // transcript — the factory mirrors that seam exactly. diff --git a/src/server/model-catalog.ts b/src/server/model-catalog.ts index 76cb27f..565f892 100644 --- a/src/server/model-catalog.ts +++ b/src/server/model-catalog.ts @@ -16,19 +16,22 @@ import { getSupportedThinkingLevels, type Api, type Model } from "@earendil-works/pi-ai"; import type { ThinkingLevel } from "@earendil-works/pi-agent-core"; -import { MODELS } from "../../config.ts"; import { piModels } from "../agent/models.ts"; import { settingsStore } from "../store/settings.ts"; import { effectiveSettings } from "./stores.ts"; +import { keyValue } from "./keys.ts"; import type { ChatSettings } from "../core/contracts/chat.ts"; import type { CatalogDefaults, + CatalogProvider, ModelCatalogEntry, ModelCatalogResponse, RolePins, + SlotPins, } from "../core/contracts/models.ts"; -import type { EffectiveModelSpec } from "../core/settings-resolution.ts"; -import { BACKGROUND_MODEL_ROLES, type BackgroundModelRole } from "../core/settings.ts"; +import type { EffectiveModelSpec, EffectiveSlot } from "../core/settings-resolution.ts"; +import { AUTH_PROVIDER_KEYS } from "../core/auth-keys.ts"; +import { BACKGROUND_MODEL_ROLES, type BackgroundModelRole, type ModelSlotName, type ModelsSettings } from "../core/settings.ts"; /** The picker's client-safe model entry (contract: core/contracts/models.ts). */ export type ModelDto = ModelCatalogEntry; @@ -37,10 +40,10 @@ export type ModelDto = ModelCatalogEntry; * chat section in, CatalogDefaults out; `catalogDefaults()` below is the * fs wrapper). Absent fields (or no record — BYOK first boot) fall back * to the config pin, exactly as before. */ -export function catalogDefaultsFor(chat?: ChatSettings): CatalogDefaults { +export function catalogDefaultsFor(chat: ChatSettings | undefined, strong: EffectiveSlot): CatalogDefaults { return { - model: chat?.model ?? { provider: "openrouter", id: MODELS.prober.model }, - thinkingLevel: (chat?.thinkingLevel ?? MODELS.prober.effort) as ThinkingLevel, + model: chat?.model ?? { provider: strong.provider, id: strong.id }, + thinkingLevel: chat?.thinkingLevel ?? strong.thinkingLevel, }; } @@ -49,7 +52,7 @@ export function catalogDefaultsFor(chat?: ChatSettings): CatalogDefaults { * the settings record's `chat` section; the picker's defaults row shows * it once chosen. */ export function catalogDefaults(): CatalogDefaults { - return catalogDefaultsFor(settingsStore.readSettings()?.chat); + return catalogDefaultsFor(settingsStore.readSettings()?.chat, effectiveSettings().models.strong); } /** Project the resolved per-role specs to the client DTO (pure — the @@ -77,6 +80,42 @@ export function catalogRolePins(): RolePins { return rolePinsFor(effectiveSettings().agent.models); } +/** The three slot tiers' RESOLVED pins (model slots wave, 2026-09-20) — + * effectiveSettings().models verbatim: slot over factory rep pin, the + * same resolution the engine wiring uses, so the Models settings page's + * captions cannot drift from what actually runs. */ +export function catalogSlots(): SlotPins { + const slots = effectiveSettings().models; + const pins = {} as SlotPins; + for (const name of ["strong", "cheap", "vision"] as const) { + const slot: EffectiveSlot = slots[name]; + pins[name] = { + model: { provider: slot.provider, id: slot.id }, + thinkingLevel: slot.thinkingLevel, + }; + } + return pins; +} + +/** The providers surface (model slots wave, 2026-09-20): one row per + * plain-key model provider (core/auth-keys.ts's pi-ai-derived table), + * with keyPresent read env-wins through the keys seam, fresh per call — + * saving a key immediately federates the provider into the picker. */ +export function catalogProviders(): CatalogProvider[] { + return AUTH_PROVIDER_KEYS.map((p) => ({ + id: p.id, + envVar: p.envVar, + keyPresent: keyValue(p.envVar) !== undefined, + })).sort((a, b) => a.id.localeCompare(b.id)); +} + +/** The providers whose key is present — the picker federates exactly + * these (a keyless provider's models are unreachable by design; the + * Keys page is the discovery surface, same discipline as search). */ +function keyedProviderIds(): Set { + return new Set(catalogProviders().filter((p) => p.keyPresent).map((p) => p.id)); +} + /** Project one catalog model to the client DTO. */ export function toModelDto(model: Model): ModelDto { return { @@ -102,12 +141,20 @@ export function toModelDto(model: Model): ModelDto { * defaults a settings-less chat runs + the background roles' resolved * pins (the settings UI's per-role default captions). */ export function modelCatalog(): ModelCatalogResponse { + const keyed = keyedProviderIds(); const models = piModels() .getProviders() + .filter((p) => keyed.has(p.id)) .flatMap((p) => piModels().getModels(p.id)) .map(toModelDto) .sort((a, b) => (a.provider === b.provider ? a.id.localeCompare(b.id) : a.provider.localeCompare(b.provider))); - return { models, defaults: catalogDefaults(), rolePins: catalogRolePins() }; + return { + models, + defaults: catalogDefaults(), + rolePins: catalogRolePins(), + slots: catalogSlots(), + providers: catalogProviders(), + }; } /** One validated outcome for a settings write. */ @@ -133,8 +180,11 @@ export function validateChatSettings(settings: ChatSettings): SettingsValidation } } if (settings.thinkingLevel !== undefined) { - const provider = settings.model?.provider ?? "openrouter"; - const id = settings.model?.id ?? MODELS.prober.model; + // The conversation chain's fallback is the strong slot (model slots + // wave, 2026-09-20) — the model a settings-less chat would run. + const strong = effectiveSettings().models.strong; + const provider = settings.model?.provider ?? strong.provider; + const id = settings.model?.id ?? strong.id; const model = piModels().getModel(provider, id); if (!model) return { ok: false, error: `No model "${id}" in the ${provider} catalog` }; const supported = getSupportedThinkingLevels(model); @@ -147,4 +197,48 @@ export function validateChatSettings(settings: ChatSettings): SettingsValidation } } return { ok: true }; -} \ No newline at end of file +} +/** Validate a models-section write (PUT /api/settings/models) against the + * catalog — the same gate the chat section gets. Model swaps must name a + * real provider+model; a thinkingLevel must be supported by the model the + * slot would resolve to (the slot's own model, else the factory rep pin). + * keyPresent is NOT gated here (a stored pin for a provider whose key + * lapsed stays valid — it fails honestly at stream time, and the picker + * stops offering it). */ +export function validateModelsSettings(settings: ModelsSettings): SettingsValidation { + for (const name of ["strong", "cheap", "vision"] as const) { + const slot = settings[name]; + if (!slot) continue; + const verdict = validateSlotSpec(name, slot); + if (!verdict.ok) return verdict; + } + return { ok: true }; +} + +function validateSlotSpec(name: ModelSlotName, slot: { model?: { provider: string; id: string }; thinkingLevel?: ThinkingLevel }): SettingsValidation { + const providers = piModels().getProviders().map((p) => p.id); + if (slot.model) { + const { provider, id } = slot.model; + if (!providers.includes(provider)) { + return { ok: false, error: `Unknown provider "${provider}" — configured: ${providers.join(", ")}` }; + } + if (!piModels().getModel(provider, id)) { + return { ok: false, error: `No model "${id}" in the ${provider} catalog` }; + } + } + if (slot.thinkingLevel !== undefined) { + const provider = slot.model?.provider ?? effectiveSettings().models[name].provider; + const id = slot.model?.id ?? effectiveSettings().models[name].id; + const model = piModels().getModel(provider, id); + if (!model) return { ok: false, error: `No model "${id}" in the ${provider} catalog` }; + const supported = getSupportedThinkingLevels(model); + if (!supported.includes(slot.thinkingLevel)) { + return { + ok: false, + error: `${id} does not support thinking level "${slot.thinkingLevel}"`, + supported, + }; + } + } + return { ok: true }; +} diff --git a/src/server/settings-body.ts b/src/server/settings-body.ts index d7a7dbf..f4c9fa7 100644 --- a/src/server/settings-body.ts +++ b/src/server/settings-body.ts @@ -19,9 +19,10 @@ import type { BackgroundModelRole, GeneralSettings, GraphSettings, + ModelsSettings, RoleModelOverride, } from "../core/settings.ts"; -import { BACKGROUND_MODEL_ROLES } from "../core/settings.ts"; +import { BACKGROUND_MODEL_ROLES, MODEL_SLOTS } from "../core/settings.ts"; import { TOGGLEABLE_TOOLS } from "../core/pending.ts"; /** Parsed-or-rejected — `ok: false` carries the 400's error message. */ @@ -292,6 +293,31 @@ export function parseGraphSettingsBody(body: unknown): SettingsBodyResult { + const raw = asRecord(body); + if (!raw) return { ok: false, error: "Invalid JSON body" }; + const settings: ModelsSettings = {}; + for (const key of Object.keys(raw)) { + const known = MODEL_SLOTS as readonly string[]; + if (!known.includes(key)) { + return { ok: false, error: `unknown slot "${key}" (supported: ${known.join(", ")})` }; + } + const parsed = parseRoleOverride(raw[key], key); + if (!parsed.ok) return { ok: false, error: parsed.error }; + if (Object.keys(parsed.override).length) { + settings[key as (typeof MODEL_SLOTS)[number]] = parsed.override; + } else { + return { ok: false, error: `slot "${key}" must set model or thinkingLevel (absent slot = unset)` }; + } + } + return { ok: true, settings }; +} + /** The section→parser map for PUT /api/settings/[section] (the route also * carries the special prompts sub-resource). */ export const SETTINGS_SECTIONS = { @@ -300,6 +326,7 @@ export const SETTINGS_SECTIONS = { agent: parseAgentSettingsBody, appearance: parseAppearanceSettingsBody, graph: parseGraphSettingsBody, + models: parseModelsSettingsBody, } as const; export type SettingsSectionName = keyof typeof SETTINGS_SECTIONS; diff --git a/src/server/stores.ts b/src/server/stores.ts index 5335e8a..c54803e 100644 --- a/src/server/stores.ts +++ b/src/server/stores.ts @@ -22,20 +22,25 @@ export const stores = { export type Stores = typeof stores; -/** config.ts's MODELS narrowed to the background roles — the compiled - * factory layer the resolution reads. core stays pure (it takes this as a - * parameter, never imports config at runtime); the prober/teacher pins - * are chat-settings-controlled and deliberately absent here. Tests pin - * that the role set matches core's BACKGROUND_MODEL_ROLES. */ -const BACKGROUND_MODEL_PINS: ModelRoleSpecs = { +/** config.ts's MODELS as the compiled factory layer the resolution reads — + * ALL NINE roles since the model-slots wave (2026-09-20): the strong + * slot's factory fallback IS the prober pin. core stays pure (it takes + * this as a parameter, never imports config at runtime). Per-role + * OVERRIDES stay background-only (the conversation pair is + * chat-settings-controlled) — that split lives in core's + * BACKGROUND_MODEL_ROLES, unchanged. */ +const MODEL_PINS: ModelRoleSpecs = { + prober: MODELS.prober, + teacher: MODELS.teacher, researcher: MODELS.researcher, demoBuilder: MODELS.demoBuilder, visualMaker: MODELS.visualMaker, + pdfReader: MODELS.pdfReader, extractor: MODELS.extractor, auditor: MODELS.auditor, labeler: MODELS.labeler, }; -export { BACKGROUND_MODEL_PINS }; +export { MODEL_PINS }; /** * The resolved view of the settings record (core/settings-resolution.ts): @@ -44,5 +49,5 @@ export { BACKGROUND_MODEL_PINS }; * no caching layer (stale toggles after a settings PUT would be worse). */ export function effectiveSettings(): EffectiveSettings { - return resolveSettings(settingsStore.readSettings(), BACKGROUND_MODEL_PINS); + return resolveSettings(settingsStore.readSettings(), MODEL_PINS); } diff --git a/tests/cost-summary.test.ts b/tests/cost-summary.test.ts index 411a276..feb097b 100644 --- a/tests/cost-summary.test.ts +++ b/tests/cost-summary.test.ts @@ -16,7 +16,7 @@ import type { CallUsage, ExtractionRunUsage, NamingRunUsage } from "../src/core/ import { PRICES, callCost } from "../src/core/prices.ts"; /** A model with full published pricing (from the generated registry). */ -const PRICED = "z-ai/glm-5.3-flash"; +const PRICED = "openrouter:z-ai/glm-5.3-flash"; assert.ok(PRICES[PRICED], "fixture model must exist in PRICES"); const step = (input: number, output: number): CallUsage => ({ diff --git a/tests/extraction.test.ts b/tests/extraction.test.ts index df2919a..a1e8856 100644 --- a/tests/extraction.test.ts +++ b/tests/extraction.test.ts @@ -553,7 +553,8 @@ describe("the extraction pipeline (extractor → auditor → merger)", () => { const run = record.extractions![0]!; assert.equal(run.stats?.nodes, 0); // linked, not created assert.equal(run.stats?.events, 3); - assert.equal(run.stages.extractor.model, "faux-1"); // the scripted engine's model id + // the scripted engine's model, provider-qualified (model slots wave) + assert.equal(run.stages.extractor.model, "faux:faux-1"); assert.equal(run.stages.extractor.steps.length, 1); // the submit call — the run STOPS after a clean submit const step = run.stages.extractor.steps[0]!; assert.ok(step.inputTokens! > 0 && step.outputTokens! > 0, "estimated usage captured"); diff --git a/tests/jobs.test.ts b/tests/jobs.test.ts index b286b0c..3ebdca8 100644 --- a/tests/jobs.test.ts +++ b/tests/jobs.test.ts @@ -1218,7 +1218,9 @@ describe("abort (src/server/jobs.ts abortJob)", () => { assert.equal(job.status, "error"); assert.equal(job.error, "Aborted by learner"); assert.equal(job.usage!.steps, 1, "usage-so-far persisted by the runner's finally"); - assert.equal(job.usage!.model, "z-ai/glm-5.3-flash", "the config role's OpenRouter id"); + // model slots wave: the stamp is the ENGINE's actual model, + // provider-qualified — the scripted faux engine here. + assert.equal(job.usage!.model, "faux:faux-1"); // faux estimates tokens from the prompt/response text — the // pinned fact is that the ONE completed step's spend survived. assert.ok(job.usage!.inputTokens! > 0, "input tokens billed"); diff --git a/tests/model-catalog.test.ts b/tests/model-catalog.test.ts index 8114bb9..1276652 100644 --- a/tests/model-catalog.test.ts +++ b/tests/model-catalog.test.ts @@ -1,21 +1,27 @@ import { describe, it } from "node:test"; import assert from "node:assert/strict"; -import { modelCatalog, validateChatSettings, catalogDefaultsFor, toModelDto, rolePinsFor, catalogRolePins } from "../src/server/model-catalog.ts"; +import { modelCatalog, validateChatSettings, validateModelsSettings, catalogDefaultsFor, catalogProviders, catalogSlots, toModelDto, rolePinsFor, catalogRolePins } from "../src/server/model-catalog.ts"; import { clampThinkingLevel, getSupportedThinkingLevels } from "@earendil-works/pi-ai"; +import type { ThinkingLevel } from "@earendil-works/pi-agent-core"; import { MODELS } from "../config.ts"; import { piEngineFor } from "../src/agent/models.ts"; import { BACKGROUND_MODEL_ROLES, type BackgroundModelRole } from "../src/core/settings.ts"; import { resolveSettings } from "../src/core/settings-resolution.ts"; -import { BACKGROUND_MODEL_PINS } from "../src/server/stores.ts"; +import { MODEL_PINS } from "../src/server/stores.ts"; // The model-control wave (2026-09-12): pi-ai owns the registry — these pins // hold our projection + validation honest against the shipped catalog, and // pin pi's per-model thinking truth so a pi-ai upgrade can't silently change // what we send. +// The picker federates only providers with a PRESENT key (model slots +// wave, 2026-09-20): pin openrouter's env key so its full catalog +// federates in tests regardless of the developer shell's exports. +process.env.OPENROUTER_API_KEY ??= "test-key-openrouter-catalog"; + describe("the model catalog projection", () => { - it("serves pi-ai's OpenRouter catalog with the picker's DTO shape", () => { - const { models, defaults } = modelCatalog(); + it("serves the keyed providers' catalogs with the picker's DTO shape", () => { + const { models, defaults, providers, slots } = modelCatalog(); // 0.85.1 ships 366 OpenRouter models — the exact count is pi's, but // the shape and the config models' presence are ours to pin. assert.ok(models.length > 300, `expected a full catalog, got ${models.length}`); @@ -32,23 +38,35 @@ describe("the model catalog projection", () => { assert.deepEqual(glm!.input, ["text", "image"]); // pi's current glm price (our old table said 0.15/0.5 — stale) assert.deepEqual(glm!.cost, { input: 0.075, output: 0.25, cacheRead: 0.015, cacheWrite: 0 }); + // model slots wave: the providers surface + the resolved slot pins + const openrouter = providers.find((p) => p.id === "openrouter"); + assert.ok(openrouter && openrouter.keyPresent, "openrouter federated (key pinned above)"); + assert.ok(providers.some((p) => !p.keyPresent), "keyless providers listed for discovery"); + assert.deepEqual(Object.keys(slots), ["strong", "cheap", "vision"]); + // a keyless provider's models never reach the picker + const keyless = providers.filter((p) => !p.keyPresent).map((p) => p.id); + for (const id of keyless) { + assert.ok(!models.some((m) => m.provider === id), `keyless ${id} must not federate`); + } }); - it("defaults mirror the conversation agents' config pin", () => { - const d = catalogDefaultsFor(); + it("defaults mirror the conversation agents' config pin (strong rep = prober pin)", () => { + const strong = { provider: "openrouter", id: MODELS.prober.model, thinkingLevel: MODELS.prober.effort as ThinkingLevel }; + const d = catalogDefaultsFor(undefined, strong); assert.deepEqual(d, { model: { provider: "openrouter", id: MODELS.prober.model }, thinkingLevel: MODELS.prober.effort }); assert.equal(d.model.id, MODELS.teacher.model, "one controller: prober and teacher share the pin"); }); it("a picked default in the record's chat section overrides the pin (catalogDefaultsFor, settings wave)", () => { - const d = catalogDefaultsFor({ model: { provider: "openrouter", id: "qwen/qwen3.8-flash" }, thinkingLevel: "high" }); + const strong = { provider: "openrouter", id: MODELS.prober.model, thinkingLevel: MODELS.prober.effort as ThinkingLevel }; + const d = catalogDefaultsFor({ model: { provider: "openrouter", id: "qwen/qwen3.8-flash" }, thinkingLevel: "high" }, strong); assert.deepEqual(d, { model: { provider: "openrouter", id: "qwen/qwen3.8-flash" }, thinkingLevel: "high" }); // partial: only the model chosen → thinking falls back to the pin - const partial = catalogDefaultsFor({ model: { provider: "openrouter", id: "qwen/qwen3.8-flash" } }); + const partial = catalogDefaultsFor({ model: { provider: "openrouter", id: "qwen/qwen3.8-flash" } }, strong); assert.equal(partial.thinkingLevel, MODELS.prober.effort); assert.equal(partial.model.id, "qwen/qwen3.8-flash"); // graphContextTokens-only record: model untouched - assert.deepEqual(catalogDefaultsFor({ graphContextTokens: 512 }), { + assert.deepEqual(catalogDefaultsFor({ graphContextTokens: 512 }, strong), { model: { provider: "openrouter", id: MODELS.prober.model }, thinkingLevel: MODELS.prober.effort, }); @@ -67,7 +85,7 @@ describe("the model catalog projection", () => { describe("the background roles' resolved pins (rolePins)", () => { it("no overrides → every role pins its config MODELS spec, nested DTO shape, all six roles", () => { - const pins = rolePinsFor(resolveSettings(null, BACKGROUND_MODEL_PINS).agent.models); + const pins = rolePinsFor(resolveSettings(null, MODEL_PINS).agent.models); assert.deepEqual(Object.keys(pins), [...BACKGROUND_MODEL_ROLES]); for (const role of BACKGROUND_MODEL_ROLES) { assert.deepEqual(pins[role].model, { provider: "openrouter", id: MODELS[role].model }); @@ -82,7 +100,7 @@ describe("the background roles' resolved pins (rolePins)", () => { version: 1, agent: { models: { researcher: { model: { provider: "openrouter", id: "qwen/qwen3.8-flash" } } } }, }; - const pins = rolePinsFor(resolveSettings(record, BACKGROUND_MODEL_PINS).agent.models); + const pins = rolePinsFor(resolveSettings(record, MODEL_PINS).agent.models); assert.equal(pins.researcher.model.id, "qwen/qwen3.8-flash"); assert.equal(pins.researcher.thinkingLevel, MODELS.researcher.effort, "level stays the pin unless overridden too"); assert.equal(pins.visualMaker.model.id, MODELS.visualMaker.model); @@ -91,12 +109,69 @@ describe("the background roles' resolved pins (rolePins)", () => { it("a thinkingLevel-only override keeps the model, changes the level", () => { const record = { version: 1, agent: { models: { extractor: { thinkingLevel: "high" as const } } } }; - const pins = rolePinsFor(resolveSettings(record, BACKGROUND_MODEL_PINS).agent.models); + const pins = rolePinsFor(resolveSettings(record, MODEL_PINS).agent.models); assert.equal(pins.extractor.model.id, MODELS.extractor.model); assert.equal(pins.extractor.thinkingLevel, "high"); }); }); +describe("the model slots surface (model slots wave, 2026-09-20)", () => { + it("catalogSlots reports the factory rep pins when no record exists", () => { + const slots = catalogSlots(); + assert.deepEqual(slots.strong.model, { provider: "openrouter", id: MODELS.prober.model }); + assert.deepEqual(slots.cheap.model, { provider: "openrouter", id: MODELS.researcher.model }); + assert.deepEqual(slots.vision.model, { provider: "openrouter", id: MODELS.visualMaker.model }); + }); + + it("catalogProviders reads keys env-wins, fresh per call", () => { + const before = catalogProviders().find((p) => p.id === "zai"); + assert.equal(before?.keyPresent, false); + const saved = process.env.ZAI_API_KEY; + process.env.ZAI_API_KEY = "test-zai-key-1234567890"; + try { + assert.equal(catalogProviders().find((p) => p.id === "zai")?.keyPresent, true); + } finally { + if (saved === undefined) delete process.env.ZAI_API_KEY; + else process.env.ZAI_API_KEY = saved; + } + }); +}); + +describe("the models-section validation gate", () => { + it("accepts a valid slot and rejects unknown provider/model", () => { + assert.equal( + validateModelsSettings({ strong: { model: { provider: "openrouter", id: "z-ai/glm-5.3-flash" } } }).ok, + true, + ); + assert.equal( + validateModelsSettings({ cheap: { model: { provider: "nope", id: "x" } } }).ok, + false, + ); + assert.equal( + validateModelsSettings({ vision: { model: { provider: "openrouter", id: "nope/nope" } } }).ok, + false, + ); + }); + + it("thinkingLevel resolves against the slot's model, else the tier's resolved pin", () => { + // level checked against the named model + assert.equal( + validateModelsSettings({ strong: { model: { provider: "openrouter", id: "z-ai/glm-5.3-flash" }, thinkingLevel: "max" } }).ok, + true, + ); + assert.equal( + validateModelsSettings({ strong: { model: { provider: "openrouter", id: "z-ai/glm-5.3-flash" }, thinkingLevel: "minimal" } }).ok, + false, + ); + // bare level: against the strong slot's resolved model (config pin) + assert.equal(validateModelsSettings({ strong: { thinkingLevel: "minimal" } }).ok, false); + }); + + it("accepts empty settings (the clear-slots write)", () => { + assert.deepEqual(validateModelsSettings({}), { ok: true }); + }); +}); + describe("the settings validation gate", () => { it("accepts a supported level and rejects an unsupported one with the list", () => { const ok = validateChatSettings({ model: { provider: "openrouter", id: "z-ai/glm-5.3-flash" }, thinkingLevel: "max" }); diff --git a/tests/render-activity-dock.test.tsx b/tests/render-activity-dock.test.tsx index 15892d4..cc392b1 100644 --- a/tests/render-activity-dock.test.tsx +++ b/tests/render-activity-dock.test.tsx @@ -48,7 +48,7 @@ describe("activity dock pure layer", () => { it("folds cost with jobCost; absent usage is null, never zero", () => { const priced = job({ usage: { - model: "z-ai/glm-5.3-flash", + model: "openrouter:z-ai/glm-5.3-flash", inputTokens: 10_000, outputTokens: 1000, cacheReadTokens: 5000, @@ -67,7 +67,7 @@ describe("activity dock pure layer", () => { it("context line = LAST step's tokens vs the model limit, never a cumulative sum", () => { const base = { - model: "z-ai/glm-5.3-flash", + model: "openrouter:z-ai/glm-5.3-flash", inputTokens: 400_000, // running total (much bigger — must NOT feed the line) outputTokens: 8_000, cacheReadTokens: 0, @@ -166,7 +166,7 @@ describe("activity section render", () => { it("shows total running cost when jobs are priced", () => { const usage = { - model: "z-ai/glm-5.3-flash", + model: "openrouter:z-ai/glm-5.3-flash", inputTokens: 10_000, outputTokens: 1000, cacheReadTokens: 0, diff --git a/tests/render-stats-bar.test.tsx b/tests/render-stats-bar.test.tsx index 869f429..d4217f9 100644 --- a/tests/render-stats-bar.test.tsx +++ b/tests/render-stats-bar.test.tsx @@ -18,7 +18,7 @@ function turn(over: Partial = {}): TurnUsage { id: "t1", messageId: "m1", at: "2026-09-09T12:00:00Z", - model: "z-ai/glm-5.3-flash", + model: "openrouter:z-ai/glm-5.3-flash", steps: [step(10_000, 1_000)], ...over, }; diff --git a/tests/settings-body.test.ts b/tests/settings-body.test.ts index b55f4cc..32d0bca 100644 --- a/tests/settings-body.test.ts +++ b/tests/settings-body.test.ts @@ -11,6 +11,7 @@ import assert from "node:assert/strict"; import { describe, it } from "node:test"; import { parseAgentSettingsBody, + parseModelsSettingsBody, parseAppearanceSettingsBody, parseGeneralSettingsBody, parseGraphSettingsBody, @@ -158,7 +159,47 @@ describe("parseGraphSettingsBody", () => { }); describe("SETTINGS_SECTIONS (the route's section map)", () => { - it("maps exactly the five record sections", () => { - assert.deepEqual(Object.keys(SETTINGS_SECTIONS), ["general", "chat", "agent", "appearance", "graph"]); + it("maps exactly the six record sections", () => { + assert.deepEqual(Object.keys(SETTINGS_SECTIONS), ["general", "chat", "agent", "appearance", "graph", "models"]); + }); +}); + +describe("parseModelsSettingsBody (model slots wave, 2026-09-20)", () => { + it("parses the three slot tiers, each field independent", () => { + const r = parseModelsSettingsBody({ + strong: { model: { provider: "openrouter", id: "z-ai/glm-5.3-flash" } }, + cheap: { thinkingLevel: "high" }, + vision: { model: { provider: "zai", id: "glm-5.3-flash" }, thinkingLevel: "low" }, + }); + assert.ok(r.ok); + assert.deepEqual(r.settings, { + strong: { model: { provider: "openrouter", id: "z-ai/glm-5.3-flash" } }, + cheap: { thinkingLevel: "high" }, + vision: { model: { provider: "zai", id: "glm-5.3-flash" }, thinkingLevel: "low" }, + }); + }); + + it("{} is the legal clear-slots write", () => { + const r = parseModelsSettingsBody({}); + assert.ok(r.ok); + assert.deepEqual(r.settings, {}); + }); + + it("unknown slots are 400s with the supported list", () => { + const bad = parseModelsSettingsBody({ mega: { thinkingLevel: "high" } }); + assert.equal(bad.ok, false); + if (!bad.ok) assert.match(bad.error, /unknown slot "mega" \(supported: strong, cheap, vision\)/); + }); + + it("a present-but-empty slot object is rejected (absent slot = unset)", () => { + const bad = parseModelsSettingsBody({ strong: {} }); + assert.equal(bad.ok, false); + if (!bad.ok) assert.match(bad.error, /slot "strong" must set model or thinkingLevel/); + }); + + it("malformed slot shapes are 400s", () => { + assert.equal(parseModelsSettingsBody({ cheap: { model: { provider: "x" } } }).ok, false); + assert.equal(parseModelsSettingsBody({ vision: { thinkingLevel: 7 } }).ok, false); + assert.equal(parseModelsSettingsBody("nope").ok, false); }); }); diff --git a/tests/settings-resolution.test.ts b/tests/settings-resolution.test.ts index 311bb1b..7d62b8a 100644 --- a/tests/settings-resolution.test.ts +++ b/tests/settings-resolution.test.ts @@ -1,26 +1,42 @@ /** - * Tests for the resolution layer (settings-storage wave, 2026-09-19): - * core/settings-resolution.ts — the delta→concrete projection. The factory - * layer is threaded in as a parameter (core stays pure; server/stores.ts - * threads config.ts's MODELS), so these tests use a small synthetic pin. + * Tests for the resolution layer (settings-storage wave, 2026-09-19; + * model-slots wave 2026-09-20 adds the slot tier): core/settings-resolution.ts + * — the delta→concrete projection. The factory layer is threaded in as a + * parameter (core stays pure; server/stores.ts threads config.ts's MODELS), + * so these tests use a small synthetic pin spanning ALL NINE roles (the + * factory contract since the slots wave — the strong slot's rep IS the + * prober pin). */ import assert from "node:assert/strict"; import { describe, it } from "node:test"; import { extractionEnabled, + factorySlotRep, graphContextEnabled, resolveModelSpec, resolveSettings, + resolveSlot, + type ModelRoleSpecs, } from "../src/core/settings-resolution.ts"; -import { BACKGROUND_MODEL_ROLES, type UserSettings } from "../src/core/settings.ts"; +import { BACKGROUND_MODEL_ROLES, type ModelSlotName, type UserSettings } from "../src/core/settings.ts"; const FACTORY_PINS = Object.fromEntries( - BACKGROUND_MODEL_ROLES.map((role, i) => [ + [ + "prober", + "teacher", + "researcher", + "demoBuilder", + "visualMaker", + "pdfReader", + "extractor", + "auditor", + "labeler", + ].map((role, i) => [ role, - { model: `factory/model-${i}`, effort: i % 2 === 0 ? "low" : "off" }, + { provider: i === 5 ? "other" : "openrouter", model: `factory/model-${i}`, effort: i % 2 === 0 ? "low" : "off" }, ]), -) as Record<(typeof BACKGROUND_MODEL_ROLES)[number], { model: string; effort: "low" | "off" }>; +) as ModelRoleSpecs; describe("resolveSettings", () => { it("null record (first boot): every knob lands on its factory default", () => { @@ -29,11 +45,28 @@ describe("resolveSettings", () => { assert.deepEqual(eff.chat, {}); // BYOK: no default model, ever assert.deepEqual(eff.agent.tools, {}); assert.deepEqual(eff.agent.prompts, {}); + assert.deepEqual(eff.agent.search, {}); for (const role of BACKGROUND_MODEL_ROLES) { - assert.equal(eff.agent.models[role].id, FACTORY_PINS[role].model); - assert.equal(eff.agent.models[role].provider, "openrouter"); - assert.equal(eff.agent.models[role].thinkingLevel, FACTORY_PINS[role].effort); + assert.equal(eff.agent.models[role].id, FACTORY_PINS[role]!.model); + assert.equal(eff.agent.models[role].provider, FACTORY_PINS[role]!.provider); + assert.equal(eff.agent.models[role].thinkingLevel, FACTORY_PINS[role]!.effort); } + // slots with no record: every tier lands on its factory rep pin + assert.deepEqual(eff.models.strong, { + provider: "openrouter", + id: FACTORY_PINS.prober!.model, + thinkingLevel: FACTORY_PINS.prober!.effort, + }); + assert.deepEqual(eff.models.cheap, { + provider: "openrouter", + id: FACTORY_PINS.researcher!.model, + thinkingLevel: FACTORY_PINS.researcher!.effort, + }); + assert.deepEqual(eff.models.vision, { + provider: "openrouter", + id: FACTORY_PINS.visualMaker!.model, + thinkingLevel: FACTORY_PINS.visualMaker!.effort, + }); assert.equal(eff.appearance.mode, "dark"); assert.equal(eff.appearance.background, null); assert.equal(eff.appearance.fontFamily, null); @@ -52,6 +85,7 @@ describe("resolveSettings", () => { models: { researcher: { model: { provider: "openrouter", id: "qwen/qwen3.8-flash" } } }, tools: { research: false }, prompts: { "system-prompt.md": true }, + search: { engine: "tavily" }, }, appearance: { mode: "light", proseFontSize: 20, mdRendering: { headingWeight: 600 } }, graph: { enabled: false }, @@ -64,6 +98,7 @@ describe("resolveSettings", () => { id: "qwen/qwen3.8-flash", thinkingLevel: "low", // thinking NOT overridden → factory effort }); + assert.deepEqual(eff.agent.search, { engine: "tavily" }); assert.deepEqual(eff.agent.tools, { research: false }); assert.deepEqual(eff.agent.prompts, { "system-prompt.md": true }); assert.equal(eff.appearance.mode, "light"); @@ -79,29 +114,101 @@ describe("resolveSettings", () => { { version: 1, agent: { models: { extractor: { thinkingLevel: "medium" } } } }, FACTORY_PINS, ); - const extractor = FACTORY_PINS.extractor; + const extractor = FACTORY_PINS.extractor!; assert.deepEqual(eff.agent.models.extractor, { - provider: "openrouter", + provider: extractor.provider, id: extractor.model, thinkingLevel: "medium", }); // sibling roles untouched - assert.equal(eff.agent.models.researcher.thinkingLevel, FACTORY_PINS.researcher.effort); + assert.equal(eff.agent.models.researcher.thinkingLevel, FACTORY_PINS.researcher!.effort); }); it("resolveModelSpec is field-independent per override aspect", () => { assert.deepEqual( resolveModelSpec("labeler", { model: { provider: "other", id: "x" } }, FACTORY_PINS), - { provider: "other", id: "x", thinkingLevel: FACTORY_PINS.labeler.effort }, + { provider: "other", id: "x", thinkingLevel: FACTORY_PINS.labeler!.effort }, ); assert.deepEqual(resolveModelSpec("labeler", {}, FACTORY_PINS), { - provider: "openrouter", - id: FACTORY_PINS.labeler.model, - thinkingLevel: FACTORY_PINS.labeler.effort, + provider: FACTORY_PINS.labeler!.provider, + id: FACTORY_PINS.labeler!.model, + thinkingLevel: FACTORY_PINS.labeler!.effort, }); }); }); +describe("the slot tier (model slots wave, 2026-09-20)", () => { + it("slot alone re-tiers every role of its tier (no role overrides present)", () => { + const eff = resolveSettings( + { version: 1, models: { cheap: { model: { provider: "zai", id: "glm-5.3-flash" } } } }, + FACTORY_PINS, + ); + for (const role of ["researcher", "demoBuilder", "extractor", "auditor", "labeler"] as const) { + assert.deepEqual(eff.agent.models[role as "researcher"], { + provider: "zai", + id: "glm-5.3-flash", + thinkingLevel: FACTORY_PINS[role]!.effort, // thinking not in slot → factory + }, role); + } + // other tiers untouched + assert.equal(eff.agent.models.visualMaker.id, FACTORY_PINS.visualMaker!.model); + }); + + it("role override still beats the slot; slot beats the factory pin (the chain)", () => { + const eff = resolveSettings( + { + version: 1, + agent: { models: { researcher: { model: { provider: "groq", id: "r-override" } } } }, + models: { cheap: { model: { provider: "zai", id: "r-slot" }, thinkingLevel: "high" } }, + }, + FACTORY_PINS, + ); + // researcher: override model + slot thinking (field-independent) + assert.deepEqual(eff.agent.models.researcher, { + provider: "groq", + id: "r-override", + thinkingLevel: "high", + }); + // labeler (same tier, no override): full slot + assert.deepEqual(eff.agent.models.labeler, { provider: "zai", id: "r-slot", thinkingLevel: "high" }); + }); + + it("vision slot covers visualMaker AND pdfReader; strong's rep is the prober pin", () => { + const eff = resolveSettings( + { version: 1, models: { vision: { thinkingLevel: "max" } } }, + FACTORY_PINS, + ); + assert.equal(eff.agent.models.visualMaker.thinkingLevel, "max"); + assert.equal(eff.agent.models.visualMaker.id, FACTORY_PINS.visualMaker!.model); + // resolved slot views exist for every tier, set or not + assert.deepEqual(eff.models.strong, factorySlotRep("strong", FACTORY_PINS)); + }); + + it("resolveSlot: slot over factory rep, per field", () => { + assert.deepEqual(resolveSlot("strong", { thinkingLevel: "medium" }, FACTORY_PINS), { + provider: FACTORY_PINS.prober!.provider, + id: FACTORY_PINS.prober!.model, + thinkingLevel: "medium", + }); + const rep = factorySlotRep("vision", FACTORY_PINS); + assert.equal(rep.id, FACTORY_PINS.visualMaker!.model); + const slot: ModelSlotName = "cheap"; + assert.deepEqual(resolveSlot(slot, undefined, FACTORY_PINS), { + provider: FACTORY_PINS.researcher!.provider, + id: FACTORY_PINS.researcher!.model, + thinkingLevel: FACTORY_PINS.researcher!.effort, + }); + }); + + it("absent provider coordinate anywhere rides the factory provider (legacy ids)", () => { + // resolveModelSpec with no slots and a factory provider of "other" + // (pdfReader is index 5 in the synthetic pins): a legacy override + // with no provider keeps the FACTORY provider, not a hardcoded one. + const spec = resolveModelSpec("auditor", {}, FACTORY_PINS); + assert.equal(spec.provider, FACTORY_PINS.auditor!.provider); + }); +}); + describe("the graph channel gates (the wave's seam honoring)", () => { it("WRITE channel (extraction): dies with the master switch only", () => { assert.equal(extractionEnabled({ enabled: true, embedding: true, clustering: true, labeling: true }), true); diff --git a/tests/settings.test.ts b/tests/settings.test.ts index 8dab06f..7f8fffa 100644 --- a/tests/settings.test.ts +++ b/tests/settings.test.ts @@ -63,6 +63,10 @@ describe("sanitizeUserSettings", () => { prompts: { "system-prompt.md": true, "teacher/20-teaching.md": false }, search: { engine: "brave" }, }, + models: { + strong: { model: { provider: "zai", id: "glm-5.3-flash" }, thinkingLevel: "low" }, + cheap: { thinkingLevel: "medium" }, + }, appearance: { mode: "light", background: "#ffffff", diff --git a/tests/usage.test.ts b/tests/usage.test.ts index 11a5391..907f10b 100644 --- a/tests/usage.test.ts +++ b/tests/usage.test.ts @@ -40,7 +40,7 @@ test("sumSteps folds steps; absent stays absent until a value appears", () => { }); test("callCost: glm-5.3-flash math — fresh input, cached read, output", () => { - const cost = callCost(call({ inputTokens: 100_000, outputTokens: 20_000, cacheReadTokens: 10_000 }), "z-ai/glm-5.3-flash"); + const cost = callCost(call({ inputTokens: 100_000, outputTokens: 20_000, cacheReadTokens: 10_000 }), "openrouter:z-ai/glm-5.3-flash"); assert.ok(cost !== null); // fresh 90k @ $0.075/M + cached 10k @ $0.015/M + output 20k @ $0.25/M // (pi-ai catalog prices — regenerated tables, scripts/sync-pricing) @@ -50,7 +50,7 @@ test("callCost: glm-5.3-flash math — fresh input, cached read, output", () => test("callCost: cache writes bill at the cacheWrite rate", () => { const cost = callCost( call({ inputTokens: 1_000_000, outputTokens: 0, cacheWriteTokens: 500_000 }), - "qwen/qwen3.8-max-0902", + "openrouter:qwen/qwen3.8-max-0902", ); assert.ok(cost !== null); // fresh 1M @ $2/M + cache write 500k @ $2.5/M @@ -59,7 +59,7 @@ test("callCost: cache writes bill at the cacheWrite rate", () => { test("callCost: unknown model and absent fields are null, never zero", () => { assert.equal(callCost(call({ inputTokens: 100, outputTokens: 5 }), "not/a-model"), null); - assert.equal(callCost(call({ inputTokens: 100, outputTokens: undefined }), "z-ai/glm-5.3-flash"), null); + assert.equal(callCost(call({ inputTokens: 100, outputTokens: undefined }), "openrouter:z-ai/glm-5.3-flash"), null); }); test("turnCost sums steps; sessionCost reports unpriced turns", () => { @@ -67,7 +67,7 @@ test("turnCost sums steps; sessionCost reports unpriced turns", () => { id: "t1", messageId: "m1", at: "2026-09-09T00:00:00Z", - model: "z-ai/glm-5.3-flash", + model: "openrouter:z-ai/glm-5.3-flash", steps: [call({ inputTokens: 10_000, outputTokens: 2_000 }), call({ inputTokens: 12_000, outputTokens: 1_000 })], }; assert.ok(turnCost(turn) !== null); @@ -81,12 +81,12 @@ test("turnCost sums steps; sessionCost reports unpriced turns", () => { test("contextWindow: last call's footprint against the model's limit", () => { const cw = contextWindow({ turns: [ - { id: "t1", messageId: "m1", at: "x", model: "z-ai/glm-5.3-flash", steps: [call({ inputTokens: 9_000, outputTokens: 1_000 })] }, - { id: "t2", messageId: "m2", at: "x", model: "z-ai/glm-5.3-flash", steps: [call({ inputTokens: 90_000, outputTokens: 10_000 })] }, + { id: "t1", messageId: "m1", at: "x", model: "openrouter:z-ai/glm-5.3-flash", steps: [call({ inputTokens: 9_000, outputTokens: 1_000 })] }, + { id: "t2", messageId: "m2", at: "x", model: "openrouter:z-ai/glm-5.3-flash", steps: [call({ inputTokens: 90_000, outputTokens: 10_000 })] }, ], }); assert.ok(cw); - assert.equal(cw.model, "z-ai/glm-5.3-flash"); + assert.equal(cw.model, "openrouter:z-ai/glm-5.3-flash"); assert.equal(cw.usedTokens, 100_000); assert.equal(cw.limit, 1_048_576); assert.equal(contextWindow({ turns: [] }), null); @@ -96,7 +96,7 @@ test("jobCost: null without usage, computed with it", () => { assert.equal(jobCost({}), null); const job: Pick = { usage: { - model: "z-ai/glm-5.3-flash", + model: "openrouter:z-ai/glm-5.3-flash", inputTokens: 1_000_000, outputTokens: 100_000, cacheReadTokens: 0, @@ -117,7 +117,7 @@ test("appendTurnUsage: appends, idempotent per turn id, continuation turns (same id: "turn_1", messageId: "msg_a", at: "2026-09-09T00:00:00Z", - model: "z-ai/glm-5.3-flash", + model: "openrouter:z-ai/glm-5.3-flash", steps: [call({ inputTokens: 100, outputTokens: 10 })], }; chatStore.appendTurnUsage(record.id, entry); @@ -149,8 +149,8 @@ test("appendExtractionUsage: appends, idempotent per startedAt, not in list payl durationMs: 42_000, stats: { nodes: 1, edges: 2, events: 3 }, stages: { - extractor: { model: "z-ai/glm-5.3-flash", steps: [call({ inputTokens: 100, outputTokens: 10 })] }, - auditor: { model: "z-ai/glm-5.3-flash", steps: [call({ inputTokens: 50, outputTokens: 5 })] }, + extractor: { model: "openrouter:z-ai/glm-5.3-flash", steps: [call({ inputTokens: 100, outputTokens: 10 })] }, + auditor: { model: "openrouter:z-ai/glm-5.3-flash", steps: [call({ inputTokens: 50, outputTokens: 5 })] }, }, }); chatStore.appendExtractionUsage(record.id, runEntry(1)); @@ -186,8 +186,8 @@ test("appendSourceUsage: appends to the source record, idempotent per startedAt, durationMs: 42_000, stats: { nodes: 1, edges: 2, events: 3 }, stages: { - extractor: { model: "z-ai/glm-5.3-flash", steps: [call({ inputTokens: 100, outputTokens: 10 })] }, - auditor: { model: "z-ai/glm-5.3-flash", steps: [call({ inputTokens: 50, outputTokens: 5 })] }, + extractor: { model: "openrouter:z-ai/glm-5.3-flash", steps: [call({ inputTokens: 100, outputTokens: 10 })] }, + auditor: { model: "openrouter:z-ai/glm-5.3-flash", steps: [call({ inputTokens: 50, outputTokens: 5 })] }, }, }); const id = "src_usagetest01";