@providerkit/core 0.21.0 → 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 +14 -13
  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 +22 -17
  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/src/usage.ts CHANGED
@@ -15,14 +15,14 @@
15
15
  import type { TokenUsage } from "./types.ts";
16
16
  import { EMPTY_USAGE } from "./types.ts";
17
17
 
18
- /** USD per MILLION tokens — how every vendor prints its price sheet, so a row
18
+ /** USD per million tokens, as every vendor prints its price sheet, so a row
19
19
  * can be checked against one without arithmetic. */
20
20
  export interface ModelRate {
21
21
  /** Cache-MISS input: fresh tokens the provider had to read. */
22
22
  input: number;
23
23
  output: number;
24
24
  /** Cache-HIT input. Providers auto-cache repeated prefixes and bill the hit
25
- * portion far cheaper — 0.1× on Anthropic, ~0.1× on Gemini, 0.5× on some
25
+ * portion far cheaper: 0.1× on Anthropic, ~0.1× on Gemini, 0.5× on some
26
26
  * OpenAI models. In an agent loop the re-sent context is overwhelmingly
27
27
  * hits, so billing it at the miss rate overcounts by up to 10×. */
28
28
  cacheRead: number;
@@ -95,14 +95,14 @@ export function costUsd(usage: TokenUsage, rate: ModelRate): number {
95
95
  }
96
96
 
97
97
  /** What one call adds to a run: its reported cost, else its rate, else
98
- * nothing — an unpriced call still counts its tokens. */
98
+ * nothing. An unpriced call still counts its tokens. */
99
99
  function callCost(usage: TokenUsage, rate: ModelRate | undefined): number {
100
100
  return rate ? costUsd(usage, rate) : (usage.reportedCostUsd ?? 0);
101
101
  }
102
102
 
103
103
  /**
104
104
  * Accumulates usage and cost across the calls of one run, pricing each with
105
- * the rate in effect for the model that served it — so a run that switches to
105
+ * the rate in effect for the model that served it, so a run that switches to
106
106
  * a backup model, or spans a time-of-day price boundary, still bills correctly.
107
107
  * A call that carries a reported cost is billed that, with or without a rate.
108
108
  */
@@ -110,7 +110,7 @@ export class UsageTracker {
110
110
  private usage: TokenUsage = { ...EMPTY_USAGE, cacheWriteTokens: 0 };
111
111
  private cost = 0;
112
112
  /** USD the cache hits saved, versus billing them all as misses.
113
- * Observability only — never billed. */
113
+ * Observability only. Never billed. */
114
114
  private saved = 0;
115
115
 
116
116
  add(usage: TokenUsage, rate?: ModelRate): void {
package/src/watchdog.ts CHANGED
@@ -42,7 +42,7 @@ import type {
42
42
  * stream is dead. */
43
43
  export const STREAM_IDLE_MS = 60_000;
44
44
 
45
- /** No chunk for this long — the wait for the response to start included —
45
+ /** No chunk for this long, including the wait for the response to start,
46
46
  * and the stream is going nowhere, keep-alives or not. */
47
47
  export const STREAM_PROGRESS_MS = 300_000;
48
48
 
@@ -51,17 +51,17 @@ export interface StreamWatch {
51
51
  readonly signal: AbortSignal;
52
52
  /** A chunk arrived: re-arm both deadlines, and mark TTFT if it was the first. */
53
53
  sawByte(): void;
54
- /** The response showed life without a chunk — its headers, a keep-alive, a
54
+ /** The response showed life without a chunk: its headers, a keep-alive, a
55
55
  * partial frame. Starts or re-arms the idle deadline only. */
56
56
  sawActivity(): void;
57
57
  /**
58
- * Milliseconds from the call opening to its first chunk of any kind — the
58
+ * Milliseconds from the call opening to its first chunk of any kind. The
59
59
  * wait a person actually experiences, and the number a prompt-cache pin
60
60
  * exists to shrink. Null until something arrives.
61
61
  */
62
62
  firstChunkMs(): number | null;
63
63
  /**
64
- * Re-issue a provider failure as the timeout when — and only when — it was
64
+ * Re-issue a provider failure as the timeout only when it was
65
65
  * one of our deadlines that aborted. A caller's Stop passes through untouched.
66
66
  */
67
67
  classify(err: unknown): unknown;
@@ -148,7 +148,7 @@ export function streamWatch(opts: StreamWatchOptions = {}): StreamWatch {
148
148
 
149
149
  /**
150
150
  * Wrap a stream so every chunk re-arms `watch`, and a failure is re-classified
151
- * through it. Disposes on any exit — completion, throw, or the consumer
151
+ * through it. Disposes on any exit: completion, throw, or the consumer
152
152
  * breaking out of the loop.
153
153
  */
154
154
  export async function* watchChunks<T>(
@@ -173,7 +173,7 @@ export async function* watchChunks<T>(
173
173
  * A stream that ends with no text and no tool call is a failure wearing a
174
174
  * success's clothes: `stop_reason: end_turn` with zero content blocks, which
175
175
  * the vendors emit under load, or a thinking block that ate the whole
176
- * `max_tokens`. Nothing throws, so nothing retries — the caller simply shows a
176
+ * `max_tokens`. Nothing throws, so nothing retries. The caller simply shows a
177
177
  * person an empty answer, and the only trace is a bill.
178
178
  *
179
179
  * Reasoning is not an answer. It still streams the moment it arrives, so a
@@ -185,12 +185,12 @@ export async function* watchChunks<T>(
185
185
  *
186
186
  * Classified by what fixes it. A `length` finish is the caller's own cap:
187
187
  * `invalid`, so nothing retries it into the same cap and no backup model is
188
- * cooled down for it — the fix is a larger `maxTokens` or a lower effort. Any
188
+ * cooled down for it. The fix is a larger `maxTokens` or a lower effort. Any
189
189
  * other empty turn is `overload`, because that is both true and useful: it is
190
190
  * theirs and temporary, so it is transient (the same model, retried, usually
191
191
  * answers) and backup-eligible (a model that keeps doing it should be walked
192
192
  * away from). Until something streams, the empty frames are held back, so the
193
- * retry rule that matters — retry only while nothing was emitted — still holds.
193
+ * retry rule still holds: retry only while nothing was emitted.
194
194
  */
195
195
  export async function* requireContent<T extends ProviderChunk>(
196
196
  provider: string,
@@ -240,7 +240,7 @@ export async function* requireContent<T extends ProviderChunk>(
240
240
  throw new ProviderError(
241
241
  provider,
242
242
  "invalid",
243
- `${provider}: the output cap ran out before any answer${spent} — raise maxTokens or lower effort`,
243
+ `${provider}: the output cap ran out before any answer${spent}. Raise maxTokens or lower effort.`,
244
244
  );
245
245
  }
246
246
  throw new ProviderError(provider, "overload", `${provider}: completed with no content`);
@@ -267,8 +267,8 @@ export interface WatchdogOptions {
267
267
  * A provider with both silent failures already handled.
268
268
  *
269
269
  * Every consumer of this package wrote the same three lines around every
270
- * `createStream` — build a watch, hand the provider the WATCH's signal, wrap
271
- * the chunks — and the middle one is the trap. Pass the caller's signal
270
+ * `createStream`: build a watch, hand the provider the watch's signal, wrap
271
+ * the chunks. The middle one is the trap. Pass the caller's signal
272
272
  * instead and everything still compiles, still streams, still passes the
273
273
  * tests: the watchdog simply never aborts anything, because the request it was
274
274
  * meant to cancel was never told about it. The failure has no symptom until
@@ -276,8 +276,8 @@ export interface WatchdogOptions {
276
276
  *
277
277
  * So the composition belongs here rather than in a docs snippet each app
278
278
  * copies. The result is still a `Provider`, so it composes unchanged with
279
- * `withStreamRetry` and `streamWithBackupModels` — and both of the failures it
280
- * catches are transient, which is what makes wrapping it in a retry correct.
279
+ * `withStreamRetry` and `streamWithBackupModels`. Timeouts and empty turns
280
+ * without a `length` finish are transient, so wrapping it in a retry is safe.
281
281
  */
282
282
  export function withWatchdog(provider: Provider, opts: WatchdogOptions = {}): Provider {
283
283
  return {
package/src/zod.ts CHANGED
@@ -12,8 +12,8 @@ import type { JsonObjectSchema } from "./types.ts";
12
12
  * A zod schema as the JSON Schema every provider's tool contract wants.
13
13
  *
14
14
  * `$schema` is dropped. zod emits the dialect URI at the root, and a provider
15
- * validating a tool's `parameters` against its own supported subset — OpenAI
16
- * under `strict: true`, Gemini's `parametersJsonSchema` — rejects the whole
15
+ * validating a tool's `parameters` against its own supported subset (OpenAI
16
+ * under `strict: true`, Gemini's `parametersJsonSchema`) rejects the whole
17
17
  * tool over that one key, with a message that names neither zod nor the field.
18
18
  */
19
19
  export function toJsonObjectSchema(schema: z.ZodType, label = "schema"): JsonObjectSchema {
@@ -46,14 +46,14 @@ export interface ZodToolSpec<I, O> {
46
46
  * rejecting the call. Worth it for a TERMINAL tool, which gets no second
47
47
  * chance: a forced-submit salvage turn runs exactly once, and discarding an
48
48
  * otherwise-valid answer over a few extra characters loses the whole run.
49
- * Off by default — an ordinary tool can simply be called again.
49
+ * Off by default: an ordinary tool can simply be called again.
50
50
  */
51
51
  clampOverflow?: boolean;
52
52
  }
53
53
 
54
54
  /**
55
55
  * A tool whose arguments are validated by zod, with the failure reported to
56
- * the MODEL in words it can act on — `topic: expected string, received number`
56
+ * the model in words it can act on. `topic: expected string, received number`
57
57
  * beats a stack trace it cannot read.
58
58
  */
59
59
  export function zodTool<I, O>(spec: ZodToolSpec<I, O>): Tool<I, O> {