@providerkit/core 0.21.1 → 0.22.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.
Files changed (92) hide show
  1. package/README.md +7 -7
  2. package/dist/attribution.d.ts +2 -2
  3. package/dist/capability.d.ts +9 -9
  4. package/dist/capability.js +9 -9
  5. package/dist/capability.js.map +1 -1
  6. package/dist/context.d.ts +4 -4
  7. package/dist/context.js +4 -4
  8. package/dist/errors.d.ts +15 -15
  9. package/dist/errors.d.ts.map +1 -1
  10. package/dist/errors.js +14 -14
  11. package/dist/image.d.ts +1 -1
  12. package/dist/image.d.ts.map +1 -1
  13. package/dist/jev.d.ts +9 -9
  14. package/dist/jev.d.ts.map +1 -1
  15. package/dist/jev.js +1 -1
  16. package/dist/key-pool.d.ts +4 -4
  17. package/dist/key-pool.js +6 -6
  18. package/dist/key-pool.js.map +1 -1
  19. package/dist/presets.d.ts +26 -22
  20. package/dist/presets.d.ts.map +1 -1
  21. package/dist/presets.js +13 -12
  22. package/dist/presets.js.map +1 -1
  23. package/dist/providers/anthropic.d.ts +5 -5
  24. package/dist/providers/anthropic.d.ts.map +1 -1
  25. package/dist/providers/anthropic.js +9 -9
  26. package/dist/providers/factory.d.ts +2 -2
  27. package/dist/providers/factory.d.ts.map +1 -1
  28. package/dist/providers/factory.js +2 -1
  29. package/dist/providers/factory.js.map +1 -1
  30. package/dist/providers/gemini.d.ts +2 -2
  31. package/dist/providers/gemini.d.ts.map +1 -1
  32. package/dist/providers/gemini.js +15 -14
  33. package/dist/providers/gemini.js.map +1 -1
  34. package/dist/providers/openai.d.ts +12 -9
  35. package/dist/providers/openai.d.ts.map +1 -1
  36. package/dist/providers/openai.js +9 -7
  37. package/dist/providers/openai.js.map +1 -1
  38. package/dist/providers/responses.d.ts +3 -3
  39. package/dist/providers/responses.js +5 -5
  40. package/dist/providers/responses.js.map +1 -1
  41. package/dist/providers/zai.d.ts +2 -2
  42. package/dist/providers/zai.js +2 -2
  43. package/dist/rate-limit.d.ts +3 -3
  44. package/dist/rate-limit.js +3 -3
  45. package/dist/retry.d.ts +5 -5
  46. package/dist/retry.js +4 -4
  47. package/dist/schema.d.ts +6 -6
  48. package/dist/schema.js +8 -8
  49. package/dist/tool-args.d.ts +1 -1
  50. package/dist/tool-args.js +2 -2
  51. package/dist/tools.d.ts +3 -3
  52. package/dist/tools.js +2 -2
  53. package/dist/tools.js.map +1 -1
  54. package/dist/transport.d.ts +7 -7
  55. package/dist/transport.js +6 -6
  56. package/dist/types.d.ts +24 -23
  57. package/dist/types.d.ts.map +1 -1
  58. package/dist/types.js +3 -3
  59. package/dist/types.js.map +1 -1
  60. package/dist/usage.d.ts +4 -4
  61. package/dist/usage.d.ts.map +1 -1
  62. package/dist/usage.js +3 -3
  63. package/dist/usage.js.map +1 -1
  64. package/dist/watchdog.d.ts +12 -12
  65. package/dist/watchdog.js +10 -10
  66. package/dist/zod.d.ts +4 -4
  67. package/dist/zod.js +3 -3
  68. package/package.json +1 -1
  69. package/src/attribution.ts +2 -2
  70. package/src/capability.ts +12 -12
  71. package/src/context.ts +4 -4
  72. package/src/errors.ts +18 -18
  73. package/src/image.ts +1 -1
  74. package/src/jev.ts +11 -11
  75. package/src/key-pool.ts +7 -7
  76. package/src/presets.ts +26 -22
  77. package/src/providers/anthropic.ts +14 -14
  78. package/src/providers/factory.ts +4 -3
  79. package/src/providers/gemini.ts +19 -16
  80. package/src/providers/openai.ts +17 -12
  81. package/src/providers/responses.ts +11 -11
  82. package/src/providers/zai.ts +2 -2
  83. package/src/rate-limit.ts +4 -4
  84. package/src/retry.ts +5 -5
  85. package/src/schema.ts +8 -8
  86. package/src/tool-args.ts +2 -2
  87. package/src/tools.ts +4 -4
  88. package/src/transport.ts +7 -7
  89. package/src/types.ts +24 -23
  90. package/src/usage.ts +5 -5
  91. package/src/watchdog.ts +13 -13
  92. package/src/zod.ts +4 -4
package/dist/usage.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import type { TokenUsage } from "./types.ts";
2
- /** USD per MILLION tokens — how every vendor prints its price sheet, so a row
2
+ /** USD per million tokens, as every vendor prints its price sheet, so a row
3
3
  * can be checked against one without arithmetic. */
4
4
  export interface ModelRate {
5
5
  /** Cache-MISS input: fresh tokens the provider had to read. */
6
6
  input: number;
7
7
  output: number;
8
8
  /** Cache-HIT input. Providers auto-cache repeated prefixes and bill the hit
9
- * portion far cheaper — 0.1× on Anthropic, ~0.1× on Gemini, 0.5× on some
9
+ * portion far cheaper: 0.1× on Anthropic, ~0.1× on Gemini, 0.5× on some
10
10
  * OpenAI models. In an agent loop the re-sent context is overwhelmingly
11
11
  * hits, so billing it at the miss rate overcounts by up to 10×. */
12
12
  cacheRead: number;
@@ -40,7 +40,7 @@ export declare function subtractUsage(a: TokenUsage, b: TokenUsage): TokenUsage;
40
40
  export declare function costUsd(usage: TokenUsage, rate: ModelRate): number;
41
41
  /**
42
42
  * Accumulates usage and cost across the calls of one run, pricing each with
43
- * the rate in effect for the model that served it — so a run that switches to
43
+ * the rate in effect for the model that served it, so a run that switches to
44
44
  * a backup model, or spans a time-of-day price boundary, still bills correctly.
45
45
  * A call that carries a reported cost is billed that, with or without a rate.
46
46
  */
@@ -48,7 +48,7 @@ export declare class UsageTracker {
48
48
  private usage;
49
49
  private cost;
50
50
  /** USD the cache hits saved, versus billing them all as misses.
51
- * Observability only — never billed. */
51
+ * Observability only. Never billed. */
52
52
  private saved;
53
53
  add(usage: TokenUsage, rate?: ModelRate): void;
54
54
  subtract(usage: TokenUsage, rate?: ModelRate): void;
@@ -1 +1 @@
1
- {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C;qDACqD;AACrD,MAAM,WAAW,SAAS;IACxB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;;;wEAGoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB;;0EAEsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;8DAG8D;AAC9D,wBAAgB,QAAQ,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,UAAU,CAUjE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,UAAU,CAUtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAgBlE;AAQD;;;;;GAKG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAuD;IACpE,OAAO,CAAC,IAAI,CAAK;IACjB;6CACyC;IACzC,OAAO,CAAC,KAAK,CAAK;IAElB,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI;IAQ9C,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI;IAQnD,IAAI,MAAM,IAAI,UAAU,CAEvB;IAED,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED;;yDAEqD;IACrD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIrC,KAAK,IAAI,IAAI;CAKd"}
1
+ {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C;qDACqD;AACrD,MAAM,WAAW,SAAS;IACxB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;;;wEAGoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB;;0EAEsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;8DAG8D;AAC9D,wBAAgB,QAAQ,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,UAAU,CAUjE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,UAAU,CAUtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAgBlE;AAQD;;;;;GAKG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAuD;IACpE,OAAO,CAAC,IAAI,CAAK;IACjB;4CACwC;IACxC,OAAO,CAAC,KAAK,CAAK;IAElB,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI;IAQ9C,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI;IAQnD,IAAI,MAAM,IAAI,UAAU,CAEvB;IAED,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED;;yDAEqD;IACrD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIrC,KAAK,IAAI,IAAI;CAKd"}
package/dist/usage.js CHANGED
@@ -58,13 +58,13 @@ export function costUsd(usage, rate) {
58
58
  1_000_000);
59
59
  }
60
60
  /** What one call adds to a run: its reported cost, else its rate, else
61
- * nothing — an unpriced call still counts its tokens. */
61
+ * nothing. An unpriced call still counts its tokens. */
62
62
  function callCost(usage, rate) {
63
63
  return rate ? costUsd(usage, rate) : (usage.reportedCostUsd ?? 0);
64
64
  }
65
65
  /**
66
66
  * Accumulates usage and cost across the calls of one run, pricing each with
67
- * the rate in effect for the model that served it — so a run that switches to
67
+ * the rate in effect for the model that served it, so a run that switches to
68
68
  * a backup model, or spans a time-of-day price boundary, still bills correctly.
69
69
  * A call that carries a reported cost is billed that, with or without a rate.
70
70
  */
@@ -72,7 +72,7 @@ export class UsageTracker {
72
72
  usage = { ...EMPTY_USAGE, cacheWriteTokens: 0 };
73
73
  cost = 0;
74
74
  /** USD the cache hits saved, versus billing them all as misses.
75
- * Observability only — never billed. */
75
+ * Observability only. Never billed. */
76
76
  saved = 0;
77
77
  add(usage, rate) {
78
78
  this.usage = addUsage(this.usage, usage);
package/dist/usage.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"usage.js","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import type { Provider, ProviderChunk } from "./types.ts";
2
2
  /** No byte at all for this long, once the response has started, and the
3
3
  * stream is dead. */
4
4
  export declare const STREAM_IDLE_MS = 60000;
5
- /** No chunk for this long — the wait for the response to start included —
5
+ /** No chunk for this long, including the wait for the response to start,
6
6
  * and the stream is going nowhere, keep-alives or not. */
7
7
  export declare const STREAM_PROGRESS_MS = 300000;
8
8
  export interface StreamWatch {
@@ -10,17 +10,17 @@ export interface StreamWatch {
10
10
  readonly signal: AbortSignal;
11
11
  /** A chunk arrived: re-arm both deadlines, and mark TTFT if it was the first. */
12
12
  sawByte(): void;
13
- /** The response showed life without a chunk — its headers, a keep-alive, a
13
+ /** The response showed life without a chunk: its headers, a keep-alive, a
14
14
  * partial frame. Starts or re-arms the idle deadline only. */
15
15
  sawActivity(): void;
16
16
  /**
17
- * Milliseconds from the call opening to its first chunk of any kind — the
17
+ * Milliseconds from the call opening to its first chunk of any kind. The
18
18
  * wait a person actually experiences, and the number a prompt-cache pin
19
19
  * exists to shrink. Null until something arrives.
20
20
  */
21
21
  firstChunkMs(): number | null;
22
22
  /**
23
- * Re-issue a provider failure as the timeout when — and only when — it was
23
+ * Re-issue a provider failure as the timeout only when it was
24
24
  * one of our deadlines that aborted. A caller's Stop passes through untouched.
25
25
  */
26
26
  classify(err: unknown): unknown;
@@ -36,7 +36,7 @@ export interface StreamWatchOptions {
36
36
  export declare function streamWatch(opts?: StreamWatchOptions): StreamWatch;
37
37
  /**
38
38
  * Wrap a stream so every chunk re-arms `watch`, and a failure is re-classified
39
- * through it. Disposes on any exit — completion, throw, or the consumer
39
+ * through it. Disposes on any exit: completion, throw, or the consumer
40
40
  * breaking out of the loop.
41
41
  */
42
42
  export declare function watchChunks<T>(watch: StreamWatch, chunks: AsyncIterable<T>): AsyncGenerator<T>;
@@ -46,7 +46,7 @@ export declare function watchChunks<T>(watch: StreamWatch, chunks: AsyncIterable
46
46
  * A stream that ends with no text and no tool call is a failure wearing a
47
47
  * success's clothes: `stop_reason: end_turn` with zero content blocks, which
48
48
  * the vendors emit under load, or a thinking block that ate the whole
49
- * `max_tokens`. Nothing throws, so nothing retries — the caller simply shows a
49
+ * `max_tokens`. Nothing throws, so nothing retries. The caller simply shows a
50
50
  * person an empty answer, and the only trace is a bill.
51
51
  *
52
52
  * Reasoning is not an answer. It still streams the moment it arrives, so a
@@ -58,12 +58,12 @@ export declare function watchChunks<T>(watch: StreamWatch, chunks: AsyncIterable
58
58
  *
59
59
  * Classified by what fixes it. A `length` finish is the caller's own cap:
60
60
  * `invalid`, so nothing retries it into the same cap and no backup model is
61
- * cooled down for it — the fix is a larger `maxTokens` or a lower effort. Any
61
+ * cooled down for it. The fix is a larger `maxTokens` or a lower effort. Any
62
62
  * other empty turn is `overload`, because that is both true and useful: it is
63
63
  * theirs and temporary, so it is transient (the same model, retried, usually
64
64
  * answers) and backup-eligible (a model that keeps doing it should be walked
65
65
  * away from). Until something streams, the empty frames are held back, so the
66
- * retry rule that matters — retry only while nothing was emitted — still holds.
66
+ * retry rule still holds: retry only while nothing was emitted.
67
67
  */
68
68
  export declare function requireContent<T extends ProviderChunk>(provider: string, chunks: AsyncIterable<T>, opts?: {
69
69
  afterToolResult?: boolean;
@@ -88,8 +88,8 @@ export interface WatchdogOptions {
88
88
  * A provider with both silent failures already handled.
89
89
  *
90
90
  * Every consumer of this package wrote the same three lines around every
91
- * `createStream` — build a watch, hand the provider the WATCH's signal, wrap
92
- * the chunks — and the middle one is the trap. Pass the caller's signal
91
+ * `createStream`: build a watch, hand the provider the watch's signal, wrap
92
+ * the chunks. The middle one is the trap. Pass the caller's signal
93
93
  * instead and everything still compiles, still streams, still passes the
94
94
  * tests: the watchdog simply never aborts anything, because the request it was
95
95
  * meant to cancel was never told about it. The failure has no symptom until
@@ -97,8 +97,8 @@ export interface WatchdogOptions {
97
97
  *
98
98
  * So the composition belongs here rather than in a docs snippet each app
99
99
  * copies. The result is still a `Provider`, so it composes unchanged with
100
- * `withStreamRetry` and `streamWithBackupModels` — and both of the failures it
101
- * catches are transient, which is what makes wrapping it in a retry correct.
100
+ * `withStreamRetry` and `streamWithBackupModels`. Timeouts and empty turns
101
+ * without a `length` finish are transient, so wrapping it in a retry is safe.
102
102
  */
103
103
  export declare function withWatchdog(provider: Provider, opts?: WatchdogOptions): Provider;
104
104
  //# sourceMappingURL=watchdog.d.ts.map
package/dist/watchdog.js CHANGED
@@ -32,7 +32,7 @@ import { ProviderError } from "./errors.js";
32
32
  /** No byte at all for this long, once the response has started, and the
33
33
  * stream is dead. */
34
34
  export const STREAM_IDLE_MS = 60_000;
35
- /** No chunk for this long — the wait for the response to start included —
35
+ /** No chunk for this long, including the wait for the response to start,
36
36
  * and the stream is going nowhere, keep-alives or not. */
37
37
  export const STREAM_PROGRESS_MS = 300_000;
38
38
  export function streamWatch(opts = {}) {
@@ -102,7 +102,7 @@ export function streamWatch(opts = {}) {
102
102
  }
103
103
  /**
104
104
  * Wrap a stream so every chunk re-arms `watch`, and a failure is re-classified
105
- * through it. Disposes on any exit — completion, throw, or the consumer
105
+ * through it. Disposes on any exit: completion, throw, or the consumer
106
106
  * breaking out of the loop.
107
107
  */
108
108
  export async function* watchChunks(watch, chunks) {
@@ -125,7 +125,7 @@ export async function* watchChunks(watch, chunks) {
125
125
  * A stream that ends with no text and no tool call is a failure wearing a
126
126
  * success's clothes: `stop_reason: end_turn` with zero content blocks, which
127
127
  * the vendors emit under load, or a thinking block that ate the whole
128
- * `max_tokens`. Nothing throws, so nothing retries — the caller simply shows a
128
+ * `max_tokens`. Nothing throws, so nothing retries. The caller simply shows a
129
129
  * person an empty answer, and the only trace is a bill.
130
130
  *
131
131
  * Reasoning is not an answer. It still streams the moment it arrives, so a
@@ -137,12 +137,12 @@ export async function* watchChunks(watch, chunks) {
137
137
  *
138
138
  * Classified by what fixes it. A `length` finish is the caller's own cap:
139
139
  * `invalid`, so nothing retries it into the same cap and no backup model is
140
- * cooled down for it — the fix is a larger `maxTokens` or a lower effort. Any
140
+ * cooled down for it. The fix is a larger `maxTokens` or a lower effort. Any
141
141
  * other empty turn is `overload`, because that is both true and useful: it is
142
142
  * theirs and temporary, so it is transient (the same model, retried, usually
143
143
  * answers) and backup-eligible (a model that keeps doing it should be walked
144
144
  * away from). Until something streams, the empty frames are held back, so the
145
- * retry rule that matters — retry only while nothing was emitted — still holds.
145
+ * retry rule still holds: retry only while nothing was emitted.
146
146
  */
147
147
  export async function* requireContent(provider, chunks, opts = {}) {
148
148
  const held = [];
@@ -186,7 +186,7 @@ export async function* requireContent(provider, chunks, opts = {}) {
186
186
  const spent = usage?.reasoningTokens
187
187
  ? ` (${usage.reasoningTokens} of ${usage.outputTokens} output tokens went to reasoning)`
188
188
  : "";
189
- throw new ProviderError(provider, "invalid", `${provider}: the output cap ran out before any answer${spent} — raise maxTokens or lower effort`);
189
+ throw new ProviderError(provider, "invalid", `${provider}: the output cap ran out before any answer${spent}. Raise maxTokens or lower effort.`);
190
190
  }
191
191
  throw new ProviderError(provider, "overload", `${provider}: completed with no content`);
192
192
  }
@@ -194,8 +194,8 @@ export async function* requireContent(provider, chunks, opts = {}) {
194
194
  * A provider with both silent failures already handled.
195
195
  *
196
196
  * Every consumer of this package wrote the same three lines around every
197
- * `createStream` — build a watch, hand the provider the WATCH's signal, wrap
198
- * the chunks — and the middle one is the trap. Pass the caller's signal
197
+ * `createStream`: build a watch, hand the provider the watch's signal, wrap
198
+ * the chunks. The middle one is the trap. Pass the caller's signal
199
199
  * instead and everything still compiles, still streams, still passes the
200
200
  * tests: the watchdog simply never aborts anything, because the request it was
201
201
  * meant to cancel was never told about it. The failure has no symptom until
@@ -203,8 +203,8 @@ export async function* requireContent(provider, chunks, opts = {}) {
203
203
  *
204
204
  * So the composition belongs here rather than in a docs snippet each app
205
205
  * copies. The result is still a `Provider`, so it composes unchanged with
206
- * `withStreamRetry` and `streamWithBackupModels` — and both of the failures it
207
- * catches are transient, which is what makes wrapping it in a retry correct.
206
+ * `withStreamRetry` and `streamWithBackupModels`. Timeouts and empty turns
207
+ * without a `length` finish are transient, so wrapping it in a retry is safe.
208
208
  */
209
209
  export function withWatchdog(provider, opts = {}) {
210
210
  return {
package/dist/zod.d.ts CHANGED
@@ -5,8 +5,8 @@ import type { JsonObjectSchema } from "./types.ts";
5
5
  * A zod schema as the JSON Schema every provider's tool contract wants.
6
6
  *
7
7
  * `$schema` is dropped. zod emits the dialect URI at the root, and a provider
8
- * validating a tool's `parameters` against its own supported subset — OpenAI
9
- * under `strict: true`, Gemini's `parametersJsonSchema` — rejects the whole
8
+ * validating a tool's `parameters` against its own supported subset (OpenAI
9
+ * under `strict: true`, Gemini's `parametersJsonSchema`) rejects the whole
10
10
  * tool over that one key, with a message that names neither zod nor the field.
11
11
  */
12
12
  export declare function toJsonObjectSchema(schema: z.ZodType, label?: string): JsonObjectSchema;
@@ -26,13 +26,13 @@ export interface ZodToolSpec<I, O> {
26
26
  * rejecting the call. Worth it for a TERMINAL tool, which gets no second
27
27
  * chance: a forced-submit salvage turn runs exactly once, and discarding an
28
28
  * otherwise-valid answer over a few extra characters loses the whole run.
29
- * Off by default — an ordinary tool can simply be called again.
29
+ * Off by default: an ordinary tool can simply be called again.
30
30
  */
31
31
  clampOverflow?: boolean;
32
32
  }
33
33
  /**
34
34
  * A tool whose arguments are validated by zod, with the failure reported to
35
- * the MODEL in words it can act on — `topic: expected string, received number`
35
+ * the model in words it can act on. `topic: expected string, received number`
36
36
  * beats a stack trace it cannot read.
37
37
  */
38
38
  export declare function zodTool<I, O>(spec: ZodToolSpec<I, O>): Tool<I, O>;
package/dist/zod.js CHANGED
@@ -10,8 +10,8 @@ import { clampToSchema } from "./schema.js";
10
10
  * A zod schema as the JSON Schema every provider's tool contract wants.
11
11
  *
12
12
  * `$schema` is dropped. zod emits the dialect URI at the root, and a provider
13
- * validating a tool's `parameters` against its own supported subset — OpenAI
14
- * under `strict: true`, Gemini's `parametersJsonSchema` — rejects the whole
13
+ * validating a tool's `parameters` against its own supported subset (OpenAI
14
+ * under `strict: true`, Gemini's `parametersJsonSchema`) rejects the whole
15
15
  * tool over that one key, with a message that names neither zod nor the field.
16
16
  */
17
17
  export function toJsonObjectSchema(schema, label = "schema") {
@@ -26,7 +26,7 @@ export function toJsonObjectSchema(schema, label = "schema") {
26
26
  }
27
27
  /**
28
28
  * A tool whose arguments are validated by zod, with the failure reported to
29
- * the MODEL in words it can act on — `topic: expected string, received number`
29
+ * the model in words it can act on. `topic: expected string, received number`
30
30
  * beats a stack trace it cannot read.
31
31
  */
32
32
  export function zodTool(spec) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@providerkit/core",
3
- "version": "0.21.1",
3
+ "version": "0.22.0",
4
4
  "description": "The layer under your agent loop: one seam for every LLM provider, plus the failure handling you only learn in production.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -9,9 +9,9 @@
9
9
  // HTTP header names are case-insensitive but this seam carries them as a
10
10
  // plain record, so `http-referer` and `HTTP-Referer` must mean the same opt-out.
11
11
  export interface Attribution {
12
- /** Site URL, sent as `HTTP-Referer` — e.g. "https://your.app". */
12
+ /** Site URL, sent as `HTTP-Referer` (e.g. "https://your.app"). */
13
13
  siteUrl?: string;
14
- /** App name, sent as `X-Title` — e.g. "Your App". */
14
+ /** App name, sent as `X-Title` (e.g. "Your App"). */
15
15
  siteName?: string;
16
16
  }
17
17
 
package/src/capability.ts CHANGED
@@ -18,12 +18,12 @@
18
18
 
19
19
  import type { JsonWithTools, Provider } from "./types.ts";
20
20
 
21
- /** Nothing a model can answer from memory — so a tool call is the only correct
22
- * turn, and NOT making one is a real signal rather than a judgement call. */
21
+ /** A question the model cannot answer from memory, so a tool call is the only
22
+ * correct turn. Not making one is a real signal rather than a judgement call. */
23
23
  const PROBE_TOOL = {
24
24
  name: "get_current_time",
25
25
  description:
26
- "The only source of the current time. You cannot know the time without calling this — never answer a time question from memory or guess.",
26
+ "The only source of the current time. You cannot know the time without calling this. Never answer a time question from memory or guess.",
27
27
  inputSchema: {
28
28
  type: "object" as const,
29
29
  properties: { timezone: { type: "string", description: "IANA timezone, e.g. Asia/Tokyo" } },
@@ -46,7 +46,7 @@ const SHAPES: JsonWithTools[] = ["response_format", "prompt"];
46
46
  export interface JsonWithToolsProbe {
47
47
  /**
48
48
  * The shape to configure, or `null` when neither called the tool on every
49
- * sample — that model cannot be trusted with tools and a schema together,
49
+ * sample. That model cannot be trusted with tools and a schema together,
50
50
  * whichever way the schema rides, and the honest fix is a different model.
51
51
  */
52
52
  use: JsonWithTools | null;
@@ -58,8 +58,8 @@ export interface JsonWithToolsProbe {
58
58
 
59
59
  export interface ProbeOptions {
60
60
  /**
61
- * Samples per shape. Above one because the interesting failures are partial —
62
- * `gemini-3.8-flash` called its tool 3/10 — and a single sample reports a
61
+ * Samples per shape. Above one because the interesting failures are partial:
62
+ * `gemini-3.8-flash` called its tool 3/10. A single sample reports a
63
63
  * coin flip as a capability. A shape passes only when EVERY sample calls.
64
64
  */
65
65
  samples?: number;
@@ -95,12 +95,12 @@ async function callsTool(
95
95
 
96
96
  /**
97
97
  * Ask a model, on the wire, which {@link JsonWithTools} shape it actually
98
- * serves — then configure the provider with `probe.use`.
98
+ * serves. Then configure the provider with `probe.use`.
99
99
  *
100
100
  * Both shapes are always tried, because a result you can read beats a result
101
101
  * you have to trust: `calls` is the table to log, and "0/3 and 3/3" is what
102
102
  * makes a later regression obvious. It costs `samples × 2` short calls, made
103
- * one after another, once, at whatever moment the app decides to ask — boot is
103
+ * one after another, once, at whatever moment the app decides to ask. Boot is
104
104
  * the usual one.
105
105
  *
106
106
  * Probe each provider on its own, never a fallback chain: the shape is a fact
@@ -117,8 +117,8 @@ async function callsTool(
117
117
  * report "this model cannot call tools", which is a much worse thing to
118
118
  * believe than "the call failed".
119
119
  *
120
- * What it catches is the structural failure — the model that CANNOT emit the
121
- * call, every time, on the easiest question there is. A model that is merely
120
+ * It catches a structural failure: a model that cannot emit the call, every
121
+ * time, on the easiest question there is. A model that is merely
122
122
  * unreliable will pass: `gemini-3.8-flash` answers this probe 3/3 and a real
123
123
  * sales turn 3/10. That is the right line to draw. A harder probe would start
124
124
  * failing good models for being terse, and "sometimes forgets its tools" is a
@@ -226,8 +226,8 @@ function normalizeId(id: string): string {
226
226
  * - `deepseek/deepseek-v4.1-flash` matches `deepseek-v4.1-flash`
227
227
  * - `accounts/fireworks/models/glm-5p3-flash` matches `glm-5.3-flash`
228
228
  *
229
- * Never throws — if the catalog cannot be retrieved or the model is unknown,
230
- * returns `undefined` so capability lookups never break caller execution.
229
+ * Never throws. If the catalog cannot be retrieved or the model is unknown,
230
+ * it returns `undefined` so capability lookups never break caller execution.
231
231
  */
232
232
  export async function resolveModelCapabilities(
233
233
  modelId: string,
package/src/context.ts CHANGED
@@ -9,13 +9,13 @@ import type { ChatMessage } from "./types.ts";
9
9
  * What the answer needs after the prompt: an output budget, plus the tools'
10
10
  * own schemas, plus the slack no provider documents.
11
11
  *
12
- * Absolute rather than a percentage on purpose — a 1M window does not need a
12
+ * Absolute rather than a percentage on purpose: a 1M window does not need a
13
13
  * 100k cushion, and a 128k window needs more than 12k.
14
14
  */
15
15
  export const CONTEXT_RESERVE_TOKENS = 32_000;
16
16
 
17
17
  /**
18
- * Four characters per token — the rule of thumb every provider's own
18
+ * Four characters per token is the rule of thumb every provider's own
19
19
  * calculator agrees with to within a fifth, which is all the precision this
20
20
  * needs. It decides WHEN to fold: folding one turn early costs a cheap model
21
21
  * call, folding one turn late costs the whole turn.
@@ -64,7 +64,7 @@ export function conversationTokens(messages: readonly ChatMessage[]): number {
64
64
  }
65
65
 
66
66
  /**
67
- * The provider's own input count says the wall is close — fold before the next
67
+ * The provider's own input count says the limit is close. Fold before the next
68
68
  * step rather than after the 400.
69
69
  *
70
70
  * Takes the REPORTED count, not an estimate, because it is the only figure
@@ -99,7 +99,7 @@ export function historyBudgetTokens(contextWindow: number): number {
99
99
  *
100
100
  * 1. Never split a tool call from its result. Every provider rejects a tool
101
101
  * result whose call is missing, so a cut landing between them produces a
102
- * 400 on the very next turn — the failure compaction was called to avoid.
102
+ * 400 on the very next turn, the failure compaction was called to avoid.
103
103
  * 2. Never cut into the system prompt. It is not history.
104
104
  *
105
105
  * Returns the index the kept tail starts at, or 0 when everything already fits.
package/src/errors.ts CHANGED
@@ -15,7 +15,7 @@ import type { FilePart } from "./types.ts";
15
15
 
16
16
  /** What kind of failure this is, named by what actually fixes it. */
17
17
  export type ErrorKind =
18
- /** Our own cancel — the caller pressed Stop. Never retried. */
18
+ /** Our own cancel: the caller pressed Stop. Never retried. */
19
19
  | "aborted"
20
20
  /** Our own deadline, or the provider's 408. Retry. */
21
21
  | "timeout"
@@ -24,13 +24,13 @@ export type ErrorKind =
24
24
  /** Theirs, and temporary: 5xx, Anthropic's 529, "overloaded". Retry, and
25
25
  * worth trying a different model. */
26
26
  | "overload"
27
- /** 429 per-minute throttle. Wait — or rotate to another key or model. */
27
+ /** 429 per-minute throttle. Wait, or rotate to another key or model. */
28
28
  | "rate"
29
29
  /** Balance or usage window exhausted. Waiting minutes will not fix it. */
30
30
  | "quota"
31
31
  /** The plan never included this API. Neither a new key nor a top-up fixes it. */
32
32
  | "entitlement"
33
- /** 401/403 — the key is wrong, not the request. */
33
+ /** 401/403: the key is wrong, not the request. */
34
34
  | "auth"
35
35
  /** The model id does not exist or is not served here. */
36
36
  | "model"
@@ -38,7 +38,7 @@ export type ErrorKind =
38
38
  | "context"
39
39
  /** Safety filter or refusal. */
40
40
  | "content"
41
- /** Any other 4xx — a bug in what we sent. */
41
+ /** Any other 4xx: a bug in what we sent. */
42
42
  | "invalid"
43
43
  | "unknown";
44
44
 
@@ -81,7 +81,7 @@ export function isBackupEligible(kind: ErrorKind): boolean {
81
81
  * 1. Caller aborts are never retryable.
82
82
  * 2. An explicit `shouldRetry` directive on ProviderError (e.g. from server `x-should-retry`)
83
83
  * 3. Non-retryable kinds (quota, context, model, entitlement, content, invalid) return false.
84
- * 4. Excessive retry-after waits (exceeding `maxWaitMs`) return false — long waits belong to fallbacks.
84
+ * 4. Excessive retry-after waits (exceeding `maxWaitMs`) return false. Long waits belong to fallbacks.
85
85
  * 5. Transient kinds (rate, overload, network, timeout) return true.
86
86
  * 6. Transport-level network faults (fetch failed, connection lost, SSL blips) return true.
87
87
  */
@@ -115,7 +115,7 @@ export class ProviderError extends Error {
115
115
  readonly window?: RateLimitWindow;
116
116
  /** Explicit server directive (`x-should-retry`), overriding default classification. */
117
117
  readonly shouldRetry?: boolean;
118
- /** The provider's own response body, truncated — the actual reason, which is
118
+ /** The provider's own response body, truncated. It carries the actual reason,
119
119
  * otherwise lost behind "400 status code (no body)". */
120
120
  readonly body?: string;
121
121
 
@@ -213,7 +213,7 @@ export function messageOf(err: unknown): string {
213
213
  * Everything readable about the failure as one searchable string: the message
214
214
  * plus the parsed provider body. SDKs park the parsed body on `.error`, and
215
215
  * that is where the real reason lives ("max_tokens too large", the quotaId,
216
- * `"type": "billing_error"`). Scanned as TEXT — the error-type strings
216
+ * `"type": "billing_error"`). Scanned as text: the error-type strings
217
217
  * serialize into it, so no JSON walking is needed.
218
218
  */
219
219
  function bodyTextOf(err: unknown): string {
@@ -293,7 +293,7 @@ function isAbort(err: unknown): boolean {
293
293
  * A transport fault: the socket died before or during the response, so there
294
294
  * is NO status and no body for the patterns below to read.
295
295
  *
296
- * The chain is walked because the useful code is rarely on the thrown error —
296
+ * The chain is walked because the useful code is rarely on the thrown error:
297
297
  * it sits on `cause`, sometimes several wrappers deep. Without this walk every
298
298
  * network blip classifies as permanent, and a long run dies on its first
299
299
  * hiccup, which is the single likeliest way to lose a minutes-long job.
@@ -455,7 +455,7 @@ const CONTENT_PATTERNS: readonly RegExp[] = [
455
455
  * A throttle said in words rather than in a 429.
456
456
  *
457
457
  * Every other kind has body evidence; rate had only the status, which is
458
- * exactly the evidence an in-band failure lacks — an SSE response is already
458
+ * exactly the evidence an in-band failure lacks. An SSE response is already
459
459
  * 200 when the throttle lands, so the reason arrives as a payload with no
460
460
  * status line at all. Checked below the status branches, so it only ever
461
461
  * catches what would otherwise fall through to "unknown".
@@ -501,18 +501,18 @@ const matches = (patterns: readonly RegExp[], text: string): boolean =>
501
501
  * The kind of failure, from whatever was thrown.
502
502
  *
503
503
  * Body patterns outrank status for the 4xx family; within them, context beats
504
- * entitlement beats quota beats auth — each earlier category's fix is useless
504
+ * entitlement beats quota beats auth. Each earlier category's fix is useless
505
505
  * for the later ones.
506
506
  */
507
507
  /**
508
- * The kind of a failure that arrived as an HTTP response — a status and a body,
508
+ * The kind of a failure that arrived as an HTTP response: a status and a body,
509
509
  * with nothing thrown.
510
510
  *
511
511
  * `classify` below is for a caught error, and it reads `status` and the body
512
512
  * text off that error when they are not passed separately. A response has no
513
513
  * error object, so callers were inventing one to fill the slot: a bare body
514
514
  * string, the same text twice, a `{ status, error }` literal. All three are
515
- * inert — nothing on them can satisfy `isAbort` or `isTransportFailure` — so
515
+ * inert (nothing on them can satisfy `isAbort` or `isTransportFailure`), so
516
516
  * they were three spellings of `undefined`.
517
517
  */
518
518
  export function classifyHttp(status: number | undefined, body: string): ErrorKind {
@@ -568,7 +568,7 @@ export function classify(err: unknown, status?: number, body?: string): ErrorKin
568
568
  /**
569
569
  * How long the provider asked us to wait, in ms. Two dialects: Gemini's
570
570
  * RetryInfo (`"retryDelay": "52s"`, inside the body) and the `Retry-After`
571
- * header, which SDKs keep on the error. Honouring it beats guessing — a
571
+ * header, which SDKs keep on the error. Honouring it beats guessing: a
572
572
  * backoff shorter than the window just burns an attempt.
573
573
  */
574
574
  export function parseRetryAfterMs(err: unknown, body?: string): number | undefined {
@@ -664,14 +664,14 @@ export function parseContextOverflow(err: unknown, body?: string): ContextOverfl
664
664
  * completion: retry sees nothing to retry, and a key pool never rotates off an
665
665
  * exhausted key.
666
666
  *
667
- * `error` is the vendor's own payload, whatever shape it came in — the numeric
667
+ * `error` is the vendor's own payload, whatever shape it came in: the numeric
668
668
  * HTTP `code` Gemini and OpenRouter use, the slug OpenAI and Anthropic put in
669
669
  * `code`/`type`, the canonical `status` name. The whole thing serializes into
670
670
  * the searchable body, so RetryInfo's `retryDelay` is honoured wherever it sits.
671
671
  *
672
672
  * `unknown` is floored to "overload" rather than kept: a stream that dies after
673
673
  * its headers is by construction a transient upstream fault, and "unknown" is
674
- * never retried. Everything the body DOES name keeps its own kind — which is
674
+ * never retried. Everything the body does name keeps its own kind, which is
675
675
  * what tells the caller to wait, rotate a key, or compact instead of retrying
676
676
  * a failure that will repeat.
677
677
  */
@@ -697,7 +697,7 @@ export function streamError(provider: string, error: unknown): ProviderError {
697
697
  }
698
698
 
699
699
  /** The reset a stream error carries: the body's clock, plus the rate-limit
700
- * headers the ChatGPT backend mirrors INTO its error frame — the only place a
700
+ * headers the ChatGPT backend mirrors into its error frame, the only place a
701
701
  * failure after the 200 can say which window ran out. */
702
702
  function readReset(error: unknown, body: string) {
703
703
  const raw =
@@ -720,7 +720,7 @@ function readReset(error: unknown, body: string) {
720
720
  * read it: a caller that never checks the finish keeps half an answer as if it
721
721
  * were the whole one, the ledger records a billed turn as free, and no pool
722
722
  * learns the endpoint is dropping streams. cc-proxy shipped the same fix
723
- * (0.1.39) for the same reason — "instead of marking affected streamed
723
+ * (0.1.39) for the same reason: "instead of marking affected streamed
724
724
  * responses as successful".
725
725
  *
726
726
  * `network`, because that is what it is: the same failure as a socket that
@@ -736,7 +736,7 @@ export function streamCut(provider: string): ProviderError {
736
736
  );
737
737
  }
738
738
 
739
- /** The loggable surface of a failure — so a dead run never reads
739
+ /** The failure details you can log, so a dead run never reads
740
740
  * "400 status code (no body)". */
741
741
  export function describeProviderError(err: unknown): Record<string, unknown> {
742
742
  if (err instanceof ProviderError) {
package/src/image.ts CHANGED
@@ -16,7 +16,7 @@ export interface ImageLimits {
16
16
  minSide: number;
17
17
  /** Smallest area, in square pixels. */
18
18
  minArea: number;
19
- /** Largest decoded size — width × height × bytes per pixel — in bytes. */
19
+ /** Largest decoded size in bytes (width × height × bytes per pixel). */
20
20
  maxDecodedBytes: number;
21
21
  /** Most images in one request. The newest win; older ones become notes. */
22
22
  maxImages: number;