agentfootprint 12.1.0 → 12.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/AGENTS.md +1 -1
  2. package/CAPABILITIES.md +3 -1
  3. package/ai-instructions/claude-code/SKILL.md +1 -1
  4. package/dist/adapters/mcp/agentcoreRuntime/invoke.js +113 -7
  5. package/dist/adapters/mcp/agentcoreRuntime/invoke.js.map +1 -1
  6. package/dist/adapters/mcp/agentcoreRuntime/session.js +21 -21
  7. package/dist/adapters/mcp/agentcoreRuntime/session.js.map +1 -1
  8. package/dist/adapters/mcp/agentcoreRuntime/transport.js +79 -5
  9. package/dist/adapters/mcp/agentcoreRuntime/transport.js.map +1 -1
  10. package/dist/core/Agent.js +6 -0
  11. package/dist/core/Agent.js.map +1 -1
  12. package/dist/core/agent/stages/toolCalls.js +4 -0
  13. package/dist/core/agent/stages/toolCalls.js.map +1 -1
  14. package/dist/core/slots/buildToolsSlot.js +8 -0
  15. package/dist/core/slots/buildToolsSlot.js.map +1 -1
  16. package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.d.ts +23 -4
  17. package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.js +112 -6
  18. package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.js.map +1 -1
  19. package/dist/esm/adapters/mcp/agentcoreRuntime/session.d.ts +20 -6
  20. package/dist/esm/adapters/mcp/agentcoreRuntime/session.js +21 -21
  21. package/dist/esm/adapters/mcp/agentcoreRuntime/session.js.map +1 -1
  22. package/dist/esm/adapters/mcp/agentcoreRuntime/transport.js +81 -7
  23. package/dist/esm/adapters/mcp/agentcoreRuntime/transport.js.map +1 -1
  24. package/dist/esm/core/Agent.js +6 -0
  25. package/dist/esm/core/Agent.js.map +1 -1
  26. package/dist/esm/core/agent/stages/toolCalls.js +4 -0
  27. package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
  28. package/dist/esm/core/slots/buildToolsSlot.d.ts +12 -0
  29. package/dist/esm/core/slots/buildToolsSlot.js +8 -0
  30. package/dist/esm/core/slots/buildToolsSlot.js.map +1 -1
  31. package/dist/esm/events/payloads.d.ts +41 -0
  32. package/dist/esm/events/registry.d.ts +3 -1
  33. package/dist/esm/events/registry.js +2 -0
  34. package/dist/esm/events/registry.js.map +1 -1
  35. package/dist/esm/identity/types.d.ts +7 -3
  36. package/dist/esm/identity/types.js.map +1 -1
  37. package/dist/esm/index.d.ts +1 -1
  38. package/dist/esm/index.js +4 -1
  39. package/dist/esm/index.js.map +1 -1
  40. package/dist/esm/lib/boundedJson.d.ts +14 -7
  41. package/dist/esm/lib/boundedJson.js +14 -7
  42. package/dist/esm/lib/boundedJson.js.map +1 -1
  43. package/dist/esm/mcp/callLifetime.js +5 -2
  44. package/dist/esm/mcp/callLifetime.js.map +1 -1
  45. package/dist/esm/mcp/clientPort.d.ts +78 -0
  46. package/dist/esm/mcp/clientPort.js +33 -0
  47. package/dist/esm/mcp/clientPort.js.map +1 -0
  48. package/dist/esm/mcp/gatewayTransport.js +13 -3
  49. package/dist/esm/mcp/gatewayTransport.js.map +1 -1
  50. package/dist/esm/mcp/index.d.ts +9 -1
  51. package/dist/esm/mcp/index.js +8 -0
  52. package/dist/esm/mcp/index.js.map +1 -1
  53. package/dist/esm/mcp/mcpClient.d.ts +18 -1
  54. package/dist/esm/mcp/mcpClient.js +203 -43
  55. package/dist/esm/mcp/mcpClient.js.map +1 -1
  56. package/dist/esm/mcp/mockMcpClient.js +13 -0
  57. package/dist/esm/mcp/mockMcpClient.js.map +1 -1
  58. package/dist/esm/mcp/pool/boundTool.d.ts +58 -0
  59. package/dist/esm/mcp/pool/boundTool.js +218 -0
  60. package/dist/esm/mcp/pool/boundTool.js.map +1 -0
  61. package/dist/esm/mcp/pool/clientSet.d.ts +73 -0
  62. package/dist/esm/mcp/pool/clientSet.js +152 -0
  63. package/dist/esm/mcp/pool/clientSet.js.map +1 -0
  64. package/dist/esm/mcp/pool/definitions.d.ts +103 -0
  65. package/dist/esm/mcp/pool/definitions.js +168 -0
  66. package/dist/esm/mcp/pool/definitions.js.map +1 -0
  67. package/dist/esm/mcp/pool/errors.d.ts +76 -0
  68. package/dist/esm/mcp/pool/errors.js +91 -0
  69. package/dist/esm/mcp/pool/errors.js.map +1 -0
  70. package/dist/esm/mcp/pool/identityKey.d.ts +57 -0
  71. package/dist/esm/mcp/pool/identityKey.js +94 -0
  72. package/dist/esm/mcp/pool/identityKey.js.map +1 -0
  73. package/dist/esm/mcp/pool/lease.d.ts +36 -0
  74. package/dist/esm/mcp/pool/lease.js +51 -0
  75. package/dist/esm/mcp/pool/lease.js.map +1 -0
  76. package/dist/esm/mcp/pool/listTools.d.ts +33 -0
  77. package/dist/esm/mcp/pool/listTools.js +146 -0
  78. package/dist/esm/mcp/pool/listTools.js.map +1 -0
  79. package/dist/esm/mcp/pool/mcpClientPool.d.ts +121 -0
  80. package/dist/esm/mcp/pool/mcpClientPool.js +151 -0
  81. package/dist/esm/mcp/pool/mcpClientPool.js.map +1 -0
  82. package/dist/esm/mcp/pool/options.d.ts +183 -0
  83. package/dist/esm/mcp/pool/options.js +119 -0
  84. package/dist/esm/mcp/pool/options.js.map +1 -0
  85. package/dist/esm/mcp/pool/plan.d.ts +77 -0
  86. package/dist/esm/mcp/pool/plan.js +134 -0
  87. package/dist/esm/mcp/pool/plan.js.map +1 -0
  88. package/dist/esm/mcp/pool/pool.d.ts +307 -0
  89. package/dist/esm/mcp/pool/pool.js +1071 -0
  90. package/dist/esm/mcp/pool/pool.js.map +1 -0
  91. package/dist/esm/mcp/pool/pooledClient.d.ts +93 -0
  92. package/dist/esm/mcp/pool/pooledClient.js +90 -0
  93. package/dist/esm/mcp/pool/pooledClient.js.map +1 -0
  94. package/dist/esm/mcp/pool/record.d.ts +80 -0
  95. package/dist/esm/mcp/pool/record.js +75 -0
  96. package/dist/esm/mcp/pool/record.js.map +1 -0
  97. package/dist/esm/mcp/pool/sessionEnded.d.ts +24 -0
  98. package/dist/esm/mcp/pool/sessionEnded.js +31 -0
  99. package/dist/esm/mcp/pool/sessionEnded.js.map +1 -0
  100. package/dist/esm/mcp/pool/work.d.ts +116 -0
  101. package/dist/esm/mcp/pool/work.js +213 -0
  102. package/dist/esm/mcp/pool/work.js.map +1 -0
  103. package/dist/esm/mcp/requestGuard.d.ts +70 -0
  104. package/dist/esm/mcp/requestGuard.js +98 -0
  105. package/dist/esm/mcp/requestGuard.js.map +1 -0
  106. package/dist/esm/mcp/requestLedger.d.ts +35 -1
  107. package/dist/esm/mcp/requestLedger.js +76 -3
  108. package/dist/esm/mcp/requestLedger.js.map +1 -1
  109. package/dist/esm/mcp/seriesEvidence.d.ts +10 -6
  110. package/dist/esm/mcp/seriesEvidence.js +16 -7
  111. package/dist/esm/mcp/seriesEvidence.js.map +1 -1
  112. package/dist/esm/mcp/terminate.d.ts +94 -0
  113. package/dist/esm/mcp/terminate.js +184 -0
  114. package/dist/esm/mcp/terminate.js.map +1 -0
  115. package/dist/esm/mcp/throttleRetry.js +71 -7
  116. package/dist/esm/mcp/throttleRetry.js.map +1 -1
  117. package/dist/esm/mcp/types.d.ts +85 -7
  118. package/dist/esm/redaction/knownStrings.js +34 -0
  119. package/dist/esm/redaction/knownStrings.js.map +1 -1
  120. package/dist/esm/tool-providers/index.d.ts +2 -2
  121. package/dist/esm/tool-providers/index.js +7 -1
  122. package/dist/esm/tool-providers/index.js.map +1 -1
  123. package/dist/esm/tools/mcpClientUse.d.ts +59 -0
  124. package/dist/esm/tools/mcpClientUse.js +216 -0
  125. package/dist/esm/tools/mcpClientUse.js.map +1 -0
  126. package/dist/esm/tools/toolProvider.d.ts +16 -0
  127. package/dist/esm/tools/toolSessions.d.ts +41 -0
  128. package/dist/esm/tools/toolSessions.js +41 -1
  129. package/dist/esm/tools/toolSessions.js.map +1 -1
  130. package/dist/events/registry.js +2 -0
  131. package/dist/events/registry.js.map +1 -1
  132. package/dist/identity/types.js.map +1 -1
  133. package/dist/index.js +6 -3
  134. package/dist/index.js.map +1 -1
  135. package/dist/lib/boundedJson.js +14 -7
  136. package/dist/lib/boundedJson.js.map +1 -1
  137. package/dist/mcp/callLifetime.js +5 -2
  138. package/dist/mcp/callLifetime.js.map +1 -1
  139. package/dist/mcp/clientPort.js +38 -0
  140. package/dist/mcp/clientPort.js.map +1 -0
  141. package/dist/mcp/gatewayTransport.js +13 -3
  142. package/dist/mcp/gatewayTransport.js.map +1 -1
  143. package/dist/mcp/index.js +16 -1
  144. package/dist/mcp/index.js.map +1 -1
  145. package/dist/mcp/mcpClient.js +207 -45
  146. package/dist/mcp/mcpClient.js.map +1 -1
  147. package/dist/mcp/mockMcpClient.js +13 -0
  148. package/dist/mcp/mockMcpClient.js.map +1 -1
  149. package/dist/mcp/pool/boundTool.js +223 -0
  150. package/dist/mcp/pool/boundTool.js.map +1 -0
  151. package/dist/mcp/pool/clientSet.js +157 -0
  152. package/dist/mcp/pool/clientSet.js.map +1 -0
  153. package/dist/mcp/pool/definitions.js +174 -0
  154. package/dist/mcp/pool/definitions.js.map +1 -0
  155. package/dist/mcp/pool/errors.js +96 -0
  156. package/dist/mcp/pool/errors.js.map +1 -0
  157. package/dist/mcp/pool/identityKey.js +99 -0
  158. package/dist/mcp/pool/identityKey.js.map +1 -0
  159. package/dist/mcp/pool/lease.js +55 -0
  160. package/dist/mcp/pool/lease.js.map +1 -0
  161. package/dist/mcp/pool/listTools.js +150 -0
  162. package/dist/mcp/pool/listTools.js.map +1 -0
  163. package/dist/mcp/pool/mcpClientPool.js +155 -0
  164. package/dist/mcp/pool/mcpClientPool.js.map +1 -0
  165. package/dist/mcp/pool/options.js +123 -0
  166. package/dist/mcp/pool/options.js.map +1 -0
  167. package/dist/mcp/pool/plan.js +140 -0
  168. package/dist/mcp/pool/plan.js.map +1 -0
  169. package/dist/mcp/pool/pool.js +1075 -0
  170. package/dist/mcp/pool/pool.js.map +1 -0
  171. package/dist/mcp/pool/pooledClient.js +94 -0
  172. package/dist/mcp/pool/pooledClient.js.map +1 -0
  173. package/dist/mcp/pool/record.js +80 -0
  174. package/dist/mcp/pool/record.js.map +1 -0
  175. package/dist/mcp/pool/sessionEnded.js +35 -0
  176. package/dist/mcp/pool/sessionEnded.js.map +1 -0
  177. package/dist/mcp/pool/work.js +219 -0
  178. package/dist/mcp/pool/work.js.map +1 -0
  179. package/dist/mcp/requestGuard.js +106 -0
  180. package/dist/mcp/requestGuard.js.map +1 -0
  181. package/dist/mcp/requestLedger.js +76 -3
  182. package/dist/mcp/requestLedger.js.map +1 -1
  183. package/dist/mcp/seriesEvidence.js +16 -7
  184. package/dist/mcp/seriesEvidence.js.map +1 -1
  185. package/dist/mcp/terminate.js +193 -0
  186. package/dist/mcp/terminate.js.map +1 -0
  187. package/dist/mcp/throttleRetry.js +71 -7
  188. package/dist/mcp/throttleRetry.js.map +1 -1
  189. package/dist/redaction/knownStrings.js +34 -0
  190. package/dist/redaction/knownStrings.js.map +1 -1
  191. package/dist/tool-providers/index.js +12 -1
  192. package/dist/tool-providers/index.js.map +1 -1
  193. package/dist/tools/mcpClientUse.js +225 -0
  194. package/dist/tools/mcpClientUse.js.map +1 -0
  195. package/dist/tools/toolSessions.js +44 -1
  196. package/dist/tools/toolSessions.js.map +1 -1
  197. package/dist/types/adapters/mcp/agentcoreRuntime/invoke.d.ts +23 -4
  198. package/dist/types/adapters/mcp/agentcoreRuntime/invoke.d.ts.map +1 -1
  199. package/dist/types/adapters/mcp/agentcoreRuntime/session.d.ts +20 -6
  200. package/dist/types/adapters/mcp/agentcoreRuntime/session.d.ts.map +1 -1
  201. package/dist/types/adapters/mcp/agentcoreRuntime/transport.d.ts.map +1 -1
  202. package/dist/types/core/Agent.d.ts.map +1 -1
  203. package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
  204. package/dist/types/core/slots/buildToolsSlot.d.ts +12 -0
  205. package/dist/types/core/slots/buildToolsSlot.d.ts.map +1 -1
  206. package/dist/types/events/payloads.d.ts +41 -0
  207. package/dist/types/events/payloads.d.ts.map +1 -1
  208. package/dist/types/events/registry.d.ts +3 -1
  209. package/dist/types/events/registry.d.ts.map +1 -1
  210. package/dist/types/identity/types.d.ts +7 -3
  211. package/dist/types/identity/types.d.ts.map +1 -1
  212. package/dist/types/index.d.ts +1 -1
  213. package/dist/types/index.d.ts.map +1 -1
  214. package/dist/types/lib/boundedJson.d.ts +14 -7
  215. package/dist/types/lib/boundedJson.d.ts.map +1 -1
  216. package/dist/types/mcp/callLifetime.d.ts.map +1 -1
  217. package/dist/types/mcp/clientPort.d.ts +79 -0
  218. package/dist/types/mcp/clientPort.d.ts.map +1 -0
  219. package/dist/types/mcp/gatewayTransport.d.ts.map +1 -1
  220. package/dist/types/mcp/index.d.ts +9 -1
  221. package/dist/types/mcp/index.d.ts.map +1 -1
  222. package/dist/types/mcp/mcpClient.d.ts +18 -1
  223. package/dist/types/mcp/mcpClient.d.ts.map +1 -1
  224. package/dist/types/mcp/mockMcpClient.d.ts.map +1 -1
  225. package/dist/types/mcp/pool/boundTool.d.ts +59 -0
  226. package/dist/types/mcp/pool/boundTool.d.ts.map +1 -0
  227. package/dist/types/mcp/pool/clientSet.d.ts +74 -0
  228. package/dist/types/mcp/pool/clientSet.d.ts.map +1 -0
  229. package/dist/types/mcp/pool/definitions.d.ts +104 -0
  230. package/dist/types/mcp/pool/definitions.d.ts.map +1 -0
  231. package/dist/types/mcp/pool/errors.d.ts +77 -0
  232. package/dist/types/mcp/pool/errors.d.ts.map +1 -0
  233. package/dist/types/mcp/pool/identityKey.d.ts +58 -0
  234. package/dist/types/mcp/pool/identityKey.d.ts.map +1 -0
  235. package/dist/types/mcp/pool/lease.d.ts +37 -0
  236. package/dist/types/mcp/pool/lease.d.ts.map +1 -0
  237. package/dist/types/mcp/pool/listTools.d.ts +34 -0
  238. package/dist/types/mcp/pool/listTools.d.ts.map +1 -0
  239. package/dist/types/mcp/pool/mcpClientPool.d.ts +122 -0
  240. package/dist/types/mcp/pool/mcpClientPool.d.ts.map +1 -0
  241. package/dist/types/mcp/pool/options.d.ts +184 -0
  242. package/dist/types/mcp/pool/options.d.ts.map +1 -0
  243. package/dist/types/mcp/pool/plan.d.ts +78 -0
  244. package/dist/types/mcp/pool/plan.d.ts.map +1 -0
  245. package/dist/types/mcp/pool/pool.d.ts +308 -0
  246. package/dist/types/mcp/pool/pool.d.ts.map +1 -0
  247. package/dist/types/mcp/pool/pooledClient.d.ts +94 -0
  248. package/dist/types/mcp/pool/pooledClient.d.ts.map +1 -0
  249. package/dist/types/mcp/pool/record.d.ts +81 -0
  250. package/dist/types/mcp/pool/record.d.ts.map +1 -0
  251. package/dist/types/mcp/pool/sessionEnded.d.ts +25 -0
  252. package/dist/types/mcp/pool/sessionEnded.d.ts.map +1 -0
  253. package/dist/types/mcp/pool/work.d.ts +117 -0
  254. package/dist/types/mcp/pool/work.d.ts.map +1 -0
  255. package/dist/types/mcp/requestGuard.d.ts +71 -0
  256. package/dist/types/mcp/requestGuard.d.ts.map +1 -0
  257. package/dist/types/mcp/requestLedger.d.ts +35 -1
  258. package/dist/types/mcp/requestLedger.d.ts.map +1 -1
  259. package/dist/types/mcp/seriesEvidence.d.ts +10 -6
  260. package/dist/types/mcp/seriesEvidence.d.ts.map +1 -1
  261. package/dist/types/mcp/terminate.d.ts +95 -0
  262. package/dist/types/mcp/terminate.d.ts.map +1 -0
  263. package/dist/types/mcp/throttleRetry.d.ts.map +1 -1
  264. package/dist/types/mcp/types.d.ts +85 -7
  265. package/dist/types/mcp/types.d.ts.map +1 -1
  266. package/dist/types/redaction/knownStrings.d.ts.map +1 -1
  267. package/dist/types/tool-providers/index.d.ts +2 -2
  268. package/dist/types/tool-providers/index.d.ts.map +1 -1
  269. package/dist/types/tools/mcpClientUse.d.ts +60 -0
  270. package/dist/types/tools/mcpClientUse.d.ts.map +1 -0
  271. package/dist/types/tools/toolProvider.d.ts +16 -0
  272. package/dist/types/tools/toolProvider.d.ts.map +1 -1
  273. package/dist/types/tools/toolSessions.d.ts +41 -0
  274. package/dist/types/tools/toolSessions.d.ts.map +1 -1
  275. package/package.json +3 -3
@@ -0,0 +1,34 @@
1
+ /**
2
+ * listTools — one conversation's tools, bound to it: one listing operation.
3
+ *
4
+ * Pattern: one admitted operation per call, the provider's and the lease's alike.
5
+ * Role: § 3.2 and § 6 of the design. A listing is one `list(ctx)` for one
6
+ * conversation, admitted against `maxOperations`. Its setup — the open
7
+ * of the key's client, the `tools/list` — runs inside its slot.
8
+ *
9
+ * - PER CLIENT: the conversation's own client is opened (or reused) and its own
10
+ * list served, listed again when it cannot be served as it stands.
11
+ * - SHARED, under the app's contract: the plan is resolved and the context
12
+ * computed WITHOUT opening anything; a current entry is served touching no
13
+ * client (`client: 'not-needed'`); a listing already under way for it is
14
+ * joined; otherwise the listing runs on THIS conversation's own client —
15
+ * never in another conversation's session.
16
+ * - THE CALLER'S CONTEXT AFTER EVERY WAIT: the app's names are asked again
17
+ * after a joined listing and after this one's own (`Pool.ensureListed`); a
18
+ * list is served only under the context the caller has at that moment, and
19
+ * a moved context is resolved again — at most three rounds, then refused
20
+ * (`binding-changed`).
21
+ *
22
+ * A refused listing never reaches the model as a tool result: it fails that
23
+ * iteration's tool discovery (`agentfootprint.tools.discovery_failed`), as any
24
+ * failing `ToolProvider` does. A list that cannot be read to its end
25
+ * (`McpToolListIncompleteError`, from the client's own discovery) is never
26
+ * served cut short.
27
+ */
28
+ import type { Tool } from '../../tools/tools.js';
29
+ import type { PoolKey } from './identityKey.js';
30
+ import type { Pool } from './pool.js';
31
+ import type { UseFacts } from './record.js';
32
+ /** List `key`'s conversation's tools, bound to it, under one admitted operation. */
33
+ export declare function listTools(pool: Pool, key: PoolKey, signal: AbortSignal | undefined, facts: UseFacts): Promise<readonly Tool[]>;
34
+ //# sourceMappingURL=listTools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listTools.d.ts","sourceRoot":"","sources":["../../../../src/mcp/pool/listTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAIjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,WAAW,CAAC;AAElD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,oFAAoF;AACpF,wBAAsB,SAAS,CAC7B,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,KAAK,EAAE,QAAQ,GACd,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAgD1B"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * mcpClientPool — a client per conversation, for one MCP server.
3
+ *
4
+ * const orders = mcpClientPool({
5
+ * name: 'orders',
6
+ * transport: () =>
7
+ * agentCoreRuntimeMcpTransport({ agentRuntimeArn, region, session: 'reuse', client: aws }),
8
+ * });
9
+ * const agent = Agent.create({ provider, model }).toolProvider(orders.toolProvider()).build();
10
+ * await agent.run({ message, identity: { tenant, principal, conversationId } });
11
+ *
12
+ * Pattern: Facade over one state machine (`pool.ts`), its accounting (`work.ts`),
13
+ * its definitions (`definitions.ts`) and its bound tools (`boundTool.ts`).
14
+ * Role: `docs/design/2026-10-mcp-client-pool.md`. A `'reuse'` session costs a
15
+ * cold start once per conversation instead of once per call — but only
16
+ * if each conversation has a client of its own, opened once, bounded,
17
+ * never closed while in use, ended remotely and said to be. This is
18
+ * the one place that does all of it:
19
+ *
20
+ * - one client per authenticated conversation, keyed by the library's
21
+ * identity encoding of the identity the CALLER named;
22
+ * - one open per key, under the pool's own signal and `initTimeoutMs`;
23
+ * - three budgets — open clients, endings, outstanding operations — each
24
+ * charged until the work under it has SETTLED, and `PoolFullError` at once
25
+ * when one is full: there is no queue;
26
+ * - tool definitions per client incarnation by default, shared only under the
27
+ * app's declared contract, every tool re-checked after each wait and at the
28
+ * send gate;
29
+ * - every ending through `terminate()`, with the remote outcome reported, and
30
+ * `close()` still only local.
31
+ *
32
+ * What it does not do: repeat a call, share anything across processes, bound a
33
+ * remote session it could not end, or make a server enforce per-user
34
+ * permissions.
35
+ */
36
+ import type { ToolProvider } from '../../tools/toolProvider.js';
37
+ import type { McpTerminateOutcome } from '../types.js';
38
+ import { type McpPoolLease } from './lease.js';
39
+ import { type McpClientPoolOptions, type McpPoolIdentity } from './options.js';
40
+ import { type McpPoolStats } from './pool.js';
41
+ /** The scope `terminate` and `permissionsChanged` name. */
42
+ export interface McpPoolScope {
43
+ /** Matched exactly, always: an absent tenant is "no tenant", never "every tenant". */
44
+ readonly tenant?: string;
45
+ /** Absent: every principal of the tenant (`permissionsChanged` only). */
46
+ readonly principal?: string;
47
+ /** Absent: every conversation of the principal. */
48
+ readonly conversationId?: string;
49
+ }
50
+ /** One pool per MCP server: a client per conversation. */
51
+ export interface McpClientPool {
52
+ /** The pool's name: the server. */
53
+ readonly name: string;
54
+ /**
55
+ * The agent path: a `ToolProvider` (id `mcp-pool:<name>`) whose `list(ctx)`
56
+ * takes the run's caller identity (`ToolDispatchContext.callerIdentity`) and
57
+ * returns that conversation's tools, bound to it. A bound tool's `execute`
58
+ * takes a lease on the key's client for one call, opening the client first
59
+ * when the key has none; nothing is held between calls. A run with no caller
60
+ * identity is refused (`no-identity`) — a derived one counts as none.
61
+ */
62
+ toolProvider(): ToolProvider;
63
+ /**
64
+ * Hold `identity`'s conversation client — opened or reused — until
65
+ * `release()`, at most `maxLeaseMs`. The only way to protect a client between
66
+ * calls (a host holds one around `agent.run()`).
67
+ *
68
+ * @throws `McpPoolRefusedError` (`no-identity`, `incomplete-identity`,
69
+ * `init-timeout`, `init-failed`, `closed`) or `PoolFullError`
70
+ */
71
+ acquire(identity: McpPoolIdentity, options?: {
72
+ readonly signal?: AbortSignal;
73
+ }): Promise<McpPoolLease>;
74
+ /**
75
+ * End the conversations `scope` names — one (`{ tenant, principal,
76
+ * conversationId }`) or every one of a principal (`{ tenant, principal }`).
77
+ * New leases stop at once; the next acquire for a key opens a new client.
78
+ * In-flight work is waited for up to 5 s; then each client is ended through
79
+ * `terminate()` once an ending slot and an operation slot are reserved. A
80
+ * client still leased, or whose slots cannot be reserved yet, is reported
81
+ * deferred (`onEvent`), never as ended, and is ended when it can be.
82
+ *
83
+ * @returns one `McpTerminateOutcome` per client it ended
84
+ */
85
+ terminate(scope: McpPoolScope): Promise<readonly McpTerminateOutcome[]>;
86
+ /**
87
+ * Shut down: refuse new work, revoke app leases, abort in-flight calls
88
+ * through the pool's own signal, then end every client as slots can be
89
+ * reserved, at most `maxEnding` at a time. Resolves after a bounded wait;
90
+ * the clients it could not end yet are reported deferred and the work still
91
+ * unsettled stays charged until it settles (`stats()`). Idempotent.
92
+ *
93
+ * @returns one `McpTerminateOutcome` per client it ended
94
+ */
95
+ close(): Promise<readonly McpTerminateOutcome[]>;
96
+ /** Resolves once every charged operation and every ending has settled. */
97
+ settled(): Promise<void>;
98
+ /**
99
+ * The app's permission signal: every tool list in the scope stops being
100
+ * served, and every tool bound to one is refused (`stale-tools`) before it is
101
+ * sent. Per process: a fleet sends it to every process, or versions its
102
+ * `authorization` names.
103
+ */
104
+ permissionsChanged(scope: {
105
+ readonly tenant?: string;
106
+ readonly principal?: string;
107
+ }): void;
108
+ /** The server changed (a deploy hook): every tool list stops being served. */
109
+ toolsChanged(): void;
110
+ /** Run the lazy sweep now: revoked leases, idle ends, deferred ends. No timer is ever installed. */
111
+ sweep(): void;
112
+ /** Counts only — never keys. They report; the budgets enforce. */
113
+ stats(): McpPoolStats;
114
+ }
115
+ /**
116
+ * Build a pool for one MCP server.
117
+ *
118
+ * @throws TypeError when an option is missing, mistyped or out of range, or when
119
+ * `connection` is given — here, when the pool is built
120
+ */
121
+ export declare function mcpClientPool(options: McpClientPoolOptions): McpClientPool;
122
+ //# sourceMappingURL=mcpClientPool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpClientPool.d.ts","sourceRoot":"","sources":["../../../../src/mcp/pool/mcpClientPool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE5D,OAAO,EAAmB,KAAK,oBAAoB,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAChG,OAAO,EAAQ,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAGpD,2DAA2D;AAC3D,MAAM,WAAW,YAAY;IAC3B,sFAAsF;IACtF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,mDAAmD;IACnD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,0DAA0D;AAC1D,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,YAAY,IAAI,YAAY,CAAC;IAC7B;;;;;;;OAOG;IACH,OAAO,CACL,QAAQ,EAAE,eAAe,EACzB,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,OAAO,CAAC,YAAY,CAAC,CAAC;IACzB;;;;;;;;;;OAUG;IACH,SAAS,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC,CAAC;IACxE;;;;;;;;OAQG;IACH,KAAK,IAAI,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC,CAAC;IACjD,0EAA0E;IAC1E,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB;;;;;OAKG;IACH,kBAAkB,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3F,8EAA8E;IAC9E,YAAY,IAAI,IAAI,CAAC;IACrB,oGAAoG;IACpG,KAAK,IAAI,IAAI,CAAC;IACd,kEAAkE;IAClE,KAAK,IAAI,YAAY,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAqE1E"}
@@ -0,0 +1,184 @@
1
+ /**
2
+ * options — what `mcpClientPool` is built from, read and checked once.
3
+ *
4
+ * Pattern: one options type + one reader that refuses by name.
5
+ * Role: The pool's budgets and clocks (`docs/design/2026-10-mcp-client-pool.md`
6
+ * § 3.1). Every number is checked when the pool is built, never at the
7
+ * first call. The pool takes the `mcpClient` options that shape one
8
+ * connection and hands them to every client it opens; it never takes
9
+ * `connection`, because it must build the transport itself — to end
10
+ * the session, to hear the tools-changed notice, and to place the send
11
+ * gate.
12
+ */
13
+ import type { MemoryIdentity } from '../../memory/identity/types.js';
14
+ import { type McpReplayOptions } from '../replay.js';
15
+ import type { RetryOnThrottle } from '../throttleRetry.js';
16
+ import type { McpJsonSchemaValidator, McpSdk, McpTransport } from '../types.js';
17
+ import type { McpPoolReport } from './record.js';
18
+ import type { PoolClientOpener } from './plan.js';
19
+ /** The identity a pool keys a client by: `{ tenant?, principal?, conversationId }`. */
20
+ export type McpPoolIdentity = MemoryIdentity;
21
+ /** What a conversation's tool list may be shared under: two names the app vouches for. */
22
+ export interface McpPoolShareContext {
23
+ /**
24
+ * What the transport hides in its code — a signer's role, the credentials of
25
+ * an AWS client, a custom `fetch`. Hashed into the context, never recorded.
26
+ */
27
+ readonly configuration: string;
28
+ /**
29
+ * What the server's tool visibility depends on — a role and a policy version
30
+ * (`'analyst@policy-7'`). A version in the name reaches a new entry without
31
+ * `permissionsChanged`, for conversations that already have a client too:
32
+ * their tools are listed again under the new name, and a tool bound under the
33
+ * old one is refused before it is sent. Hashed into the context, never
34
+ * recorded.
35
+ */
36
+ readonly authorization: string;
37
+ }
38
+ /**
39
+ * Share tool definitions between conversations — declared by the app, checked by
40
+ * the pool. `share` is asked for every conversation before anything opens, and
41
+ * again at every listing, every call and every send gate after that, so a
42
+ * changed answer takes effect at the next one; it must be synchronous and
43
+ * cheap. A listing's answer is kept only if the names still give the context it
44
+ * was listed for when it arrives — otherwise it is dropped and listed again. Return both names, or `undefined` to keep that conversation's list to
45
+ * itself. Conversations share a list only when the transport's comparable
46
+ * data, both names and the tenant are all equal. A `share` that throws refuses
47
+ * the open (`init-failed`) or, for a conversation that already has a client,
48
+ * that listing or call (`binding-changed`) — its error as `cause`. Never share
49
+ * a server whose list follows the session (one that unlocks tools as a
50
+ * conversation goes on).
51
+ */
52
+ export interface McpPoolDefinitionSharing {
53
+ readonly share: (identity: McpPoolIdentity) => McpPoolShareContext | undefined;
54
+ }
55
+ /** Options for {@link mcpClientPool}. */
56
+ export interface McpClientPoolOptions {
57
+ /** The server's name: every tool's `source`, the provider's id, and the record. */
58
+ readonly name: string;
59
+ /**
60
+ * The transport each client is opened over. A FUNCTION of the identity is
61
+ * preferred: it is called before each client opens (and again for every
62
+ * replacement) with the identity the client is for, so each client gets a
63
+ * transport — and a session map — of its own, and a provider can vend THAT
64
+ * user's credential. One shared object serves every client; a shared
65
+ * `'reuse'` runtime transport then needs `maxClients + maxEnding` at or below
66
+ * its 256 remembered connections.
67
+ */
68
+ readonly transport: McpTransport | ((identity: McpPoolIdentity) => McpTransport);
69
+ /** Open clients — opening, busy or idle. Default 64. */
70
+ readonly maxClients?: number;
71
+ /** Open clients for one principal (one tenant's principal). Default 8. */
72
+ readonly maxClientsPerPrincipal?: number;
73
+ /** Clients being ended at once, until each ending's work has settled. Default 8. */
74
+ readonly maxEnding?: number;
75
+ /**
76
+ * Opens, listings, calls and endings outstanding on any client, each from
77
+ * its admission until its work has settled — not merely until its caller was
78
+ * answered. Default 256. Size it above `maxEnding`.
79
+ */
80
+ readonly maxOperations?: number;
81
+ /** One open per conversation, under this ceiling. Default 30 000 ms. */
82
+ readonly initTimeoutMs?: number;
83
+ /**
84
+ * End a client idle this long, at the next pool interaction (no timer is
85
+ * installed). Default 600 000 ms — below AgentCore Runtime's 900 s idle
86
+ * timeout; set it lower for a runtime configured lower.
87
+ */
88
+ readonly idleMs?: number;
89
+ /** An app lease (`acquire`) is revoked past this. Default 900 000 ms (15 minutes). */
90
+ readonly maxLeaseMs?: number;
91
+ /** A tool list is listed again after this, at the next list. Default 600 000 ms. */
92
+ readonly definitionTtlMs?: number;
93
+ /** `'per-client'` (the default), or the app's declared sharing contract. */
94
+ readonly definitions?: 'per-client' | McpPoolDefinitionSharing;
95
+ /** Refuse an identity without a `principal`. Default `true`. */
96
+ readonly requirePrincipal?: boolean;
97
+ /** Refuse an identity without a `tenant` — for multitenant hosts. Default `false`. */
98
+ readonly requireTenant?: boolean;
99
+ /**
100
+ * What happens outside a run — endings, deferred endings, revoked leases,
101
+ * work that settled after its deadline. Ids and outcomes only. A throwing
102
+ * handler is swallowed and changes nothing.
103
+ */
104
+ readonly onEvent?: (report: McpPoolReport) => void;
105
+ /** Passed to every client: how a tool's result is decoded (`McpClientOptions.resultMode`). */
106
+ readonly resultMode?: 'text' | 'structured' | 'structured-or-json';
107
+ /** Passed to every client: the `initialize` identity. */
108
+ readonly clientInfo?: {
109
+ readonly name: string;
110
+ readonly version: string;
111
+ };
112
+ /** Passed to every client: the 429 retry (`McpClientOptions.retryOnThrottle`). */
113
+ readonly retryOnThrottle?: RetryOnThrottle;
114
+ /**
115
+ * Passed to every client: who may send a tool call again
116
+ * (`McpClientOptions.replay`). Read and checked when the pool is built. The
117
+ * default stays `'compatibility'`. Whatever the policy, the pool's own send
118
+ * gate refuses a pooled request it cannot check (`request-unmatched`).
119
+ */
120
+ readonly replay?: McpReplayOptions;
121
+ /** Passed to every client: the two SDK modules, imported by you (`McpClientOptions.sdk`). */
122
+ readonly sdk?: McpSdk;
123
+ /**
124
+ * Passed to every client: the JSON Schema validator a tool's own output checks
125
+ * use (`McpClientOptions.jsonSchemaValidator`). With `sdk`, give it: a shared
126
+ * definition always runs its own checks, and without a validator a tool that
127
+ * declares an `outputSchema` is refused unsent.
128
+ */
129
+ readonly jsonSchemaValidator?: McpJsonSchemaValidator;
130
+ /** Clock seam — tests drive idle, lease and definition ages without waiting. */
131
+ readonly now?: () => number;
132
+ /** @internal Test seam: how a client is opened (the real path is `openPooledClient`). */
133
+ readonly _open?: PoolClientOpener;
134
+ }
135
+ /** The defaults, named so a test and a docstring cannot drift from the code. */
136
+ export declare const MCP_POOL_DEFAULTS: Readonly<{
137
+ maxClients: 64;
138
+ maxClientsPerPrincipal: 8;
139
+ maxEnding: 8;
140
+ maxOperations: 256;
141
+ initTimeoutMs: 30000;
142
+ idleMs: 600000;
143
+ maxLeaseMs: 900000;
144
+ definitionTtlMs: 600000;
145
+ }>;
146
+ /** At most this many shared definition entries are kept; the least recently used goes first. */
147
+ export declare const MAX_DEFINITION_ENTRIES = 256;
148
+ /** A list longer than this is used by its own client and never shared. */
149
+ export declare const MAX_SHARED_TOOLS = 512;
150
+ /** The pool's settings, read once. */
151
+ export interface PoolSettings {
152
+ readonly name: string;
153
+ readonly transport: (identity: McpPoolIdentity) => McpTransport;
154
+ readonly maxClients: number;
155
+ readonly maxClientsPerPrincipal: number;
156
+ readonly maxEnding: number;
157
+ readonly maxOperations: number;
158
+ readonly initTimeoutMs: number;
159
+ readonly idleMs: number;
160
+ readonly maxLeaseMs: number;
161
+ readonly definitionTtlMs: number;
162
+ readonly share: McpPoolDefinitionSharing['share'] | undefined;
163
+ readonly requirePrincipal: boolean;
164
+ readonly requireTenant: boolean;
165
+ readonly onEvent: ((report: McpPoolReport) => void) | undefined;
166
+ readonly client: {
167
+ readonly resultMode?: McpClientPoolOptions['resultMode'];
168
+ readonly clientInfo?: McpClientPoolOptions['clientInfo'];
169
+ readonly retryOnThrottle?: RetryOnThrottle;
170
+ readonly replay?: McpReplayOptions;
171
+ readonly sdk?: McpSdk;
172
+ readonly jsonSchemaValidator?: McpJsonSchemaValidator;
173
+ };
174
+ readonly now: () => number;
175
+ readonly open: PoolClientOpener | undefined;
176
+ }
177
+ /**
178
+ * Read `options` once.
179
+ *
180
+ * @throws TypeError naming the option, when one is missing, mistyped or out of
181
+ * range, or when `connection` is given — here, when the pool is built.
182
+ */
183
+ export declare function readPoolOptions(options: McpClientPoolOptions): PoolSettings;
184
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../../src/mcp/pool/options.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * plan — what one client is opened from, resolved before anything opens, and
3
+ * the context its tool definitions belong to.
4
+ *
5
+ * Pattern: a pure resolution step + two hashes.
6
+ * Role: § 6.1–6.2 of the design. A client is opened from a PLAN: the
7
+ * transport the factory returns for this identity, resolved at that
8
+ * moment and kept unchanged for the client's life. The plan's
9
+ * `configHash` is SHA-256 over a canonical encoding of the transport's
10
+ * comparable data — the pool name; the transport kind and URL; header
11
+ * names and a digest of their values; a gateway's service, scopes,
12
+ * mode and credential provider id; stdio's command, args and working
13
+ * directory; the transport's own stated `settings`; `resultMode` and
14
+ * `clientInfo`. A function (a `fetch`, an AWS client) cannot be
15
+ * compared: the app's `configuration` name covers it.
16
+ *
17
+ * The definitions CONTEXT is the binding a tool is listed under:
18
+ *
19
+ * - per client (the default): `pc:<configHash>` — the client's own list;
20
+ * - shared, when the app's `share` names both a configuration and an
21
+ * authorization: `sh:<sha256(configHash, configuration, authorization,
22
+ * tenant)>`. The tenant is always in it: the app's names widen sharing
23
+ * across principals, never across tenants.
24
+ *
25
+ * The transport is resolved once, when a client opens; the context is not. The
26
+ * app's names can move — a policy version in `authorization` — so the pool asks
27
+ * `share` again at every listing, every call and every send gate
28
+ * (`contextFor`), over the client's own `configHash`: a conversation that
29
+ * already has a client follows a new name as a new conversation would.
30
+ *
31
+ * Neither hash leaves the process; the app's names are hashed and never kept.
32
+ */
33
+ import type { ClientPort, PooledClientSeam } from '../clientPort.js';
34
+ import type { McpClient, McpClientOptions, McpTransport } from '../types.js';
35
+ import type { PoolKey } from './identityKey.js';
36
+ import type { PoolSettings } from './options.js';
37
+ /** What a client is opened from. */
38
+ export interface ClientPlan {
39
+ readonly transport: McpTransport;
40
+ readonly configHash: string;
41
+ /** The definitions context: `pc:<configHash>` or `sh:<context>`. */
42
+ readonly context: string;
43
+ /** True when the app's sharing contract applies to this conversation. */
44
+ readonly shared: boolean;
45
+ }
46
+ /** An opened client: the ordinary `McpClient`, and the port back (`clientPort.ts`). */
47
+ export interface OpenedClient {
48
+ readonly client: McpClient;
49
+ readonly port: ClientPort;
50
+ }
51
+ /**
52
+ * How the pool opens one client. The real path is `openPooledClient`; a test
53
+ * injects its own (the `_open` seam).
54
+ */
55
+ export type PoolClientOpener = (options: McpClientOptions, seam: PooledClientSeam) => Promise<OpenedClient>;
56
+ /**
57
+ * The plan for `key`: the transport the factory returns now, and the context
58
+ * its definitions belong to.
59
+ *
60
+ * @throws what the transport factory or `share` throws, and a TypeError when
61
+ * `share` answers with anything but two names or `undefined` — the caller
62
+ * refuses the open with `init-failed`, the error as its `cause`
63
+ */
64
+ export declare function resolvePlan(settings: PoolSettings, key: PoolKey): ClientPlan;
65
+ /**
66
+ * The definitions context `key` belongs to now, for a client opened with
67
+ * `configHash`: the app's `share` asked again.
68
+ *
69
+ * @throws what `share` throws, and a TypeError when it answers with anything
70
+ * but two names or `undefined`
71
+ */
72
+ export declare function contextFor(settings: PoolSettings, key: PoolKey, configHash: string): {
73
+ readonly context: string;
74
+ readonly shared: boolean;
75
+ };
76
+ /** SHA-256 over the transport's comparable data (see the module note). */
77
+ export declare function configHashOf(settings: PoolSettings, transport: McpTransport): string;
78
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../../src/mcp/pool/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAuB,YAAY,EAAE,MAAM,cAAc,CAAC;AAEtE,oCAAoC;AACpC,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,uFAAuF;AACvF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAC7B,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,gBAAgB,KACnB,OAAO,CAAC,YAAY,CAAC,CAAC;AAE3B;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,GAAG,UAAU,CAa5E;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,YAAY,EACtB,GAAG,EAAE,OAAO,EACZ,UAAU,EAAE,MAAM,GACjB;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAYxD;AAsBD,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,GAAG,MAAM,CASpF"}