agentfootprint 11.3.0 → 11.5.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 (227) hide show
  1. package/CAPABILITIES.md +4 -1
  2. package/dist/adapters/mcp/agentcoreRuntime/invoke.js +7 -6
  3. package/dist/adapters/mcp/agentcoreRuntime/invoke.js.map +1 -1
  4. package/dist/adapters/mcp/agentcoreRuntime/sessionBusy.js +36 -2
  5. package/dist/adapters/mcp/agentcoreRuntime/sessionBusy.js.map +1 -1
  6. package/dist/adapters/mcp/agentcoreRuntime/transport.js +3 -1
  7. package/dist/adapters/mcp/agentcoreRuntime/transport.js.map +1 -1
  8. package/dist/answer-account/account.js +15 -3
  9. package/dist/answer-account/account.js.map +1 -1
  10. package/dist/answer-account/facts/howSure.js +10 -22
  11. package/dist/answer-account/facts/howSure.js.map +1 -1
  12. package/dist/core/Agent.js +26 -3
  13. package/dist/core/Agent.js.map +1 -1
  14. package/dist/core/agent/AgentBuilder.js +69 -12
  15. package/dist/core/agent/AgentBuilder.js.map +1 -1
  16. package/dist/core/agent/assessment/assess.js +15 -4
  17. package/dist/core/agent/assessment/assess.js.map +1 -1
  18. package/dist/core/agent/assessment/compose.js +153 -15
  19. package/dist/core/agent/assessment/compose.js.map +1 -1
  20. package/dist/core/agent/assessment/reasons.js +35 -1
  21. package/dist/core/agent/assessment/reasons.js.map +1 -1
  22. package/dist/core/agent/assessment/sources.js +205 -0
  23. package/dist/core/agent/assessment/sources.js.map +1 -0
  24. package/dist/core/agent/assessment/stage.js +15 -4
  25. package/dist/core/agent/assessment/stage.js.map +1 -1
  26. package/dist/core/agent/buildAgentChart.js.map +1 -1
  27. package/dist/core/agent/buildToolRegistry.js +3 -0
  28. package/dist/core/agent/buildToolRegistry.js.map +1 -1
  29. package/dist/core/agent/evidence/numberPrecision.js.map +1 -1
  30. package/dist/core/agent/honesty/mounts.js.map +1 -1
  31. package/dist/core/agent/stages/prepareFinal.js +33 -17
  32. package/dist/core/agent/stages/prepareFinal.js.map +1 -1
  33. package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.d.ts +7 -6
  34. package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.js +7 -6
  35. package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.js.map +1 -1
  36. package/dist/esm/adapters/mcp/agentcoreRuntime/sessionBusy.d.ts +32 -1
  37. package/dist/esm/adapters/mcp/agentcoreRuntime/sessionBusy.js +35 -1
  38. package/dist/esm/adapters/mcp/agentcoreRuntime/sessionBusy.js.map +1 -1
  39. package/dist/esm/adapters/mcp/agentcoreRuntime/transport.js +4 -2
  40. package/dist/esm/adapters/mcp/agentcoreRuntime/transport.js.map +1 -1
  41. package/dist/esm/answer-account/account.js +16 -4
  42. package/dist/esm/answer-account/account.js.map +1 -1
  43. package/dist/esm/answer-account/facts/howSure.js +10 -22
  44. package/dist/esm/answer-account/facts/howSure.js.map +1 -1
  45. package/dist/esm/core/Agent.d.ts +2 -1
  46. package/dist/esm/core/Agent.js +26 -3
  47. package/dist/esm/core/Agent.js.map +1 -1
  48. package/dist/esm/core/agent/AgentBuilder.d.ts +22 -1
  49. package/dist/esm/core/agent/AgentBuilder.js +69 -12
  50. package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
  51. package/dist/esm/core/agent/assessment/assess.js +15 -4
  52. package/dist/esm/core/agent/assessment/assess.js.map +1 -1
  53. package/dist/esm/core/agent/assessment/compose.d.ts +82 -5
  54. package/dist/esm/core/agent/assessment/compose.js +148 -14
  55. package/dist/esm/core/agent/assessment/compose.js.map +1 -1
  56. package/dist/esm/core/agent/assessment/reasons.d.ts +17 -1
  57. package/dist/esm/core/agent/assessment/reasons.js +35 -1
  58. package/dist/esm/core/agent/assessment/reasons.js.map +1 -1
  59. package/dist/esm/core/agent/assessment/sources.d.ts +66 -0
  60. package/dist/esm/core/agent/assessment/sources.js +201 -0
  61. package/dist/esm/core/agent/assessment/sources.js.map +1 -0
  62. package/dist/esm/core/agent/assessment/stage.d.ts +17 -4
  63. package/dist/esm/core/agent/assessment/stage.js +16 -5
  64. package/dist/esm/core/agent/assessment/stage.js.map +1 -1
  65. package/dist/esm/core/agent/assessment/types.d.ts +37 -0
  66. package/dist/esm/core/agent/buildAgentChart.d.ts +8 -0
  67. package/dist/esm/core/agent/buildAgentChart.js.map +1 -1
  68. package/dist/esm/core/agent/buildToolRegistry.js +4 -1
  69. package/dist/esm/core/agent/buildToolRegistry.js.map +1 -1
  70. package/dist/esm/core/agent/evidence/numberPrecision.d.ts +3 -2
  71. package/dist/esm/core/agent/evidence/numberPrecision.js.map +1 -1
  72. package/dist/esm/core/agent/honesty/mounts.d.ts +11 -2
  73. package/dist/esm/core/agent/honesty/mounts.js.map +1 -1
  74. package/dist/esm/core/agent/stages/prepareFinal.d.ts +19 -3
  75. package/dist/esm/core/agent/stages/prepareFinal.js +33 -17
  76. package/dist/esm/core/agent/stages/prepareFinal.js.map +1 -1
  77. package/dist/esm/core/agent/types.d.ts +16 -2
  78. package/dist/esm/events/payloads.d.ts +137 -27
  79. package/dist/esm/lib/displayName.d.ts +81 -0
  80. package/dist/esm/lib/displayName.js +119 -0
  81. package/dist/esm/lib/displayName.js.map +1 -0
  82. package/dist/esm/mcp/callLifetime.d.ts +57 -14
  83. package/dist/esm/mcp/callLifetime.js +67 -19
  84. package/dist/esm/mcp/callLifetime.js.map +1 -1
  85. package/dist/esm/mcp/callMarker.d.ts +43 -0
  86. package/dist/esm/mcp/callMarker.js +69 -0
  87. package/dist/esm/mcp/callMarker.js.map +1 -0
  88. package/dist/esm/mcp/connectionRefusals.js +7 -0
  89. package/dist/esm/mcp/connectionRefusals.js.map +1 -1
  90. package/dist/esm/mcp/index.d.ts +2 -0
  91. package/dist/esm/mcp/index.js +3 -0
  92. package/dist/esm/mcp/index.js.map +1 -1
  93. package/dist/esm/mcp/mcpClient.js +93 -26
  94. package/dist/esm/mcp/mcpClient.js.map +1 -1
  95. package/dist/esm/mcp/replay.d.ts +283 -0
  96. package/dist/esm/mcp/replay.js +401 -0
  97. package/dist/esm/mcp/replay.js.map +1 -0
  98. package/dist/esm/mcp/replayUnavailable.d.ts +55 -0
  99. package/dist/esm/mcp/replayUnavailable.js +74 -0
  100. package/dist/esm/mcp/replayUnavailable.js.map +1 -0
  101. package/dist/esm/mcp/requestLedger.d.ts +115 -32
  102. package/dist/esm/mcp/requestLedger.js +193 -52
  103. package/dist/esm/mcp/requestLedger.js.map +1 -1
  104. package/dist/esm/mcp/seriesEvidence.d.ts +73 -15
  105. package/dist/esm/mcp/seriesEvidence.js +114 -21
  106. package/dist/esm/mcp/seriesEvidence.js.map +1 -1
  107. package/dist/esm/mcp/throttleRetry.d.ts +86 -42
  108. package/dist/esm/mcp/throttleRetry.js +158 -50
  109. package/dist/esm/mcp/throttleRetry.js.map +1 -1
  110. package/dist/esm/mcp/toolResult.d.ts +6 -0
  111. package/dist/esm/mcp/toolResult.js +15 -0
  112. package/dist/esm/mcp/toolResult.js.map +1 -1
  113. package/dist/esm/mcp/types.d.ts +70 -8
  114. package/dist/esm/redaction/knownStrings.js +14 -0
  115. package/dist/esm/redaction/knownStrings.js.map +1 -1
  116. package/dist/esm/semantics/coverage/answer.d.ts +9 -1
  117. package/dist/esm/semantics/coverage/answer.js +50 -10
  118. package/dist/esm/semantics/coverage/answer.js.map +1 -1
  119. package/dist/esm/tool-providers/index.d.ts +2 -2
  120. package/dist/esm/tool-providers/index.js +4 -0
  121. package/dist/esm/tool-providers/index.js.map +1 -1
  122. package/dist/esm/tools/requestEvidence.js +60 -0
  123. package/dist/esm/tools/requestEvidence.js.map +1 -1
  124. package/dist/esm/tools/tools.d.ts +30 -0
  125. package/dist/esm/tools/tools.js +16 -0
  126. package/dist/esm/tools/tools.js.map +1 -1
  127. package/dist/lib/displayName.js +125 -0
  128. package/dist/lib/displayName.js.map +1 -0
  129. package/dist/mcp/callLifetime.js +66 -18
  130. package/dist/mcp/callLifetime.js.map +1 -1
  131. package/dist/mcp/callMarker.js +74 -0
  132. package/dist/mcp/callMarker.js.map +1 -0
  133. package/dist/mcp/connectionRefusals.js +7 -0
  134. package/dist/mcp/connectionRefusals.js.map +1 -1
  135. package/dist/mcp/index.js +5 -1
  136. package/dist/mcp/index.js.map +1 -1
  137. package/dist/mcp/mcpClient.js +91 -24
  138. package/dist/mcp/mcpClient.js.map +1 -1
  139. package/dist/mcp/replay.js +411 -0
  140. package/dist/mcp/replay.js.map +1 -0
  141. package/dist/mcp/replayUnavailable.js +79 -0
  142. package/dist/mcp/replayUnavailable.js.map +1 -0
  143. package/dist/mcp/requestLedger.js +193 -52
  144. package/dist/mcp/requestLedger.js.map +1 -1
  145. package/dist/mcp/seriesEvidence.js +116 -22
  146. package/dist/mcp/seriesEvidence.js.map +1 -1
  147. package/dist/mcp/throttleRetry.js +160 -51
  148. package/dist/mcp/throttleRetry.js.map +1 -1
  149. package/dist/mcp/toolResult.js +17 -1
  150. package/dist/mcp/toolResult.js.map +1 -1
  151. package/dist/redaction/knownStrings.js +14 -0
  152. package/dist/redaction/knownStrings.js.map +1 -1
  153. package/dist/semantics/coverage/answer.js +49 -9
  154. package/dist/semantics/coverage/answer.js.map +1 -1
  155. package/dist/tool-providers/index.js +5 -1
  156. package/dist/tool-providers/index.js.map +1 -1
  157. package/dist/tools/requestEvidence.js +60 -0
  158. package/dist/tools/requestEvidence.js.map +1 -1
  159. package/dist/tools/tools.js +18 -1
  160. package/dist/tools/tools.js.map +1 -1
  161. package/dist/types/adapters/mcp/agentcoreRuntime/invoke.d.ts +7 -6
  162. package/dist/types/adapters/mcp/agentcoreRuntime/invoke.d.ts.map +1 -1
  163. package/dist/types/adapters/mcp/agentcoreRuntime/sessionBusy.d.ts +32 -1
  164. package/dist/types/adapters/mcp/agentcoreRuntime/sessionBusy.d.ts.map +1 -1
  165. package/dist/types/adapters/mcp/agentcoreRuntime/transport.d.ts.map +1 -1
  166. package/dist/types/answer-account/account.d.ts.map +1 -1
  167. package/dist/types/answer-account/facts/howSure.d.ts.map +1 -1
  168. package/dist/types/core/Agent.d.ts +2 -1
  169. package/dist/types/core/Agent.d.ts.map +1 -1
  170. package/dist/types/core/agent/AgentBuilder.d.ts +22 -1
  171. package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
  172. package/dist/types/core/agent/assessment/assess.d.ts.map +1 -1
  173. package/dist/types/core/agent/assessment/compose.d.ts +82 -5
  174. package/dist/types/core/agent/assessment/compose.d.ts.map +1 -1
  175. package/dist/types/core/agent/assessment/reasons.d.ts +17 -1
  176. package/dist/types/core/agent/assessment/reasons.d.ts.map +1 -1
  177. package/dist/types/core/agent/assessment/sources.d.ts +67 -0
  178. package/dist/types/core/agent/assessment/sources.d.ts.map +1 -0
  179. package/dist/types/core/agent/assessment/stage.d.ts +17 -4
  180. package/dist/types/core/agent/assessment/stage.d.ts.map +1 -1
  181. package/dist/types/core/agent/assessment/types.d.ts +37 -0
  182. package/dist/types/core/agent/assessment/types.d.ts.map +1 -1
  183. package/dist/types/core/agent/buildAgentChart.d.ts +8 -0
  184. package/dist/types/core/agent/buildAgentChart.d.ts.map +1 -1
  185. package/dist/types/core/agent/buildToolRegistry.d.ts.map +1 -1
  186. package/dist/types/core/agent/evidence/numberPrecision.d.ts +3 -2
  187. package/dist/types/core/agent/evidence/numberPrecision.d.ts.map +1 -1
  188. package/dist/types/core/agent/honesty/mounts.d.ts +11 -2
  189. package/dist/types/core/agent/honesty/mounts.d.ts.map +1 -1
  190. package/dist/types/core/agent/stages/prepareFinal.d.ts +19 -3
  191. package/dist/types/core/agent/stages/prepareFinal.d.ts.map +1 -1
  192. package/dist/types/core/agent/types.d.ts +16 -2
  193. package/dist/types/core/agent/types.d.ts.map +1 -1
  194. package/dist/types/events/payloads.d.ts +137 -27
  195. package/dist/types/events/payloads.d.ts.map +1 -1
  196. package/dist/types/lib/displayName.d.ts +82 -0
  197. package/dist/types/lib/displayName.d.ts.map +1 -0
  198. package/dist/types/mcp/callLifetime.d.ts +57 -14
  199. package/dist/types/mcp/callLifetime.d.ts.map +1 -1
  200. package/dist/types/mcp/callMarker.d.ts +44 -0
  201. package/dist/types/mcp/callMarker.d.ts.map +1 -0
  202. package/dist/types/mcp/index.d.ts +2 -0
  203. package/dist/types/mcp/index.d.ts.map +1 -1
  204. package/dist/types/mcp/mcpClient.d.ts.map +1 -1
  205. package/dist/types/mcp/replay.d.ts +284 -0
  206. package/dist/types/mcp/replay.d.ts.map +1 -0
  207. package/dist/types/mcp/replayUnavailable.d.ts +56 -0
  208. package/dist/types/mcp/replayUnavailable.d.ts.map +1 -0
  209. package/dist/types/mcp/requestLedger.d.ts +115 -32
  210. package/dist/types/mcp/requestLedger.d.ts.map +1 -1
  211. package/dist/types/mcp/seriesEvidence.d.ts +73 -15
  212. package/dist/types/mcp/seriesEvidence.d.ts.map +1 -1
  213. package/dist/types/mcp/throttleRetry.d.ts +86 -42
  214. package/dist/types/mcp/throttleRetry.d.ts.map +1 -1
  215. package/dist/types/mcp/toolResult.d.ts +6 -0
  216. package/dist/types/mcp/toolResult.d.ts.map +1 -1
  217. package/dist/types/mcp/types.d.ts +70 -8
  218. package/dist/types/mcp/types.d.ts.map +1 -1
  219. package/dist/types/redaction/knownStrings.d.ts.map +1 -1
  220. package/dist/types/semantics/coverage/answer.d.ts +9 -1
  221. package/dist/types/semantics/coverage/answer.d.ts.map +1 -1
  222. package/dist/types/tool-providers/index.d.ts +2 -2
  223. package/dist/types/tool-providers/index.d.ts.map +1 -1
  224. package/dist/types/tools/requestEvidence.d.ts.map +1 -1
  225. package/dist/types/tools/tools.d.ts +30 -0
  226. package/dist/types/tools/tools.d.ts.map +1 -1
  227. package/package.json +1 -1
@@ -173,6 +173,15 @@ export interface AgentTurnEndPayload {
173
173
  * dispatcher carries the agent's `turn_end` but not the `answer.*` domain.
174
174
  */
175
175
  readonly answerAssessment?: AnswerAssessmentPayload;
176
+ /**
177
+ * The app's words the appended standing line named calls in — registered
178
+ * tool name → the tool's declared `displayName`. Present ONLY when the line
179
+ * (`.answerLayer({ standingLine: true })`) named a reason's calls by a
180
+ * declared name, so every other turn emits the exact payload it always did.
181
+ * The words are the app's own, already in `finalContent`; the record keeps
182
+ * them so a reader rebuilds the very line from the record.
183
+ */
184
+ readonly standingLineNames?: Readonly<Record<string, string>>;
176
185
  /** Runtime-composed typed negatives, with verification and delivery kept separate. */
177
186
  readonly answerNegatives?: AnswerNegativesPayload;
178
187
  /**
@@ -2261,17 +2270,22 @@ export interface ToolsCodeRunPayload {
2261
2270
  /**
2262
2271
  * What one attempt of an MCP request came to.
2263
2272
  *
2264
- * - `'answered'` — a response arrived and no retry rule refused it. It is
2265
- * delivered as it came, WHATEVER its status: a 503 is `answered` with
2273
+ * - `'answered'` — an HTTP response arrived and no retry rule refused it. It
2274
+ * is delivered as it came, WHATEVER its status: a 503 is `answered` with
2266
2275
  * `status: 503`. A response received is not an operation that succeeded,
2267
- * so nothing here is called success; read `status`.
2276
+ * so nothing here is called success; read `status`. Nor is it the MCP
2277
+ * call's answer: it records the HTTP exchange. A `202 Accepted`, or a
2278
+ * stream that closes before the call's result, is `answered`, and the
2279
+ * JSON-RPC answer may still never come — the end's `mayHaveRun` says when
2280
+ * the call failed that way.
2268
2281
  * - `'refused'` — a response the retry policy recognises as a refusal
2269
- * (`kind`): HTTP 429, or AgentCore Runtime's session-busy reply. The only
2270
- * outcome that is ever retried. It records the response the server sent,
2271
- * not proof that nothing ran: a 429 says the request was rate-limited,
2272
- * nothing more (RFC 6585 §4).
2282
+ * (`kind`): HTTP 429, or AgentCore Runtime's session-busy reply. It records
2283
+ * the response the server sent, not proof that nothing ran: a 429 says the
2284
+ * request was rate-limited, nothing more (RFC 6585 §4). `effect` says what
2285
+ * is known; `permission` says what allowed asking again.
2273
2286
  * - `'failed'` — the request threw before an answer arrived (a dropped
2274
- * connection, a DNS failure). Never retried: the server may have run it.
2287
+ * connection, a DNS failure). The server may have run it, so it is asked
2288
+ * again only when the app declared that for this tool (`replay`).
2275
2289
  * - `'timed-out'` — the call's deadline (`maxElapsedMs`) cut the request
2276
2290
  * while it was in flight.
2277
2291
  * - `'cut'` — the call was cancelled while the request was in flight: the
@@ -2279,7 +2293,7 @@ export interface ToolsCodeRunPayload {
2279
2293
  * or the call settling first. The request WAS sent; the server may already
2280
2294
  * have received it and run it. A cut is never a "not run".
2281
2295
  *
2282
- * The last three never had an answer, so they carry `remote: 'unknown'`.
2296
+ * The last three never had a response, so they carry `remote: 'unknown'`.
2283
2297
  *
2284
2298
  * Every request the series sent is a row, or is counted in `omitted`: the rows
2285
2299
  * and `omitted` together are the requests the series sent. A request that was
@@ -2296,7 +2310,7 @@ export type ToolRequestAttemptOutcome = 'answered' | 'refused' | 'failed' | 'tim
2296
2310
  export type ToolRequestOutcome = ToolRequestAttemptOutcome | 'cancelled';
2297
2311
  /**
2298
2312
  * Whether the server received and ran a request, when that is not known: the
2299
- * attempt ended without an answer (`failed`, `timed-out`, `cut`), so the
2313
+ * attempt ended without a response (`failed`, `timed-out`, `cut`), so the
2300
2314
  * request may have reached the server and run there, or not. The library never
2301
2315
  * records such a request as not run.
2302
2316
  */
@@ -2304,24 +2318,81 @@ export type ToolRequestRemote = 'unknown';
2304
2318
  /**
2305
2319
  * Why the request went on after an attempt, or ended with it.
2306
2320
  *
2307
- * - `'retryable'` — refused; another attempt follows after `waitMs`. The
2308
- * only reason that is not an end.
2321
+ * - `'retryable'` — another attempt follows after `waitMs`; `permission`
2322
+ * says what allowed it. The only reason that is not an end.
2309
2323
  * - `'answered'` — answered; the response is delivered.
2310
- * - `'exhausted'` — refused, and the request has made every attempt it may.
2311
- * - `'wait-limit'` — refused, and the wait would pass the call's total
2312
- * waiting budget (`maxWaitMs`). A stated `Retry-After` is never shortened
2313
- * to fit: the refusal is delivered instead.
2314
- * - `'no-time-left'` — refused, and the wait would pass the call's deadline;
2315
- * or the deadline cut a request or a wait.
2316
- * - `'not-replayable'` — refused, but the request's body cannot be sent twice.
2317
- * - `'not-retryable'` — the attempt failed in a way this retry never
2318
- * repeats: only a response the retry policy recognises as a refusal (a 429,
2319
- * a session-busy reply) is retried.
2324
+ * - `'exhausted'` — the request has made every attempt it may.
2325
+ * - `'wait-limit'` — the wait would pass the call's total waiting budget
2326
+ * (`maxWaitMs`). A stated `Retry-After` is never shortened to fit: the
2327
+ * refusal is delivered instead.
2328
+ * - `'no-time-left'` — the wait would pass the call's deadline; or the
2329
+ * deadline cut a request or a wait.
2330
+ * - `'not-replayable'` — the request's body cannot be sent twice.
2331
+ * - `'not-retryable'` — the attempt failed without an answer, and nothing
2332
+ * permits asking again after that failure: the app declared no repeat of
2333
+ * this tool on it (`replay`), or it is not a kind the series repeats.
2334
+ * - `'not-permitted'` — refused with a 429, and the policy in force does not
2335
+ * permit asking this tool again on it. Under `'app-authorized'`, only the
2336
+ * app's declaration does: a generic 429 does not prove the server ran
2337
+ * nothing.
2338
+ * - `'changes-without-key'` — the app declared this tool as making changes,
2339
+ * and the call carries no key the server is declared to deduplicate by. It
2340
+ * is never asked again automatically, under any policy.
2320
2341
  * - `'cancelled'` — the caller's signal ended the request.
2321
2342
  */
2322
- export type ToolRequestReason = 'retryable' | 'answered' | 'exhausted' | 'wait-limit' | 'no-time-left' | 'not-replayable' | 'not-retryable' | 'cancelled';
2343
+ export type ToolRequestReason = 'retryable' | 'answered' | 'exhausted' | 'wait-limit' | 'no-time-left' | 'not-replayable' | 'not-retryable' | 'not-permitted' | 'changes-without-key' | 'cancelled';
2323
2344
  /** The refusals a retry rule recognises: HTTP 429, and AgentCore Runtime's session-busy reply. */
2324
2345
  export type ToolRequestRefusalKind = 'throttle' | 'session-busy';
2346
+ /**
2347
+ * What is known about whether an attempt took effect on the server —
2348
+ * footprintjs's effect law (`AttemptEffect`), read for an MCP request:
2349
+ *
2350
+ * - `'none'` — it ran nothing, and that is established: the request was
2351
+ * never sent (an `end` whose `attempts` is `0`). No reply establishes it.
2352
+ * A 429 says the request was rate-limited, and AgentCore's session-busy
2353
+ * body is matched by its code and words — a server behind the runtime can
2354
+ * answer with the same error after it ran the call.
2355
+ * - `'unknown'` — anything sent that did not complete: a 429, a session-busy
2356
+ * reply, a lost connection or a timeout after the request was sent, a cut,
2357
+ * a 5xx, a JSON-RPC error, a tool error (one can follow a write that
2358
+ * succeeded).
2359
+ * - `'applied'` — the call completed: the server answered it, and not with
2360
+ * an error. It is never proof that anything was written.
2361
+ */
2362
+ export type ToolRequestEffect = 'none' | 'unknown' | 'applied';
2363
+ /** The failure kinds the app may declare a tool repeatable on (`replay.tools[name].on`). */
2364
+ export type ToolRequestReplayKind = 'throttle' | 'network';
2365
+ /**
2366
+ * What allowed the next attempt — present exactly when `reason` is
2367
+ * `'retryable'`. Permission and effect are separate facts: neither is ever
2368
+ * read from the other.
2369
+ *
2370
+ * - `by: 'declaration'` — the app's entry for this tool names the failure
2371
+ * kind (`on`).
2372
+ * - `by: 'adapter'` — the adapter the app chose retries this refusal as its
2373
+ * own policy: AgentCore Runtime's session-busy reply, which AWS documents
2374
+ * as a retryable conflict while a session starts or stops. It says what
2375
+ * it assumes in doing so (`assumes`).
2376
+ * - `by: 'compatibility'` — the compatibility policy, today's default: it
2377
+ * repeats a 429 for every tool, and says what it assumes in doing so
2378
+ * (`assumes`).
2379
+ *
2380
+ * An assumption is a policy, never evidence: the row's `effect` stays
2381
+ * `'unknown'`.
2382
+ */
2383
+ export interface ToolRequestPermission {
2384
+ readonly by: 'declaration' | 'adapter' | 'compatibility';
2385
+ /** `declaration` only — the failure kind the app's entry names. */
2386
+ readonly on?: ToolRequestReplayKind;
2387
+ /** `adapter` and `compatibility` only — what the policy assumes of the refusal it repeats. */
2388
+ readonly assumes?: 'refused-before-execution';
2389
+ /**
2390
+ * The app declared this tool as making changes, so it was asked again only
2391
+ * because the server is declared to deduplicate by a key this call carries.
2392
+ * The key protects only if the server uses it.
2393
+ */
2394
+ readonly deduplicated?: true;
2395
+ }
2325
2396
  /**
2326
2397
  * footprintjs's failure categories (`AttemptCategory`) — the one fixed set
2327
2398
  * every attempt record uses, so a saved request groups with every other.
@@ -2364,13 +2435,22 @@ export interface ToolRequestAttempt {
2364
2435
  /** `failed` and `timed-out` only. */
2365
2436
  readonly error?: ToolRequestError;
2366
2437
  /**
2367
- * `'unknown'` when the attempt ended without an answer (`failed`,
2438
+ * `'unknown'` when the attempt ended without a response (`failed`,
2368
2439
  * `timed-out`, `cut`): it was sent, and whether the server received and ran
2369
2440
  * it is not known. Absent when a response arrived: the record keeps what the
2370
2441
  * server answered (`status`) — for a `refused` attempt that is the server's
2371
2442
  * own refusal, not proof that nothing ran.
2372
2443
  */
2373
2444
  readonly remote?: ToolRequestRemote;
2445
+ /**
2446
+ * What is known about whether this attempt took effect (see
2447
+ * {@link ToolRequestEffect}). On every attempt the library files.
2448
+ */
2449
+ readonly effect?: ToolRequestEffect;
2450
+ /** What allowed the next attempt — present exactly when `reason` is `'retryable'`. */
2451
+ readonly permission?: ToolRequestPermission;
2452
+ /** How long the attempt took, in ms, from sending to its end. On every attempt the library files. */
2453
+ readonly durationMs?: number;
2374
2454
  }
2375
2455
  /** How an MCP request ended. */
2376
2456
  export interface ToolRequestEnd {
@@ -2397,17 +2477,47 @@ export interface ToolRequestEnd {
2397
2477
  /** `failed` and `timed-out` only. */
2398
2478
  readonly error?: ToolRequestError;
2399
2479
  /**
2400
- * `'unknown'` when the request ended on an attempt with no answer (`failed`,
2401
- * `timed-out`, `cut`): whether the server ran that request is not known.
2480
+ * `'unknown'` when the request ended on an attempt with no response
2481
+ * (`failed`, `timed-out`, `cut`): whether the server ran that request is not
2482
+ * known.
2402
2483
  */
2403
2484
  readonly remote?: ToolRequestRemote;
2485
+ /**
2486
+ * How many requests the series sent: `attempts.length + omitted`. On every
2487
+ * end the library files.
2488
+ */
2489
+ readonly attempts?: number;
2490
+ /**
2491
+ * What is known about the series' effect as a whole. Uncertainty survives:
2492
+ * once any attempt's effect is `'unknown'`, so is the series' — a later
2493
+ * proven refusal does not resolve it, and a later success does not prove the
2494
+ * operation happened only once. `'applied'` only when the call completed and
2495
+ * no attempt's effect is unknown; `'none'` only when every attempt is proven
2496
+ * to have run nothing (or none was sent). On every end the library files.
2497
+ */
2498
+ readonly effect?: ToolRequestEffect;
2499
+ /**
2500
+ * The call failed as "may have run" (footprintjs's `UnknownEffectError`, its
2501
+ * final error — a later refusal's, or the timeout — as the `cause`): under
2502
+ * the `'app-authorized'` policy, the call genuinely lacked an answer
2503
+ * somewhere and did not complete. Lacking an answer is not an unknown
2504
+ * effect: it is an attempt that got no response at all (`remote:
2505
+ * 'unknown'`), or a request accepted over HTTP (an `answered` 2xx) whose
2506
+ * JSON-RPC answer never came. A received refusal or error IS an answer —
2507
+ * its effect unknown, delivered as the server sent it — so a call whose
2508
+ * every attempt received one has no `mayHaveRun`. Absent under
2509
+ * `'compatibility'`, where the caller sees the error it always did, and
2510
+ * for a call its caller cancelled, which ends with the caller's reason.
2511
+ */
2512
+ readonly mayHaveRun?: true;
2404
2513
  }
2405
2514
  /**
2406
2515
  * What one MCP request's retry series did: every attempt it made, why it went
2407
2516
  * on or stopped after each, how long it waited, and how the request ended.
2408
2517
  *
2409
2518
  * Filed by `mcpClient`'s retry series for a call the agent dispatched, ONCE per
2410
- * request, when the request ends — and at the moment of a cancellation, so a
2519
+ * request, when the call settles — so the last attempt's `effect` can say
2520
+ * whether the call completed — and at the moment of a cancellation, so a
2411
2521
  * run cancelled during a wait still carries it when it is saved. A call that
2412
2522
  * settles before its series (the MCP SDK's own timeout, say) cancels the series
2413
2523
  * there and then, inside the call, so it is never filed after its run, and no
@@ -0,0 +1,81 @@
1
+ /**
2
+ * displayName — the ONE rule for a tool's `displayName` (the app's own words
3
+ * for what a call of the tool does, read by a person), and the ONE way the
4
+ * library names a set of calls in those words: the declared ones named, the
5
+ * rest counted.
6
+ *
7
+ * Pattern: two pure functions and one small reader, no state.
8
+ * Role: Leaf. Asked for the RULE by `tools/tools.ts` · `defineTool` and by
9
+ * the registration funnel (`core/agent/buildToolRegistry.ts`), and for
10
+ * the NAMING by the two texts the library appends after an answer —
11
+ * the standing line (`core/agent/assessment/compose.ts`) and the
12
+ * limits block (`semantics/coverage/answer.ts`). Those two cannot
13
+ * import each other, so the naming lives here and they cannot name
14
+ * the same calls in two different ways.
15
+ * Emits: N/A.
16
+ *
17
+ * ## Why only the app's words
18
+ *
19
+ * A tool's registered name is the MODEL's vocabulary (`load_attachment`), and
20
+ * an app may forbid showing it to the people it serves. This module never
21
+ * prints it: a call is named only by the words its tool declared, and a call
22
+ * whose tool declared none is counted ("and 1 other call"), never named. A
23
+ * caller that gets `undefined` back says what it always said. Not every
24
+ * surface asks this module yet — the time layer's limits lines and the
25
+ * answer account's rows still print the registered name (a known follow-up).
26
+ *
27
+ * ## Why the plain-line rule
28
+ *
29
+ * The words reach a person verbatim, after an answer, so they are held to the
30
+ * rule every declared label a report prints is held to (`lib/plainLine.ts` ·
31
+ * `plainLineProblem`: no control, line or paragraph separator, or invisible
32
+ * format character — a bidi override would reverse what the person reads),
33
+ * judged BEFORE the length, and capped at the 60 characters a skill's `title`
34
+ * and an account label are capped at.
35
+ */
36
+ /** The longest display name a person reads — the cap every declared label a report prints has. */
37
+ export declare const MAX_DISPLAY_NAME_CHARS = 60;
38
+ /**
39
+ * At most this many declared names in one phrase; any further call is counted
40
+ * with the calls whose tools declared none. A line for a person, not a list.
41
+ */
42
+ export declare const MAX_NAMED_CALLS = 3;
43
+ /**
44
+ * Why `value` is not a display name, or `undefined` when it is — judged on the
45
+ * trimmed text (the text a person would read). `label` names the field in the
46
+ * sentence, so a refusal says where it was written.
47
+ */
48
+ export declare function displayNameProblem(label: string, value: unknown): string | undefined;
49
+ /**
50
+ * The display name a person may read — trimmed — or `undefined`. A value the
51
+ * rule refuses is never printed: a tool assembled by hand, or served by a
52
+ * ToolProvider after the agent was built, is read through this too.
53
+ */
54
+ export declare function readDisplayName(value: unknown): string | undefined;
55
+ /**
56
+ * The calls, named in the app's words — each distinct declared name once, in
57
+ * the calls' order, at most {@link MAX_NAMED_CALLS}; every other call counted,
58
+ * with `alsoUnnamed` (calls the record does not name at all). `calls` holds one
59
+ * entry per CALL (the caller has already said each call once), each with its
60
+ * tool's registered name — the key a declared name is looked up by, never
61
+ * printed:
62
+ *
63
+ * - `loading the attached data`
64
+ * - `loading the attached data and searching the catalog`
65
+ * - `loading the attached data and 1 other call`
66
+ *
67
+ * `undefined` when no call's tool declared a name: the caller then says what
68
+ * it always said — the registered name is never the fallback.
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * namedCalls(
73
+ * [{ toolCallId: 'c1', toolName: 'load_attachment' }, { toolCallId: 'c2', toolName: 'list_runs' }],
74
+ * 0,
75
+ * (tool) => (tool === 'load_attachment' ? 'loading the attached data' : undefined),
76
+ * ); // 'loading the attached data and 1 other call'
77
+ * ```
78
+ */
79
+ export declare function namedCalls(calls: readonly {
80
+ readonly toolName: string;
81
+ }[], alsoUnnamed: number, displayNameOf: (toolName: string) => string | undefined): string | undefined;
@@ -0,0 +1,119 @@
1
+ /**
2
+ * displayName — the ONE rule for a tool's `displayName` (the app's own words
3
+ * for what a call of the tool does, read by a person), and the ONE way the
4
+ * library names a set of calls in those words: the declared ones named, the
5
+ * rest counted.
6
+ *
7
+ * Pattern: two pure functions and one small reader, no state.
8
+ * Role: Leaf. Asked for the RULE by `tools/tools.ts` · `defineTool` and by
9
+ * the registration funnel (`core/agent/buildToolRegistry.ts`), and for
10
+ * the NAMING by the two texts the library appends after an answer —
11
+ * the standing line (`core/agent/assessment/compose.ts`) and the
12
+ * limits block (`semantics/coverage/answer.ts`). Those two cannot
13
+ * import each other, so the naming lives here and they cannot name
14
+ * the same calls in two different ways.
15
+ * Emits: N/A.
16
+ *
17
+ * ## Why only the app's words
18
+ *
19
+ * A tool's registered name is the MODEL's vocabulary (`load_attachment`), and
20
+ * an app may forbid showing it to the people it serves. This module never
21
+ * prints it: a call is named only by the words its tool declared, and a call
22
+ * whose tool declared none is counted ("and 1 other call"), never named. A
23
+ * caller that gets `undefined` back says what it always said. Not every
24
+ * surface asks this module yet — the time layer's limits lines and the
25
+ * answer account's rows still print the registered name (a known follow-up).
26
+ *
27
+ * ## Why the plain-line rule
28
+ *
29
+ * The words reach a person verbatim, after an answer, so they are held to the
30
+ * rule every declared label a report prints is held to (`lib/plainLine.ts` ·
31
+ * `plainLineProblem`: no control, line or paragraph separator, or invisible
32
+ * format character — a bidi override would reverse what the person reads),
33
+ * judged BEFORE the length, and capped at the 60 characters a skill's `title`
34
+ * and an account label are capped at.
35
+ */
36
+ import { plainLineProblem } from './plainLine.js';
37
+ /** The longest display name a person reads — the cap every declared label a report prints has. */
38
+ export const MAX_DISPLAY_NAME_CHARS = 60;
39
+ /**
40
+ * At most this many declared names in one phrase; any further call is counted
41
+ * with the calls whose tools declared none. A line for a person, not a list.
42
+ */
43
+ export const MAX_NAMED_CALLS = 3;
44
+ /**
45
+ * Why `value` is not a display name, or `undefined` when it is — judged on the
46
+ * trimmed text (the text a person would read). `label` names the field in the
47
+ * sentence, so a refusal says where it was written.
48
+ */
49
+ export function displayNameProblem(label, value) {
50
+ if (typeof value !== 'string' || value.trim().length === 0) {
51
+ return (`${label} must be a non-empty string — the app's own words for what a call of this ` +
52
+ `tool does, read by a person (got ${typeof value === 'string' ? JSON.stringify(value) : typeof value}). Omit it to ` +
53
+ 'leave the call unnamed.');
54
+ }
55
+ const text = value.trim();
56
+ const notPlain = plainLineProblem(label, text);
57
+ if (notPlain !== undefined)
58
+ return notPlain;
59
+ if (text.length > MAX_DISPLAY_NAME_CHARS) {
60
+ return `${label} is ${text.length} characters; the limit is ${MAX_DISPLAY_NAME_CHARS}.`;
61
+ }
62
+ return undefined;
63
+ }
64
+ /**
65
+ * The display name a person may read — trimmed — or `undefined`. A value the
66
+ * rule refuses is never printed: a tool assembled by hand, or served by a
67
+ * ToolProvider after the agent was built, is read through this too.
68
+ */
69
+ export function readDisplayName(value) {
70
+ return displayNameProblem('displayName', value) === undefined
71
+ ? value.trim()
72
+ : undefined;
73
+ }
74
+ /**
75
+ * The calls, named in the app's words — each distinct declared name once, in
76
+ * the calls' order, at most {@link MAX_NAMED_CALLS}; every other call counted,
77
+ * with `alsoUnnamed` (calls the record does not name at all). `calls` holds one
78
+ * entry per CALL (the caller has already said each call once), each with its
79
+ * tool's registered name — the key a declared name is looked up by, never
80
+ * printed:
81
+ *
82
+ * - `loading the attached data`
83
+ * - `loading the attached data and searching the catalog`
84
+ * - `loading the attached data and 1 other call`
85
+ *
86
+ * `undefined` when no call's tool declared a name: the caller then says what
87
+ * it always said — the registered name is never the fallback.
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * namedCalls(
92
+ * [{ toolCallId: 'c1', toolName: 'load_attachment' }, { toolCallId: 'c2', toolName: 'list_runs' }],
93
+ * 0,
94
+ * (tool) => (tool === 'load_attachment' ? 'loading the attached data' : undefined),
95
+ * ); // 'loading the attached data and 1 other call'
96
+ * ```
97
+ */
98
+ export function namedCalls(calls, alsoUnnamed, displayNameOf) {
99
+ const named = [];
100
+ let rest = alsoUnnamed;
101
+ for (const call of calls) {
102
+ const words = displayNameOf(call.toolName);
103
+ if (words === undefined)
104
+ rest += 1;
105
+ else if (named.includes(words))
106
+ continue;
107
+ else if (named.length < MAX_NAMED_CALLS)
108
+ named.push(words);
109
+ else
110
+ rest += 1;
111
+ }
112
+ if (named.length === 0)
113
+ return undefined;
114
+ const parts = rest > 0 ? [...named, `${rest} other ${rest === 1 ? 'call' : 'calls'}`] : named;
115
+ return parts.length === 1
116
+ ? parts[0]
117
+ : `${parts.slice(0, -1).join(', ')} and ${parts[parts.length - 1]}`;
118
+ }
119
+ //# sourceMappingURL=displayName.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"displayName.js","sourceRoot":"","sources":["../../../src/lib/displayName.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,kGAAkG;AAClG,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC;AAEjC;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAE,KAAc;IAC9D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,OAAO,CACL,GAAG,KAAK,4EAA4E;YACpF,oCACE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,KAC7D,gBAAgB;YAChB,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC1B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC/C,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAC5C,IAAI,IAAI,CAAC,MAAM,GAAG,sBAAsB,EAAE,CAAC;QACzC,OAAO,GAAG,KAAK,OAAO,IAAI,CAAC,MAAM,6BAA6B,sBAAsB,GAAG,CAAC;IAC1F,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,OAAO,kBAAkB,CAAC,aAAa,EAAE,KAAK,CAAC,KAAK,SAAS;QAC3D,CAAC,CAAE,KAAgB,CAAC,IAAI,EAAE;QAC1B,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,UAAU,CACxB,KAA+C,EAC/C,WAAmB,EACnB,aAAuD;IAEvD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,IAAI,GAAG,WAAW,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAI,KAAK,KAAK,SAAS;YAAE,IAAI,IAAI,CAAC,CAAC;aAC9B,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAS;aACpC,IAAI,KAAK,CAAC,MAAM,GAAG,eAAe;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;;YACtD,IAAI,IAAI,CAAC,CAAC;IACjB,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,GAAG,IAAI,UAAU,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC9F,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;QACvB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACV,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;AACxE,CAAC"}
@@ -15,35 +15,78 @@
15
15
  * the call. The link is undone when the call settles: the SDK keeps its
16
16
  * abort listener on the signal it was given, and a link that outlived the
17
17
  * call would cancel a request that had already finished.
18
- * 2. ITS TICKET is issued, when the call carries the run's evidence port and
19
- * the connection has a ledger, keyed by the request's params object.
18
+ * 2. ITS MARKER is issued when the connection has a ledger, with its ticket
19
+ * when the call carries the run's evidence port: a library-private string
20
+ * in the request's `_meta` (`callMarker.ts`), which ties the request to
21
+ * the call even when the SDK copies the params, and which the transport
22
+ * takes out before anything is sent.
20
23
  * 3. ITS SETTLING ENDS ITS SERIES. However `callTool` settles — answered,
21
24
  * failed, or given up by the SDK (its own timeout) — a retry series still
22
25
  * sending the request is cut there and then, inside the call: it files
23
26
  * `cancelled` before the call's result is read, and sends nothing more.
27
+ * 4. ITS VERDICT REACHES ITS RECORD. A series that has ended waits for the
28
+ * call to settle before it files, because only the call can say whether
29
+ * the answer completed — a 200 can carry a tool error. The call leaves its
30
+ * verdict in the request's shared replay facts (`replay.ts` ·
31
+ * `RequestReplay`) before it settles the series' wait.
32
+ * 5. "MAY HAVE RUN" IS RAISED HERE — footprintjs's law, under the
33
+ * `'app-authorized'` policy (`replay.ts` · `RequestReplay`, its
34
+ * `uncertain`). A received refusal or error is preserved: a 429, a 503,
35
+ * a JSON-RPC or tool error — or a chain in which every attempt received
36
+ * one — keeps the server's error as it came, its effect still `unknown`.
37
+ * A call that genuinely lacked an answer somewhere — an attempt with no
38
+ * response at all, or a request the HTTP layer accepted whose JSON-RPC
39
+ * answer never came — and then fails, fails with footprintjs's
40
+ * `UnknownEffectError`, its final error (a later refusal's, or the
41
+ * timeout) as the `cause`: that error alone would read as "failed, try
42
+ * again". A call that completes returns normally. Under `'compatibility'`
43
+ * the caller sees the error it always did; the record still says the
44
+ * effect is unknown. A cancellation never raises it: a call its caller
45
+ * cancelled ends with the caller's reason, as it always did.
24
46
  *
25
- * In dev mode, a ticket that no request was bound to by the time the call
26
- * settled, when a `tools/call` request DID go out, is named once per connection: the SDK copied
27
- * the params, so the call's attempts could not be matched to it. Its
28
- * cancellation still reached the request (1, and the ledger's own watch on
29
- * `notifications/cancelled`).
47
+ * In dev mode, a ticket that no request was matched to by the time the call
48
+ * settled, when a `tools/call` request DID go out, is named once per
49
+ * connection: the SDK rebuilt the params without the marker, so the call's
50
+ * attempts could not be matched to it. Its cancellation still reached the
51
+ * request (1, and the ledger's own watch on `notifications/cancelled`). Under
52
+ * `'app-authorized'` such a request is never sent at all
53
+ * (`replayUnavailable.ts`).
30
54
  */
55
+ import type { CallVerdict } from './replay.js';
31
56
  import type { RequestLedger } from './requestLedger.js';
32
- /** A call that has been opened: the signal its SDK request runs under, and how to close it. */
33
- export interface OpenCall {
57
+ /** A call that has been opened: the params to send, the signal its SDK request runs under, and how to close it. */
58
+ export interface OpenCall<P extends object = object> {
59
+ /**
60
+ * What to hand the SDK: the call's params, with its private marker in
61
+ * `_meta` when a ledger watches the connection (`callMarker.ts`). The
62
+ * transport takes the marker out again: the server never sees it.
63
+ */
64
+ readonly params: P;
34
65
  /** What cancels the SDK request — absent when nothing can. */
35
66
  readonly signal?: AbortSignal;
36
- /** The call settled: undo the link, cut a series still sending, check the ticket was bound. */
37
- close(): void;
67
+ /**
68
+ * The call failed with `error` (`verdict` says how far it got): the error it
69
+ * fails with — `error` itself, or, under `'app-authorized'`, footprintjs's
70
+ * `UnknownEffectError` with `error` as its `cause` when the call genuinely
71
+ * lacked an answer somewhere (see 5 above).
72
+ */
73
+ failed(error: unknown, verdict: CallVerdict): unknown;
74
+ /**
75
+ * The call settled with `verdict`: leave it for the record, settle it in the
76
+ * ledger (its answer is no longer awaited), undo the link, cut a series
77
+ * still sending, check its request was matched.
78
+ */
79
+ close(verdict: CallVerdict): void;
38
80
  }
39
81
  /**
40
82
  * Open one call.
41
83
  *
42
- * @param params the request's params object — the SDK hands this very object to
43
- * the transport, which is how the ledger knows the request is this call's.
84
+ * @param params the request's params. The call sends them marked
85
+ * (`OpenCall.params`): the marker, not the object, is how the ledger knows
86
+ * the request is this call's — it survives an SDK that copies the params.
44
87
  * @param ctx the call's context: its signal, and the run's evidence port if any.
45
88
  * @param clientSignal the client's own `signal` (`McpClientOptions.signal`).
46
89
  * @param ledger the connection's ledger, when the library built its transport.
47
90
  * @param server the client's name, for the dev-mode note.
48
91
  */
49
- export declare function openCall(params: object, ctx: unknown, clientSignal: AbortSignal | undefined, ledger: RequestLedger | undefined, server: string): OpenCall;
92
+ export declare function openCall<P extends object>(params: P, ctx: unknown, clientSignal: AbortSignal | undefined, ledger: RequestLedger | undefined, server: string): OpenCall<P>;