slash-tokens 1.6.4 → 1.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
@@ -1,10 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.6.5] — The Fixed Deal Edition
4
+
5
+ *2026-08-25*
6
+
7
+ Solo $20 mailbox, 10% waived. Team $39 for the data.
8
+
9
+ Rebuilt tarball. 1.6.4 packed a stale gitignored `dist/` (`bun test` runs `src/`). This tarball contains the live ladder: Grok **4.6** / **4.3**, GPT-5.6 **Sol / Terra / Luna**, Claude **Opus 5 / Sonnet 5 / Haiku 4.5**, Gemini **3.5 Flash-Lite**.
10
+
11
+ No Team/Solo price change.
12
+
3
13
  ## [1.6.4] — The Fixed Deal Edition
4
14
 
5
15
  *2026-08-25*
6
16
 
7
- Live model ladder. Grok **4.6** / **4.3**, GPT-5.6 **Sol / Terra / Luna**, Claude **Opus 5 / Sonnet 5 / Haiku 4.5**, Gemini **3.5 Flash-Lite**. Old keys stay as aliases. Calibration factors carried from the 2026-08-23 corpus — not re-measured on the new IDs.
17
+ Live model ladder in source. **Tarball packed stale `dist/`** — `bun test` never rebuilds it. Use **1.6.5**.
8
18
 
9
19
  No Team/Solo price change.
10
20
 
package/README.md CHANGED
@@ -15,7 +15,7 @@ Know the cost before the call leaves your machine.
15
15
  Models change. Windows grow. Slash adapts — you keep building.
16
16
  Cheaper tokens haven't shrunk the bill — usage has.
17
17
 
18
- ## v1.6.4 — The Fixed Deal Edition
18
+ ## v1.6.5 — The Fixed Deal Edition
19
19
 
20
20
  Solo $20 mailbox, 10% waived. Team $39 for the data.
21
21
 
package/dist/cli.js CHANGED
@@ -52,14 +52,23 @@ function writeToMemory(content) {
52
52
  // src/slash.ts
53
53
  var WASM_INPUT_OFFSET2 = 4096;
54
54
  var CALIBRATION = {
55
+ "claude-opus-5": 2.05,
55
56
  "claude-opus": 2.05,
56
57
  "claude-opus-4.7": 2.05,
58
+ "claude-sonnet-5": 2.05,
57
59
  "claude-sonnet": 2.05,
60
+ "claude-haiku-4.5": 1.45,
58
61
  "claude-haiku": 1.45,
59
62
  "gemini-3.1-pro": 1.45,
63
+ "gemini-3.5-flash-lite": 1.45,
60
64
  "gemini-2.5-flash": 1.45,
65
+ "grok-4.6": 1.15,
66
+ "grok-4.3": 1.15,
61
67
  "grok-4.20": 1.15,
62
68
  "grok-4-1-fast": 1.15,
69
+ "gpt-5.6-sol": 1.15,
70
+ "gpt-5.6-terra": 1.15,
71
+ "gpt-5.6-luna": 1.15,
63
72
  "gpt-5.4": 1.15,
64
73
  "gpt-5.4-mini": 1.15,
65
74
  "gpt-5.4-nano": 1.15
@@ -91,12 +100,12 @@ var AI_PATTERNS = [
91
100
  { name: "Mistral", regex: /from\s+['"]@mistralai|MistralClient/g }
92
101
  ];
93
102
  var SDK_REPRESENTATIVE_MODEL = {
94
- Anthropic: "claude-sonnet",
95
- OpenAI: "gpt-5.4",
103
+ Anthropic: "claude-sonnet-5",
104
+ OpenAI: "gpt-5.6-sol",
96
105
  Gemini: "gemini-3.1-pro",
97
- Grok: "grok-4.20"
106
+ Grok: "grok-4.6"
98
107
  };
99
- var UNKNOWN_SDK_REPRESENTATIVE_MODEL = "claude-sonnet";
108
+ var UNKNOWN_SDK_REPRESENTATIVE_MODEL = "claude-sonnet-5";
100
109
  var SKIP_DIRS = new Set([
101
110
  "node_modules",
102
111
  ".git",
@@ -203,18 +212,61 @@ function scan(dir) {
203
212
  }
204
213
 
205
214
  // src/models.ts
215
+ var OPUS = { input: 5, output: 25, context: 1e6 };
216
+ var SONNET = { input: 2, output: 10, context: 1e6 };
217
+ var HAIKU = { input: 1, output: 5, context: 200000 };
218
+ var GROK_46 = {
219
+ input: 2,
220
+ output: 6,
221
+ context: 500000,
222
+ longContextThreshold: 200000,
223
+ longContextInput: 4,
224
+ longContextOutput: 12
225
+ };
226
+ var GROK_43 = {
227
+ input: 1.25,
228
+ output: 2.5,
229
+ context: 1e6,
230
+ longContextThreshold: 200000,
231
+ longContextInput: 2.5,
232
+ longContextOutput: 5
233
+ };
234
+ var GEMINI_PRO = {
235
+ input: 2,
236
+ output: 12,
237
+ context: 1e6,
238
+ longContextThreshold: 200000,
239
+ longContextInput: 4,
240
+ longContextOutput: 18
241
+ };
242
+ var GEMINI_FLASH = { input: 0.3, output: 2.5, context: 1e6 };
243
+ var GPT_SOL = { input: 4, output: 20, context: 1050000 };
244
+ var GPT_TERRA = { input: 2, output: 12, context: 1050000 };
245
+ var GPT_LUNA = { input: 0.2, output: 1.2, context: 1050000 };
246
+ var GPT_54 = { input: 2.5, output: 15, context: 1e6 };
247
+ var GPT_54_MINI = { input: 0.75, output: 4.5, context: 128000 };
248
+ var GPT_54_NANO = { input: 0.2, output: 1.25, context: 128000 };
206
249
  var MODELS = {
207
- "claude-opus": { input: 5, output: 25, context: 1e6 },
208
- "claude-opus-4.7": { input: 5, output: 25, context: 1e6 },
209
- "claude-sonnet": { input: 2, output: 10, context: 1e6 },
210
- "claude-haiku": { input: 1, output: 5, context: 200000 },
211
- "grok-4.20": { input: 1.25, output: 2.5, context: 1e6, longContextThreshold: 200000, longContextInput: 2.5, longContextOutput: 5 },
212
- "grok-4-1-fast": { input: 1.25, output: 2.5, context: 1e6, longContextThreshold: 200000, longContextInput: 2.5, longContextOutput: 5 },
213
- "gemini-3.1-pro": { input: 2, output: 12, context: 1e6 },
214
- "gemini-2.5-flash": { input: 0.3, output: 2.5, context: 1e6 },
215
- "gpt-5.4": { input: 2.5, output: 15, context: 1e6 },
216
- "gpt-5.4-mini": { input: 0.75, output: 4.5, context: 128000 },
217
- "gpt-5.4-nano": { input: 0.2, output: 1.25, context: 128000 }
250
+ "claude-opus-5": { ...OPUS },
251
+ "claude-opus": { ...OPUS },
252
+ "claude-opus-4.7": { ...OPUS },
253
+ "claude-sonnet-5": { ...SONNET },
254
+ "claude-sonnet": { ...SONNET },
255
+ "claude-haiku-4.5": { ...HAIKU },
256
+ "claude-haiku": { ...HAIKU },
257
+ "grok-4.6": { ...GROK_46 },
258
+ "grok-4.3": { ...GROK_43 },
259
+ "grok-4.20": { ...GROK_43 },
260
+ "grok-4-1-fast": { ...GROK_43 },
261
+ "gemini-3.1-pro": { ...GEMINI_PRO },
262
+ "gemini-3.5-flash-lite": { ...GEMINI_FLASH },
263
+ "gemini-2.5-flash": { ...GEMINI_FLASH },
264
+ "gpt-5.6-sol": { ...GPT_SOL },
265
+ "gpt-5.6-terra": { ...GPT_TERRA },
266
+ "gpt-5.6-luna": { ...GPT_LUNA },
267
+ "gpt-5.4": { ...GPT_54 },
268
+ "gpt-5.4-mini": { ...GPT_54_MINI },
269
+ "gpt-5.4-nano": { ...GPT_54_NANO }
218
270
  };
219
271
  function getModel(name) {
220
272
  return MODELS[name] || MODELS[name.toLowerCase()];
package/dist/intercept.js CHANGED
@@ -5,16 +5,25 @@ import { PROVIDER_MODELS } from './providers.js';
5
5
  // Reverse lookup: model name → provider model names in the API
6
6
  // (what to put back in the request body)
7
7
  const MODEL_API_NAMES = {
8
+ 'claude-opus-5': 'claude-opus-5',
8
9
  'claude-opus': 'claude-opus-5',
9
10
  'claude-opus-4.7': 'claude-opus-4-7',
11
+ 'claude-sonnet-5': 'claude-sonnet-5',
10
12
  'claude-sonnet': 'claude-sonnet-5',
13
+ 'claude-haiku-4.5': 'claude-haiku-4-5-20251001',
11
14
  'claude-haiku': 'claude-haiku-4-5-20251001',
15
+ 'gpt-5.6-sol': 'gpt-5.6-sol',
16
+ 'gpt-5.6-terra': 'gpt-5.6-terra',
17
+ 'gpt-5.6-luna': 'gpt-5.6-luna',
12
18
  'gpt-5.4': 'gpt-5.4',
13
19
  'gpt-5.4-mini': 'gpt-5.4-mini',
14
20
  'gpt-5.4-nano': 'gpt-5.4-nano',
21
+ 'grok-4.6': 'grok-4.6',
22
+ 'grok-4.3': 'grok-4.3',
15
23
  'grok-4.20': 'grok-4.20-0309-non-reasoning',
16
24
  'grok-4-1-fast': 'grok-4.3',
17
25
  'gemini-3.1-pro': 'gemini-pro-latest',
26
+ 'gemini-3.5-flash-lite': 'gemini-3.5-flash-lite',
18
27
  'gemini-2.5-flash': 'gemini-flash-latest',
19
28
  };
20
29
  // AI API endpoint detection
@@ -27,7 +36,7 @@ const AI_ENDPOINTS = [
27
36
  {
28
37
  pattern: /api\.openai\.com/,
29
38
  provider: 'OpenAI',
30
- modelExtractor: (body) => body?.model || 'gpt-5.4',
39
+ modelExtractor: (body) => body?.model || 'gpt-5.6-sol',
31
40
  },
32
41
  {
33
42
  pattern: /generativelanguage\.googleapis\.com/,
@@ -35,13 +44,13 @@ const AI_ENDPOINTS = [
35
44
  modelExtractor: (_body, url) => {
36
45
  // Model is in the URL path: /v1beta/models/gemini-2.0-flash:generateContent
37
46
  const match = url?.match(/\/models\/([^/:]+)/);
38
- return match ? match[1] : 'gemini-2.5-flash';
47
+ return match ? match[1] : 'gemini-3.5-flash-lite';
39
48
  },
40
49
  },
41
50
  {
42
51
  pattern: /api\.x\.ai/,
43
52
  provider: 'xAI',
44
- modelExtractor: (body) => body?.model || 'grok-4.20',
53
+ modelExtractor: (body) => body?.model || 'grok-4.6',
45
54
  },
46
55
  ];
47
56
  // Normalize model names to our pricing table keys.
@@ -55,33 +64,54 @@ const AI_ENDPOINTS = [
55
64
  // to a falsely-safe-looking value is the dangerous case).
56
65
  export function normalizeModel(raw) {
57
66
  const lower = raw.toLowerCase();
58
- // Anthropic — 4.7 before generic opus check, same order as slash-models.ts
67
+ // Anthropic — specific versions before generic family
59
68
  if (lower.includes('opus') && (lower.includes('4-7') || lower.includes('4.7')))
60
69
  return 'claude-opus-4.7';
70
+ if (lower.includes('opus-5'))
71
+ return 'claude-opus-5';
61
72
  if (lower.includes('opus'))
62
73
  return 'claude-opus';
74
+ if (lower.includes('sonnet-5'))
75
+ return 'claude-sonnet-5';
63
76
  if (lower.includes('sonnet'))
64
77
  return 'claude-sonnet';
78
+ if (lower.includes('haiku') && (lower.includes('4.5') || lower.includes('4-5')))
79
+ return 'claude-haiku-4.5';
65
80
  if (lower.includes('haiku'))
66
81
  return 'claude-haiku';
67
- // xAI
82
+ // xAI — 4.6 / 4.3 / 4.20 before generic grok
83
+ if (lower.includes('grok') && (lower.includes('4.6') || lower.includes('4-6')))
84
+ return 'grok-4.6';
85
+ if (lower.includes('grok') && (lower.includes('4.3') || lower.includes('4-3')))
86
+ return 'grok-4.3';
87
+ if (lower.includes('grok') && (lower.includes('4.20') || lower.includes('4-20')))
88
+ return 'grok-4.20';
68
89
  if (lower.includes('grok') && lower.includes('fast'))
69
90
  return 'grok-4-1-fast';
70
91
  if (lower.includes('grok'))
71
- return 'grok-4.20';
92
+ return 'grok-4.6';
72
93
  // Google
73
94
  if (lower.includes('gemini') && lower.includes('pro'))
74
95
  return 'gemini-3.1-pro';
75
- if (lower.includes('gemini'))
96
+ if (lower.includes('gemini') && lower.includes('3.5') && lower.includes('lite'))
97
+ return 'gemini-3.5-flash-lite';
98
+ if (lower.includes('gemini') && lower.includes('2.5'))
76
99
  return 'gemini-2.5-flash';
77
- // OpenAI — current (5.4 family)
100
+ if (lower.includes('gemini'))
101
+ return 'gemini-3.5-flash-lite';
102
+ // OpenAI — 5.6 then 5.4 then legacy
103
+ if (lower.includes('5.6') && lower.includes('luna'))
104
+ return 'gpt-5.6-luna';
105
+ if (lower.includes('5.6') && lower.includes('terra'))
106
+ return 'gpt-5.6-terra';
107
+ if (lower.includes('5.6'))
108
+ return 'gpt-5.6-sol';
78
109
  if (lower.includes('5.4') && lower.includes('nano'))
79
110
  return 'gpt-5.4-nano';
80
111
  if (lower.includes('5.4') && lower.includes('mini'))
81
112
  return 'gpt-5.4-mini';
82
113
  if (lower.includes('5.4'))
83
114
  return 'gpt-5.4';
84
- // OpenAI — legacy model names → map to closest current equivalent
85
115
  if (lower.includes('o1-mini') || lower.includes('o1_mini'))
86
116
  return 'gpt-5.4-mini';
87
117
  if (lower.includes('o1'))
package/dist/models.js CHANGED
@@ -1,44 +1,60 @@
1
- // Pricing as of April 2026 — USD per million tokens
2
- // Claude Sonnet 5 pricing corrected 2026-08-23: was hardcoded at $3.00/
3
- // $15.00 (the previously-scheduled Sept 1, 2026 increase), but Anthropic's
4
- // own pricing page confirms that increase will NOT occur — $2.00/$10.00
5
- // (the introductory rate) is now the permanent standard price. Found via
6
- // a full-codebase review that independently re-verified every provider's
7
- // live pricing, not just the model IDs already fixed that day.
8
- // xAI pricing re-derived 2026-08-23: grok-4.20 and grok-4-1-fast (the literal
9
- // API IDs, not just the generic keys below) were both fully retired — not
10
- // just old snapshots, they 404 on the live API. Current lineup has no cheap
11
- // tier at all; grok-4.20 (generic) now targets grok-4.20-0309-non-reasoning
12
- // and grok-4-1-fast (generic) targets grok-4.3, both $1.25/$2.50/1M — see
13
- // intercept.ts MODEL_API_NAMES. There is currently no xAI model cheaper than
14
- // $1.25/M input, so routing between these two generic keys yields zero
15
- // savings (findCheapestRoute requires strictly cheaper — this is honest,
16
- // not a bug: the old $0.20/M "fast" tier no longer exists).
1
+ const OPUS = { input: 5.00, output: 25.00, context: 1000000 };
2
+ const SONNET = { input: 2.00, output: 10.00, context: 1000000 };
3
+ const HAIKU = { input: 1.00, output: 5.00, context: 200000 };
4
+ const GROK_46 = {
5
+ input: 2.00, output: 6.00, context: 500000,
6
+ longContextThreshold: 200000, longContextInput: 4.00, longContextOutput: 12.00,
7
+ };
8
+ const GROK_43 = {
9
+ input: 1.25, output: 2.50, context: 1000000,
10
+ longContextThreshold: 200000, longContextInput: 2.50, longContextOutput: 5.00,
11
+ };
12
+ const GEMINI_PRO = {
13
+ input: 2.00, output: 12.00, context: 1000000,
14
+ longContextThreshold: 200000, longContextInput: 4.00, longContextOutput: 18.00,
15
+ };
16
+ const GEMINI_FLASH = { input: 0.30, output: 2.50, context: 1000000 };
17
+ const GPT_SOL = { input: 4.00, output: 20.00, context: 1050000 };
18
+ const GPT_TERRA = { input: 2.00, output: 12.00, context: 1050000 };
19
+ const GPT_LUNA = { input: 0.20, output: 1.20, context: 1050000 };
20
+ const GPT_54 = { input: 2.50, output: 15.00, context: 1000000 };
21
+ const GPT_54_MINI = { input: 0.75, output: 4.50, context: 128000 };
22
+ const GPT_54_NANO = { input: 0.20, output: 1.25, context: 128000 };
23
+ // Pricing as of 2026-08-25 — USD per million tokens.
24
+ // First-party: platform.claude.com/docs/en/about-claude/pricing
25
+ // developers.openai.com/api/docs/models
26
+ // docs.x.ai/developers/models
27
+ // ai.google.dev/gemini-api/docs/pricing
28
+ // Old keys stay as aliases so existing call sites don't throw.
17
29
  export const MODELS = {
18
- // Anthropic
19
- 'claude-opus': { input: 5.00, output: 25.00, context: 1000000 },
20
- 'claude-opus-4.7': { input: 5.00, output: 25.00, context: 1000000 },
21
- 'claude-sonnet': { input: 2.00, output: 10.00, context: 1000000 },
22
- 'claude-haiku': { input: 1.00, output: 5.00, context: 200000 },
23
- // xAI
24
- 'grok-4.20': { input: 1.25, output: 2.50, context: 1000000, longContextThreshold: 200000, longContextInput: 2.50, longContextOutput: 5.00 },
25
- 'grok-4-1-fast': { input: 1.25, output: 2.50, context: 1000000, longContextThreshold: 200000, longContextInput: 2.50, longContextOutput: 5.00 },
30
+ // Anthropic — live names + generic aliases (same rates)
31
+ 'claude-opus-5': { ...OPUS },
32
+ 'claude-opus': { ...OPUS },
33
+ 'claude-opus-4.7': { ...OPUS },
34
+ 'claude-sonnet-5': { ...SONNET },
35
+ 'claude-sonnet': { ...SONNET },
36
+ 'claude-haiku-4.5': { ...HAIKU },
37
+ 'claude-haiku': { ...HAIKU },
38
+ // xAI — flagship 4.6, cheap same-provider 4.3. 4.20 / fast are aliases.
39
+ 'grok-4.6': { ...GROK_46 },
40
+ 'grok-4.3': { ...GROK_43 },
41
+ 'grok-4.20': { ...GROK_43 },
42
+ 'grok-4-1-fast': { ...GROK_43 },
26
43
  // Google
27
- 'gemini-3.1-pro': { input: 2.00, output: 12.00, context: 1000000 },
28
- 'gemini-2.5-flash': { input: 0.30, output: 2.50, context: 1000000 },
29
- // OpenAI
30
- 'gpt-5.4': { input: 2.50, output: 15.00, context: 1000000 },
31
- 'gpt-5.4-mini': { input: 0.75, output: 4.50, context: 128000 },
32
- 'gpt-5.4-nano': { input: 0.20, output: 1.25, context: 128000 },
44
+ 'gemini-3.1-pro': { ...GEMINI_PRO },
45
+ 'gemini-3.5-flash-lite': { ...GEMINI_FLASH },
46
+ 'gemini-2.5-flash': { ...GEMINI_FLASH },
47
+ // OpenAI — live 5.6 ladder. 5.4 family kept as aliases (old prices).
48
+ 'gpt-5.6-sol': { ...GPT_SOL },
49
+ 'gpt-5.6-terra': { ...GPT_TERRA },
50
+ 'gpt-5.6-luna': { ...GPT_LUNA },
51
+ 'gpt-5.4': { ...GPT_54 },
52
+ 'gpt-5.4-mini': { ...GPT_54_MINI },
53
+ 'gpt-5.4-nano': { ...GPT_54_NANO },
33
54
  };
34
55
  export function getModel(name) {
35
56
  return MODELS[name] || MODELS[name.toLowerCase()];
36
57
  }
37
- // Resolve the actual billable rate for a given token count — applies the
38
- // long-context tier above if the model has one and tokens cross it.
39
- // preflight()/preflightRoute() should go through this, not read
40
- // .input/.output directly, or a Grok call over 200K tokens gets silently
41
- // under-costed at the base rate.
42
58
  export function effectiveRate(tokens, info) {
43
59
  if (info.longContextThreshold !== undefined && tokens > info.longContextThreshold) {
44
60
  return {
@@ -4,6 +4,6 @@ export interface Pattern {
4
4
  }
5
5
  export declare const AI_PATTERNS: Pattern[];
6
6
  export declare const SDK_REPRESENTATIVE_MODEL: Record<string, string>;
7
- export declare const UNKNOWN_SDK_REPRESENTATIVE_MODEL = "claude-sonnet";
7
+ export declare const UNKNOWN_SDK_REPRESENTATIVE_MODEL = "claude-sonnet-5";
8
8
  export declare const SKIP_DIRS: Set<string>;
9
9
  export declare const SCAN_EXTENSIONS: Set<string>;
package/dist/patterns.js CHANGED
@@ -34,17 +34,17 @@ export const AI_PATTERNS = [
34
34
  // know the exact model), but a real per-provider one instead of a single
35
35
  // guess applied to everyone.
36
36
  export const SDK_REPRESENTATIVE_MODEL = {
37
- 'Anthropic': 'claude-sonnet',
38
- 'OpenAI': 'gpt-5.4',
37
+ 'Anthropic': 'claude-sonnet-5',
38
+ 'OpenAI': 'gpt-5.6-sol',
39
39
  'Gemini': 'gemini-3.1-pro',
40
- 'Grok': 'grok-4.20',
40
+ 'Grok': 'grok-4.6',
41
41
  };
42
42
  // Fallback for SDKs that don't map to one specific provider (Vercel AI,
43
43
  // LangChain, and Bedrock can all wrap any underlying provider; raw
44
44
  // fetch-to-AI-endpoint and Cohere/Mistral have no pricing data in MODELS
45
45
  // at all). claude-sonnet is used as a documented, honest middle-of-the-
46
46
  // road placeholder — not a claim about which model is actually running.
47
- export const UNKNOWN_SDK_REPRESENTATIVE_MODEL = 'claude-sonnet';
47
+ export const UNKNOWN_SDK_REPRESENTATIVE_MODEL = 'claude-sonnet-5';
48
48
  export const SKIP_DIRS = new Set([
49
49
  'node_modules', '.git', 'dist', 'build', '.next', '.nuxt', '.svelte-kit',
50
50
  'coverage', '.turbo', '.cache', '__pycache__', '.venv', 'venv',
@@ -1,26 +1,11 @@
1
1
  /**
2
2
  * Provider groups — single source of truth.
3
3
  *
4
- * Slash routing is always SAME-PROVIDER. Opus → Haiku, GPT-5.4 → Nano,
5
- * Grok-4.20 → Fast, Gemini 3.1 Pro → 2.5 Flash. Never cross-provider.
4
+ * Slash routing is always SAME-PROVIDER. Opus 5 → Haiku 4.5, Sol → Luna,
5
+ * Grok 4.6 → 4.3, Gemini 3.1 Pro → 3.5 Flash-Lite. Never cross-provider.
6
6
  *
7
- * This file is the canonical provider mapping. Both `intercept.ts`
8
- * (runtime fetch patching) and `preflight.ts` (analysis + routing
9
- * prediction) consume from here so they can never drift.
10
- *
11
- * TEST-NOTE: Whenever a new model is added, it MUST appear in exactly one
12
- * provider group below. A model missing from here will:
13
- * - Never be a routing target from `findCheapestRoute` / `preflightRoute`
14
- * - Still appear in `preflight().options` (which is cross-provider analysis)
15
- * That mismatch is by design — see preflight.ts semantics.
7
+ * Order inside a group matters when two models share a price: the first
8
+ * strictly-cheaper hit wins (findCheapestRoute / preflightRoute).
16
9
  */
17
10
  export declare const PROVIDER_MODELS: Record<string, string[]>;
18
- /**
19
- * Identify a model's provider from its canonical key.
20
- *
21
- * TEST-NOTE: This function MUST return a non-null provider for every model
22
- * present in `MODELS` (from models.ts). If `MODELS` adds a model without
23
- * adding it to `PROVIDER_MODELS`, this returns null and routing is disabled
24
- * for that model. Silent skip.
25
- */
26
11
  export declare function providerOf(model: string): string | null;
package/dist/providers.js CHANGED
@@ -1,33 +1,26 @@
1
1
  /**
2
2
  * Provider groups — single source of truth.
3
3
  *
4
- * Slash routing is always SAME-PROVIDER. Opus → Haiku, GPT-5.4 → Nano,
5
- * Grok-4.20 → Fast, Gemini 3.1 Pro → 2.5 Flash. Never cross-provider.
4
+ * Slash routing is always SAME-PROVIDER. Opus 5 → Haiku 4.5, Sol → Luna,
5
+ * Grok 4.6 → 4.3, Gemini 3.1 Pro → 3.5 Flash-Lite. Never cross-provider.
6
6
  *
7
- * This file is the canonical provider mapping. Both `intercept.ts`
8
- * (runtime fetch patching) and `preflight.ts` (analysis + routing
9
- * prediction) consume from here so they can never drift.
10
- *
11
- * TEST-NOTE: Whenever a new model is added, it MUST appear in exactly one
12
- * provider group below. A model missing from here will:
13
- * - Never be a routing target from `findCheapestRoute` / `preflightRoute`
14
- * - Still appear in `preflight().options` (which is cross-provider analysis)
15
- * That mismatch is by design — see preflight.ts semantics.
7
+ * Order inside a group matters when two models share a price: the first
8
+ * strictly-cheaper hit wins (findCheapestRoute / preflightRoute).
16
9
  */
17
10
  export const PROVIDER_MODELS = {
18
- Anthropic: ['claude-opus', 'claude-opus-4.7', 'claude-sonnet', 'claude-haiku'],
19
- OpenAI: ['gpt-5.4', 'gpt-5.4-mini', 'gpt-5.4-nano'],
20
- xAI: ['grok-4.20', 'grok-4-1-fast'],
21
- Google: ['gemini-3.1-pro', 'gemini-2.5-flash'],
11
+ Anthropic: [
12
+ 'claude-opus-5', 'claude-opus', 'claude-opus-4.7',
13
+ 'claude-sonnet-5', 'claude-sonnet',
14
+ 'claude-haiku', 'claude-haiku-4.5',
15
+ ],
16
+ OpenAI: [
17
+ 'gpt-5.6-sol', 'gpt-5.6-terra',
18
+ 'gpt-5.4', 'gpt-5.4-mini', 'gpt-5.4-nano',
19
+ 'gpt-5.6-luna',
20
+ ],
21
+ xAI: ['grok-4.6', 'grok-4.3', 'grok-4.20', 'grok-4-1-fast'],
22
+ Google: ['gemini-3.1-pro', 'gemini-3.5-flash-lite', 'gemini-2.5-flash'],
22
23
  };
23
- /**
24
- * Identify a model's provider from its canonical key.
25
- *
26
- * TEST-NOTE: This function MUST return a non-null provider for every model
27
- * present in `MODELS` (from models.ts). If `MODELS` adds a model without
28
- * adding it to `PROVIDER_MODELS`, this returns null and routing is disabled
29
- * for that model. Silent skip.
30
- */
31
24
  export function providerOf(model) {
32
25
  for (const [provider, models] of Object.entries(PROVIDER_MODELS)) {
33
26
  if (models.includes(model))
package/dist/slash.js CHANGED
@@ -65,7 +65,10 @@ const WASM_INPUT_OFFSET = 4096;
65
65
  * DEFAULT_UNKNOWN_MODEL_FACTOR (1.85), a ~60% larger correction
66
66
  * than it needed. Still safe either way (1.85 > required
67
67
  * minimum), just needlessly inflated for real GPT users.
68
- * grok-4.20 / grok-4-1-fast: 1.15 — re-verified 2026-08-23 against the
68
+ * grok-4.6 / grok-4.3 (and aliases grok-4.20 / grok-4-1-fast): 1.15 —
69
+ * 4.6/4.3 IDs added 2026-08-25; factor CARRIED from the
70
+ * 2026-08-23 corpus, not re-measured on the new wire IDs.
71
+ * grok-4.20 / grok-4-1-fast (original): 1.15 — re-verified 2026-08-23 against the
69
72
  * 29-sample corpus (20 new samples: more languages, Spanish/
70
73
  * Japanese prose, more JSON shapes) and UNCHANGED — same
71
74
  * worst case (technical-docs prose, ratio 0.928) as the
@@ -91,14 +94,23 @@ const WASM_INPUT_OFFSET = 4096;
91
94
  * Slash must NEVER under-report. Over-reporting is safe (go/no-go only).
92
95
  */
93
96
  const CALIBRATION = {
97
+ 'claude-opus-5': 2.05,
94
98
  'claude-opus': 2.05,
95
99
  'claude-opus-4.7': 2.05,
100
+ 'claude-sonnet-5': 2.05,
96
101
  'claude-sonnet': 2.05,
102
+ 'claude-haiku-4.5': 1.45,
97
103
  'claude-haiku': 1.45,
98
104
  'gemini-3.1-pro': 1.45,
105
+ 'gemini-3.5-flash-lite': 1.45,
99
106
  'gemini-2.5-flash': 1.45,
107
+ 'grok-4.6': 1.15,
108
+ 'grok-4.3': 1.15,
100
109
  'grok-4.20': 1.15,
101
110
  'grok-4-1-fast': 1.15,
111
+ 'gpt-5.6-sol': 1.15,
112
+ 'gpt-5.6-terra': 1.15,
113
+ 'gpt-5.6-luna': 1.15,
102
114
  'gpt-5.4': 1.15,
103
115
  'gpt-5.4-mini': 1.15,
104
116
  'gpt-5.4-nano': 1.15,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slash-tokens",
3
- "version": "1.6.4",
3
+ "version": "1.6.5",
4
4
  "description": "Token Optimization for Context Engineers. 4.8 KB WASM. Sub-millisecond. Zero dependencies.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",