llm-retry-kit 0.2.1 → 0.3.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/README.md CHANGED
@@ -9,8 +9,9 @@
9
9
 
10
10
  Small resilience layer for production LLM calls. `llm-retry-kit` gives you
11
11
  provider-aware retries, fallback chains, jittered exponential backoff,
12
- `Retry-After` handling, budget tracking, cancellation, timeouts, and
13
- observability hooks without runtime dependencies.
12
+ `Retry-After` handling, streaming retries, circuit breakers, hedged requests,
13
+ budget tracking, cancellation, timeouts, and observability hooks without
14
+ runtime dependencies.
14
15
 
15
16
  ```bash
16
17
  npm install llm-retry-kit
@@ -42,6 +43,12 @@ and `llm-retry-kit` manages the reliability policy around it.
42
43
  `shouldFallback`.
43
44
  - Track token usage and estimated cost.
44
45
  - Use custom input/output token pricing through `costCalculator`.
46
+ - Wrap streaming responses with retry-before-first-chunk safety.
47
+ - Track partial stream token usage from provider events.
48
+ - Skip unhealthy providers with `CircuitBreaker`.
49
+ - Set timeout budgets per provider/model.
50
+ - Start hedged requests to reduce tail latency.
51
+ - Pass request `meta` and `payload` through every context for logging.
45
52
  - Abort long calls and retry sleeps with `AbortSignal` or `timeoutMs`.
46
53
  - Observe attempts, retries, success, failure, and budget events.
47
54
  - Strict TypeScript types.
@@ -169,6 +176,136 @@ console.log({
169
176
  })
170
177
  ```
171
178
 
179
+ ## Streaming
180
+
181
+ OpenAI and Anthropic both expose streaming APIs, but their event formats and
182
+ resume behavior are provider-specific. `llm-retry-kit` therefore keeps the
183
+ stream wrapper provider-agnostic and conservative:
184
+
185
+ - By default, it retries only if the stream fails before the first chunk.
186
+ - After a chunk has been yielded, retrying could duplicate output, so it stops
187
+ unless you explicitly set `retryMode: 'always'`.
188
+ - Token usage can be tracked from stream events with `getChunkUsage`.
189
+ - Use `chunkUsageMode: 'cumulative'` for providers that send cumulative usage
190
+ snapshots during a stream.
191
+
192
+ ```ts
193
+ import { llmRetryStream } from 'llm-retry-kit'
194
+
195
+ const result = llmRetryStream({
196
+ stream: async ({ signal }) => {
197
+ const stream = await openai.responses.create({
198
+ model: 'gpt-4o-mini',
199
+ input: 'Write a short incident summary.',
200
+ stream: true,
201
+ }, { signal })
202
+
203
+ return stream
204
+ },
205
+ retryMode: 'before-first-chunk',
206
+ getChunkUsage: (event) => {
207
+ if (!('usage' in event) || !event.usage) return undefined
208
+
209
+ return {
210
+ promptTokens: event.usage.input_tokens ?? 0,
211
+ completionTokens: event.usage.output_tokens ?? 0,
212
+ totalTokens: event.usage.total_tokens ?? 0,
213
+ }
214
+ },
215
+ chunkUsageMode: 'cumulative',
216
+ })
217
+
218
+ for await (const event of result.stream) {
219
+ // Send provider events to your UI, parser, or SSE response.
220
+ }
221
+
222
+ console.log(result.getStats())
223
+ ```
224
+
225
+ ## Advanced Production Controls
226
+
227
+ ### Circuit Breaker
228
+
229
+ Keep one `CircuitBreaker` instance per provider/model at application scope. If
230
+ the failure threshold is reached inside the time window, later calls skip that
231
+ provider until the cooldown expires.
232
+
233
+ ```ts
234
+ import { CircuitBreaker, llmRetry } from 'llm-retry-kit'
235
+
236
+ const openaiBreaker = new CircuitBreaker({
237
+ failureThreshold: 5,
238
+ windowMs: 60_000,
239
+ cooldownMs: 120_000,
240
+ })
241
+
242
+ await llmRetry({
243
+ providers: [
244
+ {
245
+ name: 'openai:gpt-4o-mini',
246
+ fn: callOpenAI,
247
+ circuitBreaker: openaiBreaker,
248
+ },
249
+ {
250
+ name: 'anthropic:claude-sonnet',
251
+ fn: callAnthropic,
252
+ },
253
+ ],
254
+ })
255
+ ```
256
+
257
+ ### Per-Provider Timeout
258
+
259
+ Use global `timeoutMs` for the whole workflow and provider `timeoutMs` for a
260
+ single attempt.
261
+
262
+ ```ts
263
+ await llmRetry({
264
+ providers: [
265
+ { name: 'openai:fast', fn: callOpenAI, timeoutMs: 3_000, maxRetries: 1 },
266
+ { name: 'anthropic:steady', fn: callAnthropic, timeoutMs: 10_000 },
267
+ ],
268
+ timeoutMs: 30_000,
269
+ })
270
+ ```
271
+
272
+ ### Hedged Requests
273
+
274
+ Hedging starts the next provider in parallel if the current provider has not
275
+ answered after `hedgeDelayMs`. The first successful response wins and the
276
+ slower request is aborted through the context signal.
277
+
278
+ ```ts
279
+ await llmRetry({
280
+ providers: [
281
+ { name: 'primary', fn: callPrimary },
282
+ { name: 'hedge', fn: callBackup },
283
+ ],
284
+ hedgeDelayMs: 750,
285
+ })
286
+ ```
287
+
288
+ Hedging is best for latency-sensitive read paths. It can increase provider
289
+ traffic, so pair it with budget tracking and conservative delay values.
290
+
291
+ ### Metadata And Payload Tracking
292
+
293
+ Attach request metadata once and it flows into provider calls and hooks.
294
+
295
+ ```ts
296
+ await llmRetry({
297
+ fn: callModel,
298
+ meta: { requestId: 'req_123', tenant: 'acme' },
299
+ payload: { prompt: 'Classify this ticket', userId: 'user_42' },
300
+ onAttempt: (context) => {
301
+ console.log(context.meta, context.payload)
302
+ },
303
+ onFailure: (error, context) => {
304
+ console.error(context.meta, error)
305
+ },
306
+ })
307
+ ```
308
+
172
309
  ## Simple Fallback API
173
310
 
174
311
  For smaller apps, `fn` plus `fallback` is still supported.
@@ -298,8 +435,8 @@ await llmRetry({
298
435
  onSuccess: (context) => {
299
436
  console.log(`Cost so far: $${context.totalCostUSD}`)
300
437
  },
301
- onFailure: (error) => {
302
- console.error(error)
438
+ onFailure: (error, context) => {
439
+ console.error(context.meta, error)
303
440
  },
304
441
  })
305
442
  ```
@@ -320,13 +457,16 @@ await llmRetry({
320
457
  | `initialDelayMs` | `number` | `1000` | Initial retry delay. |
321
458
  | `maxDelayMs` | `number` | `30000` | Maximum retry delay. |
322
459
  | `timeoutMs` | `number` | optional | Abort wrapper after this time. |
460
+ | `hedgeDelayMs` | `number` | optional | Start the next provider after this delay if the current provider is still pending. |
323
461
  | `signal` | `AbortSignal` | optional | External cancellation signal. |
462
+ | `meta` | `unknown` | optional | User metadata copied into attempt/failure contexts. |
463
+ | `payload` | `unknown` | optional | Request payload copied into attempt/failure contexts. |
324
464
  | `shouldRetry` | `(error, context) => boolean \| Promise<boolean>` | optional | Override retry decisions. |
325
465
  | `shouldFallback` | `(error, context) => boolean \| Promise<boolean>` | optional | Override provider fallback decisions. |
326
466
  | `onAttempt` | `(context) => void` | optional | Called before each attempt. |
327
467
  | `onRetry` | `(attempt, error, delayMs, context) => void` | optional | Called before retry wait. |
328
468
  | `onSuccess` | `(context) => void` | optional | Called after a successful response. |
329
- | `onFailure` | `(error) => void` | optional | Called before final failure is thrown. |
469
+ | `onFailure` | `(error, context) => void` | optional | Called before final failure is thrown. |
330
470
  | `onBudgetExceeded` | `(spentUSD, limitUSD) => void` | optional | Called when budget is exhausted. |
331
471
 
332
472
  ### `RetryProvider<T>`
@@ -336,11 +476,45 @@ await llmRetry({
336
476
  name: string
337
477
  fn: (context: RetryAttemptContext) => Promise<LLMResponse<T>>
338
478
  maxRetries?: number
479
+ timeoutMs?: number
480
+ hedgeDelayMs?: number
481
+ circuitBreaker?: CircuitBreaker | CircuitBreakerOptions
339
482
  costPer1kTokens?: number
340
483
  costCalculator?: (usage, context) => number
341
484
  }
342
485
  ```
343
486
 
487
+ ### `llmRetryStream(options)`
488
+
489
+ Returns `{ stream, getStats }`. The request begins when the returned async
490
+ iterable is consumed.
491
+
492
+ | Option | Type | Default | Description |
493
+ | --- | --- | --- | --- |
494
+ | `stream` | `(context) => AsyncIterable<TChunk> \| Promise<AsyncIterable<TChunk>>` | optional | Primary stream call for the simple API. |
495
+ | `fallbackStream` | `(context) => AsyncIterable<TChunk> \| Promise<AsyncIterable<TChunk>>` | optional | Backup stream call. |
496
+ | `providers` | `StreamRetryProvider<TChunk>[]` | optional | Explicit stream provider chain. |
497
+ | `retryMode` | `'before-first-chunk' \| 'always' \| 'never'` | `'before-first-chunk'` | Controls whether interrupted streams are retried. |
498
+ | `getChunkUsage` | `(chunk, context) => TokenUsage \| undefined` | optional | Extract token usage from stream chunks/events. |
499
+ | `chunkUsageMode` | `'delta' \| 'cumulative'` | `'delta'` | Interpret chunk usage as incremental or cumulative. |
500
+ | `maxRetries` | `number` | `3` | Retries after the first attempt. |
501
+ | `timeoutMs` | `number` | optional | Abort the whole stream workflow after this time. |
502
+ | `meta` | `unknown` | optional | User metadata copied into contexts. |
503
+ | `payload` | `unknown` | optional | Request payload copied into contexts. |
504
+
505
+ ### `CircuitBreaker`
506
+
507
+ ```ts
508
+ new CircuitBreaker({
509
+ failureThreshold: 5,
510
+ windowMs: 60_000,
511
+ cooldownMs: 120_000,
512
+ })
513
+ ```
514
+
515
+ `snapshot()` returns `{ state, failures, openedAt }`, where state is
516
+ `'closed'`, `'open'`, or `'half_open'`.
517
+
344
518
  ### `RetryResult<T>`
345
519
 
346
520
  ```ts
@@ -377,6 +551,7 @@ await llmRetry({
377
551
  | `initialDelayMs` | `1000` |
378
552
  | `maxDelayMs` | `30000` |
379
553
  | `costPer1kTokens` | `0.002` |
554
+ | stream retry mode | `before-first-chunk` |
380
555
  | fallback on client errors | `false` |
381
556
  | fallback on transient errors | `true` |
382
557
  | runtime dependencies | none |
@@ -0,0 +1,17 @@
1
+ import type { CircuitBreakerOptions, CircuitBreakerSnapshot } from './types.js';
2
+ export declare class CircuitBreaker {
3
+ private readonly options;
4
+ private failureTimestamps;
5
+ private state;
6
+ private openedAt;
7
+ constructor(options: CircuitBreakerOptions);
8
+ canRequest(): boolean;
9
+ recordSuccess(): void;
10
+ recordFailure(): void;
11
+ snapshot(): CircuitBreakerSnapshot;
12
+ }
13
+ export declare class CircuitBreakerOpenError extends Error {
14
+ readonly provider: string;
15
+ constructor(provider: string);
16
+ }
17
+ //# sourceMappingURL=circuit-breaker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../src/circuit-breaker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EAEvB,MAAM,YAAY,CAAA;AAEnB,qBAAa,cAAc;IAKb,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,OAAO,CAAC,iBAAiB,CAAe;IACxC,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,QAAQ,CAAsB;gBAET,OAAO,EAAE,qBAAqB;IAI3D,UAAU,IAAI,OAAO;IAcrB,aAAa,IAAI,IAAI;IAMrB,aAAa,IAAI,IAAI;IAiBrB,QAAQ,IAAI,sBAAsB;CAOnC;AAED,qBAAa,uBAAwB,SAAQ,KAAK;aACpB,QAAQ,EAAE,MAAM;gBAAhB,QAAQ,EAAE,MAAM;CAI7C"}
@@ -0,0 +1,63 @@
1
+ export class CircuitBreaker {
2
+ options;
3
+ failureTimestamps = [];
4
+ state = 'closed';
5
+ openedAt = null;
6
+ constructor(options) {
7
+ this.options = options;
8
+ validateCircuitBreakerOptions(options);
9
+ }
10
+ canRequest() {
11
+ if (this.state !== 'open') {
12
+ return true;
13
+ }
14
+ const openedAt = this.openedAt ?? 0;
15
+ if (Date.now() - openedAt >= this.options.cooldownMs) {
16
+ this.state = 'half_open';
17
+ return true;
18
+ }
19
+ return false;
20
+ }
21
+ recordSuccess() {
22
+ this.failureTimestamps = [];
23
+ this.state = 'closed';
24
+ this.openedAt = null;
25
+ }
26
+ recordFailure() {
27
+ const now = Date.now();
28
+ const windowStart = now - this.options.windowMs;
29
+ this.failureTimestamps = [...this.failureTimestamps, now].filter((timestamp) => timestamp >= windowStart);
30
+ if (this.state === 'half_open' ||
31
+ this.failureTimestamps.length >= this.options.failureThreshold) {
32
+ this.state = 'open';
33
+ this.openedAt = now;
34
+ }
35
+ }
36
+ snapshot() {
37
+ return {
38
+ state: this.state,
39
+ failures: this.failureTimestamps.length,
40
+ openedAt: this.openedAt,
41
+ };
42
+ }
43
+ }
44
+ export class CircuitBreakerOpenError extends Error {
45
+ provider;
46
+ constructor(provider) {
47
+ super(`Circuit breaker is open for provider "${provider}"`);
48
+ this.provider = provider;
49
+ this.name = 'CircuitBreakerOpenError';
50
+ }
51
+ }
52
+ function validateCircuitBreakerOptions(options) {
53
+ if (!Number.isInteger(options.failureThreshold) || options.failureThreshold <= 0) {
54
+ throw new Error('failureThreshold must be a positive integer');
55
+ }
56
+ if (options.windowMs < 0) {
57
+ throw new Error('windowMs must be greater than or equal to 0');
58
+ }
59
+ if (options.cooldownMs < 0) {
60
+ throw new Error('cooldownMs must be greater than or equal to 0');
61
+ }
62
+ }
63
+ //# sourceMappingURL=circuit-breaker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../src/circuit-breaker.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,cAAc;IAKI;IAJrB,iBAAiB,GAAa,EAAE,CAAA;IAChC,KAAK,GAAwB,QAAQ,CAAA;IACrC,QAAQ,GAAkB,IAAI,CAAA;IAEtC,YAA6B,OAA8B;QAA9B,YAAO,GAAP,OAAO,CAAuB;QACzD,6BAA6B,CAAC,OAAO,CAAC,CAAA;IACxC,CAAC;IAED,UAAU;QACR,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAA;QACb,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAA;QACnC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YACrD,IAAI,CAAC,KAAK,GAAG,WAAW,CAAA;YACxB,OAAO,IAAI,CAAA;QACb,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC;IAED,aAAa;QACX,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAA;QAC3B,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAA;QACrB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;IACtB,CAAC;IAED,aAAa;QACX,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,WAAW,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAA;QAE/C,IAAI,CAAC,iBAAiB,GAAG,CAAC,GAAG,IAAI,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC,MAAM,CAC9D,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,IAAI,WAAW,CACxC,CAAA;QAED,IACE,IAAI,CAAC,KAAK,KAAK,WAAW;YAC1B,IAAI,CAAC,iBAAiB,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAC9D,CAAC;YACD,IAAI,CAAC,KAAK,GAAG,MAAM,CAAA;YACnB,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAA;QACrB,CAAC;IACH,CAAC;IAED,QAAQ;QACN,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,IAAI,CAAC,iBAAiB,CAAC,MAAM;YACvC,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAA;IACH,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IACpB;IAA5B,YAA4B,QAAgB;QAC1C,KAAK,CAAC,yCAAyC,QAAQ,GAAG,CAAC,CAAA;QADjC,aAAQ,GAAR,QAAQ,CAAQ;QAE1C,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAA;IACvC,CAAC;CACF;AAED,SAAS,6BAA6B,CAAC,OAA8B;IACnE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,OAAO,CAAC,gBAAgB,IAAI,CAAC,EAAE,CAAC;QACjF,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;IAChE,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;IAChE,CAAC;IAED,IAAI,OAAO,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;IAClE,CAAC;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
- export { BudgetExceededError, llmRetry, LLMRetryError } from './retry.js';
1
+ export { CircuitBreaker, CircuitBreakerOpenError } from './circuit-breaker.js';
2
+ export { BudgetExceededError, llmRetry, LLMRetryError, ProviderTimeoutError } from './retry.js';
3
+ export { llmRetryStream } from './stream.js';
2
4
  export { BudgetTracker } from './budget.js';
3
5
  export { calculateBackoff, extractRetryAfter, isRetryableError } from './backoff.js';
4
- export type { CostCalculator, FallbackDecisionContext, LLMCall, LLMResponse, RetryAttemptContext, RetryDecisionContext, RetryOptions, RetryProvider, RetryResult, RetrySuccessContext, RetryableError, ShouldFallback, ShouldRetry, TokenUsage, } from './types.js';
6
+ export type { CircuitBreakerLike, CircuitBreakerOptions, CircuitBreakerSnapshot, CircuitBreakerState, CostCalculator, FallbackDecisionContext, LLMCall, LLMResponse, RetryAttemptContext, RetryDecisionContext, RetryFailureContext, RetryOptions, RetryProvider, RetryResult, RetrySuccessContext, RetryableError, ShouldFallback, ShouldRetry, StreamLLMCall, StreamRetryMode, StreamRetryOptions, StreamRetryProvider, StreamRetryResult, StreamRetryStats, StreamUsageExtractor, StreamUsageMode, TokenUsage, } from './types.js';
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACpF,YAAY,EACV,cAAc,EACd,uBAAuB,EACvB,OAAO,EACP,WAAW,EACX,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,WAAW,EACX,UAAU,GACX,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAC/F,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACpF,YAAY,EACV,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,uBAAuB,EACvB,OAAO,EACP,WAAW,EACX,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,WAAW,EACX,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,UAAU,GACX,MAAM,YAAY,CAAA"}
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
- export { BudgetExceededError, llmRetry, LLMRetryError } from './retry.js';
1
+ export { CircuitBreaker, CircuitBreakerOpenError } from './circuit-breaker.js';
2
+ export { BudgetExceededError, llmRetry, LLMRetryError, ProviderTimeoutError } from './retry.js';
3
+ export { llmRetryStream } from './stream.js';
2
4
  export { BudgetTracker } from './budget.js';
3
5
  export { calculateBackoff, extractRetryAfter, isRetryableError } from './backoff.js';
4
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAC/F,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA"}
package/dist/retry.d.ts CHANGED
@@ -15,4 +15,8 @@ export declare class BudgetExceededError extends Error {
15
15
  readonly limitUSD: number | null;
16
16
  constructor(spentUSD: number, limitUSD: number | null);
17
17
  }
18
+ export declare class ProviderTimeoutError extends Error {
19
+ readonly timeoutMs: number;
20
+ constructor(timeoutMs: number);
21
+ }
18
22
  //# sourceMappingURL=retry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAMV,YAAY,EAEZ,WAAW,EAGZ,MAAM,YAAY,CAAA;AAEnB,wBAAsB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAyKnF;AAyMD,qBAAa,aAAc,SAAQ,KAAK;aAGpB,YAAY,EAAE,KAAK,GAAG,IAAI;aAC1B,aAAa,EAAE,KAAK,GAAG,IAAI;aAC3B,YAAY,EAAE,MAAM;aACpB,WAAW,EAAE,MAAM;aACnB,QAAQ;aACR,SAAS,EAAE,MAAM,EAAE;aACnB,MAAM,EAAE,SAAS,GAAG,iBAAiB,GAAG,SAAS;gBAPjE,OAAO,EAAE,MAAM,EACC,YAAY,EAAE,KAAK,GAAG,IAAI,EAC1B,aAAa,EAAE,KAAK,GAAG,IAAI,EAC3B,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,QAAQ,SAAI,EACZ,SAAS,GAAE,MAAM,EAAO,EACxB,MAAM,GAAE,SAAS,GAAG,iBAAiB,GAAG,SAAqB;CAKhF;AAED,qBAAa,mBAAoB,SAAQ,KAAK;aAE1B,QAAQ,EAAE,MAAM;aAChB,QAAQ,EAAE,MAAM,GAAG,IAAI;gBADvB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GAAG,IAAI;CAM1C"}
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAOV,YAAY,EAEZ,WAAW,EAGZ,MAAM,YAAY,CAAA;AAMnB,wBAAsB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CA+NnF;AAmZD,qBAAa,aAAc,SAAQ,KAAK;aAGpB,YAAY,EAAE,KAAK,GAAG,IAAI;aAC1B,aAAa,EAAE,KAAK,GAAG,IAAI;aAC3B,YAAY,EAAE,MAAM;aACpB,WAAW,EAAE,MAAM;aACnB,QAAQ;aACR,SAAS,EAAE,MAAM,EAAE;aACnB,MAAM,EAAE,SAAS,GAAG,iBAAiB,GAAG,SAAS;gBAPjE,OAAO,EAAE,MAAM,EACC,YAAY,EAAE,KAAK,GAAG,IAAI,EAC1B,aAAa,EAAE,KAAK,GAAG,IAAI,EAC3B,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,QAAQ,SAAI,EACZ,SAAS,GAAE,MAAM,EAAO,EACxB,MAAM,GAAE,SAAS,GAAG,iBAAiB,GAAG,SAAqB;CAKhF;AAED,qBAAa,mBAAoB,SAAQ,KAAK;aAE1B,QAAQ,EAAE,MAAM;aAChB,QAAQ,EAAE,MAAM,GAAG,IAAI;gBADvB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GAAG,IAAI;CAM1C;AAED,qBAAa,oBAAqB,SAAQ,KAAK;aACjB,SAAS,EAAE,MAAM;gBAAjB,SAAS,EAAE,MAAM;CAI9C"}