@zerotal/ai 1.11.2 → 1.13.0

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
@@ -10,6 +10,21 @@ follows the Zerotal monorepo's unified versioning.
10
10
 
11
11
  ## [1.11.2] — 2026-08-31
12
12
 
13
+ ### Changed — **BREAKING**
14
+
15
+ - **`countTokens` returns `number | null`.** Only Anthropic has a counting endpoint, and
16
+ `0` — the old value from the others — is also a real count for an empty prompt, so the
17
+ return value could not distinguish "no tokens" from "cannot count". Callers need a
18
+ `null` check; a custom driver returning `number` still satisfies the contract.
19
+
20
+ This shipped in a patch and should have been a minor.
21
+
22
+ ### Changed — **INTERNAL**
23
+
24
+ - **`toSchema`, `strippedConstraints`, `resetSpend` and `resetStats` are `@internal`.**
25
+ Still exported, still working — no longer promised. This is the surface narrowing that
26
+ had to precede the `stable` promotion, because narrowing after it is itself breaking.
27
+
13
28
  ### Changed
14
29
 
15
30
  - **Promoted to `stable`.** The public API now follows the compatibility promise in
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerotal/ai",
3
- "version": "1.11.2",
3
+ "version": "1.13.0",
4
4
  "license": "MIT",
5
5
  "maturity": "stable",
6
6
  "private": false,
@@ -30,9 +30,9 @@
30
30
  "typecheck": "tsc --noEmit"
31
31
  },
32
32
  "dependencies": {
33
- "@zerotal/core": "1.11.2",
34
- "@zerotal/validator": "1.11.2",
35
- "@zerotal/queue": "1.11.2"
33
+ "@zerotal/core": "1.13.0",
34
+ "@zerotal/validator": "1.13.0",
35
+ "@zerotal/queue": "1.13.0"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "@anthropic-ai/sdk": ">=0.70.0"
package/src/pricing.ts CHANGED
@@ -38,7 +38,25 @@ const PRICES: Record<string, ModelPrice> = {
38
38
  "claude-haiku-4-5": { input: 1, output: 5 },
39
39
  };
40
40
 
41
- /** Cache reads bill at roughly a tenth of input; writes at a 25% premium. */
41
+ /**
42
+ * Cache reads bill at a tenth of input; writes at a 25% premium.
43
+ *
44
+ * Both are exact for the cache this driver asks for. It sends
45
+ * `cache_control: { type: "ephemeral" }` and nothing else — the 5-minute TTL — and
46
+ * Anthropic prices that at 0.1× input for a read and 1.25× for a write. On Sonnet 5's
47
+ * $2 input rate: $0.20 and $2.50 per million, which is what they publish.
48
+ *
49
+ * **The 1-hour TTL is 2× input, and this underestimates it by 37.5%.** Nothing in this
50
+ * package requests one, so the only way to get there is `providerOptions` overriding
51
+ * the cache control by hand. Worth knowing before you do, because the error is in the
52
+ * unsafe direction for a ceiling: a write priced at 1.25× when it billed at 2× lets
53
+ * spend through rather than blocking it, and a limit that under-counts fails quietly.
54
+ *
55
+ * It is not corrected automatically because `AiUsage` carries one
56
+ * `cacheWriteTokens` number with no TTL attached, so the two cases are
57
+ * indistinguishable here. Guessing between them would trade a known bias for an
58
+ * unknown one.
59
+ */
42
60
  const CACHE_READ_MULTIPLIER = 0.1;
43
61
  const CACHE_WRITE_MULTIPLIER = 1.25;
44
62