llm-retry-kit 0.1.0 → 0.2.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
@@ -1,7 +1,8 @@
1
1
  # llm-retry-kit
2
2
 
3
- Smart retry wrapper for LLM APIs. It handles transient failures, rate limits,
4
- fallback calls, exponential backoff, and simple token-cost tracking.
3
+ Small resilience layer for production LLM calls. It gives you retries,
4
+ provider fallback, jittered exponential backoff, `Retry-After` handling,
5
+ budget tracking, cancellation, timeouts, and observability hooks.
5
6
 
6
7
  ## Install
7
8
 
@@ -18,11 +19,14 @@ import OpenAI from 'openai'
18
19
  const openai = new OpenAI()
19
20
 
20
21
  const result = await llmRetry({
21
- fn: async () => {
22
- const response = await openai.chat.completions.create({
23
- model: 'gpt-4o-mini',
24
- messages: [{ role: 'user', content: 'Hello!' }],
25
- })
22
+ fn: async ({ signal }) => {
23
+ const response = await openai.chat.completions.create(
24
+ {
25
+ model: 'gpt-4o-mini',
26
+ messages: [{ role: 'user', content: 'Hello!' }],
27
+ },
28
+ { signal }
29
+ )
26
30
 
27
31
  return {
28
32
  data: response.choices[0]?.message.content ?? '',
@@ -35,60 +39,122 @@ const result = await llmRetry({
35
39
  : undefined,
36
40
  }
37
41
  },
42
+ maxRetries: 3,
38
43
  })
39
44
 
40
45
  console.log(result.data)
41
- console.log(result.attempts)
46
+ console.log(result.provider)
42
47
  console.log(result.totalCostUSD)
43
48
  ```
44
49
 
45
- ## Fallback Example
50
+ ## Provider Fallback Chain
51
+
52
+ Use `providers` when you want explicit model or vendor failover. Each provider
53
+ can have its own retry count and cost calculator.
46
54
 
47
55
  ```ts
48
- import { llmRetry } from 'llm-retry-kit'
56
+ const result = await llmRetry({
57
+ providers: [
58
+ {
59
+ name: 'openai:gpt-4o',
60
+ fn: async (context) => callOpenAI(context),
61
+ maxRetries: 2,
62
+ },
63
+ {
64
+ name: 'anthropic:sonnet',
65
+ fn: async (context) => callAnthropic(context),
66
+ maxRetries: 1,
67
+ },
68
+ ],
69
+ })
70
+
71
+ console.log(result.provider)
72
+ console.log(result.usedFallback)
73
+ ```
74
+
75
+ The older `fn` + `fallback` API still works:
49
76
 
77
+ ```ts
50
78
  const result = await llmRetry({
51
79
  fn: async () => callPrimaryModel(),
52
80
  fallback: async () => callFallbackModel(),
53
- maxRetries: 3,
54
- initialDelayMs: 1000,
55
- maxDelayMs: 30000,
56
81
  })
82
+ ```
57
83
 
58
- if (result.usedFallback) {
59
- console.log('Fallback model was used')
60
- }
84
+ ## Custom Retry Policy
85
+
86
+ ```ts
87
+ const result = await llmRetry({
88
+ fn: myLLMCall,
89
+ shouldRetry: (error, context) => {
90
+ if (error.message.includes('quota exceeded')) return false
91
+ return context.retryAttempt < context.maxRetries
92
+ },
93
+ })
61
94
  ```
62
95
 
96
+ Without `shouldRetry`, the package retries common transient failures such as
97
+ HTTP `408`, `409`, `429`, `5xx`, Anthropic `529`, timeout, network, and
98
+ overload errors.
99
+
100
+ ## Timeouts And Cancellation
101
+
102
+ ```ts
103
+ const controller = new AbortController()
104
+
105
+ const result = await llmRetry({
106
+ fn: async ({ signal }) => myLLMCall({ signal }),
107
+ signal: controller.signal,
108
+ timeoutMs: 30_000,
109
+ })
110
+ ```
111
+
112
+ `timeoutMs` aborts the wrapper and retry waits. Passing `signal` into your SDK
113
+ call lets the underlying HTTP request stop too, when the SDK supports it.
114
+
63
115
  ## Budget Tracking
64
116
 
65
- `llm-retry-kit` tracks cost from the `usage.totalTokens` value returned by your
66
- function. It cannot know the exact cost of a future LLM call before that call
67
- finishes, so the budget guard is best used to stop later retries or fallback
68
- calls after tracked usage reaches the configured cap.
117
+ Simple mode:
69
118
 
70
119
  ```ts
71
120
  const result = await llmRetry({
72
121
  fn: myLLMCall,
73
122
  maxCostUSD: 0.5,
74
123
  costPer1kTokens: 0.002,
75
- onBudgetExceeded: (spent, limit) => {
76
- console.warn(`Budget exceeded: $${spent.toFixed(4)} / $${limit}`)
77
- },
78
124
  })
79
125
  ```
80
126
 
81
- ## Retry Logging
127
+ Provider pricing is often more nuanced than one flat token price, so production
128
+ apps should prefer `costCalculator`:
82
129
 
83
130
  ```ts
84
131
  const result = await llmRetry({
85
132
  fn: myLLMCall,
86
- maxRetries: 4,
87
- initialDelayMs: 1000,
88
- maxDelayMs: 60000,
89
- onRetry: (attempt, error, delayMs) => {
90
- console.log(`Attempt ${attempt} failed: ${error.message}`)
91
- console.log(`Waiting ${(delayMs / 1000).toFixed(1)}s before retrying`)
133
+ costCalculator: (usage) => {
134
+ const input = usage.promptTokens * 0.00000015
135
+ const output = usage.completionTokens * 0.0000006
136
+ return input + output
137
+ },
138
+ })
139
+ ```
140
+
141
+ ## Observability
142
+
143
+ ```ts
144
+ await llmRetry({
145
+ fn: myLLMCall,
146
+ onAttempt: (context) => {
147
+ console.log(`Calling ${context.provider}, attempt ${context.attempt}`)
148
+ },
149
+ onRetry: (attempt, error, delayMs, context) => {
150
+ console.log(`${context.provider} failed: ${error.message}`)
151
+ console.log(`Retrying in ${delayMs}ms`)
152
+ },
153
+ onSuccess: (context) => {
154
+ console.log(`Cost so far: $${context.totalCostUSD}`)
155
+ },
156
+ onFailure: (error) => {
157
+ console.error(error)
92
158
  },
93
159
  })
94
160
  ```
@@ -99,28 +165,23 @@ const result = await llmRetry({
99
165
 
100
166
  | Option | Type | Default | Description |
101
167
  | --- | --- | --- | --- |
102
- | `fn` | `() => Promise<LLMResponse<T>>` | required | Primary async LLM call. |
103
- | `fallback` | `() => Promise<LLMResponse<T>>` | optional | Backup async LLM call. |
104
- | `maxRetries` | `number` | `3` | Number of retries after the first attempt. |
105
- | `maxCostUSD` | `number` | optional | Maximum tracked cost in USD. |
106
- | `costPer1kTokens` | `number` | `0.002` | Estimated cost per 1,000 tokens. |
168
+ | `fn` | `(context) => Promise<LLMResponse<T>>` | optional | Primary LLM call for the simple API. |
169
+ | `fallback` | `(context) => Promise<LLMResponse<T>>` | optional | Backup LLM call for the simple API. |
170
+ | `providers` | `RetryProvider<T>[]` | optional | Explicit provider/model chain. |
171
+ | `maxRetries` | `number` | `3` | Retries after the first attempt. |
172
+ | `maxCostUSD` | `number` | optional | Maximum tracked cost before later attempts stop. |
173
+ | `costPer1kTokens` | `number` | `0.002` | Simple cost estimate. |
174
+ | `costCalculator` | `(usage, context) => number` | optional | Custom cost calculation. |
107
175
  | `initialDelayMs` | `number` | `1000` | Initial retry delay. |
108
176
  | `maxDelayMs` | `number` | `30000` | Maximum retry delay. |
109
- | `onRetry` | `(attempt, error, delayMs) => void` | optional | Called before each retry wait. |
110
- | `onBudgetExceeded` | `(spentUSD, limitUSD) => void` | optional | Called when tracked budget is exhausted. |
111
-
112
- ### `LLMResponse<T>`
113
-
114
- ```ts
115
- {
116
- data: T
117
- usage?: {
118
- promptTokens: number
119
- completionTokens: number
120
- totalTokens: number
121
- }
122
- }
123
- ```
177
+ | `timeoutMs` | `number` | optional | Abort wrapper after this time. |
178
+ | `signal` | `AbortSignal` | optional | External cancellation signal. |
179
+ | `shouldRetry` | `(error, context) => boolean \| Promise<boolean>` | optional | Override retry decisions. |
180
+ | `onAttempt` | `(context) => void` | optional | Called before each attempt. |
181
+ | `onRetry` | `(attempt, error, delayMs, context) => void` | optional | Called before retry wait. |
182
+ | `onSuccess` | `(context) => void` | optional | Called after a successful response. |
183
+ | `onFailure` | `(error) => void` | optional | Called before final failure is thrown. |
184
+ | `onBudgetExceeded` | `(spentUSD, limitUSD) => void` | optional | Called when budget is exhausted. |
124
185
 
125
186
  ### `RetryResult<T>`
126
187
 
@@ -128,24 +189,18 @@ const result = await llmRetry({
128
189
  {
129
190
  data: T
130
191
  attempts: number
192
+ provider: string
131
193
  usedFallback: boolean
132
194
  totalCostUSD: number
133
195
  totalTokens: number
134
196
  }
135
197
  ```
136
198
 
137
- ## Retryable Errors
138
-
139
- The package retries common transient failures:
140
-
141
- - HTTP `429`
142
- - HTTP `5xx`
143
- - timeout errors
144
- - network connection errors
145
- - overloaded server errors
199
+ ## Notes
146
200
 
147
- Authentication errors, invalid requests, and other non-transient failures are
148
- not retried.
201
+ Budget tracking is based on the `usage` object returned by your function. A
202
+ wrapper cannot know the final cost of an in-flight LLM call before the provider
203
+ returns usage, so `maxCostUSD` is a guard for later attempts and fallback calls.
149
204
 
150
205
  ## License
151
206
 
package/dist/backoff.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export declare function calculateBackoff(attempt: number, initialDelayMs: number, maxDelayMs: number): number;
2
- export declare function sleep(ms: number): Promise<void>;
2
+ export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
3
3
  export declare function isRetryableError(error: unknown): boolean;
4
4
  export declare function extractRetryAfter(error: unknown): number | null;
5
+ export declare function createAbortError(): Error;
5
6
  //# sourceMappingURL=backoff.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"backoff.d.ts","sourceRoot":"","sources":["../src/backoff.ts"],"names":[],"mappings":"AAAA,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GACjB,MAAM,CAMR;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAiDxD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAyB/D"}
1
+ {"version":3,"file":"backoff.d.ts","sourceRoot":"","sources":["../src/backoff.ts"],"names":[],"mappings":"AAAA,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GACjB,MAAM,CAMR;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBrE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CA2DxD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CA4B/D;AAED,wBAAgB,gBAAgB,IAAI,KAAK,CAIxC"}
package/dist/backoff.js CHANGED
@@ -4,15 +4,27 @@ export function calculateBackoff(attempt, initialDelayMs, maxDelayMs) {
4
4
  const delay = exponential + jitter;
5
5
  return Math.min(Math.max(delay, initialDelayMs), maxDelayMs);
6
6
  }
7
- export function sleep(ms) {
8
- return new Promise((resolve) => setTimeout(resolve, ms));
7
+ export function sleep(ms, signal) {
8
+ if (signal?.aborted) {
9
+ return Promise.reject(createAbortError());
10
+ }
11
+ return new Promise((resolve, reject) => {
12
+ const timeout = setTimeout(resolve, ms);
13
+ signal?.addEventListener('abort', () => {
14
+ clearTimeout(timeout);
15
+ reject(createAbortError());
16
+ }, { once: true });
17
+ });
9
18
  }
10
19
  export function isRetryableError(error) {
11
20
  if (!(error instanceof Error))
12
21
  return false;
13
22
  const err = error;
14
23
  const status = toNumber(err.status ?? err.statusCode);
15
- if (status === 429 || (status !== null && status >= 500 && status <= 599)) {
24
+ if (status === 408 ||
25
+ status === 409 ||
26
+ status === 429 ||
27
+ (status !== null && status >= 500 && status <= 599)) {
16
28
  return true;
17
29
  }
18
30
  const code = typeof err.code === 'string' ? err.code.toLowerCase() : '';
@@ -23,6 +35,8 @@ export function isRetryableError(error) {
23
35
  'enotfound',
24
36
  'eai_again',
25
37
  'rate_limit_exceeded',
38
+ 'conflict',
39
+ 'overloaded_error',
26
40
  ].includes(code)) {
27
41
  return true;
28
42
  }
@@ -32,6 +46,8 @@ export function isRetryableError(error) {
32
46
  'rate_limit',
33
47
  'too many requests',
34
48
  '429',
49
+ '408',
50
+ '409',
35
51
  'server error',
36
52
  '500',
37
53
  '502',
@@ -44,6 +60,7 @@ export function isRetryableError(error) {
44
60
  'network',
45
61
  'socket',
46
62
  'overloaded',
63
+ 'overloaded_error',
47
64
  ];
48
65
  return retryablePatterns.some((pattern) => message.includes(pattern));
49
66
  }
@@ -55,7 +72,9 @@ export function extractRetryAfter(error) {
55
72
  if (retryAfter !== null) {
56
73
  return retryAfter * 1000;
57
74
  }
58
- const headerValue = getHeader(err['headers'], 'retry-after');
75
+ const response = err['response'];
76
+ const headerValue = getHeader(err['headers'], 'retry-after') ??
77
+ getHeader(response?.['headers'], 'retry-after');
59
78
  if (!headerValue) {
60
79
  return null;
61
80
  }
@@ -69,6 +88,11 @@ export function extractRetryAfter(error) {
69
88
  }
70
89
  return null;
71
90
  }
91
+ export function createAbortError() {
92
+ const error = new Error('The operation was aborted');
93
+ error.name = 'AbortError';
94
+ return error;
95
+ }
72
96
  function toNumber(value) {
73
97
  if (typeof value === 'number' && Number.isFinite(value)) {
74
98
  return value;
@@ -1 +1 @@
1
- {"version":3,"file":"backoff.js","sourceRoot":"","sources":["../src/backoff.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"backoff.js","sourceRoot":"","sources":["../src/backoff.ts"],"names":[],"mappings":"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"}
package/dist/budget.d.ts CHANGED
@@ -5,7 +5,8 @@ export declare class BudgetTracker {
5
5
  private readonly costPer1kTokens;
6
6
  private readonly maxCostUSD;
7
7
  constructor(costPer1kTokens: number, maxCostUSD?: number);
8
- add(usage: TokenUsage): void;
8
+ add(usage: TokenUsage, costUSD?: number): void;
9
+ estimate(usage: TokenUsage): number;
9
10
  isExceeded(): boolean;
10
11
  get spent(): number;
11
12
  get tokens(): number;
@@ -1 +1 @@
1
- {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,qBAAa,aAAa;IACxB,OAAO,CAAC,WAAW,CAAI;IACvB,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;gBAE9B,eAAe,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;IAaxD,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAK5B,UAAU,IAAI,OAAO;IAKrB,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,KAAK,IAAI,MAAM,GAAG,IAAI,CAEzB;IAED,OAAO,IAAI,MAAM;CAKlB"}
1
+ {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,qBAAa,aAAa;IACxB,OAAO,CAAC,WAAW,CAAI;IACvB,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;gBAE9B,eAAe,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;IAaxD,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAK9C,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM;IAInC,UAAU,IAAI,OAAO;IAKrB,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,KAAK,IAAI,MAAM,GAAG,IAAI,CAEzB;IAED,OAAO,IAAI,MAAM;CAKlB"}
package/dist/budget.js CHANGED
@@ -13,9 +13,12 @@ export class BudgetTracker {
13
13
  this.costPer1kTokens = costPer1kTokens;
14
14
  this.maxCostUSD = maxCostUSD ?? null;
15
15
  }
16
- add(usage) {
16
+ add(usage, costUSD) {
17
17
  this.totalTokens += usage.totalTokens;
18
- this.totalCostUSD += (usage.totalTokens / 1000) * this.costPer1kTokens;
18
+ this.totalCostUSD += costUSD ?? this.estimate(usage);
19
+ }
20
+ estimate(usage) {
21
+ return (usage.totalTokens / 1000) * this.costPer1kTokens;
19
22
  }
20
23
  isExceeded() {
21
24
  if (this.maxCostUSD === null)
@@ -1 +1 @@
1
- {"version":3,"file":"budget.js","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,aAAa;IAChB,WAAW,GAAG,CAAC,CAAA;IACf,YAAY,GAAG,CAAC,CAAA;IACP,eAAe,CAAQ;IACvB,UAAU,CAAe;IAE1C,YAAY,eAAuB,EAAE,UAAmB;QACtD,IAAI,eAAe,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAA;QACvE,CAAC;QAED,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;QAClE,CAAC;QAED,IAAI,CAAC,eAAe,GAAG,eAAe,CAAA;QACtC,IAAI,CAAC,UAAU,GAAG,UAAU,IAAI,IAAI,CAAA;IACtC,CAAC;IAED,GAAG,CAAC,KAAiB;QACnB,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAA;QACrC,IAAI,CAAC,YAAY,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,eAAe,CAAA;IACxE,CAAC;IAED,UAAU;QACR,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI;YAAE,OAAO,KAAK,CAAA;QAC1C,OAAO,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,UAAU,CAAA;IAC7C,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,YAAY,CAAA;IAC1B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,WAAW,CAAA;IACzB,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,UAAU,CAAA;IACxB,CAAC;IAED,OAAO;QACL,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACrE,OAAO,IAAI,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,UAAU,CAAA;IACzE,CAAC;CACF"}
1
+ {"version":3,"file":"budget.js","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,aAAa;IAChB,WAAW,GAAG,CAAC,CAAA;IACf,YAAY,GAAG,CAAC,CAAA;IACP,eAAe,CAAQ;IACvB,UAAU,CAAe;IAE1C,YAAY,eAAuB,EAAE,UAAmB;QACtD,IAAI,eAAe,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAA;QACvE,CAAC;QAED,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;QAClE,CAAC;QAED,IAAI,CAAC,eAAe,GAAG,eAAe,CAAA;QACtC,IAAI,CAAC,UAAU,GAAG,UAAU,IAAI,IAAI,CAAA;IACtC,CAAC;IAED,GAAG,CAAC,KAAiB,EAAE,OAAgB;QACrC,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAA;QACrC,IAAI,CAAC,YAAY,IAAI,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IACtD,CAAC;IAED,QAAQ,CAAC,KAAiB;QACxB,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,eAAe,CAAA;IAC1D,CAAC;IAED,UAAU;QACR,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI;YAAE,OAAO,KAAK,CAAA;QAC1C,OAAO,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,UAAU,CAAA;IAC7C,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,YAAY,CAAA;IAC1B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,WAAW,CAAA;IACzB,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,UAAU,CAAA;IACxB,CAAC;IAED,OAAO;QACL,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACrE,OAAO,IAAI,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,UAAU,CAAA;IACzE,CAAC;CACF"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { llmRetry, LLMRetryError } from './retry.js';
2
2
  export { BudgetTracker } from './budget.js';
3
- export { calculateBackoff, isRetryableError } from './backoff.js';
4
- export type { RetryOptions, RetryResult, TokenUsage, LLMResponse, RetryableError, } from './types.js';
3
+ export { calculateBackoff, extractRetryAfter, isRetryableError } from './backoff.js';
4
+ export type { CostCalculator, LLMCall, LLMResponse, RetryAttemptContext, RetryDecisionContext, RetryOptions, RetryProvider, RetryResult, RetrySuccessContext, RetryableError, ShouldRetry, TokenUsage, } from './types.js';
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACjE,YAAY,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,GACf,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACpF,YAAY,EACV,cAAc,EACd,OAAO,EACP,WAAW,EACX,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,WAAW,EACX,UAAU,GACX,MAAM,YAAY,CAAA"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { llmRetry, LLMRetryError } from './retry.js';
2
2
  export { BudgetTracker } from './budget.js';
3
- export { calculateBackoff, isRetryableError } from './backoff.js';
3
+ export { calculateBackoff, extractRetryAfter, isRetryableError } from './backoff.js';
4
4
  //# 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,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACpD,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
@@ -5,6 +5,8 @@ export declare class LLMRetryError extends Error {
5
5
  readonly fallbackError: Error | null;
6
6
  readonly totalCostUSD: number;
7
7
  readonly totalTokens: number;
8
- constructor(message: string, primaryError: Error | null, fallbackError: Error | null, totalCostUSD: number, totalTokens: number);
8
+ readonly attempts: number;
9
+ readonly providers: string[];
10
+ constructor(message: string, primaryError: Error | null, fallbackError: Error | null, totalCostUSD: number, totalTokens: number, attempts?: number, providers?: string[]);
9
11
  }
10
12
  //# sourceMappingURL=retry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE3D,wBAAsB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAgHnF;AAeD,qBAAa,aAAc,SAAQ,KAAK;aAGpB,YAAY,EAAE,KAAK,GAAG,IAAI;aAC1B,aAAa,EAAE,KAAK,GAAG,IAAI;aAC3B,YAAY,EAAE,MAAM;aACpB,WAAW,EAAE,MAAM;gBAJnC,OAAO,EAAE,MAAM,EACC,YAAY,EAAE,KAAK,GAAG,IAAI,EAC1B,aAAa,EAAE,KAAK,GAAG,IAAI,EAC3B,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM;CAKtC"}
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAKV,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,CAyJnF;AAgLD,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;gBANnC,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;CAK3C"}
package/dist/retry.js CHANGED
@@ -1,70 +1,215 @@
1
- import { calculateBackoff, extractRetryAfter, isRetryableError, sleep } from './backoff.js';
1
+ import { calculateBackoff, createAbortError, extractRetryAfter, isRetryableError, sleep, } from './backoff.js';
2
2
  import { BudgetTracker } from './budget.js';
3
3
  export async function llmRetry(options) {
4
- const { fn, fallback, maxRetries = 3, maxCostUSD, costPer1kTokens = 0.002, initialDelayMs = 1000, maxDelayMs = 30000, onRetry, onBudgetExceeded, } = options;
5
- validateOptions({ maxRetries, initialDelayMs, maxDelayMs });
4
+ const { maxRetries = 3, maxCostUSD, costPer1kTokens = 0.002, initialDelayMs = 1000, maxDelayMs = 30000, timeoutMs, signal, shouldRetry, onAttempt, onRetry, onSuccess, onFailure, onBudgetExceeded, } = options;
5
+ validateOptions({ maxRetries, initialDelayMs, maxDelayMs, timeoutMs });
6
+ const providers = normalizeProviders(options, maxRetries);
7
+ const startedAt = Date.now();
6
8
  const budget = new BudgetTracker(costPer1kTokens, maxCostUSD);
7
- let lastError = null;
9
+ const runtimeSignal = createRuntimeSignal(signal, timeoutMs);
8
10
  let attempts = 0;
11
+ let lastError = null;
12
+ let primaryError = null;
13
+ let fallbackError = null;
9
14
  let budgetExceededNotified = false;
10
- for (let retryIndex = 0; retryIndex <= maxRetries; retryIndex++) {
11
- if (budget.isExceeded()) {
12
- budgetExceededNotified = notifyBudgetExceeded(budget.spent, budget.limit, onBudgetExceeded, budgetExceededNotified);
13
- break;
14
- }
15
- attempts += 1;
16
- try {
17
- const response = await fn();
18
- if (response.usage) {
19
- budget.add(response.usage);
15
+ try {
16
+ for (let providerIndex = 0; providerIndex < providers.length; providerIndex++) {
17
+ const provider = providers[providerIndex];
18
+ const providerMaxRetries = provider.maxRetries ?? maxRetries;
19
+ for (let retryAttempt = 0; retryAttempt <= providerMaxRetries; retryAttempt++) {
20
+ if (runtimeSignal.signal?.aborted) {
21
+ throw createAbortError();
22
+ }
23
+ if (budget.isExceeded()) {
24
+ budgetExceededNotified = notifyBudgetExceeded(budget.spent, budget.limit, onBudgetExceeded, budgetExceededNotified);
25
+ throw new Error('Budget exceeded');
26
+ }
27
+ attempts += 1;
28
+ const context = createAttemptContext({
29
+ attempt: attempts,
30
+ retryAttempt,
31
+ provider,
32
+ providerIndex,
33
+ startedAt,
34
+ signal: runtimeSignal.signal,
35
+ lastError,
36
+ });
37
+ onAttempt?.(context);
38
+ try {
39
+ const response = await runWithAbort(provider.fn(context), runtimeSignal.signal);
40
+ const costUSD = trackUsage({
41
+ response,
42
+ context,
43
+ provider,
44
+ defaultCostPer1kTokens: costPer1kTokens,
45
+ defaultCostCalculator: options.costCalculator,
46
+ budget,
47
+ });
48
+ onSuccess?.({
49
+ ...context,
50
+ costUSD,
51
+ totalCostUSD: budget.spent,
52
+ totalTokens: budget.tokens,
53
+ });
54
+ return {
55
+ data: response.data,
56
+ attempts,
57
+ provider: provider.name,
58
+ usedFallback: providerIndex > 0,
59
+ totalCostUSD: budget.spent,
60
+ totalTokens: budget.tokens,
61
+ };
62
+ }
63
+ catch (error) {
64
+ const err = error instanceof Error ? error : new Error(String(error));
65
+ lastError = err;
66
+ if (providerIndex === 0) {
67
+ primaryError = err;
68
+ }
69
+ else {
70
+ fallbackError = err;
71
+ }
72
+ const decisionContext = {
73
+ ...context,
74
+ maxRetries: providerMaxRetries,
75
+ };
76
+ const retry = await shouldRetryAttempt({
77
+ error: err,
78
+ context: decisionContext,
79
+ shouldRetry,
80
+ retryAttempt,
81
+ maxRetries: providerMaxRetries,
82
+ });
83
+ if (!retry) {
84
+ break;
85
+ }
86
+ const serverDelay = extractRetryAfter(err);
87
+ const delay = serverDelay ?? calculateBackoff(retryAttempt, initialDelayMs, maxDelayMs);
88
+ onRetry?.(attempts, err, delay, decisionContext);
89
+ await sleep(delay, runtimeSignal.signal);
90
+ }
20
91
  }
21
- return {
22
- data: response.data,
23
- attempts,
24
- usedFallback: false,
25
- totalCostUSD: budget.spent,
26
- totalTokens: budget.tokens,
27
- };
28
92
  }
29
- catch (error) {
30
- const err = error instanceof Error ? error : new Error(String(error));
31
- lastError = err;
32
- const isLastAttempt = retryIndex === maxRetries;
33
- if (isLastAttempt || !isRetryableError(err)) {
34
- break;
35
- }
36
- const serverDelay = extractRetryAfter(error);
37
- const delay = serverDelay ?? calculateBackoff(retryIndex, initialDelayMs, maxDelayMs);
38
- onRetry?.(attempts, err, delay);
39
- await sleep(delay);
93
+ if (budget.isExceeded()) {
94
+ budgetExceededNotified = notifyBudgetExceeded(budget.spent, budget.limit, onBudgetExceeded, budgetExceededNotified);
40
95
  }
96
+ throw new Error(lastError?.message ?? 'No provider returned a successful response');
41
97
  }
42
- if (fallback && !budget.isExceeded()) {
43
- attempts += 1;
44
- try {
45
- const response = await fallback();
46
- if (response.usage) {
47
- budget.add(response.usage);
48
- }
49
- return {
50
- data: response.data,
51
- attempts,
52
- usedFallback: true,
53
- totalCostUSD: budget.spent,
54
- totalTokens: budget.tokens,
55
- };
56
- }
57
- catch (fallbackError) {
58
- const err = fallbackError instanceof Error
59
- ? fallbackError
60
- : new Error(String(fallbackError));
61
- throw new LLMRetryError(`Both primary and fallback failed. Primary: ${lastError?.message ?? 'unknown error'}. Fallback: ${err.message}`, lastError, err, budget.spent, budget.tokens);
98
+ catch (error) {
99
+ const err = error instanceof Error ? error : new Error(String(error));
100
+ const retryError = new LLMRetryError(`LLM call failed after ${attempts} attempt${attempts === 1 ? '' : 's'}: ${err.message}`, primaryError ?? lastError, fallbackError, budget.spent, budget.tokens, attempts, providers.map((provider) => provider.name));
101
+ onFailure?.(retryError);
102
+ throw retryError;
103
+ }
104
+ finally {
105
+ runtimeSignal.cleanup();
106
+ }
107
+ }
108
+ function normalizeProviders(options, defaultMaxRetries) {
109
+ if (options.providers && options.providers.length > 0) {
110
+ if (options.fn || options.fallback) {
111
+ throw new Error('Use either providers or fn/fallback, not both');
62
112
  }
113
+ return options.providers.map((provider) => ({
114
+ ...provider,
115
+ maxRetries: provider.maxRetries ?? defaultMaxRetries,
116
+ }));
117
+ }
118
+ if (!options.fn) {
119
+ throw new Error('llmRetry requires fn or at least one provider');
63
120
  }
64
- if (budget.isExceeded()) {
65
- notifyBudgetExceeded(budget.spent, budget.limit, onBudgetExceeded, budgetExceededNotified);
121
+ const providers = [
122
+ {
123
+ name: 'primary',
124
+ fn: options.fn,
125
+ maxRetries: defaultMaxRetries,
126
+ costCalculator: options.costCalculator,
127
+ costPer1kTokens: options.costPer1kTokens,
128
+ },
129
+ ];
130
+ if (options.fallback) {
131
+ providers.push({
132
+ name: 'fallback',
133
+ fn: options.fallback,
134
+ maxRetries: 0,
135
+ costCalculator: options.costCalculator,
136
+ costPer1kTokens: options.costPer1kTokens,
137
+ });
66
138
  }
67
- throw new LLMRetryError(`LLM call failed after ${attempts} attempt${attempts === 1 ? '' : 's'}: ${lastError?.message ?? 'budget exceeded'}`, lastError, null, budget.spent, budget.tokens);
139
+ return providers;
140
+ }
141
+ function createAttemptContext(options) {
142
+ return {
143
+ attempt: options.attempt,
144
+ retryAttempt: options.retryAttempt,
145
+ provider: options.provider.name,
146
+ providerIndex: options.providerIndex,
147
+ elapsedMs: Date.now() - options.startedAt,
148
+ signal: options.signal,
149
+ lastError: options.lastError ?? undefined,
150
+ };
151
+ }
152
+ async function shouldRetryAttempt(options) {
153
+ if (options.error.name === 'AbortError') {
154
+ return false;
155
+ }
156
+ if (options.retryAttempt >= options.maxRetries) {
157
+ return false;
158
+ }
159
+ if (options.shouldRetry) {
160
+ return options.shouldRetry(options.error, options.context);
161
+ }
162
+ return isRetryableError(options.error);
163
+ }
164
+ function trackUsage(options) {
165
+ const usage = options.response.usage;
166
+ if (!usage) {
167
+ return 0;
168
+ }
169
+ const calculator = options.provider.costCalculator ?? options.defaultCostCalculator;
170
+ const costUSD = calculator
171
+ ? calculator(usage, options.context)
172
+ : calculateDefaultCost(usage, options.provider.costPer1kTokens ?? options.defaultCostPer1kTokens);
173
+ options.budget.add(usage, costUSD);
174
+ return costUSD;
175
+ }
176
+ function calculateDefaultCost(usage, costPer1kTokens) {
177
+ return (usage.totalTokens / 1000) * costPer1kTokens;
178
+ }
179
+ function runWithAbort(promise, signal) {
180
+ if (!signal) {
181
+ return promise;
182
+ }
183
+ if (signal.aborted) {
184
+ return Promise.reject(createAbortError());
185
+ }
186
+ return new Promise((resolve, reject) => {
187
+ const abort = () => reject(createAbortError());
188
+ signal.addEventListener('abort', abort, { once: true });
189
+ promise.then((value) => {
190
+ signal.removeEventListener('abort', abort);
191
+ resolve(value);
192
+ }, (error) => {
193
+ signal.removeEventListener('abort', abort);
194
+ reject(error);
195
+ });
196
+ });
197
+ }
198
+ function createRuntimeSignal(signal, timeoutMs) {
199
+ if (timeoutMs === undefined) {
200
+ return { signal, cleanup: () => undefined };
201
+ }
202
+ const controller = new AbortController();
203
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
204
+ const abortFromParent = () => controller.abort();
205
+ signal?.addEventListener('abort', abortFromParent, { once: true });
206
+ return {
207
+ signal: controller.signal,
208
+ cleanup: () => {
209
+ clearTimeout(timeout);
210
+ signal?.removeEventListener('abort', abortFromParent);
211
+ },
212
+ };
68
213
  }
69
214
  function notifyBudgetExceeded(spentUSD, limitUSD, callback, alreadyNotified) {
70
215
  if (!alreadyNotified && limitUSD !== null) {
@@ -77,12 +222,16 @@ export class LLMRetryError extends Error {
77
222
  fallbackError;
78
223
  totalCostUSD;
79
224
  totalTokens;
80
- constructor(message, primaryError, fallbackError, totalCostUSD, totalTokens) {
225
+ attempts;
226
+ providers;
227
+ constructor(message, primaryError, fallbackError, totalCostUSD, totalTokens, attempts = 0, providers = []) {
81
228
  super(message);
82
229
  this.primaryError = primaryError;
83
230
  this.fallbackError = fallbackError;
84
231
  this.totalCostUSD = totalCostUSD;
85
232
  this.totalTokens = totalTokens;
233
+ this.attempts = attempts;
234
+ this.providers = providers;
86
235
  this.name = 'LLMRetryError';
87
236
  }
88
237
  }
@@ -99,5 +248,8 @@ function validateOptions(options) {
99
248
  if (options.maxDelayMs < options.initialDelayMs) {
100
249
  throw new Error('maxDelayMs must be greater than or equal to initialDelayMs');
101
250
  }
251
+ if (options.timeoutMs !== undefined && options.timeoutMs < 0) {
252
+ throw new Error('timeoutMs must be greater than or equal to 0');
253
+ }
102
254
  }
103
255
  //# sourceMappingURL=retry.js.map
package/dist/retry.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -7,23 +7,59 @@ export interface LLMResponse<T = unknown> {
7
7
  data: T;
8
8
  usage?: TokenUsage;
9
9
  }
10
+ export interface RetryAttemptContext {
11
+ attempt: number;
12
+ retryAttempt: number;
13
+ provider: string;
14
+ providerIndex: number;
15
+ elapsedMs: number;
16
+ signal?: AbortSignal;
17
+ lastError?: Error;
18
+ }
19
+ export interface RetryDecisionContext extends RetryAttemptContext {
20
+ maxRetries: number;
21
+ }
22
+ export interface RetrySuccessContext extends RetryAttemptContext {
23
+ costUSD: number;
24
+ totalCostUSD: number;
25
+ totalTokens: number;
26
+ }
27
+ export type LLMCall<T = unknown> = (context: RetryAttemptContext) => Promise<LLMResponse<T>>;
28
+ export type CostCalculator = (usage: TokenUsage, context: RetryAttemptContext) => number;
29
+ export type ShouldRetry = (error: Error, context: RetryDecisionContext) => boolean | Promise<boolean>;
30
+ export interface RetryProvider<T = unknown> {
31
+ name: string;
32
+ fn: LLMCall<T>;
33
+ maxRetries?: number;
34
+ costPer1kTokens?: number;
35
+ costCalculator?: CostCalculator;
36
+ }
10
37
  export interface RetryOptions<T = unknown> {
11
- fn: () => Promise<LLMResponse<T>>;
12
- fallback?: () => Promise<LLMResponse<T>>;
38
+ fn?: LLMCall<T>;
39
+ fallback?: LLMCall<T>;
40
+ providers?: Array<RetryProvider<T>>;
13
41
  maxRetries?: number;
14
42
  maxCostUSD?: number;
15
43
  costPer1kTokens?: number;
44
+ costCalculator?: CostCalculator;
16
45
  initialDelayMs?: number;
17
46
  maxDelayMs?: number;
18
- onRetry?: (attempt: number, error: Error, delayMs: number) => void;
47
+ timeoutMs?: number;
48
+ signal?: AbortSignal;
49
+ shouldRetry?: ShouldRetry;
50
+ onAttempt?: (context: RetryAttemptContext) => void;
51
+ onRetry?: (attempt: number, error: Error, delayMs: number, context: RetryDecisionContext) => void;
52
+ onSuccess?: (context: RetrySuccessContext) => void;
53
+ onFailure?: (error: Error) => void;
19
54
  onBudgetExceeded?: (spentUSD: number, limitUSD: number) => void;
20
55
  }
21
56
  export interface RetryResult<T = unknown> {
22
57
  data: T;
23
58
  attempts: number;
59
+ provider: string;
24
60
  usedFallback: boolean;
25
61
  totalCostUSD: number;
26
62
  totalTokens: number;
27
63
  }
28
- export type RetryableError = 'rate_limit' | 'server_error' | 'timeout' | 'network_error';
64
+ export type RetryableError = 'rate_limit' | 'server_error' | 'timeout' | 'network_error' | 'conflict' | 'overloaded';
29
65
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,gBAAgB,EAAE,MAAM,CAAA;IACxB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACtC,IAAI,EAAE,CAAC,CAAA;IACP,KAAK,CAAC,EAAE,UAAU,CAAA;CACnB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO;IACvC,EAAE,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;IACjC,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;IACxC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IAClE,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;CAChE;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACtC,IAAI,EAAE,CAAC,CAAA;IACP,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,OAAO,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,MAAM,cAAc,GACtB,YAAY,GACZ,cAAc,GACd,SAAS,GACT,eAAe,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "llm-retry-kit",
3
- "version": "0.1.0",
4
- "description": "Smart retry wrapper for LLM APIs with fallback, budget tracking, and exponential backoff.",
3
+ "version": "0.2.0",
4
+ "description": "Resilience toolkit for LLM APIs with retries, provider fallback, budget tracking, aborts, and observability.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",