@namzu/sdk 46.0.0 → 48.1.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 (768) hide show
  1. package/CHANGELOG.md +351 -8
  2. package/README.md +7 -8
  3. package/dist/advisory/history.d.ts.map +1 -1
  4. package/dist/advisory/history.js +21 -1
  5. package/dist/advisory/history.js.map +1 -1
  6. package/dist/advisory/index.d.ts +1 -1
  7. package/dist/advisory/index.d.ts.map +1 -1
  8. package/dist/advisory/index.js +1 -1
  9. package/dist/advisory/index.js.map +1 -1
  10. package/dist/advisory/registry.d.ts +17 -0
  11. package/dist/advisory/registry.d.ts.map +1 -1
  12. package/dist/advisory/registry.js +26 -0
  13. package/dist/advisory/registry.js.map +1 -1
  14. package/dist/agents/PipelineAgent.d.ts +2 -46
  15. package/dist/agents/PipelineAgent.d.ts.map +1 -1
  16. package/dist/agents/PipelineAgent.js +2 -242
  17. package/dist/agents/PipelineAgent.js.map +1 -1
  18. package/dist/agents/QueryAgent.d.ts +21 -0
  19. package/dist/agents/QueryAgent.d.ts.map +1 -0
  20. package/dist/agents/QueryAgent.js +214 -0
  21. package/dist/agents/QueryAgent.js.map +1 -0
  22. package/dist/agents/ReactiveAgent.d.ts +4 -16
  23. package/dist/agents/ReactiveAgent.d.ts.map +1 -1
  24. package/dist/agents/ReactiveAgent.js +4 -183
  25. package/dist/agents/ReactiveAgent.js.map +1 -1
  26. package/dist/agents/RouterAgent.d.ts +2 -20
  27. package/dist/agents/RouterAgent.d.ts.map +1 -1
  28. package/dist/agents/RouterAgent.js +2 -266
  29. package/dist/agents/RouterAgent.js.map +1 -1
  30. package/dist/agents/SupervisorAgent.d.ts +3 -43
  31. package/dist/agents/SupervisorAgent.d.ts.map +1 -1
  32. package/dist/agents/SupervisorAgent.js +3 -418
  33. package/dist/agents/SupervisorAgent.js.map +1 -1
  34. package/dist/agents/defineAgent.d.ts +2 -1
  35. package/dist/agents/defineAgent.d.ts.map +1 -1
  36. package/dist/agents/defineAgent.js +6 -1
  37. package/dist/agents/defineAgent.js.map +1 -1
  38. package/dist/agents/examples/PipelineAgent.d.ts +46 -0
  39. package/dist/agents/examples/PipelineAgent.d.ts.map +1 -0
  40. package/dist/agents/examples/PipelineAgent.js +242 -0
  41. package/dist/agents/examples/PipelineAgent.js.map +1 -0
  42. package/dist/agents/examples/RouterAgent.d.ts +22 -0
  43. package/dist/agents/examples/RouterAgent.d.ts.map +1 -0
  44. package/dist/agents/examples/RouterAgent.js +268 -0
  45. package/dist/agents/examples/RouterAgent.js.map +1 -0
  46. package/dist/agents/examples/SupervisorAgent.d.ts +45 -0
  47. package/dist/agents/examples/SupervisorAgent.d.ts.map +1 -0
  48. package/dist/agents/examples/SupervisorAgent.js +406 -0
  49. package/dist/agents/examples/SupervisorAgent.js.map +1 -0
  50. package/dist/agents/explore.d.ts +6 -3
  51. package/dist/agents/explore.d.ts.map +1 -1
  52. package/dist/agents/explore.js +6 -3
  53. package/dist/agents/explore.js.map +1 -1
  54. package/dist/agents/forward-options.d.ts +11 -0
  55. package/dist/agents/forward-options.d.ts.map +1 -0
  56. package/dist/agents/forward-options.js +15 -0
  57. package/dist/agents/forward-options.js.map +1 -0
  58. package/dist/agents/index.d.ts +1 -0
  59. package/dist/agents/index.d.ts.map +1 -1
  60. package/dist/agents/index.js +2 -0
  61. package/dist/agents/index.js.map +1 -1
  62. package/dist/agents/runAgent.d.ts +19 -8
  63. package/dist/agents/runAgent.d.ts.map +1 -1
  64. package/dist/agents/runAgent.js +99 -29
  65. package/dist/agents/runAgent.js.map +1 -1
  66. package/dist/authorization/command-line.d.ts +2 -0
  67. package/dist/authorization/command-line.d.ts.map +1 -1
  68. package/dist/authorization/command-line.js +2 -2
  69. package/dist/authorization/command-line.js.map +1 -1
  70. package/dist/authorization/gate.d.ts +8 -0
  71. package/dist/authorization/gate.d.ts.map +1 -1
  72. package/dist/authorization/gate.js +12 -1
  73. package/dist/authorization/gate.js.map +1 -1
  74. package/dist/authorization/program.d.ts +151 -0
  75. package/dist/authorization/program.d.ts.map +1 -0
  76. package/dist/authorization/program.js +713 -0
  77. package/dist/authorization/program.js.map +1 -0
  78. package/dist/authorization/reexec-wrapper.d.ts +106 -0
  79. package/dist/authorization/reexec-wrapper.d.ts.map +1 -0
  80. package/dist/authorization/reexec-wrapper.js +532 -0
  81. package/dist/authorization/reexec-wrapper.js.map +1 -0
  82. package/dist/authorization/rules.d.ts +9 -0
  83. package/dist/authorization/rules.d.ts.map +1 -1
  84. package/dist/authorization/rules.js +8 -1
  85. package/dist/authorization/rules.js.map +1 -1
  86. package/dist/authorization/shell-lexer.d.ts +19 -4
  87. package/dist/authorization/shell-lexer.d.ts.map +1 -1
  88. package/dist/authorization/shell-lexer.js +91 -65
  89. package/dist/authorization/shell-lexer.js.map +1 -1
  90. package/dist/bridge/sse/mapper.d.ts.map +1 -1
  91. package/dist/bridge/sse/mapper.js +6 -0
  92. package/dist/bridge/sse/mapper.js.map +1 -1
  93. package/dist/capabilities/index.d.ts +54 -0
  94. package/dist/capabilities/index.d.ts.map +1 -0
  95. package/dist/capabilities/index.js +92 -0
  96. package/dist/capabilities/index.js.map +1 -0
  97. package/dist/config/registry.d.ts +2 -1
  98. package/dist/config/registry.d.ts.map +1 -1
  99. package/dist/config/registry.js +3 -2
  100. package/dist/config/registry.js.map +1 -1
  101. package/dist/connector/index.d.ts +4 -4
  102. package/dist/connector/index.d.ts.map +1 -1
  103. package/dist/connector/index.js +3 -3
  104. package/dist/connector/index.js.map +1 -1
  105. package/dist/connector/mcp/adapter.d.ts +16 -1
  106. package/dist/connector/mcp/adapter.d.ts.map +1 -1
  107. package/dist/connector/mcp/adapter.js +71 -4
  108. package/dist/connector/mcp/adapter.js.map +1 -1
  109. package/dist/connector/mcp/client.d.ts +32 -4
  110. package/dist/connector/mcp/client.d.ts.map +1 -1
  111. package/dist/connector/mcp/client.js +383 -5
  112. package/dist/connector/mcp/client.js.map +1 -1
  113. package/dist/connector/mcp/discovery.d.ts +24 -1
  114. package/dist/connector/mcp/discovery.d.ts.map +1 -1
  115. package/dist/connector/mcp/discovery.js +44 -0
  116. package/dist/connector/mcp/discovery.js.map +1 -1
  117. package/dist/connector/mcp/era.d.ts.map +1 -1
  118. package/dist/connector/mcp/era.js +7 -0
  119. package/dist/connector/mcp/era.js.map +1 -1
  120. package/dist/connector/mcp/index.d.ts +2 -0
  121. package/dist/connector/mcp/index.d.ts.map +1 -1
  122. package/dist/connector/mcp/index.js +11 -0
  123. package/dist/connector/mcp/index.js.map +1 -1
  124. package/dist/connector/mcp/mcp-toolset.d.ts +133 -0
  125. package/dist/connector/mcp/mcp-toolset.d.ts.map +1 -0
  126. package/dist/connector/mcp/mcp-toolset.js +399 -0
  127. package/dist/connector/mcp/mcp-toolset.js.map +1 -0
  128. package/dist/connector/mcp/streamable-http.d.ts +15 -0
  129. package/dist/connector/mcp/streamable-http.d.ts.map +1 -1
  130. package/dist/connector/mcp/streamable-http.js +281 -6
  131. package/dist/connector/mcp/streamable-http.js.map +1 -1
  132. package/dist/connector/tools/index.d.ts +2 -2
  133. package/dist/connector/tools/index.d.ts.map +1 -1
  134. package/dist/connector/tools/index.js +1 -1
  135. package/dist/connector/tools/index.js.map +1 -1
  136. package/dist/connector/tools/router.d.ts +15 -13
  137. package/dist/connector/tools/router.d.ts.map +1 -1
  138. package/dist/connector/tools/router.js +30 -51
  139. package/dist/connector/tools/router.js.map +1 -1
  140. package/dist/contracts/a2a.d.ts +2 -2
  141. package/dist/directory/derive-supervisor.d.ts +2 -2
  142. package/dist/directory/derive-supervisor.d.ts.map +1 -1
  143. package/dist/directory/derive-supervisor.js +6 -7
  144. package/dist/directory/derive-supervisor.js.map +1 -1
  145. package/dist/directory/derive.d.ts.map +1 -1
  146. package/dist/directory/derive.js +5 -5
  147. package/dist/directory/derive.js.map +1 -1
  148. package/dist/execution/code-runtime/types.d.ts +2 -2
  149. package/dist/execution/code-runtime/types.js +1 -1
  150. package/dist/invariants/index.d.ts +2 -1
  151. package/dist/invariants/index.d.ts.map +1 -1
  152. package/dist/invariants/index.js +3 -2
  153. package/dist/invariants/index.js.map +1 -1
  154. package/dist/manager/agent/lifecycle.d.ts +1 -0
  155. package/dist/manager/agent/lifecycle.d.ts.map +1 -1
  156. package/dist/manager/agent/lifecycle.js +146 -18
  157. package/dist/manager/agent/lifecycle.js.map +1 -1
  158. package/dist/manager/connector/environment.d.ts +6 -0
  159. package/dist/manager/connector/environment.d.ts.map +1 -1
  160. package/dist/manager/connector/environment.js +11 -4
  161. package/dist/manager/connector/environment.js.map +1 -1
  162. package/dist/manager/connector/index.d.ts +2 -2
  163. package/dist/manager/connector/index.d.ts.map +1 -1
  164. package/dist/manager/connector/index.js +2 -2
  165. package/dist/manager/connector/index.js.map +1 -1
  166. package/dist/manager/connector/tenant.d.ts +6 -0
  167. package/dist/manager/connector/tenant.d.ts.map +1 -1
  168. package/dist/manager/connector/tenant.js +11 -4
  169. package/dist/manager/connector/tenant.js.map +1 -1
  170. package/dist/manager/index.d.ts +2 -2
  171. package/dist/manager/index.d.ts.map +1 -1
  172. package/dist/manager/index.js +2 -2
  173. package/dist/manager/index.js.map +1 -1
  174. package/dist/manager/resident/initiative.d.ts +6 -6
  175. package/dist/manager/resident/learning-observation.d.ts +4 -4
  176. package/dist/manager/resident/learning.d.ts +36 -36
  177. package/dist/manager/resident/outbox.d.ts +4 -4
  178. package/dist/manager/session/attribution.d.ts +22 -0
  179. package/dist/manager/session/attribution.d.ts.map +1 -0
  180. package/dist/manager/session/attribution.js +64 -0
  181. package/dist/manager/session/attribution.js.map +1 -0
  182. package/dist/manager/session/turn-recorder.d.ts +14 -0
  183. package/dist/manager/session/turn-recorder.d.ts.map +1 -1
  184. package/dist/manager/session/turn-recorder.js +208 -55
  185. package/dist/manager/session/turn-recorder.js.map +1 -1
  186. package/dist/peers/address.d.ts +36 -0
  187. package/dist/peers/address.d.ts.map +1 -0
  188. package/dist/peers/address.js +52 -0
  189. package/dist/peers/address.js.map +1 -0
  190. package/dist/peers/client.d.ts +47 -0
  191. package/dist/peers/client.d.ts.map +1 -0
  192. package/dist/peers/client.js +132 -0
  193. package/dist/peers/client.js.map +1 -0
  194. package/dist/peers/dir.d.ts +88 -0
  195. package/dist/peers/dir.d.ts.map +1 -0
  196. package/dist/peers/dir.js +139 -0
  197. package/dist/peers/dir.js.map +1 -0
  198. package/dist/peers/endpoint.d.ts +144 -0
  199. package/dist/peers/endpoint.d.ts.map +1 -0
  200. package/dist/peers/endpoint.js +420 -0
  201. package/dist/peers/endpoint.js.map +1 -0
  202. package/dist/peers/envelope.d.ts +42 -0
  203. package/dist/peers/envelope.d.ts.map +1 -0
  204. package/dist/peers/envelope.js +110 -0
  205. package/dist/peers/envelope.js.map +1 -0
  206. package/dist/peers/index.d.ts +30 -0
  207. package/dist/peers/index.d.ts.map +1 -0
  208. package/dist/peers/index.js +22 -0
  209. package/dist/peers/index.js.map +1 -0
  210. package/dist/peers/protocol.d.ts +645 -0
  211. package/dist/peers/protocol.d.ts.map +1 -0
  212. package/dist/peers/protocol.js +151 -0
  213. package/dist/peers/protocol.js.map +1 -0
  214. package/dist/peers/record.d.ts +71 -0
  215. package/dist/peers/record.d.ts.map +1 -0
  216. package/dist/peers/record.js +45 -0
  217. package/dist/peers/record.js.map +1 -0
  218. package/dist/peers/registry.d.ts +54 -0
  219. package/dist/peers/registry.d.ts.map +1 -0
  220. package/dist/peers/registry.js +213 -0
  221. package/dist/peers/registry.js.map +1 -0
  222. package/dist/plugin/define.d.ts +24 -0
  223. package/dist/plugin/define.d.ts.map +1 -0
  224. package/dist/plugin/define.js +42 -0
  225. package/dist/plugin/define.js.map +1 -0
  226. package/dist/plugin/index.d.ts +2 -0
  227. package/dist/plugin/index.d.ts.map +1 -1
  228. package/dist/plugin/index.js +1 -0
  229. package/dist/plugin/index.js.map +1 -1
  230. package/dist/plugin/lifecycle.d.ts +27 -3
  231. package/dist/plugin/lifecycle.d.ts.map +1 -1
  232. package/dist/plugin/lifecycle.js +242 -92
  233. package/dist/plugin/lifecycle.js.map +1 -1
  234. package/dist/plugin/resolver.d.ts +2 -2
  235. package/dist/plugin/resolver.d.ts.map +1 -1
  236. package/dist/plugin/resolver.js.map +1 -1
  237. package/dist/plugin/shell-hook.d.ts.map +1 -1
  238. package/dist/plugin/shell-hook.js +17 -3
  239. package/dist/plugin/shell-hook.js.map +1 -1
  240. package/dist/probe/errors.d.ts +2 -1
  241. package/dist/probe/errors.d.ts.map +1 -1
  242. package/dist/probe/errors.js +3 -2
  243. package/dist/probe/errors.js.map +1 -1
  244. package/dist/prompt/coding-agent-doctrine.d.ts +18 -7
  245. package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
  246. package/dist/prompt/coding-agent-doctrine.js +11 -6
  247. package/dist/prompt/coding-agent-doctrine.js.map +1 -1
  248. package/dist/prompt/contributions.d.ts +4 -1
  249. package/dist/prompt/contributions.d.ts.map +1 -1
  250. package/dist/prompt/contributions.js +7 -2
  251. package/dist/prompt/contributions.js.map +1 -1
  252. package/dist/prompt/index.d.ts +1 -1
  253. package/dist/prompt/index.d.ts.map +1 -1
  254. package/dist/prompt/index.js +1 -1
  255. package/dist/prompt/index.js.map +1 -1
  256. package/dist/provider/collect-chat-completion.d.ts +6 -1
  257. package/dist/provider/collect-chat-completion.d.ts.map +1 -1
  258. package/dist/provider/collect-chat-completion.js +88 -10
  259. package/dist/provider/collect-chat-completion.js.map +1 -1
  260. package/dist/provider/mock.d.ts.map +1 -1
  261. package/dist/provider/mock.js +23 -6
  262. package/dist/provider/mock.js.map +1 -1
  263. package/dist/provider/registry.d.ts +2 -1
  264. package/dist/provider/registry.d.ts.map +1 -1
  265. package/dist/provider/registry.js +3 -2
  266. package/dist/provider/registry.js.map +1 -1
  267. package/dist/provider/tool-call-framing.d.ts +164 -0
  268. package/dist/provider/tool-call-framing.d.ts.map +1 -0
  269. package/dist/provider/tool-call-framing.js +163 -0
  270. package/dist/provider/tool-call-framing.js.map +1 -0
  271. package/dist/public-runtime.d.ts +24 -11
  272. package/dist/public-runtime.d.ts.map +1 -1
  273. package/dist/public-runtime.js +45 -9
  274. package/dist/public-runtime.js.map +1 -1
  275. package/dist/public-tools.d.ts +6 -4
  276. package/dist/public-tools.d.ts.map +1 -1
  277. package/dist/public-tools.js +8 -3
  278. package/dist/public-tools.js.map +1 -1
  279. package/dist/public-types.d.ts +13 -2
  280. package/dist/public-types.d.ts.map +1 -1
  281. package/dist/read-model/registry.d.ts +2 -1
  282. package/dist/read-model/registry.d.ts.map +1 -1
  283. package/dist/read-model/registry.js +3 -2
  284. package/dist/read-model/registry.js.map +1 -1
  285. package/dist/registry/ManagedRegistry.d.ts +30 -0
  286. package/dist/registry/ManagedRegistry.d.ts.map +1 -1
  287. package/dist/registry/ManagedRegistry.js +45 -6
  288. package/dist/registry/ManagedRegistry.js.map +1 -1
  289. package/dist/registry/collision.d.ts +57 -0
  290. package/dist/registry/collision.d.ts.map +1 -0
  291. package/dist/registry/collision.js +41 -0
  292. package/dist/registry/collision.js.map +1 -0
  293. package/dist/registry/command/index.d.ts +5 -3
  294. package/dist/registry/command/index.d.ts.map +1 -1
  295. package/dist/registry/command/index.js +6 -4
  296. package/dist/registry/command/index.js.map +1 -1
  297. package/dist/registry/index.d.ts +3 -4
  298. package/dist/registry/index.d.ts.map +1 -1
  299. package/dist/registry/index.js +2 -2
  300. package/dist/registry/index.js.map +1 -1
  301. package/dist/registry/plugin/index.d.ts.map +1 -1
  302. package/dist/registry/plugin/index.js +14 -1
  303. package/dist/registry/plugin/index.js.map +1 -1
  304. package/dist/registry/tool/callable.d.ts +7 -7
  305. package/dist/registry/tool/callable.d.ts.map +1 -1
  306. package/dist/registry/tool/callable.js +6 -7
  307. package/dist/registry/tool/callable.js.map +1 -1
  308. package/dist/registry/tool/execute.d.ts +14 -77
  309. package/dist/registry/tool/execute.d.ts.map +1 -1
  310. package/dist/registry/tool/execute.js +15 -727
  311. package/dist/registry/tool/execute.js.map +1 -1
  312. package/dist/registry/tool/portable.d.ts +25 -0
  313. package/dist/registry/tool/portable.d.ts.map +1 -1
  314. package/dist/registry/tool/portable.js +50 -0
  315. package/dist/registry/tool/portable.js.map +1 -1
  316. package/dist/registry/tool/presentation.d.ts +6 -5
  317. package/dist/registry/tool/presentation.d.ts.map +1 -1
  318. package/dist/registry/tool/presentation.js +3 -3
  319. package/dist/registry/tool/presentation.js.map +1 -1
  320. package/dist/runtime/bidi/session.d.ts +5 -4
  321. package/dist/runtime/bidi/session.d.ts.map +1 -1
  322. package/dist/runtime/bidi/session.js +18 -1
  323. package/dist/runtime/bidi/session.js.map +1 -1
  324. package/dist/runtime/query/executor/tool-call-admission.d.ts +45 -2
  325. package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
  326. package/dist/runtime/query/executor/tool-call-admission.js +189 -5
  327. package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
  328. package/dist/runtime/query/executor.d.ts +33 -3
  329. package/dist/runtime/query/executor.d.ts.map +1 -1
  330. package/dist/runtime/query/executor.js +86 -10
  331. package/dist/runtime/query/executor.js.map +1 -1
  332. package/dist/runtime/query/file-evidence-replay.d.ts +1 -1
  333. package/dist/runtime/query/file-evidence-replay.d.ts.map +1 -1
  334. package/dist/runtime/query/file-evidence-replay.js +8 -7
  335. package/dist/runtime/query/file-evidence-replay.js.map +1 -1
  336. package/dist/runtime/query/fork/prepare.d.ts +4 -1
  337. package/dist/runtime/query/fork/prepare.d.ts.map +1 -1
  338. package/dist/runtime/query/fork/prepare.js +4 -0
  339. package/dist/runtime/query/fork/prepare.js.map +1 -1
  340. package/dist/runtime/query/guardrail-presets.d.ts +4 -3
  341. package/dist/runtime/query/guardrail-presets.d.ts.map +1 -1
  342. package/dist/runtime/query/guardrail-presets.js +4 -3
  343. package/dist/runtime/query/guardrail-presets.js.map +1 -1
  344. package/dist/runtime/query/index.d.ts +23 -10
  345. package/dist/runtime/query/index.d.ts.map +1 -1
  346. package/dist/runtime/query/index.js +149 -70
  347. package/dist/runtime/query/index.js.map +1 -1
  348. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  349. package/dist/runtime/query/iteration/index.js +8 -1
  350. package/dist/runtime/query/iteration/index.js.map +1 -1
  351. package/dist/runtime/query/iteration/phases/compaction.js +1 -1
  352. package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
  353. package/dist/runtime/query/iteration/phases/context.d.ts +2 -2
  354. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  355. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  356. package/dist/runtime/query/iteration/phases/tool-review.js +55 -2
  357. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  358. package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
  359. package/dist/runtime/query/iteration/stream-turn.js +342 -116
  360. package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
  361. package/dist/runtime/query/iteration/tool-input.d.ts +79 -0
  362. package/dist/runtime/query/iteration/tool-input.d.ts.map +1 -0
  363. package/dist/runtime/query/iteration/tool-input.js +291 -0
  364. package/dist/runtime/query/iteration/tool-input.js.map +1 -0
  365. package/dist/runtime/query/observation-context.d.ts +2 -2
  366. package/dist/runtime/query/observation-context.d.ts.map +1 -1
  367. package/dist/runtime/query/observation-context.js.map +1 -1
  368. package/dist/runtime/query/prelude-lease.d.ts +18 -0
  369. package/dist/runtime/query/prelude-lease.d.ts.map +1 -0
  370. package/dist/runtime/query/prelude-lease.js +121 -0
  371. package/dist/runtime/query/prelude-lease.js.map +1 -0
  372. package/dist/runtime/query/prepare-turn.d.ts.map +1 -1
  373. package/dist/runtime/query/prepare-turn.js +386 -187
  374. package/dist/runtime/query/prepare-turn.js.map +1 -1
  375. package/dist/runtime/query/prompt-cache.d.ts +2 -2
  376. package/dist/runtime/query/prompt-cache.d.ts.map +1 -1
  377. package/dist/runtime/query/prompt.d.ts +2 -2
  378. package/dist/runtime/query/prompt.d.ts.map +1 -1
  379. package/dist/runtime/query/prompt.js +1 -1
  380. package/dist/runtime/query/prompt.js.map +1 -1
  381. package/dist/runtime/query/resume-session.d.ts.map +1 -1
  382. package/dist/runtime/query/resume-session.js +37 -2
  383. package/dist/runtime/query/resume-session.js.map +1 -1
  384. package/dist/runtime/query/review-policy.d.ts +22 -3
  385. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  386. package/dist/runtime/query/review-policy.js +84 -6
  387. package/dist/runtime/query/review-policy.js.map +1 -1
  388. package/dist/runtime/query/tooling.d.ts +3 -2
  389. package/dist/runtime/query/tooling.d.ts.map +1 -1
  390. package/dist/runtime/query/tooling.js.map +1 -1
  391. package/dist/runtime/query/turn-state.d.ts.map +1 -1
  392. package/dist/runtime/query/turn-state.js +5 -0
  393. package/dist/runtime/query/turn-state.js.map +1 -1
  394. package/dist/runtime/system-events.d.ts +112 -0
  395. package/dist/runtime/system-events.d.ts.map +1 -0
  396. package/dist/runtime/system-events.js +183 -0
  397. package/dist/runtime/system-events.js.map +1 -0
  398. package/dist/scheduler/delegating.d.ts +2 -1
  399. package/dist/scheduler/delegating.d.ts.map +1 -1
  400. package/dist/scheduler/delegating.js +3 -2
  401. package/dist/scheduler/delegating.js.map +1 -1
  402. package/dist/scheduler/local.d.ts.map +1 -1
  403. package/dist/scheduler/local.js +2 -0
  404. package/dist/scheduler/local.js.map +1 -1
  405. package/dist/session/retention/archive.js +1 -1
  406. package/dist/session/retention/archive.js.map +1 -1
  407. package/dist/skills/index.d.ts +1 -1
  408. package/dist/skills/index.d.ts.map +1 -1
  409. package/dist/skills/index.js +1 -1
  410. package/dist/skills/index.js.map +1 -1
  411. package/dist/skills/registry.d.ts +12 -0
  412. package/dist/skills/registry.d.ts.map +1 -1
  413. package/dist/skills/registry.js +19 -0
  414. package/dist/skills/registry.js.map +1 -1
  415. package/dist/store/evidence/index-page.d.ts +2 -2
  416. package/dist/store/session/disk.d.ts.map +1 -1
  417. package/dist/store/session/disk.js +2 -0
  418. package/dist/store/session/disk.js.map +1 -1
  419. package/dist/store/session-log/conformance.d.ts +1 -1
  420. package/dist/store/session-log/conformance.d.ts.map +1 -1
  421. package/dist/store/session-log/conformance.js +49 -8
  422. package/dist/store/session-log/conformance.js.map +1 -1
  423. package/dist/store/session-log/core.d.ts +8 -3
  424. package/dist/store/session-log/core.d.ts.map +1 -1
  425. package/dist/store/session-log/core.js +2 -1
  426. package/dist/store/session-log/core.js.map +1 -1
  427. package/dist/store/session-log/fold.d.ts +12 -0
  428. package/dist/store/session-log/fold.d.ts.map +1 -1
  429. package/dist/store/session-log/fold.js +57 -7
  430. package/dist/store/session-log/fold.js.map +1 -1
  431. package/dist/store/session-log/index.d.ts +2 -2
  432. package/dist/store/session-log/index.d.ts.map +1 -1
  433. package/dist/store/session-log/index.js +1 -1
  434. package/dist/store/session-log/index.js.map +1 -1
  435. package/dist/test-support/toolset.d.ts +19 -0
  436. package/dist/test-support/toolset.d.ts.map +1 -0
  437. package/dist/test-support/toolset.js +20 -0
  438. package/dist/test-support/toolset.js.map +1 -0
  439. package/dist/tools/builtins/bash.d.ts +29 -0
  440. package/dist/tools/builtins/bash.d.ts.map +1 -1
  441. package/dist/tools/builtins/bash.js +19 -9
  442. package/dist/tools/builtins/bash.js.map +1 -1
  443. package/dist/tools/builtins/browser-url.d.ts +1 -1
  444. package/dist/tools/builtins/browser-url.js +1 -1
  445. package/dist/tools/builtins/browser.d.ts +6 -6
  446. package/dist/tools/builtins/browser.js +2 -2
  447. package/dist/tools/builtins/browser.js.map +1 -1
  448. package/dist/tools/builtins/computer-use.d.ts.map +1 -1
  449. package/dist/tools/builtins/computer-use.js +19 -11
  450. package/dist/tools/builtins/computer-use.js.map +1 -1
  451. package/dist/tools/builtins/edit.d.ts.map +1 -1
  452. package/dist/tools/builtins/edit.js +9 -1
  453. package/dist/tools/builtins/edit.js.map +1 -1
  454. package/dist/tools/builtins/json-string-hint.d.ts +15 -0
  455. package/dist/tools/builtins/json-string-hint.d.ts.map +1 -0
  456. package/dist/tools/builtins/json-string-hint.js +17 -0
  457. package/dist/tools/builtins/json-string-hint.js.map +1 -0
  458. package/dist/tools/builtins/search-tools.d.ts.map +1 -1
  459. package/dist/tools/builtins/search-tools.js +7 -15
  460. package/dist/tools/builtins/search-tools.js.map +1 -1
  461. package/dist/tools/builtins/write-file.d.ts.map +1 -1
  462. package/dist/tools/builtins/write-file.js +11 -0
  463. package/dist/tools/builtins/write-file.js.map +1 -1
  464. package/dist/tools/command-shell.d.ts +10 -0
  465. package/dist/tools/command-shell.d.ts.map +1 -1
  466. package/dist/tools/command-shell.js +45 -1
  467. package/dist/tools/command-shell.js.map +1 -1
  468. package/dist/tools/coordinator/agent.d.ts.map +1 -1
  469. package/dist/tools/coordinator/agent.js +5 -0
  470. package/dist/tools/coordinator/agent.js.map +1 -1
  471. package/dist/tools/coordinator/ask-user-question.d.ts.map +1 -1
  472. package/dist/tools/coordinator/ask-user-question.js +26 -13
  473. package/dist/tools/coordinator/ask-user-question.js.map +1 -1
  474. package/dist/tools/coordinator/index.d.ts.map +1 -1
  475. package/dist/tools/coordinator/index.js +5 -0
  476. package/dist/tools/coordinator/index.js.map +1 -1
  477. package/dist/tools/coordinator/question-options.d.ts +78 -0
  478. package/dist/tools/coordinator/question-options.d.ts.map +1 -0
  479. package/dist/tools/coordinator/question-options.js +153 -0
  480. package/dist/tools/coordinator/question-options.js.map +1 -0
  481. package/dist/tools/defineTool.d.ts +10 -0
  482. package/dist/tools/defineTool.d.ts.map +1 -1
  483. package/dist/tools/defineTool.js +17 -0
  484. package/dist/tools/defineTool.js.map +1 -1
  485. package/dist/tools/memory/search.d.ts.map +1 -1
  486. package/dist/tools/memory/search.js +4 -1
  487. package/dist/tools/memory/search.js.map +1 -1
  488. package/dist/tools/memory/update.d.ts.map +1 -1
  489. package/dist/tools/memory/update.js +8 -5
  490. package/dist/tools/memory/update.js.map +1 -1
  491. package/dist/tools/render-nonce.d.ts +47 -0
  492. package/dist/tools/render-nonce.d.ts.map +1 -0
  493. package/dist/tools/render-nonce.js +63 -0
  494. package/dist/tools/render-nonce.js.map +1 -0
  495. package/dist/tools/roster.d.ts +46 -19
  496. package/dist/tools/roster.d.ts.map +1 -1
  497. package/dist/tools/roster.js +63 -33
  498. package/dist/tools/roster.js.map +1 -1
  499. package/dist/tools/schedules/schedule-tool.d.ts.map +1 -1
  500. package/dist/tools/schedules/schedule-tool.js +94 -14
  501. package/dist/tools/schedules/schedule-tool.js.map +1 -1
  502. package/dist/tools/schedules/types.d.ts +52 -6
  503. package/dist/tools/schedules/types.d.ts.map +1 -1
  504. package/dist/tools/trusted-read-only.d.ts +9 -5
  505. package/dist/tools/trusted-read-only.d.ts.map +1 -1
  506. package/dist/tools/trusted-read-only.js +14 -10
  507. package/dist/tools/trusted-read-only.js.map +1 -1
  508. package/dist/tools/untrusted-envelope.d.ts +67 -28
  509. package/dist/tools/untrusted-envelope.d.ts.map +1 -1
  510. package/dist/tools/untrusted-envelope.js +108 -59
  511. package/dist/tools/untrusted-envelope.js.map +1 -1
  512. package/dist/toolsets/combine.d.ts +44 -0
  513. package/dist/toolsets/combine.d.ts.map +1 -0
  514. package/dist/toolsets/combine.js +153 -0
  515. package/dist/toolsets/combine.js.map +1 -0
  516. package/dist/toolsets/manager.d.ts +201 -0
  517. package/dist/toolsets/manager.d.ts.map +1 -0
  518. package/dist/toolsets/manager.js +837 -0
  519. package/dist/toolsets/manager.js.map +1 -0
  520. package/dist/toolsets/source-glob.d.ts +15 -0
  521. package/dist/toolsets/source-glob.d.ts.map +1 -0
  522. package/dist/toolsets/source-glob.js +23 -0
  523. package/dist/toolsets/source-glob.js.map +1 -0
  524. package/dist/toolsets/toolset.d.ts +20 -0
  525. package/dist/toolsets/toolset.d.ts.map +1 -0
  526. package/dist/toolsets/toolset.js +28 -0
  527. package/dist/toolsets/toolset.js.map +1 -0
  528. package/dist/toolsets/types.d.ts +128 -0
  529. package/dist/toolsets/types.d.ts.map +1 -0
  530. package/dist/toolsets/types.js +33 -0
  531. package/dist/toolsets/types.js.map +1 -0
  532. package/dist/toolsets/wrappers.d.ts +59 -0
  533. package/dist/toolsets/wrappers.d.ts.map +1 -0
  534. package/dist/toolsets/wrappers.js +165 -0
  535. package/dist/toolsets/wrappers.js.map +1 -0
  536. package/dist/types/agent/base.d.ts +27 -16
  537. package/dist/types/agent/base.d.ts.map +1 -1
  538. package/dist/types/agent/index.d.ts +1 -0
  539. package/dist/types/agent/index.d.ts.map +1 -1
  540. package/dist/types/agent/index.js +1 -0
  541. package/dist/types/agent/index.js.map +1 -1
  542. package/dist/types/agent/pipeline.d.ts +2 -0
  543. package/dist/types/agent/pipeline.d.ts.map +1 -1
  544. package/dist/types/agent/query.d.ts +117 -0
  545. package/dist/types/agent/query.d.ts.map +1 -0
  546. package/dist/types/agent/query.js +2 -0
  547. package/dist/types/agent/query.js.map +1 -0
  548. package/dist/types/agent/reactive.d.ts +2 -129
  549. package/dist/types/agent/reactive.d.ts.map +1 -1
  550. package/dist/types/agent/router.d.ts +2 -0
  551. package/dist/types/agent/router.d.ts.map +1 -1
  552. package/dist/types/agent/scheduler.d.ts +6 -1
  553. package/dist/types/agent/scheduler.d.ts.map +1 -1
  554. package/dist/types/agent/supervisor.d.ts +5 -2
  555. package/dist/types/agent/supervisor.d.ts.map +1 -1
  556. package/dist/types/agent/task.d.ts +19 -1
  557. package/dist/types/agent/task.d.ts.map +1 -1
  558. package/dist/types/agent/task.js.map +1 -1
  559. package/dist/types/authorization/index.d.ts +49 -12
  560. package/dist/types/authorization/index.d.ts.map +1 -1
  561. package/dist/types/authorization/index.js +6 -0
  562. package/dist/types/authorization/index.js.map +1 -1
  563. package/dist/types/connector/mcp.d.ts +45 -0
  564. package/dist/types/connector/mcp.d.ts.map +1 -1
  565. package/dist/types/errors/index.d.ts +15 -0
  566. package/dist/types/errors/index.d.ts.map +1 -1
  567. package/dist/types/errors/index.js.map +1 -1
  568. package/dist/types/hitl/index.d.ts +57 -0
  569. package/dist/types/hitl/index.d.ts.map +1 -1
  570. package/dist/types/hitl/index.js.map +1 -1
  571. package/dist/types/message/index.d.ts +130 -9
  572. package/dist/types/message/index.d.ts.map +1 -1
  573. package/dist/types/message/index.js +4 -1
  574. package/dist/types/message/index.js.map +1 -1
  575. package/dist/types/plugin/index.d.ts +22 -4
  576. package/dist/types/plugin/index.d.ts.map +1 -1
  577. package/dist/types/plugin/index.js +1 -0
  578. package/dist/types/plugin/index.js.map +1 -1
  579. package/dist/types/provider/chat.d.ts +5 -0
  580. package/dist/types/provider/chat.d.ts.map +1 -1
  581. package/dist/types/provider/config.d.ts +8 -3
  582. package/dist/types/provider/config.d.ts.map +1 -1
  583. package/dist/types/provider/stream.d.ts +39 -0
  584. package/dist/types/provider/stream.d.ts.map +1 -1
  585. package/dist/types/sandbox/index.d.ts +1 -1
  586. package/dist/types/session/events.d.ts +14 -3
  587. package/dist/types/session/events.d.ts.map +1 -1
  588. package/dist/types/session/events.js.map +1 -1
  589. package/dist/types/session/sub-session.d.ts +2 -0
  590. package/dist/types/session/sub-session.d.ts.map +1 -1
  591. package/dist/types/tool/index.d.ts +152 -91
  592. package/dist/types/tool/index.d.ts.map +1 -1
  593. package/dist/types/tool/index.js.map +1 -1
  594. package/dist/types/toolset/index.d.ts +10 -40
  595. package/dist/types/toolset/index.d.ts.map +1 -1
  596. package/package.json +1 -1
  597. package/src/advisory/history.ts +27 -2
  598. package/src/advisory/index.ts +1 -1
  599. package/src/advisory/registry.ts +33 -0
  600. package/src/agents/AGENTS.md +14 -7
  601. package/src/agents/PipelineAgent.ts +2 -303
  602. package/src/agents/QueryAgent.ts +269 -0
  603. package/src/agents/ReactiveAgent.ts +6 -216
  604. package/src/agents/RouterAgent.ts +2 -337
  605. package/src/agents/SupervisorAgent.ts +3 -476
  606. package/src/agents/defineAgent.ts +13 -2
  607. package/src/agents/examples/PipelineAgent.ts +302 -0
  608. package/src/agents/examples/RouterAgent.ts +338 -0
  609. package/src/agents/examples/SupervisorAgent.ts +472 -0
  610. package/src/agents/explore.ts +6 -3
  611. package/src/agents/forward-options.ts +37 -0
  612. package/src/agents/index.ts +2 -0
  613. package/src/agents/runAgent.ts +144 -37
  614. package/src/authorization/command-line.ts +2 -2
  615. package/src/authorization/gate.ts +21 -1
  616. package/src/authorization/program.ts +773 -0
  617. package/src/authorization/reexec-wrapper.ts +589 -0
  618. package/src/authorization/rules.ts +18 -1
  619. package/src/authorization/shell-lexer.ts +104 -59
  620. package/src/bridge/sse/mapper.ts +6 -0
  621. package/src/capabilities/index.ts +157 -0
  622. package/src/config/registry.ts +4 -1
  623. package/src/connector/index.ts +9 -2
  624. package/src/connector/mcp/adapter.ts +73 -3
  625. package/src/connector/mcp/client.ts +425 -6
  626. package/src/connector/mcp/discovery.ts +60 -0
  627. package/src/connector/mcp/era.ts +7 -0
  628. package/src/connector/mcp/index.ts +13 -0
  629. package/src/connector/mcp/mcp-toolset.ts +515 -0
  630. package/src/connector/mcp/streamable-http.ts +302 -5
  631. package/src/connector/tools/index.ts +2 -2
  632. package/src/connector/tools/router.ts +35 -58
  633. package/src/directory/derive-supervisor.ts +12 -8
  634. package/src/directory/derive.ts +8 -5
  635. package/src/execution/code-runtime/types.ts +2 -2
  636. package/src/invariants/index.ts +4 -1
  637. package/src/manager/agent/lifecycle.ts +167 -19
  638. package/src/manager/connector/environment.ts +17 -4
  639. package/src/manager/connector/index.ts +2 -2
  640. package/src/manager/connector/tenant.ts +17 -4
  641. package/src/manager/index.ts +2 -2
  642. package/src/manager/session/attribution.ts +79 -0
  643. package/src/manager/session/turn-recorder.ts +211 -55
  644. package/src/peers/address.ts +58 -0
  645. package/src/peers/client.ts +202 -0
  646. package/src/peers/dir.ts +176 -0
  647. package/src/peers/endpoint.ts +564 -0
  648. package/src/peers/envelope.ts +121 -0
  649. package/src/peers/index.ts +96 -0
  650. package/src/peers/protocol.ts +196 -0
  651. package/src/peers/record.ts +56 -0
  652. package/src/peers/registry.ts +241 -0
  653. package/src/plugin/define.ts +68 -0
  654. package/src/plugin/index.ts +2 -0
  655. package/src/plugin/lifecycle.ts +286 -106
  656. package/src/plugin/resolver.ts +6 -3
  657. package/src/plugin/shell-hook.ts +21 -5
  658. package/src/probe/errors.ts +4 -1
  659. package/src/prompt/coding-agent-doctrine.ts +22 -10
  660. package/src/prompt/contributions.ts +12 -2
  661. package/src/prompt/index.ts +1 -0
  662. package/src/provider/collect-chat-completion.ts +96 -11
  663. package/src/provider/mock.ts +24 -6
  664. package/src/provider/registry.ts +4 -1
  665. package/src/provider/tool-call-framing.ts +226 -0
  666. package/src/public-runtime.ts +136 -7
  667. package/src/public-tools.ts +24 -4
  668. package/src/public-types.ts +60 -6
  669. package/src/read-model/registry.ts +7 -2
  670. package/src/registry/ManagedRegistry.ts +57 -6
  671. package/src/registry/collision.ts +64 -0
  672. package/src/registry/command/index.ts +7 -3
  673. package/src/registry/index.ts +3 -9
  674. package/src/registry/plugin/index.ts +14 -1
  675. package/src/registry/tool/callable.ts +8 -9
  676. package/src/registry/tool/execute.ts +16 -846
  677. package/src/registry/tool/portable.ts +59 -0
  678. package/src/registry/tool/presentation.ts +6 -5
  679. package/src/runtime/bidi/session.ts +24 -5
  680. package/src/runtime/query/executor/tool-call-admission.ts +228 -6
  681. package/src/runtime/query/executor.ts +110 -12
  682. package/src/runtime/query/file-evidence-replay.ts +8 -7
  683. package/src/runtime/query/fork/prepare.ts +6 -1
  684. package/src/runtime/query/guardrail-presets.ts +4 -3
  685. package/src/runtime/query/index.ts +199 -101
  686. package/src/runtime/query/iteration/index.ts +13 -3
  687. package/src/runtime/query/iteration/phases/compaction.ts +1 -1
  688. package/src/runtime/query/iteration/phases/context.ts +2 -2
  689. package/src/runtime/query/iteration/phases/tool-review.ts +59 -2
  690. package/src/runtime/query/iteration/stream-turn.ts +390 -136
  691. package/src/runtime/query/iteration/tool-input.ts +284 -0
  692. package/src/runtime/query/observation-context.ts +2 -2
  693. package/src/runtime/query/prelude-lease.ts +132 -0
  694. package/src/runtime/query/prepare-turn.ts +477 -198
  695. package/src/runtime/query/prompt-cache.ts +2 -2
  696. package/src/runtime/query/prompt.ts +4 -4
  697. package/src/runtime/query/resume-session.ts +42 -3
  698. package/src/runtime/query/review-policy.ts +87 -9
  699. package/src/runtime/query/tooling.ts +3 -6
  700. package/src/runtime/query/turn-state.ts +4 -0
  701. package/src/runtime/system-events.ts +246 -0
  702. package/src/scheduler/delegating.ts +7 -2
  703. package/src/scheduler/local.ts +2 -0
  704. package/src/session/retention/archive.ts +1 -1
  705. package/src/skills/index.ts +1 -1
  706. package/src/skills/registry.ts +25 -0
  707. package/src/store/session/disk.ts +3 -0
  708. package/src/store/session-log/conformance.ts +51 -8
  709. package/src/store/session-log/core.ts +10 -4
  710. package/src/store/session-log/fold.ts +33 -7
  711. package/src/store/session-log/index.ts +2 -0
  712. package/src/test-support/toolset.ts +23 -0
  713. package/src/tools/builtins/bash.ts +27 -10
  714. package/src/tools/builtins/browser-url.ts +1 -1
  715. package/src/tools/builtins/browser.ts +2 -2
  716. package/src/tools/builtins/computer-use.ts +21 -11
  717. package/src/tools/builtins/edit.ts +12 -2
  718. package/src/tools/builtins/json-string-hint.ts +16 -0
  719. package/src/tools/builtins/search-tools.ts +7 -20
  720. package/src/tools/builtins/write-file.ts +12 -0
  721. package/src/tools/command-shell.ts +46 -1
  722. package/src/tools/coordinator/agent.ts +6 -0
  723. package/src/tools/coordinator/ask-user-question.ts +29 -15
  724. package/src/tools/coordinator/index.ts +6 -0
  725. package/src/tools/coordinator/question-options.ts +195 -0
  726. package/src/tools/defineTool.ts +28 -0
  727. package/src/tools/memory/search.ts +4 -1
  728. package/src/tools/memory/update.ts +8 -5
  729. package/src/tools/render-nonce.ts +69 -0
  730. package/src/tools/roster.ts +84 -33
  731. package/src/tools/schedules/schedule-tool.ts +107 -14
  732. package/src/tools/schedules/types.ts +52 -6
  733. package/src/tools/trusted-read-only.ts +19 -10
  734. package/src/tools/untrusted-envelope.ts +121 -57
  735. package/src/toolsets/combine.ts +181 -0
  736. package/src/toolsets/manager.ts +996 -0
  737. package/src/toolsets/source-glob.ts +22 -0
  738. package/src/toolsets/toolset.ts +31 -0
  739. package/src/toolsets/types.ts +154 -0
  740. package/src/toolsets/wrappers.ts +191 -0
  741. package/src/types/agent/base.ts +29 -16
  742. package/src/types/agent/index.ts +1 -0
  743. package/src/types/agent/pipeline.ts +2 -0
  744. package/src/types/agent/query.ts +129 -0
  745. package/src/types/agent/reactive.ts +5 -142
  746. package/src/types/agent/router.ts +2 -0
  747. package/src/types/agent/scheduler.ts +6 -1
  748. package/src/types/agent/supervisor.ts +5 -2
  749. package/src/types/agent/task.ts +21 -1
  750. package/src/types/authorization/index.ts +12 -0
  751. package/src/types/connector/mcp.ts +46 -0
  752. package/src/types/errors/index.ts +15 -0
  753. package/src/types/hitl/index.ts +57 -0
  754. package/src/types/message/index.ts +135 -7
  755. package/src/types/plugin/index.ts +44 -21
  756. package/src/types/provider/chat.ts +5 -0
  757. package/src/types/provider/config.ts +8 -3
  758. package/src/types/provider/stream.ts +39 -0
  759. package/src/types/sandbox/index.ts +1 -1
  760. package/src/types/session/events.ts +14 -3
  761. package/src/types/session/sub-session.ts +2 -0
  762. package/src/types/tool/index.ts +154 -105
  763. package/src/types/toolset/index.ts +10 -47
  764. package/dist/registry/toolset/catalog.d.ts +0 -42
  765. package/dist/registry/toolset/catalog.d.ts.map +0 -1
  766. package/dist/registry/toolset/catalog.js +0 -234
  767. package/dist/registry/toolset/catalog.js.map +0 -1
  768. package/src/registry/toolset/catalog.ts +0 -308
@@ -0,0 +1,996 @@
1
+ import { SpanStatusCode, context as otelContext, trace } from '@opentelemetry/api'
2
+ import { isCompactionMessage } from '../compaction/summary.js'
3
+ import { assertStrictSchema } from '../provider/strict-schema.js'
4
+ import { callableToolNames, formatToolNames } from '../registry/tool/callable.js'
5
+ import { assertToolName, describeWithOutput, toolDiscoveryHint } from '../registry/tool/execute.js'
6
+ import { renderToolSchema, toolWireSchema } from '../registry/tool/schema.js'
7
+ import { ToolResultHalted, screenToolResult } from '../registry/tool/screen.js'
8
+ import { GENAI, NAMZU, toolSpanName } from '../telemetry/attributes.js'
9
+ import { recordToolCall } from '../telemetry/metrics.js'
10
+ import { getTracer } from '../telemetry/runtime-accessors.js'
11
+ import { isTrustedReadOnly } from '../tools/trusted-read-only.js'
12
+ import type { ToolResultGuardrailSpec } from '../types/guardrail/index.js'
13
+ import type { Message, ToolRevealReceipt } from '../types/message/index.js'
14
+ import { PLAN_MODE_REFUSAL } from '../types/permission/index.js'
15
+ import type {
16
+ LLMToolSchema,
17
+ PreparedToolExecution,
18
+ ToolAvailability,
19
+ ToolContext,
20
+ ToolDefinition,
21
+ ToolExecutionResult,
22
+ ToolPreparationResult,
23
+ ToolProvenance,
24
+ ToolTierConfig,
25
+ ToolsView,
26
+ } from '../types/tool/index.js'
27
+ import { toErrorMessage } from '../utils/error.js'
28
+ import { cloneJsonValue as clonePreparedInput } from '../utils/json-snapshot.js'
29
+ import { SCOPE_ATTRIBUTE } from '../utils/log/types.js'
30
+ import { type Logger, resolveLogger } from '../utils/logger.js'
31
+ import { ToolsetConflictError } from './combine.js'
32
+ import type { ToolSourceRef, Toolset, ToolsetAvailability } from './types.js'
33
+ import { toToolSourceRef, toolsetIsReady } from './types.js'
34
+
35
+ export type { ToolExecutionResult }
36
+
37
+ /**
38
+ * What `refresh()` reports after re-resolving a live toolset's change.
39
+ *
40
+ * `refused` is a newly-contributed name that would have collided with a name
41
+ * already served by another toolset — the incumbent keeps serving and the
42
+ * newcomer never reaches the manager, unlike a construction-time collision,
43
+ * which throws instead (nothing was serving anyone yet, so there is nothing
44
+ * to protect by continuing).
45
+ */
46
+ export interface ToolsetChangeReport {
47
+ /** Names a toolset started contributing that nobody else already served. */
48
+ readonly added: readonly string[]
49
+ /** Names whose owning toolset stopped contributing them, with no other toolset picking them up. */
50
+ readonly removed: readonly string[]
51
+ /**
52
+ * Names whose OWNING toolset now returns a different `ToolDefinition`
53
+ * object under the same name. The previously admitted definition keeps
54
+ * serving — see the class doc on why identity, not content, is what
55
+ * `toLLMTools`'s prompt-cache stability depends on.
56
+ */
57
+ readonly drifted: readonly string[]
58
+ /** A new contributor for a name some other toolset already serves. Refused, not applied. */
59
+ readonly refused: readonly {
60
+ readonly name: string
61
+ readonly reason: string
62
+ }[]
63
+ }
64
+
65
+ export interface ToolManagerConfig {
66
+ readonly toolsets: readonly Toolset[]
67
+ /**
68
+ * Screens run against every tool result before anything downstream reads
69
+ * it. Wins over whatever the turn's own `ToolContext.toolResultGuardrails`
70
+ * supplies when this is present — including `[]`, which means none —
71
+ * because a manager built with an explicit policy has stated it. See
72
+ * `executeRetained` below.
73
+ */
74
+ readonly resultGuardrails?: readonly ToolResultGuardrailSpec[]
75
+ readonly tierConfig?: ToolTierConfig
76
+ /**
77
+ * The turn's own message history, read fresh on every `availability`
78
+ * call rather than captured once — see {@link ToolManager.availability}.
79
+ */
80
+ readonly messages: () => readonly Message[]
81
+ }
82
+
83
+ // Tokens too generic to identify a tool by name — ignored when matching a
84
+ // batched `search_tools` query so they can't activate the whole catalog.
85
+ // Copied from `registry/tool/execute.ts`'s `ToolRegistry.searchByAvailability`
86
+ // (same weights, same stop list); consolidate once that class is removed.
87
+ const SEARCH_STOP_TOKENS = new Set([
88
+ 'clawtool',
89
+ 'tool',
90
+ 'tools',
91
+ 'mcp',
92
+ 'the',
93
+ 'and',
94
+ 'for',
95
+ 'use',
96
+ 'list',
97
+ 'read',
98
+ 'create',
99
+ 'update',
100
+ 'get',
101
+ 'find',
102
+ 'delete',
103
+ 'search',
104
+ ])
105
+
106
+ const SEARCH_WEIGHT_NAME_EXACT = 12
107
+ const SEARCH_WEIGHT_NAME_PARTIAL = 8
108
+ const SEARCH_WEIGHT_DESCRIPTION = 5
109
+ const SEARCH_WEIGHT_ARGUMENT = 3
110
+
111
+ /**
112
+ * The runtime-owned resolver of {@link Toolset}s.
113
+ *
114
+ * It is built once from a fixed list of toolsets and never mutates its own
115
+ * membership: a toolset changing live (`onChange`) is only adopted when the caller calls
116
+ * {@link refresh}, at an iteration boundary the caller chooses — never
117
+ * mid-call. This is what keeps `toLLMTools`'s wire rendering byte-stable
118
+ * between refreshes: `toolWireSchema` (`registry/tool/schema.ts`) memoizes a
119
+ * tool's rendered schema by the object identity of `ToolDefinition.inputSchema`,
120
+ * not by anything owned by whichever object resolved the tool, so returning
121
+ * the SAME `ToolDefinition` object for the same name across calls — which a
122
+ * fixed, never-mutated resolution trivially does — is what keeps the cache
123
+ * hit.
124
+ *
125
+ * Availability has no stored, mutable map (unlike `ToolRegistry.availability`).
126
+ * It is DERIVED: an unready source is suspended; otherwise a tool is
127
+ * deferred iff its owner declared `deferred()` and no source-bound receipt
128
+ * in the turn's post-compaction history has loaded its schema. See
129
+ * {@link ToolManager.availability}.
130
+ *
131
+ * The execution pipeline below (`prepareExecution`/`executePrepared`/
132
+ * `execute`/`executeRetained`) is copied from `ToolRegistry`'s, per plan.md
133
+ * §2: "Diff it line by line; the only permitted changes are where it read
134
+ * `this.availability`, `tool.provenance` or registry identity." Those three
135
+ * substitutions are exactly: `this.availability(name)` (derived, above) for
136
+ * `this.getAvailability(name)`; `this.sourceOf(name)` for `tool.provenance`;
137
+ * and `this.toolsByName` for `this.items`. Every check, in the same order,
138
+ * with the same messages, is unchanged.
139
+ */
140
+ export class ToolManager {
141
+ private readonly toolsets: readonly Toolset[]
142
+ private readonly resultGuardrails?: readonly ToolResultGuardrailSpec[]
143
+ private readonly tierConfig?: ToolTierConfig
144
+ private readonly messagesAccessor: () => readonly Message[]
145
+ private readonly log: Logger
146
+
147
+ private toolsByName = new Map<string, ToolDefinition>()
148
+ private ownerToolsetByName = new Map<string, Toolset>()
149
+ private defaultAvailabilityByName = new Map<string, ToolsetAvailability>()
150
+ /**
151
+ * The object each name's owning toolset returned the LAST time `refresh()`
152
+ * (or construction) observed it — distinct from `toolsByName`, which holds
153
+ * whatever was first admitted under that name and never changes on drift.
154
+ * `refresh()` diffs against this map, not `toolsByName`, so a name that
155
+ * drifted once and has been stable ever since is not reported as drifted
156
+ * again just because some unrelated toolset's change forced a re-walk.
157
+ */
158
+ private lastObservedByName = new Map<string, ToolDefinition>()
159
+ private dirty = false
160
+ private readonly unsubscribeToolsetChanges: (() => void)[] = []
161
+ private disposed = false
162
+
163
+ private readonly preparations = new WeakMap<
164
+ PreparedToolExecution,
165
+ { readonly tool: ToolDefinition; readonly input: unknown }
166
+ >()
167
+
168
+ constructor(config: ToolManagerConfig) {
169
+ this.toolsets = config.toolsets
170
+ this.resultGuardrails = config.resultGuardrails
171
+ this.tierConfig = config.tierConfig
172
+ this.messagesAccessor = config.messages
173
+ this.log = resolveLogger(undefined).child({
174
+ [SCOPE_ATTRIBUTE]: 'registry',
175
+ [NAMZU.REGISTRY_NAME]: 'ToolManager',
176
+ })
177
+
178
+ this.resolveInitial()
179
+
180
+ try {
181
+ for (const toolset of this.toolsets) {
182
+ const unsubscribe = toolset.onChange?.(() => {
183
+ if (!this.disposed) this.dirty = true
184
+ })
185
+ if (unsubscribe) this.unsubscribeToolsetChanges.push(unsubscribe)
186
+ }
187
+ } catch (error) {
188
+ // A later subscription can fail after earlier live toolsets subscribed.
189
+ this.dispose()
190
+ throw error
191
+ }
192
+ }
193
+
194
+ /** Stop observing live toolsets when this manager's owner finishes; the host owns their connections. */
195
+ dispose(): void {
196
+ if (this.disposed) return
197
+ this.disposed = true
198
+ for (const unsubscribe of this.unsubscribeToolsetChanges.splice(0).reverse()) {
199
+ try {
200
+ unsubscribe()
201
+ } catch (error) {
202
+ // A broken source must not prevent the other listeners (or the
203
+ // turn's recorder) from being released.
204
+ this.log.warn('Toolset change listener cleanup failed', {
205
+ 'exception.message': toErrorMessage(error),
206
+ })
207
+ }
208
+ }
209
+ }
210
+
211
+ // ---- Composition / membership ----------------------------------------
212
+
213
+ /**
214
+ * First resolution, at construction. Toolset order, then tool order,
215
+ * matching `combineToolsets` (`./combine.ts`) — a name contributed by two
216
+ * sources throws {@link ToolsetConflictError} naming both, because
217
+ * nothing has served anyone yet: unlike {@link refresh}, there is no
218
+ * incumbent to protect by refusing the newcomer instead.
219
+ */
220
+ /**
221
+ * The checks `ToolRegistry.registerOne` used to run before admitting a
222
+ * tool, copied verbatim: a legal name; `enforceModelInput` requires a
223
+ * `modelInputSchema` (nothing to constrain generation against
224
+ * otherwise) and that schema must itself fit the strict-decoding subset
225
+ * `assertStrictSchema` checks (existing is not enough — it also has to
226
+ * be sendable); a declared `tier` must be one `this.tierConfig` lists.
227
+ */
228
+ private assertAdmissible(tool: ToolDefinition): void {
229
+ assertToolName(tool.name)
230
+ if (tool.enforceModelInput && !tool.modelInputSchema) {
231
+ throw new Error(
232
+ `Tool "${tool.name}" enables enforceModelInput but does not define modelInputSchema. Constrained input generation requires an explicit provider-safe model schema.`,
233
+ )
234
+ }
235
+ if (tool.enforceModelInput) {
236
+ assertStrictSchema(tool.name, tool.modelInputSchema)
237
+ }
238
+ if (tool.tier && this.tierConfig) {
239
+ const validIds = this.tierConfig.tiers.map((t) => t.id)
240
+ if (!validIds.includes(tool.tier)) {
241
+ throw new Error(
242
+ `Tool "${tool.name}" has tier "${tool.tier}" which is not defined. Valid tiers: ${validIds.join(', ')}`,
243
+ )
244
+ }
245
+ }
246
+ }
247
+
248
+ private resolveInitial(): void {
249
+ const toolsByName = new Map<string, ToolDefinition>()
250
+ const ownerToolsetByName = new Map<string, Toolset>()
251
+ const defaultAvailabilityByName = new Map<string, ToolsetAvailability>()
252
+
253
+ for (const toolset of this.toolsets) {
254
+ for (const tool of toolset.tools()) {
255
+ // The same admission checks `ToolRegistry.register` used to run
256
+ // (name legality, `enforceModelInput`'s two schema
257
+ // requirements, a declared tier's existence) — moved here
258
+ // rather than dropped when that class went away. "Fail where
259
+ // it can still be attributed" (at construction) instead of at
260
+ // the first request.
261
+ this.assertAdmissible(tool)
262
+ const existingOwner = ownerToolsetByName.get(tool.name)
263
+ if (existingOwner) {
264
+ throw new ToolsetConflictError(tool.name, existingOwner.source, toolset.source)
265
+ }
266
+ toolsByName.set(tool.name, tool)
267
+ ownerToolsetByName.set(tool.name, toolset)
268
+ defaultAvailabilityByName.set(tool.name, toolset.availability ?? 'active')
269
+ }
270
+ }
271
+
272
+ this.toolsByName = toolsByName
273
+ this.ownerToolsetByName = ownerToolsetByName
274
+ this.defaultAvailabilityByName = defaultAvailabilityByName
275
+ this.lastObservedByName = new Map(toolsByName)
276
+ }
277
+
278
+ /**
279
+ * Re-resolve iff a toolset signalled change (`onChange`) since
280
+ * construction or the last `refresh()` — otherwise returns `undefined`
281
+ * without re-walking anything, so a caller that refreshes every
282
+ * iteration boundary pays nothing on the common case where nothing
283
+ * changed.
284
+ *
285
+ * Three outcomes per name, matching plan.md §2:
286
+ * - A name only ONE current toolset contributes, that nobody served
287
+ * before: `added`.
288
+ * - A name a toolset served before and stopped, with no other toolset
289
+ * now contributing it: `removed`.
290
+ * - A name still contributed by its ORIGINAL owning toolset, under a
291
+ * `ToolDefinition` object different from the one that toolset returned
292
+ * the LAST time it was observed (construction, or the previous
293
+ * `refresh()`): `drifted` — the previously admitted definition keeps
294
+ * serving; the new object is held, not adopted, so `toolWireSchema`'s
295
+ * identity-keyed cache (see the class doc) survives a live toolset's
296
+ * own internal change. Comparing against the last OBSERVATION, not
297
+ * the served object, means a name that drifted once and has been
298
+ * stable since is reported only on the refresh where it actually
299
+ * changed, not again on every later refresh some unrelated toolset's
300
+ * change happens to trigger.
301
+ * - A name some OTHER toolset starts contributing while its incumbent
302
+ * owner still serves it: `refused` — the incumbent wins regardless of
303
+ * toolset order; the newcomer is reported, never applied.
304
+ */
305
+ refresh(): ToolsetChangeReport | undefined {
306
+ if (!this.dirty) return undefined
307
+ this.dirty = false
308
+
309
+ const current = this.toolsets.map((toolset) => ({
310
+ toolset,
311
+ tools: toolset.tools(),
312
+ }))
313
+ const nextToolsByName = new Map<string, ToolDefinition>()
314
+ const nextOwnerByName = new Map<string, Toolset>()
315
+ const nextDefaultAvailabilityByName = new Map<string, ToolsetAvailability>()
316
+ const nextLastObservedByName = new Map<string, ToolDefinition>()
317
+ const added: string[] = []
318
+ const drifted: string[] = []
319
+ const refused: { name: string; reason: string }[] = []
320
+
321
+ // Pass 1: every incumbent whose OWN owning toolset still offers it
322
+ // keeps its slot — held at its OLD object identity even if the fresh
323
+ // one differs (drift), so a live toolset's own change never bumps an
324
+ // unrelated newcomer ahead of it, and never busts the wire-schema
325
+ // identity cache mid-turn. Drift is judged against the last fresh
326
+ // observation, not the held object, and that observation is updated
327
+ // unconditionally so a name that just drifted is not drifted again
328
+ // next time nothing about it has changed.
329
+ for (const [name, ownerToolset] of this.ownerToolsetByName) {
330
+ const ownerEntry = current.find((entry) => entry.toolset === ownerToolset)
331
+ const freshTool = ownerEntry?.tools.find((tool) => tool.name === name)
332
+ if (!freshTool) continue // handled as `removed` below, unless re-added by pass 2
333
+ const oldTool = this.toolsByName.get(name)
334
+ const lastObserved = this.lastObservedByName.get(name)
335
+ if (lastObserved && freshTool !== lastObserved) drifted.push(name)
336
+ nextToolsByName.set(name, oldTool ?? freshTool)
337
+ nextOwnerByName.set(name, ownerToolset)
338
+ nextDefaultAvailabilityByName.set(name, ownerToolset.availability ?? 'active')
339
+ nextLastObservedByName.set(name, freshTool)
340
+ }
341
+
342
+ // Pass 2: walk every toolset, in order, for names no incumbent
343
+ // claimed above. First writer among the CURRENTLY offered names wins;
344
+ // anything already claimed here was necessarily claimed by pass 1
345
+ // (an incumbent), so this can only ever refuse a newcomer, never an
346
+ // incumbent.
347
+ for (const { toolset, tools } of current) {
348
+ for (const tool of tools) {
349
+ const claimedBy = nextOwnerByName.get(tool.name)
350
+ if (claimedBy) {
351
+ if (claimedBy !== toolset) {
352
+ refused.push({
353
+ name: tool.name,
354
+ reason: `tool "${tool.name}" is already served by "${claimedBy.source.id}"; "${toolset.source.id}" was refused. Rename it, or wrap the newcomer with prefixed(toolset, prefix).`,
355
+ })
356
+ }
357
+ continue
358
+ }
359
+ nextToolsByName.set(tool.name, tool)
360
+ nextOwnerByName.set(tool.name, toolset)
361
+ nextDefaultAvailabilityByName.set(tool.name, toolset.availability ?? 'active')
362
+ nextLastObservedByName.set(tool.name, tool)
363
+ added.push(tool.name)
364
+ }
365
+ }
366
+
367
+ const removed = [...this.toolsByName.keys()].filter((name) => !nextToolsByName.has(name))
368
+
369
+ this.toolsByName = nextToolsByName
370
+ this.ownerToolsetByName = nextOwnerByName
371
+ this.defaultAvailabilityByName = nextDefaultAvailabilityByName
372
+ this.lastObservedByName = nextLastObservedByName
373
+
374
+ return { added, removed, drifted, refused }
375
+ }
376
+
377
+ has(name: string): boolean {
378
+ return this.toolsByName.has(name)
379
+ }
380
+
381
+ get(name: string): ToolDefinition | undefined {
382
+ return this.toolsByName.get(name)
383
+ }
384
+
385
+ listNames(): string[] {
386
+ return [...this.toolsByName.keys()]
387
+ }
388
+
389
+ /** Where `name` came from. Throws for an unknown name, like {@link getOrThrow}. */
390
+ sourceOf(name: string): ToolSourceRef {
391
+ const ownerToolset = this.ownerToolsetByName.get(name)
392
+ if (!ownerToolset) {
393
+ throw new Error(`Not found: "${name}". Available: ${this.listNames().join(', ')}`)
394
+ }
395
+ return toToolSourceRef(ownerToolset.source)
396
+ }
397
+
398
+ private getOrThrow(name: string): ToolDefinition {
399
+ const tool = this.toolsByName.get(name)
400
+ if (!tool) {
401
+ throw new Error(`Not found: "${name}". Available: ${this.listNames().join(', ')}`)
402
+ }
403
+ return tool
404
+ }
405
+
406
+ // ---- Availability (derived) -------------------------------------------
407
+
408
+ /**
409
+ * `'suspended'` when the owning toolset is unready; otherwise `'deferred'`
410
+ * when it declared deferred and no matching receipt exists in the
411
+ * post-compaction history; otherwise `'active'`.
412
+ *
413
+ * Nothing here is stored: this is a pure read of the toolset's own
414
+ * declaration plus a scan of `messages()`, recomputed on every call — the
415
+ * same "safe to call repeatedly, byte-identical between calls" property
416
+ * `toLLMTools` already has. The scan is bounded to the window AFTER the
417
+ * last compaction summary (`compaction/summary.ts`'s
418
+ * `isCompactionMessage` — the one marker a compacted history carries, a
419
+ * system message whose content starts with `COMPACTION_HEADER`):
420
+ * compaction is the one deliberate "forget" boundary a derivation like
421
+ * this one needs, the same way it is the one boundary namzu's own
422
+ * summarisation treats as a reset. A tool message's own `revealedTools`
423
+ * (`types/message/index.ts`) is written by the executor from
424
+ * `ToolResult.reveals`, persisted like any other message field — there is
425
+ * no separate store to keep in sync, restore on resume, or lose across a
426
+ * fork.
427
+ */
428
+ availability(name: string): ToolAvailability {
429
+ const owner = this.ownerToolsetByName.get(name)
430
+ if (owner && !toolsetIsReady(owner)) return 'suspended'
431
+ const declared = this.defaultAvailabilityByName.get(name) ?? 'active'
432
+ if (declared === 'active') return 'active'
433
+ return this.wasRevealed(name) ? 'active' : 'deferred'
434
+ }
435
+
436
+ private wasRevealed(name: string): boolean {
437
+ const owner = this.ownerToolsetByName.get(name)
438
+ if (!owner) return false
439
+ const window = postCompactionWindow(this.messagesAccessor())
440
+ for (const message of window) {
441
+ if (
442
+ message.role === 'tool' &&
443
+ !message.isError &&
444
+ message.revealedTools?.some(
445
+ (receipt) =>
446
+ receipt.name === name &&
447
+ receipt.sourceId === owner.source.id &&
448
+ receipt.sourceKind === owner.source.kind,
449
+ )
450
+ )
451
+ return true
452
+ }
453
+ return false
454
+ }
455
+
456
+ /** Bind a reveal to the source currently serving the named tool. */
457
+ revealReceipt(name: string): ToolRevealReceipt {
458
+ const source = this.sourceOf(name)
459
+ return { name, sourceId: source.id, sourceKind: source.kind }
460
+ }
461
+
462
+ private getByAvailability(
463
+ states: readonly ToolAvailability[],
464
+ filter?: readonly string[],
465
+ ): ToolDefinition[] {
466
+ const candidates = filter
467
+ ? filter.map((name) => this.getOrThrow(name))
468
+ : [...this.toolsByName.values()]
469
+ return candidates.filter((tool) => states.includes(this.availability(tool.name)))
470
+ }
471
+
472
+ // ---- Discovery ----------------------------------------------------------
473
+
474
+ /**
475
+ * Ranked lexical search over deferred tools — same scoring
476
+ * `ToolRegistry.searchDeferred` used (exact name 12 / name-substring 8 /
477
+ * description 5 / argument-name 3, generic tokens stopped), extended
478
+ * with an optional cap so a caller does not have to slice the result
479
+ * itself.
480
+ */
481
+ searchDeferred(query: string, limit?: number): readonly ToolDefinition[] {
482
+ const results = this.searchByAvailability(query, 'deferred')
483
+ return limit === undefined ? results : results.slice(0, limit)
484
+ }
485
+
486
+ private searchByAvailability(query: string, state: ToolsetAvailability): ToolDefinition[] {
487
+ const q = query.toLowerCase().trim()
488
+ if (q.length === 0) return []
489
+ const terms = q.split(/\s+/).filter((tok) => tok.length >= 3 && !SEARCH_STOP_TOKENS.has(tok))
490
+
491
+ const scored: Array<{ tool: ToolDefinition; score: number }> = []
492
+ for (const tool of this.toolsByName.values()) {
493
+ if (this.availability(tool.name) !== state) continue
494
+ const name = tool.name.toLowerCase()
495
+ const description = tool.description.toLowerCase()
496
+ const argumentNames = listArgumentNames(tool)
497
+ let score = terms.length === 0 && name === q ? SEARCH_WEIGHT_NAME_EXACT : 0
498
+ for (const term of terms) {
499
+ if (name === term) {
500
+ score += SEARCH_WEIGHT_NAME_EXACT
501
+ } else if (name.includes(term)) {
502
+ score += SEARCH_WEIGHT_NAME_PARTIAL
503
+ }
504
+ if (description.includes(term)) {
505
+ score += SEARCH_WEIGHT_DESCRIPTION
506
+ }
507
+ if (argumentNames.some((arg) => arg.includes(term))) {
508
+ score += SEARCH_WEIGHT_ARGUMENT
509
+ }
510
+ }
511
+ if (score > 0) scored.push({ tool, score })
512
+ }
513
+
514
+ scored.sort((a, b) => b.score - a.score || a.tool.name.localeCompare(b.tool.name))
515
+ return scored.map((entry) => entry.tool)
516
+ }
517
+
518
+ // ---- Rendering to the model ----------------------------------------------
519
+
520
+ toLLMTools(names?: readonly string[]): LLMToolSchema[] {
521
+ const tools = this.getByAvailability(['active'], names)
522
+ return tools.map((tool) => {
523
+ let description = tool.description
524
+ if (this.tierConfig?.labelInDescription && tool.tier) {
525
+ const tierDef = this.tierConfig.tiers.find((t) => t.id === tool.tier)
526
+ if (tierDef) description = `[${tierDef.label}] ${description}`
527
+ }
528
+ return {
529
+ type: 'function' as const,
530
+ function: {
531
+ name: tool.name,
532
+ description: describeWithOutput(description, tool.outputSchema),
533
+ parameters: toolWireSchema(tool),
534
+ },
535
+ }
536
+ })
537
+ }
538
+
539
+ toPromptSection(names?: readonly string[]): string {
540
+ const active = this.getByAvailability(['active'], names)
541
+ const deferred = this.getByAvailability(['deferred'], names)
542
+
543
+ const parts: string[] = []
544
+ const contractNote = `<tool_runtime_contract>
545
+ Executable tool names, descriptions, and JSON input schemas are attached through the runtime tools parameter. Treat that runtime schema as authoritative; this prompt section is a discoverability summary only.
546
+ </tool_runtime_contract>`
547
+
548
+ if (active.length > 0) {
549
+ const entries = active.map((t) => `- ${t.name}`).join('\n')
550
+ parts.push(`<available_tools>\n${entries}\n</available_tools>`)
551
+ }
552
+
553
+ if (deferred.length > 0) {
554
+ const entries = deferred
555
+ .map((t) => {
556
+ const hint = toolDiscoveryHint(t.description)
557
+ return hint.length > 0 ? `- ${t.name}: ${hint}` : `- ${t.name}`
558
+ })
559
+ .join('\n')
560
+ const deferredIntro =
561
+ this.has('search_tools') &&
562
+ this.availability('search_tools') === 'active' &&
563
+ (!names || names.includes('search_tools'))
564
+ ? 'Use search_tools to load these before use:'
565
+ : 'Deferred tools are discoverable but not executable until the runtime activates them:'
566
+ parts.push(`<deferred_tools>\n${deferredIntro}\n${entries}\n</deferred_tools>`)
567
+ }
568
+
569
+ if (parts.length === 0) return ''
570
+ return [contractNote, ...parts].join('\n\n')
571
+ }
572
+
573
+ toTierGuidance(): string | null {
574
+ if (!this.tierConfig?.guidanceTemplate) return null
575
+ return this.tierConfig.guidanceTemplate(this.tierConfig.tiers)
576
+ }
577
+
578
+ // ---- Narrow live view for a running tool's own `execute()` --------------
579
+
580
+ /** What `ToolContext` gives a running tool: read-only, no mutation. */
581
+ view(): ToolsView {
582
+ return {
583
+ has: (name) => this.has(name),
584
+ availability: (name) => this.availability(name),
585
+ searchDeferred: (query, limit) => this.searchDeferred(query, limit),
586
+ }
587
+ }
588
+
589
+ // ---- Execution pipeline ---------------------------------------------
590
+ //
591
+ // Copied from `ToolRegistry` (`registry/tool/execute.ts:475-791`) per
592
+ // plan.md §2. See the class doc for the three permitted substitutions;
593
+ // everything else — order of checks, messages, the WeakMap ownership and
594
+ // staleness re-check, the halt/fail distinction, the explicit parent
595
+ // span — is unchanged.
596
+
597
+ prepareExecution(toolName: string, rawInput: unknown): ToolPreparationResult {
598
+ const tool = this.getOrThrow(toolName)
599
+ const parseResult = tool.inputSchema.safeParse(rawInput)
600
+ if (!parseResult.success) {
601
+ return {
602
+ success: false,
603
+ result: this.validationFailure(tool, rawInput, parseResult.error),
604
+ }
605
+ }
606
+
607
+ let retainedInput: unknown
608
+ let reviewInput: unknown
609
+ try {
610
+ retainedInput = clonePreparedInput(parseResult.data, false)
611
+ reviewInput = clonePreparedInput(retainedInput, true)
612
+ } catch (err) {
613
+ const message = `Tool "${toolName}" produced an input that cannot be safely prepared for review and execution: ${toErrorMessage(err)}`
614
+ this.log.error('Prepared tool input could not be detached for review and execution', {
615
+ 'namzu.tool.name': toolName,
616
+ 'exception.message': toErrorMessage(err),
617
+ })
618
+ return {
619
+ success: false,
620
+ result: { success: false, output: '', error: message },
621
+ }
622
+ }
623
+
624
+ const prepared = Object.freeze({ toolName, input: reviewInput })
625
+ this.preparations.set(prepared, { tool, input: retainedInput })
626
+ return { success: true, prepared }
627
+ }
628
+
629
+ async executePrepared(
630
+ prepared: PreparedToolExecution,
631
+ context: ToolContext,
632
+ ): Promise<ToolExecutionResult> {
633
+ const retained = this.preparations.get(prepared)
634
+ if (!retained) {
635
+ return {
636
+ success: false,
637
+ output: '',
638
+ error: `Tool "${prepared.toolName}" preparation is not owned by this registry or is no longer valid.`,
639
+ }
640
+ }
641
+ if (this.toolsByName.get(prepared.toolName) !== retained.tool) {
642
+ return {
643
+ success: false,
644
+ output: '',
645
+ error: `Tool "${prepared.toolName}" changed after its input was reviewed; prepare the call again.`,
646
+ }
647
+ }
648
+ return this.executeRetained(prepared.toolName, retained.tool, retained.input, context)
649
+ }
650
+
651
+ async execute(
652
+ toolName: string,
653
+ rawInput: unknown,
654
+ context: ToolContext,
655
+ ): Promise<ToolExecutionResult> {
656
+ let preparation: ToolPreparationResult
657
+ try {
658
+ preparation = this.prepareExecution(toolName, rawInput)
659
+ } catch (err) {
660
+ return this.rejectPreparationWithClosedSpan(toolName, context, err)
661
+ }
662
+ if (!preparation.success) return preparation.result
663
+ return this.executePrepared(preparation.prepared, context)
664
+ }
665
+
666
+ private rejectPreparationWithClosedSpan(
667
+ toolName: string,
668
+ context: ToolContext,
669
+ err: unknown,
670
+ ): Promise<never> {
671
+ const tracer = getTracer()
672
+ const parentCtx = context.parentSpan
673
+ ? trace.setSpan(otelContext.active(), context.parentSpan)
674
+ : otelContext.active()
675
+ return tracer.startActiveSpan(toolSpanName(toolName), {}, parentCtx, async (span) => {
676
+ try {
677
+ span.setAttributes({
678
+ [GENAI.TOOL_NAME]: toolName,
679
+ [GENAI.TOOL_TYPE]: 'function',
680
+ ...(context.toolUseId !== undefined ? { [GENAI.TOOL_CALL_ID]: context.toolUseId } : {}),
681
+ ...toolSpanIdentity(context),
682
+ [NAMZU.TOOL_SUCCESS]: false,
683
+ [NAMZU.TOOL_ERROR]: toErrorMessage(err),
684
+ })
685
+ span.setStatus({
686
+ code: SpanStatusCode.ERROR,
687
+ message: toErrorMessage(err),
688
+ })
689
+ throw err
690
+ } finally {
691
+ span.end()
692
+ }
693
+ })
694
+ }
695
+
696
+ private async executeRetained(
697
+ toolName: string,
698
+ tool: ToolDefinition,
699
+ finalInput: unknown,
700
+ context: ToolContext,
701
+ ): Promise<ToolExecutionResult> {
702
+ const tracer = getTracer()
703
+ // The permitted `tool.provenance` substitution: a lean per-tool source
704
+ // pointer from the OWNING toolset, computed once per call, rather than
705
+ // something stamped onto the shared `ToolDefinition` object.
706
+ const source = this.sourceOf(toolName)
707
+
708
+ const parentCtx = context.parentSpan
709
+ ? trace.setSpan(otelContext.active(), context.parentSpan)
710
+ : otelContext.active()
711
+
712
+ return tracer.startActiveSpan(toolSpanName(toolName), {}, parentCtx, async (span) => {
713
+ try {
714
+ span.setAttributes({
715
+ [GENAI.TOOL_NAME]: toolName,
716
+ [GENAI.TOOL_TYPE]: 'function',
717
+ ...(context.toolUseId !== undefined ? { [GENAI.TOOL_CALL_ID]: context.toolUseId } : {}),
718
+ ...toolSpanIdentity(context),
719
+ })
720
+
721
+ // The permitted `this.getAvailability` substitution: derived,
722
+ // not read off a stored map. See `availability` above.
723
+ const availability = this.availability(toolName)
724
+ if (availability !== 'active') {
725
+ const msg = `Tool "${toolName}" is ${availability} and cannot be executed`
726
+ this.log.warn(msg)
727
+ span.setAttributes({
728
+ [NAMZU.TOOL_SUCCESS]: false,
729
+ [NAMZU.TOOL_ERROR]: msg,
730
+ })
731
+ span.setStatus({ code: SpanStatusCode.ERROR, message: msg })
732
+ return {
733
+ success: false,
734
+ output: '',
735
+ error: msg,
736
+ }
737
+ }
738
+
739
+ const allowed = context.allowedTools
740
+ if (allowed !== undefined && !allowed.includes(toolName)) {
741
+ const msg = `Tool "${toolName}" is not available on this step. Available: ${formatToolNames(callableToolNames(this, allowed))}`
742
+ this.log.warn('Blocked a tool outside the step allow-list', {
743
+ [GENAI.TOOL_NAME]: toolName,
744
+ 'namzu.registry.allowed': allowed.length,
745
+ })
746
+ span.setAttributes({
747
+ [NAMZU.TOOL_SUCCESS]: false,
748
+ [NAMZU.TOOL_ERROR]: msg,
749
+ })
750
+ span.setStatus({ code: SpanStatusCode.ERROR, message: msg })
751
+ return {
752
+ success: false,
753
+ output: '',
754
+ error: msg,
755
+ permissionDenied: true,
756
+ }
757
+ }
758
+
759
+ const mode = context.permissionContext?.mode ?? 'auto'
760
+ if (mode === 'plan') {
761
+ const isReadOnly = isTrustedReadOnly(tool, finalInput, source)
762
+ if (!isReadOnly) {
763
+ const msg = `plan mode: non-read-only tool "${toolName}" blocked. ${PLAN_MODE_REFUSAL}`
764
+ span.setAttributes({
765
+ [NAMZU.TOOL_SUCCESS]: false,
766
+ [NAMZU.TOOL_ERROR]: msg,
767
+ })
768
+ span.setStatus({ code: SpanStatusCode.ERROR, message: msg })
769
+ return {
770
+ success: false,
771
+ output: '',
772
+ error: msg,
773
+ permissionDenied: true,
774
+ permissionMessage: msg,
775
+ }
776
+ }
777
+ }
778
+
779
+ try {
780
+ this.log.debug('Executing tool', { 'namzu.tool.name': toolName })
781
+ const startedAt = Date.now()
782
+ const runResultGuardrails = context.toolResultGuardrails
783
+ const produced = await tool.execute(finalInput, context)
784
+ const provenance = sourceToProvenance(source)
785
+ const result = await screenToolResult(
786
+ this.resultGuardrails ?? runResultGuardrails,
787
+ produced,
788
+ {
789
+ toolName,
790
+ input: finalInput,
791
+ ...(provenance ? { provenance } : {}),
792
+ },
793
+ this.log,
794
+ )
795
+ const durationMs = Date.now() - startedAt
796
+ this.log.debug('Tool completed', {
797
+ 'namzu.tool.name': toolName,
798
+ 'namzu.registry.success': result.success,
799
+ })
800
+
801
+ span.setAttribute(NAMZU.TOOL_SUCCESS, result.success)
802
+ recordToolCall(
803
+ toolName,
804
+ result.success,
805
+ result.success ? undefined : result.error,
806
+ durationMs,
807
+ )
808
+ if (!result.success && result.error) {
809
+ span.setAttribute(NAMZU.TOOL_ERROR, result.error)
810
+ span.setStatus({
811
+ code: SpanStatusCode.ERROR,
812
+ message: result.error,
813
+ })
814
+ } else {
815
+ span.setStatus({ code: SpanStatusCode.OK })
816
+ }
817
+
818
+ return result
819
+ } catch (err) {
820
+ if (err instanceof ToolResultHalted) {
821
+ span.setAttributes({
822
+ [NAMZU.TOOL_SUCCESS]: false,
823
+ [NAMZU.TOOL_ERROR]: err.message,
824
+ })
825
+ span.setStatus({
826
+ code: SpanStatusCode.ERROR,
827
+ message: err.message,
828
+ })
829
+ throw err
830
+ }
831
+ const errorMessage = toErrorMessage(err)
832
+ this.log.error('Tool execution error', {
833
+ 'namzu.tool.name': toolName,
834
+ 'exception.message': errorMessage,
835
+ })
836
+
837
+ span.setAttributes({
838
+ [NAMZU.TOOL_SUCCESS]: false,
839
+ [NAMZU.TOOL_ERROR]: errorMessage,
840
+ })
841
+ span.setStatus({
842
+ code: SpanStatusCode.ERROR,
843
+ message: errorMessage,
844
+ })
845
+ span.recordException(err instanceof Error ? err : new Error(errorMessage))
846
+
847
+ return {
848
+ success: false,
849
+ output: '',
850
+ error: `Tool "${toolName}" execution failed: ${errorMessage}`,
851
+ }
852
+ }
853
+ } finally {
854
+ span.end()
855
+ }
856
+ })
857
+ }
858
+
859
+ private validationFailure(
860
+ tool: ToolDefinition,
861
+ rawInput: unknown,
862
+ error: {
863
+ readonly issues: readonly {
864
+ readonly path: readonly PropertyKey[]
865
+ readonly message: string
866
+ }[]
867
+ },
868
+ ): ToolExecutionResult {
869
+ const errorMessage = error.issues
870
+ .map((issue) => `${issue.path.join('.')}: ${issue.message}`)
871
+ .join('; ')
872
+ const isEmptyInput =
873
+ rawInput === null ||
874
+ rawInput === undefined ||
875
+ (typeof rawInput === 'object' &&
876
+ !Array.isArray(rawInput) &&
877
+ Object.keys(rawInput as Record<string, unknown>).length === 0)
878
+ const requiredHint = describeRequiredInput(tool.inputSchema)
879
+ const recoveryHint = tool.validationErrorHint?.trim()
880
+ ? ` ${tool.validationErrorHint.trim()}`
881
+ : ''
882
+ const enrichedMessage = isEmptyInput
883
+ ? `Tool "${tool.name}" was called with no arguments. ${requiredHint}${recoveryHint} Retry the call with the required parameters populated.`
884
+ : `Validation failed for "${tool.name}": ${errorMessage}. ${requiredHint}${recoveryHint}`
885
+ this.log.error('Tool input validation failed', {
886
+ 'namzu.tool.name': tool.name,
887
+ 'namzu.registry.errors': errorMessage,
888
+ 'namzu.registry.empty': isEmptyInput,
889
+ })
890
+ return { success: false, output: '', error: enrichedMessage }
891
+ }
892
+ }
893
+
894
+ /**
895
+ * The session and turn a tool span belongs to, copied from
896
+ * `registry/tool/execute.ts`'s identically named private function.
897
+ */
898
+ function toolSpanIdentity(context: ToolContext): Record<string, string> {
899
+ return {
900
+ ...(context.sessionId ? { [GENAI.CONVERSATION_ID]: context.sessionId } : {}),
901
+ ...(context.turnId ? { [NAMZU.TURN_ID]: context.turnId } : {}),
902
+ }
903
+ }
904
+
905
+ /** Project a `ToolSourceRef` to the `ToolProvenance` shape `screenToolResult` reads, for MCP-kind sources only. */
906
+ function sourceToProvenance(source: ToolSourceRef): ToolProvenance | undefined {
907
+ if (source.kind !== 'mcp_server') return undefined
908
+ return {
909
+ server: source.server ?? source.id,
910
+ readOnlyHintTrusted: source.readOnlyHintTrusted ?? false,
911
+ }
912
+ }
913
+
914
+ /**
915
+ * Every message after the last compaction summary. `isCompactionMessage`
916
+ * (`compaction/summary.ts`) is the one marker a compacted history carries: a
917
+ * system message whose content starts with `COMPACTION_HEADER`. No such
918
+ * message means nothing has been compacted yet, so the whole history is the
919
+ * window.
920
+ */
921
+ function postCompactionWindow(messages: readonly Message[]): readonly Message[] {
922
+ for (let i = messages.length - 1; i >= 0; i--) {
923
+ const message = messages[i]
924
+ if (message?.role === 'system' && isCompactionMessage(message.content)) {
925
+ return messages.slice(i + 1)
926
+ }
927
+ }
928
+ return messages
929
+ }
930
+
931
+ /**
932
+ * Lower-cased argument (property) names of a tool's input schema, copied
933
+ * from `registry/tool/execute.ts`'s identically named private function
934
+ * (used by `searchByAvailability`'s ranking).
935
+ */
936
+ function listArgumentNames(tool: ToolDefinition): string[] {
937
+ try {
938
+ const json = tool.modelInputSchema ?? renderToolSchema(tool.inputSchema)
939
+ return [...collectSchemaPropertyNames(json)].map((key) => key.toLowerCase())
940
+ } catch {
941
+ return []
942
+ }
943
+ }
944
+
945
+ /**
946
+ * Every property name a schema can accept, including ones that only appear
947
+ * inside a branch. Copied from `registry/tool/execute.ts`'s identically
948
+ * named private function.
949
+ */
950
+ function collectSchemaPropertyNames(
951
+ schema: unknown,
952
+ names: Set<string> = new Set(),
953
+ seen: Set<object> = new Set(),
954
+ ): Set<string> {
955
+ if (!schema || typeof schema !== 'object' || Array.isArray(schema)) return names
956
+ if (seen.has(schema)) return names
957
+ seen.add(schema)
958
+
959
+ const record = schema as Record<string, unknown>
960
+ const properties = record.properties
961
+ if (properties && typeof properties === 'object' && !Array.isArray(properties)) {
962
+ for (const name of Object.keys(properties)) names.add(name)
963
+ }
964
+ for (const keyword of ['anyOf', 'oneOf', 'allOf'] as const) {
965
+ const branches = record[keyword]
966
+ if (!Array.isArray(branches)) continue
967
+ for (const branch of branches) collectSchemaPropertyNames(branch, names, seen)
968
+ }
969
+ return names
970
+ }
971
+
972
+ /**
973
+ * Build a one-sentence "Required: <field>: <type>, …" validation hint.
974
+ * Copied from `registry/tool/execute.ts`'s identically named private
975
+ * function.
976
+ */
977
+ function describeRequiredInput(schema: { _def?: unknown }): string {
978
+ try {
979
+ const json = renderToolSchema(schema as never) as {
980
+ properties?: Record<string, { type?: string; description?: string }>
981
+ required?: string[]
982
+ }
983
+ const required = json.required ?? []
984
+ if (required.length === 0) return 'No required parameters known.'
985
+ const props = json.properties ?? {}
986
+ const lines = required.map((name) => {
987
+ const def = props[name] ?? {}
988
+ const type = def.type ?? 'value'
989
+ const desc = def.description ? ` — ${def.description}` : ''
990
+ return `${name}: ${type}${desc}`
991
+ })
992
+ return `Required: ${lines.join(', ')}.`
993
+ } catch {
994
+ return 'Could not introspect required parameters.'
995
+ }
996
+ }