@syncended/dsh-usage 0.1.0 → 0.2.1

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/README.md CHANGED
@@ -46,9 +46,13 @@ dsh plugin --profile web remove @syncended/dsh-usage
46
46
 
47
47
  ## Pricing
48
48
 
49
- Cost is an estimate derived from provider-reported token buckets and USD-per-million-token rules. The plugin ships starter public-list-price rules for common OpenAI GPT-5, Anthropic Claude 4, and DeepSeek routes. Pricing changes over time and negotiated or subscription plans may not map to token billing, so override the rules for your environment.
49
+ Cost is an estimate derived from provider-reported token buckets and USD-per-million-token rules. The built-in catalog was verified on **2026-08-26 UTC** and contains 120 price/tier entries compiled into 259 exact provider-route rules for OpenAI GPT, Anthropic Claude, Google Gemini, DeepSeek, Z.AI GLM, Moonshot/Kimi, xAI Grok, Mistral, Cohere, Alibaba Qwen, and MiniMax.
50
50
 
51
- Rules are matched in order against `provider/model`. `*` is the only wildcard. A route without a matching rule remains visible as **UNPRICED** and is excluded from estimated spend; the dashboard reports pricing coverage.
51
+ See the [complete generated catalog](docs/pricing-catalog.md) for every model, price, condition, caveat, and official source URL. The engine handles prompt-length tiers and DeepSeek's recurring UTC peak/off-peak windows. It deliberately does not guess broad future model families: a route without a matching rule remains visible as **UNPRICED** and is excluded from estimated spend, while the dashboard reports pricing coverage.
52
+
53
+ Rules are matched in order against `provider/model`; `*` is the only route wildcard. Prompt tiers use `minPromptTokens` / `maxPromptTokens`, while known promotions and retirements use inclusive `validFrom` / exclusive `validTo` ISO-8601 instants. Calls outside a known validity interval remain unpriced rather than silently inheriting an expired rate.
54
+
55
+ Pricing changes over time, and batch/flex/priority service tiers, regional uplifts, negotiated rates, subscription plans, tool fees, and cache-storage duration may not map to token billing, so override the catalog for your environment when necessary. Current rules without an explicit validity interval remain current-list-price estimates rather than a historical invoice reconstruction.
52
56
 
53
57
  Override the bundle row in `$DSH_HOME/profiles/web/cordis.patch.yml`:
54
58
 
@@ -57,11 +61,18 @@ Override the bundle row in `$DSH_HOME/profiles/web/cordis.patch.yml`:
57
61
  config:
58
62
  scanConcurrency: 4
59
63
  pricing:
60
- - route: openai-codex/gpt-5*
61
- input: 1.25
62
- output: 10
63
- cacheRead: 0.125
64
- cacheWrite: 1.25
64
+ - route: openai-codex/gpt-5.6-sol
65
+ minPromptTokens: 272000
66
+ input: 8
67
+ output: 30
68
+ cacheRead: 0.8
69
+ cacheWrite: 10
70
+ - route: openai-codex/gpt-5.6-sol
71
+ maxPromptTokens: 271999
72
+ input: 4
73
+ output: 20
74
+ cacheRead: 0.4
75
+ cacheWrite: 5
65
76
  - route: my-provider/private-model
66
77
  input: 0.8
67
78
  output: 3.2
@@ -1,12 +1,8 @@
1
1
  import type { SessionEvent, SessionHeader } from '@deepseek-ai/dsh-session';
2
2
  import type { ModelPrice, SessionUsage, UsageRange, UsageSnapshot } from './types.js';
3
- /**
4
- * Built-in public-list-price estimates (USD / 1M tokens).
5
- * Route rules are deliberately overridable through plugin config.
6
- */
7
- export declare const DEFAULT_PRICING: ModelPrice[];
3
+ export { DEFAULT_PRICING } from './pricing-catalog.js';
8
4
  /** Fold one durable session into billable provider usage samples. */
9
5
  export declare function extractSessionUsage(meta: SessionHeader, events: readonly SessionEvent[]): SessionUsage;
10
6
  export declare function dateKey(timestamp: number, timeZone: string): string;
11
- export declare function priceFor(route: string, pricing: readonly ModelPrice[]): ModelPrice | undefined;
7
+ export declare function priceFor(route: string, pricing: readonly ModelPrice[], promptTokens?: number, timestamp?: number): ModelPrice | undefined;
12
8
  export declare function aggregateUsage(sessions: readonly SessionUsage[], pricing: readonly ModelPrice[], range: UsageRange, timeZone: string, now?: number, errors?: number): UsageSnapshot;
package/dist/aggregate.js CHANGED
@@ -1,15 +1,5 @@
1
- /**
2
- * Built-in public-list-price estimates (USD / 1M tokens).
3
- * Route rules are deliberately overridable through plugin config.
4
- */
5
- export const DEFAULT_PRICING = [
6
- { route: 'openai-codex/gpt-5', input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 1.25 },
7
- { route: 'openai/gpt-5', input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 1.25 },
8
- { route: 'anthropic/claude-sonnet-4-20250514', input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
9
- { route: 'anthropic/claude-opus-4-20250514', input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
10
- { route: 'deepseek/deepseek-chat', input: 0.28, output: 0.42, cacheRead: 0.028, cacheWrite: 0.28 },
11
- { route: 'deepseek/deepseek-reasoner', input: 0.55, output: 2.19, cacheRead: 0.14, cacheWrite: 0.55 },
12
- ];
1
+ import { DEFAULT_PRICING } from './pricing-catalog.js';
2
+ export { DEFAULT_PRICING } from './pricing-catalog.js';
13
3
  const DAY_MS = 86_400_000;
14
4
  const dateFormatterCache = new Map();
15
5
  function finiteToken(value) {
@@ -43,6 +33,8 @@ function assistantRoute(event) {
43
33
  export function extractSessionUsage(meta, events) {
44
34
  let currentRoute = null;
45
35
  const samples = new Map();
36
+ const stepStarts = new Map();
37
+ const compactionStarts = new Map();
46
38
  const seedLength = meta.seedLength ?? 0;
47
39
  for (let index = 0; index < events.length; index += 1) {
48
40
  const event = events[index];
@@ -58,11 +50,19 @@ export function extractSessionUsage(meta, events) {
58
50
  }
59
51
  if (index < seedLength)
60
52
  continue;
53
+ if (event.type === 'step/start') {
54
+ stepStarts.set(`${event.data.turn}:${event.data.step}`, event.time);
55
+ continue;
56
+ }
57
+ if (event.type === 'compaction/start') {
58
+ compactionStarts.set(String(event.data.compactionId), event.time);
59
+ continue;
60
+ }
61
61
  if (event.type === 'compaction/summary' && event.data.usage !== undefined) {
62
62
  const amount = buckets(event.data.usage);
63
63
  samples.set(`compaction:${event.seq}`, {
64
64
  sessionId: String(meta.id),
65
- timestamp: event.time,
65
+ timestamp: compactionStarts.get(String(event.data.compactionId)) ?? event.time,
66
66
  provider: event.data.provider,
67
67
  model: event.data.model,
68
68
  ...amount,
@@ -87,9 +87,10 @@ export function extractSessionUsage(meta, events) {
87
87
  continue;
88
88
  const amount = buckets(usage);
89
89
  const route = assistantRoute(event) ?? currentRoute ?? { provider: 'unknown', model: 'unknown' };
90
- samples.set(`${turn}:${step}`, {
90
+ const sampleKey = `${turn}:${step}`;
91
+ samples.set(sampleKey, {
91
92
  sessionId: String(meta.id),
92
- timestamp: event.time,
93
+ timestamp: stepStarts.get(sampleKey) ?? event.time,
93
94
  provider: route.provider,
94
95
  model: route.model,
95
96
  ...amount,
@@ -130,12 +131,51 @@ function datesBetween(start, end) {
130
131
  const days = Math.max(0, Math.round((Date.parse(`${end}T00:00:00Z`) - Date.parse(`${start}T00:00:00Z`)) / DAY_MS));
131
132
  return Array.from({ length: days + 1 }, (_, index) => shiftDate(start, index));
132
133
  }
134
+ const wildcardRegexCache = new Map();
135
+ const pricingBoundaryCache = new Map();
133
136
  function wildcardMatches(pattern, value) {
134
- const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*');
135
- return new RegExp(`^${escaped}$`, 'i').test(value);
137
+ let regex = wildcardRegexCache.get(pattern);
138
+ if (regex === undefined) {
139
+ const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*');
140
+ regex = new RegExp(`^${escaped}$`, 'i');
141
+ wildcardRegexCache.set(pattern, regex);
142
+ }
143
+ return regex.test(value);
136
144
  }
137
- export function priceFor(route, pricing) {
138
- return pricing.find((price) => wildcardMatches(price.route, route));
145
+ function validityMatches(price, timestamp) {
146
+ if (price.validFrom === undefined && price.validTo === undefined)
147
+ return true;
148
+ const instant = timestamp ?? Date.now();
149
+ if (!Number.isFinite(instant))
150
+ return false;
151
+ const boundary = (value) => {
152
+ let parsed = pricingBoundaryCache.get(value);
153
+ if (parsed === undefined) {
154
+ parsed = Date.parse(value);
155
+ pricingBoundaryCache.set(value, parsed);
156
+ }
157
+ return parsed;
158
+ };
159
+ return (price.validFrom === undefined || instant >= boundary(price.validFrom)) &&
160
+ (price.validTo === undefined || instant < boundary(price.validTo));
161
+ }
162
+ function scheduleMatches(price, timestamp) {
163
+ if (price.utcWindows === undefined || price.utcWindows.length === 0)
164
+ return true;
165
+ if (timestamp === undefined || !Number.isFinite(timestamp))
166
+ return false;
167
+ const date = new Date(timestamp);
168
+ const day = date.getUTCDay();
169
+ const hour = date.getUTCHours();
170
+ const inside = price.utcWindows.some((window) => window.days.includes(day) && hour >= window.startHour && hour < window.endHour);
171
+ return price.outsideUtcWindows === true ? !inside : inside;
172
+ }
173
+ export function priceFor(route, pricing, promptTokens = 0, timestamp) {
174
+ return pricing.find((price) => wildcardMatches(price.route, route) &&
175
+ (price.minPromptTokens === undefined || promptTokens >= price.minPromptTokens) &&
176
+ (price.maxPromptTokens === undefined || promptTokens <= price.maxPromptTokens) &&
177
+ validityMatches(price, timestamp) &&
178
+ scheduleMatches(price, timestamp));
139
179
  }
140
180
  function tokensOf(value) {
141
181
  return value.input + value.output + value.cacheRead + value.cacheWrite;
@@ -191,18 +231,14 @@ export function aggregateUsage(sessions, pricing, range, timeZone, now = Date.no
191
231
  const dailySessions = new Map();
192
232
  const rangeSessionIds = new Set();
193
233
  const modelRows = new Map();
194
- const priceCache = new Map();
195
234
  for (const session of sessions) {
196
235
  for (const record of session.records) {
197
236
  const date = dateKey(record.timestamp, timeZone);
198
237
  if (date < allStart || date > endDate)
199
238
  continue;
200
239
  const route = `${record.provider}/${record.model}`;
201
- let price = priceCache.get(route);
202
- if (!priceCache.has(route)) {
203
- price = priceFor(route, pricing);
204
- priceCache.set(route, price);
205
- }
240
+ const promptTokens = record.input + record.cacheRead + record.cacheWrite;
241
+ const price = priceFor(route, pricing, promptTokens, record.timestamp);
206
242
  const totalTokens = tokensOf(record);
207
243
  const pricedTokens = price === undefined ? 0 : totalTokens;
208
244
  const cost = costOf(record, price);
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import { Context, Service } from '@deepseek-ai/cordis';
2
2
  import z from '@deepseek-ai/schemastery';
3
3
  import type { UsagePluginConfig, UsageRange, UsageSnapshot } from './types.js';
4
4
  export * from './aggregate.js';
5
+ export * from './pricing-catalog.js';
5
6
  export * from './types.js';
6
7
  export declare const name = "usage";
7
8
  export declare const Config: z<UsagePluginConfig>;
package/dist/index.js CHANGED
@@ -2,19 +2,42 @@ import { Context, Service } from '@deepseek-ai/cordis';
2
2
  import z from '@deepseek-ai/schemastery';
3
3
  import { aggregateUsage, DEFAULT_PRICING, extractSessionUsage } from './aggregate.js';
4
4
  import { createUsageHttpHandler } from './http.js';
5
+ import { validatePricing } from './pricing-catalog.js';
5
6
  export * from './aggregate.js';
7
+ export * from './pricing-catalog.js';
6
8
  export * from './types.js';
7
9
  export const name = 'usage';
8
10
  const API_PREFIX = '/api/usage';
11
+ const UtcWindowSchema = z.object({
12
+ days: z.array(z.number().min(0).max(6)).required(),
13
+ startHour: z.number().min(0).max(23).required(),
14
+ endHour: z.number().min(1).max(24).required(),
15
+ });
9
16
  const PriceSchema = z.object({
10
17
  route: z.string().required(),
11
18
  input: z.number().min(0).default(0),
12
19
  output: z.number().min(0).default(0),
13
20
  cacheRead: z.number().min(0).default(0),
14
21
  cacheWrite: z.number().min(0).default(0),
22
+ minPromptTokens: z.number().min(0),
23
+ maxPromptTokens: z.number().min(0),
24
+ // Schemastery arrays default to [], so wrap this optional field in a union
25
+ // to preserve undefined for ordinary flat/context-tiered prices.
26
+ utcWindows: z.union([z.array(UtcWindowSchema), z.const(undefined)]),
27
+ outsideUtcWindows: z.boolean(),
28
+ validFrom: z.string(),
29
+ validTo: z.string(),
15
30
  });
31
+ function clonePrice(price) {
32
+ return {
33
+ ...price,
34
+ ...(price.utcWindows === undefined ? {} : {
35
+ utcWindows: price.utcWindows.map((window) => ({ ...window, days: [...window.days] })),
36
+ }),
37
+ };
38
+ }
16
39
  export const Config = z.object({
17
- pricing: z.array(PriceSchema).default(DEFAULT_PRICING.map((price) => ({ ...price }))),
40
+ pricing: z.array(PriceSchema).default(DEFAULT_PRICING.map(clonePrice)),
18
41
  scanConcurrency: z.number().min(1).max(16).default(4),
19
42
  });
20
43
  /** Read-only analytics over the canonical durable Harness session log. */
@@ -27,7 +50,9 @@ export class UsageService extends Service {
27
50
  refreshPromise;
28
51
  constructor(ctx, config) {
29
52
  super(ctx, 'usage');
30
- this.pricing = (config.pricing ?? DEFAULT_PRICING).map((price) => ({ ...price }));
53
+ const pricing = (config.pricing ?? DEFAULT_PRICING).map(clonePrice);
54
+ validatePricing(pricing);
55
+ this.pricing = pricing;
31
56
  this.scanConcurrency = config.scanConcurrency ?? 4;
32
57
  }
33
58
  async *[Service.init]() {
@@ -0,0 +1,35 @@
1
+ import type { ModelPrice, UtcPricingWindow } from './types.js';
2
+ export declare const PRICING_CATALOG_VERIFIED_AT = "2026-08-26";
3
+ export declare const PRICING_SOURCES: Readonly<{
4
+ openai: "https://developers.openai.com/api/docs/pricing";
5
+ anthropic: "https://platform.claude.com/docs/en/about-claude/pricing";
6
+ gemini: "https://ai.google.dev/gemini-api/docs/pricing";
7
+ deepseek: "https://api-docs.deepseek.com/quick_start/pricing/";
8
+ zai: "https://docs.z.ai/guides/overview/pricing";
9
+ kimi: "https://platform.kimi.ai/docs/pricing";
10
+ xai: "https://docs.x.ai/developers/pricing";
11
+ mistral: "https://mistral.ai/pricing/api/";
12
+ cohere: "https://cohere.com/pricing";
13
+ qwen: "https://www.alibabacloud.com/help/en/model-studio/model-pricing";
14
+ minimax: "https://platform.minimax.io/docs/guides/pricing-paygo";
15
+ }>;
16
+ export interface PricingCatalogEntry {
17
+ family: string;
18
+ providers: string[];
19
+ models: string[];
20
+ input: number;
21
+ output: number;
22
+ cacheRead: number;
23
+ cacheWrite: number;
24
+ source: keyof typeof PRICING_SOURCES;
25
+ note?: string;
26
+ minPromptTokens?: number;
27
+ maxPromptTokens?: number;
28
+ utcWindows?: UtcPricingWindow[];
29
+ outsideUtcWindows?: boolean;
30
+ validFrom?: string;
31
+ validTo?: string;
32
+ }
33
+ export declare const PRICING_CATALOG: readonly PricingCatalogEntry[];
34
+ export declare function validatePricing(pricing: readonly ModelPrice[]): void;
35
+ export declare const DEFAULT_PRICING: ModelPrice[];
@@ -0,0 +1,277 @@
1
+ export const PRICING_CATALOG_VERIFIED_AT = '2026-08-26';
2
+ export const PRICING_SOURCES = Object.freeze({
3
+ openai: 'https://developers.openai.com/api/docs/pricing',
4
+ anthropic: 'https://platform.claude.com/docs/en/about-claude/pricing',
5
+ gemini: 'https://ai.google.dev/gemini-api/docs/pricing',
6
+ deepseek: 'https://api-docs.deepseek.com/quick_start/pricing/',
7
+ zai: 'https://docs.z.ai/guides/overview/pricing',
8
+ kimi: 'https://platform.kimi.ai/docs/pricing',
9
+ xai: 'https://docs.x.ai/developers/pricing',
10
+ mistral: 'https://mistral.ai/pricing/api/',
11
+ cohere: 'https://cohere.com/pricing',
12
+ qwen: 'https://www.alibabacloud.com/help/en/model-studio/model-pricing',
13
+ minimax: 'https://platform.minimax.io/docs/guides/pricing-paygo',
14
+ });
15
+ const WEEKDAY_DEEPSEEK_PEAK = [
16
+ { days: [1, 2, 3, 4, 5], startHour: 1, endHour: 4 },
17
+ { days: [1, 2, 3, 4, 5], startHour: 6, endHour: 10 },
18
+ ];
19
+ const entries = [];
20
+ function add(entry) {
21
+ entries.push(entry);
22
+ }
23
+ function addFlat(source, family, providers, models, input, cacheRead, output, options = {}) {
24
+ add({
25
+ source,
26
+ family,
27
+ providers,
28
+ models,
29
+ input,
30
+ cacheRead,
31
+ cacheWrite: options.cacheWrite ?? input,
32
+ output,
33
+ ...(options.note === undefined ? {} : { note: options.note }),
34
+ ...(options.validFrom === undefined ? {} : { validFrom: options.validFrom }),
35
+ ...(options.validTo === undefined ? {} : { validTo: options.validTo }),
36
+ });
37
+ }
38
+ function addContextTiered(source, family, providers, models, threshold, short, long, note, validity = {}) {
39
+ add({
40
+ source,
41
+ family: `${family} · long context`,
42
+ providers,
43
+ models,
44
+ input: long.input,
45
+ cacheRead: long.cacheRead,
46
+ cacheWrite: long.cacheWrite ?? long.input,
47
+ output: long.output,
48
+ minPromptTokens: threshold,
49
+ ...(note === undefined ? {} : { note }),
50
+ ...(validity.validFrom === undefined ? {} : { validFrom: validity.validFrom }),
51
+ ...(validity.validTo === undefined ? {} : { validTo: validity.validTo }),
52
+ });
53
+ add({
54
+ source,
55
+ family,
56
+ providers,
57
+ models,
58
+ input: short.input,
59
+ cacheRead: short.cacheRead,
60
+ cacheWrite: short.cacheWrite ?? short.input,
61
+ output: short.output,
62
+ maxPromptTokens: threshold - 1,
63
+ ...(note === undefined ? {} : { note }),
64
+ ...(validity.validFrom === undefined ? {} : { validFrom: validity.validFrom }),
65
+ ...(validity.validTo === undefined ? {} : { validTo: validity.validTo }),
66
+ });
67
+ }
68
+ const OPENAI = ['openai', 'openai-codex'];
69
+ addContextTiered('openai', 'GPT-5.6 Sol', OPENAI, ['gpt-5.6-sol'], 272_000, { input: 4, cacheRead: 0.4, cacheWrite: 5, output: 20 }, { input: 8, cacheRead: 0.8, cacheWrite: 10, output: 30 }, 'Standard synchronous tier; promotional through at least 2026-11-21.', { validFrom: '2026-08-26T00:00:00.000Z', validTo: '2026-11-22T00:00:00.000Z' });
70
+ addContextTiered('openai', 'GPT-5.6 Terra', OPENAI, ['gpt-5.6-terra'], 272_000, { input: 2, cacheRead: 0.2, cacheWrite: 2.5, output: 12 }, { input: 4, cacheRead: 0.4, cacheWrite: 5, output: 18 });
71
+ addContextTiered('openai', 'GPT-5.6 Luna', OPENAI, ['gpt-5.6-luna'], 272_000, { input: 0.2, cacheRead: 0.02, cacheWrite: 0.25, output: 1.2 }, { input: 0.4, cacheRead: 0.04, cacheWrite: 0.5, output: 1.8 });
72
+ addContextTiered('openai', 'GPT-5.5', OPENAI, ['gpt-5.5'], 272_000, { input: 5, cacheRead: 0.5, output: 30 }, { input: 10, cacheRead: 1, output: 45 });
73
+ addContextTiered('openai', 'GPT-5.5 Pro', OPENAI, ['gpt-5.5-pro'], 272_000, { input: 30, cacheRead: 30, output: 180 }, { input: 60, cacheRead: 60, output: 270 }, 'No discounted cached-input SKU is published; cached buckets use input price.');
74
+ addContextTiered('openai', 'GPT-5.4', OPENAI, ['gpt-5.4'], 272_000, { input: 2.5, cacheRead: 0.25, output: 15 }, { input: 5, cacheRead: 0.5, output: 22.5 });
75
+ addContextTiered('openai', 'GPT-5.4 Pro', OPENAI, ['gpt-5.4-pro'], 272_000, { input: 30, cacheRead: 30, output: 180 }, { input: 60, cacheRead: 60, output: 270 }, 'No discounted cached-input SKU is published; cached buckets use input price.');
76
+ addFlat('openai', 'GPT-5.4 Mini', OPENAI, ['gpt-5.4-mini'], 0.75, 0.075, 4.5);
77
+ addFlat('openai', 'GPT-5.4 Nano', OPENAI, ['gpt-5.4-nano'], 0.2, 0.02, 1.25);
78
+ addFlat('openai', 'GPT-4.1', OPENAI, ['gpt-4.1', 'gpt-4.1-20*'], 2, 0.5, 8);
79
+ addFlat('openai', 'GPT-4.1 Mini', OPENAI, ['gpt-4.1-mini', 'gpt-4.1-mini-20*'], 0.4, 0.1, 1.6);
80
+ addFlat('openai', 'GPT-4.1 Nano', OPENAI, ['gpt-4.1-nano', 'gpt-4.1-nano-20*'], 0.1, 0.025, 0.4);
81
+ addFlat('openai', 'GPT-5.3 Codex', OPENAI, ['gpt-5.3-codex'], 1.75, 0.175, 14, { note: 'Standard Codex tier.' });
82
+ addFlat('openai', 'GPT-5', OPENAI, ['gpt-5'], 1.25, 0.125, 10, { note: 'Prior-generation exact ID retained for existing sessions.' });
83
+ addFlat('openai', 'GPT-5 Mini', OPENAI, ['gpt-5-mini'], 0.25, 0.025, 2, { note: 'Prior-generation exact ID retained for existing sessions.' });
84
+ addFlat('openai', 'GPT-5 Nano', OPENAI, ['gpt-5-nano'], 0.05, 0.005, 0.4, { note: 'Prior-generation exact ID retained for existing sessions.' });
85
+ addFlat('openai', 'GPT-4o', OPENAI, ['gpt-4o', 'gpt-4o-20*'], 2.5, 1.25, 10);
86
+ addFlat('openai', 'GPT-4o Mini', OPENAI, ['gpt-4o-mini', 'gpt-4o-mini-20*'], 0.15, 0.075, 0.6);
87
+ const ANTHROPIC = ['anthropic'];
88
+ addFlat('anthropic', 'Claude Fable 5', ANTHROPIC, ['claude-fable-5*'], 10, 1, 50, { cacheWrite: 12.5, note: 'Cache-write estimate uses the standard 5-minute cache rate.' });
89
+ addFlat('anthropic', 'Claude Mythos 5', ANTHROPIC, ['claude-mythos-5*'], 10, 1, 50, { cacheWrite: 12.5, note: 'Limited availability; cache-write estimate uses the 5-minute rate.' });
90
+ for (const [family, model] of [
91
+ ['Claude Opus 5', 'claude-opus-5*'],
92
+ ['Claude Opus 4.8', 'claude-opus-4-8*'],
93
+ ['Claude Opus 4.7', 'claude-opus-4-7*'],
94
+ ['Claude Opus 4.6', 'claude-opus-4-6*'],
95
+ ['Claude Opus 4.5', 'claude-opus-4-5*'],
96
+ ])
97
+ addFlat('anthropic', family, ANTHROPIC, [model], 5, 0.5, 25, { cacheWrite: 6.25, note: 'Global standard inference; cache-write estimate uses the 5-minute rate.' });
98
+ for (const [family, model] of [
99
+ ['Claude Opus 4.1', 'claude-opus-4-1*'],
100
+ ['Claude Opus 4', 'claude-opus-4-2025*'],
101
+ ])
102
+ addFlat('anthropic', family, ANTHROPIC, [model], 15, 1.5, 75, { cacheWrite: 18.75, note: 'Retired on the first-party API; retained for historical logs.' });
103
+ addFlat('anthropic', 'Claude Sonnet 5', ANTHROPIC, ['claude-sonnet-5*'], 2, 0.2, 10, { cacheWrite: 2.5, note: 'Cache-write estimate uses the 5-minute rate.' });
104
+ for (const [family, model] of [
105
+ ['Claude Sonnet 4.6', 'claude-sonnet-4-6*'],
106
+ ['Claude Sonnet 4.5', 'claude-sonnet-4-5*'],
107
+ ['Claude Sonnet 4', 'claude-sonnet-4-2025*'],
108
+ ])
109
+ addFlat('anthropic', family, ANTHROPIC, [model], 3, 0.3, 15, { cacheWrite: 3.75, note: 'Cache-write estimate uses the 5-minute rate.' });
110
+ addFlat('anthropic', 'Claude Haiku 4.5', ANTHROPIC, ['claude-haiku-4-5*'], 1, 0.1, 5, { cacheWrite: 1.25, note: 'Cache-write estimate uses the 5-minute rate.' });
111
+ addFlat('anthropic', 'Claude Haiku 3.5', ANTHROPIC, ['claude-3-5-haiku*', 'claude-haiku-3-5*'], 0.8, 0.08, 4, { cacheWrite: 1, note: 'Retired on the first-party API; retained for historical logs.' });
112
+ const GEMINI = ['google', 'gemini', 'google-ai'];
113
+ addFlat('gemini', 'Gemini 3.7 Flash', GEMINI, ['gemini-3.7-flash'], 0.75, 0.075, 3.75, { note: 'Promotional through 2026-12-31; cache storage token-hours are excluded.', validFrom: '2026-08-26T00:00:00.000Z', validTo: '2027-01-01T00:00:00.000Z' });
114
+ addFlat('gemini', 'Gemini 3.7 Flash · 2027 rate', GEMINI, ['gemini-3.7-flash'], 1.5, 0.15, 7.5, { note: 'Official rate beginning 2027-01-01; cache storage token-hours are excluded.', validFrom: '2027-01-01T00:00:00.000Z' });
115
+ addFlat('gemini', 'Gemini 3.6 Flash', GEMINI, ['gemini-3.6-flash'], 0.75, 0.075, 3.75, { note: 'Promotional through 2026-12-31; cache storage token-hours are excluded.', validFrom: '2026-08-26T00:00:00.000Z', validTo: '2027-01-01T00:00:00.000Z' });
116
+ addFlat('gemini', 'Gemini 3.6 Flash · 2027 rate', GEMINI, ['gemini-3.6-flash'], 1.5, 0.15, 7.5, { note: 'Official rate beginning 2027-01-01; cache storage token-hours are excluded.', validFrom: '2027-01-01T00:00:00.000Z' });
117
+ addFlat('gemini', 'Gemini 3.5 Flash', GEMINI, ['gemini-3.5-flash'], 1.5, 0.15, 9, { note: 'Cache storage token-hours are excluded.' });
118
+ addFlat('gemini', 'Gemini 3.5 Flash-Lite', GEMINI, ['gemini-3.5-flash-lite'], 0.3, 0.03, 2.5, { note: 'Cache storage token-hours are excluded.' });
119
+ addContextTiered('gemini', 'Gemini 3.1 Pro Preview', GEMINI, ['gemini-3.1-pro-preview', 'gemini-3.1-pro-preview-customtools'], 200_001, { input: 2, cacheRead: 0.2, output: 12 }, { input: 4, cacheRead: 0.4, output: 18 }, 'Cache storage token-hours are excluded.');
120
+ addFlat('gemini', 'Gemini 3.1 Flash-Lite', GEMINI, ['gemini-3.1-flash-lite'], 0.25, 0.025, 1.5, { note: 'Text/image/video rate; audio and cache storage are excluded.' });
121
+ addContextTiered('gemini', 'Gemini 2.5 Pro', GEMINI, ['gemini-2.5-pro'], 200_001, { input: 1.25, cacheRead: 0.125, output: 10 }, { input: 2.5, cacheRead: 0.25, output: 15 }, 'Cache storage token-hours are excluded.');
122
+ addFlat('gemini', 'Gemini 2.5 Flash', GEMINI, ['gemini-2.5-flash'], 0.3, 0.03, 2.5, { note: 'Text/image/video rate; audio and cache storage are excluded.' });
123
+ addFlat('gemini', 'Gemini 2.5 Flash-Lite', GEMINI, ['gemini-2.5-flash-lite'], 0.1, 0.01, 0.4, { note: 'Text/image/video rate; audio and cache storage are excluded.' });
124
+ const DEEPSEEK = ['deepseek', 'deepseek-api'];
125
+ function addDeepSeek(family, model, offPeak, peak) {
126
+ add({ source: 'deepseek', family: `${family} · peak`, providers: DEEPSEEK, models: [model], input: peak[0], cacheRead: peak[1], cacheWrite: peak[0], output: peak[2], utcWindows: WEEKDAY_DEEPSEEK_PEAK });
127
+ add({ source: 'deepseek', family: `${family} · off-peak`, providers: DEEPSEEK, models: [model], input: offPeak[0], cacheRead: offPeak[1], cacheWrite: offPeak[0], output: offPeak[2], utcWindows: WEEKDAY_DEEPSEEK_PEAK, outsideUtcWindows: true });
128
+ }
129
+ addDeepSeek('DeepSeek V4 Flash', 'deepseek-v4-flash', [0.22, 0.007, 0.66], [0.44, 0.014, 1.32]);
130
+ addDeepSeek('DeepSeek V4 Pro', 'deepseek-v4-pro', [0.66, 0.022, 1.98], [1.32, 0.044, 3.96]);
131
+ addFlat('deepseek', 'DeepSeek Chat legacy', ['deepseek'], ['deepseek-chat'], 0.28, 0.028, 0.42, { note: 'Retired after 2026-07-24 15:59 UTC; retained for historical logs.', validTo: '2026-07-24T16:00:00.000Z' });
132
+ addFlat('deepseek', 'DeepSeek Reasoner legacy', ['deepseek'], ['deepseek-reasoner'], 0.55, 0.14, 2.19, { note: 'Retired after 2026-07-24 15:59 UTC; retained for historical logs.', validTo: '2026-07-24T16:00:00.000Z' });
133
+ const ZAI = ['zai', 'z-ai', 'zhipu', 'bigmodel'];
134
+ for (const [family, model, input, cacheRead, output] of [
135
+ ['GLM-5.3', 'glm-5.3', 1.4, 0.26, 4.4],
136
+ ['GLM-5.2', 'glm-5.2', 1.4, 0.26, 4.4],
137
+ ['GLM-5.1', 'glm-5.1', 1.4, 0.26, 4.4],
138
+ ['GLM-5', 'glm-5', 1, 0.2, 3.2],
139
+ ['GLM-5 Turbo', 'glm-5-turbo', 1.2, 0.24, 4],
140
+ ['GLM-4.7', 'glm-4.7', 0.6, 0.11, 2.2],
141
+ ['GLM-4.7 FlashX', 'glm-4.7-flashx', 0.07, 0.01, 0.4],
142
+ ['GLM-4.6', 'glm-4.6', 0.6, 0.11, 2.2],
143
+ ['GLM-4.5', 'glm-4.5', 0.6, 0.11, 2.2],
144
+ ['GLM-4.5 X', 'glm-4.5-x', 2.2, 0.45, 8.9],
145
+ ['GLM-4.5 Air', 'glm-4.5-air', 0.2, 0.03, 1.1],
146
+ ['GLM-4.5 AirX', 'glm-4.5-airx', 1.1, 0.22, 4.5],
147
+ ['GLM-4 32B', 'glm-4-32b-0414-128k', 0.1, 0.1, 0.1],
148
+ ['GLM-4.7 Flash', 'glm-4.7-flash', 0, 0, 0],
149
+ ['GLM-4.5 Flash', 'glm-4.5-flash', 0, 0, 0],
150
+ ])
151
+ addFlat('zai', family, ZAI, [model], input, cacheRead, output, { note: 'Global Z.AI endpoint; cached-input storage is currently free.' });
152
+ const KIMI = ['kimi', 'moonshot'];
153
+ for (const [family, model, input, cacheRead, output, note, validTo] of [
154
+ ['Kimi K3', 'kimi-k3', 3, 0.3, 15, 'Standard realtime tier.', undefined],
155
+ ['Kimi K2.7 Code', 'kimi-k2.7-code', 0.95, 0.19, 4, 'Standard realtime tier.', undefined],
156
+ ['Kimi K2.7 Code Highspeed', 'kimi-k2.7-code-highspeed', 1.9, 0.38, 8, 'High-speed serving tier.', undefined],
157
+ ['Kimi K2.6', 'kimi-k2.6', 0.95, 0.16, 4, 'Standard realtime tier.', undefined],
158
+ ['Kimi K2.5', 'kimi-k2.5', 0.6, 0.1, 3, 'Scheduled for retirement on 2026-08-31; retained for historical logs.', '2026-09-01T00:00:00.000Z'],
159
+ ['Moonshot V1 8K', 'moonshot-v1-8k', 0.2, 0.2, 2, 'Scheduled for retirement on 2026-08-31; no cache discount is published.', '2026-09-01T00:00:00.000Z'],
160
+ ['Moonshot V1 32K', 'moonshot-v1-32k', 1, 1, 3, 'Scheduled for retirement on 2026-08-31; no cache discount is published.', '2026-09-01T00:00:00.000Z'],
161
+ ['Moonshot V1 128K', 'moonshot-v1-128k', 2, 2, 5, 'Scheduled for retirement on 2026-08-31; no cache discount is published.', '2026-09-01T00:00:00.000Z'],
162
+ ])
163
+ addFlat('kimi', family, KIMI, [model], input, cacheRead, output, { note, ...(validTo === undefined ? {} : { validTo }) });
164
+ const XAI = ['xai'];
165
+ for (const [family, model, shortInput, shortCache, shortOutput, longInput, longCache, longOutput] of [
166
+ ['Grok 4.6', 'grok-4.6', 2, 0.5, 6, 4, 1, 12],
167
+ ['Grok Build 0.1', 'grok-build-0.1', 1, 0.2, 2, 2, 0.4, 4],
168
+ ['Grok 4.5', 'grok-4.5', 2, 0.3, 6, 4, 0.6, 12],
169
+ ['Grok 4.3', 'grok-4.3', 1.25, 0.2, 2.5, 2.5, 0.4, 5],
170
+ ['Grok 4.20 Reasoning', 'grok-4.20-0309-reasoning', 1.25, 0.2, 2.5, 2.5, 0.4, 5],
171
+ ['Grok 4.20 Non-Reasoning', 'grok-4.20-0309-non-reasoning', 1.25, 0.2, 2.5, 2.5, 0.4, 5],
172
+ ['Grok 4.20 Multi-Agent', 'grok-4.20-multi-agent-0309', 1.25, 0.2, 2.5, 2.5, 0.4, 5],
173
+ ])
174
+ addContextTiered('xai', family, XAI, [model], 200_000, { input: shortInput, cacheRead: shortCache, output: shortOutput }, { input: longInput, cacheRead: longCache, output: longOutput }, 'Standard text API; tool-call fees are excluded.');
175
+ const MISTRAL = ['mistral'];
176
+ for (const [family, models, input, output] of [
177
+ ['Mistral Medium 3.5', ['mistral-medium-3-5'], 1.5, 7.5],
178
+ ['Mistral Large 3', ['mistral-large-2512'], 0.5, 1.5],
179
+ ['Mistral Small 4', ['mistral-small-2603'], 0.15, 0.6],
180
+ ['Codestral', ['codestral-2508'], 0.3, 0.9],
181
+ ])
182
+ addFlat('mistral', family, MISTRAL, [...models], input, input, output, { note: 'Exact cache discount is not published per model; cached buckets conservatively use input price.' });
183
+ const COHERE = ['cohere'];
184
+ for (const [family, model, input, output, note] of [
185
+ ['Command A', 'command-a-03-2025', 2.5, 10, 'Current paid production model.'],
186
+ ['Command R7B', 'command-r7b-12-2024', 0.0375, 0.15, 'Pinned paid model.'],
187
+ ['Command R', 'command-r-08-2024', 0.15, 0.6, 'Pinned paid model.'],
188
+ ['Command R+', 'command-r-plus-08-2024', 2.5, 10, 'Pinned paid model.'],
189
+ ['Command legacy', 'command', 1, 2, 'Deprecated; retained for historical logs.'],
190
+ ['Command Light legacy', 'command-light', 0.3, 0.6, 'Deprecated; retained for historical logs.'],
191
+ ['Command R legacy', 'command-r-03-2024', 0.5, 1.5, 'Deprecated; retained for historical logs.'],
192
+ ['Command R+ legacy', 'command-r-plus-04-2024', 3, 15, 'Deprecated; retained for historical logs.'],
193
+ ])
194
+ addFlat('cohere', family, COHERE, [model], input, input, output, { note: `${note} No cache discount is published.` });
195
+ const QWEN = ['dashscope', 'alibaba', 'qwen'];
196
+ add({ source: 'qwen', family: 'Qwen 3.7 Max', providers: QWEN, models: ['qwen3.7-max-2026-06-08'], input: 2.5, cacheRead: 0.5, cacheWrite: 3.125, output: 7.5, maxPromptTokens: 1_000_000, note: 'Singapore international list price; cache read uses the implicit-cache rate.' });
197
+ addContextTiered('qwen', 'Qwen 3.7 Plus', QWEN, ['qwen3.7-plus-2026-05-26'], 256_001, { input: 0.4, cacheRead: 0.08, cacheWrite: 0.5, output: 1.6 }, { input: 1.2, cacheRead: 0.24, cacheWrite: 1.5, output: 4.8 }, 'Singapore international list price; cache read uses the implicit-cache rate.');
198
+ function addQwenTier(family, model, min, max, input, output) {
199
+ const cacheRead = Number((input * 0.2).toFixed(6));
200
+ const cacheWrite = Number((input * 1.25).toFixed(6));
201
+ add({ source: 'qwen', family, providers: QWEN, models: [model], input, cacheRead, cacheWrite, output, minPromptTokens: min, maxPromptTokens: max, note: 'Singapore international list price; cache read uses the implicit-cache rate.' });
202
+ }
203
+ addQwenTier('Qwen 3 Max · ≤32K', 'qwen3-max-2026-01-23', 0, 32_000, 1.2, 6);
204
+ addQwenTier('Qwen 3 Max · 32K–128K', 'qwen3-max-2026-01-23', 32_001, 128_000, 2.4, 12);
205
+ addQwenTier('Qwen 3 Max · 128K–256K', 'qwen3-max-2026-01-23', 128_001, 256_000, 3, 15);
206
+ addQwenTier('Qwen 3 Coder Plus · ≤32K', 'qwen3-coder-plus-2025-09-23', 0, 32_000, 1, 5);
207
+ addQwenTier('Qwen 3 Coder Plus · 32K–128K', 'qwen3-coder-plus-2025-09-23', 32_001, 128_000, 1.8, 9);
208
+ addQwenTier('Qwen 3 Coder Plus · 128K–256K', 'qwen3-coder-plus-2025-09-23', 128_001, 256_000, 3, 15);
209
+ addQwenTier('Qwen 3 Coder Plus · 256K–1M', 'qwen3-coder-plus-2025-09-23', 256_001, 1_000_000, 6, 60);
210
+ addQwenTier('Qwen 3 Coder Flash · ≤32K', 'qwen3-coder-flash-2025-07-28', 0, 32_000, 0.3, 1.5);
211
+ addQwenTier('Qwen 3 Coder Flash · 32K–128K', 'qwen3-coder-flash-2025-07-28', 32_001, 128_000, 0.5, 2.5);
212
+ addQwenTier('Qwen 3 Coder Flash · 128K–256K', 'qwen3-coder-flash-2025-07-28', 128_001, 256_000, 0.8, 4);
213
+ addQwenTier('Qwen 3 Coder Flash · 256K–1M', 'qwen3-coder-flash-2025-07-28', 256_001, 1_000_000, 1.6, 9.6);
214
+ const MINIMAX = ['minimax'];
215
+ addContextTiered('minimax', 'MiniMax M3', MINIMAX, ['MiniMax-M3'], 512_001, { input: 0.3, cacheRead: 0.06, output: 1.2 }, { input: 0.6, cacheRead: 0.12, output: 2.4 }, 'Standard tier; no separate cache-write price is published.');
216
+ for (const [family, model, input, cacheRead, cacheWrite, output] of [
217
+ ['MiniMax M2.7', 'MiniMax-M2.7', 0.3, 0.06, 0.375, 1.2],
218
+ ['MiniMax M2.7 Highspeed', 'MiniMax-M2.7-highspeed', 0.6, 0.06, 0.375, 2.4],
219
+ ['MiniMax M2.5', 'MiniMax-M2.5', 0.3, 0.03, 0.375, 1.2],
220
+ ['MiniMax M2.5 Highspeed', 'MiniMax-M2.5-highspeed', 0.6, 0.03, 0.375, 2.4],
221
+ ])
222
+ addFlat('minimax', family, MINIMAX, [model], input, cacheRead, output, { cacheWrite });
223
+ export const PRICING_CATALOG = Object.freeze(entries.map((entry) => Object.freeze({ ...entry })));
224
+ export function validatePricing(pricing) {
225
+ for (const [index, price] of pricing.entries()) {
226
+ const label = `pricing[${index}] (${price.route})`;
227
+ if (price.route === '')
228
+ throw new Error(`${label}: route must not be empty`);
229
+ for (const [bucket, value] of Object.entries({ input: price.input, output: price.output, cacheRead: price.cacheRead, cacheWrite: price.cacheWrite })) {
230
+ if (!Number.isFinite(value) || value < 0)
231
+ throw new Error(`${label}: ${bucket} must be a non-negative finite number`);
232
+ }
233
+ for (const [field, value] of [['minPromptTokens', price.minPromptTokens], ['maxPromptTokens', price.maxPromptTokens]]) {
234
+ if (value !== undefined && (!Number.isSafeInteger(value) || value < 0))
235
+ throw new Error(`${label}: ${field} must be a non-negative safe integer`);
236
+ }
237
+ if (price.minPromptTokens !== undefined && price.maxPromptTokens !== undefined && price.minPromptTokens > price.maxPromptTokens) {
238
+ throw new Error(`${label}: minPromptTokens must not exceed maxPromptTokens`);
239
+ }
240
+ if (price.utcWindows !== undefined && price.utcWindows.length === 0) {
241
+ throw new Error(`${label}: utcWindows requires at least one utcWindow`);
242
+ }
243
+ if (price.outsideUtcWindows === true && price.utcWindows === undefined) {
244
+ throw new Error(`${label}: outsideUtcWindows requires at least one utcWindow`);
245
+ }
246
+ for (const window of price.utcWindows ?? []) {
247
+ if (window.days.length === 0 || new Set(window.days).size !== window.days.length || window.days.some((day) => !Number.isInteger(day) || day < 0 || day > 6)) {
248
+ throw new Error(`${label}: utcWindow days must be unique integers from 0 through 6`);
249
+ }
250
+ if (!Number.isInteger(window.startHour) || !Number.isInteger(window.endHour) || window.startHour < 0 || window.endHour > 24 || window.startHour >= window.endHour) {
251
+ throw new Error(`${label}: utcWindow requires integer hours with 0 <= startHour < endHour <= 24`);
252
+ }
253
+ }
254
+ const validFrom = price.validFrom === undefined ? undefined : Date.parse(price.validFrom);
255
+ const validTo = price.validTo === undefined ? undefined : Date.parse(price.validTo);
256
+ if (validFrom !== undefined && !Number.isFinite(validFrom))
257
+ throw new Error(`${label}: validFrom must be ISO-8601`);
258
+ if (validTo !== undefined && !Number.isFinite(validTo))
259
+ throw new Error(`${label}: validTo must be ISO-8601`);
260
+ if (validFrom !== undefined && validTo !== undefined && validFrom >= validTo)
261
+ throw new Error(`${label}: validFrom must precede validTo`);
262
+ }
263
+ }
264
+ export const DEFAULT_PRICING = PRICING_CATALOG.flatMap((entry) => entry.providers.flatMap((provider) => entry.models.map((model) => ({
265
+ route: `${provider}/${model}`,
266
+ input: entry.input,
267
+ output: entry.output,
268
+ cacheRead: entry.cacheRead,
269
+ cacheWrite: entry.cacheWrite,
270
+ ...(entry.minPromptTokens === undefined ? {} : { minPromptTokens: entry.minPromptTokens }),
271
+ ...(entry.maxPromptTokens === undefined ? {} : { maxPromptTokens: entry.maxPromptTokens }),
272
+ ...(entry.utcWindows === undefined ? {} : { utcWindows: entry.utcWindows.map((window) => ({ ...window, days: [...window.days] })) }),
273
+ ...(entry.outsideUtcWindows === undefined ? {} : { outsideUtcWindows: entry.outsideUtcWindows }),
274
+ ...(entry.validFrom === undefined ? {} : { validFrom: entry.validFrom }),
275
+ ...(entry.validTo === undefined ? {} : { validTo: entry.validTo }),
276
+ }))));
277
+ validatePricing(DEFAULT_PRICING);
package/dist/types.d.ts CHANGED
@@ -1,4 +1,12 @@
1
1
  export type UsageRange = '30d' | '90d' | '365d' | 'all';
2
+ export interface UtcPricingWindow {
3
+ /** UTC weekday numbers, Sunday = 0. */
4
+ days: number[];
5
+ /** Inclusive UTC hour, 0–23. */
6
+ startHour: number;
7
+ /** Exclusive UTC hour, 1–24. */
8
+ endHour: number;
9
+ }
2
10
  export interface ModelPrice {
3
11
  /** Provider/model glob. Only `*` is special. */
4
12
  route: string;
@@ -10,6 +18,18 @@ export interface ModelPrice {
10
18
  cacheRead: number;
11
19
  /** USD per one million cache-write tokens. */
12
20
  cacheWrite: number;
21
+ /** Match calls whose total prompt buckets are at least this size. */
22
+ minPromptTokens?: number;
23
+ /** Match calls whose total prompt buckets are no larger than this size. */
24
+ maxPromptTokens?: number;
25
+ /** Optional recurring UTC billing windows. */
26
+ utcWindows?: UtcPricingWindow[];
27
+ /** Match outside utcWindows instead of inside them. */
28
+ outsideUtcWindows?: boolean;
29
+ /** Inclusive ISO-8601 instant when this price becomes valid. */
30
+ validFrom?: string;
31
+ /** Exclusive ISO-8601 instant when this price stops being valid. */
32
+ validTo?: string;
13
33
  }
14
34
  export interface UsagePluginConfig {
15
35
  pricing?: ModelPrice[];
@@ -0,0 +1,164 @@
1
+ # Built-in pricing catalog
2
+
3
+ Verified against official public pricing pages on **2026-08-26 UTC**. Prices are USD per one million tokens.
4
+
5
+ The catalog estimates standard, synchronous, first-party API usage. Batch/flex/priority modes, regional uplifts, negotiated discounts, subscriptions, tool-call fees, taxes, and cache-storage token-hours are excluded unless a row note explicitly says otherwise.
6
+
7
+ Catalog entries: **128**. Generated route rules include provider aliases and context/time tiers.
8
+
9
+ | Family / tier | Provider routes | Models | Input | Cache read | Cache write | Output | Match | Notes |
10
+ |---|---|---|---:|---:|---:|---:|---|---|
11
+ | GPT-5.6 Sol · long context | openai, openai-codex | gpt-5.6-sol | $8 | $0.8 | $10 | $30 | prompt ≥ 272,000; from 2026-08-26T00:00:00.000Z; before 2026-11-22T00:00:00.000Z | Standard synchronous tier; promotional through at least 2026-11-21. |
12
+ | GPT-5.6 Sol | openai, openai-codex | gpt-5.6-sol | $4 | $0.4 | $5 | $20 | prompt ≤ 271,999; from 2026-08-26T00:00:00.000Z; before 2026-11-22T00:00:00.000Z | Standard synchronous tier; promotional through at least 2026-11-21. |
13
+ | GPT-5.6 Terra · long context | openai, openai-codex | gpt-5.6-terra | $4 | $0.4 | $5 | $18 | prompt ≥ 272,000 | |
14
+ | GPT-5.6 Terra | openai, openai-codex | gpt-5.6-terra | $2 | $0.2 | $2.5 | $12 | prompt ≤ 271,999 | |
15
+ | GPT-5.6 Luna · long context | openai, openai-codex | gpt-5.6-luna | $0.4 | $0.04 | $0.5 | $1.8 | prompt ≥ 272,000 | |
16
+ | GPT-5.6 Luna | openai, openai-codex | gpt-5.6-luna | $0.2 | $0.02 | $0.25 | $1.2 | prompt ≤ 271,999 | |
17
+ | GPT-5.5 · long context | openai, openai-codex | gpt-5.5 | $10 | $1 | $10 | $45 | prompt ≥ 272,000 | |
18
+ | GPT-5.5 | openai, openai-codex | gpt-5.5 | $5 | $0.5 | $5 | $30 | prompt ≤ 271,999 | |
19
+ | GPT-5.5 Pro · long context | openai, openai-codex | gpt-5.5-pro | $60 | $60 | $60 | $270 | prompt ≥ 272,000 | No discounted cached-input SKU is published; cached buckets use input price. |
20
+ | GPT-5.5 Pro | openai, openai-codex | gpt-5.5-pro | $30 | $30 | $30 | $180 | prompt ≤ 271,999 | No discounted cached-input SKU is published; cached buckets use input price. |
21
+ | GPT-5.4 · long context | openai, openai-codex | gpt-5.4 | $5 | $0.5 | $5 | $22.5 | prompt ≥ 272,000 | |
22
+ | GPT-5.4 | openai, openai-codex | gpt-5.4 | $2.5 | $0.25 | $2.5 | $15 | prompt ≤ 271,999 | |
23
+ | GPT-5.4 Pro · long context | openai, openai-codex | gpt-5.4-pro | $60 | $60 | $60 | $270 | prompt ≥ 272,000 | No discounted cached-input SKU is published; cached buckets use input price. |
24
+ | GPT-5.4 Pro | openai, openai-codex | gpt-5.4-pro | $30 | $30 | $30 | $180 | prompt ≤ 271,999 | No discounted cached-input SKU is published; cached buckets use input price. |
25
+ | GPT-5.4 Mini | openai, openai-codex | gpt-5.4-mini | $0.75 | $0.075 | $0.75 | $4.5 | standard | |
26
+ | GPT-5.4 Nano | openai, openai-codex | gpt-5.4-nano | $0.2 | $0.02 | $0.2 | $1.25 | standard | |
27
+ | GPT-4.1 | openai, openai-codex | gpt-4.1, gpt-4.1-20* | $2 | $0.5 | $2 | $8 | standard | |
28
+ | GPT-4.1 Mini | openai, openai-codex | gpt-4.1-mini, gpt-4.1-mini-20* | $0.4 | $0.1 | $0.4 | $1.6 | standard | |
29
+ | GPT-4.1 Nano | openai, openai-codex | gpt-4.1-nano, gpt-4.1-nano-20* | $0.1 | $0.025 | $0.1 | $0.4 | standard | |
30
+ | GPT-5.3 Codex | openai, openai-codex | gpt-5.3-codex | $1.75 | $0.175 | $1.75 | $14 | standard | Standard Codex tier. |
31
+ | GPT-5 | openai, openai-codex | gpt-5 | $1.25 | $0.125 | $1.25 | $10 | standard | Prior-generation exact ID retained for existing sessions. |
32
+ | GPT-5 Mini | openai, openai-codex | gpt-5-mini | $0.25 | $0.025 | $0.25 | $2 | standard | Prior-generation exact ID retained for existing sessions. |
33
+ | GPT-5 Nano | openai, openai-codex | gpt-5-nano | $0.05 | $0.005 | $0.05 | $0.4 | standard | Prior-generation exact ID retained for existing sessions. |
34
+ | GPT-4o | openai, openai-codex | gpt-4o, gpt-4o-20* | $2.5 | $1.25 | $2.5 | $10 | standard | |
35
+ | GPT-4o Mini | openai, openai-codex | gpt-4o-mini, gpt-4o-mini-20* | $0.15 | $0.075 | $0.15 | $0.6 | standard | |
36
+ | Claude Fable 5 | anthropic | claude-fable-5* | $10 | $1 | $12.5 | $50 | standard | Cache-write estimate uses the standard 5-minute cache rate. |
37
+ | Claude Mythos 5 | anthropic | claude-mythos-5* | $10 | $1 | $12.5 | $50 | standard | Limited availability; cache-write estimate uses the 5-minute rate. |
38
+ | Claude Opus 5 | anthropic | claude-opus-5* | $5 | $0.5 | $6.25 | $25 | standard | Global standard inference; cache-write estimate uses the 5-minute rate. |
39
+ | Claude Opus 4.8 | anthropic | claude-opus-4-8* | $5 | $0.5 | $6.25 | $25 | standard | Global standard inference; cache-write estimate uses the 5-minute rate. |
40
+ | Claude Opus 4.7 | anthropic | claude-opus-4-7* | $5 | $0.5 | $6.25 | $25 | standard | Global standard inference; cache-write estimate uses the 5-minute rate. |
41
+ | Claude Opus 4.6 | anthropic | claude-opus-4-6* | $5 | $0.5 | $6.25 | $25 | standard | Global standard inference; cache-write estimate uses the 5-minute rate. |
42
+ | Claude Opus 4.5 | anthropic | claude-opus-4-5* | $5 | $0.5 | $6.25 | $25 | standard | Global standard inference; cache-write estimate uses the 5-minute rate. |
43
+ | Claude Opus 4.1 | anthropic | claude-opus-4-1* | $15 | $1.5 | $18.75 | $75 | standard | Retired on the first-party API; retained for historical logs. |
44
+ | Claude Opus 4 | anthropic | claude-opus-4-2025* | $15 | $1.5 | $18.75 | $75 | standard | Retired on the first-party API; retained for historical logs. |
45
+ | Claude Sonnet 5 | anthropic | claude-sonnet-5* | $2 | $0.2 | $2.5 | $10 | standard | Cache-write estimate uses the 5-minute rate. |
46
+ | Claude Sonnet 4.6 | anthropic | claude-sonnet-4-6* | $3 | $0.3 | $3.75 | $15 | standard | Cache-write estimate uses the 5-minute rate. |
47
+ | Claude Sonnet 4.5 | anthropic | claude-sonnet-4-5* | $3 | $0.3 | $3.75 | $15 | standard | Cache-write estimate uses the 5-minute rate. |
48
+ | Claude Sonnet 4 | anthropic | claude-sonnet-4-2025* | $3 | $0.3 | $3.75 | $15 | standard | Cache-write estimate uses the 5-minute rate. |
49
+ | Claude Haiku 4.5 | anthropic | claude-haiku-4-5* | $1 | $0.1 | $1.25 | $5 | standard | Cache-write estimate uses the 5-minute rate. |
50
+ | Claude Haiku 3.5 | anthropic | claude-3-5-haiku*, claude-haiku-3-5* | $0.8 | $0.08 | $1 | $4 | standard | Retired on the first-party API; retained for historical logs. |
51
+ | Gemini 3.7 Flash | google, gemini, google-ai | gemini-3.7-flash | $0.75 | $0.075 | $0.75 | $3.75 | from 2026-08-26T00:00:00.000Z; before 2027-01-01T00:00:00.000Z | Promotional through 2026-12-31; cache storage token-hours are excluded. |
52
+ | Gemini 3.7 Flash · 2027 rate | google, gemini, google-ai | gemini-3.7-flash | $1.5 | $0.15 | $1.5 | $7.5 | from 2027-01-01T00:00:00.000Z | Official rate beginning 2027-01-01; cache storage token-hours are excluded. |
53
+ | Gemini 3.6 Flash | google, gemini, google-ai | gemini-3.6-flash | $0.75 | $0.075 | $0.75 | $3.75 | from 2026-08-26T00:00:00.000Z; before 2027-01-01T00:00:00.000Z | Promotional through 2026-12-31; cache storage token-hours are excluded. |
54
+ | Gemini 3.6 Flash · 2027 rate | google, gemini, google-ai | gemini-3.6-flash | $1.5 | $0.15 | $1.5 | $7.5 | from 2027-01-01T00:00:00.000Z | Official rate beginning 2027-01-01; cache storage token-hours are excluded. |
55
+ | Gemini 3.5 Flash | google, gemini, google-ai | gemini-3.5-flash | $1.5 | $0.15 | $1.5 | $9 | standard | Cache storage token-hours are excluded. |
56
+ | Gemini 3.5 Flash-Lite | google, gemini, google-ai | gemini-3.5-flash-lite | $0.3 | $0.03 | $0.3 | $2.5 | standard | Cache storage token-hours are excluded. |
57
+ | Gemini 3.1 Pro Preview · long context | google, gemini, google-ai | gemini-3.1-pro-preview, gemini-3.1-pro-preview-customtools | $4 | $0.4 | $4 | $18 | prompt ≥ 200,001 | Cache storage token-hours are excluded. |
58
+ | Gemini 3.1 Pro Preview | google, gemini, google-ai | gemini-3.1-pro-preview, gemini-3.1-pro-preview-customtools | $2 | $0.2 | $2 | $12 | prompt ≤ 200,000 | Cache storage token-hours are excluded. |
59
+ | Gemini 3.1 Flash-Lite | google, gemini, google-ai | gemini-3.1-flash-lite | $0.25 | $0.025 | $0.25 | $1.5 | standard | Text/image/video rate; audio and cache storage are excluded. |
60
+ | Gemini 2.5 Pro · long context | google, gemini, google-ai | gemini-2.5-pro | $2.5 | $0.25 | $2.5 | $15 | prompt ≥ 200,001 | Cache storage token-hours are excluded. |
61
+ | Gemini 2.5 Pro | google, gemini, google-ai | gemini-2.5-pro | $1.25 | $0.125 | $1.25 | $10 | prompt ≤ 200,000 | Cache storage token-hours are excluded. |
62
+ | Gemini 2.5 Flash | google, gemini, google-ai | gemini-2.5-flash | $0.3 | $0.03 | $0.3 | $2.5 | standard | Text/image/video rate; audio and cache storage are excluded. |
63
+ | Gemini 2.5 Flash-Lite | google, gemini, google-ai | gemini-2.5-flash-lite | $0.1 | $0.01 | $0.1 | $0.4 | standard | Text/image/video rate; audio and cache storage are excluded. |
64
+ | DeepSeek V4 Flash · peak | deepseek, deepseek-api | deepseek-v4-flash | $0.44 | $0.014 | $0.44 | $1.32 | inside listed UTC windows | |
65
+ | DeepSeek V4 Flash · off-peak | deepseek, deepseek-api | deepseek-v4-flash | $0.22 | $0.007 | $0.22 | $0.66 | outside listed UTC windows | |
66
+ | DeepSeek V4 Pro · peak | deepseek, deepseek-api | deepseek-v4-pro | $1.32 | $0.044 | $1.32 | $3.96 | inside listed UTC windows | |
67
+ | DeepSeek V4 Pro · off-peak | deepseek, deepseek-api | deepseek-v4-pro | $0.66 | $0.022 | $0.66 | $1.98 | outside listed UTC windows | |
68
+ | DeepSeek Chat legacy | deepseek | deepseek-chat | $0.28 | $0.028 | $0.28 | $0.42 | before 2026-07-24T16:00:00.000Z | Retired after 2026-07-24 15:59 UTC; retained for historical logs. |
69
+ | DeepSeek Reasoner legacy | deepseek | deepseek-reasoner | $0.55 | $0.14 | $0.55 | $2.19 | before 2026-07-24T16:00:00.000Z | Retired after 2026-07-24 15:59 UTC; retained for historical logs. |
70
+ | GLM-5.3 | zai, z-ai, zhipu, bigmodel | glm-5.3 | $1.4 | $0.26 | $1.4 | $4.4 | standard | Global Z.AI endpoint; cached-input storage is currently free. |
71
+ | GLM-5.2 | zai, z-ai, zhipu, bigmodel | glm-5.2 | $1.4 | $0.26 | $1.4 | $4.4 | standard | Global Z.AI endpoint; cached-input storage is currently free. |
72
+ | GLM-5.1 | zai, z-ai, zhipu, bigmodel | glm-5.1 | $1.4 | $0.26 | $1.4 | $4.4 | standard | Global Z.AI endpoint; cached-input storage is currently free. |
73
+ | GLM-5 | zai, z-ai, zhipu, bigmodel | glm-5 | $1 | $0.2 | $1 | $3.2 | standard | Global Z.AI endpoint; cached-input storage is currently free. |
74
+ | GLM-5 Turbo | zai, z-ai, zhipu, bigmodel | glm-5-turbo | $1.2 | $0.24 | $1.2 | $4 | standard | Global Z.AI endpoint; cached-input storage is currently free. |
75
+ | GLM-4.7 | zai, z-ai, zhipu, bigmodel | glm-4.7 | $0.6 | $0.11 | $0.6 | $2.2 | standard | Global Z.AI endpoint; cached-input storage is currently free. |
76
+ | GLM-4.7 FlashX | zai, z-ai, zhipu, bigmodel | glm-4.7-flashx | $0.07 | $0.01 | $0.07 | $0.4 | standard | Global Z.AI endpoint; cached-input storage is currently free. |
77
+ | GLM-4.6 | zai, z-ai, zhipu, bigmodel | glm-4.6 | $0.6 | $0.11 | $0.6 | $2.2 | standard | Global Z.AI endpoint; cached-input storage is currently free. |
78
+ | GLM-4.5 | zai, z-ai, zhipu, bigmodel | glm-4.5 | $0.6 | $0.11 | $0.6 | $2.2 | standard | Global Z.AI endpoint; cached-input storage is currently free. |
79
+ | GLM-4.5 X | zai, z-ai, zhipu, bigmodel | glm-4.5-x | $2.2 | $0.45 | $2.2 | $8.9 | standard | Global Z.AI endpoint; cached-input storage is currently free. |
80
+ | GLM-4.5 Air | zai, z-ai, zhipu, bigmodel | glm-4.5-air | $0.2 | $0.03 | $0.2 | $1.1 | standard | Global Z.AI endpoint; cached-input storage is currently free. |
81
+ | GLM-4.5 AirX | zai, z-ai, zhipu, bigmodel | glm-4.5-airx | $1.1 | $0.22 | $1.1 | $4.5 | standard | Global Z.AI endpoint; cached-input storage is currently free. |
82
+ | GLM-4 32B | zai, z-ai, zhipu, bigmodel | glm-4-32b-0414-128k | $0.1 | $0.1 | $0.1 | $0.1 | standard | Global Z.AI endpoint; cached-input storage is currently free. |
83
+ | GLM-4.7 Flash | zai, z-ai, zhipu, bigmodel | glm-4.7-flash | $0 | $0 | $0 | $0 | standard | Global Z.AI endpoint; cached-input storage is currently free. |
84
+ | GLM-4.5 Flash | zai, z-ai, zhipu, bigmodel | glm-4.5-flash | $0 | $0 | $0 | $0 | standard | Global Z.AI endpoint; cached-input storage is currently free. |
85
+ | Kimi K3 | kimi, moonshot | kimi-k3 | $3 | $0.3 | $3 | $15 | standard | Standard realtime tier. |
86
+ | Kimi K2.7 Code | kimi, moonshot | kimi-k2.7-code | $0.95 | $0.19 | $0.95 | $4 | standard | Standard realtime tier. |
87
+ | Kimi K2.7 Code Highspeed | kimi, moonshot | kimi-k2.7-code-highspeed | $1.9 | $0.38 | $1.9 | $8 | standard | High-speed serving tier. |
88
+ | Kimi K2.6 | kimi, moonshot | kimi-k2.6 | $0.95 | $0.16 | $0.95 | $4 | standard | Standard realtime tier. |
89
+ | Kimi K2.5 | kimi, moonshot | kimi-k2.5 | $0.6 | $0.1 | $0.6 | $3 | before 2026-09-01T00:00:00.000Z | Scheduled for retirement on 2026-08-31; retained for historical logs. |
90
+ | Moonshot V1 8K | kimi, moonshot | moonshot-v1-8k | $0.2 | $0.2 | $0.2 | $2 | before 2026-09-01T00:00:00.000Z | Scheduled for retirement on 2026-08-31; no cache discount is published. |
91
+ | Moonshot V1 32K | kimi, moonshot | moonshot-v1-32k | $1 | $1 | $1 | $3 | before 2026-09-01T00:00:00.000Z | Scheduled for retirement on 2026-08-31; no cache discount is published. |
92
+ | Moonshot V1 128K | kimi, moonshot | moonshot-v1-128k | $2 | $2 | $2 | $5 | before 2026-09-01T00:00:00.000Z | Scheduled for retirement on 2026-08-31; no cache discount is published. |
93
+ | Grok 4.6 · long context | xai | grok-4.6 | $4 | $1 | $4 | $12 | prompt ≥ 200,000 | Standard text API; tool-call fees are excluded. |
94
+ | Grok 4.6 | xai | grok-4.6 | $2 | $0.5 | $2 | $6 | prompt ≤ 199,999 | Standard text API; tool-call fees are excluded. |
95
+ | Grok Build 0.1 · long context | xai | grok-build-0.1 | $2 | $0.4 | $2 | $4 | prompt ≥ 200,000 | Standard text API; tool-call fees are excluded. |
96
+ | Grok Build 0.1 | xai | grok-build-0.1 | $1 | $0.2 | $1 | $2 | prompt ≤ 199,999 | Standard text API; tool-call fees are excluded. |
97
+ | Grok 4.5 · long context | xai | grok-4.5 | $4 | $0.6 | $4 | $12 | prompt ≥ 200,000 | Standard text API; tool-call fees are excluded. |
98
+ | Grok 4.5 | xai | grok-4.5 | $2 | $0.3 | $2 | $6 | prompt ≤ 199,999 | Standard text API; tool-call fees are excluded. |
99
+ | Grok 4.3 · long context | xai | grok-4.3 | $2.5 | $0.4 | $2.5 | $5 | prompt ≥ 200,000 | Standard text API; tool-call fees are excluded. |
100
+ | Grok 4.3 | xai | grok-4.3 | $1.25 | $0.2 | $1.25 | $2.5 | prompt ≤ 199,999 | Standard text API; tool-call fees are excluded. |
101
+ | Grok 4.20 Reasoning · long context | xai | grok-4.20-0309-reasoning | $2.5 | $0.4 | $2.5 | $5 | prompt ≥ 200,000 | Standard text API; tool-call fees are excluded. |
102
+ | Grok 4.20 Reasoning | xai | grok-4.20-0309-reasoning | $1.25 | $0.2 | $1.25 | $2.5 | prompt ≤ 199,999 | Standard text API; tool-call fees are excluded. |
103
+ | Grok 4.20 Non-Reasoning · long context | xai | grok-4.20-0309-non-reasoning | $2.5 | $0.4 | $2.5 | $5 | prompt ≥ 200,000 | Standard text API; tool-call fees are excluded. |
104
+ | Grok 4.20 Non-Reasoning | xai | grok-4.20-0309-non-reasoning | $1.25 | $0.2 | $1.25 | $2.5 | prompt ≤ 199,999 | Standard text API; tool-call fees are excluded. |
105
+ | Grok 4.20 Multi-Agent · long context | xai | grok-4.20-multi-agent-0309 | $2.5 | $0.4 | $2.5 | $5 | prompt ≥ 200,000 | Standard text API; tool-call fees are excluded. |
106
+ | Grok 4.20 Multi-Agent | xai | grok-4.20-multi-agent-0309 | $1.25 | $0.2 | $1.25 | $2.5 | prompt ≤ 199,999 | Standard text API; tool-call fees are excluded. |
107
+ | Mistral Medium 3.5 | mistral | mistral-medium-3-5 | $1.5 | $1.5 | $1.5 | $7.5 | standard | Exact cache discount is not published per model; cached buckets conservatively use input price. |
108
+ | Mistral Large 3 | mistral | mistral-large-2512 | $0.5 | $0.5 | $0.5 | $1.5 | standard | Exact cache discount is not published per model; cached buckets conservatively use input price. |
109
+ | Mistral Small 4 | mistral | mistral-small-2603 | $0.15 | $0.15 | $0.15 | $0.6 | standard | Exact cache discount is not published per model; cached buckets conservatively use input price. |
110
+ | Codestral | mistral | codestral-2508 | $0.3 | $0.3 | $0.3 | $0.9 | standard | Exact cache discount is not published per model; cached buckets conservatively use input price. |
111
+ | Command A | cohere | command-a-03-2025 | $2.5 | $2.5 | $2.5 | $10 | standard | Current paid production model. No cache discount is published. |
112
+ | Command R7B | cohere | command-r7b-12-2024 | $0.0375 | $0.0375 | $0.0375 | $0.15 | standard | Pinned paid model. No cache discount is published. |
113
+ | Command R | cohere | command-r-08-2024 | $0.15 | $0.15 | $0.15 | $0.6 | standard | Pinned paid model. No cache discount is published. |
114
+ | Command R+ | cohere | command-r-plus-08-2024 | $2.5 | $2.5 | $2.5 | $10 | standard | Pinned paid model. No cache discount is published. |
115
+ | Command legacy | cohere | command | $1 | $1 | $1 | $2 | standard | Deprecated; retained for historical logs. No cache discount is published. |
116
+ | Command Light legacy | cohere | command-light | $0.3 | $0.3 | $0.3 | $0.6 | standard | Deprecated; retained for historical logs. No cache discount is published. |
117
+ | Command R legacy | cohere | command-r-03-2024 | $0.5 | $0.5 | $0.5 | $1.5 | standard | Deprecated; retained for historical logs. No cache discount is published. |
118
+ | Command R+ legacy | cohere | command-r-plus-04-2024 | $3 | $3 | $3 | $15 | standard | Deprecated; retained for historical logs. No cache discount is published. |
119
+ | Qwen 3.7 Max | dashscope, alibaba, qwen | qwen3.7-max-2026-06-08 | $2.5 | $0.5 | $3.125 | $7.5 | prompt ≤ 1,000,000 | Singapore international list price; cache read uses the implicit-cache rate. |
120
+ | Qwen 3.7 Plus · long context | dashscope, alibaba, qwen | qwen3.7-plus-2026-05-26 | $1.2 | $0.24 | $1.5 | $4.8 | prompt ≥ 256,001 | Singapore international list price; cache read uses the implicit-cache rate. |
121
+ | Qwen 3.7 Plus | dashscope, alibaba, qwen | qwen3.7-plus-2026-05-26 | $0.4 | $0.08 | $0.5 | $1.6 | prompt ≤ 256,000 | Singapore international list price; cache read uses the implicit-cache rate. |
122
+ | Qwen 3 Max · ≤32K | dashscope, alibaba, qwen | qwen3-max-2026-01-23 | $1.2 | $0.24 | $1.5 | $6 | prompt ≥ 0; prompt ≤ 32,000 | Singapore international list price; cache read uses the implicit-cache rate. |
123
+ | Qwen 3 Max · 32K–128K | dashscope, alibaba, qwen | qwen3-max-2026-01-23 | $2.4 | $0.48 | $3 | $12 | prompt ≥ 32,001; prompt ≤ 128,000 | Singapore international list price; cache read uses the implicit-cache rate. |
124
+ | Qwen 3 Max · 128K–256K | dashscope, alibaba, qwen | qwen3-max-2026-01-23 | $3 | $0.6 | $3.75 | $15 | prompt ≥ 128,001; prompt ≤ 256,000 | Singapore international list price; cache read uses the implicit-cache rate. |
125
+ | Qwen 3 Coder Plus · ≤32K | dashscope, alibaba, qwen | qwen3-coder-plus-2025-09-23 | $1 | $0.2 | $1.25 | $5 | prompt ≥ 0; prompt ≤ 32,000 | Singapore international list price; cache read uses the implicit-cache rate. |
126
+ | Qwen 3 Coder Plus · 32K–128K | dashscope, alibaba, qwen | qwen3-coder-plus-2025-09-23 | $1.8 | $0.36 | $2.25 | $9 | prompt ≥ 32,001; prompt ≤ 128,000 | Singapore international list price; cache read uses the implicit-cache rate. |
127
+ | Qwen 3 Coder Plus · 128K–256K | dashscope, alibaba, qwen | qwen3-coder-plus-2025-09-23 | $3 | $0.6 | $3.75 | $15 | prompt ≥ 128,001; prompt ≤ 256,000 | Singapore international list price; cache read uses the implicit-cache rate. |
128
+ | Qwen 3 Coder Plus · 256K–1M | dashscope, alibaba, qwen | qwen3-coder-plus-2025-09-23 | $6 | $1.2 | $7.5 | $60 | prompt ≥ 256,001; prompt ≤ 1,000,000 | Singapore international list price; cache read uses the implicit-cache rate. |
129
+ | Qwen 3 Coder Flash · ≤32K | dashscope, alibaba, qwen | qwen3-coder-flash-2025-07-28 | $0.3 | $0.06 | $0.375 | $1.5 | prompt ≥ 0; prompt ≤ 32,000 | Singapore international list price; cache read uses the implicit-cache rate. |
130
+ | Qwen 3 Coder Flash · 32K–128K | dashscope, alibaba, qwen | qwen3-coder-flash-2025-07-28 | $0.5 | $0.1 | $0.625 | $2.5 | prompt ≥ 32,001; prompt ≤ 128,000 | Singapore international list price; cache read uses the implicit-cache rate. |
131
+ | Qwen 3 Coder Flash · 128K–256K | dashscope, alibaba, qwen | qwen3-coder-flash-2025-07-28 | $0.8 | $0.16 | $1 | $4 | prompt ≥ 128,001; prompt ≤ 256,000 | Singapore international list price; cache read uses the implicit-cache rate. |
132
+ | Qwen 3 Coder Flash · 256K–1M | dashscope, alibaba, qwen | qwen3-coder-flash-2025-07-28 | $1.6 | $0.32 | $2 | $9.6 | prompt ≥ 256,001; prompt ≤ 1,000,000 | Singapore international list price; cache read uses the implicit-cache rate. |
133
+ | MiniMax M3 · long context | minimax | MiniMax-M3 | $0.6 | $0.12 | $0.6 | $2.4 | prompt ≥ 512,001 | Standard tier; no separate cache-write price is published. |
134
+ | MiniMax M3 | minimax | MiniMax-M3 | $0.3 | $0.06 | $0.3 | $1.2 | prompt ≤ 512,000 | Standard tier; no separate cache-write price is published. |
135
+ | MiniMax M2.7 | minimax | MiniMax-M2.7 | $0.3 | $0.06 | $0.375 | $1.2 | standard | |
136
+ | MiniMax M2.7 Highspeed | minimax | MiniMax-M2.7-highspeed | $0.6 | $0.06 | $0.375 | $2.4 | standard | |
137
+ | MiniMax M2.5 | minimax | MiniMax-M2.5 | $0.3 | $0.03 | $0.375 | $1.2 | standard | |
138
+ | MiniMax M2.5 Highspeed | minimax | MiniMax-M2.5-highspeed | $0.6 | $0.03 | $0.375 | $2.4 | standard | |
139
+
140
+ ## Official sources
141
+
142
+ - **openai**: https://developers.openai.com/api/docs/pricing
143
+ - **anthropic**: https://platform.claude.com/docs/en/about-claude/pricing
144
+ - **gemini**: https://ai.google.dev/gemini-api/docs/pricing
145
+ - **deepseek**: https://api-docs.deepseek.com/quick_start/pricing/
146
+ - **zai**: https://docs.z.ai/guides/overview/pricing
147
+ - **kimi**: https://platform.kimi.ai/docs/pricing
148
+ - **xai**: https://docs.x.ai/developers/pricing
149
+ - **mistral**: https://mistral.ai/pricing/api/
150
+ - **cohere**: https://cohere.com/pricing
151
+ - **qwen**: https://www.alibabacloud.com/help/en/model-studio/model-pricing
152
+ - **minimax**: https://platform.minimax.io/docs/guides/pricing-paygo
153
+
154
+ ## Accuracy boundaries
155
+
156
+ - Route matching is case-insensitive. Only explicit model aliases and narrowly scoped version-suffix globs are included.
157
+ - Prompt length is the sum of uncached input, cache-read, and cache-write buckets reported for a call.
158
+ - DeepSeek V4 peak windows are evaluated from each model-call start timestamp in UTC.
159
+ - Known promotions and retirements use inclusive `validFrom` / exclusive `validTo` instants; calls outside them remain unpriced unless a successor rule is published.
160
+ - Anthropic cache writes use the 5-minute rate because Harness usage records do not expose cache TTL.
161
+ - Qwen cache reads use the implicit-cache rate; explicit cache hits can be cheaper.
162
+ - Unknown routes remain unpriced rather than inheriting a broad family wildcard.
163
+ - A custom `pricing` array replaces the built-in catalog for that plugin instance.
164
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syncended/dsh-usage",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Token usage, model cost analytics, trends, and activity heatmaps for DeepSeek Harness",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "files": [
18
18
  "dist",
19
+ "docs",
19
20
  "lib/client.js",
20
21
  "cordis.patch.yml",
21
22
  "README.md",
@@ -42,7 +43,9 @@
42
43
  "build": "pnpm clean && tsc -p tsconfig.json && node --check lib/client.js",
43
44
  "typecheck": "tsc -p tsconfig.json --noEmit",
44
45
  "test": "pnpm build && node --test test/*.test.mjs",
45
- "check": "pnpm typecheck && pnpm test",
46
+ "docs:pricing": "node scripts/render-pricing-catalog.mjs",
47
+ "docs:check": "node scripts/render-pricing-catalog.mjs --check",
48
+ "check": "pnpm typecheck && pnpm test && pnpm docs:check",
46
49
  "prepare": "pnpm build"
47
50
  },
48
51
  "keywords": [