agentfootprint 11.2.0 → 11.4.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 (259) hide show
  1. package/AGENTS.md +1 -1
  2. package/CAPABILITIES.md +4 -0
  3. package/ai-instructions/claude-code/SKILL.md +1 -1
  4. package/dist/adapters/identity/verify/claims.js +3 -3
  5. package/dist/adapters/mcp/agentcoreRuntime/invoke.js +3 -2
  6. package/dist/adapters/mcp/agentcoreRuntime/invoke.js.map +1 -1
  7. package/dist/adapters/mcp/agentcoreRuntime/sessionBusy.js +6 -5
  8. package/dist/adapters/mcp/agentcoreRuntime/sessionBusy.js.map +1 -1
  9. package/dist/adapters/mcp/agentcoreRuntime/transport.js +8 -6
  10. package/dist/adapters/mcp/agentcoreRuntime/transport.js.map +1 -1
  11. package/dist/answer-account/account.js +15 -3
  12. package/dist/answer-account/account.js.map +1 -1
  13. package/dist/answer-account/facts/howSure.js +10 -22
  14. package/dist/answer-account/facts/howSure.js.map +1 -1
  15. package/dist/core/Agent.js +26 -3
  16. package/dist/core/Agent.js.map +1 -1
  17. package/dist/core/agent/AgentBuilder.js +69 -12
  18. package/dist/core/agent/AgentBuilder.js.map +1 -1
  19. package/dist/core/agent/assessment/assess.js +15 -4
  20. package/dist/core/agent/assessment/assess.js.map +1 -1
  21. package/dist/core/agent/assessment/compose.js +153 -15
  22. package/dist/core/agent/assessment/compose.js.map +1 -1
  23. package/dist/core/agent/assessment/reasons.js +35 -1
  24. package/dist/core/agent/assessment/reasons.js.map +1 -1
  25. package/dist/core/agent/assessment/sources.js +205 -0
  26. package/dist/core/agent/assessment/sources.js.map +1 -0
  27. package/dist/core/agent/assessment/stage.js +15 -4
  28. package/dist/core/agent/assessment/stage.js.map +1 -1
  29. package/dist/core/agent/buildAgentChart.js.map +1 -1
  30. package/dist/core/agent/buildToolRegistry.js +4 -1
  31. package/dist/core/agent/buildToolRegistry.js.map +1 -1
  32. package/dist/core/agent/evidence/evidenceIndex.js +30 -2
  33. package/dist/core/agent/evidence/evidenceIndex.js.map +1 -1
  34. package/dist/core/agent/evidence/extract.js +34 -5
  35. package/dist/core/agent/evidence/extract.js.map +1 -1
  36. package/dist/core/agent/evidence/figures.js +31 -3
  37. package/dist/core/agent/evidence/figures.js.map +1 -1
  38. package/dist/core/agent/evidence/numberPrecision.js +58 -2
  39. package/dist/core/agent/evidence/numberPrecision.js.map +1 -1
  40. package/dist/core/agent/honesty/mounts.js.map +1 -1
  41. package/dist/core/agent/stages/prepareFinal.js +33 -17
  42. package/dist/core/agent/stages/prepareFinal.js.map +1 -1
  43. package/dist/core/agent/stages/route.js +2 -1
  44. package/dist/core/agent/stages/route.js.map +1 -1
  45. package/dist/core/agent/stages/toolCalls.js +14 -1
  46. package/dist/core/agent/stages/toolCalls.js.map +1 -1
  47. package/dist/core/slots/buildToolsSlot.js +1 -1
  48. package/dist/core/slots/buildToolsSlot.js.map +1 -1
  49. package/dist/esm/adapters/identity/jwks.d.ts +2 -2
  50. package/dist/esm/adapters/identity/verify/claims.d.ts +3 -3
  51. package/dist/esm/adapters/identity/verify/claims.js +3 -3
  52. package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.d.ts +3 -2
  53. package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.js +3 -2
  54. package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.js.map +1 -1
  55. package/dist/esm/adapters/mcp/agentcoreRuntime/sessionBusy.d.ts +6 -5
  56. package/dist/esm/adapters/mcp/agentcoreRuntime/sessionBusy.js +6 -5
  57. package/dist/esm/adapters/mcp/agentcoreRuntime/sessionBusy.js.map +1 -1
  58. package/dist/esm/adapters/mcp/agentcoreRuntime/transport.d.ts +3 -1
  59. package/dist/esm/adapters/mcp/agentcoreRuntime/transport.js +9 -7
  60. package/dist/esm/adapters/mcp/agentcoreRuntime/transport.js.map +1 -1
  61. package/dist/esm/answer-account/account.js +16 -4
  62. package/dist/esm/answer-account/account.js.map +1 -1
  63. package/dist/esm/answer-account/facts/howSure.js +10 -22
  64. package/dist/esm/answer-account/facts/howSure.js.map +1 -1
  65. package/dist/esm/core/Agent.d.ts +2 -1
  66. package/dist/esm/core/Agent.js +26 -3
  67. package/dist/esm/core/Agent.js.map +1 -1
  68. package/dist/esm/core/agent/AgentBuilder.d.ts +22 -1
  69. package/dist/esm/core/agent/AgentBuilder.js +69 -12
  70. package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
  71. package/dist/esm/core/agent/assessment/assess.js +15 -4
  72. package/dist/esm/core/agent/assessment/assess.js.map +1 -1
  73. package/dist/esm/core/agent/assessment/compose.d.ts +82 -5
  74. package/dist/esm/core/agent/assessment/compose.js +148 -14
  75. package/dist/esm/core/agent/assessment/compose.js.map +1 -1
  76. package/dist/esm/core/agent/assessment/reasons.d.ts +17 -1
  77. package/dist/esm/core/agent/assessment/reasons.js +35 -1
  78. package/dist/esm/core/agent/assessment/reasons.js.map +1 -1
  79. package/dist/esm/core/agent/assessment/sources.d.ts +66 -0
  80. package/dist/esm/core/agent/assessment/sources.js +201 -0
  81. package/dist/esm/core/agent/assessment/sources.js.map +1 -0
  82. package/dist/esm/core/agent/assessment/stage.d.ts +17 -4
  83. package/dist/esm/core/agent/assessment/stage.js +16 -5
  84. package/dist/esm/core/agent/assessment/stage.js.map +1 -1
  85. package/dist/esm/core/agent/assessment/types.d.ts +37 -0
  86. package/dist/esm/core/agent/buildAgentChart.d.ts +8 -0
  87. package/dist/esm/core/agent/buildAgentChart.js.map +1 -1
  88. package/dist/esm/core/agent/buildToolRegistry.js +5 -2
  89. package/dist/esm/core/agent/buildToolRegistry.js.map +1 -1
  90. package/dist/esm/core/agent/evidence/evidenceIndex.d.ts +12 -2
  91. package/dist/esm/core/agent/evidence/evidenceIndex.js +30 -2
  92. package/dist/esm/core/agent/evidence/evidenceIndex.js.map +1 -1
  93. package/dist/esm/core/agent/evidence/extract.js +35 -6
  94. package/dist/esm/core/agent/evidence/extract.js.map +1 -1
  95. package/dist/esm/core/agent/evidence/figures.d.ts +6 -0
  96. package/dist/esm/core/agent/evidence/figures.js +32 -4
  97. package/dist/esm/core/agent/evidence/figures.js.map +1 -1
  98. package/dist/esm/core/agent/evidence/numberPrecision.d.ts +29 -1
  99. package/dist/esm/core/agent/evidence/numberPrecision.js +56 -1
  100. package/dist/esm/core/agent/evidence/numberPrecision.js.map +1 -1
  101. package/dist/esm/core/agent/honesty/mounts.d.ts +11 -2
  102. package/dist/esm/core/agent/honesty/mounts.js.map +1 -1
  103. package/dist/esm/core/agent/stages/prepareFinal.d.ts +19 -3
  104. package/dist/esm/core/agent/stages/prepareFinal.js +33 -17
  105. package/dist/esm/core/agent/stages/prepareFinal.js.map +1 -1
  106. package/dist/esm/core/agent/stages/route.js +2 -1
  107. package/dist/esm/core/agent/stages/route.js.map +1 -1
  108. package/dist/esm/core/agent/stages/toolCalls.js +14 -1
  109. package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
  110. package/dist/esm/core/agent/types.d.ts +16 -2
  111. package/dist/esm/core/slots/buildToolsSlot.js +1 -1
  112. package/dist/esm/core/slots/buildToolsSlot.js.map +1 -1
  113. package/dist/esm/events/payloads.d.ts +194 -0
  114. package/dist/esm/events/registry.d.ts +3 -1
  115. package/dist/esm/events/registry.js +2 -0
  116. package/dist/esm/events/registry.js.map +1 -1
  117. package/dist/esm/hosting/doorGuard.d.ts +3 -3
  118. package/dist/esm/hosting/doorGuard.js +2 -2
  119. package/dist/esm/hosting/nodeHost.d.ts +1 -1
  120. package/dist/esm/lib/displayName.d.ts +81 -0
  121. package/dist/esm/lib/displayName.js +119 -0
  122. package/dist/esm/lib/displayName.js.map +1 -0
  123. package/dist/esm/mcp/callLifetime.d.ts +49 -0
  124. package/dist/esm/mcp/callLifetime.js +99 -0
  125. package/dist/esm/mcp/callLifetime.js.map +1 -0
  126. package/dist/esm/mcp/mcpClient.d.ts +4 -1
  127. package/dist/esm/mcp/mcpClient.js +70 -28
  128. package/dist/esm/mcp/mcpClient.js.map +1 -1
  129. package/dist/esm/mcp/requestLedger.d.ts +97 -0
  130. package/dist/esm/mcp/requestLedger.js +192 -0
  131. package/dist/esm/mcp/requestLedger.js.map +1 -0
  132. package/dist/esm/mcp/seriesEvidence.d.ts +102 -0
  133. package/dist/esm/mcp/seriesEvidence.js +246 -0
  134. package/dist/esm/mcp/seriesEvidence.js.map +1 -0
  135. package/dist/esm/mcp/throttleRetry.d.ts +70 -35
  136. package/dist/esm/mcp/throttleRetry.js +181 -54
  137. package/dist/esm/mcp/throttleRetry.js.map +1 -1
  138. package/dist/esm/mcp/types.d.ts +12 -7
  139. package/dist/esm/redaction/knownStrings.js +30 -0
  140. package/dist/esm/redaction/knownStrings.js.map +1 -1
  141. package/dist/esm/security/PermissionPolicy.d.ts +1 -1
  142. package/dist/esm/security/PermissionPolicy.js +1 -1
  143. package/dist/esm/semantics/coverage/answer.d.ts +9 -1
  144. package/dist/esm/semantics/coverage/answer.js +50 -10
  145. package/dist/esm/semantics/coverage/answer.js.map +1 -1
  146. package/dist/esm/strategies/defaults/chatBubbleLiveStatus.d.ts +1 -1
  147. package/dist/esm/strategies/defaults/chatBubbleLiveStatus.js +1 -1
  148. package/dist/esm/tool-lint/analyze.d.ts +1 -1
  149. package/dist/esm/tool-lint/analyze.js +1 -1
  150. package/dist/esm/tool-lint/rules.d.ts +3 -3
  151. package/dist/esm/tool-lint/rules.js +3 -3
  152. package/dist/esm/tools/requestEvidence.d.ts +78 -0
  153. package/dist/esm/tools/requestEvidence.js +331 -0
  154. package/dist/esm/tools/requestEvidence.js.map +1 -0
  155. package/dist/esm/tools/tools.d.ts +30 -0
  156. package/dist/esm/tools/tools.js +16 -0
  157. package/dist/esm/tools/tools.js.map +1 -1
  158. package/dist/events/registry.js +2 -0
  159. package/dist/events/registry.js.map +1 -1
  160. package/dist/hosting/doorGuard.js +2 -2
  161. package/dist/lib/displayName.js +125 -0
  162. package/dist/lib/displayName.js.map +1 -0
  163. package/dist/mcp/callLifetime.js +103 -0
  164. package/dist/mcp/callLifetime.js.map +1 -0
  165. package/dist/mcp/mcpClient.js +69 -27
  166. package/dist/mcp/mcpClient.js.map +1 -1
  167. package/dist/mcp/requestLedger.js +196 -0
  168. package/dist/mcp/requestLedger.js.map +1 -0
  169. package/dist/mcp/seriesEvidence.js +251 -0
  170. package/dist/mcp/seriesEvidence.js.map +1 -0
  171. package/dist/mcp/throttleRetry.js +184 -55
  172. package/dist/mcp/throttleRetry.js.map +1 -1
  173. package/dist/redaction/knownStrings.js +30 -0
  174. package/dist/redaction/knownStrings.js.map +1 -1
  175. package/dist/security/PermissionPolicy.js +1 -1
  176. package/dist/semantics/coverage/answer.js +49 -9
  177. package/dist/semantics/coverage/answer.js.map +1 -1
  178. package/dist/strategies/defaults/chatBubbleLiveStatus.js +1 -1
  179. package/dist/tool-lint/analyze.js +1 -1
  180. package/dist/tool-lint/rules.js +3 -3
  181. package/dist/tools/requestEvidence.js +337 -0
  182. package/dist/tools/requestEvidence.js.map +1 -0
  183. package/dist/tools/tools.js +18 -1
  184. package/dist/tools/tools.js.map +1 -1
  185. package/dist/types/adapters/identity/jwks.d.ts +2 -2
  186. package/dist/types/adapters/identity/verify/claims.d.ts +3 -3
  187. package/dist/types/adapters/mcp/agentcoreRuntime/invoke.d.ts +3 -2
  188. package/dist/types/adapters/mcp/agentcoreRuntime/invoke.d.ts.map +1 -1
  189. package/dist/types/adapters/mcp/agentcoreRuntime/sessionBusy.d.ts +6 -5
  190. package/dist/types/adapters/mcp/agentcoreRuntime/sessionBusy.d.ts.map +1 -1
  191. package/dist/types/adapters/mcp/agentcoreRuntime/transport.d.ts +3 -1
  192. package/dist/types/adapters/mcp/agentcoreRuntime/transport.d.ts.map +1 -1
  193. package/dist/types/answer-account/account.d.ts.map +1 -1
  194. package/dist/types/answer-account/facts/howSure.d.ts.map +1 -1
  195. package/dist/types/core/Agent.d.ts +2 -1
  196. package/dist/types/core/Agent.d.ts.map +1 -1
  197. package/dist/types/core/agent/AgentBuilder.d.ts +22 -1
  198. package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
  199. package/dist/types/core/agent/assessment/assess.d.ts.map +1 -1
  200. package/dist/types/core/agent/assessment/compose.d.ts +82 -5
  201. package/dist/types/core/agent/assessment/compose.d.ts.map +1 -1
  202. package/dist/types/core/agent/assessment/reasons.d.ts +17 -1
  203. package/dist/types/core/agent/assessment/reasons.d.ts.map +1 -1
  204. package/dist/types/core/agent/assessment/sources.d.ts +67 -0
  205. package/dist/types/core/agent/assessment/sources.d.ts.map +1 -0
  206. package/dist/types/core/agent/assessment/stage.d.ts +17 -4
  207. package/dist/types/core/agent/assessment/stage.d.ts.map +1 -1
  208. package/dist/types/core/agent/assessment/types.d.ts +37 -0
  209. package/dist/types/core/agent/assessment/types.d.ts.map +1 -1
  210. package/dist/types/core/agent/buildAgentChart.d.ts +8 -0
  211. package/dist/types/core/agent/buildAgentChart.d.ts.map +1 -1
  212. package/dist/types/core/agent/buildToolRegistry.d.ts.map +1 -1
  213. package/dist/types/core/agent/evidence/evidenceIndex.d.ts +12 -2
  214. package/dist/types/core/agent/evidence/evidenceIndex.d.ts.map +1 -1
  215. package/dist/types/core/agent/evidence/extract.d.ts.map +1 -1
  216. package/dist/types/core/agent/evidence/figures.d.ts +6 -0
  217. package/dist/types/core/agent/evidence/figures.d.ts.map +1 -1
  218. package/dist/types/core/agent/evidence/numberPrecision.d.ts +29 -1
  219. package/dist/types/core/agent/evidence/numberPrecision.d.ts.map +1 -1
  220. package/dist/types/core/agent/honesty/mounts.d.ts +11 -2
  221. package/dist/types/core/agent/honesty/mounts.d.ts.map +1 -1
  222. package/dist/types/core/agent/stages/prepareFinal.d.ts +19 -3
  223. package/dist/types/core/agent/stages/prepareFinal.d.ts.map +1 -1
  224. package/dist/types/core/agent/stages/route.d.ts.map +1 -1
  225. package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
  226. package/dist/types/core/agent/types.d.ts +16 -2
  227. package/dist/types/core/agent/types.d.ts.map +1 -1
  228. package/dist/types/events/payloads.d.ts +194 -0
  229. package/dist/types/events/payloads.d.ts.map +1 -1
  230. package/dist/types/events/registry.d.ts +3 -1
  231. package/dist/types/events/registry.d.ts.map +1 -1
  232. package/dist/types/hosting/doorGuard.d.ts +3 -3
  233. package/dist/types/hosting/nodeHost.d.ts +1 -1
  234. package/dist/types/lib/displayName.d.ts +82 -0
  235. package/dist/types/lib/displayName.d.ts.map +1 -0
  236. package/dist/types/mcp/callLifetime.d.ts +50 -0
  237. package/dist/types/mcp/callLifetime.d.ts.map +1 -0
  238. package/dist/types/mcp/mcpClient.d.ts +4 -1
  239. package/dist/types/mcp/mcpClient.d.ts.map +1 -1
  240. package/dist/types/mcp/requestLedger.d.ts +98 -0
  241. package/dist/types/mcp/requestLedger.d.ts.map +1 -0
  242. package/dist/types/mcp/seriesEvidence.d.ts +103 -0
  243. package/dist/types/mcp/seriesEvidence.d.ts.map +1 -0
  244. package/dist/types/mcp/throttleRetry.d.ts +70 -35
  245. package/dist/types/mcp/throttleRetry.d.ts.map +1 -1
  246. package/dist/types/mcp/types.d.ts +12 -7
  247. package/dist/types/mcp/types.d.ts.map +1 -1
  248. package/dist/types/redaction/knownStrings.d.ts.map +1 -1
  249. package/dist/types/security/PermissionPolicy.d.ts +1 -1
  250. package/dist/types/semantics/coverage/answer.d.ts +9 -1
  251. package/dist/types/semantics/coverage/answer.d.ts.map +1 -1
  252. package/dist/types/strategies/defaults/chatBubbleLiveStatus.d.ts +1 -1
  253. package/dist/types/tool-lint/analyze.d.ts +1 -1
  254. package/dist/types/tool-lint/rules.d.ts +3 -3
  255. package/dist/types/tools/requestEvidence.d.ts +79 -0
  256. package/dist/types/tools/requestEvidence.d.ts.map +1 -0
  257. package/dist/types/tools/tools.d.ts +30 -0
  258. package/dist/types/tools/tools.d.ts.map +1 -1
  259. package/package.json +1 -1
@@ -0,0 +1,192 @@
1
+ /**
2
+ * requestLedger — which dispatched tool call an MCP request belongs to, so the
3
+ * retry series that sends it files its attempts into THAT call's run; and when
4
+ * the MCP SDK cancels a request, so the series sending it stops.
5
+ *
6
+ * Pattern: a per-connection ledger + the SDK transport's `send`, watched in place.
7
+ * Role: The middle of the evidence seam (`tools/requestEvidence.ts` is its
8
+ * door). The retry series runs inside the transport's `fetch`, which
9
+ * the MCP SDK calls with a serialized body and nothing else — no tool
10
+ * call, no run. Three hops carry the call down to it, each by an
11
+ * identity the hop already holds:
12
+ *
13
+ * 1. call → params `issue`: the MCP tool keys its ticket by the request's
14
+ * params OBJECT. The SDK puts that very object into the
15
+ * JSON-RPC message it hands the transport.
16
+ * 2. params → id the watched `send` finds the ticket by `message.params`
17
+ * and keys it by the JSON-RPC `id` the SDK assigned, until
18
+ * that send settles.
19
+ * 3. id → series `claim`: the series reads the `id` back out of the body
20
+ * it is about to send.
21
+ *
22
+ * CANCELLATION DOES NOT WAIT ON ATTRIBUTION. Every `tools/call` in flight gets
23
+ * an entry, ticket or not, and the SDK says when it gives a request up: it sends
24
+ * `notifications/cancelled` naming the request's id — on its own timeout, or
25
+ * when the call's signal fires — through this same `send`. The ledger aborts
26
+ * that request's series there and then, so a request nobody waits for is never
27
+ * asked again, even when its params could not be matched to a call.
28
+ *
29
+ * Nothing is added to the wire: the request the server receives is
30
+ * byte-identical, and the SDK's own options keep their meanings. Ids are the
31
+ * client's, one ledger per connection, so concurrent calls — and concurrent
32
+ * runs sharing one client — can never claim each other's request. A request
33
+ * that is not a `tools/call` (a `tools/list`, a notification, a response)
34
+ * claims nothing.
35
+ *
36
+ * `send` is installed as an OWN property of the transport instance — the same
37
+ * object, its own `send` bound to it, so a transport class with `#private`
38
+ * fields works as it always did. Assigning `send` again afterwards THROWS: a
39
+ * send that bypassed the ledger would quietly lose every call's attempts.
40
+ *
41
+ * What it does NOT do: retry, wait, or decide anything. The series is the one
42
+ * retry owner; this only tells it whose attempts it is making, and when the SDK
43
+ * has stopped waiting for them.
44
+ */
45
+ /** The method whose requests a tool call issues tickets for. */
46
+ const TOOLS_CALL = 'tools/call';
47
+ /** The notification the SDK sends when it gives up one of its own requests. */
48
+ const CANCELLED = 'notifications/cancelled';
49
+ /** Per connection: the tickets issued and not yet sent, and the requests being sent. */
50
+ export class RequestLedger {
51
+ /** Issued, not yet sent — keyed by the request's params object. Collected with it. */
52
+ issued = new WeakMap();
53
+ /** Tickets a request was bound to. */
54
+ bound = new WeakSet();
55
+ /** Every `tools/call` sent and not yet settled — keyed by its JSON-RPC id. */
56
+ sending = new Map();
57
+ calls = 0;
58
+ unboundNamed = false;
59
+ /** The call about to send `params` files its attempts through `ticket`. */
60
+ issue(params, ticket) {
61
+ this.issued.set(params, ticket);
62
+ }
63
+ /** Whether a request the transport sent was bound to `ticket`. */
64
+ wasBound(ticket) {
65
+ return this.bound.has(ticket);
66
+ }
67
+ /** How many `tools/call` requests the watched transport has sent — matched to a call or not. */
68
+ get toolCallsSent() {
69
+ return this.calls;
70
+ }
71
+ /** `true` the first time it is asked, then never again: an unmatched request is named once per connection. */
72
+ firstUnbound() {
73
+ if (this.unboundNamed)
74
+ return false;
75
+ this.unboundNamed = true;
76
+ return true;
77
+ }
78
+ /**
79
+ * Watch `transport`'s `send`: install a wrapped `send` as its OWN property, the
80
+ * original bound to the instance itself. Returns the SAME object — or
81
+ * `undefined` when it has no `send` to watch or refuses the property, and
82
+ * then nothing is watched and no call should expect its attempts filed.
83
+ */
84
+ watch(transport) {
85
+ const send = Reflect.get(transport, 'send');
86
+ if (typeof send !== 'function')
87
+ return undefined;
88
+ const original = send.bind(transport);
89
+ const watched = (message, options) => this.send(original, message, options);
90
+ try {
91
+ Object.defineProperty(transport, 'send', {
92
+ configurable: false,
93
+ enumerable: false,
94
+ get: () => watched,
95
+ set: () => {
96
+ throw new TypeError("mcpClient: this transport's `send` is watched by its request ledger, which " +
97
+ 'matches each tools/call request to the call that sent it. Assigning `send` ' +
98
+ 'again would send requests the ledger never sees, so it is refused.');
99
+ },
100
+ });
101
+ }
102
+ catch {
103
+ return undefined;
104
+ }
105
+ return transport;
106
+ }
107
+ /**
108
+ * The `tools/call` request `body` carries, while its send runs — its ticket
109
+ * when a call issued one, and the signal its cancellation fires. `undefined`
110
+ * for any other body. Parses only while some request is being sent.
111
+ */
112
+ claim(body) {
113
+ if (this.sending.size === 0 || typeof body !== 'string')
114
+ return undefined;
115
+ let message;
116
+ try {
117
+ message = JSON.parse(body);
118
+ }
119
+ catch {
120
+ return undefined;
121
+ }
122
+ const id = requestIdOf(message);
123
+ const entry = id === undefined ? undefined : this.sending.get(id);
124
+ if (entry === undefined)
125
+ return undefined;
126
+ return {
127
+ ...(entry.ticket !== undefined && { ticket: entry.ticket }),
128
+ cancelled: entry.cut.signal,
129
+ };
130
+ }
131
+ /** One message through the watched transport. */
132
+ send(original, message, options) {
133
+ this.cancelIfAsked(message);
134
+ const id = this.bind(message);
135
+ if (id === undefined)
136
+ return original(message, options);
137
+ const entry = this.sending.get(id);
138
+ const release = () => {
139
+ if (this.sending.get(id) === entry)
140
+ this.sending.delete(id);
141
+ };
142
+ try {
143
+ return Promise.resolve(original(message, options)).finally(release);
144
+ }
145
+ catch (err) {
146
+ release();
147
+ throw err;
148
+ }
149
+ }
150
+ /** Register a `tools/call` in flight, with the ticket its params were issued — if any. */
151
+ bind(message) {
152
+ const id = requestIdOf(message);
153
+ if (id === undefined)
154
+ return undefined;
155
+ this.calls += 1;
156
+ const params = message.params;
157
+ const ticket = params !== null && typeof params === 'object' ? this.issued.get(params) : undefined;
158
+ if (ticket !== undefined) {
159
+ // One request per ticket: a second message reusing these params is not this call's.
160
+ this.issued.delete(params);
161
+ this.bound.add(ticket);
162
+ }
163
+ this.sending.set(id, { ...(ticket !== undefined && { ticket }), cut: new AbortController() });
164
+ return id;
165
+ }
166
+ /** The SDK gave a request up: stop the series still sending it. */
167
+ cancelIfAsked(message) {
168
+ if (message === null || typeof message !== 'object' || Array.isArray(message))
169
+ return;
170
+ const { method, params } = message;
171
+ if (method !== CANCELLED || params === null || typeof params !== 'object')
172
+ return;
173
+ const requestId = params.requestId;
174
+ if (typeof requestId !== 'string' && typeof requestId !== 'number')
175
+ return;
176
+ this.sending.get(requestId)?.cut.abort(sdkCancelled());
177
+ }
178
+ }
179
+ /** The reason a series stops when the SDK cancelled its request — a fixed sentence. */
180
+ function sdkCancelled() {
181
+ return Object.assign(new Error('The MCP SDK cancelled this request.'), { name: 'AbortError' });
182
+ }
183
+ /** The id of a `tools/call` REQUEST — a response or a notification has none to claim. */
184
+ function requestIdOf(message) {
185
+ if (message === null || typeof message !== 'object' || Array.isArray(message))
186
+ return undefined;
187
+ const { method, id } = message;
188
+ if (method !== TOOLS_CALL)
189
+ return undefined;
190
+ return typeof id === 'string' || typeof id === 'number' ? id : undefined;
191
+ }
192
+ //# sourceMappingURL=requestLedger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requestLedger.js","sourceRoot":"","sources":["../../../src/mcp/requestLedger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * seriesEvidence — one MCP request's retry series, written down for its run.
3
+ *
4
+ * Pattern: a collector over footprintjs's attempt records, filed once.
5
+ * Role: The series (`throttleRetry.ts` · `Series`) is the one retry owner and
6
+ * the attempt runner makes one record per try; this turns each record
7
+ * into an allow-listed row and files the request's whole story — its
8
+ * rows, how many were not listed, and how it ended — to the call's sink
9
+ * (`tools/requestEvidence.ts`) exactly ONCE.
10
+ *
11
+ * WHAT A ROW MAY SAY. Numbers and the library's own words; never the server's
12
+ * answer, the call's arguments or an error's text. A failure is a fixed sentence
13
+ * and its category — a network or SDK error message can carry a URL with a token
14
+ * in it, a host's internal name or a server's reply.
15
+ *
16
+ * A RESPONSE IS NOT A SUCCESS. The runner records an attempt that returned a
17
+ * response as `ok` with the reason `succeeded`; here it is `answered`, with the
18
+ * status the server sent — a 503 delivered is `answered` + `503`, never success.
19
+ *
20
+ * EVERY REQUEST SENT IS COUNTED. Each attempt the series started is a row — or,
21
+ * past the cap, one more in `omitted` — so `rows + omitted` is the number of
22
+ * requests the series sent. An attempt a cancellation cuts in flight is a row
23
+ * too (`cut`), exactly as an attempt the deadline cuts is (`timed-out`). A
24
+ * request the series never sent — the next one after a cancelled wait — has no
25
+ * row.
26
+ *
27
+ * A CUT IS NOT A "NOT RUN". An attempt that ended without an answer — cut,
28
+ * timed out, or failed — was sent, and the server may have received it and run
29
+ * it. Its row says so (`remote: 'unknown'`); nothing here records it as not run.
30
+ *
31
+ * WHEN IT FILES. When the series ends — and, for a cancellation, at the moment the
32
+ * signal fires: a cancelled run stops waiting for its stage at once, so a record
33
+ * filed when the series later unwinds would land after the run was saved. The
34
+ * runner makes no record for an attempt it abandons at that moment or for a wait
35
+ * it was cut out of, so those are written here: the cut attempt's row and
36
+ * `during: 'request'`, or `during: 'wait'`. Anything the series reports after it
37
+ * has filed is not part of the request's story any more and is ignored.
38
+ */
39
+ import type { AttemptRecord } from 'footprintjs';
40
+ import type { ToolRequestAttempt, ToolRequestReason } from '../events/payloads.js';
41
+ import { type RequestEvidence, type RequestEvidenceSink } from '../tools/requestEvidence.js';
42
+ /** Where the request went, as a row may say it: the app's label for it, or its origin. */
43
+ export type RequestWhere = Pick<RequestEvidence, 'endpoint' | 'origin'>;
44
+ /** What the series saw of one attempt that its record does not hold. */
45
+ export interface AttemptSeen {
46
+ /** The response's status, when a response arrived. */
47
+ readonly status?: number;
48
+ /** The refusal a rule recognised in that response, when one did. */
49
+ readonly refusal?: {
50
+ readonly kind: 'throttle' | 'session-busy';
51
+ readonly retryAfterMs?: number;
52
+ };
53
+ }
54
+ /** Why the series' `retryOn` said no — the reasons the runner calls `declined`. */
55
+ export type DeclineReason = Extract<ToolRequestReason, 'exhausted' | 'wait-limit' | 'no-time-left' | 'not-replayable' | 'not-retryable'>;
56
+ /** One request's evidence, collected as its series runs and filed once. */
57
+ export declare class SeriesEvidence {
58
+ private readonly sink;
59
+ private readonly where;
60
+ private readonly rows;
61
+ private omitted;
62
+ private last;
63
+ private filed;
64
+ constructor(sink: RequestEvidenceSink, where: RequestWhere);
65
+ /** One attempt as the runner recorded it. */
66
+ attempt(record: AttemptRecord, seen: AttemptSeen | undefined, declined?: DeclineReason): void;
67
+ /**
68
+ * The caller's cancellation cut attempt `n` in flight. It was sent — the
69
+ * server may have it, and may have run it — so it is a row, `cut`, with the
70
+ * remote outcome `unknown`; then the request's end says the same.
71
+ */
72
+ cutInFlight(n: number): void;
73
+ /**
74
+ * The caller's cancellation landed with NO request in flight: between two —
75
+ * `during: 'wait'`, the next request never sent — or before the first, when
76
+ * nothing was sent and there is no `during`. No row is added: there is no
77
+ * request to account for. A request that had already ended keeps its end.
78
+ */
79
+ cancelled(): void;
80
+ /**
81
+ * The series delivered a response. It is the last attempt's — an answer, or a
82
+ * refusal it will not ask again after. A refusal it MEANT to ask again after
83
+ * is delivered when the deadline lands inside the wait: the runner's wait
84
+ * ends early, the series stops, and the end says so (`no-time-left`, during
85
+ * the `wait`).
86
+ */
87
+ delivered(): void;
88
+ /**
89
+ * The series threw. The end is the last attempt's when that attempt ended it
90
+ * (a failure, a timed-out request). The rest is defensive — footprintjs 10.6's
91
+ * runner never throws without a record but for a cancellation, which is filed
92
+ * as one: a deadline that had passed before the first request (`timed-out`,
93
+ * no `during`, nothing sent) or one a future runner reports from inside a wait
94
+ * (`during: 'wait'`); anything else is filed as a failure the record cannot
95
+ * account for, so a request is never left unfiled.
96
+ */
97
+ threw(outOfTime: boolean): void;
98
+ private add;
99
+ private file;
100
+ }
101
+ /** One record as a row — see the module note for what a row may say. */
102
+ export declare function rowOf(record: AttemptRecord, seen: AttemptSeen | undefined, declined?: DeclineReason): ToolRequestAttempt;
@@ -0,0 +1,246 @@
1
+ /**
2
+ * seriesEvidence — one MCP request's retry series, written down for its run.
3
+ *
4
+ * Pattern: a collector over footprintjs's attempt records, filed once.
5
+ * Role: The series (`throttleRetry.ts` · `Series`) is the one retry owner and
6
+ * the attempt runner makes one record per try; this turns each record
7
+ * into an allow-listed row and files the request's whole story — its
8
+ * rows, how many were not listed, and how it ended — to the call's sink
9
+ * (`tools/requestEvidence.ts`) exactly ONCE.
10
+ *
11
+ * WHAT A ROW MAY SAY. Numbers and the library's own words; never the server's
12
+ * answer, the call's arguments or an error's text. A failure is a fixed sentence
13
+ * and its category — a network or SDK error message can carry a URL with a token
14
+ * in it, a host's internal name or a server's reply.
15
+ *
16
+ * A RESPONSE IS NOT A SUCCESS. The runner records an attempt that returned a
17
+ * response as `ok` with the reason `succeeded`; here it is `answered`, with the
18
+ * status the server sent — a 503 delivered is `answered` + `503`, never success.
19
+ *
20
+ * EVERY REQUEST SENT IS COUNTED. Each attempt the series started is a row — or,
21
+ * past the cap, one more in `omitted` — so `rows + omitted` is the number of
22
+ * requests the series sent. An attempt a cancellation cuts in flight is a row
23
+ * too (`cut`), exactly as an attempt the deadline cuts is (`timed-out`). A
24
+ * request the series never sent — the next one after a cancelled wait — has no
25
+ * row.
26
+ *
27
+ * A CUT IS NOT A "NOT RUN". An attempt that ended without an answer — cut,
28
+ * timed out, or failed — was sent, and the server may have received it and run
29
+ * it. Its row says so (`remote: 'unknown'`); nothing here records it as not run.
30
+ *
31
+ * WHEN IT FILES. When the series ends — and, for a cancellation, at the moment the
32
+ * signal fires: a cancelled run stops waiting for its stage at once, so a record
33
+ * filed when the series later unwinds would land after the run was saved. The
34
+ * runner makes no record for an attempt it abandons at that moment or for a wait
35
+ * it was cut out of, so those are written here: the cut attempt's row and
36
+ * `during: 'request'`, or `during: 'wait'`. Anything the series reports after it
37
+ * has filed is not part of the request's story any more and is ignored.
38
+ */
39
+ import { MAX_REQUEST_ATTEMPT_ROWS, } from '../tools/requestEvidence.js';
40
+ const FAILED = 'The request failed before an answer arrived. Its error is not kept.';
41
+ const OUT_OF_TIME = 'The call ran out of time before an answer arrived.';
42
+ /** One request's evidence, collected as its series runs and filed once. */
43
+ export class SeriesEvidence {
44
+ sink;
45
+ where;
46
+ rows = [];
47
+ omitted = 0;
48
+ last;
49
+ filed = false;
50
+ constructor(sink, where) {
51
+ this.sink = sink;
52
+ this.where = where;
53
+ }
54
+ /** One attempt as the runner recorded it. */
55
+ attempt(record, seen, declined) {
56
+ if (this.filed)
57
+ return;
58
+ this.add(rowOf(record, seen, declined));
59
+ }
60
+ /**
61
+ * The caller's cancellation cut attempt `n` in flight. It was sent — the
62
+ * server may have it, and may have run it — so it is a row, `cut`, with the
63
+ * remote outcome `unknown`; then the request's end says the same.
64
+ */
65
+ cutInFlight(n) {
66
+ if (this.filed)
67
+ return;
68
+ this.add({ attempt: n, outcome: 'cut', reason: 'cancelled', remote: 'unknown' });
69
+ this.file({ outcome: 'cut', reason: 'cancelled', during: 'request', remote: 'unknown' });
70
+ }
71
+ /**
72
+ * The caller's cancellation landed with NO request in flight: between two —
73
+ * `during: 'wait'`, the next request never sent — or before the first, when
74
+ * nothing was sent and there is no `during`. No row is added: there is no
75
+ * request to account for. A request that had already ended keeps its end.
76
+ */
77
+ cancelled() {
78
+ const last = this.last;
79
+ if (last !== undefined && last.reason !== 'retryable') {
80
+ this.file(endOf(last));
81
+ return;
82
+ }
83
+ this.file({
84
+ outcome: 'cancelled',
85
+ reason: 'cancelled',
86
+ ...(last !== undefined && { during: 'wait' }),
87
+ });
88
+ }
89
+ /**
90
+ * The series delivered a response. It is the last attempt's — an answer, or a
91
+ * refusal it will not ask again after. A refusal it MEANT to ask again after
92
+ * is delivered when the deadline lands inside the wait: the runner's wait
93
+ * ends early, the series stops, and the end says so (`no-time-left`, during
94
+ * the `wait`).
95
+ */
96
+ delivered() {
97
+ const last = this.last;
98
+ if (last === undefined) {
99
+ this.file(UNACCOUNTED);
100
+ return;
101
+ }
102
+ this.file(last.reason === 'retryable'
103
+ ? { ...endOf(last), reason: 'no-time-left', during: 'wait' }
104
+ : endOf(last));
105
+ }
106
+ /**
107
+ * The series threw. The end is the last attempt's when that attempt ended it
108
+ * (a failure, a timed-out request). The rest is defensive — footprintjs 10.6's
109
+ * runner never throws without a record but for a cancellation, which is filed
110
+ * as one: a deadline that had passed before the first request (`timed-out`,
111
+ * no `during`, nothing sent) or one a future runner reports from inside a wait
112
+ * (`during: 'wait'`); anything else is filed as a failure the record cannot
113
+ * account for, so a request is never left unfiled.
114
+ */
115
+ threw(outOfTime) {
116
+ const last = this.last;
117
+ if (last !== undefined && last.reason !== 'retryable') {
118
+ this.file(endOf(last));
119
+ return;
120
+ }
121
+ if (!outOfTime) {
122
+ this.file(UNACCOUNTED);
123
+ return;
124
+ }
125
+ this.file({
126
+ outcome: 'timed-out',
127
+ reason: 'no-time-left',
128
+ failure: 'timeout',
129
+ ...(last !== undefined && { during: 'wait' }),
130
+ error: { message: OUT_OF_TIME, code: 'timeout' },
131
+ });
132
+ }
133
+ add(row) {
134
+ this.last = row;
135
+ if (this.rows.length < MAX_REQUEST_ATTEMPT_ROWS)
136
+ this.rows.push(row);
137
+ else
138
+ this.omitted += 1;
139
+ }
140
+ file(end) {
141
+ if (this.filed)
142
+ return;
143
+ this.filed = true;
144
+ try {
145
+ this.sink.file({ ...this.where, attempts: [...this.rows], omitted: this.omitted, end });
146
+ }
147
+ catch {
148
+ // The library's sink never throws; one that does must not fail the call.
149
+ }
150
+ }
151
+ }
152
+ /**
153
+ * An end no attempt accounts for — never seen; kept so a request is never left
154
+ * unfiled, and never claiming more than is known.
155
+ */
156
+ const UNACCOUNTED = {
157
+ outcome: 'failed',
158
+ reason: 'not-retryable',
159
+ failure: 'unknown',
160
+ error: { message: FAILED, code: 'unknown' },
161
+ remote: 'unknown',
162
+ };
163
+ /** One record as a row — see the module note for what a row may say. */
164
+ export function rowOf(record, seen, declined) {
165
+ const outcome = outcomeOf(record, seen);
166
+ const reason = reasonOf(record, declined);
167
+ const refusal = outcome === 'refused' ? seen?.refusal : undefined;
168
+ return {
169
+ attempt: record.attempt,
170
+ outcome,
171
+ reason,
172
+ ...((outcome === 'answered' || outcome === 'refused') &&
173
+ seen?.status !== undefined && { status: seen.status }),
174
+ ...(refusal !== undefined && { kind: refusal.kind }),
175
+ ...(outcome !== 'answered' &&
176
+ outcome !== 'cut' &&
177
+ record.category !== undefined && { failure: record.category }),
178
+ ...(reason === 'retryable' && { waitMs: record.delayMs ?? 0 }),
179
+ ...(refusal?.retryAfterMs !== undefined && { retryAfterMs: refusal.retryAfterMs }),
180
+ ...((outcome === 'failed' || outcome === 'timed-out') && {
181
+ error: errorOf(outcome, record.category),
182
+ }),
183
+ ...(noAnswer(outcome) && { remote: 'unknown' }),
184
+ };
185
+ }
186
+ /** An attempt that ended without an answer — the server may have run it, or not. */
187
+ function noAnswer(outcome) {
188
+ return outcome === 'failed' || outcome === 'timed-out' || outcome === 'cut';
189
+ }
190
+ function outcomeOf(record, seen) {
191
+ switch (record.outcome) {
192
+ case 'ok':
193
+ return 'answered';
194
+ case 'timeout':
195
+ return 'timed-out';
196
+ case 'failed':
197
+ return seen?.refusal !== undefined ? 'refused' : 'failed';
198
+ case 'aborted':
199
+ // Cut in flight by the series' cancellation. The cancellation itself files
200
+ // this row first (`cutInFlight`), so the record is seen only if it did not.
201
+ return 'cut';
202
+ default:
203
+ // `paused` cannot happen inside a fetch.
204
+ return 'failed';
205
+ }
206
+ }
207
+ function reasonOf(record, declined) {
208
+ if (record.outcome === 'ok')
209
+ return 'answered';
210
+ if (record.next === 'retry')
211
+ return 'retryable';
212
+ if (record.outcome === 'timeout')
213
+ return 'no-time-left';
214
+ switch (record.reason) {
215
+ case 'exhausted':
216
+ return 'exhausted';
217
+ case 'no-time-left':
218
+ return 'no-time-left';
219
+ case 'aborted':
220
+ return 'cancelled';
221
+ case 'declined':
222
+ return declined ?? 'not-retryable';
223
+ default:
224
+ return 'not-retryable';
225
+ }
226
+ }
227
+ function errorOf(outcome, category) {
228
+ return outcome === 'timed-out'
229
+ ? { message: OUT_OF_TIME, code: category ?? 'timeout' }
230
+ : { message: FAILED, code: category ?? 'unknown' };
231
+ }
232
+ /** How a request ended, when it ended with its last attempt. */
233
+ function endOf(last) {
234
+ const { outcome, reason, status, kind, failure, error, remote } = last;
235
+ return {
236
+ outcome,
237
+ reason,
238
+ ...(status !== undefined && { status }),
239
+ ...(kind !== undefined && { kind }),
240
+ ...(failure !== undefined && { failure }),
241
+ ...((outcome === 'timed-out' || outcome === 'cut') && { during: 'request' }),
242
+ ...(error !== undefined && { error }),
243
+ ...(remote !== undefined && { remote }),
244
+ };
245
+ }
246
+ //# sourceMappingURL=seriesEvidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seriesEvidence.js","sourceRoot":"","sources":["../../../src/mcp/seriesEvidence.ts"],"names":[],"mappings":"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"}