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 @@
1
+ {"version":3,"file":"clientSet.js","sourceRoot":"","sources":["../../../../src/mcp/pool/clientSet.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * definitions — the tool lists a pool serves, and when each stops being served.
3
+ *
4
+ * Pattern: one list type, two owners — a client incarnation, or a shared entry.
5
+ * Role: § 6 of the design. A definition is what one `tools/list` entry says:
6
+ * name, description, input schema, and the declarations its `_meta`
7
+ * carries. The executable half (the connection) is never shared.
8
+ *
9
+ * - PER CLIENT (the default): a conversation's list is its own client's, and
10
+ * it belongs to that client INCARNATION alone — a replacement client, even
11
+ * one opened from the same plan, is a new session whose list may differ,
12
+ * so it lists again.
13
+ * - SHARED, only under the app's declared contract: one entry per context
14
+ * (`plan.ts`), listed on the client of whichever conversation needs it,
15
+ * bounded at `MAX_DEFINITION_ENTRIES` entries; a list longer than
16
+ * `MAX_SHARED_TOOLS` is used by its own client and not shared.
17
+ *
18
+ * A list stops being served in four ways, plus a time limit: the configuration
19
+ * (a new context is a new list), the server's tools-changed notice, the app's
20
+ * `permissionsChanged`, and `toolsChanged`. Invalidation moves the list's
21
+ * GENERATION at once — every tool bound to an older one is refused — and marks
22
+ * it to be listed again. A lapsed time limit lists again at the next list, and
23
+ * moves the generation only if the new list differs. A generation counts within
24
+ * one list: a replacement client and a new entry start counts of their own, and
25
+ * a binding names the list it came from, so no number of an old list can match
26
+ * a new one. A listing still in flight when its list's generation moved is
27
+ * discarded, never written.
28
+ *
29
+ * Every list is a frozen plain-data copy (`mcp/plainData.ts` · `copyJsonObject`),
30
+ * written once per generation, by one listing at a time.
31
+ */
32
+ import type { Tool } from '../../tools/tools.js';
33
+ import type { McpListedTool } from '../types.js';
34
+ /** One definition, frozen, and its canonical JSON — what "the same definition" compares. */
35
+ export interface Definition {
36
+ readonly listed: McpListedTool;
37
+ readonly canonical: string;
38
+ }
39
+ /** A frozen copy of `listed`, or `undefined` when it is not plain JSON data. */
40
+ export declare function definitionOf(listed: McpListedTool): Definition | undefined;
41
+ /**
42
+ * One list: an incarnation's own or a shared entry. Its `id` is stable for its
43
+ * life; its `generation` moves on invalidation, and on a time-limit relisting
44
+ * that changed it.
45
+ */
46
+ export declare class DefinitionList {
47
+ readonly id: string;
48
+ private current;
49
+ private tools;
50
+ /** Has any listing been written? */
51
+ private written;
52
+ /** 0 until the first listing is written. */
53
+ generation: number;
54
+ /** Invalidated: listed again before it is served. */
55
+ stale: boolean;
56
+ /** When it was last written, on the pool's clock. */
57
+ listedAt: number;
58
+ /** The listing in flight, joined by anyone who needs the same list. */
59
+ listing: Promise<void> | undefined;
60
+ /** Can it be served at `now`, as it stands? */
61
+ servable(now: number, ttlMs: number): boolean;
62
+ /**
63
+ * Invalidate: every older binding is refused, the next list lists again, and
64
+ * a listing in flight is discarded — even a first one, before anything was
65
+ * written. Generations only ever increase.
66
+ */
67
+ invalidate(): void;
68
+ /** The definition named `name`, at the current generation. */
69
+ definition(name: string): Definition | undefined;
70
+ /** The client's own wrapped tool named `name` (per-client lists only). */
71
+ tool(name: string): Tool | undefined;
72
+ /** Every definition, in listing order. */
73
+ all(): readonly Definition[];
74
+ /**
75
+ * Write a listing that began at generation `began`. Refused — `false`, nothing
76
+ * written — when the generation moved while it ran. A first write moves the
77
+ * generation to a number no binding has seen; a write after invalidation keeps
78
+ * the moved one; a time-limit rewrite moves it only when the list differs.
79
+ */
80
+ write(began: number, definitions: readonly Definition[], tools: readonly Tool[] | undefined, now: number): boolean;
81
+ }
82
+ /** A shared entry: a list and the tenant its context carries. */
83
+ export interface SharedEntry {
84
+ readonly list: DefinitionList;
85
+ readonly tenant: string;
86
+ }
87
+ /**
88
+ * The shared definition entries, by context — bounded at
89
+ * `MAX_DEFINITION_ENTRIES`, the least recently used dropped first. A dropped
90
+ * entry's bindings are refused as stale: the entry they name is gone.
91
+ */
92
+ export declare class SharedDefinitions {
93
+ private readonly maxEntries;
94
+ private readonly entries;
95
+ constructor(maxEntries?: number);
96
+ get size(): number;
97
+ /** The entry for `context`, created empty when there is none; most recently used. */
98
+ entryFor(context: string, tenant: string): SharedEntry;
99
+ /** The entry for `context` if it still exists — never created. */
100
+ peek(context: string): SharedEntry | undefined;
101
+ /** Invalidate every entry `matches` selects. */
102
+ invalidate(matches: (entry: SharedEntry) => boolean): void;
103
+ }
@@ -0,0 +1,168 @@
1
+ /**
2
+ * definitions — the tool lists a pool serves, and when each stops being served.
3
+ *
4
+ * Pattern: one list type, two owners — a client incarnation, or a shared entry.
5
+ * Role: § 6 of the design. A definition is what one `tools/list` entry says:
6
+ * name, description, input schema, and the declarations its `_meta`
7
+ * carries. The executable half (the connection) is never shared.
8
+ *
9
+ * - PER CLIENT (the default): a conversation's list is its own client's, and
10
+ * it belongs to that client INCARNATION alone — a replacement client, even
11
+ * one opened from the same plan, is a new session whose list may differ,
12
+ * so it lists again.
13
+ * - SHARED, only under the app's declared contract: one entry per context
14
+ * (`plan.ts`), listed on the client of whichever conversation needs it,
15
+ * bounded at `MAX_DEFINITION_ENTRIES` entries; a list longer than
16
+ * `MAX_SHARED_TOOLS` is used by its own client and not shared.
17
+ *
18
+ * A list stops being served in four ways, plus a time limit: the configuration
19
+ * (a new context is a new list), the server's tools-changed notice, the app's
20
+ * `permissionsChanged`, and `toolsChanged`. Invalidation moves the list's
21
+ * GENERATION at once — every tool bound to an older one is refused — and marks
22
+ * it to be listed again. A lapsed time limit lists again at the next list, and
23
+ * moves the generation only if the new list differs. A generation counts within
24
+ * one list: a replacement client and a new entry start counts of their own, and
25
+ * a binding names the list it came from, so no number of an old list can match
26
+ * a new one. A listing still in flight when its list's generation moved is
27
+ * discarded, never written.
28
+ *
29
+ * Every list is a frozen plain-data copy (`mcp/plainData.ts` · `copyJsonObject`),
30
+ * written once per generation, by one listing at a time.
31
+ */
32
+ import { canonicalJson } from '../../lib/canonicalJson.js';
33
+ import { copyJsonObject } from '../plainData.js';
34
+ import { MAX_DEFINITION_ENTRIES } from './options.js';
35
+ /** A frozen copy of `listed`, or `undefined` when it is not plain JSON data. */
36
+ export function definitionOf(listed) {
37
+ const copy = copyJsonObject(listed);
38
+ if (copy === undefined || typeof copy['name'] !== 'string')
39
+ return undefined;
40
+ return { listed: deepFreeze(copy), canonical: canonicalJson(copy) };
41
+ }
42
+ function deepFreeze(value) {
43
+ if (value !== null && typeof value === 'object' && !Object.isFrozen(value)) {
44
+ Object.freeze(value);
45
+ for (const child of Object.values(value))
46
+ deepFreeze(child);
47
+ }
48
+ return value;
49
+ }
50
+ /** Sequence for list ids: a binding names the list it came from. */
51
+ let lists = 0;
52
+ /**
53
+ * One list: an incarnation's own or a shared entry. Its `id` is stable for its
54
+ * life; its `generation` moves on invalidation, and on a time-limit relisting
55
+ * that changed it.
56
+ */
57
+ export class DefinitionList {
58
+ id = `list-${++lists}`;
59
+ current = new Map();
60
+ tools = new Map();
61
+ /** Has any listing been written? */
62
+ written = false;
63
+ /** 0 until the first listing is written. */
64
+ generation = 0;
65
+ /** Invalidated: listed again before it is served. */
66
+ stale = false;
67
+ /** When it was last written, on the pool's clock. */
68
+ listedAt = 0;
69
+ /** The listing in flight, joined by anyone who needs the same list. */
70
+ listing;
71
+ /** Can it be served at `now`, as it stands? */
72
+ servable(now, ttlMs) {
73
+ return this.written && !this.stale && now - this.listedAt < ttlMs;
74
+ }
75
+ /**
76
+ * Invalidate: every older binding is refused, the next list lists again, and
77
+ * a listing in flight is discarded — even a first one, before anything was
78
+ * written. Generations only ever increase.
79
+ */
80
+ invalidate() {
81
+ this.generation += 1;
82
+ this.stale = true;
83
+ }
84
+ /** The definition named `name`, at the current generation. */
85
+ definition(name) {
86
+ return this.current.get(name);
87
+ }
88
+ /** The client's own wrapped tool named `name` (per-client lists only). */
89
+ tool(name) {
90
+ return this.tools.get(name);
91
+ }
92
+ /** Every definition, in listing order. */
93
+ all() {
94
+ return [...this.current.values()];
95
+ }
96
+ /**
97
+ * Write a listing that began at generation `began`. Refused — `false`, nothing
98
+ * written — when the generation moved while it ran. A first write moves the
99
+ * generation to a number no binding has seen; a write after invalidation keeps
100
+ * the moved one; a time-limit rewrite moves it only when the list differs.
101
+ */
102
+ write(began, definitions, tools, now) {
103
+ if (this.generation !== began)
104
+ return false;
105
+ const next = new Map(definitions.map((d) => [d.listed.name, d]));
106
+ if (!this.written)
107
+ this.generation += 1;
108
+ else if (!this.stale && differs(this.current, next))
109
+ this.generation += 1;
110
+ this.current = next;
111
+ this.tools = new Map((tools ?? []).map((t) => [t.schema.name, t]));
112
+ this.written = true;
113
+ this.stale = false;
114
+ this.listedAt = now;
115
+ return true;
116
+ }
117
+ }
118
+ function differs(a, b) {
119
+ if (a.size !== b.size)
120
+ return true;
121
+ for (const [name, definition] of a) {
122
+ if (b.get(name)?.canonical !== definition.canonical)
123
+ return true;
124
+ }
125
+ return false;
126
+ }
127
+ /**
128
+ * The shared definition entries, by context — bounded at
129
+ * `MAX_DEFINITION_ENTRIES`, the least recently used dropped first. A dropped
130
+ * entry's bindings are refused as stale: the entry they name is gone.
131
+ */
132
+ export class SharedDefinitions {
133
+ maxEntries;
134
+ entries = new Map();
135
+ constructor(maxEntries = MAX_DEFINITION_ENTRIES) {
136
+ this.maxEntries = maxEntries;
137
+ }
138
+ get size() {
139
+ return this.entries.size;
140
+ }
141
+ /** The entry for `context`, created empty when there is none; most recently used. */
142
+ entryFor(context, tenant) {
143
+ let entry = this.entries.get(context);
144
+ if (entry !== undefined)
145
+ this.entries.delete(context);
146
+ else
147
+ entry = { list: new DefinitionList(), tenant };
148
+ this.entries.set(context, entry);
149
+ while (this.entries.size > this.maxEntries) {
150
+ const oldest = this.entries.keys().next().value;
151
+ if (oldest === undefined)
152
+ break;
153
+ this.entries.delete(oldest);
154
+ }
155
+ return entry;
156
+ }
157
+ /** The entry for `context` if it still exists — never created. */
158
+ peek(context) {
159
+ return this.entries.get(context);
160
+ }
161
+ /** Invalidate every entry `matches` selects. */
162
+ invalidate(matches) {
163
+ for (const entry of this.entries.values())
164
+ if (matches(entry))
165
+ entry.list.invalidate();
166
+ }
167
+ }
168
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../../../src/mcp/pool/definitions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * errors — the pool's two refusals, each one fixed sentence.
3
+ *
4
+ * Pattern: typed errors whose message reaches the model and whose fields reach
5
+ * the app.
6
+ * Role: A refusal comes before the `tools/call` is sent, and says so
7
+ * (`sent: false`) for the record of what that attempt did. Control
8
+ * requests made on the way — the `initialize` of a replacement client,
9
+ * a revalidating `tools/list` — may already have reached the server;
10
+ * `sent` describes the `tools/call` only.
11
+ *
12
+ * A message is a fixed sentence per reason. It names no identity, no key, no
13
+ * session and no count: the counts ride typed fields the app reads, and the
14
+ * original error of a failed open rides `cause`, for the app, never composed
15
+ * into the message.
16
+ */
17
+ /** Why a pool refused, by name. */
18
+ export type McpPoolRefusal = 'no-identity' | 'incomplete-identity' | 'identity-mismatch' | 'init-timeout' | 'init-failed' | 'stale-tools' | 'binding-changed' | 'request-unmatched' | 'lease-expired' | 'closed';
19
+ /** The sentence each refusal reaches the model as. */
20
+ export declare const MCP_POOL_REFUSAL_SENTENCES: Readonly<Record<McpPoolRefusal, string>>;
21
+ /**
22
+ * The pool refused before the `tools/call` was sent — by `reason`.
23
+ *
24
+ * `init-failed` keeps the open's own error as `cause`, for the app; its text is
25
+ * never in the message.
26
+ */
27
+ export declare class McpPoolRefusedError extends Error {
28
+ readonly reason: McpPoolRefusal;
29
+ /** The pool's name: the server. */
30
+ readonly server: string;
31
+ readonly code: "ERR_MCP_POOL_REFUSED";
32
+ /** The `tools/call` was not sent. Control requests on the way may have been. */
33
+ readonly sent: false;
34
+ constructor(reason: McpPoolRefusal,
35
+ /** The pool's name: the server. */
36
+ server: string, options?: {
37
+ readonly cause?: unknown;
38
+ });
39
+ }
40
+ /** Which budget was full. */
41
+ export type McpPoolLimit = 'pool' | 'principal' | 'ending' | 'operations';
42
+ /** The one sentence a full pool reaches the model as. */
43
+ export declare const POOL_FULL_SENTENCE = "The connection pool for this server was full, so the tool call was not sent.";
44
+ /**
45
+ * A budget was full, so the work was refused at once — there is no queue. Its
46
+ * scope is the `tools/call`, as with `sent: false`. The counts ride typed fields.
47
+ */
48
+ export declare class PoolFullError extends Error {
49
+ /** The pool's name: the server. */
50
+ readonly server: string;
51
+ /** Which budget was full. */
52
+ readonly limit: McpPoolLimit;
53
+ /** That budget's size. */
54
+ readonly max: number;
55
+ /** Busy clients when it was refused. */
56
+ readonly busy: number;
57
+ /** Clients being ended when it was refused. */
58
+ readonly ending: number;
59
+ /** Operations charged when it was refused. */
60
+ readonly operations: number;
61
+ readonly code: "ERR_MCP_POOL_FULL";
62
+ readonly sent: false;
63
+ constructor(
64
+ /** The pool's name: the server. */
65
+ server: string,
66
+ /** Which budget was full. */
67
+ limit: McpPoolLimit,
68
+ /** That budget's size. */
69
+ max: number,
70
+ /** Busy clients when it was refused. */
71
+ busy: number,
72
+ /** Clients being ended when it was refused. */
73
+ ending: number,
74
+ /** Operations charged when it was refused. */
75
+ operations: number);
76
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * errors — the pool's two refusals, each one fixed sentence.
3
+ *
4
+ * Pattern: typed errors whose message reaches the model and whose fields reach
5
+ * the app.
6
+ * Role: A refusal comes before the `tools/call` is sent, and says so
7
+ * (`sent: false`) for the record of what that attempt did. Control
8
+ * requests made on the way — the `initialize` of a replacement client,
9
+ * a revalidating `tools/list` — may already have reached the server;
10
+ * `sent` describes the `tools/call` only.
11
+ *
12
+ * A message is a fixed sentence per reason. It names no identity, no key, no
13
+ * session and no count: the counts ride typed fields the app reads, and the
14
+ * original error of a failed open rides `cause`, for the app, never composed
15
+ * into the message.
16
+ */
17
+ /** The sentence each refusal reaches the model as. */
18
+ export const MCP_POOL_REFUSAL_SENTENCES = Object.freeze({
19
+ 'no-identity': "This tool needs the caller's identity and none was named, so the call this result answers was not sent.",
20
+ 'incomplete-identity': 'This tool needs a complete caller identity and the one named is incomplete, so the call this result answers was not sent.',
21
+ 'identity-mismatch': 'This tool was listed for another conversation, so the tool call was not sent.',
22
+ 'init-timeout': 'The connection to this server did not open in time, so the tool call was not sent.',
23
+ 'init-failed': 'The connection to this server could not be opened, so the tool call was not sent.',
24
+ 'stale-tools': "This tool's definition is no longer current, so the tool call was not sent. List the tools again.",
25
+ 'binding-changed': 'This tool was listed for another configuration of this server, so the tool call was not sent. List the tools again.',
26
+ 'request-unmatched': "The pool could not check this tool's request against its listing before sending it, so the tool call was not sent.",
27
+ 'lease-expired': 'This connection lease has expired, so the tool call was not sent.',
28
+ closed: 'The connection pool for this server is closed, so the tool call was not sent.',
29
+ });
30
+ /**
31
+ * The pool refused before the `tools/call` was sent — by `reason`.
32
+ *
33
+ * `init-failed` keeps the open's own error as `cause`, for the app; its text is
34
+ * never in the message.
35
+ */
36
+ export class McpPoolRefusedError extends Error {
37
+ reason;
38
+ server;
39
+ code = 'ERR_MCP_POOL_REFUSED';
40
+ /** The `tools/call` was not sent. Control requests on the way may have been. */
41
+ sent = false;
42
+ constructor(reason,
43
+ /** The pool's name: the server. */
44
+ server, options = {}) {
45
+ super(MCP_POOL_REFUSAL_SENTENCES[reason], {
46
+ ...(options.cause !== undefined && { cause: options.cause }),
47
+ });
48
+ this.reason = reason;
49
+ this.server = server;
50
+ this.name = 'McpPoolRefusedError';
51
+ }
52
+ }
53
+ /** The one sentence a full pool reaches the model as. */
54
+ export const POOL_FULL_SENTENCE = 'The connection pool for this server was full, so the tool call was not sent.';
55
+ /**
56
+ * A budget was full, so the work was refused at once — there is no queue. Its
57
+ * scope is the `tools/call`, as with `sent: false`. The counts ride typed fields.
58
+ */
59
+ export class PoolFullError extends Error {
60
+ server;
61
+ limit;
62
+ max;
63
+ busy;
64
+ ending;
65
+ operations;
66
+ code = 'ERR_MCP_POOL_FULL';
67
+ sent = false;
68
+ constructor(
69
+ /** The pool's name: the server. */
70
+ server,
71
+ /** Which budget was full. */
72
+ limit,
73
+ /** That budget's size. */
74
+ max,
75
+ /** Busy clients when it was refused. */
76
+ busy,
77
+ /** Clients being ended when it was refused. */
78
+ ending,
79
+ /** Operations charged when it was refused. */
80
+ operations) {
81
+ super(POOL_FULL_SENTENCE);
82
+ this.server = server;
83
+ this.limit = limit;
84
+ this.max = max;
85
+ this.busy = busy;
86
+ this.ending = ending;
87
+ this.operations = operations;
88
+ this.name = 'PoolFullError';
89
+ }
90
+ }
91
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../../src/mcp/pool/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAeH,sDAAsD;AACtD,MAAM,CAAC,MAAM,0BAA0B,GAA6C,MAAM,CAAC,MAAM,CAAC;IAChG,aAAa,EACX,yGAAyG;IAC3G,qBAAqB,EACnB,2HAA2H;IAC7H,mBAAmB,EACjB,+EAA+E;IACjF,cAAc,EACZ,oFAAoF;IACtF,aAAa,EACX,mFAAmF;IACrF,aAAa,EACX,mGAAmG;IACrG,iBAAiB,EACf,qHAAqH;IACvH,mBAAmB,EACjB,oHAAoH;IACtH,eAAe,EAAE,mEAAmE;IACpF,MAAM,EAAE,+EAA+E;CACxF,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAMjC;IAEA;IAPF,IAAI,GAAG,sBAA+B,CAAC;IAChD,gFAAgF;IACvE,IAAI,GAAG,KAAc,CAAC;IAE/B,YACW,MAAsB;IAC/B,mCAAmC;IAC1B,MAAc,EACvB,UAAwC,EAAE;QAE1C,KAAK,CAAC,0BAA0B,CAAC,MAAM,CAAC,EAAE;YACxC,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;SAC7D,CAAC,CAAC;QAPM,WAAM,GAAN,MAAM,CAAgB;QAEtB,WAAM,GAAN,MAAM,CAAQ;QAMvB,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAKD,yDAAyD;AACzD,MAAM,CAAC,MAAM,kBAAkB,GAC7B,8EAA8E,CAAC;AAEjF;;;GAGG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IAM3B;IAEA;IAEA;IAEA;IAEA;IAEA;IAfF,IAAI,GAAG,mBAA4B,CAAC;IACpC,IAAI,GAAG,KAAc,CAAC;IAE/B;IACE,mCAAmC;IAC1B,MAAc;IACvB,6BAA6B;IACpB,KAAmB;IAC5B,0BAA0B;IACjB,GAAW;IACpB,wCAAwC;IAC/B,IAAY;IACrB,+CAA+C;IACtC,MAAc;IACvB,8CAA8C;IACrC,UAAkB;QAE3B,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAZjB,WAAM,GAAN,MAAM,CAAQ;QAEd,UAAK,GAAL,KAAK,CAAc;QAEnB,QAAG,GAAH,GAAG,CAAQ;QAEX,SAAI,GAAJ,IAAI,CAAQ;QAEZ,WAAM,GAAN,MAAM,CAAQ;QAEd,eAAU,GAAV,UAAU,CAAQ;QAG3B,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * identityKey — the conversation a pooled client belongs to, as one key.
3
+ *
4
+ * Pattern: the library's one identity encoding, never a second.
5
+ * Role: The client key is `identityNamespace` of the identity the CALLER
6
+ * named — each field through `encodeIdentityField`, the encoding the
7
+ * memory layer calls the tenant boundary. It is injective: tenant
8
+ * `acme/hr` with principal `alice` and tenant `acme` with principal
9
+ * `hr/alice` are two keys, and an absent field and a field named `_`
10
+ * are two keys. A pool is one server, so the key needs no server
11
+ * segment, and two pools never share a client.
12
+ *
13
+ * Two doors only: the run's caller identity (`ToolDispatchContext.callerIdentity`,
14
+ * `ToolExecutionContext.identity`) and the identity app code passes to `acquire`
15
+ * and `terminate`. Never tool arguments, model output, a message, a request
16
+ * body, or a `sessionId` alone. No identity value is ever written to an error,
17
+ * an event or a report: the wire carries `keyHash`, the tool-session digest.
18
+ */
19
+ import type { McpPoolIdentity } from './options.js';
20
+ /** One conversation's key, and the coarser keys its budgets count by. */
21
+ export interface PoolKey {
22
+ /** `identityNamespace` of the identity — the client key. */
23
+ readonly key: string;
24
+ /** The tenant and principal segments — what `maxClientsPerPrincipal` counts by. */
25
+ readonly principal: string;
26
+ /** The tenant segment — always part of a shared definitions context. */
27
+ readonly tenant: string;
28
+ /** The digest the record carries in the key's place. */
29
+ readonly keyHash: string;
30
+ /** The identity itself, as a frozen copy — what the transport factory and `share` are asked with. */
31
+ readonly identity: McpPoolIdentity;
32
+ }
33
+ /** What an identity must carry. */
34
+ export interface IdentityRules {
35
+ readonly requirePrincipal: boolean;
36
+ readonly requireTenant: boolean;
37
+ }
38
+ /**
39
+ * The key for `identity`, or why there is none: `'no-identity'` when nothing was
40
+ * named (a derived identity counts as none), `'incomplete-identity'` when it
41
+ * lacks a `conversationId`, a required `principal` or a required `tenant`, or a
42
+ * field is not a string.
43
+ */
44
+ export declare function poolKeyOf(identity: unknown, rules: IdentityRules): PoolKey | 'no-identity' | 'incomplete-identity';
45
+ /**
46
+ * Which keys a scope names. The tenant is matched exactly, always — an absent
47
+ * tenant is the absent segment, never a wildcard, because the tenant is the
48
+ * boundary. A scope that names a `conversationId` names exactly that one
49
+ * conversation (an absent principal is then the absent segment, as in the key).
50
+ * A scope without one names every conversation of its principal, and a scope
51
+ * without a principal either names every conversation of its tenant.
52
+ */
53
+ export declare function scopeMatcher(scope: {
54
+ readonly tenant?: string;
55
+ readonly principal?: string;
56
+ readonly conversationId?: string;
57
+ }): (key: PoolKey) => boolean;
@@ -0,0 +1,94 @@
1
+ /**
2
+ * identityKey — the conversation a pooled client belongs to, as one key.
3
+ *
4
+ * Pattern: the library's one identity encoding, never a second.
5
+ * Role: The client key is `identityNamespace` of the identity the CALLER
6
+ * named — each field through `encodeIdentityField`, the encoding the
7
+ * memory layer calls the tenant boundary. It is injective: tenant
8
+ * `acme/hr` with principal `alice` and tenant `acme` with principal
9
+ * `hr/alice` are two keys, and an absent field and a field named `_`
10
+ * are two keys. A pool is one server, so the key needs no server
11
+ * segment, and two pools never share a client.
12
+ *
13
+ * Two doors only: the run's caller identity (`ToolDispatchContext.callerIdentity`,
14
+ * `ToolExecutionContext.identity`) and the identity app code passes to `acquire`
15
+ * and `terminate`. Never tool arguments, model output, a message, a request
16
+ * body, or a `sessionId` alone. No identity value is ever written to an error,
17
+ * an event or a report: the wire carries `keyHash`, the tool-session digest.
18
+ */
19
+ import { encodeIdentityField } from '../../memory/identity/encode.js';
20
+ import { identityNamespace } from '../../memory/identity/types.js';
21
+ import { hashSessionKey } from '../../tools/toolSessions.js';
22
+ /**
23
+ * The key for `identity`, or why there is none: `'no-identity'` when nothing was
24
+ * named (a derived identity counts as none), `'incomplete-identity'` when it
25
+ * lacks a `conversationId`, a required `principal` or a required `tenant`, or a
26
+ * field is not a string.
27
+ */
28
+ export function poolKeyOf(identity, rules) {
29
+ if (identity === undefined || identity === null)
30
+ return 'no-identity';
31
+ if (typeof identity !== 'object' || Array.isArray(identity))
32
+ return 'incomplete-identity';
33
+ const raw = identity;
34
+ const fields = {};
35
+ for (const name of ['tenant', 'principal', 'conversationId']) {
36
+ let value;
37
+ try {
38
+ value = raw[name];
39
+ }
40
+ catch {
41
+ return 'incomplete-identity';
42
+ }
43
+ if (value === undefined || value === null || value === '')
44
+ continue;
45
+ if (typeof value !== 'string')
46
+ return 'incomplete-identity';
47
+ fields[name] = value;
48
+ }
49
+ if (fields.conversationId === undefined)
50
+ return 'incomplete-identity';
51
+ if (rules.requirePrincipal && fields.principal === undefined)
52
+ return 'incomplete-identity';
53
+ if (rules.requireTenant && fields.tenant === undefined)
54
+ return 'incomplete-identity';
55
+ const named = Object.freeze({
56
+ conversationId: fields.conversationId,
57
+ ...(fields.tenant !== undefined && { tenant: fields.tenant }),
58
+ ...(fields.principal !== undefined && { principal: fields.principal }),
59
+ });
60
+ const key = identityNamespace(named);
61
+ const tenant = encodeIdentityField(named.tenant);
62
+ return {
63
+ key,
64
+ principal: `${tenant}/${encodeIdentityField(named.principal)}`,
65
+ tenant,
66
+ keyHash: hashSessionKey(key),
67
+ identity: named,
68
+ };
69
+ }
70
+ /**
71
+ * Which keys a scope names. The tenant is matched exactly, always — an absent
72
+ * tenant is the absent segment, never a wildcard, because the tenant is the
73
+ * boundary. A scope that names a `conversationId` names exactly that one
74
+ * conversation (an absent principal is then the absent segment, as in the key).
75
+ * A scope without one names every conversation of its principal, and a scope
76
+ * without a principal either names every conversation of its tenant.
77
+ */
78
+ export function scopeMatcher(scope) {
79
+ const tenant = encodeIdentityField(scope.tenant);
80
+ if (scope.conversationId !== undefined && scope.conversationId !== '') {
81
+ const exact = identityNamespace({
82
+ conversationId: scope.conversationId,
83
+ ...(scope.tenant !== undefined && { tenant: scope.tenant }),
84
+ ...(scope.principal !== undefined && { principal: scope.principal }),
85
+ });
86
+ return (key) => key.key === exact;
87
+ }
88
+ if (scope.principal !== undefined && scope.principal !== '') {
89
+ const principal = `${tenant}/${encodeIdentityField(scope.principal)}`;
90
+ return (key) => key.principal === principal;
91
+ }
92
+ return (key) => key.tenant === tenant;
93
+ }
94
+ //# sourceMappingURL=identityKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identityKey.js","sourceRoot":"","sources":["../../../../src/mcp/pool/identityKey.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * lease — the app's explicit, bounded hold on one conversation's client.
3
+ *
4
+ * Pattern: a handle that releases at most once, by hand or by `await using`.
5
+ * Role: § 3.3 and § 5.2 of the design. `acquire` is for code that drives a
6
+ * sequence itself, or a host that must keep a conversation's client
7
+ * from eviction for a whole turn (it holds one around `agent.run()`, and
8
+ * the provider then finds the same client). It is the only way to
9
+ * protect a client between calls: there is no hidden grace period.
10
+ *
11
+ * The `acquire` that opened it was the operation; the held lease is not one. It
12
+ * is bounded by `maxLeaseMs`: past it, it is revoked at the next pool
13
+ * interaction and reported, and its next use throws `lease-expired`. Calls
14
+ * already in flight keep their own leases until they settle.
15
+ */
16
+ import type { Tool } from '../../tools/tools.js';
17
+ import type { PoolKey } from './identityKey.js';
18
+ import type { HeldLease, Pool } from './pool.js';
19
+ /** The app's hold on one conversation's client. Release it — or `await using` it. */
20
+ export interface McpPoolLease extends AsyncDisposable {
21
+ /**
22
+ * This conversation's tools, bound to it. A call through one needs the
23
+ * conversation's identity on its context (`ToolExecutionContext.identity`);
24
+ * the agent puts it there for a run that named one.
25
+ *
26
+ * @throws `McpPoolRefusedError` (`lease-expired`) once the lease was revoked
27
+ * or released; what a listing throws otherwise
28
+ */
29
+ tools(options?: {
30
+ readonly signal?: AbortSignal;
31
+ }): Promise<readonly Tool[]>;
32
+ /** Release the hold. Idempotent. */
33
+ release(): void;
34
+ }
35
+ /** The lease handle for `held`, on `key`'s client. */
36
+ export declare function leaseHandle(pool: Pool, key: PoolKey, held: HeldLease): McpPoolLease;