@nhtio/adk 1.20260921.0 → 1.20260925.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 (658) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/adk-mcp.cjs +2 -2
  3. package/{arg_specs-iYmIM3wI.js → arg_specs-iYmIM3wI.cjs} +1 -1
  4. package/arg_specs-iYmIM3wI.cjs.map +1 -0
  5. package/artifact_methods-9BemAvd4.mjs +1 -0
  6. package/artifact_methods-FKgk4q_1.cjs +1 -0
  7. package/batteries/artifacts/ecmascript.cjs +2 -2
  8. package/batteries/artifacts/ecmascript.mjs +1 -1
  9. package/batteries/artifacts/toon.cjs +2 -2
  10. package/batteries/artifacts/toon.mjs +1 -1
  11. package/batteries/artifacts/xml.cjs +2 -2
  12. package/batteries/artifacts/xml.mjs +1 -1
  13. package/batteries/artifacts/yaml.cjs +2 -2
  14. package/batteries/artifacts/yaml.mjs +1 -1
  15. package/batteries/artifacts.cjs +5 -5
  16. package/batteries/artifacts.mjs +4 -4
  17. package/batteries/context/compact/contracts.cjs +1 -1
  18. package/batteries/context/compact/summarizer.cjs +1 -1
  19. package/batteries/context/compact.cjs +1 -1
  20. package/batteries/context/exceptions.cjs +2 -2
  21. package/batteries/context/thrift/contracts.cjs +1 -1
  22. package/batteries/context/thrift/relevance.cjs +1 -1
  23. package/batteries/context/thrift/subtractive_pass.cjs +1 -1
  24. package/batteries/context/thrift.cjs +1 -1
  25. package/batteries/context.cjs +1 -1
  26. package/batteries/dev-tools/conformance.cjs +2 -2
  27. package/batteries/dev-tools/forge.cjs +5 -5
  28. package/batteries/dev-tools/forge.mjs +3 -3
  29. package/batteries/dev-tools.cjs +9 -9
  30. package/batteries/dev-tools.mjs +3 -3
  31. package/batteries/embeddings/ollama/adapter.cjs +2 -2
  32. package/batteries/embeddings/ollama/exceptions.cjs +2 -2
  33. package/batteries/embeddings/ollama/types.cjs +1 -1
  34. package/batteries/embeddings/ollama/validation.cjs +1 -1
  35. package/batteries/embeddings/ollama.cjs +1 -1
  36. package/batteries/embeddings/openai/adapter.cjs +2 -2
  37. package/batteries/embeddings/openai/exceptions.cjs +2 -2
  38. package/batteries/embeddings/openai/helpers.cjs +1 -1
  39. package/batteries/embeddings/openai/types.cjs +1 -1
  40. package/batteries/embeddings/openai/validation.cjs +1 -1
  41. package/batteries/embeddings/openai.cjs +1 -1
  42. package/batteries/embeddings/transformers_js/adapter.cjs +3 -3
  43. package/batteries/embeddings/transformers_js/exceptions.cjs +2 -2
  44. package/batteries/embeddings/transformers_js/pooling.cjs +1 -1
  45. package/batteries/embeddings/transformers_js/types.cjs +1 -1
  46. package/batteries/embeddings/transformers_js/validation.cjs +2 -2
  47. package/batteries/embeddings/transformers_js.cjs +1 -1
  48. package/batteries/embeddings/webllm/adapter.cjs +2 -2
  49. package/batteries/embeddings/webllm/exceptions.cjs +2 -2
  50. package/batteries/embeddings/webllm/types.cjs +1 -1
  51. package/batteries/embeddings/webllm/validation.cjs +1 -1
  52. package/batteries/embeddings/webllm.cjs +1 -1
  53. package/batteries/embeddings.cjs +1 -1
  54. package/batteries/encoding.cjs +8 -8
  55. package/batteries/encoding.mjs +7 -7
  56. package/batteries/generation/_shared.cjs +2 -2
  57. package/batteries/generation/gemini/adapter.cjs +3 -3
  58. package/batteries/generation/gemini/adapter.mjs +1 -1
  59. package/batteries/generation/gemini/exceptions.cjs +2 -2
  60. package/batteries/generation/gemini/types.cjs +1 -1
  61. package/batteries/generation/gemini/validation.cjs +1 -1
  62. package/batteries/generation/gemini.cjs +1 -1
  63. package/batteries/generation/local_diffusion/adapter.cjs +5 -5
  64. package/batteries/generation/local_diffusion/adapter.mjs +2 -2
  65. package/batteries/generation/local_diffusion/exceptions.cjs +2 -2
  66. package/batteries/generation/local_diffusion/protocol.cjs +2 -2
  67. package/batteries/generation/local_diffusion/types.cjs +1 -1
  68. package/batteries/generation/local_diffusion/validation.cjs +1 -1
  69. package/batteries/generation/local_diffusion.cjs +1 -1
  70. package/batteries/generation/openai/adapter.cjs +3 -3
  71. package/batteries/generation/openai/adapter.mjs +1 -1
  72. package/batteries/generation/openai/exceptions.cjs +2 -2
  73. package/batteries/generation/openai/types.cjs +1 -1
  74. package/batteries/generation/openai/validation.cjs +1 -1
  75. package/batteries/generation/openai.cjs +1 -1
  76. package/batteries/generation/transformers_js/adapter.cjs +3 -3
  77. package/batteries/generation/transformers_js/exceptions.cjs +2 -2
  78. package/batteries/generation/transformers_js/helpers.cjs +1 -1
  79. package/batteries/generation/transformers_js/types.cjs +1 -1
  80. package/batteries/generation/transformers_js/validation.cjs +2 -2
  81. package/batteries/generation/transformers_js.cjs +1 -1
  82. package/batteries/generation.cjs +1 -1
  83. package/batteries/isolation/child_process.cjs +3 -3
  84. package/batteries/isolation/child_process.mjs +1 -1
  85. package/batteries/isolation.cjs +2 -2
  86. package/batteries/isolation.mjs +1 -1
  87. package/batteries/llm/anthropic_messages/adapter.cjs +10 -10
  88. package/batteries/llm/anthropic_messages/adapter.mjs +6 -6
  89. package/batteries/llm/anthropic_messages/count_tokens.cjs +4 -4
  90. package/batteries/llm/anthropic_messages/count_tokens.mjs +1 -1
  91. package/batteries/llm/anthropic_messages/error_translation.cjs +2 -2
  92. package/batteries/llm/anthropic_messages/exceptions.cjs +2 -2
  93. package/batteries/llm/anthropic_messages/helpers.cjs +4 -4
  94. package/batteries/llm/anthropic_messages/helpers.mjs +3 -3
  95. package/batteries/llm/anthropic_messages/types.cjs +1 -1
  96. package/batteries/llm/anthropic_messages/validation.cjs +3 -3
  97. package/batteries/llm/anthropic_messages/validation.mjs +2 -2
  98. package/batteries/llm/anthropic_messages.cjs +4 -4
  99. package/batteries/llm/anthropic_messages.mjs +2 -2
  100. package/batteries/llm/bedrock_converse/adapter.cjs +165 -24
  101. package/batteries/llm/bedrock_converse/adapter.cjs.map +1 -1
  102. package/batteries/llm/bedrock_converse/adapter.mjs +162 -21
  103. package/batteries/llm/bedrock_converse/adapter.mjs.map +1 -1
  104. package/batteries/llm/bedrock_converse/exceptions.cjs +2 -2
  105. package/batteries/llm/bedrock_converse/helpers.cjs +3 -3
  106. package/batteries/llm/bedrock_converse/helpers.mjs +1 -1
  107. package/batteries/llm/bedrock_converse/types.cjs +1 -1
  108. package/batteries/llm/bedrock_converse/validation.cjs +3 -3
  109. package/batteries/llm/bedrock_converse/validation.mjs +2 -2
  110. package/batteries/llm/bedrock_converse.cjs +3 -3
  111. package/batteries/llm/bedrock_converse.mjs +2 -2
  112. package/batteries/llm/chat_common/exceptions.cjs +2 -2
  113. package/batteries/llm/claude_code_cli/adapter.cjs +349 -49
  114. package/batteries/llm/claude_code_cli/adapter.cjs.map +1 -1
  115. package/batteries/llm/claude_code_cli/adapter.d.ts +125 -0
  116. package/batteries/llm/claude_code_cli/adapter.mjs +347 -49
  117. package/batteries/llm/claude_code_cli/adapter.mjs.map +1 -1
  118. package/batteries/llm/claude_code_cli/exceptions.cjs +13 -2
  119. package/batteries/llm/claude_code_cli/exceptions.cjs.map +1 -1
  120. package/batteries/llm/claude_code_cli/exceptions.d.ts +12 -0
  121. package/batteries/llm/claude_code_cli/exceptions.mjs +11 -1
  122. package/batteries/llm/claude_code_cli/exceptions.mjs.map +1 -1
  123. package/batteries/llm/claude_code_cli/helpers.cjs +4 -4
  124. package/batteries/llm/claude_code_cli/helpers.mjs +3 -3
  125. package/batteries/llm/claude_code_cli/index.d.ts +3 -2
  126. package/batteries/llm/claude_code_cli/line_queue.d.ts +39 -0
  127. package/batteries/llm/claude_code_cli/message_id_state.d.ts +48 -0
  128. package/batteries/llm/claude_code_cli/types.cjs +1 -1
  129. package/batteries/llm/claude_code_cli/types.d.ts +112 -2
  130. package/batteries/llm/claude_code_cli/validation.cjs +7 -3
  131. package/batteries/llm/claude_code_cli/validation.cjs.map +1 -1
  132. package/batteries/llm/claude_code_cli/validation.mjs +6 -2
  133. package/batteries/llm/claude_code_cli/validation.mjs.map +1 -1
  134. package/batteries/llm/claude_code_cli/wire.cjs +1 -1
  135. package/batteries/llm/claude_code_cli/wire.cjs.map +1 -1
  136. package/batteries/llm/claude_code_cli/wire.d.ts +45 -1
  137. package/batteries/llm/claude_code_cli/wire.mjs.map +1 -1
  138. package/batteries/llm/claude_code_cli/wrapper.d.ts +5 -4
  139. package/batteries/llm/claude_code_cli.cjs +5 -2
  140. package/batteries/llm/claude_code_cli.mjs +4 -3
  141. package/batteries/llm/gemini_generate_content/adapter.cjs +163 -22
  142. package/batteries/llm/gemini_generate_content/adapter.cjs.map +1 -1
  143. package/batteries/llm/gemini_generate_content/adapter.mjs +160 -19
  144. package/batteries/llm/gemini_generate_content/adapter.mjs.map +1 -1
  145. package/batteries/llm/gemini_generate_content/exceptions.cjs +2 -2
  146. package/batteries/llm/gemini_generate_content/helpers.cjs +3 -3
  147. package/batteries/llm/gemini_generate_content/helpers.mjs +1 -1
  148. package/batteries/llm/gemini_generate_content/types.cjs +1 -1
  149. package/batteries/llm/gemini_generate_content/validation.cjs +3 -3
  150. package/batteries/llm/gemini_generate_content/validation.mjs +2 -2
  151. package/batteries/llm/gemini_generate_content.cjs +2 -2
  152. package/batteries/llm/gemini_generate_content.mjs +1 -1
  153. package/batteries/llm/index.d.ts +1 -1
  154. package/batteries/llm/litert_lm/adapter.cjs +11 -11
  155. package/batteries/llm/litert_lm/adapter.mjs +6 -6
  156. package/batteries/llm/litert_lm/exceptions.cjs +2 -2
  157. package/batteries/llm/litert_lm/helpers.cjs +7 -7
  158. package/batteries/llm/litert_lm/helpers.mjs +3 -3
  159. package/batteries/llm/litert_lm/types.cjs +1 -1
  160. package/batteries/llm/litert_lm/validation.cjs +4 -4
  161. package/batteries/llm/litert_lm/validation.mjs +2 -2
  162. package/batteries/llm/litert_lm.cjs +5 -5
  163. package/batteries/llm/litert_lm.mjs +1 -1
  164. package/batteries/llm/ollama/adapter.cjs +9 -9
  165. package/batteries/llm/ollama/adapter.mjs +6 -6
  166. package/batteries/llm/ollama/exceptions.cjs +2 -2
  167. package/batteries/llm/ollama/helpers.cjs +5 -5
  168. package/batteries/llm/ollama/helpers.mjs +4 -4
  169. package/batteries/llm/ollama/types.cjs +1 -1
  170. package/batteries/llm/ollama/validation.cjs +3 -3
  171. package/batteries/llm/ollama/validation.mjs +2 -2
  172. package/batteries/llm/ollama.cjs +3 -3
  173. package/batteries/llm/ollama.mjs +2 -2
  174. package/batteries/llm/openai_chat_completions/adapter.cjs +9 -9
  175. package/batteries/llm/openai_chat_completions/adapter.mjs +6 -6
  176. package/batteries/llm/openai_chat_completions/exceptions.cjs +2 -2
  177. package/batteries/llm/openai_chat_completions/helpers.cjs +5 -5
  178. package/batteries/llm/openai_chat_completions/helpers.mjs +4 -4
  179. package/batteries/llm/openai_chat_completions/types.cjs +1 -1
  180. package/batteries/llm/openai_chat_completions/validation.cjs +3 -3
  181. package/batteries/llm/openai_chat_completions/validation.mjs +2 -2
  182. package/batteries/llm/openai_chat_completions.cjs +3 -3
  183. package/batteries/llm/openai_chat_completions.mjs +2 -2
  184. package/batteries/llm/openai_responses/adapter.cjs +9 -9
  185. package/batteries/llm/openai_responses/adapter.mjs +6 -6
  186. package/batteries/llm/openai_responses/exceptions.cjs +2 -2
  187. package/batteries/llm/openai_responses/helpers.cjs +4 -4
  188. package/batteries/llm/openai_responses/helpers.mjs +3 -3
  189. package/batteries/llm/openai_responses/types.cjs +1 -1
  190. package/batteries/llm/openai_responses/validation.cjs +3 -3
  191. package/batteries/llm/openai_responses/validation.mjs +2 -2
  192. package/batteries/llm/openai_responses.cjs +3 -3
  193. package/batteries/llm/openai_responses.mjs +2 -2
  194. package/batteries/llm/transformers_js/adapter.cjs +11 -11
  195. package/batteries/llm/transformers_js/adapter.mjs +6 -6
  196. package/batteries/llm/transformers_js/exceptions.cjs +2 -2
  197. package/batteries/llm/transformers_js/helpers.cjs +8 -8
  198. package/batteries/llm/transformers_js/helpers.mjs +3 -3
  199. package/batteries/llm/transformers_js/model_source.cjs +2 -2
  200. package/batteries/llm/transformers_js/types.cjs +1 -1
  201. package/batteries/llm/transformers_js/validation.cjs +4 -4
  202. package/batteries/llm/transformers_js/validation.mjs +2 -2
  203. package/batteries/llm/transformers_js.cjs +5 -5
  204. package/batteries/llm/transformers_js.mjs +1 -1
  205. package/batteries/llm/webllm_chat_completions/adapter.cjs +10 -10
  206. package/batteries/llm/webllm_chat_completions/adapter.mjs +6 -6
  207. package/batteries/llm/webllm_chat_completions/exceptions.cjs +2 -2
  208. package/batteries/llm/webllm_chat_completions/helpers.cjs +2 -2
  209. package/batteries/llm/webllm_chat_completions/helpers.mjs +1 -1
  210. package/batteries/llm/webllm_chat_completions/validation.cjs +3 -3
  211. package/batteries/llm/webllm_chat_completions/validation.mjs +2 -2
  212. package/batteries/llm/webllm_chat_completions.cjs +3 -3
  213. package/batteries/llm/webllm_chat_completions.mjs +2 -2
  214. package/batteries/llm.cjs +4 -3
  215. package/batteries/llm.mjs +4 -4
  216. package/batteries/media/contracts.cjs +2 -2
  217. package/batteries/media/engines/audio_decode.cjs +3 -3
  218. package/batteries/media/engines/data.cjs +4 -4
  219. package/batteries/media/engines/exceljs.cjs +4 -4
  220. package/batteries/media/engines/execa_executor.cjs +3 -3
  221. package/batteries/media/engines/fs_workspace.cjs +3 -3
  222. package/batteries/media/engines/jimp.cjs +3 -3
  223. package/batteries/media/engines/sharp.cjs +3 -3
  224. package/batteries/media/engines/sheetjs.cjs +6 -6
  225. package/batteries/media/engines/sheetjs.cjs.map +1 -1
  226. package/batteries/media/engines/soffice.cjs +2 -2
  227. package/batteries/media/engines/tesseract_js.cjs +3 -3
  228. package/batteries/media/engines/transformers_asr.cjs +3 -3
  229. package/batteries/media/forge.cjs +8 -8
  230. package/batteries/media/forge.mjs +4 -4
  231. package/batteries/media/lint.cjs +2 -2
  232. package/batteries/media/lint.mjs +1 -1
  233. package/batteries/media.cjs +6 -6
  234. package/batteries/orchestration/approval.cjs +2 -2
  235. package/batteries/orchestration/cells/jexl.cjs +3 -3
  236. package/batteries/orchestration/cells/jexl.mjs +1 -1
  237. package/batteries/orchestration/cells/lua.cjs +3 -3
  238. package/batteries/orchestration/cells/lua.mjs +1 -1
  239. package/batteries/orchestration/cells/structured.cjs +3 -3
  240. package/batteries/orchestration/cells/structured.mjs +1 -1
  241. package/batteries/orchestration/conformance.cjs +2 -2
  242. package/batteries/orchestration/dispatch_reasoner.cjs +6 -6
  243. package/batteries/orchestration/dispatch_reasoner.mjs +4 -4
  244. package/batteries/orchestration/encoding.cjs +2 -2
  245. package/batteries/orchestration/executor.cjs +4 -4
  246. package/batteries/orchestration/executor.mjs +2 -2
  247. package/batteries/orchestration/forge.cjs +5 -5
  248. package/batteries/orchestration/forge.mjs +3 -3
  249. package/batteries/orchestration/in_memory.cjs +1 -1
  250. package/batteries/orchestration/ops.cjs +1 -1
  251. package/batteries/orchestration/outline.cjs +2 -2
  252. package/batteries/orchestration/plan.cjs +1 -1
  253. package/batteries/orchestration/raw.cjs +2 -2
  254. package/batteries/orchestration/reason.cjs +1 -1
  255. package/batteries/orchestration/render.cjs +2 -2
  256. package/batteries/orchestration/runs.cjs +1 -1
  257. package/batteries/orchestration/templates.cjs +2 -2
  258. package/batteries/orchestration/types.cjs +1 -1
  259. package/batteries/orchestration/validation.cjs +5 -5
  260. package/batteries/orchestration/validation.mjs +2 -2
  261. package/batteries/orchestration.cjs +6 -6
  262. package/batteries/orchestration.mjs +4 -4
  263. package/batteries/sandbox/js.cjs +6 -6
  264. package/batteries/sandbox/js.mjs +1 -1
  265. package/batteries/sandbox/node.cjs +4 -4
  266. package/batteries/sandbox/tools.cjs +2 -2
  267. package/batteries/sandbox/tools.mjs +1 -1
  268. package/batteries/sandbox.cjs +11 -11
  269. package/batteries/sandbox.mjs +4 -4
  270. package/batteries/skills/conformance.cjs +1 -1
  271. package/batteries/skills/in_memory.cjs +2 -2
  272. package/batteries/skills/in_memory.mjs +1 -1
  273. package/batteries/skills.cjs +13 -13
  274. package/batteries/skills.mjs +9 -9
  275. package/batteries/specialists/_shared.cjs +2 -2
  276. package/batteries/specialists/caption/transformers_js/adapter.cjs +3 -3
  277. package/batteries/specialists/caption/transformers_js/exceptions.cjs +2 -2
  278. package/batteries/specialists/caption/transformers_js/types.cjs +1 -1
  279. package/batteries/specialists/caption/transformers_js/validation.cjs +2 -2
  280. package/batteries/specialists/caption/transformers_js.cjs +1 -1
  281. package/batteries/specialists/caption.cjs +1 -1
  282. package/batteries/specialists/ocr/tesseract_js/adapter.cjs +3 -3
  283. package/batteries/specialists/ocr/tesseract_js/exceptions.cjs +2 -2
  284. package/batteries/specialists/ocr/tesseract_js/types.cjs +1 -1
  285. package/batteries/specialists/ocr/tesseract_js/validation.cjs +2 -2
  286. package/batteries/specialists/ocr/tesseract_js.cjs +1 -1
  287. package/batteries/specialists/ocr.cjs +1 -1
  288. package/batteries/specialists/stt/transformers_js.cjs +2 -2
  289. package/batteries/specialists/stt/transformers_js.mjs +1 -1
  290. package/batteries/specialists/stt.cjs +2 -2
  291. package/batteries/specialists/stt.mjs +1 -1
  292. package/batteries/specialists.cjs +2 -2
  293. package/batteries/specialists.mjs +1 -1
  294. package/batteries/storage/flydrive.cjs +2 -2
  295. package/batteries/storage/in_memory.cjs +2 -2
  296. package/batteries/storage/opfs.cjs +2 -2
  297. package/batteries/storage.cjs +1 -1
  298. package/batteries/tools/_shared.cjs +4 -4
  299. package/batteries/tools/_shared.mjs +2 -2
  300. package/batteries/tools/color.cjs +3 -3
  301. package/batteries/tools/color.mjs +2 -2
  302. package/batteries/tools/comparison.cjs +4 -4
  303. package/batteries/tools/comparison.mjs +2 -2
  304. package/batteries/tools/data_structure.cjs +4 -4
  305. package/batteries/tools/data_structure.mjs +2 -2
  306. package/batteries/tools/datetime_extended.cjs +3 -3
  307. package/batteries/tools/datetime_extended.mjs +2 -2
  308. package/batteries/tools/datetime_math.cjs +3 -3
  309. package/batteries/tools/datetime_math.mjs +2 -2
  310. package/batteries/tools/encoding.cjs +4 -4
  311. package/batteries/tools/encoding.mjs +2 -2
  312. package/batteries/tools/formatting.cjs +4 -4
  313. package/batteries/tools/formatting.mjs +2 -2
  314. package/batteries/tools/geo_basics.cjs +3 -3
  315. package/batteries/tools/geo_basics.mjs +2 -2
  316. package/batteries/tools/math.cjs +4 -4
  317. package/batteries/tools/math.mjs +2 -2
  318. package/batteries/tools/memory.cjs +6 -6
  319. package/batteries/tools/memory.mjs +4 -4
  320. package/batteries/tools/parsing.cjs +5 -5
  321. package/batteries/tools/parsing.mjs +3 -3
  322. package/batteries/tools/retrievables.cjs +6 -6
  323. package/batteries/tools/retrievables.mjs +4 -4
  324. package/batteries/tools/scrapper.cjs +2 -2
  325. package/batteries/tools/scrapper.mjs +1 -1
  326. package/batteries/tools/searxng.cjs +2 -2
  327. package/batteries/tools/searxng.mjs +1 -1
  328. package/batteries/tools/standing_instructions.cjs +5 -5
  329. package/batteries/tools/standing_instructions.mjs +3 -3
  330. package/batteries/tools/statistics.cjs +5 -5
  331. package/batteries/tools/statistics.mjs +3 -3
  332. package/batteries/tools/string_processing.cjs +4 -4
  333. package/batteries/tools/string_processing.mjs +2 -2
  334. package/batteries/tools/structured_data.cjs +4 -4
  335. package/batteries/tools/structured_data.mjs +2 -2
  336. package/batteries/tools/text_analysis.cjs +4 -4
  337. package/batteries/tools/text_analysis.mjs +3 -3
  338. package/batteries/tools/text_comparison.cjs +3 -3
  339. package/batteries/tools/text_comparison.mjs +2 -2
  340. package/batteries/tools/time.cjs +3 -3
  341. package/batteries/tools/time.mjs +2 -2
  342. package/batteries/tools/unit_conversion.cjs +3 -3
  343. package/batteries/tools/unit_conversion.mjs +2 -2
  344. package/batteries/tools/web_retrieval.cjs +2 -2
  345. package/batteries/tools.cjs +3 -3
  346. package/batteries/tools.mjs +2 -2
  347. package/batteries/tts/_shared.cjs +1 -1
  348. package/batteries/tts/native/adapter.cjs +2 -2
  349. package/batteries/tts/native/exceptions.cjs +2 -2
  350. package/batteries/tts/native/helpers.cjs +1 -1
  351. package/batteries/tts/native/types.cjs +1 -1
  352. package/batteries/tts/native/validation.cjs +2 -2
  353. package/batteries/tts/native.cjs +1 -1
  354. package/batteries/tts/transformers_js/adapter.cjs +3 -3
  355. package/batteries/tts/transformers_js/exceptions.cjs +2 -2
  356. package/batteries/tts/transformers_js/types.cjs +1 -1
  357. package/batteries/tts/transformers_js/validation.cjs +2 -2
  358. package/batteries/tts/transformers_js.cjs +1 -1
  359. package/batteries/tts.cjs +1 -1
  360. package/batteries/validation/exceptions.cjs +2 -2
  361. package/batteries/validation/types.cjs +1 -1
  362. package/batteries/validation/validation.cjs +1 -1
  363. package/batteries/validation.cjs +6 -6
  364. package/batteries/validation.mjs +4 -4
  365. package/batteries/vector/arangodb.cjs +2 -2
  366. package/batteries/vector/builder.cjs +1 -1
  367. package/batteries/vector/chroma.cjs +2 -2
  368. package/batteries/vector/chroma.mjs +1 -1
  369. package/batteries/vector/clickhouse.cjs +3 -3
  370. package/batteries/vector/clickhouse.mjs +1 -1
  371. package/batteries/vector/cloudflare.cjs +3 -3
  372. package/batteries/vector/cloudflare.mjs +1 -1
  373. package/batteries/vector/conformance.cjs +1 -1
  374. package/batteries/vector/contract.cjs +1 -1
  375. package/batteries/vector/couchbase.cjs +3 -3
  376. package/batteries/vector/couchbase.mjs +1 -1
  377. package/batteries/vector/duckdb.cjs +3 -3
  378. package/batteries/vector/duckdb.mjs +1 -1
  379. package/batteries/vector/elasticsearch.cjs +3 -3
  380. package/batteries/vector/elasticsearch.mjs +1 -1
  381. package/batteries/vector/exceptions.cjs +2 -2
  382. package/batteries/vector/factory.cjs +1 -1
  383. package/batteries/vector/filters.cjs +2 -2
  384. package/batteries/vector/helpers.cjs +1 -1
  385. package/batteries/vector/hnswlib.cjs +3 -3
  386. package/batteries/vector/hnswlib.mjs +1 -1
  387. package/batteries/vector/in_memory.cjs +2 -2
  388. package/batteries/vector/in_memory.mjs +1 -1
  389. package/batteries/vector/lancedb.cjs +3 -3
  390. package/batteries/vector/lancedb.mjs +1 -1
  391. package/batteries/vector/mariadb.cjs +3 -3
  392. package/batteries/vector/mariadb.mjs +1 -1
  393. package/batteries/vector/meilisearch.cjs +2 -2
  394. package/batteries/vector/migrate.cjs +2 -2
  395. package/batteries/vector/milvus.cjs +2 -2
  396. package/batteries/vector/milvus.mjs +1 -1
  397. package/batteries/vector/mongodb.cjs +2 -2
  398. package/batteries/vector/neo4j.cjs +2 -2
  399. package/batteries/vector/opensearch.cjs +3 -3
  400. package/batteries/vector/opensearch.mjs +1 -1
  401. package/batteries/vector/oracle23ai.cjs +3 -3
  402. package/batteries/vector/oracle23ai.mjs +1 -1
  403. package/batteries/vector/orama.cjs +2 -2
  404. package/batteries/vector/orama.mjs +1 -1
  405. package/batteries/vector/pgvector.cjs +2 -2
  406. package/batteries/vector/pgvector.mjs +1 -1
  407. package/batteries/vector/pinecone.cjs +3 -3
  408. package/batteries/vector/pinecone.mjs +1 -1
  409. package/batteries/vector/plan.cjs +1 -1
  410. package/batteries/vector/qdrant.cjs +2 -2
  411. package/batteries/vector/qdrant.mjs +1 -1
  412. package/batteries/vector/redis.cjs +3 -3
  413. package/batteries/vector/redis.mjs +1 -1
  414. package/batteries/vector/retrievable.cjs +2 -2
  415. package/batteries/vector/retrievable.mjs +1 -1
  416. package/batteries/vector/s3vectors.cjs +3 -3
  417. package/batteries/vector/s3vectors.mjs +1 -1
  418. package/batteries/vector/schema.cjs +1 -1
  419. package/batteries/vector/solr.cjs +2 -2
  420. package/batteries/vector/sqlite_vec.cjs +2 -2
  421. package/batteries/vector/sqlite_vec.mjs +1 -1
  422. package/batteries/vector/surrealdb.cjs +2 -2
  423. package/batteries/vector/types.cjs +1 -1
  424. package/batteries/vector/typesense.cjs +3 -3
  425. package/batteries/vector/typesense.mjs +1 -1
  426. package/batteries/vector/validation.cjs +1 -1
  427. package/batteries/vector/vector_store_constructor.cjs +1 -1
  428. package/batteries/vector/vespa.cjs +3 -3
  429. package/batteries/vector/vespa.mjs +1 -1
  430. package/batteries/vector/weaviate.cjs +3 -3
  431. package/batteries/vector/weaviate.mjs +1 -1
  432. package/batteries/vector.cjs +2 -2
  433. package/batteries/vector.mjs +1 -1
  434. package/batteries.cjs +11 -10
  435. package/batteries.mjs +11 -11
  436. package/{chat_common-CBqn22t1.js → chat_common-4huaTp6d.cjs} +5 -5
  437. package/chat_common-4huaTp6d.cjs.map +1 -0
  438. package/{chat_common-DKw8FDol.mjs → chat_common-D_XGNjcK.mjs} +2 -2
  439. package/{chat_common-DKw8FDol.mjs.map → chat_common-D_XGNjcK.mjs.map} +1 -1
  440. package/claude-code-cli-wrapper.cjs +106 -24
  441. package/claude-code-cli-wrapper.cjs.map +1 -1
  442. package/claude-code-cli-wrapper.mjs +104 -22
  443. package/claude-code-cli-wrapper.mjs.map +1 -1
  444. package/{common-0rLuBEeY.js → common-BiRzOsxe.cjs} +9 -9
  445. package/common-BiRzOsxe.cjs.map +1 -0
  446. package/{common-BuVhq_3h.js → common-BuVhq_3h.cjs} +1 -1
  447. package/common-BuVhq_3h.cjs.map +1 -0
  448. package/{common-oI1niK9Z.mjs → common-DsLvTGmm.mjs} +7 -7
  449. package/{common-oI1niK9Z.mjs.map → common-DsLvTGmm.mjs.map} +1 -1
  450. package/common.cjs +8 -8
  451. package/common.mjs +7 -7
  452. package/{conformance-T1qEg8Sv.js → conformance-T1qEg8Sv.cjs} +1 -1
  453. package/conformance-T1qEg8Sv.cjs.map +1 -0
  454. package/{dispatch_runner-CKhm-scw.js → dispatch_runner-C5S3KCqH.cjs} +6 -6
  455. package/dispatch_runner-C5S3KCqH.cjs.map +1 -0
  456. package/{dispatch_runner-BZDXUe0G.mjs → dispatch_runner-DDH_dGPU.mjs} +4 -4
  457. package/{dispatch_runner-BZDXUe0G.mjs.map → dispatch_runner-DDH_dGPU.mjs.map} +1 -1
  458. package/dispatch_runner.cjs +2 -2
  459. package/dispatch_runner.mjs +1 -1
  460. package/{ecmascript-DmrNI2Wo.js → ecmascript-BGr_0Dwn.cjs} +6 -6
  461. package/ecmascript-BGr_0Dwn.cjs.map +1 -0
  462. package/{ecmascript-B9Z2C24U.mjs → ecmascript-CWLZ7bCX.mjs} +5 -5
  463. package/{ecmascript-B9Z2C24U.mjs.map → ecmascript-CWLZ7bCX.mjs.map} +1 -1
  464. package/{error_translation-BCa4wxUL.js → error_translation-D8Ea1_th.cjs} +2 -2
  465. package/error_translation-D8Ea1_th.cjs.map +1 -0
  466. package/{escape-COeB923i.js → escape-C12OWStb.cjs} +3 -3
  467. package/escape-C12OWStb.cjs.map +1 -0
  468. package/eslint/rules/artifact_tool_forbids_artifact_constructor.cjs +2 -2
  469. package/eslint/rules/no_model_in_tool_handler.cjs +2 -2
  470. package/eslint/rules/require_string_empty_disposition.cjs +2 -2
  471. package/eslint/rules/require_validator_any_required.cjs +2 -2
  472. package/eslint/rules/thought_payload_requires_replay_tag.cjs +2 -2
  473. package/eslint/rules/token_encoding_requires_context_window.cjs +2 -2
  474. package/eslint/rules.cjs +1 -1
  475. package/eslint.cjs +3 -3
  476. package/eslint.mjs +2 -2
  477. package/{exceptions-Dlw1Jr6E.js → exceptions-Bc1s_ld5.cjs} +2 -2
  478. package/exceptions-Bc1s_ld5.cjs.map +1 -0
  479. package/{exceptions-BY1RQNVP.js → exceptions-BwGzlXoz.cjs} +2 -2
  480. package/exceptions-BwGzlXoz.cjs.map +1 -0
  481. package/{exceptions-DrHnAGQz.js → exceptions-DrHnAGQz.cjs} +1 -1
  482. package/exceptions-DrHnAGQz.cjs.map +1 -0
  483. package/exceptions.cjs +3 -3
  484. package/exceptions.mjs +1 -1
  485. package/factories.cjs +2 -2
  486. package/forge.cjs +3 -3
  487. package/forge.mjs +2 -2
  488. package/{formats-DZVuqZUN.js → formats-DZVuqZUN.cjs} +1 -1
  489. package/formats-DZVuqZUN.cjs.map +1 -0
  490. package/{fs_node-WwUEiuo6.js → fs_node-XvgZtNJV.cjs} +2 -2
  491. package/fs_node-XvgZtNJV.cjs.map +1 -0
  492. package/{function_serializer-ChL2I8Kq.js → function_serializer-D1Kyicai.cjs} +3 -3
  493. package/function_serializer-D1Kyicai.cjs.map +1 -0
  494. package/{gpu_budget-BBIUyLoj.js → gpu_budget-BBIUyLoj.cjs} +1 -1
  495. package/gpu_budget-BBIUyLoj.cjs.map +1 -0
  496. package/{guards-05Uq3J4M.js → guards-5-XmJgD2.cjs} +2 -2
  497. package/guards-5-XmJgD2.cjs.map +1 -0
  498. package/guards.cjs +10 -10
  499. package/guards.mjs +7 -7
  500. package/{helpers-CObtMmAZ.js → helpers-BPi_iwxv.cjs} +4 -4
  501. package/helpers-BPi_iwxv.cjs.map +1 -0
  502. package/{helpers-mbn_EsDV.mjs → helpers-D47G8WQb.mjs} +3 -3
  503. package/{helpers-mbn_EsDV.mjs.map → helpers-D47G8WQb.mjs.map} +1 -1
  504. package/index.cjs +13 -13
  505. package/index.mjs +10 -10
  506. package/{isolation-7Jrcucgc.js → isolation-B2FgKbap.cjs} +5 -5
  507. package/isolation-B2FgKbap.cjs.map +1 -0
  508. package/{isolation-CO0NiK8R.mjs → isolation-BRGpiU-K.mjs} +2 -2
  509. package/{isolation-CO0NiK8R.mjs.map → isolation-BRGpiU-K.mjs.map} +1 -1
  510. package/lib/helpers/bignum.cjs +1 -1
  511. package/lib/utils/audio.cjs +1 -1
  512. package/lib/utils/retry.cjs +1 -1
  513. package/{lifecycle-vYQJ2rmf.js → lifecycle-vYQJ2rmf.cjs} +1 -1
  514. package/lifecycle-vYQJ2rmf.cjs.map +1 -0
  515. package/{manifest-D8UTRohY.mjs → manifest-B5bWMHgj.mjs} +2 -2
  516. package/{manifest-D8UTRohY.mjs.map → manifest-B5bWMHgj.mjs.map} +1 -1
  517. package/{manifest-iMAmSDay.js → manifest-Chjh-3s1.cjs} +4 -4
  518. package/manifest-Chjh-3s1.cjs.map +1 -0
  519. package/mcp/adk-docs-corpus.json +2 -2
  520. package/package.json +490 -490
  521. package/{patch-BXX9Q0FM.js → patch-BXX9Q0FM.cjs} +1 -1
  522. package/patch-BXX9Q0FM.cjs.map +1 -0
  523. package/{predicates-CM27Z3TF.mjs → predicates-2dZQ82LY.mjs} +2 -2
  524. package/{predicates-CM27Z3TF.mjs.map → predicates-2dZQ82LY.mjs.map} +1 -1
  525. package/{predicates-f3wvKYT8.js → predicates-C9jl2QPZ.cjs} +3 -3
  526. package/predicates-C9jl2QPZ.cjs.map +1 -0
  527. package/{retrievable-BTwjmPnl.js → retrievable-ReauMJxJ.cjs} +5 -5
  528. package/retrievable-ReauMJxJ.cjs.map +1 -0
  529. package/{retrievable-CXTAUuuv.mjs → retrievable-mFgC1aty.mjs} +3 -3
  530. package/{retrievable-CXTAUuuv.mjs.map → retrievable-mFgC1aty.mjs.map} +1 -1
  531. package/{sandbox-utils-DLCceTeU.js → sandbox-utils-D12AZhWE.cjs} +2 -2
  532. package/sandbox-utils-D12AZhWE.cjs.map +1 -0
  533. package/{scrapper-CJexXXK-.js → scrapper-BsEY0Wo6.cjs} +7 -7
  534. package/scrapper-BsEY0Wo6.cjs.map +1 -0
  535. package/{scrapper-DiQ5FfDL.mjs → scrapper-bShwZxKP.mjs} +5 -5
  536. package/{scrapper-DiQ5FfDL.mjs.map → scrapper-bShwZxKP.mjs.map} +1 -1
  537. package/{searxng-BFTJ6rTE.mjs → searxng-CAY-bOMl.mjs} +5 -5
  538. package/{searxng-BFTJ6rTE.mjs.map → searxng-CAY-bOMl.mjs.map} +1 -1
  539. package/{searxng-DzlGZG4V.js → searxng-CLF0vBMT.cjs} +7 -7
  540. package/searxng-CLF0vBMT.cjs.map +1 -0
  541. package/{server-CnUZcn6e.js → server-CkVjzQaC.cjs} +2 -2
  542. package/server-CkVjzQaC.cjs.map +1 -0
  543. package/server.json +2 -2
  544. package/{shell-quote-CIuPmePF.js → shell-quote-BUxBTn3M.cjs} +2 -2
  545. package/shell-quote-BUxBTn3M.cjs.map +1 -0
  546. package/shims.cjs +2 -2
  547. package/skills/adk-assembly/SKILL.md +2 -2
  548. package/{spooled_artifact-Bw_7swIp.mjs → spooled_artifact-B710Rb0d.mjs} +731 -731
  549. package/spooled_artifact-B710Rb0d.mjs.map +1 -0
  550. package/{spooled_artifact-BpcesRBv.js → spooled_artifact-CFjf6ULg.cjs} +733 -733
  551. package/spooled_artifact-CFjf6ULg.cjs.map +1 -0
  552. package/spooled_artifact.cjs +3 -3
  553. package/spooled_artifact.mjs +2 -2
  554. package/{spooled_markdown_artifact-vd6eNtIP.mjs → spooled_markdown_artifact-1C4mmi73.mjs} +3 -3
  555. package/{spooled_markdown_artifact-vd6eNtIP.mjs.map → spooled_markdown_artifact-1C4mmi73.mjs.map} +1 -1
  556. package/{spooled_markdown_artifact-wJPnE8Ij.js → spooled_markdown_artifact-PWppwnPQ.cjs} +5 -5
  557. package/spooled_markdown_artifact-PWppwnPQ.cjs.map +1 -0
  558. package/{thought-CxSaF6Xf.mjs → thought-BKXwUZoq.mjs} +3 -3
  559. package/{thought-CxSaF6Xf.mjs.map → thought-BKXwUZoq.mjs.map} +1 -1
  560. package/{thought-Dg_4UZxg.js → thought-D5fJsxBW.cjs} +5 -5
  561. package/thought-D5fJsxBW.cjs.map +1 -0
  562. package/{tokenizable-BMZuGWRd.js → tokenizable-DDIdXbJN.cjs} +31 -31
  563. package/tokenizable-DDIdXbJN.cjs.map +1 -0
  564. package/{tokenizable-VB4Av8GF.mjs → tokenizable-xPXj1AQX.mjs} +30 -30
  565. package/{tokenizable-VB4Av8GF.mjs.map → tokenizable-xPXj1AQX.mjs.map} +1 -1
  566. package/{tool_call-Fs_Uh5wQ.js → tool_call-CDV5pW13.cjs} +5 -5
  567. package/tool_call-CDV5pW13.cjs.map +1 -0
  568. package/{tool_call-Cfaj-6zK.mjs → tool_call-D-LqMvpU.mjs} +3 -3
  569. package/{tool_call-Cfaj-6zK.mjs.map → tool_call-D-LqMvpU.mjs.map} +1 -1
  570. package/{tool_parsers-csSBFWob.js → tool_parsers-8_qO0a_F.cjs} +2 -2
  571. package/tool_parsers-8_qO0a_F.cjs.map +1 -0
  572. package/{tools-rJvfktHR.js → tools-CACuuMV4.cjs} +9 -9
  573. package/tools-CACuuMV4.cjs.map +1 -0
  574. package/{tools-D0MBDh2R.mjs → tools-CvCMdAd7.mjs} +6 -6
  575. package/{tools-D0MBDh2R.mjs.map → tools-CvCMdAd7.mjs.map} +1 -1
  576. package/{toon-BXPdJRz7.js → toon-B7Q9RWJF.cjs} +7 -7
  577. package/toon-B7Q9RWJF.cjs.map +1 -0
  578. package/{toon-BSTQnHed.mjs → toon-CCjuuzd_.mjs} +6 -6
  579. package/{toon-BSTQnHed.mjs.map → toon-CCjuuzd_.mjs.map} +1 -1
  580. package/{transformers_js-p3lAkHFH.mjs → transformers_js-BR2Ov0Su.mjs} +2 -2
  581. package/{transformers_js-p3lAkHFH.mjs.map → transformers_js-BR2Ov0Su.mjs.map} +1 -1
  582. package/{transformers_js-C050gRfd.js → transformers_js-DM01eAzh.cjs} +4 -4
  583. package/transformers_js-DM01eAzh.cjs.map +1 -0
  584. package/{turn_runner-BHHD6h77.mjs → turn_runner-BgPw9uqb.mjs} +4 -4
  585. package/{turn_runner-BHHD6h77.mjs.map → turn_runner-BgPw9uqb.mjs.map} +1 -1
  586. package/{turn_runner-DhLI7OTH.js → turn_runner-CP2zxSlu.cjs} +6 -6
  587. package/turn_runner-CP2zxSlu.cjs.map +1 -0
  588. package/turn_runner.cjs +2 -2
  589. package/turn_runner.mjs +1 -1
  590. package/{type_guards-BAhiOypL-C2eOOyxU.js → type_guards-BAhiOypL-C2eOOyxU.cjs} +1 -1
  591. package/{type_guards-BAhiOypL-C2eOOyxU.js.map → type_guards-BAhiOypL-C2eOOyxU.cjs.map} +1 -1
  592. package/{type_guards-DuKwiYgg.js → type_guards-BWTKysPt.cjs} +2 -2
  593. package/{types-DrSosVaM.js → types-DWOiL208.cjs} +4 -4
  594. package/types-DWOiL208.cjs.map +1 -0
  595. package/types.cjs +1 -1
  596. package/{validate-CkQI-48O.js → validate-tUm9MY8y.cjs} +3 -3
  597. package/validate-tUm9MY8y.cjs.map +1 -0
  598. package/{xlsx-B0sTpEC2.js → xlsx-Dtql4S-9.cjs} +2 -2
  599. package/xlsx-Dtql4S-9.cjs.map +1 -0
  600. package/{xlsx.zahl-ZIcUQVv8.js → xlsx.zahl-C9pM7cyt.cjs} +2 -2
  601. package/xlsx.zahl-C9pM7cyt.cjs.map +1 -0
  602. package/{xml-CYseDztH.mjs → xml-BqTTIFhv.mjs} +6 -6
  603. package/{xml-CYseDztH.mjs.map → xml-BqTTIFhv.mjs.map} +1 -1
  604. package/{xml-CNmgj5Qq.js → xml-viE54OTe.cjs} +7 -7
  605. package/xml-viE54OTe.cjs.map +1 -0
  606. package/{yaml-BPBoiOjx.mjs → yaml-B1So-pUR.mjs} +6 -6
  607. package/{yaml-BPBoiOjx.mjs.map → yaml-B1So-pUR.mjs.map} +1 -1
  608. package/{yaml-CaoIJyRe.js → yaml-cGhhPyZq.cjs} +7 -7
  609. package/yaml-cGhhPyZq.cjs.map +1 -0
  610. package/arg_specs-iYmIM3wI.js.map +0 -1
  611. package/artifact_methods-Cg0go7Q4.mjs +0 -1
  612. package/artifact_methods-SKgM322C.js +0 -1
  613. package/chat_common-CBqn22t1.js.map +0 -1
  614. package/common-0rLuBEeY.js.map +0 -1
  615. package/common-BuVhq_3h.js.map +0 -1
  616. package/conformance-T1qEg8Sv.js.map +0 -1
  617. package/dispatch_runner-CKhm-scw.js.map +0 -1
  618. package/ecmascript-DmrNI2Wo.js.map +0 -1
  619. package/error_translation-BCa4wxUL.js.map +0 -1
  620. package/escape-COeB923i.js.map +0 -1
  621. package/exceptions-BY1RQNVP.js.map +0 -1
  622. package/exceptions-Dlw1Jr6E.js.map +0 -1
  623. package/exceptions-DrHnAGQz.js.map +0 -1
  624. package/formats-DZVuqZUN.js.map +0 -1
  625. package/fs_node-WwUEiuo6.js.map +0 -1
  626. package/function_serializer-ChL2I8Kq.js.map +0 -1
  627. package/gpu_budget-BBIUyLoj.js.map +0 -1
  628. package/guards-05Uq3J4M.js.map +0 -1
  629. package/helpers-CObtMmAZ.js.map +0 -1
  630. package/isolation-7Jrcucgc.js.map +0 -1
  631. package/lifecycle-vYQJ2rmf.js.map +0 -1
  632. package/manifest-iMAmSDay.js.map +0 -1
  633. package/patch-BXX9Q0FM.js.map +0 -1
  634. package/predicates-f3wvKYT8.js.map +0 -1
  635. package/retrievable-BTwjmPnl.js.map +0 -1
  636. package/sandbox-utils-DLCceTeU.js.map +0 -1
  637. package/scrapper-CJexXXK-.js.map +0 -1
  638. package/searxng-DzlGZG4V.js.map +0 -1
  639. package/server-CnUZcn6e.js.map +0 -1
  640. package/shell-quote-CIuPmePF.js.map +0 -1
  641. package/spooled_artifact-BpcesRBv.js.map +0 -1
  642. package/spooled_artifact-Bw_7swIp.mjs.map +0 -1
  643. package/spooled_markdown_artifact-wJPnE8Ij.js.map +0 -1
  644. package/thought-Dg_4UZxg.js.map +0 -1
  645. package/tokenizable-BMZuGWRd.js.map +0 -1
  646. package/tool_call-Fs_Uh5wQ.js.map +0 -1
  647. package/tool_parsers-csSBFWob.js.map +0 -1
  648. package/tools-rJvfktHR.js.map +0 -1
  649. package/toon-BXPdJRz7.js.map +0 -1
  650. package/transformers_js-C050gRfd.js.map +0 -1
  651. package/turn_runner-DhLI7OTH.js.map +0 -1
  652. package/types-DrSosVaM.js.map +0 -1
  653. package/validate-CkQI-48O.js.map +0 -1
  654. package/xlsx-B0sTpEC2.js.map +0 -1
  655. package/xlsx.zahl-ZIcUQVv8.js.map +0 -1
  656. package/xml-CNmgj5Qq.js.map +0 -1
  657. package/yaml-CaoIJyRe.js.map +0 -1
  658. /package/{chunk-Cek0wNdY.js → chunk-Cek0wNdY.cjs} +0 -0
@@ -1,532 +1,538 @@
1
- const require_chunk = require("./chunk-Cek0wNdY.js");
2
- const require_exceptions = require("./exceptions-DrHnAGQz.js");
3
- const require_guards = require("./guards-05Uq3J4M.js");
4
- const require_tokenizable = require("./tokenizable-BMZuGWRd.js");
1
+ const require_chunk = require("./chunk-Cek0wNdY.cjs");
2
+ const require_exceptions = require("./exceptions-DrHnAGQz.cjs");
3
+ const require_guards = require("./guards-5-XmJgD2.cjs");
4
+ const require_tokenizable = require("./tokenizable-DDIdXbJN.cjs");
5
5
  let _nhtio_validation = require("@nhtio/validation");
6
+ let luxon = require("luxon");
7
+ let js_sha256 = require("js-sha256");
6
8
  let dset = require("dset");
7
9
  let klona = require("klona");
8
10
  let dlv = require("dlv");
9
11
  dlv = require_chunk.__toESM(dlv);
10
- let luxon = require("luxon");
11
- let js_sha256 = require("js-sha256");
12
- //#region src/lib/classes/registry.ts
12
+ //#region src/lib/classes/tool_registry.ts
13
13
  /**
14
- * A controlled-mutation key-value store with dot-path access and deep-clone isolation.
14
+ * A mutable, turn-scoped collection of {@link @nhtio/adk!Tool} instances.
15
15
  *
16
16
  * @remarks
17
- * The registry enforces a safe read/write contract: callers never hold a live reference into
18
- * the internal store. Every value that enters (`set`) or leaves (`get`, `all`) is deep-cloned
19
- * via `klona`, so mutations to a retrieved value cannot affect stored state and vice versa.
17
+ * Each `TurnRunner.run()` call constructs a fresh `ToolRegistry` from the runner's configured
18
+ * baseline tools, so middleware edits are isolated to the current turn and cannot bleed across
19
+ * concurrent or subsequent turns.
20
20
  *
21
- * Keys are dot-delimited paths (e.g. `"user.profile.name"`), resolved via `dlv` for reads and
22
- * `dset` for writes; intermediate objects are created automatically on write.
21
+ * `Tool` instances are immutable, so `all()` returns a fresh array without deep-cloning.
22
+ *
23
+ * `register()` throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} if a tool with the same name is already
24
+ * present — pass `overwrite: true` to replace it explicitly.
25
+ *
26
+ * Tools can be **hidden** — registered and callable, but excluded from the default tool list
27
+ * rendered to the model. This is useful for discovery patterns where an agent has a tool that
28
+ * enumerates available tools, and the model picks one to call by name in a subsequent iteration.
29
+ * Hidden state is a property of the registry, not the tool: the same tool can be visible in one
30
+ * registry and hidden in another. See {@link hide}, {@link visible}, {@link hidden}.
23
31
  */
24
- var Registry = class Registry {
25
- #store;
32
+ var ToolRegistry = class ToolRegistry {
33
+ #tools;
34
+ #hidden;
26
35
  /**
27
- * @param initial - Optional plain object to seed the registry. Deep-cloned on construction.
28
- * @throws {@link @nhtio/adk!E_INVALID_INITIAL_REGISTRY_VALUE} when `initial` is defined but not a plain object.
36
+ * Returns `true` if `value` is a {@link ToolRegistry} instance.
37
+ *
38
+ * @param value - The value to test.
39
+ * @returns `true` when `value` is a {@link ToolRegistry} instance.
29
40
  */
30
- constructor(initial) {
31
- if ("undefined" !== typeof initial && !require_guards.isObject(initial)) throw new require_tokenizable.E_INVALID_INITIAL_REGISTRY_VALUE();
32
- this.#store = initial ? (0, klona.klona)(initial) : {};
41
+ static isToolRegistry(value) {
42
+ return require_guards.isInstanceOf(value, "ToolRegistry", ToolRegistry);
33
43
  }
34
44
  /**
35
- * Returns `true` if `value` is a {@link Registry} instance.
45
+ * @param tools - Optional initial tools. Insertion order is preserved. Duplicate names throw
46
+ * {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} — ensure each tool has a unique name.
47
+ * @throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} when two tools in `tools` share a name.
48
+ */
49
+ constructor(tools) {
50
+ this.#tools = /* @__PURE__ */ new Map();
51
+ this.#hidden = /* @__PURE__ */ new Set();
52
+ for (const tool of tools ?? []) this.register(tool);
53
+ }
54
+ /**
55
+ * Adds a tool to the registry.
56
+ *
57
+ * @param tool - The tool to register.
58
+ * @param overwrite - When `true`, silently replaces an existing tool with the same name.
59
+ * Defaults to `false`.
60
+ * @throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} when a tool with the same name is already registered
61
+ * and `overwrite` is not `true`.
62
+ */
63
+ register(tool, overwrite) {
64
+ if (this.#tools.has(tool.name) && !overwrite) throw new require_tokenizable.E_TOOL_ALREADY_REGISTERED();
65
+ this.#tools.set(tool.name, tool);
66
+ }
67
+ /**
68
+ * Removes the tool with the given name from the registry.
36
69
  *
37
70
  * @remarks
38
- * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety.
71
+ * Also removes the name from the hidden set if present. No-ops if no tool with that name is
72
+ * registered.
39
73
  *
40
- * @param value - The value to test.
41
- * @returns `true` when `value` is a {@link Registry} instance.
74
+ * @param name - The name of the tool to remove.
42
75
  */
43
- static isRegistry(value) {
44
- return require_guards.isInstanceOf(value, "Registry", Registry);
76
+ unregister(name) {
77
+ this.#tools.delete(name);
78
+ this.#hidden.delete(name);
45
79
  }
46
80
  /**
47
- * Retrieves the value at `key`, returning `defaultValue` if the path is absent.
81
+ * Returns the tool registered under `name`, or `undefined` if not present.
48
82
  *
49
- * @remarks
50
- * The returned value is a deep clone — mutating it will not affect the stored state.
83
+ * @param name - The tool name to look up.
84
+ */
85
+ get(name) {
86
+ return this.#tools.get(name);
87
+ }
88
+ /**
89
+ * Returns `true` if a tool with the given name is registered.
51
90
  *
52
- * @typeParam T - Expected type of the value at `key`.
53
- * @param key - Dot-delimited path into the store (e.g. `"user.name"`).
54
- * @param defaultValue - Fallback returned when the path resolves to `undefined`.
55
- * @returns A deep clone of the stored value cast to `T`, or `defaultValue` when the path is absent.
91
+ * @param name - The tool name to test.
56
92
  */
57
- get(key, defaultValue) {
58
- const value = (0, dlv.default)((0, klona.klona)(this.#store), key);
59
- return "undefined" === typeof value ? defaultValue : value;
93
+ has(name) {
94
+ return this.#tools.has(name);
60
95
  }
61
96
  /**
62
- * Sets the value at `key`, creating intermediate objects as needed.
97
+ * Returns a fresh array of all registered tools in insertion order.
63
98
  *
64
99
  * @remarks
65
- * The stored value is isolated from the caller — mutating `value` after this call will not
66
- * affect what is held in the registry.
100
+ * Includes both visible and hidden tools. Use {@link visible} to get only non-hidden tools, or
101
+ * {@link hidden} to get only hidden tools.
67
102
  *
68
- * @param key - Dot-delimited path into the store (e.g. `"user.name"`).
69
- * @param value - Value to store at the path.
103
+ * Since {@link @nhtio/adk!Tool} instances are immutable, no deep-cloning is needed.
70
104
  */
71
- set(key, value) {
72
- (0, dset.dset)(this.#store, key, value);
105
+ all() {
106
+ return Array.from(this.#tools.values());
73
107
  }
74
108
  /**
75
- * Returns `true` if the registry has a value at `key`, `false` otherwise.
109
+ * Returns a fresh array of registered tools that are **not** hidden, in insertion order.
76
110
  *
77
111
  * @remarks
78
- * A key resolving to `undefined` is treated as absent — same convention as {@link Registry.get}'s
79
- * `defaultValue` fallback. No clone is performed; this is a pure existence check.
112
+ * This is the accessor LLM batteries should use when building the tool list for the model.
113
+ * Hidden tools are still callable (they resolve via {@link get}) but are excluded from the
114
+ * rendered tool definitions.
115
+ */
116
+ visible() {
117
+ return this.all().filter((t) => !this.#hidden.has(t.name));
118
+ }
119
+ /**
120
+ * Returns a fresh array of registered tools that **are** hidden, in insertion order.
80
121
  *
81
- * @param key - Dot-delimited path into the store (e.g. `"user.name"`).
82
- * @returns `true` when the path resolves to a value other than `undefined`.
122
+ * @remarks
123
+ * The converse of {@link visible}. Useful for discovery tools that enumerate all available
124
+ * tools, and for propagating hidden state across {@link merge}.
83
125
  */
84
- has(key) {
85
- return "undefined" !== typeof (0, dlv.default)(this.#store, key);
126
+ hidden() {
127
+ return this.all().filter((t) => this.#hidden.has(t.name));
86
128
  }
87
129
  /**
88
- * Returns all leaf dot-paths present in the registry.
130
+ * Marks one or more registered tools as hidden.
89
131
  *
90
132
  * @remarks
91
- * The store is deep-cloned before traversal. Plain objects are walked recursively with path
92
- * segments joined by dots; arrays, primitives, `null`, and class instances are treated as leaves.
133
+ * Hidden tools remain registered and callable via {@link get}, but are excluded from
134
+ * {@link visible} (and therefore from the LLM tool list). No-ops for any name that is not
135
+ * currently registered — the end result (the tool is not visible) matches the intent.
93
136
  *
94
- * @returns A string array of dot-delimited paths to leaf values in the store.
137
+ * @param names - One or more tool names to hide.
95
138
  */
96
- keys() {
97
- const store = (0, klona.klona)(this.#store);
98
- const keys = [];
99
- const isPlainRecord = (value) => {
100
- if (!require_guards.isObject(value)) return false;
101
- const prototype = Object.getPrototypeOf(value);
102
- return prototype === Object.prototype || prototype === null;
103
- };
104
- const walk = (value, segments) => {
105
- if (!isPlainRecord(value)) {
106
- if (segments.length > 0) keys.push(segments.join("."));
107
- return;
108
- }
109
- for (const [segment, child] of Object.entries(value)) walk(child, [...segments, segment]);
110
- };
111
- walk(store, []);
112
- return keys;
139
+ hide(...names) {
140
+ for (const name of names) this.#hidden.add(name);
113
141
  }
114
142
  /**
115
- * Returns a deep clone of the entire store contents.
143
+ * Unmarks one or more tools as hidden, making them visible again.
116
144
  *
117
- * @returns A plain object snapshot of all stored key-value pairs.
145
+ * @remarks
146
+ * No-ops for any name that is not currently hidden.
147
+ *
148
+ * @param names - One or more tool names to unhide.
118
149
  */
119
- all() {
120
- return (0, klona.klona)(this.#store);
150
+ unhide(...names) {
151
+ for (const name of names) this.#hidden.delete(name);
121
152
  }
122
153
  /**
123
- * Serialise this Registry into an `@nhtio/encoder` snapshot.
154
+ * Replaces the entire hidden set with the given tool names.
124
155
  *
125
156
  * @remarks
126
- * The snapshot is a deep clone of the store ({@link Registry.all}). Leaf values that are themselves
127
- * registered encodable instances round-trip; anything the encoder cannot serialise throws at encode
128
- * time (standard encoder behaviour). Round-trips via {@link Registry.[DECODE_METHOD]}.
157
+ * Any previously hidden tool not in `names` becomes visible. Names that are not registered are
158
+ * silently ignored — they are added to the set but have no effect until a tool with that name
159
+ * is registered.
129
160
  *
130
- * @returns A deep-cloned plain-object snapshot of the store.
161
+ * @param names - The complete set of tool names to hide.
131
162
  */
132
- [require_tokenizable.ENCODE_METHOD]() {
133
- return this.all();
163
+ setHidden(...names) {
164
+ this.#hidden = new Set(names);
134
165
  }
135
166
  /**
136
- * Reconstruct a {@link Registry} from a {@link Registry.[ENCODE_METHOD]} snapshot.
167
+ * Unhides every tool in the registry.
168
+ */
169
+ clearHidden() {
170
+ this.#hidden.clear();
171
+ }
172
+ /**
173
+ * Removes every tool whose {@link @nhtio/adk!Tool.ephemeral} flag is `true`.
137
174
  *
138
- * @param data - The store snapshot produced by {@link Registry.[ENCODE_METHOD]}.
139
- * @returns A fresh {@link Registry} seeded with the snapshot.
175
+ * @remarks
176
+ * Also removes pruned tool names from the hidden set. Synchronous and idempotent — calling it
177
+ * twice in a row is a no-op the second time. The canonical caller is
178
+ * {@link ToolRegistry.bindContext}, which schedules this method to run at
179
+ * {@link @nhtio/adk!DispatchContext.ack}. Non-ephemeral tools are left untouched.
140
180
  */
141
- static [require_tokenizable.DECODE_METHOD](data) {
142
- return new Registry(data);
181
+ pruneEphemeral() {
182
+ for (const [name, tool] of this.#tools) if (tool.ephemeral) {
183
+ this.#tools.delete(name);
184
+ this.#hidden.delete(name);
185
+ }
143
186
  }
144
- };
145
- //#endregion
146
- //#region src/lib/utils/canonical_json.ts
147
- /**
148
- * Canonical `JSON.stringify` that sorts object keys recursively so that semantically-equal
149
- * objects produce identical strings.
150
- *
151
- * @remarks
152
- * Used wherever the ADK derives a stable identity from a structured value — for example,
153
- * `Tool.executor` computing the `callId` for `ToolExecutionStart`/`End` events, and the
154
- * `reportToolCall` executor helper computing the `checksum` field on `TurnToolCallContent`.
155
- * Both code paths hash `canonicalStringify({ tool, args })` so that argument key order does not
156
- * affect the resulting identifier.
157
- *
158
- * Arrays are serialised in their declared order (order is meaningful for an array). Object keys
159
- * are sorted with `Array.prototype.sort()`'s default lexicographic comparator.
160
- *
161
- * @param value - The value to serialise.
162
- * @returns A canonical JSON string representation of `value`.
163
- */
164
- function canonicalStringify(value) {
165
- if (value === null || typeof value !== "object") return JSON.stringify(value);
166
- if (Array.isArray(value)) return "[" + value.map((v) => canonicalStringify(v)).join(",") + "]";
167
- const obj = value;
168
- return "{" + Object.keys(obj).sort().map((k) => JSON.stringify(k) + ":" + canonicalStringify(obj[k])).join(",") + "}";
169
- }
170
- //#endregion
171
- //#region src/lib/contracts/spooled_artifact_constructor.ts
172
- var ARTIFACT_METHODS = [
173
- "head",
174
- "tail",
175
- "grep",
176
- "cat",
177
- "byteLength",
178
- "lineCount",
179
- "estimateTokens"
180
- ];
181
- /**
182
- * Validator schema used to validate a {@link SpooledArtifactConstructorLike} value.
183
- *
184
- * @remarks
185
- * Because the validator is invoked at validate-time (not at module-load), it is safe to inspect
186
- * the constructor's prototype here. The check is duck-typed: the value must be a function whose
187
- * `prototype` carries every canonical artifact instance method (`head`, `tail`, `grep`, `cat`,
188
- * `byteLength`, `lineCount`, `estimateTokens`). This mirrors {@link spoolReaderSchema}'s
189
- * cross-realm-safe duck-type pattern — `instanceof SpooledArtifact` would be tighter but would
190
- * force a value-import of the class and reopen the module cycle.
191
- */
192
- var spooledArtifactConstructorSchema = _nhtio_validation.validator.any().required().custom((value, helpers) => {
193
- if (typeof value !== "function") return helpers.error("any.invalid");
194
- const proto = value.prototype;
195
- if (proto === void 0 || proto === null) return helpers.error("any.invalid");
196
- if (ARTIFACT_METHODS.every((m) => typeof proto[m] === "function")) return value;
197
- return helpers.error("any.invalid");
198
- });
187
+ /**
188
+ * Binds this registry to a {@link @nhtio/adk!DispatchContext} so that {@link pruneEphemeral} runs
189
+ * automatically when the context is acked.
190
+ *
191
+ * @remarks
192
+ * The handler does NOT fire on {@link @nhtio/adk!DispatchContext.nack} — failed executor runs leave
193
+ * any forged tools in place so the consumer can inspect what was registered when debugging the
194
+ * failure. Subscriptions are short-lived and die with the context regardless.
195
+ *
196
+ * ARTIFACT READERS ARE FORGED BY THE CORE. As of the core-forge change, the `DispatchRunner` forges
197
+ * artifact-reader tools from prior-turn `SpooledArtifact` results into `ctx.tools` (and calls
198
+ * `ctx.tools.bindContext(ctx)`) once per iteration, BEFORE the input pipeline — so a battery executor no
199
+ * longer forges or binds; it reads the already-forged `ctx.tools` for both representation (rendering the
200
+ * tool declarations) and resolution (looking up an incoming call by name). The lifecycle is unchanged:
201
+ * ephemeral readers are still pruned on `ack`, and the core re-forges each iteration (prune-then-forge) so
202
+ * the `callId` enum never goes stale.
203
+ *
204
+ * `bindContext` remains the public seam for a CUSTOM consumer that forges its own ephemeral tools outside
205
+ * the core path. If you forge into a long-lived registry yourself, bind it (or prune manually) or the
206
+ * ephemeral tools accumulate and later `forgeTools(ctx)` calls see a stale `callId` enum. The pattern for a
207
+ * hand-rolled forge is:
208
+ *
209
+ * ```ts
210
+ * // Custom forge (the core already does this for artifact readers on ctx.tools):
211
+ * const forged = SpooledArtifact.forgeTools(ctx)
212
+ * for (const tool of forged.all()) ctx.tools.register(tool, true)
213
+ * ctx.tools.bindContext(ctx) // prune the ephemeral readers when the dispatch acks
214
+ * ```
215
+ *
216
+ * @param ctx - The execution context whose `ack` event should trigger pruning.
217
+ * @returns An unsubscribe function — calling it before `ctx.ack()` prevents pruning. Rarely
218
+ * useful outside of tests.
219
+ *
220
+ * @see {@link @nhtio/adk!SpooledArtifact.forgeTools}
221
+ * @see {@link @nhtio/adk!DispatchContext.onAck}
222
+ */
223
+ bindContext(ctx) {
224
+ return ctx.onAck(() => this.pruneEphemeral());
225
+ }
226
+ /**
227
+ * Combines multiple {@link ToolRegistry} instances into a fresh registry without mutating any
228
+ * input.
229
+ *
230
+ * @remarks
231
+ * Iteration is left-to-right across `registries` and then in each registry's insertion order.
232
+ * Collisions are resolved by consulting the **incoming** tool's {@link @nhtio/adk!Tool.onCollision} first:
233
+ *
234
+ * - `'replace'` (per-tool): the incoming tool wins, replacing the existing entry.
235
+ * - `'keep'` (per-tool): the existing entry wins; the incoming tool is dropped.
236
+ * - `'throw'` (per-tool, the default): fall back to the merge-level `options.onCollision`.
237
+ *
238
+ * The merge-level `options.onCollision` defaults to `'throw'`, which mirrors {@link register}.
239
+ *
240
+ * The result is a brand-new registry; no input is mutated and no event subscription is
241
+ * propagated. Each `Tool`'s `ephemeral` flag carries through unchanged — the flag lives on the
242
+ * tool, not the registry, so `bindContext(ctx)` on the merged registry will prune the forged
243
+ * tools as expected.
244
+ *
245
+ * Hidden state is also propagated: a tool that is hidden in any source registry remains hidden
246
+ * in the merged result, provided it survives collision resolution.
247
+ *
248
+ * @param registries - Registries to merge, in priority order (left-to-right insertion).
249
+ * @param options - Merge-level collision policy. Defaults to `{ onCollision: 'throw' }`.
250
+ * @returns A fresh {@link ToolRegistry} containing the resolved union of all inputs.
251
+ * @throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} when the resolved collision policy is `'throw'`
252
+ * and a collision occurs.
253
+ */
254
+ static merge(registries, options) {
255
+ const policy = options?.onCollision ?? "throw";
256
+ const merged = new ToolRegistry();
257
+ for (const registry of registries) {
258
+ for (const tool of registry.all()) {
259
+ if (!merged.get(tool.name)) {
260
+ merged.register(tool);
261
+ continue;
262
+ }
263
+ const incomingPolicy = tool.onCollision;
264
+ if (incomingPolicy === "replace") {
265
+ merged.register(tool, true);
266
+ continue;
267
+ }
268
+ if (incomingPolicy === "keep") continue;
269
+ if (policy === "replace") {
270
+ merged.register(tool, true);
271
+ continue;
272
+ }
273
+ if (policy === "keep") continue;
274
+ throw new require_tokenizable.E_TOOL_ALREADY_REGISTERED();
275
+ }
276
+ for (const tool of registry.hidden()) if (merged.has(tool.name)) merged.hide(tool.name);
277
+ }
278
+ return merged;
279
+ }
280
+ /**
281
+ * Serialise this ToolRegistry into an `@nhtio/encoder` snapshot.
282
+ *
283
+ * @remarks
284
+ * Emits the live {@link @nhtio/adk!Tool} instances (the encoder recurses into each — so every tool's
285
+ * handler-closure caveat from {@link Tool.[ENCODE_METHOD]} applies) plus the hidden-set names. Both
286
+ * {@link @nhtio/adk!Tool} and {@link @nhtio/adk!ArtifactTool} entries round-trip to their correct
287
+ * subtype. Round-trips via {@link ToolRegistry.[DECODE_METHOD]}.
288
+ *
289
+ * @returns A `{ tools, hidden }` snapshot.
290
+ */
291
+ [require_tokenizable.ENCODE_METHOD]() {
292
+ return {
293
+ tools: this.all(),
294
+ hidden: this.hidden().map((tool) => tool.name)
295
+ };
296
+ }
297
+ /**
298
+ * Reconstruct a {@link ToolRegistry} from a {@link ToolRegistry.[ENCODE_METHOD]} snapshot.
299
+ *
300
+ * @param data - The snapshot produced by {@link ToolRegistry.[ENCODE_METHOD]}.
301
+ * @returns A fresh {@link ToolRegistry} with the same tools and hidden set.
302
+ */
303
+ static [require_tokenizable.DECODE_METHOD](data) {
304
+ const snapshot = data;
305
+ const registry = new ToolRegistry(snapshot.tools);
306
+ registry.setHidden(...snapshot.hidden);
307
+ return registry;
308
+ }
309
+ };
310
+ //#endregion
311
+ //#region src/lib/utils/canonical_json.ts
199
312
  /**
200
- * Returns `true` if `value` is a constructor whose prototype carries every canonical
201
- * {@link @nhtio/adk!SpooledArtifact} instance method.
313
+ * Canonical `JSON.stringify` that sorts object keys recursively so that semantically-equal
314
+ * objects produce identical strings.
202
315
  *
203
316
  * @remarks
204
- * Duck-typed; does not use `instanceof SpooledArtifact`. Used by the `Tool.artifactConstructor`
205
- * resolver validator and any other site that needs to recognise a `SpooledArtifact`-like
206
- * constructor without pulling the class into its module-load graph.
317
+ * Used wherever the ADK derives a stable identity from a structured value — for example,
318
+ * `Tool.executor` computing the `callId` for `ToolExecutionStart`/`End` events, and the
319
+ * `reportToolCall` executor helper computing the `checksum` field on `TurnToolCallContent`.
320
+ * Both code paths hash `canonicalStringify({ tool, args })` so that argument key order does not
321
+ * affect the resulting identifier.
207
322
  *
208
- * @param value - The value to test.
209
- * @returns `true` when `value` is a `SpooledArtifact`-shaped constructor.
210
- */
211
- var implementsSpooledArtifactConstructor = (value) => {
212
- return require_exceptions.passesSchema(spooledArtifactConstructorSchema, value);
213
- };
214
- /**
215
- * Creates the validator fragment for a resolver returning a spooled-artifact constructor.
323
+ * Arrays are serialised in their declared order (order is meaningful for an array). Object keys
324
+ * are sorted with `Array.prototype.sort()`'s default lexicographic comparator.
216
325
  *
217
- * The resolver is invoked during validation, then its result is checked with the canonical
218
- * cross-realm-safe constructor guard. Keeping this fragment here makes `Tool` and `Retrievable`
219
- * share exactly the same validation behaviour.
326
+ * @param value - The value to serialise.
327
+ * @returns A canonical JSON string representation of `value`.
220
328
  */
221
- var artifactConstructorResolverSchema = () => _nhtio_validation.validator.any().custom((value, helpers) => {
222
- if (typeof value !== "function") return helpers.error("any.invalid");
223
- let resolved;
224
- try {
225
- resolved = value();
226
- } catch {
227
- return helpers.error("any.invalid");
228
- }
229
- return implementsSpooledArtifactConstructor(resolved) ? value : helpers.error("any.invalid");
230
- });
329
+ function canonicalStringify(value) {
330
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
331
+ if (Array.isArray(value)) return "[" + value.map((v) => canonicalStringify(v)).join(",") + "]";
332
+ const obj = value;
333
+ return "{" + Object.keys(obj).sort().map((k) => JSON.stringify(k) + ":" + canonicalStringify(obj[k])).join(",") + "}";
334
+ }
231
335
  //#endregion
232
- //#region src/lib/classes/tool.ts
233
- /**
234
- * Validator schema for a {@link RawTool}.
235
- */
236
- var rawToolSchema = _nhtio_validation.validator.object({
237
- name: _nhtio_validation.validator.string().required(),
238
- description: _nhtio_validation.validator.string().required(),
239
- inputSchema: _nhtio_validation.validator.any().custom((value, helpers) => {
240
- if (_nhtio_validation.validator.isSchema(value) && value.type === "object") return value;
241
- return helpers.error("any.invalid");
242
- }).required(),
243
- handler: _nhtio_validation.validator.function().required(),
244
- artifactConstructor: artifactConstructorResolverSchema().optional(),
245
- meta: _nhtio_validation.validator.object().pattern(_nhtio_validation.validator.string(), _nhtio_validation.validator.any()).default({}),
246
- ephemeral: _nhtio_validation.validator.boolean().default(false),
247
- trusted: _nhtio_validation.validator.boolean().default(false),
248
- onCollision: _nhtio_validation.validator.string().valid("throw", "replace", "keep").default("throw")
249
- });
336
+ //#region src/lib/classes/registry.ts
250
337
  /**
251
- * A tool definition that serves as the single source of truth for a callable tool: its name,
252
- * description, input schema, execution handler, and the {@link @nhtio/adk!SpooledArtifact} subclass that
253
- * wraps its serialised output.
254
- *
255
- * @typeParam A - The {@link @nhtio/adk!SpooledArtifact} subtype this tool's results should be wrapped in.
256
- * Defaults to {@link @nhtio/adk!SpooledArtifact}.
338
+ * A controlled-mutation key-value store with dot-path access and deep-clone isolation.
257
339
  *
258
340
  * @remarks
259
- * The `inputSchema` is a `@nhtio/validation` schema. It is used at runtime to validate incoming
260
- * arguments before the handler is called, and its `.describe()` output provides all the metadata
261
- * needed to build a provider-specific LLM tool definition — annotate the schema with
262
- * `.description()`, `.note()`, `.example()` etc. once, and that information is available in both
263
- * contexts without duplication.
264
- *
265
- * The handler is private — invoke it only through `executor(ctx)` which validates args, fires
266
- * observability events (with a stable `callId` derived from the tool name and arguments), and
267
- * wraps handler errors in {@link @nhtio/adk!E_TOOL_DOWNSTREAM_ERROR}. The handler returns serialised bytes
268
- * (`string | Uint8Array`); persistence is the consumer's responsibility.
341
+ * The registry enforces a safe read/write contract: callers never hold a live reference into
342
+ * the internal store. Every value that enters (`set`) or leaves (`get`, `all`) is deep-cloned
343
+ * via `klona`, so mutations to a retrieved value cannot affect stored state and vice versa.
269
344
  *
270
- * `artifactConstructor` is the {@link @nhtio/adk!SpooledArtifact} subclass the consumer should use when
271
- * wrapping the handler's output into a `ToolCall.results` field. The author declares it once
272
- * on the tool instance; the consumer reads it when assembling persisted records.
345
+ * Keys are dot-delimited paths (e.g. `"user.profile.name"`), resolved via `dlv` for reads and
346
+ * `dset` for writes; intermediate objects are created automatically on write.
273
347
  */
274
- var Tool = class Tool {
348
+ var Registry = class Registry {
349
+ #store;
275
350
  /**
276
- * Validator schema that accepts a {@link RawTool} object.
277
- *
278
- * @remarks
279
- * Reusable fragment for any schema that needs to validate or nest a tool entry
280
- * (e.g. `TurnRunnerConfig.tools`).
351
+ * @param initial - Optional plain object to seed the registry. Deep-cloned on construction.
352
+ * @throws {@link @nhtio/adk!E_INVALID_INITIAL_REGISTRY_VALUE} when `initial` is defined but not a plain object.
281
353
  */
282
- static schema = rawToolSchema;
354
+ constructor(initial) {
355
+ if ("undefined" !== typeof initial && !require_guards.isObject(initial)) throw new require_tokenizable.E_INVALID_INITIAL_REGISTRY_VALUE();
356
+ this.#store = initial ? (0, klona.klona)(initial) : {};
357
+ }
283
358
  /**
284
- * Returns `true` if `value` is a {@link Tool} instance.
359
+ * Returns `true` if `value` is a {@link Registry} instance.
360
+ *
361
+ * @remarks
362
+ * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety.
285
363
  *
286
364
  * @param value - The value to test.
287
- * @returns `true` when `value` is a {@link Tool} instance.
365
+ * @returns `true` when `value` is a {@link Registry} instance.
288
366
  */
289
- static isTool(value) {
290
- return require_guards.isInstanceOf(value, "Tool", Tool);
367
+ static isRegistry(value) {
368
+ return require_guards.isInstanceOf(value, "Registry", Registry);
291
369
  }
292
- #name;
293
- #description;
294
- #inputSchema;
295
- #handler;
296
- #artifactConstructor;
297
- #meta;
298
- #ephemeral;
299
- #trusted;
300
- #onCollision;
301
370
  /**
302
- * @param raw - The raw tool input validated against `rawToolSchema`.
303
- * @throws {@link @nhtio/adk!E_INVALID_INITIAL_TOOL_VALUE} when `raw` does not satisfy the schema.
371
+ * Retrieves the value at `key`, returning `defaultValue` if the path is absent.
372
+ *
373
+ * @remarks
374
+ * The returned value is a deep clone — mutating it will not affect the stored state.
375
+ *
376
+ * @typeParam T - Expected type of the value at `key`.
377
+ * @param key - Dot-delimited path into the store (e.g. `"user.name"`).
378
+ * @param defaultValue - Fallback returned when the path resolves to `undefined`.
379
+ * @returns A deep clone of the stored value cast to `T`, or `defaultValue` when the path is absent.
304
380
  */
305
- constructor(raw) {
306
- let resolved;
307
- try {
308
- resolved = require_exceptions.validateOrThrow(rawToolSchema, raw, true);
309
- } catch (err) {
310
- throw new require_tokenizable.E_INVALID_INITIAL_TOOL_VALUE({ cause: require_guards.isError(err) ? err : void 0 });
311
- }
312
- this.#name = resolved.name;
313
- this.#description = resolved.description;
314
- this.#inputSchema = resolved.inputSchema;
315
- this.#handler = resolved.handler;
316
- this.#artifactConstructor = resolved.artifactConstructor;
317
- this.#meta = new Registry(resolved.meta);
318
- this.#ephemeral = resolved.ephemeral;
319
- this.#trusted = resolved.trusted;
320
- this.#onCollision = resolved.onCollision;
321
- Object.defineProperties(this, {
322
- name: {
323
- get: () => this.#name,
324
- enumerable: true,
325
- configurable: false
326
- },
327
- description: {
328
- get: () => this.#description,
329
- enumerable: true,
330
- configurable: false
331
- },
332
- inputSchema: {
333
- get: () => this.#inputSchema,
334
- enumerable: true,
335
- configurable: false
336
- },
337
- artifactConstructor: {
338
- get: () => this.#artifactConstructor,
339
- enumerable: true,
340
- configurable: false
341
- },
342
- meta: {
343
- get: () => this.#meta,
344
- enumerable: true,
345
- configurable: false
346
- },
347
- ephemeral: {
348
- get: () => this.#ephemeral,
349
- enumerable: true,
350
- configurable: false
351
- },
352
- trusted: {
353
- get: () => this.#trusted,
354
- enumerable: true,
355
- configurable: false
356
- },
357
- onCollision: {
358
- get: () => this.#onCollision,
359
- enumerable: true,
360
- configurable: false
361
- }
362
- });
381
+ get(key, defaultValue) {
382
+ const value = (0, dlv.default)((0, klona.klona)(this.#store), key);
383
+ return "undefined" === typeof value ? defaultValue : value;
363
384
  }
364
385
  /**
365
- * Validates `args` against the tool's input schema asynchronously.
386
+ * Sets the value at `key`, creating intermediate objects as needed.
366
387
  *
367
388
  * @remarks
368
- * Async to support schemas with external validators (e.g. database lookups, API calls).
369
- * A validation failure throws {@link @nhtio/adk!E_INVALID_TOOL_ARGS} — this indicates a programming error
370
- * in the tool call loop, not a downstream failure.
389
+ * The stored value is isolated from the caller — mutating `value` after this call will not
390
+ * affect what is held in the registry.
371
391
  *
372
- * @param args - The arguments to validate.
373
- * @returns The validated (and coerced) arguments.
374
- * @throws {@link @nhtio/adk!E_INVALID_TOOL_ARGS} when `args` does not satisfy the input schema.
392
+ * @param key - Dot-delimited path into the store (e.g. `"user.name"`).
393
+ * @param value - Value to store at the path.
375
394
  */
376
- async validate(args) {
377
- try {
378
- return await require_exceptions.asyncValidateOrThrow(this.#inputSchema, args);
379
- } catch (err) {
380
- if (require_guards.isInstanceOf(err, "ValidationException", require_exceptions.ValidationException)) throw new require_tokenizable.E_INVALID_TOOL_ARGS({ cause: err });
381
- throw err;
382
- }
395
+ set(key, value) {
396
+ (0, dset.dset)(this.#store, key, value);
383
397
  }
384
398
  /**
385
- * Returns a bound executor function for this tool against the given turn context.
399
+ * Returns `true` if the registry has a value at `key`, `false` otherwise.
386
400
  *
387
401
  * @remarks
388
- * The executor: (1) computes a stable `callId` as `sha256(canonicalStringify({tool, args}))`
389
- * over the **raw, pre-validation args**, (2) validates `args` via {@link Tool.validate},
390
- * (3) emits `toolExecutionStart` on the context (with the computed `callId`), (4) calls the
391
- * handler, (5) emits `toolExecutionEnd` (with the same `callId`), (6) wraps any handler error
392
- * in {@link @nhtio/adk!E_TOOL_DOWNSTREAM_ERROR} before re-throwing.
402
+ * A key resolving to `undefined` is treated as absent — same convention as {@link Registry.get}'s
403
+ * `defaultValue` fallback. No clone is performed; this is a pure existence check.
393
404
  *
394
- * The handler usually returns serialised bytes (`string | Uint8Array`) — persistence is then the
395
- * consumer's concern, and {@link Tool.artifactConstructor} is the class a wrap-site uses when
396
- * wrapping those bytes into a `ToolCall.results` field. **A handler may instead return a
397
- * {@link @nhtio/adk!SpooledArtifact} it built itself** (streaming into storage and wrapping the
398
- * reader), in which case wrap-sites pass it through untouched and `artifactConstructor` does not
399
- * apply — the returned instance's own class is what artifact-tool forging reads.
405
+ * @param key - Dot-delimited path into the store (e.g. `"user.name"`).
406
+ * @returns `true` when the path resolves to a value other than `undefined`.
407
+ */
408
+ has(key) {
409
+ return "undefined" !== typeof (0, dlv.default)(this.#store, key);
410
+ }
411
+ /**
412
+ * Returns all leaf dot-paths present in the registry.
400
413
  *
401
- * Pattern mirrors `Middleware.runner()` — call once per turn, reuse the returned function.
414
+ * @remarks
415
+ * The store is deep-cloned before traversal. Plain objects are walked recursively with path
416
+ * segments joined by dots; arrays, primitives, `null`, and class instances are treated as leaves.
402
417
  *
403
- * @param ctx - The active turn context. Provides emit functions and turn ID.
404
- * @returns An async function `(args) => Promise<string | Uint8Array | SpooledArtifact | Media | Media[]>`.
405
- * A `SpooledArtifact` is a result the HANDLER built (streamed to storage and wrapped itself); a
406
- * wrap-site passes it through unwrapped rather than re-spooling it. `string`/`Uint8Array` are the
407
- * opposite case — bytes the consumer must still store and wrap.
418
+ * @returns A string array of dot-delimited paths to leaf values in the store.
408
419
  */
409
- executor(ctx) {
410
- return async (args) => {
411
- const callId = (0, js_sha256.sha256)(canonicalStringify({
412
- tool: this.#name,
413
- args
414
- }));
415
- const validatedArgs = await this.validate(args);
416
- const startedAt = luxon.DateTime.now();
417
- ctx.emitToolExecutionStart({
418
- toolName: this.#name,
419
- turnId: ctx.id,
420
- callId,
421
- args: validatedArgs,
422
- startedAt
423
- });
424
- try {
425
- const result = await this.#handler(validatedArgs, ctx, this.#meta);
426
- const endedAt = luxon.DateTime.now();
427
- ctx.emitToolExecutionEnd({
428
- toolName: this.#name,
429
- turnId: ctx.id,
430
- callId,
431
- startedAt,
432
- endedAt,
433
- durationMs: endedAt.diff(startedAt).milliseconds,
434
- isError: false
435
- });
436
- return result;
437
- } catch (err) {
438
- const endedAt = luxon.DateTime.now();
439
- ctx.emitToolExecutionEnd({
440
- toolName: this.#name,
441
- turnId: ctx.id,
442
- callId,
443
- startedAt,
444
- endedAt,
445
- durationMs: endedAt.diff(startedAt).milliseconds,
446
- isError: true
447
- });
448
- throw new require_tokenizable.E_TOOL_DOWNSTREAM_ERROR({ cause: require_guards.isError(err) ? err : void 0 });
420
+ keys() {
421
+ const store = (0, klona.klona)(this.#store);
422
+ const keys = [];
423
+ const isPlainRecord = (value) => {
424
+ if (!require_guards.isObject(value)) return false;
425
+ const prototype = Object.getPrototypeOf(value);
426
+ return prototype === Object.prototype || prototype === null;
427
+ };
428
+ const walk = (value, segments) => {
429
+ if (!isPlainRecord(value)) {
430
+ if (segments.length > 0) keys.push(segments.join("."));
431
+ return;
449
432
  }
433
+ for (const [segment, child] of Object.entries(value)) walk(child, [...segments, segment]);
450
434
  };
435
+ walk(store, []);
436
+ return keys;
451
437
  }
452
438
  /**
453
- * Returns a fully serialisable snapshot of this tool's definition.
454
- *
455
- * @remarks
456
- * The `inputSchema` property is the result of calling `.describe()` on the raw schema — a plain
457
- * object carrying all the annotation metadata (descriptions, notes, examples, types) without any
458
- * validator functions. Use this to build provider-specific LLM tool definitions.
439
+ * Returns a deep clone of the entire store contents.
459
440
  *
460
- * @returns `{ name, description, inputSchema }` where `inputSchema` is the schema description.
441
+ * @returns A plain object snapshot of all stored key-value pairs.
461
442
  */
462
- describe() {
463
- return {
464
- name: this.#name,
465
- description: this.#description,
466
- inputSchema: this.#inputSchema.describe()
467
- };
443
+ all() {
444
+ return (0, klona.klona)(this.#store);
468
445
  }
469
446
  /**
470
- * Serialise this Tool into an `@nhtio/encoder` snapshot.
447
+ * Serialise this Registry into an `@nhtio/encoder` snapshot.
471
448
  *
472
449
  * @remarks
473
- * Three halves with different serialisation strategies:
474
- *
475
- * - **Plain config** (`name`, `description`, `meta`, flags) — emitted verbatim.
476
- * - **`inputSchema`** — delegated to `@nhtio/validation`'s `encode()`, which captures the full schema
477
- * description plus its library version into a compact string; decode rebuilds the live `Schema`.
478
- * - **`handler` / `artifactConstructor`** — emitted as **functions**. The encoder's `FunctionSerializer`
479
- * serialises them by **source text** (`fn.toString()`). This is the sharp edge: a handler that
480
- * closes over `ctx`, service clients, or config loses those bindings on decode — only the source
481
- * survives, and the captured variables read back as `undefined`. A `.bind()`-ed or native handler
482
- * cannot be serialised at all and the encoder throws. Tools are rarely serialised in practice; when
483
- * they are, write handlers that reconstruct their dependencies inside the body rather than closing
484
- * over them.
450
+ * The snapshot is a deep clone of the store ({@link Registry.all}). Leaf values that are themselves
451
+ * registered encodable instances round-trip; anything the encoder cannot serialise throws at encode
452
+ * time (standard encoder behaviour). Round-trips via {@link Registry.[DECODE_METHOD]}.
485
453
  *
486
- * @returns A {@link RawTool}-shaped snapshot (with `inputSchema` as an encoded string).
454
+ * @returns A deep-cloned plain-object snapshot of the store.
487
455
  */
488
456
  [require_tokenizable.ENCODE_METHOD]() {
489
- return {
490
- name: this.#name,
491
- description: this.#description,
492
- inputSchema: (0, _nhtio_validation.encode)(this.#inputSchema),
493
- handler: this.#handler,
494
- artifactConstructor: this.#artifactConstructor,
495
- meta: this.#meta.all(),
496
- ephemeral: this.#ephemeral,
497
- trusted: this.#trusted,
498
- onCollision: this.#onCollision
499
- };
457
+ return this.all();
500
458
  }
501
459
  /**
502
- * Reconstruct a {@link Tool} from a {@link Tool.[ENCODE_METHOD]} snapshot.
503
- *
504
- * @remarks
505
- * Rebuilds the live `Schema` via `@nhtio/validation`'s `decode()`, then re-validates through the
506
- * constructor. The rehydrated `handler` carries only its source text — see
507
- * {@link Tool.[ENCODE_METHOD]} for the closure caveat.
460
+ * Reconstruct a {@link Registry} from a {@link Registry.[ENCODE_METHOD]} snapshot.
508
461
  *
509
- * @param data - The snapshot produced by {@link Tool.[ENCODE_METHOD]}.
510
- * @returns A fully-validated {@link Tool}.
462
+ * @param data - The store snapshot produced by {@link Registry.[ENCODE_METHOD]}.
463
+ * @returns A fresh {@link Registry} seeded with the snapshot.
511
464
  */
512
465
  static [require_tokenizable.DECODE_METHOD](data) {
513
- const snapshot = data;
514
- return new Tool({
515
- ...snapshot,
516
- inputSchema: (0, _nhtio_validation.decode)(snapshot.inputSchema)
517
- });
466
+ return new Registry(data);
518
467
  }
519
468
  };
520
469
  //#endregion
521
- //#region src/lib/classes/artifact_tool.ts
470
+ //#region src/lib/contracts/spooled_artifact_constructor.ts
471
+ var ARTIFACT_METHODS = [
472
+ "head",
473
+ "tail",
474
+ "grep",
475
+ "cat",
476
+ "byteLength",
477
+ "lineCount",
478
+ "estimateTokens"
479
+ ];
522
480
  /**
523
- * Validator schema for a {@link RawArtifactTool}.
481
+ * Validator schema used to validate a {@link SpooledArtifactConstructorLike} value.
524
482
  *
525
483
  * @remarks
526
- * Mirrors the base tool schema but explicitly forbids `artifactConstructor` — the entire
527
- * point of `ArtifactTool` is to opt out of `SpooledArtifact` wrapping.
484
+ * Because the validator is invoked at validate-time (not at module-load), it is safe to inspect
485
+ * the constructor's prototype here. The check is duck-typed: the value must be a function whose
486
+ * `prototype` carries every canonical artifact instance method (`head`, `tail`, `grep`, `cat`,
487
+ * `byteLength`, `lineCount`, `estimateTokens`). This mirrors {@link spoolReaderSchema}'s
488
+ * cross-realm-safe duck-type pattern — `instanceof SpooledArtifact` would be tighter but would
489
+ * force a value-import of the class and reopen the module cycle.
528
490
  */
529
- var rawArtifactToolSchema = _nhtio_validation.validator.object({
491
+ var spooledArtifactConstructorSchema = _nhtio_validation.validator.any().required().custom((value, helpers) => {
492
+ if (typeof value !== "function") return helpers.error("any.invalid");
493
+ const proto = value.prototype;
494
+ if (proto === void 0 || proto === null) return helpers.error("any.invalid");
495
+ if (ARTIFACT_METHODS.every((m) => typeof proto[m] === "function")) return value;
496
+ return helpers.error("any.invalid");
497
+ });
498
+ /**
499
+ * Returns `true` if `value` is a constructor whose prototype carries every canonical
500
+ * {@link @nhtio/adk!SpooledArtifact} instance method.
501
+ *
502
+ * @remarks
503
+ * Duck-typed; does not use `instanceof SpooledArtifact`. Used by the `Tool.artifactConstructor`
504
+ * resolver validator and any other site that needs to recognise a `SpooledArtifact`-like
505
+ * constructor without pulling the class into its module-load graph.
506
+ *
507
+ * @param value - The value to test.
508
+ * @returns `true` when `value` is a `SpooledArtifact`-shaped constructor.
509
+ */
510
+ var implementsSpooledArtifactConstructor = (value) => {
511
+ return require_exceptions.passesSchema(spooledArtifactConstructorSchema, value);
512
+ };
513
+ /**
514
+ * Creates the validator fragment for a resolver returning a spooled-artifact constructor.
515
+ *
516
+ * The resolver is invoked during validation, then its result is checked with the canonical
517
+ * cross-realm-safe constructor guard. Keeping this fragment here makes `Tool` and `Retrievable`
518
+ * share exactly the same validation behaviour.
519
+ */
520
+ var artifactConstructorResolverSchema = () => _nhtio_validation.validator.any().custom((value, helpers) => {
521
+ if (typeof value !== "function") return helpers.error("any.invalid");
522
+ let resolved;
523
+ try {
524
+ resolved = value();
525
+ } catch {
526
+ return helpers.error("any.invalid");
527
+ }
528
+ return implementsSpooledArtifactConstructor(resolved) ? value : helpers.error("any.invalid");
529
+ });
530
+ //#endregion
531
+ //#region src/lib/classes/tool.ts
532
+ /**
533
+ * Validator schema for a {@link RawTool}.
534
+ */
535
+ var rawToolSchema = _nhtio_validation.validator.object({
530
536
  name: _nhtio_validation.validator.string().required(),
531
537
  description: _nhtio_validation.validator.string().required(),
532
538
  inputSchema: _nhtio_validation.validator.any().custom((value, helpers) => {
@@ -534,404 +540,398 @@ var rawArtifactToolSchema = _nhtio_validation.validator.object({
534
540
  return helpers.error("any.invalid");
535
541
  }).required(),
536
542
  handler: _nhtio_validation.validator.function().required(),
543
+ artifactConstructor: artifactConstructorResolverSchema().optional(),
537
544
  meta: _nhtio_validation.validator.object().pattern(_nhtio_validation.validator.string(), _nhtio_validation.validator.any()).default({}),
538
545
  ephemeral: _nhtio_validation.validator.boolean().default(false),
539
546
  trusted: _nhtio_validation.validator.boolean().default(false),
540
- onCollision: _nhtio_validation.validator.string().valid("throw", "replace", "keep").default("throw"),
541
- artifactConstructor: _nhtio_validation.validator.any().forbidden()
547
+ onCollision: _nhtio_validation.validator.string().valid("throw", "replace", "keep").default("throw")
542
548
  });
543
549
  /**
544
- * A {@link @nhtio/adk!Tool} subclass whose handler return value is wrapped directly in a
545
- * {@link @nhtio/adk!Tokenizable} (not a {@link @nhtio/adk!SpooledArtifact}) when it
546
- * lands on `ToolCall.results`.
547
- *
548
- * @remarks
549
- * `ArtifactTool` is the canonical producer for **forged artifact-query tools** — the tools
550
- * `SpooledArtifact.forgeTools(ctx)` emits so the model can `head`, `tail`, `grep`, `json_get`,
551
- * `md_headings` (etc.) an artifact that is already in `ctx.turnToolCalls`.
552
- *
553
- * The difference from {@link @nhtio/adk!Tool} is structural, not stylistic:
554
- *
555
- * - A normal `Tool`'s handler returns bytes the ADK wraps in a fresh `SpooledArtifact`.
556
- * The artifact lands in `ToolCall.results`, joins `ctx.turnToolCalls`, and is itself a
557
- * first-class queryable artifact in the turn.
558
- * - An `ArtifactTool`'s handler returns a string that is **already the model-visible answer**
559
- * to a query against an existing artifact. The ADK wraps it in a `Tokenizable` rather
560
- * than a `SpooledArtifact`; nothing new is queryable on its own. Subsequent
561
- * `forgeTools(ctx)` calls exclude `ToolCall`s produced by an `ArtifactTool` from the
562
- * `callId` enum (via the `ToolCall.fromArtifactTool` marker) — this is the structural fix
563
- * that breaks the otherwise-recursive grep-on-the-grep-result loop.
550
+ * A tool definition that serves as the single source of truth for a callable tool: its name,
551
+ * description, input schema, execution handler, and the {@link @nhtio/adk!SpooledArtifact} subclass that
552
+ * wraps its serialised output.
564
553
  *
565
- * Consumers who want to build their own artifact-query tools (e.g. for a domain-specific
566
- * spooled subclass not shipped by the ADK) should extend or instantiate this class.
567
- */
568
- var ArtifactTool = class ArtifactTool extends Tool {
569
- /**
570
- * Validator schema that accepts a {@link RawArtifactTool} object.
571
- *
572
- * @remarks
573
- * Differs from {@link @nhtio/adk!Tool.schema} by forbidding `artifactConstructor` — wrapping is
574
- * exactly the thing this class opts out of. Typed identically to {@link @nhtio/adk!Tool.schema} so the
575
- * subclass relationship `class ArtifactTool extends Tool` remains structurally sound; the
576
- * runtime validation rules still differ as declared by `rawArtifactToolSchema`.
577
- */
578
- static schema = rawArtifactToolSchema;
579
- /**
580
- * Returns `true` if `value` is an {@link ArtifactTool} instance.
581
- *
582
- * @remarks
583
- * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety — `instanceof` would fail for instances
584
- * created in a different module copy or VM context.
585
- *
586
- * @param value - The value to test.
587
- * @returns `true` when `value` is an {@link ArtifactTool} instance.
588
- */
589
- static isArtifactTool(value) {
590
- return require_guards.isInstanceOf(value, "ArtifactTool", ArtifactTool);
591
- }
592
- /**
593
- * @param raw - Raw tool input validated against {@link ArtifactTool.schema}.
594
- *
595
- * @throws {@link @nhtio/adk!E_INVALID_INITIAL_TOOL_VALUE} when `raw` does not satisfy
596
- * {@link ArtifactTool.schema} (most commonly, when `artifactConstructor` is supplied — it is
597
- * explicitly forbidden on this class) or when the base {@link @nhtio/adk!Tool} constructor rejects the
598
- * input for any reason.
599
- */
600
- constructor(raw) {
601
- try {
602
- require_exceptions.validateOrThrow(rawArtifactToolSchema, raw, true);
603
- } catch (err) {
604
- if (require_guards.isInstanceOf(err, "ValidationException", require_exceptions.ValidationException)) throw new require_tokenizable.E_INVALID_INITIAL_TOOL_VALUE({ cause: err });
605
- throw err;
606
- }
607
- super(raw);
608
- }
609
- /**
610
- * Serialise this ArtifactTool into an `@nhtio/encoder` snapshot.
611
- *
612
- * @remarks
613
- * Reuses the base {@link Tool.[ENCODE_METHOD]} (function-serialised `handler`, validation-encoded
614
- * `inputSchema`, plain config) and strips `artifactConstructor` — which {@link ArtifactTool.schema}
615
- * forbids. The handler's closure caveat from {@link Tool.[ENCODE_METHOD]} applies here too.
616
- *
617
- * @returns A {@link RawArtifactTool}-shaped snapshot (with `inputSchema` as an encoded string).
618
- */
619
- [require_tokenizable.ENCODE_METHOD]() {
620
- const base = super[require_tokenizable.ENCODE_METHOD]();
621
- delete base.artifactConstructor;
622
- return base;
623
- }
624
- /**
625
- * Reconstruct an {@link ArtifactTool} from an {@link ArtifactTool.[ENCODE_METHOD]} snapshot.
626
- *
627
- * @param data - The snapshot produced by {@link ArtifactTool.[ENCODE_METHOD]}.
628
- * @returns A fully-validated {@link ArtifactTool}.
629
- */
630
- static [require_tokenizable.DECODE_METHOD](data) {
631
- const snapshot = data;
632
- return new ArtifactTool({
633
- ...snapshot,
634
- inputSchema: (0, _nhtio_validation.decode)(snapshot.inputSchema)
635
- });
636
- }
637
- };
638
- //#endregion
639
- //#region src/lib/classes/tool_registry.ts
640
- /**
641
- * A mutable, turn-scoped collection of {@link @nhtio/adk!Tool} instances.
554
+ * @typeParam A - The {@link @nhtio/adk!SpooledArtifact} subtype this tool's results should be wrapped in.
555
+ * Defaults to {@link @nhtio/adk!SpooledArtifact}.
642
556
  *
643
557
  * @remarks
644
- * Each `TurnRunner.run()` call constructs a fresh `ToolRegistry` from the runner's configured
645
- * baseline tools, so middleware edits are isolated to the current turn and cannot bleed across
646
- * concurrent or subsequent turns.
647
- *
648
- * `Tool` instances are immutable, so `all()` returns a fresh array without deep-cloning.
558
+ * The `inputSchema` is a `@nhtio/validation` schema. It is used at runtime to validate incoming
559
+ * arguments before the handler is called, and its `.describe()` output provides all the metadata
560
+ * needed to build a provider-specific LLM tool definition — annotate the schema with
561
+ * `.description()`, `.note()`, `.example()` etc. once, and that information is available in both
562
+ * contexts without duplication.
649
563
  *
650
- * `register()` throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} if a tool with the same name is already
651
- * present — pass `overwrite: true` to replace it explicitly.
564
+ * The handler is private — invoke it only through `executor(ctx)` which validates args, fires
565
+ * observability events (with a stable `callId` derived from the tool name and arguments), and
566
+ * wraps handler errors in {@link @nhtio/adk!E_TOOL_DOWNSTREAM_ERROR}. The handler returns serialised bytes
567
+ * (`string | Uint8Array`); persistence is the consumer's responsibility.
652
568
  *
653
- * Tools can be **hidden** — registered and callable, but excluded from the default tool list
654
- * rendered to the model. This is useful for discovery patterns where an agent has a tool that
655
- * enumerates available tools, and the model picks one to call by name in a subsequent iteration.
656
- * Hidden state is a property of the registry, not the tool: the same tool can be visible in one
657
- * registry and hidden in another. See {@link hide}, {@link visible}, {@link hidden}.
569
+ * `artifactConstructor` is the {@link @nhtio/adk!SpooledArtifact} subclass the consumer should use when
570
+ * wrapping the handler's output into a `ToolCall.results` field. The author declares it once
571
+ * on the tool instance; the consumer reads it when assembling persisted records.
658
572
  */
659
- var ToolRegistry = class ToolRegistry {
660
- #tools;
661
- #hidden;
662
- /**
663
- * Returns `true` if `value` is a {@link ToolRegistry} instance.
664
- *
665
- * @param value - The value to test.
666
- * @returns `true` when `value` is a {@link ToolRegistry} instance.
667
- */
668
- static isToolRegistry(value) {
669
- return require_guards.isInstanceOf(value, "ToolRegistry", ToolRegistry);
670
- }
671
- /**
672
- * @param tools - Optional initial tools. Insertion order is preserved. Duplicate names throw
673
- * {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} — ensure each tool has a unique name.
674
- * @throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} when two tools in `tools` share a name.
675
- */
676
- constructor(tools) {
677
- this.#tools = /* @__PURE__ */ new Map();
678
- this.#hidden = /* @__PURE__ */ new Set();
679
- for (const tool of tools ?? []) this.register(tool);
680
- }
681
- /**
682
- * Adds a tool to the registry.
683
- *
684
- * @param tool - The tool to register.
685
- * @param overwrite - When `true`, silently replaces an existing tool with the same name.
686
- * Defaults to `false`.
687
- * @throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} when a tool with the same name is already registered
688
- * and `overwrite` is not `true`.
689
- */
690
- register(tool, overwrite) {
691
- if (this.#tools.has(tool.name) && !overwrite) throw new require_tokenizable.E_TOOL_ALREADY_REGISTERED();
692
- this.#tools.set(tool.name, tool);
693
- }
573
+ var Tool = class Tool {
694
574
  /**
695
- * Removes the tool with the given name from the registry.
575
+ * Validator schema that accepts a {@link RawTool} object.
696
576
  *
697
577
  * @remarks
698
- * Also removes the name from the hidden set if present. No-ops if no tool with that name is
699
- * registered.
700
- *
701
- * @param name - The name of the tool to remove.
578
+ * Reusable fragment for any schema that needs to validate or nest a tool entry
579
+ * (e.g. `TurnRunnerConfig.tools`).
702
580
  */
703
- unregister(name) {
704
- this.#tools.delete(name);
705
- this.#hidden.delete(name);
706
- }
581
+ static schema = rawToolSchema;
707
582
  /**
708
- * Returns the tool registered under `name`, or `undefined` if not present.
583
+ * Returns `true` if `value` is a {@link Tool} instance.
709
584
  *
710
- * @param name - The tool name to look up.
585
+ * @param value - The value to test.
586
+ * @returns `true` when `value` is a {@link Tool} instance.
711
587
  */
712
- get(name) {
713
- return this.#tools.get(name);
588
+ static isTool(value) {
589
+ return require_guards.isInstanceOf(value, "Tool", Tool);
714
590
  }
591
+ #name;
592
+ #description;
593
+ #inputSchema;
594
+ #handler;
595
+ #artifactConstructor;
596
+ #meta;
597
+ #ephemeral;
598
+ #trusted;
599
+ #onCollision;
715
600
  /**
716
- * Returns `true` if a tool with the given name is registered.
717
- *
718
- * @param name - The tool name to test.
601
+ * @param raw - The raw tool input validated against `rawToolSchema`.
602
+ * @throws {@link @nhtio/adk!E_INVALID_INITIAL_TOOL_VALUE} when `raw` does not satisfy the schema.
719
603
  */
720
- has(name) {
721
- return this.#tools.has(name);
604
+ constructor(raw) {
605
+ let resolved;
606
+ try {
607
+ resolved = require_exceptions.validateOrThrow(rawToolSchema, raw, true);
608
+ } catch (err) {
609
+ throw new require_tokenizable.E_INVALID_INITIAL_TOOL_VALUE({ cause: require_guards.isError(err) ? err : void 0 });
610
+ }
611
+ this.#name = resolved.name;
612
+ this.#description = resolved.description;
613
+ this.#inputSchema = resolved.inputSchema;
614
+ this.#handler = resolved.handler;
615
+ this.#artifactConstructor = resolved.artifactConstructor;
616
+ this.#meta = new Registry(resolved.meta);
617
+ this.#ephemeral = resolved.ephemeral;
618
+ this.#trusted = resolved.trusted;
619
+ this.#onCollision = resolved.onCollision;
620
+ Object.defineProperties(this, {
621
+ name: {
622
+ get: () => this.#name,
623
+ enumerable: true,
624
+ configurable: false
625
+ },
626
+ description: {
627
+ get: () => this.#description,
628
+ enumerable: true,
629
+ configurable: false
630
+ },
631
+ inputSchema: {
632
+ get: () => this.#inputSchema,
633
+ enumerable: true,
634
+ configurable: false
635
+ },
636
+ artifactConstructor: {
637
+ get: () => this.#artifactConstructor,
638
+ enumerable: true,
639
+ configurable: false
640
+ },
641
+ meta: {
642
+ get: () => this.#meta,
643
+ enumerable: true,
644
+ configurable: false
645
+ },
646
+ ephemeral: {
647
+ get: () => this.#ephemeral,
648
+ enumerable: true,
649
+ configurable: false
650
+ },
651
+ trusted: {
652
+ get: () => this.#trusted,
653
+ enumerable: true,
654
+ configurable: false
655
+ },
656
+ onCollision: {
657
+ get: () => this.#onCollision,
658
+ enumerable: true,
659
+ configurable: false
660
+ }
661
+ });
722
662
  }
723
663
  /**
724
- * Returns a fresh array of all registered tools in insertion order.
664
+ * Validates `args` against the tool's input schema asynchronously.
725
665
  *
726
666
  * @remarks
727
- * Includes both visible and hidden tools. Use {@link visible} to get only non-hidden tools, or
728
- * {@link hidden} to get only hidden tools.
667
+ * Async to support schemas with external validators (e.g. database lookups, API calls).
668
+ * A validation failure throws {@link @nhtio/adk!E_INVALID_TOOL_ARGS} — this indicates a programming error
669
+ * in the tool call loop, not a downstream failure.
729
670
  *
730
- * Since {@link @nhtio/adk!Tool} instances are immutable, no deep-cloning is needed.
671
+ * @param args - The arguments to validate.
672
+ * @returns The validated (and coerced) arguments.
673
+ * @throws {@link @nhtio/adk!E_INVALID_TOOL_ARGS} when `args` does not satisfy the input schema.
731
674
  */
732
- all() {
733
- return Array.from(this.#tools.values());
675
+ async validate(args) {
676
+ try {
677
+ return await require_exceptions.asyncValidateOrThrow(this.#inputSchema, args);
678
+ } catch (err) {
679
+ if (require_guards.isInstanceOf(err, "ValidationException", require_exceptions.ValidationException)) throw new require_tokenizable.E_INVALID_TOOL_ARGS({ cause: err });
680
+ throw err;
681
+ }
734
682
  }
735
683
  /**
736
- * Returns a fresh array of registered tools that are **not** hidden, in insertion order.
684
+ * Returns a bound executor function for this tool against the given turn context.
737
685
  *
738
686
  * @remarks
739
- * This is the accessor LLM batteries should use when building the tool list for the model.
740
- * Hidden tools are still callable (they resolve via {@link get}) but are excluded from the
741
- * rendered tool definitions.
742
- */
743
- visible() {
744
- return this.all().filter((t) => !this.#hidden.has(t.name));
745
- }
746
- /**
747
- * Returns a fresh array of registered tools that **are** hidden, in insertion order.
687
+ * The executor: (1) computes a stable `callId` as `sha256(canonicalStringify({tool, args}))`
688
+ * over the **raw, pre-validation args**, (2) validates `args` via {@link Tool.validate},
689
+ * (3) emits `toolExecutionStart` on the context (with the computed `callId`), (4) calls the
690
+ * handler, (5) emits `toolExecutionEnd` (with the same `callId`), (6) wraps any handler error
691
+ * in {@link @nhtio/adk!E_TOOL_DOWNSTREAM_ERROR} before re-throwing.
748
692
  *
749
- * @remarks
750
- * The converse of {@link visible}. Useful for discovery tools that enumerate all available
751
- * tools, and for propagating hidden state across {@link merge}.
693
+ * The handler usually returns serialised bytes (`string | Uint8Array`) — persistence is then the
694
+ * consumer's concern, and {@link Tool.artifactConstructor} is the class a wrap-site uses when
695
+ * wrapping those bytes into a `ToolCall.results` field. **A handler may instead return a
696
+ * {@link @nhtio/adk!SpooledArtifact} it built itself** (streaming into storage and wrapping the
697
+ * reader), in which case wrap-sites pass it through untouched and `artifactConstructor` does not
698
+ * apply — the returned instance's own class is what artifact-tool forging reads.
699
+ *
700
+ * Pattern mirrors `Middleware.runner()` — call once per turn, reuse the returned function.
701
+ *
702
+ * @param ctx - The active turn context. Provides emit functions and turn ID.
703
+ * @returns An async function `(args) => Promise<string | Uint8Array | SpooledArtifact | Media | Media[]>`.
704
+ * A `SpooledArtifact` is a result the HANDLER built (streamed to storage and wrapped itself); a
705
+ * wrap-site passes it through unwrapped rather than re-spooling it. `string`/`Uint8Array` are the
706
+ * opposite case — bytes the consumer must still store and wrap.
752
707
  */
753
- hidden() {
754
- return this.all().filter((t) => this.#hidden.has(t.name));
708
+ executor(ctx) {
709
+ return async (args) => {
710
+ const callId = (0, js_sha256.sha256)(canonicalStringify({
711
+ tool: this.#name,
712
+ args
713
+ }));
714
+ const validatedArgs = await this.validate(args);
715
+ const startedAt = luxon.DateTime.now();
716
+ ctx.emitToolExecutionStart({
717
+ toolName: this.#name,
718
+ turnId: ctx.id,
719
+ callId,
720
+ args: validatedArgs,
721
+ startedAt
722
+ });
723
+ try {
724
+ const result = await this.#handler(validatedArgs, ctx, this.#meta);
725
+ const endedAt = luxon.DateTime.now();
726
+ ctx.emitToolExecutionEnd({
727
+ toolName: this.#name,
728
+ turnId: ctx.id,
729
+ callId,
730
+ startedAt,
731
+ endedAt,
732
+ durationMs: endedAt.diff(startedAt).milliseconds,
733
+ isError: false
734
+ });
735
+ return result;
736
+ } catch (err) {
737
+ const endedAt = luxon.DateTime.now();
738
+ ctx.emitToolExecutionEnd({
739
+ toolName: this.#name,
740
+ turnId: ctx.id,
741
+ callId,
742
+ startedAt,
743
+ endedAt,
744
+ durationMs: endedAt.diff(startedAt).milliseconds,
745
+ isError: true
746
+ });
747
+ throw new require_tokenizable.E_TOOL_DOWNSTREAM_ERROR({ cause: require_guards.isError(err) ? err : void 0 });
748
+ }
749
+ };
755
750
  }
756
751
  /**
757
- * Marks one or more registered tools as hidden.
752
+ * Returns a fully serialisable snapshot of this tool's definition.
758
753
  *
759
754
  * @remarks
760
- * Hidden tools remain registered and callable via {@link get}, but are excluded from
761
- * {@link visible} (and therefore from the LLM tool list). No-ops for any name that is not
762
- * currently registered — the end result (the tool is not visible) matches the intent.
755
+ * The `inputSchema` property is the result of calling `.describe()` on the raw schema — a plain
756
+ * object carrying all the annotation metadata (descriptions, notes, examples, types) without any
757
+ * validator functions. Use this to build provider-specific LLM tool definitions.
763
758
  *
764
- * @param names - One or more tool names to hide.
759
+ * @returns `{ name, description, inputSchema }` where `inputSchema` is the schema description.
765
760
  */
766
- hide(...names) {
767
- for (const name of names) this.#hidden.add(name);
761
+ describe() {
762
+ return {
763
+ name: this.#name,
764
+ description: this.#description,
765
+ inputSchema: this.#inputSchema.describe()
766
+ };
768
767
  }
769
768
  /**
770
- * Unmarks one or more tools as hidden, making them visible again.
769
+ * Serialise this Tool into an `@nhtio/encoder` snapshot.
771
770
  *
772
771
  * @remarks
773
- * No-ops for any name that is not currently hidden.
772
+ * Three halves with different serialisation strategies:
774
773
  *
775
- * @param names - One or more tool names to unhide.
774
+ * - **Plain config** (`name`, `description`, `meta`, flags) — emitted verbatim.
775
+ * - **`inputSchema`** — delegated to `@nhtio/validation`'s `encode()`, which captures the full schema
776
+ * description plus its library version into a compact string; decode rebuilds the live `Schema`.
777
+ * - **`handler` / `artifactConstructor`** — emitted as **functions**. The encoder's `FunctionSerializer`
778
+ * serialises them by **source text** (`fn.toString()`). This is the sharp edge: a handler that
779
+ * closes over `ctx`, service clients, or config loses those bindings on decode — only the source
780
+ * survives, and the captured variables read back as `undefined`. A `.bind()`-ed or native handler
781
+ * cannot be serialised at all and the encoder throws. Tools are rarely serialised in practice; when
782
+ * they are, write handlers that reconstruct their dependencies inside the body rather than closing
783
+ * over them.
784
+ *
785
+ * @returns A {@link RawTool}-shaped snapshot (with `inputSchema` as an encoded string).
776
786
  */
777
- unhide(...names) {
778
- for (const name of names) this.#hidden.delete(name);
787
+ [require_tokenizable.ENCODE_METHOD]() {
788
+ return {
789
+ name: this.#name,
790
+ description: this.#description,
791
+ inputSchema: (0, _nhtio_validation.encode)(this.#inputSchema),
792
+ handler: this.#handler,
793
+ artifactConstructor: this.#artifactConstructor,
794
+ meta: this.#meta.all(),
795
+ ephemeral: this.#ephemeral,
796
+ trusted: this.#trusted,
797
+ onCollision: this.#onCollision
798
+ };
779
799
  }
780
800
  /**
781
- * Replaces the entire hidden set with the given tool names.
801
+ * Reconstruct a {@link Tool} from a {@link Tool.[ENCODE_METHOD]} snapshot.
782
802
  *
783
803
  * @remarks
784
- * Any previously hidden tool not in `names` becomes visible. Names that are not registered are
785
- * silently ignored — they are added to the set but have no effect until a tool with that name
786
- * is registered.
804
+ * Rebuilds the live `Schema` via `@nhtio/validation`'s `decode()`, then re-validates through the
805
+ * constructor. The rehydrated `handler` carries only its source text — see
806
+ * {@link Tool.[ENCODE_METHOD]} for the closure caveat.
787
807
  *
788
- * @param names - The complete set of tool names to hide.
789
- */
790
- setHidden(...names) {
791
- this.#hidden = new Set(names);
792
- }
793
- /**
794
- * Unhides every tool in the registry.
808
+ * @param data - The snapshot produced by {@link Tool.[ENCODE_METHOD]}.
809
+ * @returns A fully-validated {@link Tool}.
795
810
  */
796
- clearHidden() {
797
- this.#hidden.clear();
811
+ static [require_tokenizable.DECODE_METHOD](data) {
812
+ const snapshot = data;
813
+ return new Tool({
814
+ ...snapshot,
815
+ inputSchema: (0, _nhtio_validation.decode)(snapshot.inputSchema)
816
+ });
798
817
  }
818
+ };
819
+ //#endregion
820
+ //#region src/lib/classes/artifact_tool.ts
821
+ /**
822
+ * Validator schema for a {@link RawArtifactTool}.
823
+ *
824
+ * @remarks
825
+ * Mirrors the base tool schema but explicitly forbids `artifactConstructor` — the entire
826
+ * point of `ArtifactTool` is to opt out of `SpooledArtifact` wrapping.
827
+ */
828
+ var rawArtifactToolSchema = _nhtio_validation.validator.object({
829
+ name: _nhtio_validation.validator.string().required(),
830
+ description: _nhtio_validation.validator.string().required(),
831
+ inputSchema: _nhtio_validation.validator.any().custom((value, helpers) => {
832
+ if (_nhtio_validation.validator.isSchema(value) && value.type === "object") return value;
833
+ return helpers.error("any.invalid");
834
+ }).required(),
835
+ handler: _nhtio_validation.validator.function().required(),
836
+ meta: _nhtio_validation.validator.object().pattern(_nhtio_validation.validator.string(), _nhtio_validation.validator.any()).default({}),
837
+ ephemeral: _nhtio_validation.validator.boolean().default(false),
838
+ trusted: _nhtio_validation.validator.boolean().default(false),
839
+ onCollision: _nhtio_validation.validator.string().valid("throw", "replace", "keep").default("throw"),
840
+ artifactConstructor: _nhtio_validation.validator.any().forbidden()
841
+ });
842
+ /**
843
+ * A {@link @nhtio/adk!Tool} subclass whose handler return value is wrapped directly in a
844
+ * {@link @nhtio/adk!Tokenizable} (not a {@link @nhtio/adk!SpooledArtifact}) when it
845
+ * lands on `ToolCall.results`.
846
+ *
847
+ * @remarks
848
+ * `ArtifactTool` is the canonical producer for **forged artifact-query tools** — the tools
849
+ * `SpooledArtifact.forgeTools(ctx)` emits so the model can `head`, `tail`, `grep`, `json_get`,
850
+ * `md_headings` (etc.) an artifact that is already in `ctx.turnToolCalls`.
851
+ *
852
+ * The difference from {@link @nhtio/adk!Tool} is structural, not stylistic:
853
+ *
854
+ * - A normal `Tool`'s handler returns bytes the ADK wraps in a fresh `SpooledArtifact`.
855
+ * The artifact lands in `ToolCall.results`, joins `ctx.turnToolCalls`, and is itself a
856
+ * first-class queryable artifact in the turn.
857
+ * - An `ArtifactTool`'s handler returns a string that is **already the model-visible answer**
858
+ * to a query against an existing artifact. The ADK wraps it in a `Tokenizable` rather
859
+ * than a `SpooledArtifact`; nothing new is queryable on its own. Subsequent
860
+ * `forgeTools(ctx)` calls exclude `ToolCall`s produced by an `ArtifactTool` from the
861
+ * `callId` enum (via the `ToolCall.fromArtifactTool` marker) — this is the structural fix
862
+ * that breaks the otherwise-recursive grep-on-the-grep-result loop.
863
+ *
864
+ * Consumers who want to build their own artifact-query tools (e.g. for a domain-specific
865
+ * spooled subclass not shipped by the ADK) should extend or instantiate this class.
866
+ */
867
+ var ArtifactTool = class ArtifactTool extends Tool {
799
868
  /**
800
- * Removes every tool whose {@link @nhtio/adk!Tool.ephemeral} flag is `true`.
869
+ * Validator schema that accepts a {@link RawArtifactTool} object.
801
870
  *
802
871
  * @remarks
803
- * Also removes pruned tool names from the hidden set. Synchronous and idempotent — calling it
804
- * twice in a row is a no-op the second time. The canonical caller is
805
- * {@link ToolRegistry.bindContext}, which schedules this method to run at
806
- * {@link @nhtio/adk!DispatchContext.ack}. Non-ephemeral tools are left untouched.
872
+ * Differs from {@link @nhtio/adk!Tool.schema} by forbidding `artifactConstructor` — wrapping is
873
+ * exactly the thing this class opts out of. Typed identically to {@link @nhtio/adk!Tool.schema} so the
874
+ * subclass relationship `class ArtifactTool extends Tool` remains structurally sound; the
875
+ * runtime validation rules still differ as declared by `rawArtifactToolSchema`.
807
876
  */
808
- pruneEphemeral() {
809
- for (const [name, tool] of this.#tools) if (tool.ephemeral) {
810
- this.#tools.delete(name);
811
- this.#hidden.delete(name);
812
- }
813
- }
877
+ static schema = rawArtifactToolSchema;
814
878
  /**
815
- * Binds this registry to a {@link @nhtio/adk!DispatchContext} so that {@link pruneEphemeral} runs
816
- * automatically when the context is acked.
879
+ * Returns `true` if `value` is an {@link ArtifactTool} instance.
817
880
  *
818
881
  * @remarks
819
- * The handler does NOT fire on {@link @nhtio/adk!DispatchContext.nack} — failed executor runs leave
820
- * any forged tools in place so the consumer can inspect what was registered when debugging the
821
- * failure. Subscriptions are short-lived and die with the context regardless.
822
- *
823
- * ARTIFACT READERS ARE FORGED BY THE CORE. As of the core-forge change, the `DispatchRunner` forges
824
- * artifact-reader tools from prior-turn `SpooledArtifact` results into `ctx.tools` (and calls
825
- * `ctx.tools.bindContext(ctx)`) once per iteration, BEFORE the input pipeline — so a battery executor no
826
- * longer forges or binds; it reads the already-forged `ctx.tools` for both representation (rendering the
827
- * tool declarations) and resolution (looking up an incoming call by name). The lifecycle is unchanged:
828
- * ephemeral readers are still pruned on `ack`, and the core re-forges each iteration (prune-then-forge) so
829
- * the `callId` enum never goes stale.
830
- *
831
- * `bindContext` remains the public seam for a CUSTOM consumer that forges its own ephemeral tools outside
832
- * the core path. If you forge into a long-lived registry yourself, bind it (or prune manually) or the
833
- * ephemeral tools accumulate and later `forgeTools(ctx)` calls see a stale `callId` enum. The pattern for a
834
- * hand-rolled forge is:
835
- *
836
- * ```ts
837
- * // Custom forge (the core already does this for artifact readers on ctx.tools):
838
- * const forged = SpooledArtifact.forgeTools(ctx)
839
- * for (const tool of forged.all()) ctx.tools.register(tool, true)
840
- * ctx.tools.bindContext(ctx) // prune the ephemeral readers when the dispatch acks
841
- * ```
842
- *
843
- * @param ctx - The execution context whose `ack` event should trigger pruning.
844
- * @returns An unsubscribe function — calling it before `ctx.ack()` prevents pruning. Rarely
845
- * useful outside of tests.
882
+ * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety — `instanceof` would fail for instances
883
+ * created in a different module copy or VM context.
846
884
  *
847
- * @see {@link @nhtio/adk!SpooledArtifact.forgeTools}
848
- * @see {@link @nhtio/adk!DispatchContext.onAck}
885
+ * @param value - The value to test.
886
+ * @returns `true` when `value` is an {@link ArtifactTool} instance.
849
887
  */
850
- bindContext(ctx) {
851
- return ctx.onAck(() => this.pruneEphemeral());
888
+ static isArtifactTool(value) {
889
+ return require_guards.isInstanceOf(value, "ArtifactTool", ArtifactTool);
852
890
  }
853
891
  /**
854
- * Combines multiple {@link ToolRegistry} instances into a fresh registry without mutating any
855
- * input.
856
- *
857
- * @remarks
858
- * Iteration is left-to-right across `registries` and then in each registry's insertion order.
859
- * Collisions are resolved by consulting the **incoming** tool's {@link @nhtio/adk!Tool.onCollision} first:
860
- *
861
- * - `'replace'` (per-tool): the incoming tool wins, replacing the existing entry.
862
- * - `'keep'` (per-tool): the existing entry wins; the incoming tool is dropped.
863
- * - `'throw'` (per-tool, the default): fall back to the merge-level `options.onCollision`.
864
- *
865
- * The merge-level `options.onCollision` defaults to `'throw'`, which mirrors {@link register}.
866
- *
867
- * The result is a brand-new registry; no input is mutated and no event subscription is
868
- * propagated. Each `Tool`'s `ephemeral` flag carries through unchanged — the flag lives on the
869
- * tool, not the registry, so `bindContext(ctx)` on the merged registry will prune the forged
870
- * tools as expected.
871
- *
872
- * Hidden state is also propagated: a tool that is hidden in any source registry remains hidden
873
- * in the merged result, provided it survives collision resolution.
892
+ * @param raw - Raw tool input validated against {@link ArtifactTool.schema}.
874
893
  *
875
- * @param registries - Registries to merge, in priority order (left-to-right insertion).
876
- * @param options - Merge-level collision policy. Defaults to `{ onCollision: 'throw' }`.
877
- * @returns A fresh {@link ToolRegistry} containing the resolved union of all inputs.
878
- * @throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} when the resolved collision policy is `'throw'`
879
- * and a collision occurs.
894
+ * @throws {@link @nhtio/adk!E_INVALID_INITIAL_TOOL_VALUE} when `raw` does not satisfy
895
+ * {@link ArtifactTool.schema} (most commonly, when `artifactConstructor` is supplied — it is
896
+ * explicitly forbidden on this class) or when the base {@link @nhtio/adk!Tool} constructor rejects the
897
+ * input for any reason.
880
898
  */
881
- static merge(registries, options) {
882
- const policy = options?.onCollision ?? "throw";
883
- const merged = new ToolRegistry();
884
- for (const registry of registries) {
885
- for (const tool of registry.all()) {
886
- if (!merged.get(tool.name)) {
887
- merged.register(tool);
888
- continue;
889
- }
890
- const incomingPolicy = tool.onCollision;
891
- if (incomingPolicy === "replace") {
892
- merged.register(tool, true);
893
- continue;
894
- }
895
- if (incomingPolicy === "keep") continue;
896
- if (policy === "replace") {
897
- merged.register(tool, true);
898
- continue;
899
- }
900
- if (policy === "keep") continue;
901
- throw new require_tokenizable.E_TOOL_ALREADY_REGISTERED();
902
- }
903
- for (const tool of registry.hidden()) if (merged.has(tool.name)) merged.hide(tool.name);
899
+ constructor(raw) {
900
+ try {
901
+ require_exceptions.validateOrThrow(rawArtifactToolSchema, raw, true);
902
+ } catch (err) {
903
+ if (require_guards.isInstanceOf(err, "ValidationException", require_exceptions.ValidationException)) throw new require_tokenizable.E_INVALID_INITIAL_TOOL_VALUE({ cause: err });
904
+ throw err;
904
905
  }
905
- return merged;
906
+ super(raw);
906
907
  }
907
908
  /**
908
- * Serialise this ToolRegistry into an `@nhtio/encoder` snapshot.
909
+ * Serialise this ArtifactTool into an `@nhtio/encoder` snapshot.
909
910
  *
910
911
  * @remarks
911
- * Emits the live {@link @nhtio/adk!Tool} instances (the encoder recurses into each — so every tool's
912
- * handler-closure caveat from {@link Tool.[ENCODE_METHOD]} applies) plus the hidden-set names. Both
913
- * {@link @nhtio/adk!Tool} and {@link @nhtio/adk!ArtifactTool} entries round-trip to their correct
914
- * subtype. Round-trips via {@link ToolRegistry.[DECODE_METHOD]}.
912
+ * Reuses the base {@link Tool.[ENCODE_METHOD]} (function-serialised `handler`, validation-encoded
913
+ * `inputSchema`, plain config) and strips `artifactConstructor` — which {@link ArtifactTool.schema}
914
+ * forbids. The handler's closure caveat from {@link Tool.[ENCODE_METHOD]} applies here too.
915
915
  *
916
- * @returns A `{ tools, hidden }` snapshot.
916
+ * @returns A {@link RawArtifactTool}-shaped snapshot (with `inputSchema` as an encoded string).
917
917
  */
918
918
  [require_tokenizable.ENCODE_METHOD]() {
919
- return {
920
- tools: this.all(),
921
- hidden: this.hidden().map((tool) => tool.name)
922
- };
919
+ const base = super[require_tokenizable.ENCODE_METHOD]();
920
+ delete base.artifactConstructor;
921
+ return base;
923
922
  }
924
923
  /**
925
- * Reconstruct a {@link ToolRegistry} from a {@link ToolRegistry.[ENCODE_METHOD]} snapshot.
924
+ * Reconstruct an {@link ArtifactTool} from an {@link ArtifactTool.[ENCODE_METHOD]} snapshot.
926
925
  *
927
- * @param data - The snapshot produced by {@link ToolRegistry.[ENCODE_METHOD]}.
928
- * @returns A fresh {@link ToolRegistry} with the same tools and hidden set.
926
+ * @param data - The snapshot produced by {@link ArtifactTool.[ENCODE_METHOD]}.
927
+ * @returns A fully-validated {@link ArtifactTool}.
929
928
  */
930
929
  static [require_tokenizable.DECODE_METHOD](data) {
931
930
  const snapshot = data;
932
- const registry = new ToolRegistry(snapshot.tools);
933
- registry.setHidden(...snapshot.hidden);
934
- return registry;
931
+ return new ArtifactTool({
932
+ ...snapshot,
933
+ inputSchema: (0, _nhtio_validation.decode)(snapshot.inputSchema)
934
+ });
935
935
  }
936
936
  };
937
937
  //#endregion
@@ -1727,4 +1727,4 @@ Object.defineProperty(exports, "resolveSpoolReader", {
1727
1727
  }
1728
1728
  });
1729
1729
 
1730
- //# sourceMappingURL=spooled_artifact-BpcesRBv.js.map
1730
+ //# sourceMappingURL=spooled_artifact-CFjf6ULg.cjs.map