@cyanheads/federal-regulations-mcp-server 0.2.1 → 0.2.3

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 (61) hide show
  1. package/AGENTS.md +9 -9
  2. package/CLAUDE.md +9 -9
  3. package/Dockerfile +12 -5
  4. package/README.md +2 -1
  5. package/changelog/0.2.x/0.2.2.md +15 -0
  6. package/changelog/0.2.x/0.2.3.md +24 -0
  7. package/changelog/template.md +55 -16
  8. package/dist/mcp-server/tools/definitions/browse-cfr.tool.d.ts +3 -3
  9. package/dist/mcp-server/tools/definitions/browse-cfr.tool.js +3 -3
  10. package/dist/mcp-server/tools/definitions/browse-cfr.tool.js.map +1 -1
  11. package/dist/mcp-server/tools/definitions/find-comments.tool.d.ts +5 -5
  12. package/dist/mcp-server/tools/definitions/find-comments.tool.d.ts.map +1 -1
  13. package/dist/mcp-server/tools/definitions/find-comments.tool.js +10 -6
  14. package/dist/mcp-server/tools/definitions/find-comments.tool.js.map +1 -1
  15. package/dist/mcp-server/tools/definitions/get-cfr-section.tool.d.ts +3 -3
  16. package/dist/mcp-server/tools/definitions/get-cfr-section.tool.js +3 -3
  17. package/dist/mcp-server/tools/definitions/get-cfr-section.tool.js.map +1 -1
  18. package/dist/mcp-server/tools/definitions/get-docket.tool.d.ts +5 -4
  19. package/dist/mcp-server/tools/definitions/get-docket.tool.d.ts.map +1 -1
  20. package/dist/mcp-server/tools/definitions/get-docket.tool.js +10 -5
  21. package/dist/mcp-server/tools/definitions/get-docket.tool.js.map +1 -1
  22. package/dist/mcp-server/tools/definitions/get-document.tool.d.ts +1 -1
  23. package/dist/mcp-server/tools/definitions/get-document.tool.js +1 -1
  24. package/dist/mcp-server/tools/definitions/get-document.tool.js.map +1 -1
  25. package/dist/mcp-server/tools/definitions/index.d.ts +15 -15
  26. package/dist/mcp-server/tools/definitions/list-open-comments.tool.d.ts.map +1 -1
  27. package/dist/mcp-server/tools/definitions/list-open-comments.tool.js +2 -2
  28. package/dist/mcp-server/tools/definitions/list-open-comments.tool.js.map +1 -1
  29. package/dist/mcp-server/tools/definitions/search-rules.tool.d.ts.map +1 -1
  30. package/dist/mcp-server/tools/definitions/search-rules.tool.js +2 -2
  31. package/dist/mcp-server/tools/definitions/search-rules.tool.js.map +1 -1
  32. package/dist/services/ecfr/ecfr-service.d.ts +30 -6
  33. package/dist/services/ecfr/ecfr-service.d.ts.map +1 -1
  34. package/dist/services/ecfr/ecfr-service.js +64 -29
  35. package/dist/services/ecfr/ecfr-service.js.map +1 -1
  36. package/dist/services/ecfr-mirror/ecfr-mirror.d.ts.map +1 -1
  37. package/dist/services/ecfr-mirror/ecfr-mirror.js +38 -5
  38. package/dist/services/ecfr-mirror/ecfr-mirror.js.map +1 -1
  39. package/dist/services/federal-register/federal-register-service.d.ts +17 -6
  40. package/dist/services/federal-register/federal-register-service.d.ts.map +1 -1
  41. package/dist/services/federal-register/federal-register-service.js +47 -19
  42. package/dist/services/federal-register/federal-register-service.js.map +1 -1
  43. package/dist/services/regulations-gov/regulations-gov-service.d.ts +37 -8
  44. package/dist/services/regulations-gov/regulations-gov-service.d.ts.map +1 -1
  45. package/dist/services/regulations-gov/regulations-gov-service.js +103 -24
  46. package/dist/services/regulations-gov/regulations-gov-service.js.map +1 -1
  47. package/dist/services/request-budget.d.ts +63 -0
  48. package/dist/services/request-budget.d.ts.map +1 -0
  49. package/dist/services/request-budget.js +95 -0
  50. package/dist/services/request-budget.js.map +1 -0
  51. package/dist/services/upstream-failure.d.ts +122 -18
  52. package/dist/services/upstream-failure.d.ts.map +1 -1
  53. package/dist/services/upstream-failure.js +177 -10
  54. package/dist/services/upstream-failure.js.map +1 -1
  55. package/package.json +8 -8
  56. package/scripts/_mirror-context.ts +1 -1
  57. package/server.json +3 -3
  58. package/dist/services/request-context.d.ts +0 -13
  59. package/dist/services/request-context.d.ts.map +0 -1
  60. package/dist/services/request-context.js +0 -23
  61. package/dist/services/request-context.js.map +0 -1
@@ -3,10 +3,16 @@
3
3
  * API (api.regulations.gov/v4, `X-Api-Key`). Backs `get_docket` and
4
4
  * `find_comments`, and enriches `list_open_comments`. JSON:API responses are
5
5
  * unwrapped to flat domain objects. The key is optional at the service level
6
- * (`hasKey()` lets keyless tools degrade or throw `auth_required`); 429s carry a
7
- * distinct `rate_limited` signal via `Retry-After`, and a 400 that names an
8
- * unusable resource ID joins the 404s on the `not_found` path. Comment bodies are
9
- * HTML-stripped and attachment-primary submissions flagged.
6
+ * (`hasKey()` lets keyless tools degrade or throw `auth_required`, which a key
7
+ * the API rejects raises too); 429s carry a distinct `rate_limited` signal via
8
+ * `Retry-After`, and a 400 that names an unusable resource ID joins the 404s on
9
+ * the `not_found` path. Those branches read the live `Response`, so requests go
10
+ * through `fetchUpstream` rather than the framework's `fetchWithTimeout`, which
11
+ * throws every non-2xx before a caller can inspect it; the wrapper keeps the
12
+ * branching and still classifies a connect-level failure as a transport failure.
13
+ * The deadline the wrapper does not impose comes from `runUpstream`, which bounds
14
+ * each attempt and draws every one of them down the request's shared budget.
15
+ * Comment bodies are HTML-stripped and attachment-primary submissions flagged.
10
16
  * @module services/regulations-gov/regulations-gov-service
11
17
  */
12
18
  import type { Context } from '@cyanheads/mcp-ts-core';
@@ -49,10 +55,33 @@ export declare class RegulationsGovService {
49
55
  */
50
56
  resolveFrDocumentObjectId(frDocumentNumber: string, ctx: Context): Promise<string | null>;
51
57
  /**
52
- * Fetch + parse JSON with key header and retry; maps 429 → rate_limited and
53
- * both flavours of "no such record" (404, and the 400 Regulations.gov issues
54
- * for an ID it cannot parse) → not_found. Whatever survives retry as a
55
- * transport failure leaves as upstream_unavailable.
58
+ * Fetch + parse JSON with key header and retry; maps 401/403 → auth_required,
59
+ * 429 → rate_limited, and both flavours of "no such record" (404, and the 400
60
+ * Regulations.gov issues for an ID it cannot parse) → not_found. Whatever
61
+ * survives retry as a transport failure leaves as upstream_unavailable.
62
+ *
63
+ * The request goes through `fetchUpstream` rather than bare `fetch` so a
64
+ * connect-level failure — one that never produces a `Response`, so none of the
65
+ * status branches below can see it — is classified as a transport failure
66
+ * instead of reaching the caller as an unclassified `InternalError`. The
67
+ * branches themselves need the live `Response` (the 400 discrimination reads
68
+ * the body, the 429 reads `Retry-After`), which is why this is not
69
+ * `fetchWithTimeout`: that helper turns every non-2xx into a thrown `McpError`
70
+ * before the caller sees it, and its `expectedStatuses` option only lowers the
71
+ * log severity of that throw.
72
+ *
73
+ * Keeping the raw `Response` used to mean keeping no deadline either — this
74
+ * leg was bounded by `ctx.signal` alone, so an upstream that accepted the
75
+ * connection and then said nothing held the request open for as long as it
76
+ * pleased, once per retry. `runUpstream` supplies the deadline the branching
77
+ * ruled out, as a signal composed into the request rather than a helper that
78
+ * consumes the response: every branch below still reads a live `Response`, and
79
+ * both the fetch and the `.json()` that follows it are inside the deadline.
80
+ *
81
+ * Retry is scoped to `retryTransportOnly`: a 429 on the shared hourly key is
82
+ * deterministic for the rest of the window, and expressing that here rather
83
+ * than through `data.retryable` keeps the flag — which is also the caller's own
84
+ * backoff hint — from contradicting the contract both tools declare.
56
85
  */
57
86
  private fetchJson;
58
87
  }
@@ -1 +1 @@
1
- {"version":3,"file":"regulations-gov-service.d.ts","sourceRoot":"","sources":["../../../src/services/regulations-gov/regulations-gov-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAKrE,OAAO,KAAK,EAEV,mBAAmB,EACnB,iBAAiB,EAEjB,YAAY,EASb,MAAM,YAAY,CAAC;AAIpB,qCAAqC;AACrC,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,+EAA+E;AAC/E,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAE5C,YAAY,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAIvD;IAED,uDAAuD;IACvD,MAAM,IAAI,OAAO,CAEhB;IAED,gEAAgE;IAC1D,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAyCzE;IAED,6EAA6E;IACvE,YAAY,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAuBtF;IAED,qEAAqE;IAC/D,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAQ9E;IAED;;;;OAIG;IACG,yBAAyB,CAAC,gBAAgB,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoB9F;IAED;;;;;OAKG;IACH,OAAO,CAAC,SAAS;CA+DlB;AAqKD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAE1F;AAED,wBAAgB,wBAAwB,IAAI,qBAAqB,CAOhE"}
1
+ {"version":3,"file":"regulations-gov-service.d.ts","sourceRoot":"","sources":["../../../src/services/regulations-gov/regulations-gov-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAU/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAUrE,OAAO,KAAK,EAEV,mBAAmB,EACnB,iBAAiB,EAEjB,YAAY,EASb,MAAM,YAAY,CAAC;AAWpB,qCAAqC;AACrC,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,+EAA+E;AAC/E,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAE5C,YAAY,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAIvD;IAED,uDAAuD;IACvD,MAAM,IAAI,OAAO,CAEhB;IAED,gEAAgE;IAC1D,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAyCzE;IAED,6EAA6E;IACvE,YAAY,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAuBtF;IAED,qEAAqE;IAC/D,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAQ9E;IAED;;;;OAIG;IACG,yBAAyB,CAAC,gBAAgB,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoB9F;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,OAAO,CAAC,SAAS;CA6FlB;AAwLD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAE1F;AAED,wBAAgB,wBAAwB,IAAI,qBAAqB,CAOhE"}
@@ -3,18 +3,31 @@
3
3
  * API (api.regulations.gov/v4, `X-Api-Key`). Backs `get_docket` and
4
4
  * `find_comments`, and enriches `list_open_comments`. JSON:API responses are
5
5
  * unwrapped to flat domain objects. The key is optional at the service level
6
- * (`hasKey()` lets keyless tools degrade or throw `auth_required`); 429s carry a
7
- * distinct `rate_limited` signal via `Retry-After`, and a 400 that names an
8
- * unusable resource ID joins the 404s on the `not_found` path. Comment bodies are
9
- * HTML-stripped and attachment-primary submissions flagged.
6
+ * (`hasKey()` lets keyless tools degrade or throw `auth_required`, which a key
7
+ * the API rejects raises too); 429s carry a distinct `rate_limited` signal via
8
+ * `Retry-After`, and a 400 that names an unusable resource ID joins the 404s on
9
+ * the `not_found` path. Those branches read the live `Response`, so requests go
10
+ * through `fetchUpstream` rather than the framework's `fetchWithTimeout`, which
11
+ * throws every non-2xx before a caller can inspect it; the wrapper keeps the
12
+ * branching and still classifies a connect-level failure as a transport failure.
13
+ * The deadline the wrapper does not impose comes from `runUpstream`, which bounds
14
+ * each attempt and draws every one of them down the request's shared budget.
15
+ * Comment bodies are HTML-stripped and attachment-primary submissions flagged.
10
16
  * @module services/regulations-gov/regulations-gov-service
11
17
  */
12
- import { internalError, notFound, rateLimited } from '@cyanheads/mcp-ts-core/errors';
13
- import { httpErrorFromResponse, withRetry } from '@cyanheads/mcp-ts-core/utils';
18
+ import { internalError, JsonRpcErrorCode, McpError, notFound, rateLimited, unauthorized, validationError, } from '@cyanheads/mcp-ts-core/errors';
19
+ import { httpErrorFromResponse, withExtra } from '@cyanheads/mcp-ts-core/utils';
14
20
  import { getServerConfig } from '../../config/server-config.js';
15
- import { toRequestContext } from '../../services/request-context.js';
16
- import { withUpstreamReason } from '../../services/upstream-failure.js';
21
+ import { requestBudget } from '../../services/request-budget.js';
22
+ import { fetchUpstream, rethrowTransportFailure, retryTransportOnly, runUpstream, } from '../../services/upstream-failure.js';
17
23
  const BASE_DELAY_MS = 1500;
24
+ /**
25
+ * Per-attempt deadline. Matches the Federal Register leg rather than eCFR's
26
+ * looser one: every Regulations.gov response here is a page of JSON:API metadata
27
+ * capped at 250 records, not a bulk document, so an attempt still running at 15s
28
+ * is a peer that is not going to answer.
29
+ */
30
+ const TIMEOUT_MS = 15_000;
18
31
  export class RegulationsGovService {
19
32
  baseUrl;
20
33
  apiKey;
@@ -108,10 +121,33 @@ export class RegulationsGovService {
108
121
  return first?.attributes?.objectId ?? null;
109
122
  }
110
123
  /**
111
- * Fetch + parse JSON with key header and retry; maps 429 → rate_limited and
112
- * both flavours of "no such record" (404, and the 400 Regulations.gov issues
113
- * for an ID it cannot parse) → not_found. Whatever survives retry as a
114
- * transport failure leaves as upstream_unavailable.
124
+ * Fetch + parse JSON with key header and retry; maps 401/403 → auth_required,
125
+ * 429 → rate_limited, and both flavours of "no such record" (404, and the 400
126
+ * Regulations.gov issues for an ID it cannot parse) → not_found. Whatever
127
+ * survives retry as a transport failure leaves as upstream_unavailable.
128
+ *
129
+ * The request goes through `fetchUpstream` rather than bare `fetch` so a
130
+ * connect-level failure — one that never produces a `Response`, so none of the
131
+ * status branches below can see it — is classified as a transport failure
132
+ * instead of reaching the caller as an unclassified `InternalError`. The
133
+ * branches themselves need the live `Response` (the 400 discrimination reads
134
+ * the body, the 429 reads `Retry-After`), which is why this is not
135
+ * `fetchWithTimeout`: that helper turns every non-2xx into a thrown `McpError`
136
+ * before the caller sees it, and its `expectedStatuses` option only lowers the
137
+ * log severity of that throw.
138
+ *
139
+ * Keeping the raw `Response` used to mean keeping no deadline either — this
140
+ * leg was bounded by `ctx.signal` alone, so an upstream that accepted the
141
+ * connection and then said nothing held the request open for as long as it
142
+ * pleased, once per retry. `runUpstream` supplies the deadline the branching
143
+ * ruled out, as a signal composed into the request rather than a helper that
144
+ * consumes the response: every branch below still reads a live `Response`, and
145
+ * both the fetch and the `.json()` that follows it are inside the deadline.
146
+ *
147
+ * Retry is scoped to `retryTransportOnly`: a 429 on the shared hourly key is
148
+ * deterministic for the rest of the window, and expressing that here rather
149
+ * than through `data.retryable` keeps the flag — which is also the caller's own
150
+ * backoff hint — from contradicting the contract both tools declare.
115
151
  */
116
152
  fetchJson(url, ctx, operation) {
117
153
  const key = this.apiKey;
@@ -121,24 +157,44 @@ export class RegulationsGovService {
121
157
  // is a programmer error (a caller bypassed the gate), not an operational one.
122
158
  throw internalError('RegulationsGovService called without an API key.', { operation });
123
159
  }
124
- const reqCtx = toRequestContext(ctx, operation);
125
- return withUpstreamReason(withRetry(async () => {
126
- const response = await fetch(url, {
160
+ const reqCtx = withExtra(ctx, { operation });
161
+ return runUpstream(ctx, requestBudget(ctx), {
162
+ operation,
163
+ context: reqCtx,
164
+ attemptMs: TIMEOUT_MS,
165
+ baseDelayMs: BASE_DELAY_MS,
166
+ isTransient: retryTransportOnly,
167
+ }, async (_deadlineMs, signal) => {
168
+ const response = await fetchUpstream(url, {
127
169
  headers: { 'X-Api-Key': key, Accept: 'application/vnd.api+json' },
128
- signal: ctx.signal,
129
- });
170
+ signal,
171
+ }, { service: 'Regulations.gov', operation });
130
172
  if (!response.ok) {
131
173
  if (response.status === 429) {
132
174
  const retryAfter = response.headers.get('retry-after');
133
- // Fail fast on the shared key's hourly limit: surface rate_limited so
134
- // the agent backs off, rather than retry-storming the same key.
135
- // `retryable: false` opts this throw out of withRetry's retry loop.
175
+ // Surface rate_limited so the agent backs off, rather than
176
+ // retry-storming the shared key's hourly limit. The fail-fast lives
177
+ // in this call's `isTransient`, not in `data.retryable` — that key
178
+ // is also the caller's own backoff hint, and both tools declare this
179
+ // failure retryable.
136
180
  throw rateLimited('Regulations.gov rate limit hit (1,000 requests/hour per key).', {
137
181
  reason: 'rate_limited',
138
- retryable: false,
139
182
  ...(retryAfter ? { retryAfter } : {}),
183
+ ...rateLimitRecovery(ctx, retryAfter),
140
184
  });
141
185
  }
186
+ if (response.status === 401 || response.status === 403) {
187
+ // The same failure the hasKey() gate names, one step further on: a
188
+ // key that is configured but rejected. api.data.gov answers both
189
+ // with 403 (API_KEY_INVALID / API_KEY_MISSING) and reserves 401 for
190
+ // the same class, and the caller's move is identical either way —
191
+ // supply a working key. Raised as Unauthorized because that is the
192
+ // code both tools declare auth_required against; a Forbidden here
193
+ // would answer with a code its own contract contradicts. The
194
+ // upstream body is deliberately not captured: a rejected-credential
195
+ // response is the one place an upstream echoes what it was sent.
196
+ throw unauthorized(`Regulations.gov rejected the configured API key (HTTP ${response.status}).`, { operation, reason: 'auth_required', ...ctx.recoveryFor('auth_required') });
197
+ }
142
198
  if (response.status === 404) {
143
199
  // Translate the bare 404 into an actionable not_found so the tool's
144
200
  // contract recovery surfaces, rather than "returned HTTP 404".
@@ -156,21 +212,44 @@ export class RegulationsGovService {
156
212
  throw notFound(`No matching docket, document, or comment found on Regulations.gov for "${invalidId}". Verify the ID (e.g. "EPA-HQ-OAR-2025-0194" for a docket, "EPA-HQ-OAR-2025-0194-0001" for a document, "EPA-HQ-OAR-2025-0194-31102" for a comment).`, { operation, reason: 'not_found', ...ctx.recoveryFor('not_found') });
157
213
  }
158
214
  }
159
- throw await httpErrorFromResponse(response, {
215
+ const failure = await httpErrorFromResponse(response, {
160
216
  service: 'Regulations.gov',
161
217
  data: { operation },
162
218
  });
219
+ if (failure instanceof McpError && failure.code === JsonRpcErrorCode.InvalidParams) {
220
+ throw validationError(failure.message, { ...failure.data }, { cause: failure });
221
+ }
222
+ rethrowTransportFailure(failure);
163
223
  }
164
224
  return (await response.json());
165
- }, { operation, context: reqCtx, baseDelayMs: BASE_DELAY_MS, signal: ctx.signal }), ctx);
225
+ });
166
226
  }
167
227
  }
228
+ /**
229
+ * The declared `rate_limited` hint, carrying the wait Regulations.gov asked for
230
+ * when it sent one.
231
+ *
232
+ * `Retry-After` already reaches the JSON surface as `data.retryAfter`, but never
233
+ * reaches a client reading `content[]`, which sees the `Recovery:` line and
234
+ * nothing else — so the number is folded into the hint each tool declares rather
235
+ * than replacing it. Falls back to the declared hint alone when the header is
236
+ * absent, or when the calling definition declares no `rate_limited` recovery.
237
+ */
238
+ function rateLimitRecovery(ctx, retryAfter) {
239
+ const declared = ctx.recoveryFor('rate_limited');
240
+ if (!retryAfter || !('recovery' in declared))
241
+ return declared;
242
+ return {
243
+ recovery: { hint: `${declared.recovery.hint} Regulations.gov asked for ${retryAfter}s.` },
244
+ };
245
+ }
168
246
  /**
169
247
  * The offending ID from a Regulations.gov 400 whose body reports an unusable
170
248
  * resource ID, or null for every other 400. The API answers a single-resource
171
249
  * lookup it cannot parse with `{"errors":[{"status":"400","title":"Invalid ID:
172
250
  * <id>"}]}`; a malformed request (bad filter name, out-of-range page size)
173
- * carries a different title and must keep its InvalidParams classification.
251
+ * carries a different title and is domain validation rather than malformed
252
+ * JSON-RPC parameters.
174
253
  */
175
254
  async function readInvalidIdTitle(response) {
176
255
  let parsed;
@@ -1 +1 @@
1
- {"version":3,"file":"regulations-gov-service.js","sourceRoot":"","sources":["../../../src/services/regulations-gov/regulations-gov-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"regulations-gov-service.js","sourceRoot":"","sources":["../../../src/services/regulations-gov/regulations-gov-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,eAAe,GAChB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,kBAAkB,EAClB,WAAW,GACZ,MAAM,gCAAgC,CAAC;AAiBxC,MAAM,aAAa,GAAG,IAAI,CAAC;AAC3B;;;;;GAKG;AACH,MAAM,UAAU,GAAG,MAAM,CAAC;AAiB1B,MAAM,OAAO,qBAAqB;IACf,OAAO,CAAS;IAChB,MAAM,CAAqB;IAE5C,YAAY,OAAkB,EAAE,QAAwB;QACtD,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,qBAAqB,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,oBAAoB,CAAC;IACzC,CAAC;IAED,uDAAuD;IACvD,MAAM;QACJ,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IACnE,CAAC;IAED,gEAAgE;IAChE,KAAK,CAAC,SAAS,CAAC,MAAoB,EAAE,GAAY;QAChD,MAAM,SAAS,GAAG,GAAG,IAAI,CAAC,OAAO,YAAY,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnF,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,SAAS,CACpC,SAAS,EACT,GAAG,EACH,iCAAiC,CAClC,CAAC;QACF,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,UAAU,IAAI,EAAE,CAAC;QAE/C,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC;YACpC,kBAAkB,EAAE,MAAM,CAAC,QAAQ;YACnC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;YACpC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;YACnC,IAAI,EAAE,aAAa;SACpB,CAAC,CAAC;QACH,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC;YAC9C,SAAS,CAAC,MAAM,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,OAAO,cAAc,SAAS,CAAC,QAAQ,EAAE,EAAE,CAAC;QACpE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAClC,OAAO,EACP,GAAG,EACH,0CAA0C,CAC3C,CAAC;QAEF,MAAM,SAAS,GAAkB,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC;aAClD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;aAChC,MAAM,CAAC,CAAC,CAAC,EAAoB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAE/C,OAAO;YACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,mBAAmB;YACzC,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;YACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI;YAChC,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,IAAI;YACtB,QAAQ,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;YAClC,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;YACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI;YAChC,aAAa,EAAE,OAAO,CAAC,IAAI,EAAE,aAAa,IAAI,SAAS,CAAC,MAAM;YAC9D,SAAS;SACV,CAAC;IACJ,CAAC;IAED,6EAA6E;IAC7E,KAAK,CAAC,YAAY,CAAC,MAAyB,EAAE,GAAY;QACxD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;YACpC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;YACnC,IAAI,EAAE,aAAa;SACpB,CAAC,CAAC;QACH,IAAI,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACnC,MAAM,CAAC,GAAG,CAAC,qBAAqB,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC/D,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,aAAa,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC5D,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAC9B,GAAG,EACH,GAAG,EACH,oCAAoC,CACrC,CAAC;QAEF,MAAM,QAAQ,GAAqB,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;aAChD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC;aACtC,MAAM,CAAC,CAAC,CAAC,EAAuB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAElD,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,IAAI,EAAE,aAAa,IAAI,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC9E,CAAC;IAED,qEAAqE;IACrE,KAAK,CAAC,UAAU,CAAC,SAAiB,EAAE,GAAY;QAC9C,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,aAAa,kBAAkB,CAAC,SAAS,CAAC,sBAAsB,CAAC;QAC5F,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAC9B,GAAG,EACH,GAAG,EACH,kCAAkC,CACnC,CAAC;QACF,OAAO,sBAAsB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAChD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,yBAAyB,CAAC,gBAAwB,EAAE,GAAY;QACpE,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,oBAAoB,EAAE,gBAAgB;YACtC,YAAY,EAAE,GAAG;YACjB,cAAc,EAAE,GAAG;SACpB,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,cAAc,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC7D,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAC9B,GAAG,EACH,GAAG,EACH,yCAAyC,CAC1C,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;YAC/B,IAAI,CAAC,CAAC,UAAU,EAAE,QAAQ,KAAK,gBAAgB,IAAI,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC;gBAC1E,OAAO,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC/B,CAAC;QACH,CAAC;QACD,uDAAuD;QACvD,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,IAAI,IAAI,CAAC;IAC7C,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACK,SAAS,CAAI,GAAW,EAAE,GAAY,EAAE,SAAiB;QAC/D,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QACxB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,yEAAyE;YACzE,2EAA2E;YAC3E,8EAA8E;YAC9E,MAAM,aAAa,CAAC,kDAAkD,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QACzF,CAAC;QACD,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAC7C,OAAO,WAAW,CAChB,GAAG,EACH,aAAa,CAAC,GAAG,CAAC,EAClB;YACE,SAAS;YACT,OAAO,EAAE,MAAM;YACf,SAAS,EAAE,UAAU;YACrB,WAAW,EAAE,aAAa;YAC1B,WAAW,EAAE,kBAAkB;SAChC,EACD,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE;YAC5B,MAAM,QAAQ,GAAG,MAAM,aAAa,CAClC,GAAG,EACH;gBACE,OAAO,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,0BAA0B,EAAE;gBACjE,MAAM;aACP,EACD,EAAE,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,CAC1C,CAAC;YACF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC5B,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;oBACvD,2DAA2D;oBAC3D,oEAAoE;oBACpE,mEAAmE;oBACnE,qEAAqE;oBACrE,qBAAqB;oBACrB,MAAM,WAAW,CAAC,+DAA+D,EAAE;wBACjF,MAAM,EAAE,cAAc;wBACtB,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACrC,GAAG,iBAAiB,CAAC,GAAG,EAAE,UAAU,CAAC;qBACtC,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBACvD,mEAAmE;oBACnE,iEAAiE;oBACjE,oEAAoE;oBACpE,kEAAkE;oBAClE,mEAAmE;oBACnE,kEAAkE;oBAClE,6DAA6D;oBAC7D,oEAAoE;oBACpE,iEAAiE;oBACjE,MAAM,YAAY,CAChB,yDAAyD,QAAQ,CAAC,MAAM,IAAI,EAC5E,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,GAAG,CAAC,WAAW,CAAC,eAAe,CAAC,EAAE,CAC5E,CAAC;gBACJ,CAAC;gBACD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC5B,oEAAoE;oBACpE,+DAA+D;oBAC/D,MAAM,QAAQ,CACZ,8HAA8H,EAC9H,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CACpE,CAAC;gBACJ,CAAC;gBACD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC5B,iEAAiE;oBACjE,qEAAqE;oBACrE,oEAAoE;oBACpE,oEAAoE;oBACpE,iEAAiE;oBACjE,+CAA+C;oBAC/C,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;oBAC7D,IAAI,SAAS,EAAE,CAAC;wBACd,MAAM,QAAQ,CACZ,0EAA0E,SAAS,sJAAsJ,EACzO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CACpE,CAAC;oBACJ,CAAC;gBACH,CAAC;gBACD,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE;oBACpD,OAAO,EAAE,iBAAiB;oBAC1B,IAAI,EAAE,EAAE,SAAS,EAAE;iBACpB,CAAC,CAAC;gBACH,IAAI,OAAO,YAAY,QAAQ,IAAI,OAAO,CAAC,IAAI,KAAK,gBAAgB,CAAC,aAAa,EAAE,CAAC;oBACnF,MAAM,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;gBAClF,CAAC;gBACD,uBAAuB,CAAC,OAAO,CAAC,CAAC;YACnC,CAAC;YACD,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;QACtC,CAAC,CACF,CAAC;IACJ,CAAC;CACF;AAED;;;;;;;;;GASG;AACH,SAAS,iBAAiB,CAAC,GAAY,EAAE,UAAyB;IAChE,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;IACjD,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,UAAU,IAAI,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC9D,OAAO;QACL,QAAQ,EAAE,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,8BAA8B,UAAU,IAAI,EAAE;KAC1F,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,kBAAkB,CAAC,QAAkB;IAClD,IAAI,MAA8C,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAkB,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAC7D,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;IAC7C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,iBAAiB,CAAC,CAAyC;IAClE,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC;IACvB,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO;QACL,UAAU,EAAE,CAAC,CAAC,EAAE;QAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,YAAY;QAC9B,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,SAAS;QACzC,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,EAAE;QAC9B,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI;QAC5B,cAAc,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;QACxC,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,KAAK;KAChC,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,CAAwC;IACvE,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC;IACvB,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACvB,OAAO;QACL,SAAS,EAAE,CAAC,CAAC,EAAE;QACf,KAAK,EAAE,CAAC,EAAE,KAAK,IAAI,oBAAoB;QACvC,YAAY,EAAE,CAAC,EAAE,YAAY,IAAI,mBAAmB;QACpD,UAAU,EAAE,CAAC,EAAE,UAAU,IAAI,EAAE;QAC/B,QAAQ,EAAE,CAAC,EAAE,QAAQ,IAAI,IAAI;QAC7B,QAAQ,EAAE,CAAC,EAAE,QAAQ,IAAI,EAAE;QAC3B,SAAS,EAAE,CAAC,EAAE,SAAS,IAAI,KAAK;KACjC,CAAC;AACJ,CAAC;AAED,8DAA8D;AAC9D,SAAS,kBAAkB,CACzB,QAAqE;IAErE,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC;SACvC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,WAAW,IAAI,EAAE,CAAC;aAC9C,MAAM,CACL,CAAC,CAAC,EAAiE,EAAE,CACnE,OAAO,CAAC,EAAE,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CACzD;aACA,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,SAAS;YAC7B,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;SACjD,CAAC,CAAC,CAAC;QACN,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,UAAU,EAAE,KAAK,IAAI,uBAAuB,EAAE,OAAO,EAAE,CAAC;IAC5E,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,mBAAmB,GAA2B;IAClD,GAAG,EAAE,GAAG;IACR,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;IACT,KAAK,EAAE,GAAG;IACV,KAAK,EAAE,GAAG;IACV,KAAK,EAAE,GAAG;IACV,KAAK,EAAE,GAAG;IACV,KAAK,EAAE,GAAG;IACV,KAAK,EAAE,GAAG;IACV,MAAM,EAAE,GAAG;CACZ,CAAC;AAEF,6DAA6D;AAC7D,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,IAAI,GAAG,IAAI;SACd,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC;SAChC,OAAO,CAAC,qBAAqB,EAAE,IAAI,CAAC;SACpC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC3B,OAAO,IAAI;SACR,OAAO,CAAC,gCAAgC,EAAE,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;QACjE,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAChD,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAChD,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,mBAAmB,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC;IAC5C,CAAC,CAAC;SACD,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC;SAC1B,IAAI,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,UAAU,CAAC,IAAmB;IACrC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,gFAAgF;IAChF,OAAO,qGAAqG,CAAC,IAAI,CAC/G,OAAO,CACR,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAC7B,SAAiB,EACjB,GAAwC;IAExC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,UAAU,IAAI,EAAE,CAAC;IACrC,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACrD,MAAM,QAAQ,GACZ,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACtF,MAAM,aAAa,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC;SAC5C,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;SACjE,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,OAAO;QACL,SAAS;QACT,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,oBAAoB;QACtC,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI;QAC5B,mBAAmB,EAAE,CAAC,CAAC,mBAAmB,IAAI,IAAI;QAClD,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,EAAE;QAC9B,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,IAAI;QACpC,aAAa,EAAE,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI;QAC9D,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,IAAI;QACpC,QAAQ;QACR,cAAc,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC;QAC9D,WAAW;QACX,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,KAAK;QAC/B,cAAc,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;KACzC,CAAC;AACJ,CAAC;AAED,gCAAgC;AAEhC,IAAI,QAA2C,CAAC;AAEhD,MAAM,UAAU,yBAAyB,CAAC,MAAiB,EAAE,OAAuB;IAClF,QAAQ,GAAG,IAAI,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,qFAAqF,CACtF,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @fileoverview The wall clock one MCP request may spend upstream, and the only
3
+ * thing that makes a tool's answer arrive inside a client's request timeout.
4
+ *
5
+ * A per-attempt deadline does not bound a tool call. Attempts multiply — four of
6
+ * them at 15s each, plus backoff, is already past a client's timeout — and so do
7
+ * the calls a tool makes: `regulations_get_cfr_section` reads a date, then the
8
+ * text, then the hierarchy, each with a retry loop of its own. Bounding those
9
+ * separately bounds nothing a caller can act on, so all of them draw down one
10
+ * clock, started at the first upstream call of a request and shared by every
11
+ * attempt, backoff, and service that request touches afterwards.
12
+ *
13
+ * {@link REQUEST_BUDGET_MS} sits well under the MCP TypeScript SDK's 60s default
14
+ * client request timeout (`DEFAULT_REQUEST_TIMEOUT_MSEC`), which neither this
15
+ * server nor the framework overrides — a server that reliably answers
16
+ * `upstream_unavailable` with the budget spent is worth more than one still
17
+ * retrying when the client has already given up and left the caller nothing to
18
+ * read.
19
+ *
20
+ * The budget belongs to a *request*. Out-of-band work — the eCFR mirror ingest,
21
+ * which is a background CLI/cron job pulling ~150 MB of XML per title — has no
22
+ * client waiting on it, so it takes {@link ingestBudget} and keeps its own long
23
+ * deadlines.
24
+ * @module services/request-budget
25
+ */
26
+ import type { Context } from '@cyanheads/mcp-ts-core';
27
+ /**
28
+ * Total wall clock a single MCP request may spend on upstream work.
29
+ *
30
+ * Deliberately a constant rather than an env var: the number that matters is the
31
+ * client's request timeout, which the server cannot see, and 45s leaves room
32
+ * under the only value that is actually specified anywhere (the SDK's 60s
33
+ * default) for the transport and the client's own overhead.
34
+ */
35
+ export declare const REQUEST_BUDGET_MS = 45000;
36
+ /** One request's share of wall clock, drawn down by every attempt it makes. */
37
+ export interface RequestBudget {
38
+ /** A single attempt's deadline: the shorter of the leg's own and what is left. */
39
+ attemptMs(preferredMs: number): number;
40
+ /** Whether the budget is spent. */
41
+ expired(): boolean;
42
+ /** Fires when the budget runs out, or when the caller aborts — whichever first. */
43
+ readonly signal: AbortSignal;
44
+ }
45
+ /**
46
+ * The budget for `ctx`, started on first use and shared by every later call in
47
+ * the same request.
48
+ */
49
+ export declare function requestBudget(ctx: Context): RequestBudget;
50
+ /**
51
+ * Claim `ctx` for work no client is waiting on, and hand back the unbounded
52
+ * budget every later lookup on it will find.
53
+ *
54
+ * Registering rather than returning a loose object is what makes the split hold.
55
+ * An ingest run is one context shared across many calls, and only the bulk read
56
+ * asks for a long deadline outright — the titles list its title loop is built
57
+ * from goes through the ordinary JSON helper, which would start a 45-second
58
+ * clock over a job with hours of work ahead of it. Call this once where the
59
+ * out-of-band context is built, and every later lookup finds it. Still
60
+ * cancellable: the ingest's own signal (SIGINT/SIGTERM) is what stops it.
61
+ */
62
+ export declare function ingestBudget(ctx: Context): RequestBudget;
63
+ //# sourceMappingURL=request-budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-budget.d.ts","sourceRoot":"","sources":["../../src/services/request-budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEtD;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,QAAS,CAAC;AAExC,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,kFAAkF;IAClF,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IACvC,mCAAmC;IACnC,OAAO,IAAI,OAAO,CAAC;IACnB,mFAAmF;IACnF,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAUD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,CAyBzD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,CAWxD"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * @fileoverview The wall clock one MCP request may spend upstream, and the only
3
+ * thing that makes a tool's answer arrive inside a client's request timeout.
4
+ *
5
+ * A per-attempt deadline does not bound a tool call. Attempts multiply — four of
6
+ * them at 15s each, plus backoff, is already past a client's timeout — and so do
7
+ * the calls a tool makes: `regulations_get_cfr_section` reads a date, then the
8
+ * text, then the hierarchy, each with a retry loop of its own. Bounding those
9
+ * separately bounds nothing a caller can act on, so all of them draw down one
10
+ * clock, started at the first upstream call of a request and shared by every
11
+ * attempt, backoff, and service that request touches afterwards.
12
+ *
13
+ * {@link REQUEST_BUDGET_MS} sits well under the MCP TypeScript SDK's 60s default
14
+ * client request timeout (`DEFAULT_REQUEST_TIMEOUT_MSEC`), which neither this
15
+ * server nor the framework overrides — a server that reliably answers
16
+ * `upstream_unavailable` with the budget spent is worth more than one still
17
+ * retrying when the client has already given up and left the caller nothing to
18
+ * read.
19
+ *
20
+ * The budget belongs to a *request*. Out-of-band work — the eCFR mirror ingest,
21
+ * which is a background CLI/cron job pulling ~150 MB of XML per title — has no
22
+ * client waiting on it, so it takes {@link ingestBudget} and keeps its own long
23
+ * deadlines.
24
+ * @module services/request-budget
25
+ */
26
+ /**
27
+ * Total wall clock a single MCP request may spend on upstream work.
28
+ *
29
+ * Deliberately a constant rather than an env var: the number that matters is the
30
+ * client's request timeout, which the server cannot see, and 45s leaves room
31
+ * under the only value that is actually specified anywhere (the SDK's 60s
32
+ * default) for the transport and the client's own overhead.
33
+ */
34
+ export const REQUEST_BUDGET_MS = 45_000;
35
+ /**
36
+ * WeakMap rather than a field on `Context`: the budget has to be shared by every
37
+ * service a request calls, and the handler `Context` is the one object all of
38
+ * them already receive. Keyed weakly so a finished request's budget is collected
39
+ * with it.
40
+ */
41
+ const budgets = new WeakMap();
42
+ /**
43
+ * The budget for `ctx`, started on first use and shared by every later call in
44
+ * the same request.
45
+ */
46
+ export function requestBudget(ctx) {
47
+ const existing = budgets.get(ctx);
48
+ if (existing)
49
+ return existing;
50
+ const deadline = Date.now() + REQUEST_BUDGET_MS;
51
+ const controller = new AbortController();
52
+ const timer = setTimeout(() => {
53
+ ctx.signal.removeEventListener('abort', clearOnCallerAbort);
54
+ controller.abort(new DOMException(`Request budget of ${REQUEST_BUDGET_MS}ms spent.`, 'TimeoutError'));
55
+ }, REQUEST_BUDGET_MS);
56
+ const clearOnCallerAbort = () => clearTimeout(timer);
57
+ if (ctx.signal.aborted)
58
+ clearOnCallerAbort();
59
+ else
60
+ ctx.signal.addEventListener('abort', clearOnCallerAbort, { once: true });
61
+ // Never blocks an exit: the budget outlives its request only as a timer.
62
+ timer.unref?.();
63
+ const budget = {
64
+ attemptMs: (preferredMs) => Math.max(1, Math.min(preferredMs, deadline - Date.now())),
65
+ expired: () => Date.now() >= deadline,
66
+ signal: AbortSignal.any([controller.signal, ctx.signal]),
67
+ };
68
+ budgets.set(ctx, budget);
69
+ return budget;
70
+ }
71
+ /**
72
+ * Claim `ctx` for work no client is waiting on, and hand back the unbounded
73
+ * budget every later lookup on it will find.
74
+ *
75
+ * Registering rather than returning a loose object is what makes the split hold.
76
+ * An ingest run is one context shared across many calls, and only the bulk read
77
+ * asks for a long deadline outright — the titles list its title loop is built
78
+ * from goes through the ordinary JSON helper, which would start a 45-second
79
+ * clock over a job with hours of work ahead of it. Call this once where the
80
+ * out-of-band context is built, and every later lookup finds it. Still
81
+ * cancellable: the ingest's own signal (SIGINT/SIGTERM) is what stops it.
82
+ */
83
+ export function ingestBudget(ctx) {
84
+ const existing = budgets.get(ctx);
85
+ if (existing)
86
+ return existing;
87
+ const budget = {
88
+ attemptMs: (preferredMs) => preferredMs,
89
+ expired: () => false,
90
+ signal: ctx.signal,
91
+ };
92
+ budgets.set(ctx, budget);
93
+ return budget;
94
+ }
95
+ //# sourceMappingURL=request-budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-budget.js","sourceRoot":"","sources":["../../src/services/request-budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAYxC;;;;;GAKG;AACH,MAAM,OAAO,GAAG,IAAI,OAAO,EAA0B,CAAC;AAEtD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,iBAAiB,CAAC;IAChD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QAC5B,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;QAC5D,UAAU,CAAC,KAAK,CACd,IAAI,YAAY,CAAC,qBAAqB,iBAAiB,WAAW,EAAE,cAAc,CAAC,CACpF,CAAC;IACJ,CAAC,EAAE,iBAAiB,CAAC,CAAC;IACtB,MAAM,kBAAkB,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACrD,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO;QAAE,kBAAkB,EAAE,CAAC;;QACxC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9E,yEAAyE;IACzE,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAEhB,MAAM,MAAM,GAAkB;QAC5B,SAAS,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACrF,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ;QACrC,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;KACzD,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACzB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,MAAM,GAAkB;QAC5B,SAAS,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW;QACvC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK;QACpB,MAAM,EAAE,GAAG,CAAC,MAAM;KACnB,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACzB,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,14 +1,21 @@
1
1
  /**
2
- * @fileoverview Shared helper that stamps the `upstream_unavailable` contract
3
- * reason onto a transport failure on its way out of a service.
2
+ * @fileoverview How every upstream call on this surface is run, and how whatever
3
+ * it fails with becomes `upstream_unavailable`. `runUpstream` is the one pipeline
4
+ * all three services fetch through — attempt deadline, retry, request budget,
5
+ * classification — and the rest are the pieces it composes: `fetchUpstream`
6
+ * raises a transport failure from a request that never produced a response,
7
+ * `rethrowTransportFailure` re-codes the 5xx statuses the status→code map does
8
+ * not call one, `retryTransportOnly` says which of them a retry can fix, and
9
+ * `withUpstreamReason` stamps the contract reason onto whichever transport
10
+ * failure reaches it.
4
11
  *
5
12
  * Every tool on this surface declares `upstream_unavailable`, but the failure it
6
- * describes is raised inside the framework's fetch pipeline, below any handler:
7
- * `fetchWithTimeout` classifies a 5xx, a network error, or a deadline, and
8
- * `withRetry` exhausts its attempts before the error surfaces. Nothing on that
9
- * path knows the calling tool's contract, so the answer used to reach the caller
10
- * with the right code and a null `data.reason` — the one failure an agent most
11
- * needs to switch on to decide whether to retry.
13
+ * describes is raised below any handler: the framework's fetch pipeline
14
+ * classifies a 5xx, a network error, or a deadline, and `withRetry` exhausts its
15
+ * attempts before the error surfaces. Nothing on that path knows the calling
16
+ * tool's contract, so the answer used to reach the caller with the right code and
17
+ * a null `data.reason` — the one failure an agent most needs to switch on to
18
+ * decide whether to retry.
12
19
  *
13
20
  * Services carry the reason the way the framework prescribes for code that has
14
21
  * no `ctx.fail`: put `reason` in the thrown error's `data`, and spread
@@ -18,18 +25,115 @@
18
25
  * @module services/upstream-failure
19
26
  */
20
27
  import type { Context } from '@cyanheads/mcp-ts-core';
28
+ import { type RequestContext } from '@cyanheads/mcp-ts-core/utils';
29
+ import type { RequestBudget } from '../services/request-budget.js';
30
+ /** Identifies the request in the raised error's message and `data`. */
31
+ interface UpstreamRequestContext {
32
+ /** Service method raising the request, e.g. `RegulationsGovService.getDocket`. */
33
+ operation: string;
34
+ /** Upstream named in the error message, e.g. `Regulations.gov`. */
35
+ service: string;
36
+ }
21
37
  /**
22
- * Run upstream work, stamping `upstream_unavailable` on a transport failure.
38
+ * Perform an upstream request, raising a classified `ServiceUnavailable` when it
39
+ * never produced a response.
23
40
  *
24
- * A `Timeout` is re-coded to `ServiceUnavailable` rather than kept as-is: the
25
- * reason is declared against one code on every tool that carries it, and a
26
- * contract that names a code the wire contradicts is worse than one that loses
27
- * the distinction between "did not answer in time" and "answered 503". The
28
- * distinction survives in the message, which the framework built from the
29
- * deadline it missed, and in the `cause` chain.
41
+ * `fetchWithTimeout` already does this for the services that route through it,
42
+ * but a service that has to branch on `response.status` calls `fetch` directly
43
+ * and gets no such classification — `fetch` rejects with whatever the runtime
44
+ * throws, which is not an `McpError`, so it reaches the caller as an
45
+ * unclassified `InternalError` with no reason. That is the gap this closes.
30
46
  *
31
- * Anything else passes through untouched — an already-classified domain failure,
32
- * a parse error, a caller abort, a programmer error.
47
+ * **Classified by position, not by message.** A rejection here means no
48
+ * `Response` was ever produced — DNS failure, refused connection, TLS failure, a
49
+ * socket dropped before headers — which is exactly the condition
50
+ * `upstream_unavailable` names. Matching the message text instead would be a rule
51
+ * per runtime: Bun answers both a refused connection and an unresolvable host
52
+ * with the one message "Unable to connect. Is the computer able to access the
53
+ * url?" and no `cause` at all, while Node says "fetch failed" and keeps the
54
+ * syscall detail one level below that. Neither puts `ECONNREFUSED`/`ENOTFOUND`
55
+ * where the framework's patterns for them look, so those never match. Reaching
56
+ * this catch is itself the evidence.
57
+ *
58
+ * An abort is the exception and re-throws untouched: the caller ending its own
59
+ * request is not an upstream failure, and the framework already classifies it.
60
+ * That covers an attempt deadline too — {@link runUpstream} composes it into
61
+ * `init.signal` and identifies its own expiry above this wrapper, so the raw
62
+ * rejection is exactly what it needs to see.
63
+ */
64
+ export declare function fetchUpstream(url: string, init: RequestInit, { service, operation }: UpstreamRequestContext): Promise<Response>;
65
+ /**
66
+ * Re-raise an upstream failure, re-coding a 5xx the status→code map does not
67
+ * already call a transport failure.
68
+ *
69
+ * Both HTTP helpers map 500 and 501 to `InternalError` and everything else in
70
+ * the range to `ServiceUnavailable`. That split is right for a status→code map —
71
+ * "the server has a bug" is not "the server is down" — but every definition here
72
+ * declares `upstream_unavailable` for a 5xx, and a 500 is the commonest one an
73
+ * upstream serves. Left alone it reached the caller as `InternalError` with no
74
+ * reason and no hint, and `withRetry` did not retry it, while the 502 beside it
75
+ * was retried and answered `upstream_unavailable`.
76
+ *
77
+ * **Keyed on the status, not the code or the message.** `data.status` is set only
78
+ * by the two helpers that read a real `Response`, so a caller abort (an
79
+ * `InternalError` carrying `errorSource: 'FetchAborted'` and no status) and a
80
+ * programmer error (no `data` at all) cannot reach this branch — which is the
81
+ * point, since both are `InternalError` too and neither is an unreachable
82
+ * upstream. An error already carrying a transport code is left alone rather than
83
+ * re-wrapped to the same code: a 504's `Timeout` then reaches
84
+ * {@link withUpstreamReason} as itself, and the 502/503 that need nothing done
85
+ * to them keep their own object and a `cause` chain one link shorter.
86
+ */
87
+ export declare function rethrowTransportFailure(error: unknown): never;
88
+ /**
89
+ * Retry predicate for a service that raises a non-retryable failure with a
90
+ * retryable code.
91
+ *
92
+ * `withRetry`'s default treats every `RateLimited` as transient unless the throw
93
+ * carries `data.retryable: false`. That flag is also the client's own backoff
94
+ * hint, so opting out through it tells the caller not to retry a failure the
95
+ * tools declare as retryable. Deciding it here keeps the wire honest: a transport
96
+ * failure is retried, an answer with a status is not, and an unclassified throw
97
+ * (a parse failure mid-pipeline) stays transient the way the default has it.
98
+ */
99
+ export declare function retryTransportOnly(error: unknown): boolean;
100
+ /** What {@link runUpstream} needs to know about the leg it is running. */
101
+ export interface UpstreamSpec {
102
+ /** The leg's own per-attempt deadline, before the budget has its say. */
103
+ attemptMs: number;
104
+ /** Retry backoff base, calibrated to the upstream. */
105
+ baseDelayMs: number;
106
+ /** Correlated log bindings, shared with the fetch inside the attempt. */
107
+ context: RequestContext;
108
+ /** Retry classification, where the leg's default differs from the framework's. */
109
+ isTransient?: ((error: unknown) => boolean) | undefined;
110
+ /** Service method raising the request, e.g. `EcfrService.getSectionText`. */
111
+ operation: string;
112
+ }
113
+ /**
114
+ * Run one upstream fetch+parse pipeline: an attempt deadline, `withRetry` around
115
+ * it, the request's shared wall-clock budget over both, and the classification
116
+ * that turns whatever comes out into a reason the caller can switch on.
117
+ *
118
+ * **Three deadlines, one clock.** `attempt` is handed the deadline for *this*
119
+ * attempt — the shorter of the leg's own and what the budget has left — and a
120
+ * signal that fires when it expires. The budget's signal drives `withRetry`, so
121
+ * a spent budget ends the loop and cuts short a backoff already sleeping rather
122
+ * than waiting out an attempt that cannot finish in time. Nothing here is
123
+ * per-call: a tool making three upstream calls draws all of them down the same
124
+ * budget, so the answer arrives inside the client's request timeout regardless
125
+ * of how the work is split.
126
+ *
127
+ * **A deadline is not a cancellation.** The attempt signal composes the caller's
128
+ * own, so both abort the same fetch — but the two answer differently, and have
129
+ * to. A deadline is the upstream failing to respond, so it leaves as a `Timeout`
130
+ * that {@link withUpstreamReason} stamps `upstream_unavailable`, retryable and
131
+ * actionable. A caller abort is the caller ending its own request, with nothing
132
+ * to recover and nothing to advertise, so it passes through with whatever
133
+ * classification the layer that caught it gave it. They are told apart by
134
+ * identity — this attempt's own abort reason, and the caller's `ctx.signal` —
135
+ * never by the rejection's text, which is a different string per runtime.
33
136
  */
34
- export declare function withUpstreamReason<T>(work: Promise<T>, ctx: Context): Promise<T>;
137
+ export declare function runUpstream<T>(ctx: Context, budget: RequestBudget, spec: UpstreamSpec, attempt: (deadlineMs: number, signal: AbortSignal) => Promise<T>): Promise<T>;
138
+ export {};
35
139
  //# sourceMappingURL=upstream-failure.d.ts.map