agentfootprint 11.1.1 → 11.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.
Files changed (73) hide show
  1. package/CAPABILITIES.md +1 -0
  2. package/dist/adapters/mcp/agentcoreRuntime/sessionBusy.js +35 -4
  3. package/dist/adapters/mcp/agentcoreRuntime/sessionBusy.js.map +1 -1
  4. package/dist/adapters/mcp/agentcoreRuntime/transport.js +48 -22
  5. package/dist/adapters/mcp/agentcoreRuntime/transport.js.map +1 -1
  6. package/dist/core/RunnerBase.js +20 -1
  7. package/dist/core/RunnerBase.js.map +1 -1
  8. package/dist/esm/adapters/mcp/agentcoreRuntime/sessionBusy.d.ts +6 -2
  9. package/dist/esm/adapters/mcp/agentcoreRuntime/sessionBusy.js +35 -4
  10. package/dist/esm/adapters/mcp/agentcoreRuntime/sessionBusy.js.map +1 -1
  11. package/dist/esm/adapters/mcp/agentcoreRuntime/transport.d.ts +38 -12
  12. package/dist/esm/adapters/mcp/agentcoreRuntime/transport.js +47 -21
  13. package/dist/esm/adapters/mcp/agentcoreRuntime/transport.js.map +1 -1
  14. package/dist/esm/core/RunnerBase.d.ts +18 -0
  15. package/dist/esm/core/RunnerBase.js +20 -1
  16. package/dist/esm/core/RunnerBase.js.map +1 -1
  17. package/dist/esm/core/runner.d.ts +1 -0
  18. package/dist/esm/lib/longTimeout.d.ts +34 -0
  19. package/dist/esm/lib/longTimeout.js +56 -0
  20. package/dist/esm/lib/longTimeout.js.map +1 -0
  21. package/dist/esm/lib/sleep.d.ts +2 -0
  22. package/dist/esm/lib/sleep.js +2 -0
  23. package/dist/esm/lib/sleep.js.map +1 -1
  24. package/dist/esm/mcp/backoff.d.ts +81 -0
  25. package/dist/esm/mcp/backoff.js +158 -0
  26. package/dist/esm/mcp/backoff.js.map +1 -0
  27. package/dist/esm/mcp/mcpClient.js +3 -1
  28. package/dist/esm/mcp/mcpClient.js.map +1 -1
  29. package/dist/esm/mcp/throttleRetry.d.ts +198 -28
  30. package/dist/esm/mcp/throttleRetry.js +428 -83
  31. package/dist/esm/mcp/throttleRetry.js.map +1 -1
  32. package/dist/esm/mcp/types.d.ts +16 -7
  33. package/dist/esm/strategies/attach.js +3 -0
  34. package/dist/esm/strategies/attach.js.map +1 -1
  35. package/dist/esm/strategies/flushDeadline.d.ts +47 -0
  36. package/dist/esm/strategies/flushDeadline.js +96 -0
  37. package/dist/esm/strategies/flushDeadline.js.map +1 -0
  38. package/dist/lib/longTimeout.js +60 -0
  39. package/dist/lib/longTimeout.js.map +1 -0
  40. package/dist/lib/sleep.js +2 -0
  41. package/dist/lib/sleep.js.map +1 -1
  42. package/dist/mcp/backoff.js +163 -0
  43. package/dist/mcp/backoff.js.map +1 -0
  44. package/dist/mcp/mcpClient.js +3 -1
  45. package/dist/mcp/mcpClient.js.map +1 -1
  46. package/dist/mcp/throttleRetry.js +432 -85
  47. package/dist/mcp/throttleRetry.js.map +1 -1
  48. package/dist/strategies/attach.js +3 -0
  49. package/dist/strategies/attach.js.map +1 -1
  50. package/dist/strategies/flushDeadline.js +102 -0
  51. package/dist/strategies/flushDeadline.js.map +1 -0
  52. package/dist/types/adapters/mcp/agentcoreRuntime/sessionBusy.d.ts +6 -2
  53. package/dist/types/adapters/mcp/agentcoreRuntime/sessionBusy.d.ts.map +1 -1
  54. package/dist/types/adapters/mcp/agentcoreRuntime/transport.d.ts +38 -12
  55. package/dist/types/adapters/mcp/agentcoreRuntime/transport.d.ts.map +1 -1
  56. package/dist/types/core/RunnerBase.d.ts +18 -0
  57. package/dist/types/core/RunnerBase.d.ts.map +1 -1
  58. package/dist/types/core/runner.d.ts +1 -0
  59. package/dist/types/core/runner.d.ts.map +1 -1
  60. package/dist/types/lib/longTimeout.d.ts +35 -0
  61. package/dist/types/lib/longTimeout.d.ts.map +1 -0
  62. package/dist/types/lib/sleep.d.ts +2 -0
  63. package/dist/types/lib/sleep.d.ts.map +1 -1
  64. package/dist/types/mcp/backoff.d.ts +82 -0
  65. package/dist/types/mcp/backoff.d.ts.map +1 -0
  66. package/dist/types/mcp/throttleRetry.d.ts +198 -28
  67. package/dist/types/mcp/throttleRetry.d.ts.map +1 -1
  68. package/dist/types/mcp/types.d.ts +16 -7
  69. package/dist/types/mcp/types.d.ts.map +1 -1
  70. package/dist/types/strategies/attach.d.ts.map +1 -1
  71. package/dist/types/strategies/flushDeadline.d.ts +48 -0
  72. package/dist/types/strategies/flushDeadline.d.ts.map +1 -0
  73. package/package.json +2 -2
@@ -1,5 +1,6 @@
1
1
  /**
2
- * throttleRetry — when an MCP server says "too many requests", wait and ask again.
2
+ * throttleRetry — when an MCP server refuses a request before running it, wait
3
+ * and ask again.
3
4
  *
4
5
  * ── Why this exists ──────────────────────────────────────────────────────────
5
6
  * Managed MCP gateways enforce per-principal rate limits. A throttled
@@ -43,25 +44,48 @@
43
44
  * that would have died during the wait is simply never the one reused. The
44
45
  * gateway secrecy invariant is untouched: each attempt vends, applies, drops.
45
46
  *
47
+ * ── The loop is footprintjs's attempt runner, one series per call ────────────
48
+ * Each call runs ONE `attempt()` series (footprintjs, used as it ships). Its
49
+ * runner makes an attempt record per try; they stay inside this module for
50
+ * now — only `onRetry`, before each wait, reaches a caller. An attempt sends
51
+ * the request once, and an attempt that got a RESPONSE is not an operation
52
+ * that succeeded: a 503 is delivered as the answer it was, never retried.
53
+ * A response a rule's decision recognises is thrown as a refusal that names
54
+ * its kind, and the policy's `retryOn` accepts those refusals and nothing
55
+ * else — so a 5xx, a dropped connection or a timeout ends the series on the
56
+ * attempt it happened in, as it always did. When the
57
+ * series ends on a refusal (attempts spent, a ceiling reached, no time left),
58
+ * the refusal's response is delivered as the server sent it: the caller sees
59
+ * the 429, never an error of ours.
60
+ *
61
+ * ── A fetch that already retries is JOINED, never wrapped ────────────────────
62
+ * A transport whose own fetch runs a series (AgentCore Runtime's session-busy
63
+ * retry) says how to rebuild itself with one more rule (`joinableRetry`).
64
+ * `retryingFetch` over such a fetch — what `mcpClient` applies to every http
65
+ * transport — adds its 429 rule to THAT series instead of starting a second
66
+ * one around it. One series means one attempt count, one waiting total and one
67
+ * deadline per call, by construction: the layers can never multiply requests.
68
+ * The series' FIRST rule holds the call's budget — its `maxAttempts`,
69
+ * `maxWaitMs` and `maxElapsedMs` bound every attempt and wait, whatever the
70
+ * reason. A rule that joins keeps its own values as limits on its own kind:
71
+ * they can stop its retries sooner, never make the call longer.
72
+ *
73
+ * ── The wait: a stated one wins, whole ───────────────────────────────────────
74
+ * Each retry's wait is `statedWaitFirst(retry-after, exponentialBackoff({ …,
75
+ * maxDelayMs }))`: the server's `Retry-After` when it sent one, else our
76
+ * jittered backoff, whose CEILING is capped at `maxDelayMs` before the draw
77
+ * (so capped waits keep their jitter). The cap is on the SCHEDULE only —
78
+ * never on a stated wait — so the footprintjs policy's `maxBackoffMs`,
79
+ * which would cut every wait and send the request again before the server
80
+ * said it may, is left unset. A stated wait too long for `maxWaitMs` or the
81
+ * deadline is never shortened either: the series stops, and the 429 is
82
+ * delivered as the server sent it.
83
+ *
46
84
  * Pattern: Decorator over `fetch`. Role: Layer-3 tool transport.
47
85
  */
48
- import { sleep } from '../lib/sleep.js';
49
- // ─── Defaults ────────────────────────────────────────────────────────
50
- const DEFAULT_MAX_ATTEMPTS = 3;
51
- const DEFAULT_MAX_WAIT_MS = 10_000;
52
- /** First backoff when the server sent no `Retry-After`. */
53
- const BASE_BACKOFF_MS = 200;
54
- /** `undefined` means "do not retry" — the caller then leaves `fetch` alone. */
55
- function resolveConfig(config) {
56
- if (config === false)
57
- return undefined;
58
- const opts = config === true || config === undefined ? {} : config;
59
- return {
60
- maxAttempts: Math.max(1, opts.maxAttempts ?? DEFAULT_MAX_ATTEMPTS),
61
- maxWaitMs: Math.max(0, opts.maxWaitMs ?? DEFAULT_MAX_WAIT_MS),
62
- ...(opts.onRetry && { onRetry: opts.onRetry }),
63
- };
64
- }
86
+ import { attempt, } from 'footprintjs';
87
+ import { abortErrorOf, eitherSignal, linkedController } from '../lib/abort.js';
88
+ import { exponentialBackoff, statedWaitFirst } from './backoff.js';
65
89
  /** HTTP 429, with the server's own `Retry-After` when it sent one. */
66
90
  export function throttled(response) {
67
91
  if (response.status !== 429)
@@ -69,6 +93,49 @@ export function throttled(response) {
69
93
  const retryAfterMs = parseRetryAfter(response.headers.get('retry-after'));
70
94
  return retryAfterMs === undefined ? {} : { retryAfterMs };
71
95
  }
96
+ /**
97
+ * `retryOnThrottle`'s defaults — unchanged since 8.11.0: 3 attempts, a 200 ms
98
+ * backoff doubling with equal jitter (100–200 ms, then 200–400 ms), never more
99
+ * than 10 s of waiting in total. No deadline and no cap on one wait.
100
+ */
101
+ export const THROTTLE_RETRY_DEFAULTS = Object.freeze({
102
+ maxAttempts: 3,
103
+ maxWaitMs: 10_000,
104
+ maxElapsedMs: Infinity,
105
+ baseDelayMs: 200,
106
+ multiplier: 2,
107
+ jitter: 'equal',
108
+ maxDelayMs: Infinity,
109
+ });
110
+ /**
111
+ * @internal A rule from a caller's options — `undefined` when retry is off
112
+ * (`false`). An option field left out, or set to `undefined`, takes its
113
+ * default. `maxAttempts` and `maxWaitMs` keep the clamps they always had (below
114
+ * 1 reads as 1, below 0 as 0).
115
+ *
116
+ * @throws TypeError, when the rule is BUILT, for a value the schedule cannot
117
+ * mean — named by option, never echoing a value that is not a number.
118
+ */
119
+ export function retryRule(kind, decide, config, defaults, where) {
120
+ if (config === false)
121
+ return undefined;
122
+ const opts = typeof config === 'object' && config !== null ? config : {};
123
+ const option = new OptionReader(where);
124
+ const rule = {
125
+ kind,
126
+ decide,
127
+ maxAttempts: option.atLeast('maxAttempts', Math.max(1, opts.maxAttempts ?? defaults.maxAttempts)),
128
+ maxWaitMs: option.atLeast('maxWaitMs', Math.max(0, opts.maxWaitMs ?? defaults.maxWaitMs)),
129
+ maxElapsedMs: option.positive('maxElapsedMs', opts.maxElapsedMs ?? defaults.maxElapsedMs),
130
+ maxDelayMs: option.nonNegative('maxDelayMs', opts.maxDelayMs ?? defaults.maxDelayMs),
131
+ baseDelayMs: option.finite('baseDelayMs', opts.baseDelayMs ?? defaults.baseDelayMs, 0),
132
+ multiplier: option.finite('multiplier', opts.multiplier ?? defaults.multiplier, 1),
133
+ jitter: option.jitter(opts.jitter ?? defaults.jitter),
134
+ ...(opts.endpointLabel !== undefined && { endpointLabel: option.label(opts.endpointLabel) }),
135
+ ...(opts.onRetry && { onRetry: opts.onRetry }),
136
+ };
137
+ return rule;
138
+ }
72
139
  // ─── The decorator ───────────────────────────────────────────────────
73
140
  /**
74
141
  * Wrap a `fetch` so HTTP 429 responses are retried, honouring `Retry-After`.
@@ -77,6 +144,10 @@ export function throttled(response) {
77
144
  * so a transport that passed no custom fetch keeps passing none and its
78
145
  * behaviour is byte-identical to before this existed.
79
146
  *
147
+ * When `inner` already runs a retry series of its own (an AgentCore Runtime
148
+ * transport's fetch), the 429 rule JOINS that series rather than wrapping it,
149
+ * so the two can never multiply requests — see the module note.
150
+ *
80
151
  * ── Why this is public ───────────────────────────────────────────────────────
81
152
  * `mcpClient({ transport })` applies it for you, ON by default. `mcpClient({
82
153
  * connection })` cannot: the library builds no transport on that arm, so there
@@ -98,70 +169,333 @@ export function throttled(response) {
98
169
  * @param inner the fetch to wrap. `undefined` means the global `fetch`,
99
170
  * resolved at CALL time so a later polyfill still wins.
100
171
  * @param config `true` / `undefined` for the defaults, `false` to get `inner`
101
- * back unchanged, or an object to tune the ceilings.
172
+ * back unchanged, or an object to tune the ceilings and the backoff.
173
+ * @throws TypeError when an option is outside its range — here, when the fetch
174
+ * is built, never at the first call.
102
175
  */
103
176
  export function retryingFetch(inner, config) {
104
- return retryingFetchWhen(inner, config, throttled);
177
+ const rule = retryRule('throttle', throttled, config, THROTTLE_RETRY_DEFAULTS, 'retryOnThrottle');
178
+ if (rule === undefined)
179
+ return inner;
180
+ const join = inner === undefined ? undefined : JOINS.get(inner);
181
+ return join !== undefined ? join(rule) : retryingFetchFor(inner ?? platformFetch, [rule]);
105
182
  }
106
183
  /**
107
- * The bounded loop itself, asking `decide` of every response.
108
- *
109
- * {@link retryingFetch} is this loop asking {@link throttled}. A vendor adapter
110
- * whose service documents a refusal of its own — one made before anything ran —
111
- * passes its decision here instead of writing a second loop, so the ceilings,
112
- * the `Retry-After` rail, the replay check, the abort and the `onRetry` report
113
- * stay one implementation.
114
- *
115
- * `decide` is asked only when a retry could actually follow — attempts left, a
116
- * body that can be sent again, no abort — so a decision that has to read the
117
- * response pays for that only when its answer can matter.
118
- *
119
- * @internal Public to adapters, not to the door: the decision is the vendor's
120
- * fact, and each one is reviewed against the license on {@link RetryDecision}.
184
+ * Fetches that run their retries in one series, each with the way to rebuild
185
+ * it with one more rule. Module-private: only `joinableRetry` adds to it, so a
186
+ * caller cannot make a fetch claim a series it does not run.
187
+ */
188
+ const JOINS = new WeakMap();
189
+ /**
190
+ * @internal Declare that `fetch` runs its retries in ONE series, and how to
191
+ * rebuild it with one more rule in that same series. `retryingFetch` joins such
192
+ * a fetch instead of wrapping it. A transport whose public fetch wraps its
193
+ * series (a session applied around it, its answers rewritten after it) uses
194
+ * this so the rule lands INSIDE that wrapping.
121
195
  */
122
- export function retryingFetchWhen(inner, config, decide) {
123
- const resolved = resolveConfig(config);
124
- if (!resolved)
196
+ export function joinableRetry(fetch, join) {
197
+ JOINS.set(fetch, join);
198
+ return fetch;
199
+ }
200
+ /**
201
+ * @internal The one series per call over `inner`, asking `rules` in order —
202
+ * `inner` itself when there are none. The first rule holds the call's budget;
203
+ * see the module note. The result is joinable.
204
+ */
205
+ export function retryingFetchFor(inner, rules) {
206
+ const [owner] = rules;
207
+ if (owner === undefined)
125
208
  return inner;
126
- const base = inner ?? ((input, init) => globalThis.fetch(input, init));
127
- return async (input, init) => {
128
- let totalWaited = 0;
129
- for (let attempt = 1;; attempt++) {
130
- const response = await base(input, init);
131
- if (attempt >= resolved.maxAttempts)
132
- return response;
133
- // A body we cannot send twice makes a retry a different request. Rare
134
- // for MCP (JSON strings), but silently replaying half a stream would be
135
- // worse than surfacing the refusal.
136
- if (!isReplayable(input, init))
137
- return response;
138
- if (init?.signal?.aborted)
139
- return response;
140
- const verdict = await decide(response);
141
- if (verdict === undefined)
142
- return response;
143
- const { retryAfterMs } = verdict;
144
- const waitMs = retryAfterMs ?? backoffMs(attempt);
145
- // The rail on Retry-After: never let a server talk us into a wait that
146
- // breaks the caller's budget.
147
- if (totalWaited + waitMs > resolved.maxWaitMs)
209
+ const bound = rules.map((rule) => boundRule(rule, owner));
210
+ return joinableRetry((input, init) => new Series(bound, input, init).run(inner), (rule) => retryingFetchFor(inner, [...rules, rule]));
211
+ }
212
+ /** The platform's fetch, looked up at call time so a later polyfill still wins. */
213
+ const platformFetch = (input, init) => globalThis.fetch(input, init);
214
+ function boundRule(rule, owner) {
215
+ const maxDelayMs = Math.min(rule.maxDelayMs, owner.maxDelayMs);
216
+ const schedule = exponentialBackoff({
217
+ baseDelayMs: rule.baseDelayMs,
218
+ multiplier: rule.multiplier,
219
+ jitter: rule.jitter,
220
+ maxDelayMs,
221
+ });
222
+ return {
223
+ ...rule,
224
+ maxAttempts: Math.min(rule.maxAttempts, owner.maxAttempts),
225
+ maxWaitMs: Math.min(rule.maxWaitMs, owner.maxWaitMs),
226
+ maxElapsedMs: Math.min(rule.maxElapsedMs, owner.maxElapsedMs),
227
+ maxDelayMs,
228
+ // The cap is on the schedule's ceiling only: a stated wait wins, whole.
229
+ backoffMs: statedWaitFirst(retryAfterOf, schedule),
230
+ };
231
+ }
232
+ /** The wait a refusal stated (its parsed `Retry-After`), or none. */
233
+ function retryAfterOf(error) {
234
+ return error instanceof RetryableRefusal ? error.retryAfterMs : undefined;
235
+ }
236
+ /** What a series names its records' target — a name from code, never a value. */
237
+ const SERIES_TARGET = 'mcp-request';
238
+ /**
239
+ * One call: one `attempt()` series, and what its policy's functions share while
240
+ * it runs — the waiting so far, and the latest refusal.
241
+ */
242
+ class Series {
243
+ rules;
244
+ input;
245
+ init;
246
+ owner;
247
+ startedAt = Date.now();
248
+ deadline;
249
+ signal;
250
+ replayable;
251
+ attemptNo = 0;
252
+ waitedMs = 0;
253
+ plannedWaitMs = 0;
254
+ latest;
255
+ constructor(rules, input, init) {
256
+ this.rules = rules;
257
+ this.input = input;
258
+ this.init = init;
259
+ this.owner = rules[0];
260
+ this.signal = init?.signal ?? undefined;
261
+ this.replayable = isReplayable(input, init);
262
+ const { maxElapsedMs } = this.owner;
263
+ this.deadline = Number.isFinite(maxElapsedMs) ? this.startedAt + maxElapsedMs : undefined;
264
+ }
265
+ async run(inner) {
266
+ try {
267
+ return await attempt((t) => this.send(inner, t), this.policy(), this.options());
268
+ }
269
+ catch (error) {
270
+ return this.settle(error);
271
+ }
272
+ }
273
+ /**
274
+ * The owner's budget as footprintjs reads it; the rest is this series'
275
+ * `retryOn` and backoff. `maxBackoffMs` is deliberately unset: it would cap a
276
+ * stated `Retry-After` too, and send the request before the server said.
277
+ */
278
+ policy() {
279
+ const { maxAttempts } = this.owner;
280
+ return {
281
+ // A whole number for the runner; "no count" is a count no call reaches.
282
+ attempts: Number.isFinite(maxAttempts) ? Math.ceil(maxAttempts) : Number.MAX_SAFE_INTEGER,
283
+ retryOn: (error) => this.retryOn(error),
284
+ // `retryOn` planned the wait — it needs the length to hold the ceilings.
285
+ backoffMs: () => this.plannedWaitMs,
286
+ };
287
+ }
288
+ options() {
289
+ return {
290
+ target: SERIES_TARGET,
291
+ ...(this.signal !== undefined && { signal: this.signal }),
292
+ ...(this.deadline !== undefined && { deadline: this.deadline }),
293
+ onAttempt: (record) => this.report(record),
294
+ };
295
+ }
296
+ /**
297
+ * One attempt: the request, sent once, and its answer classified. A refusal
298
+ * a rule recognises is thrown for the runner to decide on.
299
+ *
300
+ * With no deadline of ours the request carries the caller's own `init`,
301
+ * exactly as before this series existed. Under a deadline the runner can cut
302
+ * the attempt before it is ANSWERED — and an answer is not in until it has
303
+ * been classified, which can mean reading its body (a session-busy reply is
304
+ * JSON in a 200). So the cut stays connected through the classification: a
305
+ * stall in the request or in that body stops the request and releases the
306
+ * body. Only then does it let go: an answer handed back to the caller keeps
307
+ * streaming for as long as the caller's own signal allows.
308
+ */
309
+ async send(inner, t) {
310
+ this.attemptNo = t.attempt;
311
+ // The previous attempt's refusal will not be delivered: release its body, so
312
+ // a keep-alive connection is not pinned by an unread stream.
313
+ this.supersede();
314
+ const cut = this.deadline === undefined ? undefined : linkedController(t.signal);
315
+ const signal = eitherSignal(this.signal, cut?.controller.signal);
316
+ try {
317
+ const init = cut === undefined ? this.init : { ...this.init, ...(signal && { signal }) };
318
+ const response = await inner(this.input, init);
319
+ const refused = await this.recognise(response, signal);
320
+ if (refused === undefined)
148
321
  return response;
149
- // Release the throttle response's body before asking again, so a
150
- // keep-alive connection is not pinned by an unread stream.
322
+ this.latest = refused;
323
+ throw refused.refusal;
324
+ }
325
+ finally {
326
+ cut?.unlink();
327
+ }
328
+ }
329
+ /**
330
+ * The first rule whose decision says "again", or none. A decision the
331
+ * request's signal cut short leaves an answer nobody will read: it is
332
+ * released here, so its connection is not held open.
333
+ */
334
+ async recognise(response, signal) {
335
+ try {
336
+ for (const rule of this.rules) {
337
+ const verdict = await rule.decide(response, signal);
338
+ if (verdict === undefined)
339
+ continue;
340
+ return { refusal: new RetryableRefusal(rule.kind, verdict), rule, verdict, response };
341
+ }
342
+ return undefined;
343
+ }
344
+ catch (error) {
151
345
  discardBody(response);
152
- resolved.onRetry?.({
153
- attempt: attempt + 1,
154
- maxAttempts: resolved.maxAttempts,
155
- waitMs,
156
- ...(retryAfterMs !== undefined && { retryAfterMs }),
157
- url: describeUrl(input),
158
- });
159
- await sleep(waitMs, init?.signal);
160
- totalWaited += waitMs;
346
+ throw error;
161
347
  }
162
- };
348
+ }
349
+ /**
350
+ * The runner's `retryOn`: is this attempt's error a refusal worth another
351
+ * attempt? Plans the wait as it answers, because the ceilings need its length.
352
+ */
353
+ retryOn(error) {
354
+ this.plannedWaitMs = 0;
355
+ const refused = this.latest;
356
+ // The license: only a refusal made before the server ran anything. A 5xx, a
357
+ // dropped connection or a timeout may be the record of work that ran.
358
+ if (refused === undefined || error !== refused.refusal)
359
+ return false;
360
+ // A body we cannot send twice makes a retry a different request. Rare for
361
+ // MCP (JSON strings), but silently replaying half a stream would be worse
362
+ // than surfacing the refusal.
363
+ if (!this.replayable)
364
+ return false;
365
+ const { rule } = refused;
366
+ if (this.attemptNo >= rule.maxAttempts)
367
+ return false;
368
+ // The stated wait whole, else the schedule under `maxDelayMs`.
369
+ const waitMs = rule.backoffMs(this.attemptNo, error);
370
+ // The rail on Retry-After: never let a server talk us into a wait that
371
+ // breaks the caller's budget. It stops the series; it never shortens the
372
+ // wait. Past the deadline, the runner stops it the same way (`no-time-left`).
373
+ if (this.waitedMs + waitMs > rule.maxWaitMs)
374
+ return false;
375
+ // A joined rule's own, sooner deadline. The owner's is the runner's to hold.
376
+ if (rule.maxElapsedMs < this.owner.maxElapsedMs &&
377
+ this.elapsedAfter(waitMs) > rule.maxElapsedMs) {
378
+ return false;
379
+ }
380
+ this.plannedWaitMs = waitMs;
381
+ return true;
382
+ }
383
+ elapsedAfter(waitMs) {
384
+ return Date.now() - this.startedAt + waitMs;
385
+ }
386
+ /** Each record as the runner ends an attempt: a retry is counted and reported to its rule. */
387
+ report(record) {
388
+ const refused = this.latest;
389
+ if (record.next !== 'retry' || refused === undefined)
390
+ return;
391
+ const waitMs = record.delayMs ?? 0;
392
+ this.waitedMs += waitMs;
393
+ const { rule, verdict } = refused;
394
+ rule.onRetry?.({
395
+ kind: rule.kind,
396
+ attempt: record.attempt + 1,
397
+ maxAttempts: rule.maxAttempts,
398
+ waitMs,
399
+ ...(verdict.retryAfterMs !== undefined && { retryAfterMs: verdict.retryAfterMs }),
400
+ url: originOf(this.input),
401
+ ...(rule.endpointLabel !== undefined && { endpoint: rule.endpointLabel }),
402
+ });
403
+ }
404
+ /** How the call ends when the series did not answer. */
405
+ settle(error) {
406
+ // The caller's cancellation wins: the call ends with their reason, and the
407
+ // refusal nobody is waiting for any more is released.
408
+ if (this.signal?.aborted) {
409
+ this.supersede();
410
+ throw abortErrorOf(this.signal);
411
+ }
412
+ // The series ended on a refusal — attempts spent, a ceiling reached, no
413
+ // time left. The server's answer is delivered as it sent it.
414
+ if (this.latest !== undefined && error === this.latest.refusal)
415
+ return this.latest.response;
416
+ throw error;
417
+ }
418
+ supersede() {
419
+ if (this.latest !== undefined)
420
+ discardBody(this.latest.response);
421
+ this.latest = undefined;
422
+ }
163
423
  }
424
+ /**
425
+ * A response a rule recognised as a refusal made before anything ran, thrown so
426
+ * the attempt runner decides on it. It carries only what an attempt record may
427
+ * keep: a fixed sentence, its kind as `code`, a 429's status and the wait the
428
+ * server stated. Never the server's text, the request or the response — the
429
+ * series holds the response, not the error.
430
+ */
431
+ class RetryableRefusal extends Error {
432
+ name = 'RetryableRefusal';
433
+ code;
434
+ /** A throttle's status, so footprintjs's `errorCategory` reads it as rate-limited. */
435
+ status;
436
+ retryAfterMs;
437
+ constructor(kind, verdict) {
438
+ super(REFUSAL_SENTENCES[kind]);
439
+ this.code = kind;
440
+ this.status = kind === 'throttle' ? 429 : undefined;
441
+ this.retryAfterMs = verdict.retryAfterMs;
442
+ }
443
+ }
444
+ const REFUSAL_SENTENCES = {
445
+ throttle: 'The server refused the request with HTTP 429 before running it.',
446
+ 'session-busy': 'AgentCore Runtime refused the request while its session was starting or stopping, before running it.',
447
+ };
164
448
  // ─── Helpers ─────────────────────────────────────────────────────────
449
+ /** Reads one rule's numeric options, refusing by name what the schedule cannot mean. */
450
+ class OptionReader {
451
+ where;
452
+ constructor(where) {
453
+ this.where = where;
454
+ }
455
+ /** A number that is not NaN (`Infinity` allowed) — the clamps already applied. */
456
+ atLeast(name, value) {
457
+ if (typeof value !== 'number' || Number.isNaN(value))
458
+ this.refuse(name, 'a number');
459
+ return value;
460
+ }
461
+ /** A number > 0; `Infinity` is none. */
462
+ positive(name, value) {
463
+ if (!(typeof value === 'number' && value > 0))
464
+ this.refuse(name, 'a number > 0');
465
+ return value;
466
+ }
467
+ /** A number ≥ 0; `Infinity` is none. */
468
+ nonNegative(name, value) {
469
+ if (!(typeof value === 'number' && value >= 0))
470
+ this.refuse(name, 'a number ≥ 0');
471
+ return value;
472
+ }
473
+ /** A finite number ≥ `min`. */
474
+ finite(name, value, min) {
475
+ if (!(typeof value === 'number' && Number.isFinite(value) && value >= min)) {
476
+ this.refuse(name, `a finite number ≥ ${min}`);
477
+ }
478
+ return value;
479
+ }
480
+ jitter(value) {
481
+ if (value === 'none' || value === 'equal' || value === 'full')
482
+ return value;
483
+ return this.refuse('jitter', "'none', 'equal' or 'full'");
484
+ }
485
+ /** A caller's label: 1–128 characters, no control character. Never echoed in a refusal. */
486
+ label(value) {
487
+ if (typeof value === 'string' &&
488
+ value.length >= 1 &&
489
+ value.length <= 128 &&
490
+ !hasControl(value)) {
491
+ return value;
492
+ }
493
+ return this.refuse('endpointLabel', 'a string of 1–128 characters with no control character');
494
+ }
495
+ refuse(name, wanted) {
496
+ throw new TypeError(`${this.where}: \`${name}\` must be ${wanted}.`);
497
+ }
498
+ }
165
499
  /**
166
500
  * `Retry-After` in either legal form: delta-seconds (`"2"`) or an HTTP-date
167
501
  * (`"Wed, 21 Oct 2026 07:28:00 GMT"`). Anything else is treated as absent so a
@@ -178,15 +512,6 @@ export function parseRetryAfter(value) {
178
512
  return undefined;
179
513
  return Math.max(0, when - Date.now());
180
514
  }
181
- /**
182
- * Exponential backoff with equal jitter — half fixed, half random. The fixed
183
- * half keeps the wait meaningful; the random half stops a fleet of agents that
184
- * were all throttled at the same instant from retrying at the same instant.
185
- */
186
- function backoffMs(attempt) {
187
- const ceiling = BASE_BACKOFF_MS * Math.pow(2, attempt - 1);
188
- return Math.round(ceiling / 2 + Math.random() * (ceiling / 2));
189
- }
190
515
  /** Can this exact request be sent again? A stream body cannot be rewound. */
191
516
  function isReplayable(input, init) {
192
517
  // Defensive: the declared type says otherwise, but a `Request` carries its
@@ -215,8 +540,28 @@ function discardBody(response) {
215
540
  // A body that refuses to cancel is not worth failing a retry over.
216
541
  }
217
542
  }
218
- /** The endpoint, for the `onRetry` report. Never a credential. */
219
- function describeUrl(input) {
220
- return typeof input === 'string' ? input : input.toString();
543
+ /**
544
+ * The endpoint's ORIGIN, for the `onRetry` report: scheme, host and port. The
545
+ * path, user info, query and fragment are all dropped — a token, a credential
546
+ * or a customer id can ride in any of them. A URL that does not parse has no
547
+ * origin to report: the empty string.
548
+ */
549
+ function originOf(input) {
550
+ try {
551
+ const url = new URL(typeof input === 'string' ? input : input.toString());
552
+ return url.host === '' ? '' : `${url.protocol}//${url.host}`;
553
+ }
554
+ catch {
555
+ return '';
556
+ }
557
+ }
558
+ /** Whether `text` holds a control character (C0, DEL or C1). */
559
+ function hasControl(text) {
560
+ for (let i = 0; i < text.length; i++) {
561
+ const code = text.charCodeAt(i);
562
+ if (code < 0x20 || (code >= 0x7f && code <= 0x9f))
563
+ return true;
564
+ }
565
+ return false;
221
566
  }
222
567
  //# sourceMappingURL=throttleRetry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"throttleRetry.js","sourceRoot":"","sources":["../../../src/mcp/throttleRetry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"throttleRetry.js","sourceRoot":"","sources":["../../../src/mcp/throttleRetry.ts"],"names":[],"mappings":"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"}
@@ -180,11 +180,13 @@ export interface McpClientOptions {
180
180
  * What happens when the server says "too many requests" (HTTP 429). New in
181
181
  * 8.11.0, and **on by default**.
182
182
  *
183
- * Default: retry up to 3 times, waiting as long as the server's
184
- * `Retry-After` header asks (and, when it sends none, a jittered backoff),
185
- * never longer than 10 seconds of waiting in total across one call. Set
186
- * `false` to let a throttled call fail immediately, or pass an object to
187
- * tune the ceilings and to learn when it happens:
183
+ * Default: up to 3 attempts, waiting as long as the server's `Retry-After`
184
+ * header asks (and, when it sends none, a backoff of 200 ms doubling, with
185
+ * equal jitter), never longer than 10 seconds of waiting in total across one
186
+ * call. Set `false` to let a throttled call fail immediately, or pass an
187
+ * object to tune the ceilings and the backoff (`baseDelayMs`, `multiplier`,
188
+ * `jitter`, `maxDelayMs`, a `maxElapsedMs` deadline) and to learn when it
189
+ * happens:
188
190
  *
189
191
  * ```ts
190
192
  * const gateway = await mcpClient({
@@ -192,12 +194,19 @@ export interface McpClientOptions {
192
194
  * transport: gatewayTransport({ url, credentials }),
193
195
  * retryOnThrottle: {
194
196
  * maxAttempts: 5,
195
- * onRetry: ({ attempt, waitMs, retryAfterMs }) =>
196
- * log.warn({ attempt, waitMs, retryAfterMs }, 'gateway throttled'),
197
+ * onRetry: ({ kind, attempt, waitMs, retryAfterMs }) =>
198
+ * log.warn({ kind, attempt, waitMs, retryAfterMs }, 'gateway throttled'),
197
199
  * },
198
200
  * });
199
201
  * ```
200
202
  *
203
+ * Each call is ONE retry series (footprintjs's attempt runner). When the
204
+ * transport's own fetch already retries — `agentCoreRuntimeMcpTransport`'s
205
+ * session-busy retry — this 429 retry joins that series instead of wrapping
206
+ * it: one attempt count, one waiting total and one deadline per call, with
207
+ * the transport's `retry` values as the call's overall limits and these as
208
+ * limits on the 429 retries inside them.
209
+ *
201
210
  * **Why this is on by default.** A 429 is a *pre-execution rejection* — the
202
211
  * rate limiter refused the request at the edge and the server never ran the
203
212
  * tool, so a retry cannot double-execute anything. That is not true of a