ai-lcr 0.6.3 → 0.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,48 @@ All notable changes to `ai-lcr` are documented here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/), and the project adheres to
5
5
  [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [0.6.5] — 2026-06-16
8
+
9
+ Bundled price table now covers the open-weights labs, not just the Western
10
+ proprietary makers — so `autoPrice` resolves Qwen, Kimi, MiniMax, and GLM routes
11
+ out of the box (previously they needed a hand-typed `cost`).
12
+
13
+ ### Added
14
+
15
+ - **`MODEL_PRICES` now includes the open-weights makers** — Qwen (Alibaba /
16
+ `dashscope`), Kimi (Moonshot), MiniMax, and GLM (Z.ai), alongside the existing
17
+ DeepSeek. 55 new first-party list prices (229 → 284 entries), keyed by each
18
+ maker's own bare model id (`qwen-plus`, `kimi-k2.5`, `MiniMax-M2`, `glm-4.6`,
19
+ …). The generator's `ALLOW` set gained `dashscope` / `moonshot` / `minimax` /
20
+ `zai`; no existing price changed.
21
+
22
+ ### Notes
23
+
24
+ - These are **first-party** list rates (the maker's own API). A dedicated
25
+ inference *host* (DeepInfra, …) is often cheaper and uses HF-style ids
26
+ (`Qwen/Qwen3-…`) that won't match these bare keys — for an aggregator route,
27
+ keep passing an explicit `cost` or `discount`. The bundled rate is the
28
+ `autoPrice` baseline for the maker's own provider and a reference for the rest.
29
+ - Aggregators (deepinfra, together, fireworks, groq, openrouter) remain
30
+ deliberately excluded from the table — their prices drift per-model.
31
+
32
+ ## [0.6.4] — 2026-06-16
33
+
34
+ DX improvements that eliminate per-project boilerplate for consumers.
35
+
36
+ ### Added
37
+
38
+ - **`DEFAULT_PROVIDERS`** — canonical URL + env-var-name for common providers
39
+ (openrouter, deepinfra, tokenmart, deepseek, kunavo, runware, fal). Import
40
+ instead of redeclaring in every app; a URL change propagates on `npm update`.
41
+ - **`createEnvSink(dispatch)`** — reads `LCR_INGEST_URL` / `LCR_PROJECT` /
42
+ `LCR_INGEST_KEY` from env and returns a ready-to-use `onCall` handler (or
43
+ `undefined` when unset). Replaces the identical 30-line `sink.ts` every
44
+ consumer was copy-pasting. Pass `after` from `next/server` as `dispatch`.
45
+ - **`AnyLanguageModel`** — duck-typed model interface on `ProviderEntry` so
46
+ consumers no longer need `as` casts when their `@ai-sdk/provider` version
47
+ differs from ai-lcr's. Runtime behavior unchanged.
48
+
7
49
  ## [0.6.3] — 2026-06-11
8
50
 
9
51
  Caching — both kinds, each off by default and each a pure config flag with no
package/README.md CHANGED
@@ -96,7 +96,7 @@ const lcr = createLCR({
96
96
  });
97
97
  ```
98
98
 
99
- The same pattern works for any vendor's native SDK provider — `@ai-sdk/anthropic`, `@ai-sdk/google`, `@ai-sdk/openai`, `@ai-sdk/xai`, and so on. They all return `LanguageModelV3`, so you can mix a native vendor API with aggregators in one model's list. Native APIs are narrow (only that vendor's models) but featureful; aggregators are broad. **Official-first + aggregator-fallback** is the natural LCR shape.
99
+ The same pattern works for any vendor's native SDK provider — `@ai-sdk/anthropic`, `@ai-sdk/google`, `@ai-sdk/openai`, `@ai-sdk/xai`, and so on. `ProviderEntry` accepts `AnyLanguageModel` a duck-typed interface (`doGenerate` + `doStream` + `provider` + `modelId`) that any AI SDK model satisfies regardless of spec version (V2 or V3), so you never need `as`-casts at the integration boundary. Native APIs are narrow (only that vendor's models) but featureful; aggregators are broad. **Official-first + aggregator-fallback** is the natural LCR shape.
100
100
 
101
101
  ## Cheapest route for open-weights models (DeepInfra)
102
102
 
@@ -138,9 +138,50 @@ const lcr = createLCR({
138
138
 
139
139
  DeepInfra carries open weights only — no first-party Claude / GPT / Gemini. For those closed models, route through OpenRouter or a discount gateway instead.
140
140
 
141
+ ## Skip the boilerplate (`DEFAULT_PROVIDERS`)
142
+
143
+ Every project that routes through OpenRouter, DeepInfra, TokenMart, DeepSeek, etc. redeclares the same `baseURL` + `apiKeyEnv` pair. `DEFAULT_PROVIDERS` is a bundled dictionary — import what you need instead of copy-pasting URLs:
144
+
145
+ ```ts
146
+ import { DEFAULT_PROVIDERS } from "ai-lcr";
147
+ import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
148
+
149
+ // Pick the providers you use — type-safe, no hardcoded URLs.
150
+ const deepinfra = createOpenAICompatible({
151
+ name: "deepinfra",
152
+ baseURL: DEFAULT_PROVIDERS.deepinfra.baseURL,
153
+ apiKey: process.env[DEFAULT_PROVIDERS.deepinfra.apiKeyEnv],
154
+ });
155
+ ```
156
+
157
+ Available providers:
158
+
159
+ | Key | Base URL | Env var |
160
+ |---|---|---|
161
+ | `openrouter` | `https://openrouter.ai/api/v1` | `OPENROUTER_API_KEY` |
162
+ | `deepinfra` | `https://api.deepinfra.com/v1/openai` | `DEEPINFRA_API_KEY` |
163
+ | `tokenmart` | `https://model.service-inference.ai/v1` | `INFERENCE_API_KEY` |
164
+ | `deepseek` | `https://api.deepseek.com` | `DEEPSEEK_API_KEY` |
165
+ | `kunavo` | `https://api.kunavo.com/v1` | `KUNAVO_API_KEY` |
166
+ | `runware` | `https://api.runware.ai/v1` | `RUNWARE_API_KEY` |
167
+ | `fal` | `https://queue.fal.run` | `FAL_KEY` |
168
+
169
+ A common pattern is to subset `DEFAULT_PROVIDERS` into a project-local type for compile-time safety:
170
+
171
+ ```ts
172
+ import { DEFAULT_PROVIDERS } from "ai-lcr";
173
+
174
+ type ProviderId = "deepinfra" | "openrouter";
175
+
176
+ export const PROVIDERS = {
177
+ deepinfra: DEFAULT_PROVIDERS.deepinfra,
178
+ openrouter: DEFAULT_PROVIDERS.openrouter,
179
+ } satisfies Record<ProviderId, { baseURL: string; apiKeyEnv: string }>;
180
+ ```
181
+
141
182
  ## Zero-config pricing (`autoPrice`)
142
183
 
143
- Typing `cost: { input, output }` for every provider is the tedious part. `autoPrice: true` fills any entry that has no explicit `cost` from a **bundled price table** (`MODEL_PRICES`) — official first-party rates for the native makers (OpenAI, Anthropic, Google, DeepSeek, xAI, Mistral), keyed by the bare model id you already pass to the provider:
184
+ Typing `cost: { input, output }` for every provider is the tedious part. `autoPrice: true` fills any entry that has no explicit `cost` from a **bundled price table** (`MODEL_PRICES`) — official first-party rates for the native makers (OpenAI, Anthropic, Google, xAI, Mistral, plus the open-weights labs DeepSeek, Qwen, Kimi, MiniMax, GLM), keyed by the bare model id you already pass to the provider:
144
185
 
145
186
  ```ts
146
187
  const lcr = createLCR({
@@ -161,7 +202,7 @@ Three rules keep it predictable:
161
202
 
162
203
  - **Off by default.** Unpriced entries stay unpriced (the pre-existing behavior), so turning `autoPrice` on never silently re-prices a model — and an **explicit `cost` always wins** over the table.
163
204
  - **`discount` is the reseller knob.** A flat-% aggregator (Kunavo −20%) becomes `discount: 0.2` instead of a hand-typed number; it scales input, output, and `cacheRead` alike, and only applies when the table fills the entry. Variable-discount providers (TokenMart) still want explicit per-model `cost`.
164
- - **Native makers only.** The table carries first-party list prices the cheapest, most-featureful "go direct" route. Open-weights hosts (DeepInfra) and breadth aggregators (OpenRouter) aren't in it; price those explicitly.
205
+ - **Native makers only.** The table carries first-party list prices, keyed by each maker's own bare id (`qwen-plus`, `glm-4.6`, `kimi-k2.5`, `MiniMax-M2`). It's the autoPrice baseline when you route through that maker's own API. Open-weights *hosts* (DeepInfra uses HF-style ids like `Qwen/Qwen3-…`) and breadth aggregators (OpenRouter) aren't keyed here price those with explicit `cost` or `discount`.
165
206
 
166
207
  Look a price up yourself with `getModelPrice("claude-sonnet-4-6")`. The table is generated from [LiteLLM's price map](https://github.com/BerriAI/litellm) (MIT) — refresh with `node scripts/gen-text-prices.mjs`.
167
208
 
@@ -315,6 +356,26 @@ const lcr = createLCR({
315
356
  });
316
357
  ```
317
358
 
359
+ ### Convention-based sink (`createEnvSink`)
360
+
361
+ If your app uses the standard env vars (`LCR_INGEST_URL`, `LCR_PROJECT`, `LCR_INGEST_KEY`), you don't need to wire `createHttpSink` at all — `createEnvSink` reads them for you and returns a ready-to-use `onCall` handler (or `undefined` when `LCR_INGEST_URL` is unset, so local dev stays quiet):
362
+
363
+ ```ts
364
+ import { createEnvSink } from "ai-lcr";
365
+ import { after } from "next/server";
366
+
367
+ export const lcrCallSink = createEnvSink(after);
368
+ // → use as `onCall: lcrCallSink` in createLCR
369
+ ```
370
+
371
+ The only required argument is `dispatch` — a framework-specific fire-and-forget runner (Next.js: `after`, Cloudflare: `ctx.waitUntil`, plain servers: `(fn) => fn()`). Env vars:
372
+
373
+ | Var | Required | Description |
374
+ |---|---|---|
375
+ | `LCR_INGEST_URL` | yes (no URL → sink is `undefined`) | Dashboard origin, e.g. `https://lcr.ideamarketfit.com` |
376
+ | `LCR_PROJECT` | no | Project tag merged into each payload; falls back to `SITE_KEY` |
377
+ | `LCR_INGEST_KEY` | no | Bearer token (only if the dashboard sets `INGEST_KEY`) |
378
+
318
379
  ### The companion dashboard ([`ai-lcr-dashboard`](https://github.com/ai-lcr/ai-lcr-dashboard))
319
380
 
320
381
  <p align="center">
package/README.zh-CN.md CHANGED
@@ -96,7 +96,7 @@ const lcr = createLCR({
96
96
  });
97
97
  ```
98
98
 
99
- 同样的模式适用于任何厂商的原生 SDK provider——`@ai-sdk/anthropic`、`@ai-sdk/google`、`@ai-sdk/openai`、`@ai-sdk/xai` 等等。它们都返回 `LanguageModelV3`,所以你可以在一个模型的列表里把厂商原生 API 和聚合器混着用。原生 API 覆盖窄(只有该厂商自己的模型)但特性全;聚合器覆盖广。**官方优先 + 聚合器兜底** 正是 LCR 最自然的形态。
99
+ 同样的模式适用于任何厂商的原生 SDK provider——`@ai-sdk/anthropic`、`@ai-sdk/google`、`@ai-sdk/openai`、`@ai-sdk/xai` 等等。`ProviderEntry` 接受 `AnyLanguageModel`——一个鸭子类型接口(`doGenerate` + `doStream` + `provider` + `modelId`),任何 AI SDK model 无论 V2 还是 V3 spec 都满足,集成边界无需 `as` 强转。原生 API 覆盖窄(只有该厂商自己的模型)但特性全;聚合器覆盖广。**官方优先 + 聚合器兜底** 正是 LCR 最自然的形态。
100
100
 
101
101
  ## 开源权重模型的最便宜路由(DeepInfra)
102
102
 
@@ -138,6 +138,47 @@ const lcr = createLCR({
138
138
 
139
139
  DeepInfra 只承载开源权重——没有第一方 Claude / GPT / Gemini。那些闭源模型请走 OpenRouter 或折扣中转。
140
140
 
141
+ ## 省掉样板代码(`DEFAULT_PROVIDERS`)
142
+
143
+ 每个路由 OpenRouter、DeepInfra、TokenMart、DeepSeek 等的项目都要重复声明相同的 `baseURL` + `apiKeyEnv`。`DEFAULT_PROVIDERS` 是一份内置字典——import 你需要的那几个就行,不用再复制粘贴 URL:
144
+
145
+ ```ts
146
+ import { DEFAULT_PROVIDERS } from "ai-lcr";
147
+ import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
148
+
149
+ // 按需取——类型安全,无硬编码 URL。
150
+ const deepinfra = createOpenAICompatible({
151
+ name: "deepinfra",
152
+ baseURL: DEFAULT_PROVIDERS.deepinfra.baseURL,
153
+ apiKey: process.env[DEFAULT_PROVIDERS.deepinfra.apiKeyEnv],
154
+ });
155
+ ```
156
+
157
+ 可用 provider:
158
+
159
+ | Key | Base URL | Env 变量 |
160
+ |---|---|---|
161
+ | `openrouter` | `https://openrouter.ai/api/v1` | `OPENROUTER_API_KEY` |
162
+ | `deepinfra` | `https://api.deepinfra.com/v1/openai` | `DEEPINFRA_API_KEY` |
163
+ | `tokenmart` | `https://model.service-inference.ai/v1` | `INFERENCE_API_KEY` |
164
+ | `deepseek` | `https://api.deepseek.com` | `DEEPSEEK_API_KEY` |
165
+ | `kunavo` | `https://api.kunavo.com/v1` | `KUNAVO_API_KEY` |
166
+ | `runware` | `https://api.runware.ai/v1` | `RUNWARE_API_KEY` |
167
+ | `fal` | `https://queue.fal.run` | `FAL_KEY` |
168
+
169
+ 常见用法是取 `DEFAULT_PROVIDERS` 的子集,并声明一个项目级类型保证编译安全:
170
+
171
+ ```ts
172
+ import { DEFAULT_PROVIDERS } from "ai-lcr";
173
+
174
+ type ProviderId = "deepinfra" | "openrouter";
175
+
176
+ export const PROVIDERS = {
177
+ deepinfra: DEFAULT_PROVIDERS.deepinfra,
178
+ openrouter: DEFAULT_PROVIDERS.openrouter,
179
+ } satisfies Record<ProviderId, { baseURL: string; apiKeyEnv: string }>;
180
+ ```
181
+
141
182
  ## 它如何路由
142
183
 
143
184
  1. **最便宜优先。** provider 按顺序依次尝试——把它们排成最便宜优先,或设置 `autoSort: true` 让它按 `cost` 自动排序。
@@ -221,7 +262,17 @@ interface CallRecord {
221
262
 
222
263
  **节约怎么算才诚实:** `baselineKind` 说明 `baselineUsd` 是哪种基线——文本是**链尾兜底 provider 的列表价**(`"last-leg"`,故意不取最贵的一条:prompt 缓存可能让标价更便宜的那家在缓存重的调用上反而更贵,取最大值会凭空造出"节约");媒体是**模型厂商官方第一方价**(`"official"`,按实际秒数算),查不到官方价时退化为你配置里最贵的路由(`"priciest-route"`,自我参照,仅说明跨 provider 价差)。
223
264
 
224
- **送进收集器:** `createHttpSink` 把每条记录 POST 到任意 endpoint(serverless 上传 Next.js 的 `after` 作 `dispatch` 防止被掐断)。配套的自托管 dashboard [`ai-lcr-dashboard`](https://github.com/ai-lcr/ai-lcr-dashboard)(Next.js + Postgres,Vercel 一键部署)专为这些记录而建:花费 vs 节约趋势、各 provider failover 健康度、媒体 $/秒 与 $/张、以及**价格漂移面板**——某条 model@provider 路由的实报账单与价格表偏差超过 ±20% 时点名示警(约 100× 基本就是美元当美分的笔误)。只存元数据,不存 prompt 和输出。
265
+ **送进收集器:** `createHttpSink` 把每条记录 POST 到任意 endpoint(serverless 上传 Next.js 的 `after` 作 `dispatch` 防止被掐断)。如果你用标准环境变量(`LCR_INGEST_URL`、`LCR_PROJECT`、`LCR_INGEST_KEY`),`createEnvSink` 全部替你读好——三行搞定:
266
+
267
+ ```ts
268
+ import { createEnvSink } from "ai-lcr";
269
+ import { after } from "next/server";
270
+ export const lcrCallSink = createEnvSink(after);
271
+ ```
272
+
273
+ `LCR_INGEST_URL` 不设 → sink 是 `undefined`,本地开发自动静默。唯一必传参数是 `dispatch`——框架相关的 fire-and-forget runner(Next.js: `after`;Cloudflare: `ctx.waitUntil`;长驻服务: `(fn) => fn()`)。
274
+
275
+ 配套的自托管 dashboard [`ai-lcr-dashboard`](https://github.com/ai-lcr/ai-lcr-dashboard)(Next.js + Postgres,Vercel 一键部署)专为这些记录而建:花费 vs 节约趋势、各 provider failover 健康度、媒体 $/秒 与 $/张、以及**价格漂移面板**——某条 model@provider 路由的实报账单与价格表偏差超过 ±20% 时点名示警(约 100× 基本就是美元当美分的笔误)。只存元数据,不存 prompt 和输出。
225
276
 
226
277
  ## 支持的 provider
227
278
 
package/dist/index.cjs CHANGED
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ DEFAULT_PROVIDERS: () => DEFAULT_PROVIDERS,
23
24
  DEFAULT_REFERENCE: () => DEFAULT_REFERENCE,
24
25
  MEDIA_PRICING: () => MEDIA_PRICING,
25
26
  MODEL_PRICES: () => MODEL_PRICES,
@@ -29,6 +30,7 @@ __export(index_exports, {
29
30
  classifyError: () => classifyError,
30
31
  classifyErrorKind: () => classifyErrorKind,
31
32
  comparePrices: () => comparePrices,
33
+ createEnvSink: () => createEnvSink,
32
34
  createFalMediaAdapter: () => createFalMediaAdapter,
33
35
  createHttpSink: () => createHttpSink,
34
36
  createKunavoMediaAdapter: () => createKunavoMediaAdapter,
@@ -905,6 +907,30 @@ function createHttpSink(options) {
905
907
  };
906
908
  }
907
909
 
910
+ // src/env-sink.ts
911
+ function createEnvSink(dispatch) {
912
+ const base = process.env.LCR_INGEST_URL?.replace(/\/+$/, "");
913
+ if (!base) return void 0;
914
+ return createHttpSink({
915
+ url: `${base}/api/ingest`,
916
+ headers: process.env.LCR_INGEST_KEY ? { authorization: `Bearer ${process.env.LCR_INGEST_KEY}` } : void 0,
917
+ project: process.env.LCR_PROJECT ?? process.env.SITE_KEY,
918
+ dispatch,
919
+ onError: (err) => console.error("[lcr] ingest POST failed:", err)
920
+ });
921
+ }
922
+
923
+ // src/providers.ts
924
+ var DEFAULT_PROVIDERS = {
925
+ openrouter: { baseURL: "https://openrouter.ai/api/v1", apiKeyEnv: "OPENROUTER_API_KEY" },
926
+ deepinfra: { baseURL: "https://api.deepinfra.com/v1/openai", apiKeyEnv: "DEEPINFRA_API_KEY" },
927
+ tokenmart: { baseURL: "https://model.service-inference.ai/v1", apiKeyEnv: "INFERENCE_API_KEY" },
928
+ deepseek: { baseURL: "https://api.deepseek.com", apiKeyEnv: "DEEPSEEK_API_KEY" },
929
+ kunavo: { baseURL: "https://api.kunavo.com/v1", apiKeyEnv: "KUNAVO_API_KEY" },
930
+ runware: { baseURL: "https://api.runware.ai/v1", apiKeyEnv: "RUNWARE_API_KEY" },
931
+ fal: { baseURL: "https://queue.fal.run", apiKeyEnv: "FAL_KEY" }
932
+ };
933
+
908
934
  // src/text-prices.ts
909
935
  var MODEL_PRICES = {
910
936
  "chatgpt-4o-latest": { input: 5, output: 15 },
@@ -977,6 +1003,16 @@ var MODEL_PRICES = {
977
1003
  "gemini-gemma-2-9b-it": { input: 0.35, output: 1.05 },
978
1004
  "gemini-pro-latest": { input: 1.25, output: 10, cacheRead: 0.125 },
979
1005
  "gemini-robotics-er-1.5-preview": { input: 0.3, output: 2.5 },
1006
+ "glm-4-32b-0414-128k": { input: 0.1, output: 0.1 },
1007
+ "glm-4.5": { input: 0.6, output: 2.2 },
1008
+ "glm-4.5-air": { input: 0.2, output: 1.1 },
1009
+ "glm-4.5-airx": { input: 1.1, output: 4.5 },
1010
+ "glm-4.5-x": { input: 2.2, output: 8.9 },
1011
+ "glm-4.5v": { input: 0.6, output: 1.8 },
1012
+ "glm-4.6": { input: 0.6, output: 2.2, cacheRead: 0.11 },
1013
+ "glm-4.7": { input: 0.6, output: 2.2, cacheRead: 0.11 },
1014
+ "glm-5": { input: 1, output: 3.2, cacheRead: 0.2 },
1015
+ "glm-5-code": { input: 1.2, output: 5, cacheRead: 0.3 },
980
1016
  "gpt-3.5-turbo": { input: 0.5, output: 1.5 },
981
1017
  "gpt-3.5-turbo-0125": { input: 0.5, output: 1.5 },
982
1018
  "gpt-3.5-turbo-1106": { input: 1, output: 2 },
@@ -1091,6 +1127,18 @@ var MODEL_PRICES = {
1091
1127
  "grok-code-fast-1": { input: 0.2, output: 1.5, cacheRead: 0.02 },
1092
1128
  "grok-code-fast-1-0825": { input: 0.2, output: 1.5, cacheRead: 0.02 },
1093
1129
  "grok-vision-beta": { input: 5, output: 15 },
1130
+ "kimi-k2-0711-preview": { input: 0.6, output: 2.5, cacheRead: 0.15 },
1131
+ "kimi-k2-0905-preview": { input: 0.6, output: 2.5, cacheRead: 0.15 },
1132
+ "kimi-k2-thinking": { input: 0.6, output: 2.5, cacheRead: 0.15 },
1133
+ "kimi-k2-thinking-turbo": { input: 1.15, output: 8, cacheRead: 0.15 },
1134
+ "kimi-k2-turbo-preview": { input: 1.15, output: 8, cacheRead: 0.15 },
1135
+ "kimi-k2.5": { input: 0.6, output: 3, cacheRead: 0.1 },
1136
+ "kimi-k2.6": { input: 0.95, output: 4, cacheRead: 0.16 },
1137
+ "kimi-latest": { input: 2, output: 5, cacheRead: 0.15 },
1138
+ "kimi-latest-128k": { input: 2, output: 5, cacheRead: 0.15 },
1139
+ "kimi-latest-32k": { input: 1, output: 3, cacheRead: 0.15 },
1140
+ "kimi-latest-8k": { input: 0.2, output: 2, cacheRead: 0.15 },
1141
+ "kimi-thinking-preview": { input: 0.6, output: 2.5, cacheRead: 0.15 },
1094
1142
  "labs-devstral-small-2512": { input: 0.1, output: 0.3 },
1095
1143
  "magistral-medium-1-2-2509": { input: 2, output: 5 },
1096
1144
  "magistral-medium-2506": { input: 2, output: 5 },
@@ -1099,6 +1147,12 @@ var MODEL_PRICES = {
1099
1147
  "magistral-small-1-2-2509": { input: 0.5, output: 1.5 },
1100
1148
  "magistral-small-2506": { input: 0.5, output: 1.5 },
1101
1149
  "magistral-small-latest": { input: 0.5, output: 1.5 },
1150
+ "MiniMax-M2": { input: 0.3, output: 1.2, cacheRead: 0.03 },
1151
+ "MiniMax-M2.1": { input: 0.3, output: 1.2, cacheRead: 0.03 },
1152
+ "MiniMax-M2.1-lightning": { input: 0.3, output: 2.4, cacheRead: 0.03 },
1153
+ "MiniMax-M2.5": { input: 0.3, output: 1.2, cacheRead: 0.03 },
1154
+ "MiniMax-M2.5-lightning": { input: 0.3, output: 2.4, cacheRead: 0.03 },
1155
+ "MiniMax-M3": { input: 0.6, output: 2.4, cacheRead: 0.12 },
1102
1156
  "ministral-3-14b-2512": { input: 0.2, output: 0.2 },
1103
1157
  "ministral-3-3b-2512": { input: 0.1, output: 0.1 },
1104
1158
  "ministral-3-8b-2512": { input: 0.15, output: 0.15 },
@@ -1119,6 +1173,16 @@ var MODEL_PRICES = {
1119
1173
  "mistral-small-3-2-2506": { input: 0.06, output: 0.18 },
1120
1174
  "mistral-small-latest": { input: 0.06, output: 0.18 },
1121
1175
  "mistral-tiny": { input: 0.25, output: 0.25 },
1176
+ "moonshot-v1-128k": { input: 2, output: 5 },
1177
+ "moonshot-v1-128k-0430": { input: 2, output: 5 },
1178
+ "moonshot-v1-128k-vision-preview": { input: 2, output: 5 },
1179
+ "moonshot-v1-32k": { input: 1, output: 3 },
1180
+ "moonshot-v1-32k-0430": { input: 1, output: 3 },
1181
+ "moonshot-v1-32k-vision-preview": { input: 1, output: 3 },
1182
+ "moonshot-v1-8k": { input: 0.2, output: 2 },
1183
+ "moonshot-v1-8k-0430": { input: 0.2, output: 2 },
1184
+ "moonshot-v1-8k-vision-preview": { input: 0.2, output: 2 },
1185
+ "moonshot-v1-auto": { input: 2, output: 5 },
1122
1186
  "o1": { input: 15, output: 60, cacheRead: 7.5 },
1123
1187
  "o1-2024-12-17": { input: 15, output: 60, cacheRead: 7.5 },
1124
1188
  "o3": { input: 2, output: 8, cacheRead: 0.5 },
@@ -1135,7 +1199,24 @@ var MODEL_PRICES = {
1135
1199
  "open-mixtral-8x7b": { input: 0.7, output: 0.7 },
1136
1200
  "pixtral-12b-2409": { input: 0.15, output: 0.15 },
1137
1201
  "pixtral-large-2411": { input: 2, output: 6 },
1138
- "pixtral-large-latest": { input: 2, output: 6 }
1202
+ "pixtral-large-latest": { input: 2, output: 6 },
1203
+ "qwen-coder": { input: 0.3, output: 1.5 },
1204
+ "qwen-max": { input: 1.6, output: 6.4 },
1205
+ "qwen-plus": { input: 0.4, output: 1.2 },
1206
+ "qwen-plus-2025-01-25": { input: 0.4, output: 1.2 },
1207
+ "qwen-plus-2025-04-28": { input: 0.4, output: 1.2 },
1208
+ "qwen-plus-2025-07-14": { input: 0.4, output: 1.2 },
1209
+ "qwen-turbo": { input: 0.05, output: 0.2 },
1210
+ "qwen-turbo-2024-11-01": { input: 0.05, output: 0.2 },
1211
+ "qwen-turbo-2025-04-28": { input: 0.05, output: 0.2 },
1212
+ "qwen-turbo-latest": { input: 0.05, output: 0.2 },
1213
+ "qwen3-next-80b-a3b-instruct": { input: 0.15, output: 1.2 },
1214
+ "qwen3-next-80b-a3b-thinking": { input: 0.15, output: 1.2 },
1215
+ "qwen3-vl-235b-a22b-instruct": { input: 0.4, output: 1.6 },
1216
+ "qwen3-vl-235b-a22b-thinking": { input: 0.4, output: 4 },
1217
+ "qwen3-vl-32b-instruct": { input: 0.16, output: 0.64 },
1218
+ "qwen3-vl-32b-thinking": { input: 0.16, output: 2.87 },
1219
+ "qwq-plus": { input: 0.8, output: 2.4 }
1139
1220
  };
1140
1221
 
1141
1222
  // src/media-official.ts
@@ -2259,6 +2340,7 @@ function createLCR(config) {
2259
2340
  }
2260
2341
  // Annotate the CommonJS export names for ESM import in node:
2261
2342
  0 && (module.exports = {
2343
+ DEFAULT_PROVIDERS,
2262
2344
  DEFAULT_REFERENCE,
2263
2345
  MEDIA_PRICING,
2264
2346
  MODEL_PRICES,
@@ -2268,6 +2350,7 @@ function createLCR(config) {
2268
2350
  classifyError,
2269
2351
  classifyErrorKind,
2270
2352
  comparePrices,
2353
+ createEnvSink,
2271
2354
  createFalMediaAdapter,
2272
2355
  createHttpSink,
2273
2356
  createKunavoMediaAdapter,
package/dist/index.d.cts CHANGED
@@ -472,6 +472,62 @@ interface HttpSinkOptions {
472
472
  */
473
473
  declare function createHttpSink(options: HttpSinkOptions): (record: CallRecord) => void;
474
474
 
475
+ /**
476
+ * Build an `onCall` sink from env vars, or return undefined when
477
+ * `LCR_INGEST_URL` is not set.
478
+ *
479
+ * Env vars read:
480
+ * - `LCR_INGEST_URL` — dashboard origin (required for the sink to activate)
481
+ * - `LCR_PROJECT` — project tag; falls back to `SITE_KEY` (freeart compat)
482
+ * - `LCR_INGEST_KEY` — optional Bearer token
483
+ */
484
+ declare function createEnvSink(dispatch: (task: () => void | Promise<void>) => void): ((record: CallRecord) => void) | undefined;
485
+
486
+ /**
487
+ * Default provider configs — the URLs + env var names that every portfolio app
488
+ * copy-pastes. Import these instead of redeclaring them per project.
489
+ *
490
+ * Adding a provider here (or changing a URL) propagates to every consumer on
491
+ * the next `npm update ai-lcr` — no per-app code change.
492
+ */
493
+ interface ProviderConfig {
494
+ /** Base URL for the OpenAI-compatible endpoint (no trailing `/v1` unless required). */
495
+ baseURL: string;
496
+ /** Name of the env var that holds the API key. */
497
+ apiKeyEnv: string;
498
+ }
499
+ declare const DEFAULT_PROVIDERS: {
500
+ readonly openrouter: {
501
+ readonly baseURL: "https://openrouter.ai/api/v1";
502
+ readonly apiKeyEnv: "OPENROUTER_API_KEY";
503
+ };
504
+ readonly deepinfra: {
505
+ readonly baseURL: "https://api.deepinfra.com/v1/openai";
506
+ readonly apiKeyEnv: "DEEPINFRA_API_KEY";
507
+ };
508
+ readonly tokenmart: {
509
+ readonly baseURL: "https://model.service-inference.ai/v1";
510
+ readonly apiKeyEnv: "INFERENCE_API_KEY";
511
+ };
512
+ readonly deepseek: {
513
+ readonly baseURL: "https://api.deepseek.com";
514
+ readonly apiKeyEnv: "DEEPSEEK_API_KEY";
515
+ };
516
+ readonly kunavo: {
517
+ readonly baseURL: "https://api.kunavo.com/v1";
518
+ readonly apiKeyEnv: "KUNAVO_API_KEY";
519
+ };
520
+ readonly runware: {
521
+ readonly baseURL: "https://api.runware.ai/v1";
522
+ readonly apiKeyEnv: "RUNWARE_API_KEY";
523
+ };
524
+ readonly fal: {
525
+ readonly baseURL: "https://queue.fal.run";
526
+ readonly apiKeyEnv: "FAL_KEY";
527
+ };
528
+ };
529
+ type DefaultProviderId = keyof typeof DEFAULT_PROVIDERS;
530
+
475
531
  declare const MODEL_PRICES: Record<string, ProviderCost>;
476
532
 
477
533
  /**
@@ -997,13 +1053,28 @@ declare function createFalMediaAdapter(config: FalMediaConfig): MediaAdapter;
997
1053
  * a bundled price table for zero-config cheapest-first ordering.
998
1054
  */
999
1055
 
1056
+ /**
1057
+ * Any object with the `doGenerate` + `doStream` shape — accepts LanguageModelV3
1058
+ * from any version of `@ai-sdk/provider` so consumers don't need a cast when
1059
+ * their transitive `@ai-sdk/provider` version differs from ai-lcr's.
1060
+ */
1061
+ type AnyLanguageModel = {
1062
+ doGenerate: (...args: any[]) => any;
1063
+ doStream: (...args: any[]) => any;
1064
+ provider: string;
1065
+ modelId: string;
1066
+ };
1000
1067
  /**
1001
1068
  * A provider for a model: either a bare AI SDK model (e.g.
1002
1069
  * `createOpenAICompatible(...)("id")`), or that model wrapped with price/label
1003
1070
  * metadata to unlock cost accounting and cheapest-first auto-sorting.
1071
+ *
1072
+ * `model` accepts any AI SDK language model — both LanguageModelV3 and
1073
+ * compatible shapes from other `@ai-sdk/provider` versions — so consumers
1074
+ * never need an `as` cast at the boundary.
1004
1075
  */
1005
- type ProviderEntry = LanguageModelV3 | {
1006
- model: LanguageModelV3;
1076
+ type ProviderEntry = AnyLanguageModel | {
1077
+ model: AnyLanguageModel;
1007
1078
  /** USD per 1M tokens. Enables `onCost` and `autoSort`. */
1008
1079
  cost?: ProviderCost;
1009
1080
  /** Label used in cost events / logs. Defaults to the model's provider id. */
@@ -1128,4 +1199,4 @@ type LCRRouter = (modelName: string) => LanguageModelV3;
1128
1199
  */
1129
1200
  declare function createLCR(config: LCRConfig): LCRRouter;
1130
1201
 
1131
- export { type BillableContext, type CacheOptions, type CacheStore, type CachedCall, type CachedMeta, type CallRecord, type CooldownOptions, type CostEvent, DEFAULT_REFERENCE, type ErrorKind, type FormatOptions, type HttpSinkOptions, type LCRConfig, type LCRRouter, MEDIA_PRICING, MODEL_PRICES, type MediaAdapter, type MediaCostEvent, type MediaGenerateRequest, type MediaGenerateResult, type MediaJobHandle, type MediaJobStatus, type MediaLCR, type MediaLCRConfig, type MediaModality, type MediaModelDef, type MediaOutput, type MediaPollResult, type MediaPricing, type MediaRegistry, type MediaRoute, type MediaRunResult, type MediaStatusRequest, type MediaStatusResult, type MediaSubmitOptions, type MediaSubmitRequest, type MediaSubmitResult, type MediaUnit, type MediaUsage, type MemoryCacheOptions, OFFICIAL_PRICES, type PriceComparisonRow, type PromptCacheOptions, type ProviderCost, type ProviderEntry, type RankedRoute, type ReferenceSpec, type RouteAttempt, billableUnits, cheapestRoute, classifyError, classifyErrorKind, comparePrices, createFalMediaAdapter, createHttpSink, createKunavoMediaAdapter, createLCR, createMediaLCR, createMemoryCacheStore, createRunwareMediaAdapter, durationFromInput, formatCallRecord, getModelPrice, isAbortError, isNetworkError, isRetryableError, normalizedCents, priceCents, rankRoutes, referenceMegapixels, shouldFailover };
1202
+ export { type AnyLanguageModel, type BillableContext, type CacheOptions, type CacheStore, type CachedCall, type CachedMeta, type CallRecord, type CooldownOptions, type CostEvent, DEFAULT_PROVIDERS, DEFAULT_REFERENCE, type DefaultProviderId, type ErrorKind, type FormatOptions, type HttpSinkOptions, type LCRConfig, type LCRRouter, MEDIA_PRICING, MODEL_PRICES, type MediaAdapter, type MediaCostEvent, type MediaGenerateRequest, type MediaGenerateResult, type MediaJobHandle, type MediaJobStatus, type MediaLCR, type MediaLCRConfig, type MediaModality, type MediaModelDef, type MediaOutput, type MediaPollResult, type MediaPricing, type MediaRegistry, type MediaRoute, type MediaRunResult, type MediaStatusRequest, type MediaStatusResult, type MediaSubmitOptions, type MediaSubmitRequest, type MediaSubmitResult, type MediaUnit, type MediaUsage, type MemoryCacheOptions, OFFICIAL_PRICES, type PriceComparisonRow, type PromptCacheOptions, type ProviderConfig, type ProviderCost, type ProviderEntry, type RankedRoute, type ReferenceSpec, type RouteAttempt, billableUnits, cheapestRoute, classifyError, classifyErrorKind, comparePrices, createEnvSink, createFalMediaAdapter, createHttpSink, createKunavoMediaAdapter, createLCR, createMediaLCR, createMemoryCacheStore, createRunwareMediaAdapter, durationFromInput, formatCallRecord, getModelPrice, isAbortError, isNetworkError, isRetryableError, normalizedCents, priceCents, rankRoutes, referenceMegapixels, shouldFailover };
package/dist/index.d.ts CHANGED
@@ -472,6 +472,62 @@ interface HttpSinkOptions {
472
472
  */
473
473
  declare function createHttpSink(options: HttpSinkOptions): (record: CallRecord) => void;
474
474
 
475
+ /**
476
+ * Build an `onCall` sink from env vars, or return undefined when
477
+ * `LCR_INGEST_URL` is not set.
478
+ *
479
+ * Env vars read:
480
+ * - `LCR_INGEST_URL` — dashboard origin (required for the sink to activate)
481
+ * - `LCR_PROJECT` — project tag; falls back to `SITE_KEY` (freeart compat)
482
+ * - `LCR_INGEST_KEY` — optional Bearer token
483
+ */
484
+ declare function createEnvSink(dispatch: (task: () => void | Promise<void>) => void): ((record: CallRecord) => void) | undefined;
485
+
486
+ /**
487
+ * Default provider configs — the URLs + env var names that every portfolio app
488
+ * copy-pastes. Import these instead of redeclaring them per project.
489
+ *
490
+ * Adding a provider here (or changing a URL) propagates to every consumer on
491
+ * the next `npm update ai-lcr` — no per-app code change.
492
+ */
493
+ interface ProviderConfig {
494
+ /** Base URL for the OpenAI-compatible endpoint (no trailing `/v1` unless required). */
495
+ baseURL: string;
496
+ /** Name of the env var that holds the API key. */
497
+ apiKeyEnv: string;
498
+ }
499
+ declare const DEFAULT_PROVIDERS: {
500
+ readonly openrouter: {
501
+ readonly baseURL: "https://openrouter.ai/api/v1";
502
+ readonly apiKeyEnv: "OPENROUTER_API_KEY";
503
+ };
504
+ readonly deepinfra: {
505
+ readonly baseURL: "https://api.deepinfra.com/v1/openai";
506
+ readonly apiKeyEnv: "DEEPINFRA_API_KEY";
507
+ };
508
+ readonly tokenmart: {
509
+ readonly baseURL: "https://model.service-inference.ai/v1";
510
+ readonly apiKeyEnv: "INFERENCE_API_KEY";
511
+ };
512
+ readonly deepseek: {
513
+ readonly baseURL: "https://api.deepseek.com";
514
+ readonly apiKeyEnv: "DEEPSEEK_API_KEY";
515
+ };
516
+ readonly kunavo: {
517
+ readonly baseURL: "https://api.kunavo.com/v1";
518
+ readonly apiKeyEnv: "KUNAVO_API_KEY";
519
+ };
520
+ readonly runware: {
521
+ readonly baseURL: "https://api.runware.ai/v1";
522
+ readonly apiKeyEnv: "RUNWARE_API_KEY";
523
+ };
524
+ readonly fal: {
525
+ readonly baseURL: "https://queue.fal.run";
526
+ readonly apiKeyEnv: "FAL_KEY";
527
+ };
528
+ };
529
+ type DefaultProviderId = keyof typeof DEFAULT_PROVIDERS;
530
+
475
531
  declare const MODEL_PRICES: Record<string, ProviderCost>;
476
532
 
477
533
  /**
@@ -997,13 +1053,28 @@ declare function createFalMediaAdapter(config: FalMediaConfig): MediaAdapter;
997
1053
  * a bundled price table for zero-config cheapest-first ordering.
998
1054
  */
999
1055
 
1056
+ /**
1057
+ * Any object with the `doGenerate` + `doStream` shape — accepts LanguageModelV3
1058
+ * from any version of `@ai-sdk/provider` so consumers don't need a cast when
1059
+ * their transitive `@ai-sdk/provider` version differs from ai-lcr's.
1060
+ */
1061
+ type AnyLanguageModel = {
1062
+ doGenerate: (...args: any[]) => any;
1063
+ doStream: (...args: any[]) => any;
1064
+ provider: string;
1065
+ modelId: string;
1066
+ };
1000
1067
  /**
1001
1068
  * A provider for a model: either a bare AI SDK model (e.g.
1002
1069
  * `createOpenAICompatible(...)("id")`), or that model wrapped with price/label
1003
1070
  * metadata to unlock cost accounting and cheapest-first auto-sorting.
1071
+ *
1072
+ * `model` accepts any AI SDK language model — both LanguageModelV3 and
1073
+ * compatible shapes from other `@ai-sdk/provider` versions — so consumers
1074
+ * never need an `as` cast at the boundary.
1004
1075
  */
1005
- type ProviderEntry = LanguageModelV3 | {
1006
- model: LanguageModelV3;
1076
+ type ProviderEntry = AnyLanguageModel | {
1077
+ model: AnyLanguageModel;
1007
1078
  /** USD per 1M tokens. Enables `onCost` and `autoSort`. */
1008
1079
  cost?: ProviderCost;
1009
1080
  /** Label used in cost events / logs. Defaults to the model's provider id. */
@@ -1128,4 +1199,4 @@ type LCRRouter = (modelName: string) => LanguageModelV3;
1128
1199
  */
1129
1200
  declare function createLCR(config: LCRConfig): LCRRouter;
1130
1201
 
1131
- export { type BillableContext, type CacheOptions, type CacheStore, type CachedCall, type CachedMeta, type CallRecord, type CooldownOptions, type CostEvent, DEFAULT_REFERENCE, type ErrorKind, type FormatOptions, type HttpSinkOptions, type LCRConfig, type LCRRouter, MEDIA_PRICING, MODEL_PRICES, type MediaAdapter, type MediaCostEvent, type MediaGenerateRequest, type MediaGenerateResult, type MediaJobHandle, type MediaJobStatus, type MediaLCR, type MediaLCRConfig, type MediaModality, type MediaModelDef, type MediaOutput, type MediaPollResult, type MediaPricing, type MediaRegistry, type MediaRoute, type MediaRunResult, type MediaStatusRequest, type MediaStatusResult, type MediaSubmitOptions, type MediaSubmitRequest, type MediaSubmitResult, type MediaUnit, type MediaUsage, type MemoryCacheOptions, OFFICIAL_PRICES, type PriceComparisonRow, type PromptCacheOptions, type ProviderCost, type ProviderEntry, type RankedRoute, type ReferenceSpec, type RouteAttempt, billableUnits, cheapestRoute, classifyError, classifyErrorKind, comparePrices, createFalMediaAdapter, createHttpSink, createKunavoMediaAdapter, createLCR, createMediaLCR, createMemoryCacheStore, createRunwareMediaAdapter, durationFromInput, formatCallRecord, getModelPrice, isAbortError, isNetworkError, isRetryableError, normalizedCents, priceCents, rankRoutes, referenceMegapixels, shouldFailover };
1202
+ export { type AnyLanguageModel, type BillableContext, type CacheOptions, type CacheStore, type CachedCall, type CachedMeta, type CallRecord, type CooldownOptions, type CostEvent, DEFAULT_PROVIDERS, DEFAULT_REFERENCE, type DefaultProviderId, type ErrorKind, type FormatOptions, type HttpSinkOptions, type LCRConfig, type LCRRouter, MEDIA_PRICING, MODEL_PRICES, type MediaAdapter, type MediaCostEvent, type MediaGenerateRequest, type MediaGenerateResult, type MediaJobHandle, type MediaJobStatus, type MediaLCR, type MediaLCRConfig, type MediaModality, type MediaModelDef, type MediaOutput, type MediaPollResult, type MediaPricing, type MediaRegistry, type MediaRoute, type MediaRunResult, type MediaStatusRequest, type MediaStatusResult, type MediaSubmitOptions, type MediaSubmitRequest, type MediaSubmitResult, type MediaUnit, type MediaUsage, type MemoryCacheOptions, OFFICIAL_PRICES, type PriceComparisonRow, type PromptCacheOptions, type ProviderConfig, type ProviderCost, type ProviderEntry, type RankedRoute, type ReferenceSpec, type RouteAttempt, billableUnits, cheapestRoute, classifyError, classifyErrorKind, comparePrices, createEnvSink, createFalMediaAdapter, createHttpSink, createKunavoMediaAdapter, createLCR, createMediaLCR, createMemoryCacheStore, createRunwareMediaAdapter, durationFromInput, formatCallRecord, getModelPrice, isAbortError, isNetworkError, isRetryableError, normalizedCents, priceCents, rankRoutes, referenceMegapixels, shouldFailover };
package/dist/index.js CHANGED
@@ -853,6 +853,30 @@ function createHttpSink(options) {
853
853
  };
854
854
  }
855
855
 
856
+ // src/env-sink.ts
857
+ function createEnvSink(dispatch) {
858
+ const base = process.env.LCR_INGEST_URL?.replace(/\/+$/, "");
859
+ if (!base) return void 0;
860
+ return createHttpSink({
861
+ url: `${base}/api/ingest`,
862
+ headers: process.env.LCR_INGEST_KEY ? { authorization: `Bearer ${process.env.LCR_INGEST_KEY}` } : void 0,
863
+ project: process.env.LCR_PROJECT ?? process.env.SITE_KEY,
864
+ dispatch,
865
+ onError: (err) => console.error("[lcr] ingest POST failed:", err)
866
+ });
867
+ }
868
+
869
+ // src/providers.ts
870
+ var DEFAULT_PROVIDERS = {
871
+ openrouter: { baseURL: "https://openrouter.ai/api/v1", apiKeyEnv: "OPENROUTER_API_KEY" },
872
+ deepinfra: { baseURL: "https://api.deepinfra.com/v1/openai", apiKeyEnv: "DEEPINFRA_API_KEY" },
873
+ tokenmart: { baseURL: "https://model.service-inference.ai/v1", apiKeyEnv: "INFERENCE_API_KEY" },
874
+ deepseek: { baseURL: "https://api.deepseek.com", apiKeyEnv: "DEEPSEEK_API_KEY" },
875
+ kunavo: { baseURL: "https://api.kunavo.com/v1", apiKeyEnv: "KUNAVO_API_KEY" },
876
+ runware: { baseURL: "https://api.runware.ai/v1", apiKeyEnv: "RUNWARE_API_KEY" },
877
+ fal: { baseURL: "https://queue.fal.run", apiKeyEnv: "FAL_KEY" }
878
+ };
879
+
856
880
  // src/text-prices.ts
857
881
  var MODEL_PRICES = {
858
882
  "chatgpt-4o-latest": { input: 5, output: 15 },
@@ -925,6 +949,16 @@ var MODEL_PRICES = {
925
949
  "gemini-gemma-2-9b-it": { input: 0.35, output: 1.05 },
926
950
  "gemini-pro-latest": { input: 1.25, output: 10, cacheRead: 0.125 },
927
951
  "gemini-robotics-er-1.5-preview": { input: 0.3, output: 2.5 },
952
+ "glm-4-32b-0414-128k": { input: 0.1, output: 0.1 },
953
+ "glm-4.5": { input: 0.6, output: 2.2 },
954
+ "glm-4.5-air": { input: 0.2, output: 1.1 },
955
+ "glm-4.5-airx": { input: 1.1, output: 4.5 },
956
+ "glm-4.5-x": { input: 2.2, output: 8.9 },
957
+ "glm-4.5v": { input: 0.6, output: 1.8 },
958
+ "glm-4.6": { input: 0.6, output: 2.2, cacheRead: 0.11 },
959
+ "glm-4.7": { input: 0.6, output: 2.2, cacheRead: 0.11 },
960
+ "glm-5": { input: 1, output: 3.2, cacheRead: 0.2 },
961
+ "glm-5-code": { input: 1.2, output: 5, cacheRead: 0.3 },
928
962
  "gpt-3.5-turbo": { input: 0.5, output: 1.5 },
929
963
  "gpt-3.5-turbo-0125": { input: 0.5, output: 1.5 },
930
964
  "gpt-3.5-turbo-1106": { input: 1, output: 2 },
@@ -1039,6 +1073,18 @@ var MODEL_PRICES = {
1039
1073
  "grok-code-fast-1": { input: 0.2, output: 1.5, cacheRead: 0.02 },
1040
1074
  "grok-code-fast-1-0825": { input: 0.2, output: 1.5, cacheRead: 0.02 },
1041
1075
  "grok-vision-beta": { input: 5, output: 15 },
1076
+ "kimi-k2-0711-preview": { input: 0.6, output: 2.5, cacheRead: 0.15 },
1077
+ "kimi-k2-0905-preview": { input: 0.6, output: 2.5, cacheRead: 0.15 },
1078
+ "kimi-k2-thinking": { input: 0.6, output: 2.5, cacheRead: 0.15 },
1079
+ "kimi-k2-thinking-turbo": { input: 1.15, output: 8, cacheRead: 0.15 },
1080
+ "kimi-k2-turbo-preview": { input: 1.15, output: 8, cacheRead: 0.15 },
1081
+ "kimi-k2.5": { input: 0.6, output: 3, cacheRead: 0.1 },
1082
+ "kimi-k2.6": { input: 0.95, output: 4, cacheRead: 0.16 },
1083
+ "kimi-latest": { input: 2, output: 5, cacheRead: 0.15 },
1084
+ "kimi-latest-128k": { input: 2, output: 5, cacheRead: 0.15 },
1085
+ "kimi-latest-32k": { input: 1, output: 3, cacheRead: 0.15 },
1086
+ "kimi-latest-8k": { input: 0.2, output: 2, cacheRead: 0.15 },
1087
+ "kimi-thinking-preview": { input: 0.6, output: 2.5, cacheRead: 0.15 },
1042
1088
  "labs-devstral-small-2512": { input: 0.1, output: 0.3 },
1043
1089
  "magistral-medium-1-2-2509": { input: 2, output: 5 },
1044
1090
  "magistral-medium-2506": { input: 2, output: 5 },
@@ -1047,6 +1093,12 @@ var MODEL_PRICES = {
1047
1093
  "magistral-small-1-2-2509": { input: 0.5, output: 1.5 },
1048
1094
  "magistral-small-2506": { input: 0.5, output: 1.5 },
1049
1095
  "magistral-small-latest": { input: 0.5, output: 1.5 },
1096
+ "MiniMax-M2": { input: 0.3, output: 1.2, cacheRead: 0.03 },
1097
+ "MiniMax-M2.1": { input: 0.3, output: 1.2, cacheRead: 0.03 },
1098
+ "MiniMax-M2.1-lightning": { input: 0.3, output: 2.4, cacheRead: 0.03 },
1099
+ "MiniMax-M2.5": { input: 0.3, output: 1.2, cacheRead: 0.03 },
1100
+ "MiniMax-M2.5-lightning": { input: 0.3, output: 2.4, cacheRead: 0.03 },
1101
+ "MiniMax-M3": { input: 0.6, output: 2.4, cacheRead: 0.12 },
1050
1102
  "ministral-3-14b-2512": { input: 0.2, output: 0.2 },
1051
1103
  "ministral-3-3b-2512": { input: 0.1, output: 0.1 },
1052
1104
  "ministral-3-8b-2512": { input: 0.15, output: 0.15 },
@@ -1067,6 +1119,16 @@ var MODEL_PRICES = {
1067
1119
  "mistral-small-3-2-2506": { input: 0.06, output: 0.18 },
1068
1120
  "mistral-small-latest": { input: 0.06, output: 0.18 },
1069
1121
  "mistral-tiny": { input: 0.25, output: 0.25 },
1122
+ "moonshot-v1-128k": { input: 2, output: 5 },
1123
+ "moonshot-v1-128k-0430": { input: 2, output: 5 },
1124
+ "moonshot-v1-128k-vision-preview": { input: 2, output: 5 },
1125
+ "moonshot-v1-32k": { input: 1, output: 3 },
1126
+ "moonshot-v1-32k-0430": { input: 1, output: 3 },
1127
+ "moonshot-v1-32k-vision-preview": { input: 1, output: 3 },
1128
+ "moonshot-v1-8k": { input: 0.2, output: 2 },
1129
+ "moonshot-v1-8k-0430": { input: 0.2, output: 2 },
1130
+ "moonshot-v1-8k-vision-preview": { input: 0.2, output: 2 },
1131
+ "moonshot-v1-auto": { input: 2, output: 5 },
1070
1132
  "o1": { input: 15, output: 60, cacheRead: 7.5 },
1071
1133
  "o1-2024-12-17": { input: 15, output: 60, cacheRead: 7.5 },
1072
1134
  "o3": { input: 2, output: 8, cacheRead: 0.5 },
@@ -1083,7 +1145,24 @@ var MODEL_PRICES = {
1083
1145
  "open-mixtral-8x7b": { input: 0.7, output: 0.7 },
1084
1146
  "pixtral-12b-2409": { input: 0.15, output: 0.15 },
1085
1147
  "pixtral-large-2411": { input: 2, output: 6 },
1086
- "pixtral-large-latest": { input: 2, output: 6 }
1148
+ "pixtral-large-latest": { input: 2, output: 6 },
1149
+ "qwen-coder": { input: 0.3, output: 1.5 },
1150
+ "qwen-max": { input: 1.6, output: 6.4 },
1151
+ "qwen-plus": { input: 0.4, output: 1.2 },
1152
+ "qwen-plus-2025-01-25": { input: 0.4, output: 1.2 },
1153
+ "qwen-plus-2025-04-28": { input: 0.4, output: 1.2 },
1154
+ "qwen-plus-2025-07-14": { input: 0.4, output: 1.2 },
1155
+ "qwen-turbo": { input: 0.05, output: 0.2 },
1156
+ "qwen-turbo-2024-11-01": { input: 0.05, output: 0.2 },
1157
+ "qwen-turbo-2025-04-28": { input: 0.05, output: 0.2 },
1158
+ "qwen-turbo-latest": { input: 0.05, output: 0.2 },
1159
+ "qwen3-next-80b-a3b-instruct": { input: 0.15, output: 1.2 },
1160
+ "qwen3-next-80b-a3b-thinking": { input: 0.15, output: 1.2 },
1161
+ "qwen3-vl-235b-a22b-instruct": { input: 0.4, output: 1.6 },
1162
+ "qwen3-vl-235b-a22b-thinking": { input: 0.4, output: 4 },
1163
+ "qwen3-vl-32b-instruct": { input: 0.16, output: 0.64 },
1164
+ "qwen3-vl-32b-thinking": { input: 0.16, output: 2.87 },
1165
+ "qwq-plus": { input: 0.8, output: 2.4 }
1087
1166
  };
1088
1167
 
1089
1168
  // src/media-official.ts
@@ -2206,6 +2285,7 @@ function createLCR(config) {
2206
2285
  };
2207
2286
  }
2208
2287
  export {
2288
+ DEFAULT_PROVIDERS,
2209
2289
  DEFAULT_REFERENCE,
2210
2290
  MEDIA_PRICING,
2211
2291
  MODEL_PRICES,
@@ -2215,6 +2295,7 @@ export {
2215
2295
  classifyError,
2216
2296
  classifyErrorKind,
2217
2297
  comparePrices,
2298
+ createEnvSink,
2218
2299
  createFalMediaAdapter,
2219
2300
  createHttpSink,
2220
2301
  createKunavoMediaAdapter,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-lcr",
3
- "version": "0.6.3",
3
+ "version": "0.6.5",
4
4
  "description": "Least Cost Routing for LLMs — route every model call to the cheapest available provider, fall back automatically, and track real cost. Built for the Vercel AI SDK.",
5
5
  "keywords": [
6
6
  "ai",