@askalf/dario 4.8.44 → 4.8.46

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/dist/analytics.js CHANGED
@@ -40,6 +40,9 @@ export function billingBucketFromClaim(claim) {
40
40
  // Anthropic pricing (per 1M tokens, USD). Not authoritative — used for
41
41
  // rough burn-rate display in the /analytics summary.
42
42
  const PRICING = {
43
+ // Fable 5 official per-token pricing wasn't published at integration time
44
+ // (2026-06-09) — assumed at the current flagship (opus-4-8) rate. Display-only.
45
+ 'claude-fable-5': { input: 5, output: 25, cacheRead: 0.5, cacheCreate: 6.25 },
43
46
  'claude-opus-4-8': { input: 5, output: 25, cacheRead: 0.5, cacheCreate: 6.25 },
44
47
  'claude-opus-4-7': { input: 5, output: 25, cacheRead: 0.5, cacheCreate: 6.25 },
45
48
  'claude-opus-4-6': { input: 15, output: 75, cacheRead: 1.5, cacheCreate: 18.75 },
@@ -47,7 +50,11 @@ const PRICING = {
47
50
  'claude-haiku-4-5': { input: 0.8, output: 4, cacheRead: 0.08, cacheCreate: 1 },
48
51
  };
49
52
  function estimateCost(record) {
50
- const p = PRICING[record.model] ?? PRICING['claude-sonnet-4-6'];
53
+ // Strip a trailing context tag (`claude-fable-5[1m]`, `claude-opus-4-7[1m]`)
54
+ // before the lookup — the [1m] ids billed at the wrong family's rate before
55
+ // (fell through to the sonnet fallback).
56
+ const baseModel = record.model.replace(/\[[^\]]*\]$/, '');
57
+ const p = PRICING[baseModel] ?? PRICING['claude-sonnet-4-6'];
51
58
  return ((record.inputTokens * p.input) +
52
59
  (record.outputTokens * p.output) +
53
60
  (record.cacheReadTokens * p.cacheRead) +
@@ -308,6 +308,9 @@ export declare function resolveEffort(flag: EffortValue | undefined, clientBody:
308
308
  * claude-opus-4-7 ✓ accepts adaptive
309
309
  * claude-opus-4-6 ✓ accepts adaptive
310
310
  * claude-sonnet-4-6 ✓ accepts adaptive
311
+ * claude-fable-5 ✓ accepts adaptive (2026-06-09 — Fable 5 is CC's new
312
+ * flagship and real CC sends `thinking:{type:"adaptive"}`
313
+ * on it, incl. the `claude-fable-5[1m]` long-context id)
311
314
  * claude-opus-4-5 ✗ "adaptive thinking is not supported on this model"
312
315
  * claude-sonnet-4-5 ✗ same
313
316
  * claude-haiku-4-5 ✗ same (already gated separately by isHaiku)
@@ -1013,6 +1013,9 @@ export function resolveEffort(flag, clientBody) {
1013
1013
  * claude-opus-4-7 ✓ accepts adaptive
1014
1014
  * claude-opus-4-6 ✓ accepts adaptive
1015
1015
  * claude-sonnet-4-6 ✓ accepts adaptive
1016
+ * claude-fable-5 ✓ accepts adaptive (2026-06-09 — Fable 5 is CC's new
1017
+ * flagship and real CC sends `thinking:{type:"adaptive"}`
1018
+ * on it, incl. the `claude-fable-5[1m]` long-context id)
1016
1019
  * claude-opus-4-5 ✗ "adaptive thinking is not supported on this model"
1017
1020
  * claude-sonnet-4-5 ✗ same
1018
1021
  * claude-haiku-4-5 ✗ same (already gated separately by isHaiku)
@@ -1029,26 +1032,30 @@ export function resolveEffort(flag, clientBody) {
1029
1032
  */
1030
1033
  export function supportsAdaptiveThinking(modelId) {
1031
1034
  const m = modelId.toLowerCase();
1032
- // Opus/Sonnet, major-minor form: opus-4-6+, sonnet-4-6+, opus-5-X, etc.
1035
+ // Opus/Sonnet/Fable, major-minor form: opus-4-6+, sonnet-4-6+, opus-5-X,
1036
+ // fable-5-X, etc. (Fable launched at 5 — there is no fable-4 line — so the
1037
+ // shared "4-6+" threshold is correct for it by construction.)
1033
1038
  //
1034
1039
  // Digit groups are bounded to {1,2} so the dated-suffix pre-4.x line
1035
1040
  // (`claude-3-5-sonnet-20241022`, `claude-3-7-sonnet-20250219`) doesn't
1036
1041
  // accidentally match the date as `sonnet-2024-1022` and parse year as
1037
1042
  // major. Realistic Anthropic version numbers are 1-2 digits.
1038
- const mm = m.match(/(?:opus|sonnet)-(\d{1,2})-(\d{1,2})\b/);
1043
+ const mm = m.match(/(?:opus|sonnet|fable)-(\d{1,2})-(\d{1,2})\b/);
1039
1044
  if (mm) {
1040
1045
  const major = Number(mm[1]);
1041
1046
  const minor = Number(mm[2]);
1042
1047
  if (major > 4)
1043
- return true; // any opus-5+ / sonnet-5+
1048
+ return true; // any opus-5+ / sonnet-5+ / fable-5+
1044
1049
  if (major === 4 && minor >= 6)
1045
1050
  return true; // 4-6, 4-7, …
1046
1051
  return false; // 4-5 and older
1047
1052
  }
1048
- // Major-only form (e.g. `opus-5`, `opus-10`). The negative lookahead
1049
- // prevents matching the `5` in `opus-5-X` (handled above), and the
1050
- // {1,2} bound prevents matching long dated suffixes.
1051
- const majorOnly = m.match(/(?:opus|sonnet)-(\d{1,2})(?!\d|-)/);
1053
+ // Major-only form (e.g. `opus-5`, `fable-5`, `opus-10`). The negative
1054
+ // lookahead prevents matching the `5` in `opus-5-X` (handled above), and
1055
+ // the {1,2} bound prevents matching long dated suffixes. A trailing
1056
+ // context tag (`claude-fable-5[1m]`) is fine: `[` is neither digit nor
1057
+ // hyphen, so the lookahead passes.
1058
+ const majorOnly = m.match(/(?:opus|sonnet|fable)-(\d{1,2})(?!\d|-)/);
1052
1059
  if (majorOnly && Number(majorOnly[1]) >= 5)
1053
1060
  return true;
1054
1061
  return false;
package/dist/cli.js CHANGED
@@ -1159,8 +1159,9 @@ async function help() {
1159
1159
 
1160
1160
  Proxy options:
1161
1161
  --model=MODEL Force a model for all requests
1162
- Shortcuts: opus, sonnet, haiku
1163
- Full IDs: claude-opus-4-6, claude-sonnet-4-6
1162
+ Shortcuts: fable, fable1m, opus, sonnet, haiku
1163
+ Full IDs: claude-fable-5, claude-opus-4-8,
1164
+ claude-sonnet-4-6 (append [1m] for 1M context)
1164
1165
  Provider prefix: openai:gpt-4o, groq:llama-3.3-70b,
1165
1166
  claude:opus, local:qwen-coder (forces backend)
1166
1167
  Default: passthrough (client decides)
@@ -1450,7 +1451,7 @@ async function help() {
1450
1451
  curl http://localhost:3456/v1/messages \\
1451
1452
  -H "Content-Type: application/json" \\
1452
1453
  -H "anthropic-version: 2023-06-01" \\
1453
- -d '{"model":"claude-opus-4-6","max_tokens":1024,"messages":[{"role":"user","content":"Hello"}]}'
1454
+ -d '{"model":"claude-fable-5","max_tokens":1024,"messages":[{"role":"user","content":"Hello"}]}'
1454
1455
 
1455
1456
  Your subscription handles the billing. No API key needed.
1456
1457
  Tokens auto-refresh in the background — set it and forget it.
package/dist/doctor.js CHANGED
@@ -479,6 +479,7 @@ export async function runChecks(opts = {}) {
479
479
  { family: 'haiku', model: 'claude-haiku-4-5' },
480
480
  { family: 'sonnet', model: 'claude-sonnet-4-6' },
481
481
  { family: 'opus', model: 'claude-opus-4-8' },
482
+ { family: 'fable', model: 'claude-fable-5' },
482
483
  ];
483
484
  const probe = async (model) => {
484
485
  const res = await fetch(probeEndpoint, {
@@ -282,7 +282,7 @@ export declare function _resetInstalledVersionProbeForTest(): void;
282
282
  */
283
283
  export declare const SUPPORTED_CC_RANGE: {
284
284
  readonly min: "1.0.0";
285
- readonly maxTested: "2.1.169";
285
+ readonly maxTested: "2.1.170";
286
286
  };
287
287
  /**
288
288
  * Compare two dotted-numeric version strings. Returns negative if `a<b`,
@@ -786,7 +786,7 @@ export function _resetInstalledVersionProbeForTest() {
786
786
  */
787
787
  export const SUPPORTED_CC_RANGE = {
788
788
  min: '1.0.0',
789
- maxTested: '2.1.169',
789
+ maxTested: '2.1.170',
790
790
  };
791
791
  /**
792
792
  * Compare two dotted-numeric version strings. Returns negative if `a<b`,
package/dist/pool.d.ts CHANGED
@@ -78,15 +78,18 @@ export interface PoolStatus {
78
78
  /** Parse an Anthropic response's rate-limit headers into a snapshot. */
79
79
  export declare function parseRateLimits(headers: Headers): RateLimitSnapshot;
80
80
  /**
81
- * Extract the model family (`opus` / `sonnet` / `haiku`) from a request's
82
- * model id. Used to look up the per-model 7d bucket in
81
+ * Extract the model family (`opus` / `sonnet` / `haiku` / `fable`) from a
82
+ * request's model id. Used to look up the per-model 7d bucket in
83
83
  * `RateLimitSnapshot.perModel7d` during routing decisions. Returns null
84
84
  * for non-Claude models or model ids that don't carry a recognizable
85
85
  * family token (those requests just use the unified buckets).
86
86
  *
87
87
  * Generous on input shape: matches `claude-opus-4-7`, `opus`, `claude-3-7-sonnet-…`,
88
- * `claude-haiku-4-5`, anything containing the family token. Lowercase-normalized
89
- * so it pairs cleanly with `parseRateLimits`'s lowercase family keys.
88
+ * `claude-haiku-4-5`, `claude-fable-5[1m]`, anything containing the family token.
89
+ * Lowercase-normalized so it pairs cleanly with `parseRateLimits`'s lowercase
90
+ * family keys (the header parser is generic on `7d_<family>`, so a `7d_fable`
91
+ * bucket is captured automatically the moment Anthropic starts emitting it —
92
+ * this function is what lets routing USE it).
90
93
  */
91
94
  export declare function modelFamily(modelId: string | null | undefined): string | null;
92
95
  /**
package/dist/pool.js CHANGED
@@ -94,15 +94,18 @@ export function parseRateLimits(headers) {
94
94
  };
95
95
  }
96
96
  /**
97
- * Extract the model family (`opus` / `sonnet` / `haiku`) from a request's
98
- * model id. Used to look up the per-model 7d bucket in
97
+ * Extract the model family (`opus` / `sonnet` / `haiku` / `fable`) from a
98
+ * request's model id. Used to look up the per-model 7d bucket in
99
99
  * `RateLimitSnapshot.perModel7d` during routing decisions. Returns null
100
100
  * for non-Claude models or model ids that don't carry a recognizable
101
101
  * family token (those requests just use the unified buckets).
102
102
  *
103
103
  * Generous on input shape: matches `claude-opus-4-7`, `opus`, `claude-3-7-sonnet-…`,
104
- * `claude-haiku-4-5`, anything containing the family token. Lowercase-normalized
105
- * so it pairs cleanly with `parseRateLimits`'s lowercase family keys.
104
+ * `claude-haiku-4-5`, `claude-fable-5[1m]`, anything containing the family token.
105
+ * Lowercase-normalized so it pairs cleanly with `parseRateLimits`'s lowercase
106
+ * family keys (the header parser is generic on `7d_<family>`, so a `7d_fable`
107
+ * bucket is captured automatically the moment Anthropic starts emitting it —
108
+ * this function is what lets routing USE it).
106
109
  */
107
110
  export function modelFamily(modelId) {
108
111
  if (!modelId)
@@ -114,6 +117,8 @@ export function modelFamily(modelId) {
114
117
  return 'sonnet';
115
118
  if (m.includes('haiku'))
116
119
  return 'haiku';
120
+ if (m.includes('fable'))
121
+ return 'fable';
117
122
  return null;
118
123
  }
119
124
  /**
package/dist/proxy.js CHANGED
@@ -128,6 +128,8 @@ function loadClaudeIdentity() {
128
128
  }
129
129
  // Model shortcuts — users can pass short names
130
130
  const MODEL_ALIASES = {
131
+ 'fable': 'claude-fable-5',
132
+ 'fable1m': 'claude-fable-5[1m]',
131
133
  'opus': 'claude-opus-4-8',
132
134
  'opus47': 'claude-opus-4-7',
133
135
  'opus46': 'claude-opus-4-6',
@@ -363,7 +365,7 @@ function translateStreamChunk(line) {
363
365
  catch { }
364
366
  return null;
365
367
  }
366
- const OPENAI_MODELS_LIST = { object: 'list', data: ['claude-opus-4-8', 'claude-opus-4-7', 'claude-opus-4-6', 'claude-sonnet-4-6', 'claude-haiku-4-5'].map(id => ({ id, object: 'model', created: 1700000000, owned_by: 'anthropic' })) };
368
+ const OPENAI_MODELS_LIST = { object: 'list', data: ['claude-fable-5', 'claude-fable-5[1m]', 'claude-opus-4-8', 'claude-opus-4-7', 'claude-opus-4-6', 'claude-sonnet-4-6', 'claude-haiku-4-5'].map(id => ({ id, object: 'model', created: 1700000000, owned_by: 'anthropic' })) };
367
369
  /**
368
370
  * Append a JSON-ND line to the proxy log file. No-op when stream is
369
371
  * null (logFile not configured). Errors are swallowed — log writes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askalf/dario",
3
- "version": "4.8.44",
3
+ "version": "4.8.46",
4
4
  "description": "Use your Claude Pro/Max subscription in any tool — Cursor, Cline, Aider, the Agent SDK, your scripts — at subscription pricing, not per-token API bills. One local Anthropic + OpenAI-compatible endpoint.",
5
5
  "type": "module",
6
6
  "bin": {