@askalf/dario 4.8.47 → 4.8.48

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.
@@ -295,13 +295,24 @@ export declare function parseEffortSuffix(model: string): {
295
295
  * 'high' (live capture 2026-06-09, CC v2.1.170 — the same
296
296
  * capture got 'xhigh' on opus and 'high' on fable), so the
297
297
  * unset-flag default mirrors that per-family. An explicit
298
- * flag still pins.
298
+ * flag still pins (subject to the fable clamp below).
299
299
  * 'low' / 'medium' / 'high' / 'xhigh' / 'max' → pin to that value
300
300
  * 'ultracode' → 'xhigh' (CC's ultracode mode; xhigh on the wire)
301
301
  * 'client' → extract from `clientBody.output_config.effort` (normalized
302
302
  * for the wire); fall back to the per-family default if
303
303
  * absent/non-string
304
304
  *
305
+ * FABLE CLAMP (2026-06-09, live replay bisect on the deployed proxy):
306
+ * fable-5 SOFT-REFUSES `max` and `xhigh` — 200 with stop_reason "refusal"
307
+ * and empty content on every prompt, not a 400 — while `high` answers
308
+ * normally (byte-identical request bodies, only output_config.effort
309
+ * mutated). Empirical matrix on claude-fable-5:
310
+ * high → answers xhigh → refusal max → refusal
311
+ * So on the fable family any resolved 'max'/'xhigh' (from --effort /
312
+ * DARIO_EFFORT pins, ultracode, or client passthrough) is clamped to
313
+ * 'high', the strongest level fable accepts. Operators who pin
314
+ * --effort=max for Opus's sake keep that on every other family.
315
+ *
305
316
  * Exported for tests.
306
317
  */
307
318
  export declare function resolveEffort(flag: EffortValue | undefined, clientBody: Record<string, unknown>, model?: string): string;
@@ -989,27 +989,40 @@ function normalizeEffortForWire(effort) {
989
989
  * 'high' (live capture 2026-06-09, CC v2.1.170 — the same
990
990
  * capture got 'xhigh' on opus and 'high' on fable), so the
991
991
  * unset-flag default mirrors that per-family. An explicit
992
- * flag still pins.
992
+ * flag still pins (subject to the fable clamp below).
993
993
  * 'low' / 'medium' / 'high' / 'xhigh' / 'max' → pin to that value
994
994
  * 'ultracode' → 'xhigh' (CC's ultracode mode; xhigh on the wire)
995
995
  * 'client' → extract from `clientBody.output_config.effort` (normalized
996
996
  * for the wire); fall back to the per-family default if
997
997
  * absent/non-string
998
998
  *
999
+ * FABLE CLAMP (2026-06-09, live replay bisect on the deployed proxy):
1000
+ * fable-5 SOFT-REFUSES `max` and `xhigh` — 200 with stop_reason "refusal"
1001
+ * and empty content on every prompt, not a 400 — while `high` answers
1002
+ * normally (byte-identical request bodies, only output_config.effort
1003
+ * mutated). Empirical matrix on claude-fable-5:
1004
+ * high → answers xhigh → refusal max → refusal
1005
+ * So on the fable family any resolved 'max'/'xhigh' (from --effort /
1006
+ * DARIO_EFFORT pins, ultracode, or client passthrough) is clamped to
1007
+ * 'high', the strongest level fable accepts. Operators who pin
1008
+ * --effort=max for Opus's sake keep that on every other family.
1009
+ *
999
1010
  * Exported for tests.
1000
1011
  */
1001
1012
  export function resolveEffort(flag, clientBody, model) {
1002
- const familyDefault = (model ?? '').toLowerCase().includes('fable') ? 'high' : 'max';
1013
+ const isFable = (model ?? '').toLowerCase().includes('fable');
1014
+ const familyDefault = isFable ? 'high' : 'max';
1015
+ const clamp = (effort) => isFable && (effort === 'max' || effort === 'xhigh') ? 'high' : effort;
1003
1016
  if (flag === undefined)
1004
1017
  return familyDefault;
1005
1018
  if (flag === 'client') {
1006
1019
  const clientOC = clientBody.output_config;
1007
1020
  const clientEffort = clientOC?.effort;
1008
1021
  if (typeof clientEffort === 'string' && clientEffort.length > 0)
1009
- return normalizeEffortForWire(clientEffort);
1022
+ return clamp(normalizeEffortForWire(clientEffort));
1010
1023
  return familyDefault;
1011
1024
  }
1012
- return normalizeEffortForWire(flag);
1025
+ return clamp(normalizeEffortForWire(flag));
1013
1026
  }
1014
1027
  /**
1015
1028
  * Returns true if the given model accepts `thinking: { type: "adaptive" }`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askalf/dario",
3
- "version": "4.8.47",
3
+ "version": "4.8.48",
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": {