@nhtio/adk 1.20260925.0 → 1.20260928.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 (332) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/artifact_methods-Cg0go7Q4.mjs +1 -0
  3. package/artifact_methods-CxeKTocm.cjs +1 -0
  4. package/batteries/artifacts/ecmascript.cjs +1 -1
  5. package/batteries/artifacts/ecmascript.mjs +1 -1
  6. package/batteries/artifacts/toon.cjs +1 -1
  7. package/batteries/artifacts/toon.mjs +1 -1
  8. package/batteries/artifacts/xml.cjs +1 -1
  9. package/batteries/artifacts/xml.mjs +1 -1
  10. package/batteries/artifacts/yaml.cjs +1 -1
  11. package/batteries/artifacts/yaml.mjs +1 -1
  12. package/batteries/artifacts.cjs +4 -4
  13. package/batteries/artifacts.mjs +4 -4
  14. package/batteries/dev-tools/forge.cjs +3 -3
  15. package/batteries/dev-tools/forge.mjs +3 -3
  16. package/batteries/dev-tools.cjs +3 -3
  17. package/batteries/dev-tools.mjs +3 -3
  18. package/batteries/encoding.cjs +7 -7
  19. package/batteries/encoding.mjs +7 -7
  20. package/batteries/generation/gemini/adapter.cjs +1 -1
  21. package/batteries/generation/gemini/adapter.mjs +1 -1
  22. package/batteries/generation/local_diffusion/adapter.cjs +1 -1
  23. package/batteries/generation/local_diffusion/adapter.mjs +1 -1
  24. package/batteries/generation/openai/adapter.cjs +1 -1
  25. package/batteries/generation/openai/adapter.mjs +1 -1
  26. package/batteries/isolation/child_process.cjs +1 -1
  27. package/batteries/isolation/child_process.mjs +1 -1
  28. package/batteries/isolation.cjs +1 -1
  29. package/batteries/isolation.mjs +1 -1
  30. package/batteries/llm/anthropic_messages/adapter.cjs +6 -6
  31. package/batteries/llm/anthropic_messages/adapter.mjs +6 -6
  32. package/batteries/llm/anthropic_messages/count_tokens.cjs +1 -1
  33. package/batteries/llm/anthropic_messages/count_tokens.mjs +1 -1
  34. package/batteries/llm/anthropic_messages/helpers.cjs +3 -3
  35. package/batteries/llm/anthropic_messages/helpers.mjs +3 -3
  36. package/batteries/llm/anthropic_messages/validation.cjs +2 -2
  37. package/batteries/llm/anthropic_messages/validation.mjs +2 -2
  38. package/batteries/llm/anthropic_messages.cjs +2 -2
  39. package/batteries/llm/anthropic_messages.mjs +2 -2
  40. package/batteries/llm/bedrock_converse/adapter.cjs +6 -6
  41. package/batteries/llm/bedrock_converse/adapter.mjs +6 -6
  42. package/batteries/llm/bedrock_converse/helpers.cjs +1 -1
  43. package/batteries/llm/bedrock_converse/helpers.mjs +1 -1
  44. package/batteries/llm/bedrock_converse/validation.cjs +2 -2
  45. package/batteries/llm/bedrock_converse/validation.mjs +2 -2
  46. package/batteries/llm/bedrock_converse.cjs +2 -2
  47. package/batteries/llm/bedrock_converse.mjs +2 -2
  48. package/batteries/llm/claude_code_cli/adapter.cjs +7 -7
  49. package/batteries/llm/claude_code_cli/adapter.mjs +7 -7
  50. package/batteries/llm/claude_code_cli/helpers.cjs +3 -3
  51. package/batteries/llm/claude_code_cli/helpers.mjs +3 -3
  52. package/batteries/llm/claude_code_cli/validation.cjs +2 -2
  53. package/batteries/llm/claude_code_cli/validation.mjs +2 -2
  54. package/batteries/llm/claude_code_cli.cjs +2 -2
  55. package/batteries/llm/claude_code_cli.mjs +2 -2
  56. package/batteries/llm/gemini_generate_content/adapter.cjs +6 -6
  57. package/batteries/llm/gemini_generate_content/adapter.mjs +6 -6
  58. package/batteries/llm/gemini_generate_content/helpers.cjs +1 -1
  59. package/batteries/llm/gemini_generate_content/helpers.mjs +1 -1
  60. package/batteries/llm/gemini_generate_content/validation.cjs +2 -2
  61. package/batteries/llm/gemini_generate_content/validation.mjs +2 -2
  62. package/batteries/llm/gemini_generate_content.cjs +1 -1
  63. package/batteries/llm/gemini_generate_content.mjs +1 -1
  64. package/batteries/llm/litert_lm/adapter.cjs +6 -6
  65. package/batteries/llm/litert_lm/adapter.mjs +6 -6
  66. package/batteries/llm/litert_lm/helpers.cjs +3 -3
  67. package/batteries/llm/litert_lm/helpers.mjs +3 -3
  68. package/batteries/llm/litert_lm/validation.cjs +2 -2
  69. package/batteries/llm/litert_lm/validation.mjs +2 -2
  70. package/batteries/llm/litert_lm.cjs +1 -1
  71. package/batteries/llm/litert_lm.mjs +1 -1
  72. package/batteries/llm/ollama/adapter.cjs +6 -6
  73. package/batteries/llm/ollama/adapter.mjs +6 -6
  74. package/batteries/llm/ollama/helpers.cjs +4 -4
  75. package/batteries/llm/ollama/helpers.mjs +4 -4
  76. package/batteries/llm/ollama/validation.cjs +2 -2
  77. package/batteries/llm/ollama/validation.mjs +2 -2
  78. package/batteries/llm/ollama.cjs +2 -2
  79. package/batteries/llm/ollama.mjs +2 -2
  80. package/batteries/llm/openai_chat_completions/adapter.cjs +6 -6
  81. package/batteries/llm/openai_chat_completions/adapter.mjs +6 -6
  82. package/batteries/llm/openai_chat_completions/helpers.cjs +4 -4
  83. package/batteries/llm/openai_chat_completions/helpers.mjs +4 -4
  84. package/batteries/llm/openai_chat_completions/validation.cjs +2 -2
  85. package/batteries/llm/openai_chat_completions/validation.mjs +2 -2
  86. package/batteries/llm/openai_chat_completions.cjs +2 -2
  87. package/batteries/llm/openai_chat_completions.mjs +2 -2
  88. package/batteries/llm/openai_responses/adapter.cjs +6 -6
  89. package/batteries/llm/openai_responses/adapter.mjs +6 -6
  90. package/batteries/llm/openai_responses/helpers.cjs +3 -3
  91. package/batteries/llm/openai_responses/helpers.mjs +3 -3
  92. package/batteries/llm/openai_responses/validation.cjs +2 -2
  93. package/batteries/llm/openai_responses/validation.mjs +2 -2
  94. package/batteries/llm/openai_responses.cjs +2 -2
  95. package/batteries/llm/openai_responses.mjs +2 -2
  96. package/batteries/llm/transformers_js/adapter.cjs +6 -6
  97. package/batteries/llm/transformers_js/adapter.mjs +6 -6
  98. package/batteries/llm/transformers_js/helpers.cjs +3 -3
  99. package/batteries/llm/transformers_js/helpers.mjs +3 -3
  100. package/batteries/llm/transformers_js/validation.cjs +2 -2
  101. package/batteries/llm/transformers_js/validation.mjs +2 -2
  102. package/batteries/llm/transformers_js.cjs +1 -1
  103. package/batteries/llm/transformers_js.mjs +1 -1
  104. package/batteries/llm/webllm_chat_completions/adapter.cjs +6 -6
  105. package/batteries/llm/webllm_chat_completions/adapter.mjs +6 -6
  106. package/batteries/llm/webllm_chat_completions/helpers.cjs +1 -1
  107. package/batteries/llm/webllm_chat_completions/helpers.mjs +1 -1
  108. package/batteries/llm/webllm_chat_completions/validation.cjs +2 -2
  109. package/batteries/llm/webllm_chat_completions/validation.mjs +2 -2
  110. package/batteries/llm/webllm_chat_completions.cjs +2 -2
  111. package/batteries/llm/webllm_chat_completions.mjs +2 -2
  112. package/batteries/llm.cjs +2 -2
  113. package/batteries/llm.mjs +2 -2
  114. package/batteries/media/forge.cjs +4 -4
  115. package/batteries/media/forge.mjs +4 -4
  116. package/batteries/media/lint.cjs +1 -1
  117. package/batteries/media/lint.mjs +1 -1
  118. package/batteries/orchestration/cells/jexl.cjs +1 -1
  119. package/batteries/orchestration/cells/jexl.mjs +1 -1
  120. package/batteries/orchestration/cells/lua.cjs +1 -1
  121. package/batteries/orchestration/cells/lua.mjs +1 -1
  122. package/batteries/orchestration/cells/structured.cjs +1 -1
  123. package/batteries/orchestration/cells/structured.mjs +1 -1
  124. package/batteries/orchestration/dispatch_reasoner.cjs +4 -4
  125. package/batteries/orchestration/dispatch_reasoner.mjs +4 -4
  126. package/batteries/orchestration/executor.cjs +2 -2
  127. package/batteries/orchestration/executor.mjs +2 -2
  128. package/batteries/orchestration/forge.cjs +3 -3
  129. package/batteries/orchestration/forge.mjs +3 -3
  130. package/batteries/orchestration/validation.cjs +2 -2
  131. package/batteries/orchestration/validation.mjs +2 -2
  132. package/batteries/orchestration.cjs +3 -3
  133. package/batteries/orchestration.mjs +3 -3
  134. package/batteries/sandbox/js.cjs +1 -1
  135. package/batteries/sandbox/js.mjs +1 -1
  136. package/batteries/sandbox/tools.cjs +1 -1
  137. package/batteries/sandbox/tools.mjs +1 -1
  138. package/batteries/sandbox.cjs +4 -4
  139. package/batteries/sandbox.mjs +4 -4
  140. package/batteries/skills/in_memory.cjs +1 -1
  141. package/batteries/skills/in_memory.mjs +1 -1
  142. package/batteries/skills.cjs +9 -9
  143. package/batteries/skills.mjs +9 -9
  144. package/batteries/specialists/stt/transformers_js.cjs +1 -1
  145. package/batteries/specialists/stt/transformers_js.mjs +1 -1
  146. package/batteries/specialists/stt.cjs +1 -1
  147. package/batteries/specialists/stt.mjs +1 -1
  148. package/batteries/specialists.cjs +1 -1
  149. package/batteries/specialists.mjs +1 -1
  150. package/batteries/tools/_shared.cjs +2 -2
  151. package/batteries/tools/_shared.mjs +2 -2
  152. package/batteries/tools/color.cjs +2 -2
  153. package/batteries/tools/color.mjs +2 -2
  154. package/batteries/tools/comparison.cjs +2 -2
  155. package/batteries/tools/comparison.mjs +2 -2
  156. package/batteries/tools/data_structure.cjs +2 -2
  157. package/batteries/tools/data_structure.mjs +2 -2
  158. package/batteries/tools/datetime_extended.cjs +2 -2
  159. package/batteries/tools/datetime_extended.mjs +2 -2
  160. package/batteries/tools/datetime_math.cjs +2 -2
  161. package/batteries/tools/datetime_math.mjs +2 -2
  162. package/batteries/tools/encoding.cjs +2 -2
  163. package/batteries/tools/encoding.mjs +2 -2
  164. package/batteries/tools/formatting.cjs +2 -2
  165. package/batteries/tools/formatting.mjs +2 -2
  166. package/batteries/tools/geo_basics.cjs +2 -2
  167. package/batteries/tools/geo_basics.mjs +2 -2
  168. package/batteries/tools/math.cjs +2 -2
  169. package/batteries/tools/math.mjs +2 -2
  170. package/batteries/tools/memory.cjs +4 -4
  171. package/batteries/tools/memory.mjs +4 -4
  172. package/batteries/tools/parsing.cjs +3 -3
  173. package/batteries/tools/parsing.mjs +3 -3
  174. package/batteries/tools/retrievables.cjs +4 -4
  175. package/batteries/tools/retrievables.mjs +4 -4
  176. package/batteries/tools/scrapper.cjs +1 -1
  177. package/batteries/tools/scrapper.mjs +1 -1
  178. package/batteries/tools/searxng.cjs +1 -1
  179. package/batteries/tools/searxng.mjs +1 -1
  180. package/batteries/tools/standing_instructions.cjs +3 -3
  181. package/batteries/tools/standing_instructions.mjs +3 -3
  182. package/batteries/tools/statistics.cjs +3 -3
  183. package/batteries/tools/statistics.mjs +3 -3
  184. package/batteries/tools/string_processing.cjs +2 -2
  185. package/batteries/tools/string_processing.mjs +2 -2
  186. package/batteries/tools/structured_data.cjs +2 -2
  187. package/batteries/tools/structured_data.mjs +2 -2
  188. package/batteries/tools/text_analysis.cjs +3 -3
  189. package/batteries/tools/text_analysis.mjs +3 -3
  190. package/batteries/tools/text_comparison.cjs +2 -2
  191. package/batteries/tools/text_comparison.mjs +2 -2
  192. package/batteries/tools/time.cjs +2 -2
  193. package/batteries/tools/time.mjs +2 -2
  194. package/batteries/tools/unit_conversion.cjs +2 -2
  195. package/batteries/tools/unit_conversion.mjs +2 -2
  196. package/batteries/tools.cjs +2 -2
  197. package/batteries/tools.mjs +2 -2
  198. package/batteries/validation.cjs +5 -5
  199. package/batteries/validation.mjs +5 -5
  200. package/batteries/vector/conformance.cjs +59 -0
  201. package/batteries/vector/conformance.cjs.map +1 -1
  202. package/batteries/vector/conformance.mjs +59 -0
  203. package/batteries/vector/conformance.mjs.map +1 -1
  204. package/batteries/vector/lancedb.cjs +1 -1
  205. package/batteries/vector/lancedb.cjs.map +1 -1
  206. package/batteries/vector/lancedb.mjs +1 -1
  207. package/batteries/vector/lancedb.mjs.map +1 -1
  208. package/batteries/vector/retrievable.cjs +1 -1
  209. package/batteries/vector/retrievable.mjs +1 -1
  210. package/batteries/vector/sqlite_vec/index.d.ts +1 -1
  211. package/batteries/vector/sqlite_vec.cjs +19 -30
  212. package/batteries/vector/sqlite_vec.cjs.map +1 -1
  213. package/batteries/vector/sqlite_vec.mjs +20 -31
  214. package/batteries/vector/sqlite_vec.mjs.map +1 -1
  215. package/batteries.cjs +6 -6
  216. package/batteries.mjs +6 -6
  217. package/{chat_common-4huaTp6d.cjs → chat_common-CNayzS1V.cjs} +2 -2
  218. package/{chat_common-4huaTp6d.cjs.map → chat_common-CNayzS1V.cjs.map} +1 -1
  219. package/{chat_common-D_XGNjcK.mjs → chat_common-DKw8FDol.mjs} +2 -2
  220. package/{chat_common-D_XGNjcK.mjs.map → chat_common-DKw8FDol.mjs.map} +1 -1
  221. package/{common-BiRzOsxe.cjs → common-CqetsItm.cjs} +7 -7
  222. package/{common-BiRzOsxe.cjs.map → common-CqetsItm.cjs.map} +1 -1
  223. package/{common-DsLvTGmm.mjs → common-oI1niK9Z.mjs} +7 -7
  224. package/{common-DsLvTGmm.mjs.map → common-oI1niK9Z.mjs.map} +1 -1
  225. package/common.cjs +7 -7
  226. package/common.mjs +7 -7
  227. package/{dispatch_runner-DDH_dGPU.mjs → dispatch_runner-BZDXUe0G.mjs} +4 -4
  228. package/{dispatch_runner-DDH_dGPU.mjs.map → dispatch_runner-BZDXUe0G.mjs.map} +1 -1
  229. package/{dispatch_runner-C5S3KCqH.cjs → dispatch_runner-DDUxXJC3.cjs} +4 -4
  230. package/{dispatch_runner-C5S3KCqH.cjs.map → dispatch_runner-DDUxXJC3.cjs.map} +1 -1
  231. package/dispatch_runner.cjs +1 -1
  232. package/dispatch_runner.mjs +1 -1
  233. package/{ecmascript-CWLZ7bCX.mjs → ecmascript-B9Z2C24U.mjs} +5 -5
  234. package/{ecmascript-CWLZ7bCX.mjs.map → ecmascript-B9Z2C24U.mjs.map} +1 -1
  235. package/{ecmascript-BGr_0Dwn.cjs → ecmascript-BYfmjg7y.cjs} +5 -5
  236. package/{ecmascript-BGr_0Dwn.cjs.map → ecmascript-BYfmjg7y.cjs.map} +1 -1
  237. package/eslint/rules.cjs +1 -1
  238. package/eslint/rules.mjs +1 -1
  239. package/eslint.cjs +3 -3
  240. package/eslint.mjs +3 -3
  241. package/exceptions.cjs +1 -1
  242. package/exceptions.mjs +1 -1
  243. package/forge.cjs +2 -2
  244. package/forge.mjs +2 -2
  245. package/guards.cjs +7 -7
  246. package/guards.mjs +7 -7
  247. package/{helpers-BPi_iwxv.cjs → helpers-DPlh_7Bn.cjs} +3 -3
  248. package/{helpers-BPi_iwxv.cjs.map → helpers-DPlh_7Bn.cjs.map} +1 -1
  249. package/{helpers-D47G8WQb.mjs → helpers-mbn_EsDV.mjs} +3 -3
  250. package/{helpers-D47G8WQb.mjs.map → helpers-mbn_EsDV.mjs.map} +1 -1
  251. package/index.cjs +11 -11
  252. package/index.mjs +11 -11
  253. package/{isolation-B2FgKbap.cjs → isolation-B01xCIoV.cjs} +2 -2
  254. package/{isolation-B2FgKbap.cjs.map → isolation-B01xCIoV.cjs.map} +1 -1
  255. package/{isolation-BRGpiU-K.mjs → isolation-CO0NiK8R.mjs} +2 -2
  256. package/{isolation-BRGpiU-K.mjs.map → isolation-CO0NiK8R.mjs.map} +1 -1
  257. package/{manifest-B5bWMHgj.mjs → manifest-D8UTRohY.mjs} +2 -2
  258. package/{manifest-B5bWMHgj.mjs.map → manifest-D8UTRohY.mjs.map} +1 -1
  259. package/{manifest-Chjh-3s1.cjs → manifest-IP1IOJcg.cjs} +2 -2
  260. package/{manifest-Chjh-3s1.cjs.map → manifest-IP1IOJcg.cjs.map} +1 -1
  261. package/mcp/adk-docs-corpus.json +2 -2
  262. package/package.json +538 -538
  263. package/{predicates-C9jl2QPZ.cjs → predicates-Bzaa7gNI.cjs} +2 -2
  264. package/{predicates-C9jl2QPZ.cjs.map → predicates-Bzaa7gNI.cjs.map} +1 -1
  265. package/{predicates-2dZQ82LY.mjs → predicates-CM27Z3TF.mjs} +2 -2
  266. package/{predicates-2dZQ82LY.mjs.map → predicates-CM27Z3TF.mjs.map} +1 -1
  267. package/{retrievable-ReauMJxJ.cjs → retrievable-Bq-O3k6r.cjs} +3 -3
  268. package/{retrievable-ReauMJxJ.cjs.map → retrievable-Bq-O3k6r.cjs.map} +1 -1
  269. package/{retrievable-mFgC1aty.mjs → retrievable-CXTAUuuv.mjs} +3 -3
  270. package/{retrievable-mFgC1aty.mjs.map → retrievable-CXTAUuuv.mjs.map} +1 -1
  271. package/{scrapper-BsEY0Wo6.cjs → scrapper-B8xG9lTD.cjs} +5 -5
  272. package/{scrapper-BsEY0Wo6.cjs.map → scrapper-B8xG9lTD.cjs.map} +1 -1
  273. package/{scrapper-bShwZxKP.mjs → scrapper-DiQ5FfDL.mjs} +5 -5
  274. package/{scrapper-bShwZxKP.mjs.map → scrapper-DiQ5FfDL.mjs.map} +1 -1
  275. package/{searxng-CAY-bOMl.mjs → searxng-BFTJ6rTE.mjs} +5 -5
  276. package/{searxng-CAY-bOMl.mjs.map → searxng-BFTJ6rTE.mjs.map} +1 -1
  277. package/{searxng-CLF0vBMT.cjs → searxng-EJhWRnIE.cjs} +5 -5
  278. package/{searxng-CLF0vBMT.cjs.map → searxng-EJhWRnIE.cjs.map} +1 -1
  279. package/server.json +2 -2
  280. package/skills/adk-assembly/SKILL.md +2 -2
  281. package/{spooled_artifact-CFjf6ULg.cjs → spooled_artifact---DmicFW.cjs} +384 -384
  282. package/spooled_artifact---DmicFW.cjs.map +1 -0
  283. package/{spooled_artifact-B710Rb0d.mjs → spooled_artifact-Bw_7swIp.mjs} +385 -385
  284. package/spooled_artifact-Bw_7swIp.mjs.map +1 -0
  285. package/spooled_artifact.cjs +2 -2
  286. package/spooled_artifact.mjs +2 -2
  287. package/{spooled_markdown_artifact-PWppwnPQ.cjs → spooled_markdown_artifact-Rjzj-kyh.cjs} +3 -3
  288. package/{spooled_markdown_artifact-PWppwnPQ.cjs.map → spooled_markdown_artifact-Rjzj-kyh.cjs.map} +1 -1
  289. package/{spooled_markdown_artifact-1C4mmi73.mjs → spooled_markdown_artifact-vd6eNtIP.mjs} +3 -3
  290. package/{spooled_markdown_artifact-1C4mmi73.mjs.map → spooled_markdown_artifact-vd6eNtIP.mjs.map} +1 -1
  291. package/{thought-BKXwUZoq.mjs → thought-CxSaF6Xf.mjs} +3 -3
  292. package/{thought-BKXwUZoq.mjs.map → thought-CxSaF6Xf.mjs.map} +1 -1
  293. package/{thought-D5fJsxBW.cjs → thought-Dp3sMWW6.cjs} +3 -3
  294. package/{thought-D5fJsxBW.cjs.map → thought-Dp3sMWW6.cjs.map} +1 -1
  295. package/{tokenizable-DDIdXbJN.cjs → tokenizable-BcodRtoW.cjs} +29 -29
  296. package/{tokenizable-DDIdXbJN.cjs.map → tokenizable-BcodRtoW.cjs.map} +1 -1
  297. package/{tokenizable-xPXj1AQX.mjs → tokenizable-VB4Av8GF.mjs} +30 -30
  298. package/{tokenizable-xPXj1AQX.mjs.map → tokenizable-VB4Av8GF.mjs.map} +1 -1
  299. package/{tool_call-CDV5pW13.cjs → tool_call-B9px4W9k.cjs} +3 -3
  300. package/{tool_call-CDV5pW13.cjs.map → tool_call-B9px4W9k.cjs.map} +1 -1
  301. package/{tool_call-D-LqMvpU.mjs → tool_call-Cfaj-6zK.mjs} +3 -3
  302. package/{tool_call-D-LqMvpU.mjs.map → tool_call-Cfaj-6zK.mjs.map} +1 -1
  303. package/{tools-CvCMdAd7.mjs → tools-D0MBDh2R.mjs} +6 -6
  304. package/{tools-CvCMdAd7.mjs.map → tools-D0MBDh2R.mjs.map} +1 -1
  305. package/{tools-CACuuMV4.cjs → tools-aNbi6JyA.cjs} +6 -6
  306. package/{tools-CACuuMV4.cjs.map → tools-aNbi6JyA.cjs.map} +1 -1
  307. package/{toon-CCjuuzd_.mjs → toon-BSTQnHed.mjs} +6 -6
  308. package/{toon-CCjuuzd_.mjs.map → toon-BSTQnHed.mjs.map} +1 -1
  309. package/{toon-B7Q9RWJF.cjs → toon-DmLwZ6H1.cjs} +6 -6
  310. package/{toon-B7Q9RWJF.cjs.map → toon-DmLwZ6H1.cjs.map} +1 -1
  311. package/{transformers_js-DM01eAzh.cjs → transformers_js-7OzeS_Tp.cjs} +2 -2
  312. package/{transformers_js-DM01eAzh.cjs.map → transformers_js-7OzeS_Tp.cjs.map} +1 -1
  313. package/{transformers_js-BR2Ov0Su.mjs → transformers_js-p3lAkHFH.mjs} +2 -2
  314. package/{transformers_js-BR2Ov0Su.mjs.map → transformers_js-p3lAkHFH.mjs.map} +1 -1
  315. package/{turn_runner-BgPw9uqb.mjs → turn_runner-BHHD6h77.mjs} +4 -4
  316. package/{turn_runner-BgPw9uqb.mjs.map → turn_runner-BHHD6h77.mjs.map} +1 -1
  317. package/{turn_runner-CP2zxSlu.cjs → turn_runner-Dj7JsUTQ.cjs} +4 -4
  318. package/{turn_runner-CP2zxSlu.cjs.map → turn_runner-Dj7JsUTQ.cjs.map} +1 -1
  319. package/turn_runner.cjs +1 -1
  320. package/turn_runner.mjs +1 -1
  321. package/{xml-BqTTIFhv.mjs → xml-CYseDztH.mjs} +6 -6
  322. package/{xml-BqTTIFhv.mjs.map → xml-CYseDztH.mjs.map} +1 -1
  323. package/{xml-viE54OTe.cjs → xml-zJul8jMQ.cjs} +6 -6
  324. package/{xml-viE54OTe.cjs.map → xml-zJul8jMQ.cjs.map} +1 -1
  325. package/{yaml-B1So-pUR.mjs → yaml-BPBoiOjx.mjs} +6 -6
  326. package/{yaml-B1So-pUR.mjs.map → yaml-BPBoiOjx.mjs.map} +1 -1
  327. package/{yaml-cGhhPyZq.cjs → yaml-D0PzoRAr.cjs} +6 -6
  328. package/{yaml-cGhhPyZq.cjs.map → yaml-D0PzoRAr.cjs.map} +1 -1
  329. package/artifact_methods-9BemAvd4.mjs +0 -1
  330. package/artifact_methods-FKgk4q_1.cjs +0 -1
  331. package/spooled_artifact-B710Rb0d.mjs.map +0 -1
  332. package/spooled_artifact-CFjf6ULg.cjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"spooled_artifact-CFjf6ULg.cjs","names":["#tools","#hidden","#store","#name","#description","#inputSchema","#handler","#artifactConstructor","#meta","#ephemeral","#trusted","#onCollision","#reader","#sizeHints"],"sources":["../src/lib/classes/tool_registry.ts","../src/lib/utils/canonical_json.ts","../src/lib/classes/registry.ts","../src/lib/contracts/spooled_artifact_constructor.ts","../src/lib/classes/tool.ts","../src/lib/classes/artifact_tool.ts","../src/lib/contracts/spool_reader.ts","../src/lib/contracts/reader_resolvers.ts","../src/lib/classes/spooled_artifact.ts"],"sourcesContent":["import { isInstanceOf } from '../utils/guards'\nimport { E_TOOL_ALREADY_REGISTERED } from '../exceptions/runtime'\nimport { ENCODE_METHOD, DECODE_METHOD } from '../utils/encoder_symbols'\nimport type { Tool } from './tool'\nimport type { AdkEncodableSnapshot } from './encodable'\nimport type { DispatchContext } from '../contracts/dispatch_context'\n\n/**\n * Options accepted by {@link ToolRegistry.merge}.\n */\nexport interface MergeOptions {\n /**\n * What to do when two registries contain a tool with the same name AND neither tool's own\n * `onCollision` resolves the collision.\n *\n * @remarks\n * - `'throw'` (default): raise {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} on the first unresolved\n * collision. Mirrors the default behaviour of {@link ToolRegistry.register} and surfaces\n * accidental name shadowing immediately.\n * - `'replace'`: the later registry's tool wins.\n * - `'keep'`: the earlier registry's tool wins; later occurrences are dropped.\n *\n * Per-tool {@link @nhtio/adk!Tool.onCollision} takes precedence: if the incoming tool declares\n * `'replace'` or `'keep'`, that policy wins regardless of this option. Only when the incoming\n * tool's policy is `'throw'` (the default) does this fallback apply.\n *\n * @defaultValue `'throw'`\n */\n onCollision?: 'throw' | 'replace' | 'keep'\n}\n\n/**\n * A mutable, turn-scoped collection of {@link @nhtio/adk!Tool} instances.\n *\n * @remarks\n * Each `TurnRunner.run()` call constructs a fresh `ToolRegistry` from the runner's configured\n * baseline tools, so middleware edits are isolated to the current turn and cannot bleed across\n * concurrent or subsequent turns.\n *\n * `Tool` instances are immutable, so `all()` returns a fresh array without deep-cloning.\n *\n * `register()` throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} if a tool with the same name is already\n * present — pass `overwrite: true` to replace it explicitly.\n *\n * Tools can be **hidden** — registered and callable, but excluded from the default tool list\n * rendered to the model. This is useful for discovery patterns where an agent has a tool that\n * enumerates available tools, and the model picks one to call by name in a subsequent iteration.\n * Hidden state is a property of the registry, not the tool: the same tool can be visible in one\n * registry and hidden in another. See {@link hide}, {@link visible}, {@link hidden}.\n */\nexport class ToolRegistry {\n #tools: Map<string, Tool>\n #hidden: Set<string>\n\n /**\n * Returns `true` if `value` is a {@link ToolRegistry} instance.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link ToolRegistry} instance.\n */\n public static isToolRegistry(value: unknown): value is ToolRegistry {\n return isInstanceOf(value, 'ToolRegistry', ToolRegistry)\n }\n\n /**\n * @param tools - Optional initial tools. Insertion order is preserved. Duplicate names throw\n * {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} — ensure each tool has a unique name.\n * @throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} when two tools in `tools` share a name.\n */\n constructor(tools?: Tool[]) {\n this.#tools = new Map()\n this.#hidden = new Set()\n for (const tool of tools ?? []) {\n this.register(tool)\n }\n }\n\n /**\n * Adds a tool to the registry.\n *\n * @param tool - The tool to register.\n * @param overwrite - When `true`, silently replaces an existing tool with the same name.\n * Defaults to `false`.\n * @throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} when a tool with the same name is already registered\n * and `overwrite` is not `true`.\n */\n register(tool: Tool, overwrite?: boolean): void {\n if (this.#tools.has(tool.name) && !overwrite) {\n throw new E_TOOL_ALREADY_REGISTERED()\n }\n this.#tools.set(tool.name, tool)\n }\n\n /**\n * Removes the tool with the given name from the registry.\n *\n * @remarks\n * Also removes the name from the hidden set if present. No-ops if no tool with that name is\n * registered.\n *\n * @param name - The name of the tool to remove.\n */\n unregister(name: string): void {\n this.#tools.delete(name)\n this.#hidden.delete(name)\n }\n\n /**\n * Returns the tool registered under `name`, or `undefined` if not present.\n *\n * @param name - The tool name to look up.\n */\n get(name: string): Tool | undefined {\n return this.#tools.get(name)\n }\n\n /**\n * Returns `true` if a tool with the given name is registered.\n *\n * @param name - The tool name to test.\n */\n has(name: string): boolean {\n return this.#tools.has(name)\n }\n\n /**\n * Returns a fresh array of all registered tools in insertion order.\n *\n * @remarks\n * Includes both visible and hidden tools. Use {@link visible} to get only non-hidden tools, or\n * {@link hidden} to get only hidden tools.\n *\n * Since {@link @nhtio/adk!Tool} instances are immutable, no deep-cloning is needed.\n */\n all(): Tool[] {\n return Array.from(this.#tools.values())\n }\n\n /**\n * Returns a fresh array of registered tools that are **not** hidden, in insertion order.\n *\n * @remarks\n * This is the accessor LLM batteries should use when building the tool list for the model.\n * Hidden tools are still callable (they resolve via {@link get}) but are excluded from the\n * rendered tool definitions.\n */\n visible(): Tool[] {\n return this.all().filter((t) => !this.#hidden.has(t.name))\n }\n\n /**\n * Returns a fresh array of registered tools that **are** hidden, in insertion order.\n *\n * @remarks\n * The converse of {@link visible}. Useful for discovery tools that enumerate all available\n * tools, and for propagating hidden state across {@link merge}.\n */\n hidden(): Tool[] {\n return this.all().filter((t) => this.#hidden.has(t.name))\n }\n\n /**\n * Marks one or more registered tools as hidden.\n *\n * @remarks\n * Hidden tools remain registered and callable via {@link get}, but are excluded from\n * {@link visible} (and therefore from the LLM tool list). No-ops for any name that is not\n * currently registered — the end result (the tool is not visible) matches the intent.\n *\n * @param names - One or more tool names to hide.\n */\n hide(...names: string[]): void {\n for (const name of names) {\n this.#hidden.add(name)\n }\n }\n\n /**\n * Unmarks one or more tools as hidden, making them visible again.\n *\n * @remarks\n * No-ops for any name that is not currently hidden.\n *\n * @param names - One or more tool names to unhide.\n */\n unhide(...names: string[]): void {\n for (const name of names) {\n this.#hidden.delete(name)\n }\n }\n\n /**\n * Replaces the entire hidden set with the given tool names.\n *\n * @remarks\n * Any previously hidden tool not in `names` becomes visible. Names that are not registered are\n * silently ignored — they are added to the set but have no effect until a tool with that name\n * is registered.\n *\n * @param names - The complete set of tool names to hide.\n */\n setHidden(...names: string[]): void {\n this.#hidden = new Set(names)\n }\n\n /**\n * Unhides every tool in the registry.\n */\n clearHidden(): void {\n this.#hidden.clear()\n }\n\n /**\n * Removes every tool whose {@link @nhtio/adk!Tool.ephemeral} flag is `true`.\n *\n * @remarks\n * Also removes pruned tool names from the hidden set. Synchronous and idempotent — calling it\n * twice in a row is a no-op the second time. The canonical caller is\n * {@link ToolRegistry.bindContext}, which schedules this method to run at\n * {@link @nhtio/adk!DispatchContext.ack}. Non-ephemeral tools are left untouched.\n */\n pruneEphemeral(): void {\n for (const [name, tool] of this.#tools) {\n if (tool.ephemeral) {\n this.#tools.delete(name)\n this.#hidden.delete(name)\n }\n }\n }\n\n /**\n * Binds this registry to a {@link @nhtio/adk!DispatchContext} so that {@link pruneEphemeral} runs\n * automatically when the context is acked.\n *\n * @remarks\n * The handler does NOT fire on {@link @nhtio/adk!DispatchContext.nack} — failed executor runs leave\n * any forged tools in place so the consumer can inspect what was registered when debugging the\n * failure. Subscriptions are short-lived and die with the context regardless.\n *\n * ARTIFACT READERS ARE FORGED BY THE CORE. As of the core-forge change, the `DispatchRunner` forges\n * artifact-reader tools from prior-turn `SpooledArtifact` results into `ctx.tools` (and calls\n * `ctx.tools.bindContext(ctx)`) once per iteration, BEFORE the input pipeline — so a battery executor no\n * longer forges or binds; it reads the already-forged `ctx.tools` for both representation (rendering the\n * tool declarations) and resolution (looking up an incoming call by name). The lifecycle is unchanged:\n * ephemeral readers are still pruned on `ack`, and the core re-forges each iteration (prune-then-forge) so\n * the `callId` enum never goes stale.\n *\n * `bindContext` remains the public seam for a CUSTOM consumer that forges its own ephemeral tools outside\n * the core path. If you forge into a long-lived registry yourself, bind it (or prune manually) or the\n * ephemeral tools accumulate and later `forgeTools(ctx)` calls see a stale `callId` enum. The pattern for a\n * hand-rolled forge is:\n *\n * ```ts\n * // Custom forge (the core already does this for artifact readers on ctx.tools):\n * const forged = SpooledArtifact.forgeTools(ctx)\n * for (const tool of forged.all()) ctx.tools.register(tool, true)\n * ctx.tools.bindContext(ctx) // prune the ephemeral readers when the dispatch acks\n * ```\n *\n * @param ctx - The execution context whose `ack` event should trigger pruning.\n * @returns An unsubscribe function — calling it before `ctx.ack()` prevents pruning. Rarely\n * useful outside of tests.\n *\n * @see {@link @nhtio/adk!SpooledArtifact.forgeTools}\n * @see {@link @nhtio/adk!DispatchContext.onAck}\n */\n bindContext(ctx: DispatchContext): () => void {\n return ctx.onAck(() => this.pruneEphemeral())\n }\n\n /**\n * Combines multiple {@link ToolRegistry} instances into a fresh registry without mutating any\n * input.\n *\n * @remarks\n * Iteration is left-to-right across `registries` and then in each registry's insertion order.\n * Collisions are resolved by consulting the **incoming** tool's {@link @nhtio/adk!Tool.onCollision} first:\n *\n * - `'replace'` (per-tool): the incoming tool wins, replacing the existing entry.\n * - `'keep'` (per-tool): the existing entry wins; the incoming tool is dropped.\n * - `'throw'` (per-tool, the default): fall back to the merge-level `options.onCollision`.\n *\n * The merge-level `options.onCollision` defaults to `'throw'`, which mirrors {@link register}.\n *\n * The result is a brand-new registry; no input is mutated and no event subscription is\n * propagated. Each `Tool`'s `ephemeral` flag carries through unchanged — the flag lives on the\n * tool, not the registry, so `bindContext(ctx)` on the merged registry will prune the forged\n * tools as expected.\n *\n * Hidden state is also propagated: a tool that is hidden in any source registry remains hidden\n * in the merged result, provided it survives collision resolution.\n *\n * @param registries - Registries to merge, in priority order (left-to-right insertion).\n * @param options - Merge-level collision policy. Defaults to `{ onCollision: 'throw' }`.\n * @returns A fresh {@link ToolRegistry} containing the resolved union of all inputs.\n * @throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} when the resolved collision policy is `'throw'`\n * and a collision occurs.\n */\n static merge(registries: ToolRegistry[], options?: MergeOptions): ToolRegistry {\n const policy = options?.onCollision ?? 'throw'\n const merged = new ToolRegistry()\n for (const registry of registries) {\n for (const tool of registry.all()) {\n const existing = merged.get(tool.name)\n if (!existing) {\n merged.register(tool)\n continue\n }\n const incomingPolicy = tool.onCollision\n if (incomingPolicy === 'replace') {\n merged.register(tool, true)\n continue\n }\n if (incomingPolicy === 'keep') {\n continue\n }\n // Incoming policy is 'throw' — fall back to the merge-level option.\n if (policy === 'replace') {\n merged.register(tool, true)\n continue\n }\n if (policy === 'keep') {\n continue\n }\n throw new E_TOOL_ALREADY_REGISTERED()\n }\n // Propagate hidden state: any tool that was hidden in a source registry stays hidden\n // in the merged result, as long as it survived collision resolution.\n for (const tool of registry.hidden()) {\n if (merged.has(tool.name)) {\n merged.hide(tool.name)\n }\n }\n }\n return merged\n }\n\n /**\n * Serialise this ToolRegistry into an `@nhtio/encoder` snapshot.\n *\n * @remarks\n * Emits the live {@link @nhtio/adk!Tool} instances (the encoder recurses into each — so every tool's\n * handler-closure caveat from {@link Tool.[ENCODE_METHOD]} applies) plus the hidden-set names. Both\n * {@link @nhtio/adk!Tool} and {@link @nhtio/adk!ArtifactTool} entries round-trip to their correct\n * subtype. Round-trips via {@link ToolRegistry.[DECODE_METHOD]}.\n *\n * @returns A `{ tools, hidden }` snapshot.\n */\n [ENCODE_METHOD](): AdkEncodableSnapshot {\n return {\n tools: this.all(),\n hidden: this.hidden().map((tool) => tool.name),\n }\n }\n\n /**\n * Reconstruct a {@link ToolRegistry} from a {@link ToolRegistry.[ENCODE_METHOD]} snapshot.\n *\n * @param data - The snapshot produced by {@link ToolRegistry.[ENCODE_METHOD]}.\n * @returns A fresh {@link ToolRegistry} with the same tools and hidden set.\n */\n static [DECODE_METHOD](data: AdkEncodableSnapshot): ToolRegistry {\n const snapshot = data as { tools: Tool[]; hidden: string[] }\n const registry = new ToolRegistry(snapshot.tools)\n registry.setHidden(...snapshot.hidden)\n return registry\n }\n}\n","/**\n * Canonical `JSON.stringify` that sorts object keys recursively so that semantically-equal\n * objects produce identical strings.\n *\n * @remarks\n * Used wherever the ADK derives a stable identity from a structured value — for example,\n * `Tool.executor` computing the `callId` for `ToolExecutionStart`/`End` events, and the\n * `reportToolCall` executor helper computing the `checksum` field on `TurnToolCallContent`.\n * Both code paths hash `canonicalStringify({ tool, args })` so that argument key order does not\n * affect the resulting identifier.\n *\n * Arrays are serialised in their declared order (order is meaningful for an array). Object keys\n * are sorted with `Array.prototype.sort()`'s default lexicographic comparator.\n *\n * @param value - The value to serialise.\n * @returns A canonical JSON string representation of `value`.\n */\nexport function canonicalStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return '[' + value.map((v) => canonicalStringify(v)).join(',') + ']'\n const obj = value as Record<string, unknown>\n const keys = Object.keys(obj).sort()\n return '{' + keys.map((k) => JSON.stringify(k) + ':' + canonicalStringify(obj[k])).join(',') + '}'\n}\n","import { dset } from 'dset'\nimport { klona } from 'klona'\nimport { default as delve } from 'dlv'\nimport { isInstanceOf, isObject } from '../utils/guards'\nimport { ENCODE_METHOD, DECODE_METHOD } from '../utils/encoder_symbols'\nimport { E_INVALID_INITIAL_REGISTRY_VALUE } from '../exceptions/runtime'\nimport type { AdkEncodableSnapshot } from './encodable'\n\n/**\n * A controlled-mutation key-value store with dot-path access and deep-clone isolation.\n *\n * @remarks\n * The registry enforces a safe read/write contract: callers never hold a live reference into\n * the internal store. Every value that enters (`set`) or leaves (`get`, `all`) is deep-cloned\n * via `klona`, so mutations to a retrieved value cannot affect stored state and vice versa.\n *\n * Keys are dot-delimited paths (e.g. `\"user.profile.name\"`), resolved via `dlv` for reads and\n * `dset` for writes; intermediate objects are created automatically on write.\n */\nexport class Registry {\n #store: Record<string, unknown>\n\n /**\n * @param initial - Optional plain object to seed the registry. Deep-cloned on construction.\n * @throws {@link @nhtio/adk!E_INVALID_INITIAL_REGISTRY_VALUE} when `initial` is defined but not a plain object.\n */\n constructor(initial?: Record<string, unknown>) {\n if ('undefined' !== typeof initial && !isObject(initial)) {\n throw new E_INVALID_INITIAL_REGISTRY_VALUE()\n }\n this.#store = initial ? klona(initial) : {}\n }\n\n /**\n * Returns `true` if `value` is a {@link Registry} instance.\n *\n * @remarks\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link Registry} instance.\n */\n public static isRegistry(value: unknown): value is Registry {\n return isInstanceOf(value, 'Registry', Registry)\n }\n\n /**\n * Retrieves the value at `key`, returning `defaultValue` if the path is absent.\n *\n * @remarks\n * The returned value is a deep clone — mutating it will not affect the stored state.\n *\n * @typeParam T - Expected type of the value at `key`.\n * @param key - Dot-delimited path into the store (e.g. `\"user.name\"`).\n * @param defaultValue - Fallback returned when the path resolves to `undefined`.\n * @returns A deep clone of the stored value cast to `T`, or `defaultValue` when the path is absent.\n */\n get<T = unknown>(key: string, defaultValue?: T): T {\n const cloned = klona(this.#store)\n const value = delve(cloned, key)\n return 'undefined' === typeof value ? (defaultValue as T) : (value as T)\n }\n\n /**\n * Sets the value at `key`, creating intermediate objects as needed.\n *\n * @remarks\n * The stored value is isolated from the caller — mutating `value` after this call will not\n * affect what is held in the registry.\n *\n * @param key - Dot-delimited path into the store (e.g. `\"user.name\"`).\n * @param value - Value to store at the path.\n */\n set(key: string, value: unknown): void {\n dset(this.#store, key, value)\n }\n\n /**\n * Returns `true` if the registry has a value at `key`, `false` otherwise.\n *\n * @remarks\n * A key resolving to `undefined` is treated as absent — same convention as {@link Registry.get}'s\n * `defaultValue` fallback. No clone is performed; this is a pure existence check.\n *\n * @param key - Dot-delimited path into the store (e.g. `\"user.name\"`).\n * @returns `true` when the path resolves to a value other than `undefined`.\n */\n has(key: string): boolean {\n return 'undefined' !== typeof delve(this.#store, key)\n }\n\n /**\n * Returns all leaf dot-paths present in the registry.\n *\n * @remarks\n * The store is deep-cloned before traversal. Plain objects are walked recursively with path\n * segments joined by dots; arrays, primitives, `null`, and class instances are treated as leaves.\n *\n * @returns A string array of dot-delimited paths to leaf values in the store.\n */\n keys(): string[] {\n const store = klona(this.#store)\n const keys: string[] = []\n\n const isPlainRecord = (value: unknown): value is Record<string, unknown> => {\n if (!isObject(value)) return false\n const prototype = Object.getPrototypeOf(value)\n return prototype === Object.prototype || prototype === null\n }\n\n const walk = (value: unknown, segments: string[]): void => {\n if (!isPlainRecord(value)) {\n if (segments.length > 0) keys.push(segments.join('.'))\n return\n }\n\n for (const [segment, child] of Object.entries(value)) {\n walk(child, [...segments, segment])\n }\n }\n\n walk(store, [])\n return keys\n }\n\n /**\n * Returns a deep clone of the entire store contents.\n *\n * @returns A plain object snapshot of all stored key-value pairs.\n */\n all(): Record<string, unknown> {\n return klona(this.#store)\n }\n\n /**\n * Serialise this Registry into an `@nhtio/encoder` snapshot.\n *\n * @remarks\n * The snapshot is a deep clone of the store ({@link Registry.all}). Leaf values that are themselves\n * registered encodable instances round-trip; anything the encoder cannot serialise throws at encode\n * time (standard encoder behaviour). Round-trips via {@link Registry.[DECODE_METHOD]}.\n *\n * @returns A deep-cloned plain-object snapshot of the store.\n */\n [ENCODE_METHOD](): AdkEncodableSnapshot {\n return this.all()\n }\n\n /**\n * Reconstruct a {@link Registry} from a {@link Registry.[ENCODE_METHOD]} snapshot.\n *\n * @param data - The store snapshot produced by {@link Registry.[ENCODE_METHOD]}.\n * @returns A fresh {@link Registry} seeded with the snapshot.\n */\n static [DECODE_METHOD](data: AdkEncodableSnapshot): Registry {\n return new Registry(data as Record<string, unknown>)\n }\n}\n","import { validator } from '@nhtio/validation'\nimport { passesSchema } from '../utils/validation'\nimport type { SpooledArtifact } from '../classes/spooled_artifact'\n\n/**\n * Constructor signature for any {@link @nhtio/adk!SpooledArtifact} (the class itself or a subclass).\n *\n * @remarks\n * Re-declared here at the contract level so consumers — and the `Tool.artifactConstructor`\n * resolver validator in particular — can talk about the constructor shape without value-importing\n * the {@link @nhtio/adk!SpooledArtifact} class (which would close the `tool.ts` ↔ `spooled_artifact.ts` ↔\n * `artifact_tool.ts` module cycle at load time and TDZ-crash `ArtifactTool extends Tool`).\n *\n * @typeParam A - The {@link @nhtio/adk!SpooledArtifact} subtype the constructor produces.\n */\nexport type SpooledArtifactConstructorLike<A extends SpooledArtifact = SpooledArtifact> = new (\n ...args: any[]\n) => A\n\nconst ARTIFACT_METHODS = [\n 'head',\n 'tail',\n 'grep',\n 'cat',\n 'byteLength',\n 'lineCount',\n 'estimateTokens',\n] as const\n\n/**\n * Validator schema used to validate a {@link SpooledArtifactConstructorLike} value.\n *\n * @remarks\n * Because the validator is invoked at validate-time (not at module-load), it is safe to inspect\n * the constructor's prototype here. The check is duck-typed: the value must be a function whose\n * `prototype` carries every canonical artifact instance method (`head`, `tail`, `grep`, `cat`,\n * `byteLength`, `lineCount`, `estimateTokens`). This mirrors {@link spoolReaderSchema}'s\n * cross-realm-safe duck-type pattern — `instanceof SpooledArtifact` would be tighter but would\n * force a value-import of the class and reopen the module cycle.\n */\nexport const spooledArtifactConstructorSchema = validator\n .any()\n .required()\n .custom((value, helpers) => {\n if (typeof value !== 'function') return helpers.error('any.invalid')\n const proto = (value as { prototype?: unknown }).prototype\n if (proto === undefined || proto === null) return helpers.error('any.invalid')\n if (\n ARTIFACT_METHODS.every((m) => typeof (proto as Record<string, unknown>)[m] === 'function')\n ) {\n return value\n }\n return helpers.error('any.invalid')\n })\n\n/**\n * Returns `true` if `value` is a constructor whose prototype carries every canonical\n * {@link @nhtio/adk!SpooledArtifact} instance method.\n *\n * @remarks\n * Duck-typed; does not use `instanceof SpooledArtifact`. Used by the `Tool.artifactConstructor`\n * resolver validator and any other site that needs to recognise a `SpooledArtifact`-like\n * constructor without pulling the class into its module-load graph.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a `SpooledArtifact`-shaped constructor.\n */\nexport const implementsSpooledArtifactConstructor = (\n value: unknown\n): value is SpooledArtifactConstructorLike => {\n return passesSchema(spooledArtifactConstructorSchema, value)\n}\n\n/**\n * Creates the validator fragment for a resolver returning a spooled-artifact constructor.\n *\n * The resolver is invoked during validation, then its result is checked with the canonical\n * cross-realm-safe constructor guard. Keeping this fragment here makes `Tool` and `Retrievable`\n * share exactly the same validation behaviour.\n */\nexport const artifactConstructorResolverSchema = () =>\n // eslint-disable-next-line adk/require-validator-any-required -- disposition is set by the caller's .optional()/.required() appended to this returned schema\n validator.any().custom((value, helpers) => {\n if (typeof value !== 'function') return helpers.error('any.invalid')\n let resolved: unknown\n try {\n resolved = (value as () => unknown)()\n } catch {\n return helpers.error('any.invalid')\n }\n return implementsSpooledArtifactConstructor(resolved) ? value : helpers.error('any.invalid')\n })\n","import { DateTime } from 'luxon'\nimport { sha256 } from 'js-sha256'\nimport { Registry } from './registry'\nimport { isInstanceOf, isError } from '../utils/guards'\nimport { canonicalStringify } from '../utils/canonical_json'\nimport { ENCODE_METHOD, DECODE_METHOD } from '../utils/encoder_symbols'\nimport { validator, encode as encodeSchema, decode as decodeSchema } from '@nhtio/validation'\nimport { artifactConstructorResolverSchema } from '../contracts/spooled_artifact_constructor'\nimport { validateOrThrow, asyncValidateOrThrow, ValidationException } from '../utils/validation'\nimport {\n E_INVALID_INITIAL_TOOL_VALUE,\n E_INVALID_TOOL_ARGS,\n E_TOOL_DOWNSTREAM_ERROR,\n} from '../exceptions/runtime'\nimport type { Media } from './media'\nimport type { AdkEncodableSnapshot } from './encodable'\nimport type { Schema, Description } from '@nhtio/validation'\nimport type { DispatchContext } from '../contracts/dispatch_context'\nimport type { SpooledArtifact, SpooledArtifactConstructor } from './spooled_artifact'\n\n/**\n * A zero-arg function that returns the {@link @nhtio/adk!SpooledArtifactConstructor} the consumer should\n * use when wrapping this tool's serialised output into a `ToolCall.results` field.\n *\n * @remarks\n * Why a resolver (and not the constructor itself)? `tool.ts` participates in a module-load\n * cycle with `spooled_artifact.ts` and `artifact_tool.ts` (`ArtifactTool extends Tool` closes\n * the loop). Any eager value-level reference to `SpooledArtifact` in `tool.ts` would crash the\n * cycle with a TDZ error. A resolver lets `tool.ts` validate \"is a function\" at module-load\n * time and defer the actual constructor check to validate-time (which always runs after every\n * module body has executed). Wrap-sites invoke `tool.artifactConstructor?.() ?? SpooledArtifact`\n * to obtain the final constructor.\n */\nexport type ArtifactConstructorResolver<A extends SpooledArtifact = SpooledArtifact> =\n () => SpooledArtifactConstructor<A>\n\n/**\n * The execution function for a {@link Tool}.\n *\n * @remarks\n * Receives the raw arguments passed to the executor, the active {@link @nhtio/adk!DispatchContext}, and the\n * tool's metadata registry.\n *\n * Return shapes:\n * - `string` / `Uint8Array` — opaque serialised output. The ADK does not persist the bytes\n * itself; the consumer's executor middleware is responsible for storing them and wrapping\n * them via `tool.artifactConstructor?.() ?? SpooledArtifact` when assembling the `ToolCall`\n * record.\n * - {@link @nhtio/adk!SpooledArtifact} — a pre-built, reader-backed result. Return this when\n * the handler has streamed bytes into storage and wrapped the reader; the consumer passes it\n * through without materialising or re-spooling it. Its concrete class determines the forged\n * `artifact_*` query tools.\n * - {@link @nhtio/adk!Media} / `Media[]` — explicit-modality silo. Bypasses\n * {@link Tool.artifactConstructor} — the handler returns the final result shape directly.\n * The LLM battery renders each `Media` as a provider-specific content block.\n */\nexport type ToolHandler = (\n args: unknown,\n ctx: DispatchContext,\n meta: Registry\n) =>\n | string\n | Uint8Array\n | SpooledArtifact\n | Media\n | Media[]\n | Promise<string | Uint8Array | SpooledArtifact | Media | Media[]>\n\n/**\n * Plain input object supplied to {@link Tool} at construction time.\n *\n * @typeParam A - The {@link @nhtio/adk!SpooledArtifact} subtype used to wrap this tool's results when\n * the consumer assembles a `ToolCall.results` field. Defaults to {@link @nhtio/adk!SpooledArtifact}\n * (plain text). Tools producing JSON output should set this to `SpooledJsonArtifact`; tools\n * producing markdown should set it to `SpooledMarkdownArtifact`; consumers can also pass a\n * custom subclass.\n */\nexport interface RawTool<A extends SpooledArtifact = SpooledArtifact> {\n /** Unique identifier used in LLM tool definitions. Recommend lowercase snake_case. */\n name: string\n /** Human-readable description passed to the model to explain what the tool does. */\n description: string\n /** @nhtio/validation schema for the tool's input arguments. Annotate with `.description()`, `.note()`, `.example()` etc. to produce rich LLM tool definitions via `.describe()`. */\n inputSchema: Schema\n /** Execution function. Not exposed as a public property — invoke via `executor()`. */\n handler: ToolHandler\n /**\n * Zero-arg resolver returning the {@link @nhtio/adk!SpooledArtifactConstructor} the consumer should use\n * when wrapping this tool's serialised output into a `ToolCall.results` field. Optional —\n * when omitted, wrap-sites fall back to {@link @nhtio/adk!SpooledArtifact} (plain text).\n *\n * @remarks\n * Recommended call shape: `artifactConstructor: () => SpooledJsonArtifact`. The closure is\n * the indirection that lets `tool.ts` validate this field without eagerly importing\n * `SpooledArtifact` (which would crash the `tool.ts ↔ spooled_artifact.ts ↔ artifact_tool.ts`\n * module-load cycle). At validate time the schema invokes the resolver and verifies its\n * return value is a `SpooledArtifact`-derived constructor — wrong-shape resolvers throw\n * {@link @nhtio/adk!E_INVALID_INITIAL_TOOL_VALUE}.\n *\n * Wrap-sites (storage batteries, scripted executors) read the constructor via\n * `tool.artifactConstructor?.() ?? SpooledArtifact`.\n */\n artifactConstructor?: ArtifactConstructorResolver<A>\n /** Optional arbitrary metadata for this tool (e.g. RBAC scopes, feature flags). Defaults to `{}`. Stored in a {@link @nhtio/adk!Registry} for dot-path access. */\n meta?: Record<string, unknown>\n /**\n * When `true`, marks this tool as owned by a specific {@link @nhtio/adk!DispatchContext} so that\n * `ToolRegistry.pruneEphemeral()` will drop it at ctx-completion.\n *\n * @remarks\n * The flag is advisory at the `Tool` level — registries decide what to do with it. The canonical\n * producer of ephemeral tools is `SpooledArtifact.forgeTools(ctx)`, which sets this to `true`\n * on every artifact-query tool it emits.\n *\n * @defaultValue `false`\n */\n ephemeral?: boolean\n /**\n * When `true`, declares that this tool's output should be treated as **trusted developer/user\n * intent** rather than as untrusted third-party text when surfaced to the model.\n *\n * @remarks\n * LLM batteries read this flag per call when rendering tool-call results. The default\n * untrusted envelope (e.g. `<untrusted_content>` in the OpenAI Chat Completions battery) is the\n * secure-by-default treatment for arbitrary tool output. A tool whose output is authored by the\n * user or operator (Q&A tools surfacing user-authored answers, human-in-the-loop approval\n * gates, feedback-collection tools, configuration tools returning developer-authored\n * constants) sets this to `true` so the LLM battery routes the result through its trusted\n * envelope (`<trusted_content>` in the OpenAI Chat Completions battery).\n *\n * Trust is a property of the tool's output, not a property of how a particular battery is\n * wired — putting the flag here means the trust signal travels with the tool wherever it is\n * registered, no per-battery string lists, no name-matching to fail-open on typos.\n *\n * @defaultValue `false`\n */\n trusted?: boolean\n /**\n * Self-declared merge collision policy. Honoured by `ToolRegistry.merge` (NOT by\n * `ToolRegistry.register`) when this tool collides with another of the same name.\n *\n * @remarks\n * - `'throw'` (default): defer to the merge-level `options.onCollision`. If that is also\n * `'throw'`, the merge raises `E_TOOL_ALREADY_REGISTERED`. This matches the default behaviour\n * of `ToolRegistry.register`.\n * - `'replace'`: this tool always wins the collision, regardless of the merge-level option.\n * - `'keep'`: this tool always loses to any previously-registered tool of the same name.\n *\n * Forged artifact-query tools set this to `'replace'` so that merging multiple\n * `Subclass.forgeTools(ctx)` outputs (whose base-method tools overlap by name) resolves\n * silently — the descriptors, snapshot, and handler behaviour are interchangeable across\n * subclasses, so replacement is a behavioural no-op.\n *\n * @defaultValue `'throw'`\n */\n onCollision?: 'throw' | 'replace' | 'keep'\n}\n\n/**\n * Validator schema for a {@link RawTool}.\n */\nconst rawToolSchema = validator.object<RawTool>({\n name: validator.string().required(),\n description: validator.string().required(),\n inputSchema: validator\n .any()\n .custom((value, helpers) => {\n if (validator.isSchema(value) && (value as any).type === 'object') return value\n return helpers.error('any.invalid')\n })\n .required(),\n handler: validator.function().required(),\n artifactConstructor: artifactConstructorResolverSchema().optional(),\n // eslint-disable-next-line adk/require-validator-any-required -- map value type-arg: meta holds arbitrary values; disposition is set by .default({}) on the object\n meta: validator.object().pattern(validator.string(), validator.any()).default({}),\n ephemeral: validator.boolean().default(false),\n trusted: validator.boolean().default(false),\n onCollision: validator.string().valid('throw', 'replace', 'keep').default('throw'),\n})\n\n/**\n * A tool definition that serves as the single source of truth for a callable tool: its name,\n * description, input schema, execution handler, and the {@link @nhtio/adk!SpooledArtifact} subclass that\n * wraps its serialised output.\n *\n * @typeParam A - The {@link @nhtio/adk!SpooledArtifact} subtype this tool's results should be wrapped in.\n * Defaults to {@link @nhtio/adk!SpooledArtifact}.\n *\n * @remarks\n * The `inputSchema` is a `@nhtio/validation` schema. It is used at runtime to validate incoming\n * arguments before the handler is called, and its `.describe()` output provides all the metadata\n * needed to build a provider-specific LLM tool definition — annotate the schema with\n * `.description()`, `.note()`, `.example()` etc. once, and that information is available in both\n * contexts without duplication.\n *\n * The handler is private — invoke it only through `executor(ctx)` which validates args, fires\n * observability events (with a stable `callId` derived from the tool name and arguments), and\n * wraps handler errors in {@link @nhtio/adk!E_TOOL_DOWNSTREAM_ERROR}. The handler returns serialised bytes\n * (`string | Uint8Array`); persistence is the consumer's responsibility.\n *\n * `artifactConstructor` is the {@link @nhtio/adk!SpooledArtifact} subclass the consumer should use when\n * wrapping the handler's output into a `ToolCall.results` field. The author declares it once\n * on the tool instance; the consumer reads it when assembling persisted records.\n */\nexport class Tool<A extends SpooledArtifact = SpooledArtifact> {\n /**\n * Validator schema that accepts a {@link RawTool} object.\n *\n * @remarks\n * Reusable fragment for any schema that needs to validate or nest a tool entry\n * (e.g. `TurnRunnerConfig.tools`).\n */\n public static schema = rawToolSchema\n\n /**\n * Returns `true` if `value` is a {@link Tool} instance.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link Tool} instance.\n */\n public static isTool(value: unknown): value is Tool {\n return isInstanceOf(value, 'Tool', Tool)\n }\n\n /** The tool's unique name, as exposed to the model in the tool definition. */\n declare readonly name: string\n /** Human/model-facing description of what the tool does. */\n declare readonly description: string\n /** Validation schema for the tool's arguments; also drives the generated parameter definition. */\n declare readonly inputSchema: Schema\n /** Resolver for the artifact constructor used to wrap the handler's output, if any. */\n declare readonly artifactConstructor: ArtifactConstructorResolver<A> | undefined\n /** Arbitrary per-tool metadata registry, passed through to the handler. */\n declare readonly meta: Registry\n /** When `true`, the tool's results are not persisted to history (transient/one-shot). */\n declare readonly ephemeral: boolean\n /** When `true`, the tool's output is treated as trusted content by the LLM battery's envelopes. */\n declare readonly trusted: boolean\n /** How registration resolves a name clash in a {@link ToolRegistry}: throw, replace, or keep the existing. */\n declare readonly onCollision: 'throw' | 'replace' | 'keep'\n\n #name: string\n #description: string\n #inputSchema: Schema\n #handler: ToolHandler\n #artifactConstructor: ArtifactConstructorResolver<A> | undefined\n #meta: Registry\n #ephemeral: boolean\n #trusted: boolean\n #onCollision: 'throw' | 'replace' | 'keep'\n\n /**\n * @param raw - The raw tool input validated against `rawToolSchema`.\n * @throws {@link @nhtio/adk!E_INVALID_INITIAL_TOOL_VALUE} when `raw` does not satisfy the schema.\n */\n constructor(raw: RawTool<A>) {\n let resolved: RawTool<A> & {\n meta: Record<string, unknown>\n ephemeral: boolean\n trusted: boolean\n onCollision: 'throw' | 'replace' | 'keep'\n }\n try {\n resolved = validateOrThrow<typeof resolved>(\n rawToolSchema,\n raw as RawTool,\n true\n ) as typeof resolved\n } catch (err) {\n throw new E_INVALID_INITIAL_TOOL_VALUE({ cause: isError(err) ? err : undefined })\n }\n\n this.#name = resolved.name\n this.#description = resolved.description\n this.#inputSchema = resolved.inputSchema\n this.#handler = resolved.handler\n this.#artifactConstructor = resolved.artifactConstructor as\n | ArtifactConstructorResolver<A>\n | undefined\n this.#meta = new Registry(resolved.meta)\n this.#ephemeral = resolved.ephemeral\n this.#trusted = resolved.trusted\n this.#onCollision = resolved.onCollision\n\n Object.defineProperties(this, {\n name: {\n get: () => this.#name,\n enumerable: true,\n configurable: false,\n },\n description: {\n get: () => this.#description,\n enumerable: true,\n configurable: false,\n },\n inputSchema: {\n get: () => this.#inputSchema,\n enumerable: true,\n configurable: false,\n },\n artifactConstructor: {\n get: () => this.#artifactConstructor,\n enumerable: true,\n configurable: false,\n },\n meta: {\n get: () => this.#meta,\n enumerable: true,\n configurable: false,\n },\n ephemeral: {\n get: () => this.#ephemeral,\n enumerable: true,\n configurable: false,\n },\n trusted: {\n get: () => this.#trusted,\n enumerable: true,\n configurable: false,\n },\n onCollision: {\n get: () => this.#onCollision,\n enumerable: true,\n configurable: false,\n },\n })\n }\n\n /**\n * Validates `args` against the tool's input schema asynchronously.\n *\n * @remarks\n * Async to support schemas with external validators (e.g. database lookups, API calls).\n * A validation failure throws {@link @nhtio/adk!E_INVALID_TOOL_ARGS} — this indicates a programming error\n * in the tool call loop, not a downstream failure.\n *\n * @param args - The arguments to validate.\n * @returns The validated (and coerced) arguments.\n * @throws {@link @nhtio/adk!E_INVALID_TOOL_ARGS} when `args` does not satisfy the input schema.\n */\n async validate(args: unknown): Promise<unknown> {\n try {\n return await asyncValidateOrThrow(this.#inputSchema, args)\n } catch (err) {\n if (isInstanceOf(err, 'ValidationException', ValidationException)) {\n throw new E_INVALID_TOOL_ARGS({ cause: err })\n }\n throw err\n }\n }\n\n /**\n * Returns a bound executor function for this tool against the given turn context.\n *\n * @remarks\n * The executor: (1) computes a stable `callId` as `sha256(canonicalStringify({tool, args}))`\n * over the **raw, pre-validation args**, (2) validates `args` via {@link Tool.validate},\n * (3) emits `toolExecutionStart` on the context (with the computed `callId`), (4) calls the\n * handler, (5) emits `toolExecutionEnd` (with the same `callId`), (6) wraps any handler error\n * in {@link @nhtio/adk!E_TOOL_DOWNSTREAM_ERROR} before re-throwing.\n *\n * The handler usually returns serialised bytes (`string | Uint8Array`) — persistence is then the\n * consumer's concern, and {@link Tool.artifactConstructor} is the class a wrap-site uses when\n * wrapping those bytes into a `ToolCall.results` field. **A handler may instead return a\n * {@link @nhtio/adk!SpooledArtifact} it built itself** (streaming into storage and wrapping the\n * reader), in which case wrap-sites pass it through untouched and `artifactConstructor` does not\n * apply — the returned instance's own class is what artifact-tool forging reads.\n *\n * Pattern mirrors `Middleware.runner()` — call once per turn, reuse the returned function.\n *\n * @param ctx - The active turn context. Provides emit functions and turn ID.\n * @returns An async function `(args) => Promise<string | Uint8Array | SpooledArtifact | Media | Media[]>`.\n * A `SpooledArtifact` is a result the HANDLER built (streamed to storage and wrapped itself); a\n * wrap-site passes it through unwrapped rather than re-spooling it. `string`/`Uint8Array` are the\n * opposite case — bytes the consumer must still store and wrap.\n */\n executor(\n ctx: DispatchContext\n ): (args: unknown) => Promise<string | Uint8Array | SpooledArtifact | Media | Media[]> {\n return async (\n args: unknown\n ): Promise<string | Uint8Array | SpooledArtifact | Media | Media[]> => {\n // Compute callId over raw args (pre-validation) so two invocations with the same\n // (tool, raw args) produce the same identifier even if validation coerces values.\n const callId = sha256(canonicalStringify({ tool: this.#name, args }))\n const validatedArgs = await this.validate(args)\n const startedAt = DateTime.now()\n ctx.emitToolExecutionStart({\n toolName: this.#name,\n turnId: ctx.id,\n callId,\n args: validatedArgs,\n startedAt,\n })\n try {\n const result = await this.#handler(validatedArgs, ctx, this.#meta)\n const endedAt = DateTime.now()\n ctx.emitToolExecutionEnd({\n toolName: this.#name,\n turnId: ctx.id,\n callId,\n startedAt,\n endedAt,\n durationMs: endedAt.diff(startedAt).milliseconds,\n isError: false,\n })\n return result\n } catch (err) {\n const endedAt = DateTime.now()\n ctx.emitToolExecutionEnd({\n toolName: this.#name,\n turnId: ctx.id,\n callId,\n startedAt,\n endedAt,\n durationMs: endedAt.diff(startedAt).milliseconds,\n isError: true,\n })\n throw new E_TOOL_DOWNSTREAM_ERROR({ cause: isError(err) ? err : undefined })\n }\n }\n }\n\n /**\n * Returns a fully serialisable snapshot of this tool's definition.\n *\n * @remarks\n * The `inputSchema` property is the result of calling `.describe()` on the raw schema — a plain\n * object carrying all the annotation metadata (descriptions, notes, examples, types) without any\n * validator functions. Use this to build provider-specific LLM tool definitions.\n *\n * @returns `{ name, description, inputSchema }` where `inputSchema` is the schema description.\n */\n describe(): { name: string; description: string; inputSchema: Description } {\n return {\n name: this.#name,\n description: this.#description,\n inputSchema: this.#inputSchema.describe(),\n }\n }\n\n /**\n * Serialise this Tool into an `@nhtio/encoder` snapshot.\n *\n * @remarks\n * Three halves with different serialisation strategies:\n *\n * - **Plain config** (`name`, `description`, `meta`, flags) — emitted verbatim.\n * - **`inputSchema`** — delegated to `@nhtio/validation`'s `encode()`, which captures the full schema\n * description plus its library version into a compact string; decode rebuilds the live `Schema`.\n * - **`handler` / `artifactConstructor`** — emitted as **functions**. The encoder's `FunctionSerializer`\n * serialises them by **source text** (`fn.toString()`). This is the sharp edge: a handler that\n * closes over `ctx`, service clients, or config loses those bindings on decode — only the source\n * survives, and the captured variables read back as `undefined`. A `.bind()`-ed or native handler\n * cannot be serialised at all and the encoder throws. Tools are rarely serialised in practice; when\n * they are, write handlers that reconstruct their dependencies inside the body rather than closing\n * over them.\n *\n * @returns A {@link RawTool}-shaped snapshot (with `inputSchema` as an encoded string).\n */\n [ENCODE_METHOD](): AdkEncodableSnapshot {\n return {\n name: this.#name,\n description: this.#description,\n inputSchema: encodeSchema(this.#inputSchema),\n handler: this.#handler,\n artifactConstructor: this.#artifactConstructor,\n meta: this.#meta.all(),\n ephemeral: this.#ephemeral,\n trusted: this.#trusted,\n onCollision: this.#onCollision,\n }\n }\n\n /**\n * Reconstruct a {@link Tool} from a {@link Tool.[ENCODE_METHOD]} snapshot.\n *\n * @remarks\n * Rebuilds the live `Schema` via `@nhtio/validation`'s `decode()`, then re-validates through the\n * constructor. The rehydrated `handler` carries only its source text — see\n * {@link Tool.[ENCODE_METHOD]} for the closure caveat.\n *\n * @param data - The snapshot produced by {@link Tool.[ENCODE_METHOD]}.\n * @returns A fully-validated {@link Tool}.\n */\n static [DECODE_METHOD](data: AdkEncodableSnapshot): Tool {\n const snapshot = data as Omit<RawTool, 'inputSchema'> & { inputSchema: string }\n return new Tool({\n ...snapshot,\n inputSchema: decodeSchema(snapshot.inputSchema),\n })\n }\n}\n","import { Tool } from './tool'\nimport { isInstanceOf } from '../utils/guards'\nimport { E_INVALID_INITIAL_TOOL_VALUE } from '../exceptions/runtime'\nimport { validator, decode as decodeSchema } from '@nhtio/validation'\nimport { ENCODE_METHOD, DECODE_METHOD } from '../utils/encoder_symbols'\nimport { validateOrThrow, ValidationException } from '../utils/validation'\nimport type { Registry } from './registry'\nimport type { Schema } from '@nhtio/validation'\nimport type { Tokenizable } from './tokenizable'\nimport type { AdkEncodableSnapshot } from './encodable'\nimport type { DispatchContext } from '../contracts/dispatch_context'\n\n/**\n * The execution function for an {@link ArtifactTool}.\n *\n * @remarks\n * Identical to the base tool handler except the return type is narrowed to\n * `string | Tokenizable | Promise<string | Tokenizable>`. Forged artifact-query tools emit\n * model-visible strings — the ADK wraps a bare-string return into a {@link @nhtio/adk!Tokenizable}\n * at the result-wrapping site so downstream code can rely on\n * `ToolCall.results instanceof Tokenizable` for every `ArtifactTool` invocation.\n */\nexport type ArtifactToolHandler = (\n args: unknown,\n ctx: DispatchContext,\n meta: Registry\n) => string | Tokenizable | Promise<string | Tokenizable>\n\n/**\n * Plain input object supplied to {@link ArtifactTool} at construction time.\n *\n * @remarks\n * Mirrors the base `RawTool` except `artifactConstructor` is forbidden — an `ArtifactTool`\n * emits a {@link @nhtio/adk!Tokenizable} directly into `ToolCall.results` and explicitly opts out of\n * `SpooledArtifact` wrapping. The forbidden field is enforced by {@link ArtifactTool.schema}\n * at construction time.\n */\nexport interface RawArtifactTool {\n /** Unique identifier used in LLM tool definitions. Recommend lowercase snake_case. */\n name: string\n /** Human-readable description passed to the model to explain what the tool does. */\n description: string\n /** @nhtio/validation schema for the tool's input arguments. */\n inputSchema: Schema\n /** Execution function. Returns a string or {@link @nhtio/adk!Tokenizable}; the ADK wraps a bare string into a `Tokenizable` at the result-wrapping site. */\n handler: ArtifactToolHandler\n /** Optional arbitrary metadata for this tool. Defaults to `{}`. */\n meta?: Record<string, unknown>\n /**\n * When `true`, marks this tool as owned by a specific {@link @nhtio/adk!DispatchContext}.\n *\n * @remarks\n * `ArtifactTool` instances produced by `SpooledArtifact.forgeTools(ctx)` set this to `true`\n * so that `ToolRegistry.pruneEphemeral()` drops them at ctx-completion.\n *\n * @defaultValue `false`\n */\n ephemeral?: boolean\n /**\n * When `true`, declares that this tool's output should be treated as **trusted developer/user\n * intent** rather than as untrusted third-party text when surfaced to the model.\n *\n * @remarks\n * Forged artifact-query tools default to `false` because their results are derived from\n * spooled artifact bodies — which may themselves be untrusted upstream tool output. The\n * trust signal does not promote handle-query results above the trust tier of the underlying\n * artifact.\n *\n * @defaultValue `false`\n */\n trusted?: boolean\n /**\n * Self-declared merge collision policy honoured by `ToolRegistry.merge`.\n *\n * @remarks\n * Forged artifact-query tools set this to `'replace'` so that merging multiple\n * `Subclass.forgeTools(ctx)` outputs (whose base-method tools overlap by name) resolves\n * silently — the descriptors, snapshot, and handler behaviour are interchangeable across\n * subclasses, so replacement is a behavioural no-op.\n *\n * @defaultValue `'throw'`\n */\n onCollision?: 'throw' | 'replace' | 'keep'\n}\n\n/**\n * Validator schema for a {@link RawArtifactTool}.\n *\n * @remarks\n * Mirrors the base tool schema but explicitly forbids `artifactConstructor` — the entire\n * point of `ArtifactTool` is to opt out of `SpooledArtifact` wrapping.\n */\nconst rawArtifactToolSchema = validator.object<RawArtifactTool & { artifactConstructor?: never }>({\n name: validator.string().required(),\n description: validator.string().required(),\n inputSchema: validator\n .any()\n .custom((value, helpers) => {\n if (validator.isSchema(value) && (value as any).type === 'object') return value\n return helpers.error('any.invalid')\n })\n .required(),\n handler: validator.function().required(),\n // eslint-disable-next-line adk/require-validator-any-required -- map value type-arg: meta holds arbitrary values; disposition is set by .default({}) on the object\n meta: validator.object().pattern(validator.string(), validator.any()).default({}),\n ephemeral: validator.boolean().default(false),\n trusted: validator.boolean().default(false),\n onCollision: validator.string().valid('throw', 'replace', 'keep').default('throw'),\n artifactConstructor: validator.any().forbidden(),\n})\n\n/**\n * A {@link @nhtio/adk!Tool} subclass whose handler return value is wrapped directly in a\n * {@link @nhtio/adk!Tokenizable} (not a {@link @nhtio/adk!SpooledArtifact}) when it\n * lands on `ToolCall.results`.\n *\n * @remarks\n * `ArtifactTool` is the canonical producer for **forged artifact-query tools** — the tools\n * `SpooledArtifact.forgeTools(ctx)` emits so the model can `head`, `tail`, `grep`, `json_get`,\n * `md_headings` (etc.) an artifact that is already in `ctx.turnToolCalls`.\n *\n * The difference from {@link @nhtio/adk!Tool} is structural, not stylistic:\n *\n * - A normal `Tool`'s handler returns bytes the ADK wraps in a fresh `SpooledArtifact`.\n * The artifact lands in `ToolCall.results`, joins `ctx.turnToolCalls`, and is itself a\n * first-class queryable artifact in the turn.\n * - An `ArtifactTool`'s handler returns a string that is **already the model-visible answer**\n * to a query against an existing artifact. The ADK wraps it in a `Tokenizable` rather\n * than a `SpooledArtifact`; nothing new is queryable on its own. Subsequent\n * `forgeTools(ctx)` calls exclude `ToolCall`s produced by an `ArtifactTool` from the\n * `callId` enum (via the `ToolCall.fromArtifactTool` marker) — this is the structural fix\n * that breaks the otherwise-recursive grep-on-the-grep-result loop.\n *\n * Consumers who want to build their own artifact-query tools (e.g. for a domain-specific\n * spooled subclass not shipped by the ADK) should extend or instantiate this class.\n */\nexport class ArtifactTool extends Tool {\n /**\n * Validator schema that accepts a {@link RawArtifactTool} object.\n *\n * @remarks\n * Differs from {@link @nhtio/adk!Tool.schema} by forbidding `artifactConstructor` — wrapping is\n * exactly the thing this class opts out of. Typed identically to {@link @nhtio/adk!Tool.schema} so the\n * subclass relationship `class ArtifactTool extends Tool` remains structurally sound; the\n * runtime validation rules still differ as declared by `rawArtifactToolSchema`.\n */\n public static schema = rawArtifactToolSchema as unknown as typeof Tool.schema\n\n /**\n * Returns `true` if `value` is an {@link ArtifactTool} instance.\n *\n * @remarks\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety — `instanceof` would fail for instances\n * created in a different module copy or VM context.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is an {@link ArtifactTool} instance.\n */\n public static isArtifactTool(value: unknown): value is ArtifactTool {\n return isInstanceOf(value, 'ArtifactTool', ArtifactTool)\n }\n\n /**\n * @param raw - Raw tool input validated against {@link ArtifactTool.schema}.\n *\n * @throws {@link @nhtio/adk!E_INVALID_INITIAL_TOOL_VALUE} when `raw` does not satisfy\n * {@link ArtifactTool.schema} (most commonly, when `artifactConstructor` is supplied — it is\n * explicitly forbidden on this class) or when the base {@link @nhtio/adk!Tool} constructor rejects the\n * input for any reason.\n */\n constructor(raw: RawArtifactTool) {\n // Enforce the forbidden `artifactConstructor` field up-front so the error reports against\n // ArtifactTool's contract, not the base Tool's. The base Tool constructor re-validates\n // against its own schema and stores the resolved fields.\n try {\n validateOrThrow(rawArtifactToolSchema, raw, true)\n } catch (err) {\n if (isInstanceOf(err, 'ValidationException', ValidationException)) {\n throw new E_INVALID_INITIAL_TOOL_VALUE({ cause: err })\n }\n throw err\n }\n super(raw as never)\n }\n\n /**\n * Serialise this ArtifactTool into an `@nhtio/encoder` snapshot.\n *\n * @remarks\n * Reuses the base {@link Tool.[ENCODE_METHOD]} (function-serialised `handler`, validation-encoded\n * `inputSchema`, plain config) and strips `artifactConstructor` — which {@link ArtifactTool.schema}\n * forbids. The handler's closure caveat from {@link Tool.[ENCODE_METHOD]} applies here too.\n *\n * @returns A {@link RawArtifactTool}-shaped snapshot (with `inputSchema` as an encoded string).\n */\n [ENCODE_METHOD](): AdkEncodableSnapshot {\n const base = super[ENCODE_METHOD]() as Record<string, unknown>\n delete base.artifactConstructor\n return base\n }\n\n /**\n * Reconstruct an {@link ArtifactTool} from an {@link ArtifactTool.[ENCODE_METHOD]} snapshot.\n *\n * @param data - The snapshot produced by {@link ArtifactTool.[ENCODE_METHOD]}.\n * @returns A fully-validated {@link ArtifactTool}.\n */\n static [DECODE_METHOD](data: AdkEncodableSnapshot): ArtifactTool {\n const snapshot = data as Omit<RawArtifactTool, 'inputSchema'> & { inputSchema: string }\n return new ArtifactTool({\n ...snapshot,\n inputSchema: decodeSchema(snapshot.inputSchema),\n })\n }\n}\n","import { validator } from '@nhtio/validation'\nimport { passesSchema } from '../utils/validation'\nimport type { ReaderDescriptor } from './reader_descriptor'\n\n/**\n * Backing store contract for a {@link @nhtio/adk!SpooledArtifact}.\n *\n * @remarks\n * Implementations may read from memory, a file handle, a network stream, or any other byte\n * source. The interface is intentionally minimal — the artifact layer handles all higher-level\n * operations (`head`, `tail`, `grep`, etc.) by composing calls to these three primitives.\n *\n * Line indexing is 0-based. Implementations must return `undefined` from {@link SpoolReader.line}\n * when the index is out of range rather than throwing.\n *\n * All three methods may be synchronous or asynchronous to accommodate both in-memory and I/O-\n * backed implementations without forcing unnecessary promise overhead on simple cases.\n */\nexport interface SpoolReader {\n /**\n * Returns the line at the given 0-based index, or `undefined` when out of range.\n *\n * @param index - 0-based line index.\n * @returns The raw line string (without trailing newline), or `undefined`.\n */\n line(index: number): string | undefined | Promise<string | undefined>\n\n /**\n * Returns the total number of bytes in the underlying data.\n *\n * @remarks\n * Used for reporting and token-estimation purposes. Byte length is distinct from character\n * length for multi-byte encodings.\n *\n * @returns The byte length of the underlying data.\n */\n byteLength(): number | Promise<number>\n\n /**\n * Returns the total number of lines in the underlying data.\n *\n * @remarks\n * Required so consumers know when to stop iterating; the line count must remain stable for the\n * lifetime of the reader.\n *\n * @returns The total line count.\n */\n lineCount(): number | Promise<number>\n\n /**\n * Returns the full underlying content as a single decoded string, byte-faithful to the source.\n *\n * @remarks\n * Unlike {@link SpoolReader.line}, this method preserves trailing newlines and any non-`\\n`\n * line terminators (e.g. `\\r\\n`) present in the original bytes. It is the primitive that\n * powers `SpooledArtifact.asString()` — the round-trip-faithful alternative to assembling\n * the artifact body from per-line reads.\n *\n * Implementations should make this O(n) in the size of the underlying data and may cache the\n * result if the read source is durable. Streaming implementations may choose not to cache.\n *\n * @returns The full underlying content as a single string.\n */\n readAll(): string | Promise<string>\n\n /**\n * Optionally emit a serialisable {@link ReaderDescriptor} so a {@link @nhtio/adk!SpooledArtifact}\n * backed by this reader can round-trip through `encode()`/`decode()` as a **handle**.\n *\n * @remarks\n * Synchronous by contract — the encoder's `[ENCODE_METHOD]()` is synchronous and cannot await. The\n * descriptor describes *where the bytes live* (a spool key, or an inlined string for in-memory\n * readers) — never the live binding (`Disk`, OPFS root), which the matching resolver re-injects on\n * decode. A reader that omits this method is treated as non-describable: line/text reads still work at\n * runtime, the `SpooledArtifact` simply cannot be serialised, and encoding it throws\n * {@link @nhtio/adk!E_READER_NOT_DESCRIBABLE}.\n *\n * @returns A tagged, serialisable handle, or `undefined`/absent when the reader cannot describe itself.\n */\n describe?(): ReaderDescriptor | undefined\n}\n\n/**\n * Validator schema used to validate a {@link SpoolReader} value.\n *\n * @remarks\n * Because `SpoolReader` is a structural interface with no associated constructor, validation is\n * duck-typed: the value must be an object, class instance, or function with `line`, `byteLength`,\n * and `lineCount` present as callable properties. Arity is not enforced — implementations may add\n * optional parameters beyond the contract.\n */\nexport const spoolReaderSchema = validator\n .any()\n .required()\n .custom((value, helpers) => {\n if (\n value !== null &&\n value !== undefined &&\n typeof (value as any).line === 'function' &&\n typeof (value as any).byteLength === 'function' &&\n typeof (value as any).lineCount === 'function' &&\n typeof (value as any).readAll === 'function'\n ) {\n return value as SpoolReader\n }\n return helpers.error('any.invalid')\n })\n\n/**\n * Returns `true` if `value` implements the {@link SpoolReader} interface.\n *\n * @remarks\n * Duck-typed: checks that `value` is non-null with `line`, `byteLength`, `lineCount`, and\n * `readAll` as callable functions. Does not use `instanceof` — there is no `SpoolReader`\n * constructor.\n *\n * @param value - The value to test.\n * @returns `true` when `value` conforms to the {@link SpoolReader} interface.\n */\nexport const implementsSpoolReader = (value: unknown): value is SpoolReader => {\n return passesSchema(spoolReaderSchema, value)\n}\n","/**\n * Decode-time registries that re-bind a serialised {@link ReaderDescriptor} to a live reader.\n *\n * @module\n *\n * @remarks\n * Reader-backed primitives serialise as **handles**: `encode()` writes a `{ tag, locator }` descriptor;\n * `decode()` looks up the resolver registered for `tag` and calls it with the `locator` to produce a\n * working {@link @nhtio/adk!MediaReader} / {@link @nhtio/adk!SpoolReader}. The resolver closure is where\n * the *live binding* the locator cannot carry — a flydrive `Disk`, an OPFS root, `fetch` — is\n * re-injected.\n *\n * Two separate registries (media vs spool) so a `media:` tag can never resolve to a spool reader or vice\n * versa. The `register*` functions are re-exported from the `@nhtio/adk/batteries/encoding` battery for\n * consumers; the `resolve*` functions are called by the primitives' `[DECODE_METHOD]`.\n */\n\nimport { E_NO_READER_RESOLVER } from '../exceptions/runtime'\nimport type { MediaReader } from './media_reader'\nimport type { SpoolReader } from './spool_reader'\nimport type { LocatorValue, ReaderDescriptor } from './reader_descriptor'\n\n/**\n * A factory that re-binds a descriptor's `locator` to a live {@link MediaReader}.\n *\n * @param locator - The JSON pointer captured at encode time.\n * @returns A working media reader over the same bytes.\n */\nexport type MediaReaderResolver = (locator: LocatorValue) => MediaReader\n\n/**\n * A factory that re-binds a descriptor's `locator` to a live {@link SpoolReader}.\n *\n * @param locator - The JSON pointer captured at encode time.\n * @returns A working spool reader over the same bytes.\n */\nexport type SpoolReaderResolver = (locator: LocatorValue) => SpoolReader\n\nconst mediaResolvers = new Map<string, MediaReaderResolver>()\nconst spoolResolvers = new Map<string, SpoolReaderResolver>()\n\n/**\n * Register (or replace) the resolver that re-binds a `media:` reader handle on decode.\n *\n * @remarks\n * Call once at application startup, before `decode()`. For durable stores, the resolver closure must\n * capture the same live binding the bytes were written with (e.g. the `fetch`-equivalent, an HTTP\n * client). The in-memory and fetch resolvers auto-register when the encoding battery loads; you only\n * register custom or durable ones yourself. Idempotent: re-registering the same `tag` overwrites.\n *\n * @param tag - The descriptor tag this resolver handles (e.g. `\"media:in-memory\"`).\n * @param resolver - Factory turning a captured locator back into a live {@link MediaReader}.\n */\nexport const registerMediaReaderResolver = (tag: string, resolver: MediaReaderResolver): void => {\n mediaResolvers.set(tag, resolver)\n}\n\n/**\n * Register (or replace) the resolver that re-binds a `spool:` reader handle on decode.\n *\n * @remarks\n * Call once at application startup, before `decode()`. Durable-store resolvers (flydrive, OPFS) must\n * capture the live `Disk`/OPFS root — the locator carries only the key. The in-memory resolver\n * auto-registers when the encoding battery loads. Idempotent: re-registering the same `tag` overwrites.\n *\n * @param tag - The descriptor tag this resolver handles (e.g. `\"spool:flydrive\"`).\n * @param resolver - Factory turning a captured locator back into a live {@link SpoolReader}.\n */\nexport const registerSpoolReaderResolver = (tag: string, resolver: SpoolReaderResolver): void => {\n spoolResolvers.set(tag, resolver)\n}\n\n/**\n * Re-bind a media reader descriptor to a live {@link MediaReader}.\n *\n * @remarks\n * Called by {@link @nhtio/adk!Media}'s `[DECODE_METHOD]`. Throws if no resolver is registered for the\n * descriptor's `tag` — the fix is to register one (with its live binding) before decoding.\n *\n * @param descriptor - The handle captured at encode time.\n * @returns A working media reader.\n * @throws {@link @nhtio/adk!E_NO_READER_RESOLVER} when no resolver is registered for `descriptor.tag`.\n */\nexport const resolveMediaReader = (descriptor: ReaderDescriptor): MediaReader => {\n const resolver = mediaResolvers.get(descriptor.tag)\n if (!resolver) {\n throw new E_NO_READER_RESOLVER([descriptor.tag])\n }\n return resolver(descriptor.locator)\n}\n\n/**\n * Re-bind a spool reader descriptor to a live {@link SpoolReader}.\n *\n * @remarks\n * Called by {@link @nhtio/adk!SpooledArtifact}'s `[DECODE_METHOD]` (and its subclasses'). Throws if no\n * resolver is registered for the descriptor's `tag`.\n *\n * @param descriptor - The handle captured at encode time.\n * @returns A working spool reader.\n * @throws {@link @nhtio/adk!E_NO_READER_RESOLVER} when no resolver is registered for `descriptor.tag`.\n */\nexport const resolveSpoolReader = (descriptor: ReaderDescriptor): SpoolReader => {\n const resolver = spoolResolvers.get(descriptor.tag)\n if (!resolver) {\n throw new E_NO_READER_RESOLVER([descriptor.tag])\n }\n return resolver(descriptor.locator)\n}\n","import { validator } from '@nhtio/validation'\nimport { isInstanceOf } from '../utils/guards'\nimport { ArtifactTool } from './artifact_tool'\nimport { ToolRegistry } from './tool_registry'\nimport { Tokenizable, TokenEncoding } from './tokenizable'\nimport { implementsSpoolReader } from '../contracts/spool_reader'\nimport { resolveSpoolReader } from '../contracts/reader_resolvers'\nimport { ENCODE_METHOD, DECODE_METHOD } from '../utils/encoder_symbols'\nimport {\n E_NOT_A_SPOOL_READER,\n E_READER_NOT_DESCRIBABLE,\n E_ARTIFACT_ID_COLLISION,\n} from '../exceptions/runtime'\nimport type { ObjectSchema } from '@nhtio/validation'\nimport type { AdkEncodableSnapshot } from './encodable'\nimport type { SpoolReader } from '../contracts/spool_reader'\nimport type { DispatchContext } from '../contracts/dispatch_context'\nimport type { ReaderDescriptor } from '../contracts/reader_descriptor'\n\n/**\n * Constructor signature for {@link SpooledArtifact} and any subclass.\n *\n * @remarks\n * Used by {@link @nhtio/adk!Tool} to declare the artifact subclass the consumer should use when wrapping\n * the handler's serialised output. The variadic rest parameter accommodates subclass-specific\n * constructor arguments (e.g. `SpooledJsonArtifact(reader, format?)`).\n *\n * @typeParam A - The {@link SpooledArtifact} subtype the constructor produces.\n */\nexport type SpooledArtifactConstructor<A extends SpooledArtifact = SpooledArtifact> = new (\n reader: SpoolReader,\n ...rest: any[]\n) => A\n\n/**\n * Metadata table entry for one of the artifact's existing query methods, used by\n * {@link SpooledArtifact.forgeTools} to surface that method as an {@link @nhtio/adk!ArtifactTool}.\n *\n * @remarks\n * This is a metadata shape, not a general method → tool pipeline. `forgeTools` knows how to\n * marshal arguments for a fixed, closed set of method names (the base seven on\n * {@link SpooledArtifact} and the JSON/Markdown methods on the bundled subclasses); a\n * descriptor is the place to attach a tool name, description, args schema, and optional\n * serializer to one of those methods. Adding a descriptor for a method whose name is not\n * in that closed set will produce a tool whose handler invokes the method with no arguments.\n *\n * For new methods that require custom argument marshalling, branching, multi-step logic,\n * cross-artifact joins, or any other behaviour beyond \"call this existing method,\" override\n * {@link SpooledArtifact.forgeTools} and mint the {@link @nhtio/adk!ArtifactTool} directly — do not try\n * to express it through a descriptor.\n *\n * Zero-arg methods are the exception: a descriptor with no `argsSchema` (or one that adds\n * only `callId`-adjacent fields you don't consume) works for any method that takes no\n * arguments, regardless of name.\n */\nexport interface ToolMethodDescriptor {\n /** Absolute tool name as exposed to the LLM (e.g. `'artifact_head'`). */\n name: string\n /** Method to invoke on the resolved artifact instance (e.g. `'head'`, `'json_get'`). */\n method: string\n /** Human-readable description passed to the model. Should mention \"in this turn\" so the model understands the artifact's lifecycle scope. */\n description: string\n /** Schema for the method's own args, NOT including `callId`. `forgeTools()` injects `callId`. */\n argsSchema?: ObjectSchema\n /** Optional formatter for non-string return values. Defaults: string → as-is; string[] → newline-join; number → `String(n)`; otherwise `JSON.stringify(value, null, 2)`. */\n serialise?: (result: unknown) => string\n}\n\n/**\n * Returns the effective artifact tool descriptors from a constructor's static prototype chain.\n *\n * Core subclasses declare only their own `toolMethods`; a static property shadows its ancestor\n * rather than concatenating it. This walks leaf-first and deduplicates by `name`, the absolute\n * model-facing tool identifier, rather than `method`, which is the instance dispatch name and may\n * legitimately differ (and is not the vocabulary exposed to callers). The nearest declaration\n * wins, matching tool collision replacement semantics.\n *\n * @param ctor The artifact constructor whose effective descriptors are wanted.\n * @returns A frozen, leaf-first array of descriptors, or an empty array when none are declared.\n */\nexport const effectiveToolMethods = (ctor: unknown): readonly ToolMethodDescriptor[] => {\n const seen = new Set<string>()\n const out: ToolMethodDescriptor[] = []\n // Only objects and functions have a prototype chain; a null/undefined/primitive ctor has no\n // declarations and `Object.getPrototypeOf` would throw on it.\n let current: unknown = typeof ctor === 'object' || typeof ctor === 'function' ? ctor : null\n while (current !== null && current !== Function.prototype) {\n const own = Object.getOwnPropertyDescriptor(current, 'toolMethods')\n // Read via the descriptor's getter when it is accessor-backed, so a `static get toolMethods()`\n // declaration is honoured rather than silently skipped (a data descriptor has `value`).\n const value = own\n ? 'get' in own && typeof own.get === 'function'\n ? own.get.call(current)\n : own.value\n : undefined\n if (Array.isArray(value)) {\n for (const descriptor of value as unknown[]) {\n if (\n descriptor &&\n typeof descriptor === 'object' &&\n typeof (descriptor as ToolMethodDescriptor).name === 'string' &&\n !seen.has((descriptor as ToolMethodDescriptor).name)\n ) {\n const method = descriptor as ToolMethodDescriptor\n seen.add(method.name)\n out.push(method)\n }\n }\n }\n current = Object.getPrototypeOf(current)\n }\n return Object.freeze(out)\n}\n\nconst noArgsSchema = validator.object<Record<string, never>>({})\n\n/**\n * Collect artifact IDs from the current turn's tool calls and retrievables that are instances of a specific artifact class.\n *\n * @param ctx - The dispatch context containing tool calls and retrievables.\n * @param requires - The artifact class constructor to filter by.\n * @returns An array of unique artifact IDs matching the specified class, with collision detection.\n * @throws {@link @nhtio/adk!E_ARTIFACT_ID_COLLISION} when the same ID appears in both tool calls and retrievables.\n */\nexport function collectArtifactCompatibleIds(\n ctx: {\n turnToolCalls: Iterable<{\n id: string\n fromArtifactTool?: boolean\n results: unknown\n }>\n turnRetrievables: Iterable<{\n id: string\n inline: boolean\n content: unknown\n }>\n },\n requires: SpooledArtifactConstructor\n): string[] {\n const toolIds = [...ctx.turnToolCalls]\n .filter((tc) => !tc.fromArtifactTool && isInstanceOf(tc.results, requires.name, requires))\n .map((tc) => tc.id)\n const retrievableIds = [...(ctx.turnRetrievables ?? [])]\n .filter((r) => !r.inline && isInstanceOf(r.content, requires.name, requires))\n .map((r) => r.id)\n const collisions = retrievableIds.filter((id) => toolIds.includes(id))\n if (collisions.length > 0) throw new E_ARTIFACT_ID_COLLISION([collisions[0]])\n return [...new Set([...toolIds, ...retrievableIds])]\n}\n\n/**\n * Resolve an artifact by ID from the current turn's tool calls or retrievables, with type narrowing.\n *\n * @param ctx - The dispatch context containing tool calls and retrievables.\n * @param id - The artifact ID to resolve.\n * @param requires - The artifact class constructor to narrow by; only artifacts of this type are returned.\n * @returns The resolved artifact and its source (tool call or retrievable), or undefined if not found.\n */\nexport function resolveArtifactById(\n ctx: {\n turnToolCalls: Iterable<{\n id: string\n fromArtifactTool?: boolean\n results: unknown\n }>\n turnRetrievables: Iterable<{\n id: string\n inline: boolean\n content: unknown\n }>\n },\n id: string,\n requires: SpooledArtifactConstructor\n): { artifact: SpooledArtifact; source: 'toolCall' | 'retrievable' } | undefined {\n const tc = [...ctx.turnToolCalls].find((t) => t.id === id && !t.fromArtifactTool)\n if (tc && isInstanceOf(tc.results, requires.name, requires))\n return { artifact: tc.results, source: 'toolCall' }\n const r = [...(ctx.turnRetrievables ?? [])].find((v) => v.id === id && !v.inline)\n if (r && isInstanceOf(r.content, requires.name, requires))\n return { artifact: r.content, source: 'retrievable' }\n return undefined\n}\n\n/**\n * Default serialiser for {@link @nhtio/adk!ArtifactTool} handler return values when a descriptor does not\n * provide its own. Exported for reuse by subclass `forgeTools` overrides.\n *\n * @param result - The artifact-method return value.\n * @returns A string suitable for inclusion in an LLM tool-call response.\n */\nexport const defaultSerialise = (result: unknown): string => {\n if (result === undefined) return '(undefined)'\n if (result === null) return 'null'\n if (typeof result === 'string') return result\n if (Array.isArray(result) && result.every((r) => typeof r === 'string')) {\n if (result.length === 0) return '(empty list)'\n return (result as string[]).join('\\n')\n }\n if (typeof result === 'number') return String(result)\n return JSON.stringify(result, null, 2)\n}\n\nconst baseToolMethods: ReadonlyArray<ToolMethodDescriptor> = Object.freeze([\n {\n name: 'artifact_head',\n method: 'head',\n description:\n 'Return the first n lines of a spooled artifact produced earlier in this turn. Takes a callId selecting which artifact to inspect.',\n argsSchema: validator.object({\n n: validator.number().integer().min(1).default(10).description('Number of lines to return.'),\n }),\n },\n {\n name: 'artifact_tail',\n method: 'tail',\n description:\n 'Return the last n lines of a spooled artifact produced earlier in this turn. Takes a callId selecting which artifact to inspect.',\n argsSchema: validator.object({\n n: validator.number().integer().min(1).default(10).description('Number of lines to return.'),\n }),\n },\n {\n name: 'artifact_grep',\n method: 'grep',\n description:\n 'Return all lines matching a regular expression pattern from a spooled artifact produced earlier in this turn.',\n argsSchema: validator.object({\n pattern: validator\n .string()\n .required()\n .description('Regular expression pattern, applied via JavaScript RegExp.'),\n flags: validator\n .string()\n .allow('')\n .pattern(/^[imsu]*$/)\n .optional()\n .description(\n \"Optional RegExp flags. Allowed: 'i' (case-insensitive), 'm' (multiline), 's' (dotAll), 'u' (unicode). 'g' and 'y' are disallowed because per-line matching is stateless.\"\n ),\n }),\n },\n {\n name: 'artifact_cat',\n method: 'cat',\n description:\n 'Return lines from a spooled artifact produced earlier in this turn, optionally bounded to a range.',\n argsSchema: validator.object({\n start: validator.number().integer().min(0).optional().description('Start line (inclusive).'),\n end: validator.number().integer().min(0).optional().description('End line (exclusive).'),\n }),\n },\n {\n name: 'artifact_byte_length',\n method: 'byteLength',\n description:\n 'Return the total byte length of a spooled artifact produced earlier in this turn.',\n argsSchema: noArgsSchema,\n },\n {\n name: 'artifact_line_count',\n method: 'lineCount',\n description: 'Return the total line count of a spooled artifact produced earlier in this turn.',\n argsSchema: noArgsSchema,\n },\n {\n name: 'artifact_estimate_tokens',\n method: 'estimateTokens',\n description:\n 'Estimate the total token count of a spooled artifact produced earlier in this turn under a named encoding.',\n argsSchema: validator.object({\n encoding: validator\n .string()\n .valid(...TokenEncoding)\n .required()\n .description('Token encoding identifier.'),\n }),\n },\n])\n\n/**\n * A lazy, line-oriented view over an arbitrary backing store.\n *\n * @remarks\n * All I/O methods are async to remain compatible with both in-memory and streaming\n * {@link @nhtio/adk!SpoolReader} implementations. Token estimation delegates to\n * {@link @nhtio/adk!Tokenizable.estimateTokens} — the same backends used elsewhere in the ADK.\n *\n * The class is read-only by design: mutation of the underlying data is the responsibility of the\n * producer that created the {@link @nhtio/adk!SpoolReader}, not the consumer reading from this artifact.\n */\nexport class SpooledArtifact {\n /**\n * The set of artifact-query methods this class surfaces via {@link SpooledArtifact.forgeTools}.\n *\n * @remarks\n * The base set covers the generic line-oriented operations every artifact supports:\n * `artifact_head`, `artifact_tail`, `artifact_grep`, `artifact_cat`, `artifact_byte_length`,\n * `artifact_line_count`, `artifact_estimate_tokens`. Each `toolMethods` array lists **only**\n * its own class's descriptors — subclasses do not concatenate inherited descriptors. The\n * subclass instead overrides {@link SpooledArtifact.forgeTools} to merge the base registry\n * (produced by `SpooledArtifact.forgeTools(ctx)`) with its own — see\n * {@link @nhtio/adk!SpooledJsonArtifact.forgeTools} and {@link @nhtio/adk!SpooledMarkdownArtifact.forgeTools} for\n * the canonical shape and the pattern downstream consumers should follow when building\n * their own `SpooledArtifact` subclasses.\n *\n * Tool names are absolute (not subclass-prefixed). Forged tools carry\n * `Tool.onCollision = 'replace'` so merging multiple subclasses' `forgeTools()` outputs is\n * silent — every same-named tool dispatches the same method on whatever artifact the\n * `callId` resolves to, so the overlap is behaviourally interchangeable.\n *\n * Frozen at module load.\n */\n public static toolMethods: ReadonlyArray<ToolMethodDescriptor> = baseToolMethods\n\n #reader: SpoolReader\n #sizeHints: { byteLength: number; lineCount: number } | undefined\n\n /**\n * @param reader - The backing store to read from.\n * @throws {@link @nhtio/adk!E_NOT_A_SPOOL_READER} when `reader` does not implement {@link @nhtio/adk!SpoolReader}.\n */\n constructor(reader: SpoolReader) {\n if (!implementsSpoolReader(reader)) {\n throw new E_NOT_A_SPOOL_READER()\n }\n this.#reader = reader\n }\n\n /**\n * Emit the backing reader's serialisable {@link ReaderDescriptor}, or throw if it cannot describe\n * itself.\n *\n * @remarks\n * `protected` so subclasses can build their own encode snapshots over the base reader (which is\n * otherwise private). Throws {@link @nhtio/adk!E_READER_NOT_DESCRIBABLE} when the reader has no\n * `describe()` (or returns `undefined`) — there is no serialisable handle to write.\n *\n * @returns The reader's tagged handle descriptor.\n * @throws {@link @nhtio/adk!E_READER_NOT_DESCRIBABLE} when the reader is not describable.\n */\n protected readerDescriptor(): ReaderDescriptor {\n const descriptor = this.#reader.describe?.()\n if (!descriptor) {\n throw new E_READER_NOT_DESCRIBABLE(['reader'])\n }\n return descriptor\n }\n\n /**\n * Serialise this SpooledArtifact into an `@nhtio/encoder` snapshot — the reader **handle**, not the\n * bytes.\n *\n * @remarks\n * Emits the backing reader's {@link ReaderDescriptor}; decode re-binds the reader through the\n * registered resolver. Throws {@link @nhtio/adk!E_READER_NOT_DESCRIBABLE} when the reader cannot\n * describe itself. Subclasses override this to include their own discriminators (e.g.\n * {@link @nhtio/adk!SpooledJsonArtifact} adds `format`).\n *\n * @returns A snapshot consumed by {@link SpooledArtifact.[DECODE_METHOD]}.\n */\n [ENCODE_METHOD](): AdkEncodableSnapshot {\n return { reader: this.readerDescriptor() }\n }\n\n /**\n * Reconstruct a {@link SpooledArtifact} from an {@link SpooledArtifact.[ENCODE_METHOD]} snapshot.\n *\n * @remarks\n * Re-binds the reader via {@link @nhtio/adk!resolveSpoolReader}; throws\n * {@link @nhtio/adk!E_NO_READER_RESOLVER} when no resolver is registered for the descriptor's tag.\n *\n * @param data - The snapshot produced by {@link SpooledArtifact.[ENCODE_METHOD]}.\n * @returns A fresh {@link SpooledArtifact} backed by a freshly-resolved reader.\n */\n static [DECODE_METHOD](data: AdkEncodableSnapshot): SpooledArtifact {\n const snapshot = data as { reader: ReaderDescriptor }\n return new SpooledArtifact(resolveSpoolReader(snapshot.reader))\n }\n\n /**\n * Returns the line at the given 0-based index, or `undefined` when out of range.\n *\n * @remarks\n * Protected so subclasses can scan the backing store line-by-line without allocating\n * intermediate arrays. Delegates directly to the {@link @nhtio/adk!SpoolReader}.\n *\n * @param index - 0-based line index.\n * @returns The raw line string, or `undefined` when out of range.\n */\n protected async line(index: number): Promise<string | undefined> {\n return this.#reader.line(index)\n }\n\n /**\n * Returns `true` if `value` is a {@link SpooledArtifact} instance (including any subclass).\n *\n * @remarks\n * Uses the cross-realm-safe {@link @nhtio/adk!isInstanceOf} guard: `instanceof` first, then\n * `Symbol.hasInstance`, then a `constructor.name` fallback. Subclass instances (e.g.\n * {@link @nhtio/adk!SpooledJsonArtifact}) satisfy this guard because `instanceof` walks the prototype\n * chain. The fallbacks handle the dual-module-copy case where two distinct `SpooledArtifact`\n * classes coexist in the same realm (e.g. one bundled into a downstream library, one in the\n * consumer's `node_modules`).\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link SpooledArtifact} instance.\n */\n public static isSpooledArtifact(value: unknown): value is SpooledArtifact {\n return isInstanceOf(value, 'SpooledArtifact', SpooledArtifact)\n }\n\n /**\n * Returns `true` if `value` is a constructor function whose prototype chain includes\n * {@link SpooledArtifact} (including `SpooledArtifact` itself).\n *\n * @remarks\n * Used by {@link @nhtio/adk!Tool} to validate the optional `artifactConstructor` field. Performs an\n * `instanceof`-based check on the prototype chain; falls back to a duck-type test that looks\n * for the canonical SpooledArtifact instance methods on `value.prototype` for cross-realm\n * safety (constructors passed from a different module copy or VM context).\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a constructor for `SpooledArtifact` or a subclass.\n */\n public static isSpooledArtifactConstructor(\n value: unknown\n ): value is SpooledArtifactConstructor<SpooledArtifact> {\n if (typeof value !== 'function') return false\n if (value === SpooledArtifact) return true\n const proto = (value as { prototype?: unknown }).prototype\n if (proto === undefined || proto === null) return false\n if (isInstanceOf(proto, 'SpooledArtifact', SpooledArtifact)) return true\n // Cross-realm duck-type fallback: prototype carries the canonical SpooledArtifact methods\n const methods = ['head', 'tail', 'grep', 'cat', 'byteLength', 'lineCount', 'estimateTokens']\n return methods.every((m) => typeof (proto as Record<string, unknown>)[m] === 'function')\n }\n\n /**\n * Returns the first `n` lines of the artifact.\n *\n * @remarks\n * If the artifact contains fewer than `n` lines, all available lines are returned. Matches the\n * behaviour of POSIX `head -n`.\n *\n * @param n - Number of lines to return. Defaults to 10.\n * @returns Array of line strings, without trailing newlines.\n */\n async head(n: number = 10): Promise<string[]> {\n const count = await this.#reader.lineCount()\n const limit = Math.min(n, count)\n const lines: string[] = []\n for (let i = 0; i < limit; i++) {\n const line = await this.#reader.line(i)\n if (line !== undefined) {\n lines.push(line)\n }\n }\n return lines\n }\n\n /**\n * Returns the last `n` lines of the artifact.\n *\n * @remarks\n * If the artifact contains fewer than `n` lines, all available lines are returned. Matches the\n * behaviour of POSIX `tail -n`.\n *\n * @param n - Number of lines to return. Defaults to 10.\n * @returns Array of line strings, without trailing newlines.\n */\n async tail(n: number = 10): Promise<string[]> {\n const count = await this.#reader.lineCount()\n const start = Math.max(0, count - n)\n const lines: string[] = []\n for (let i = start; i < count; i++) {\n const line = await this.#reader.line(i)\n if (line !== undefined) {\n lines.push(line)\n }\n }\n return lines\n }\n\n /**\n * Returns all lines that match `pattern`.\n *\n * @remarks\n * Behaves like POSIX `grep`: each line is tested against the pattern and included in the result\n * when it matches. The pattern is applied as a JavaScript `RegExp`; flags (e.g. case-\n * insensitivity) should be encoded in the expression itself.\n *\n * Stateful flags (`g`, `y`) on the supplied `RegExp` would normally cause `pattern.test()` to\n * advance `lastIndex` across calls, producing skipped matches and order-dependent results. To\n * keep the per-line semantics stateless, `grep` resets `pattern.lastIndex` to `0` before each\n * line test. The forged `artifact_grep` tool also rejects `g` and `y` flags up-front at schema\n * validation time.\n *\n * @param pattern - The regular expression to test each line against.\n * @returns Array of matching line strings, in order.\n */\n async grep(pattern: RegExp): Promise<string[]> {\n const count = await this.#reader.lineCount()\n const matches: string[] = []\n for (let i = 0; i < count; i++) {\n const line = await this.#reader.line(i)\n if (line !== undefined) {\n pattern.lastIndex = 0\n if (pattern.test(line)) {\n matches.push(line)\n }\n }\n }\n return matches\n }\n\n /**\n * Returns lines from the artifact, optionally bounded to a range.\n *\n * @remarks\n * Without arguments, returns all lines — equivalent to POSIX `cat`. With `start` and/or `end`,\n * behaves like `Array.prototype.slice`: `start` defaults to `0`, `end` defaults to the total\n * line count, and only lines in `[start, end)` are fetched from the backing store. For large\n * artifacts, prefer a bounded range or {@link SpooledArtifact.head} / {@link SpooledArtifact.tail}.\n *\n * @param start - 0-based start line index (inclusive). Defaults to `0`.\n * @param end - 0-based end line index (exclusive). Defaults to `lineCount()`.\n * @returns Array of line strings in the requested range.\n */\n async cat(start?: number, end?: number): Promise<string[]> {\n const count = await this.#reader.lineCount()\n const from = Math.max(0, start ?? 0)\n const to = Math.min(count, end ?? count)\n const lines: string[] = []\n for (let i = from; i < to; i++) {\n const line = await this.#reader.line(i)\n if (line !== undefined) {\n lines.push(line)\n }\n }\n return lines\n }\n\n /**\n * Returns the total byte length of the underlying data.\n *\n * @returns The byte length as reported by the {@link @nhtio/adk!SpoolReader}.\n */\n async byteLength(): Promise<number> {\n return this.#sizeHints?.byteLength ?? this.#reader.byteLength()\n }\n\n /**\n * Cache producer-computed size metadata for synchronous handle estimation.\n *\n * @param hints - The byte length and line count of the backing content.\n * @internal\n */\n _setSizeHints(hints: { byteLength: number; lineCount: number }): void {\n this.#sizeHints = hints\n }\n\n /**\n * Returns whether producer-computed size metadata is available.\n *\n * @returns `true` when {@link SpooledArtifact._setSizeHints} has populated the cache.\n */\n hasSizeHints(): boolean {\n return this.#sizeHints !== undefined\n }\n\n /**\n * Returns the total number of lines in the artifact.\n *\n * @returns The line count as reported by the {@link @nhtio/adk!SpoolReader}.\n */\n async lineCount(): Promise<number> {\n return this.#sizeHints?.lineCount ?? this.#reader.lineCount()\n }\n\n /**\n * Estimates tokens for the exact handle-body metadata rendered for this artifact.\n *\n * The fallback renderer is an interim core-safe implementation. Its output is deliberately\n * specified here for fan-in parity: the lines are the fixed prose and metadata strings below,\n * with one `\\n` separator, and method entries formatted as `- name — description` (or `- name`).\n * The canonical renderer in `chat_common` should eventually delegate to this builder rather than\n * maintain a second copy.\n *\n * @param callId - The turn-local artifact identifier.\n * @param encoding - The token encoding used for estimation.\n * @param renderer - Optional renderer overriding the interim default.\n * @returns A synchronous token estimate.\n */\n estimateHandleTokens(\n callId: string,\n encoding: TokenEncoding,\n renderer?: (input: {\n callId: string\n artifact: unknown\n byteLength: number\n lineCount: number\n estimatedTokens?: number\n encoding?: string\n }) => string\n ): number {\n if (!this.#sizeHints)\n throw new Error('Cannot estimate artifact handle tokens without size hints')\n const render =\n renderer ??\n ((input) => {\n const ctor = (\n input.artifact as {\n constructor?: {\n name?: string\n toolMethods?: ReadonlyArray<{\n name: string\n description?: string\n }>\n }\n }\n ).constructor\n const methods = effectiveToolMethods(ctor ?? {})\n return [\n 'This tool returned a large artifact that was not inlined to preserve context budget.',\n '',\n 'Artifact metadata:',\n `- callId: ${input.callId}`,\n `- kind: ${ctor?.name ?? 'SpooledArtifact'}`,\n `- byteLength: ${input.byteLength}`,\n `- lineCount: ${input.lineCount}`,\n '',\n `To read this artifact in this turn, call one of the following tools with`,\n `callId=${input.callId}:`,\n ...methods.map((m) => (m.description ? `- ${m.name} — ${m.description}` : `- ${m.name}`)),\n '',\n `The artifact persists in this turn's context — multiple queries against the same callId are allowed and efficient. Do not assume the body has been inlined anywhere else.`,\n ].join('\\n')\n })\n const text = render({ callId, artifact: this, ...this.#sizeHints })\n return Tokenizable.estimateTokens(text, encoding)\n }\n\n /**\n * Estimates the total token count of the artifact under `encoding`.\n *\n * @remarks\n * Reads the full byte-faithful content via {@link SpooledArtifact.asString} (which delegates to\n * {@link @nhtio/adk!SpoolReader.readAll}) and delegates to {@link @nhtio/adk!Tokenizable.estimateTokens}. The estimate\n * therefore reflects the actual source bytes — including trailing newlines and non-`\\n` line\n * terminators that the line-based {@link SpooledArtifact.cat} view would otherwise discard or\n * misrepresent.\n *\n * @param encoding - The encoding identifier to use for counting.\n * @returns The estimated number of tokens.\n */\n async estimateTokens(encoding: TokenEncoding): Promise<number> {\n const content = await this.#reader.readAll()\n return Tokenizable.estimateTokens(content, encoding)\n }\n\n /**\n * Returns the full artifact body as a single byte-faithful string.\n *\n * @remarks\n * Round-trip faithful to whatever bytes the {@link @nhtio/adk!SpoolReader} was constructed over —\n * preserves trailing newlines and non-`\\n` line terminators that {@link SpooledArtifact.cat}\n * discards via its line-based view. This is the canonical primitive for \"inline the artifact\n * content directly into a message\" use cases.\n *\n * `asString()` and the static `forgeTools(ctx)` factory on each subclass are independent\n * alternatives — a consumer chooses per turn whether to inline the body in a message\n * (`await tc.results.asString()`) or hand the model query tools\n * (`SpooledArtifact.forgeTools(ctx)`). Neither calls the other; either works with neither.\n *\n * @returns The full content as a single string.\n */\n async asString(): Promise<string> {\n return this.#reader.readAll()\n }\n\n /**\n * Forges a fresh {@link @nhtio/adk!ToolRegistry} of ephemeral {@link @nhtio/adk!ArtifactTool} instances that let the\n * LLM query artifacts already present in `ctx.turnToolCalls`.\n *\n * @remarks\n * Standard subclass extension pattern — each class owns only its own `toolMethods` and its\n * own `forgeTools`. The base `SpooledArtifact.forgeTools(ctx)` narrows the `callId` enum to\n * any `tc.results instanceof SpooledArtifact` (so subclass instances are included — that's\n * the whole point of inheritance) and dispatches the seven base methods (`head`, `tail`,\n * `grep`, `cat`, `byteLength`, `lineCount`, `estimateTokens`) on the resolved artifact.\n * Subclasses override `forgeTools` to call this static first and then register their own\n * tools on the returned registry — see {@link @nhtio/adk!SpooledJsonArtifact.forgeTools} and\n * {@link @nhtio/adk!SpooledMarkdownArtifact.forgeTools} for the canonical shape. There is no\n * `requiresSubclass` field, no helper indirection, and no `this`-based class narrowing —\n * just plain `instanceof ThisClass` at each subclass's own filter site.\n *\n * For each descriptor in this class's `toolMethods`, the factory:\n *\n * 1. Walks `ctx.turnToolCalls` to find `ToolCall`s whose `results instanceof SpooledArtifact`.\n * `ToolCall`s flagged `fromArtifactTool === true` are excluded — they carry a\n * {@link @nhtio/adk!Tokenizable}, not a `SpooledArtifact`, and including them would let the model\n * `artifact_grep` on a previous `artifact_grep` result (an infinite-recursion hazard with\n * no semantic value).\n * 2. Returns an empty registry if no compatible callIds are found — no point shipping tools\n * whose `callId` enum is empty.\n * 3. Otherwise mints an {@link @nhtio/adk!ArtifactTool} with `ephemeral: true` and `onCollision: 'replace'`\n * so multiple `Subclass.forgeTools(ctx)` outputs merge silently. The tool's `inputSchema`\n * includes a required `callId` field with `.valid(...compatibleIds)`, plus the descriptor's\n * own `argsSchema` fields.\n *\n * The handler resolves the artifact via `[...ctx.turnToolCalls].find(t => t.id === callId)`,\n * dispatches the descriptor's method, and serialises the return value (string → as-is;\n * string[] → newline-join; number → `String(n)`; otherwise `JSON.stringify(value, null, 2)`;\n * `descriptor.serialise` overrides the defaults). `grep` is special-cased: the handler\n * constructs `new RegExp(pattern, flags ?? '')` before invoking the artifact's `grep` method.\n *\n * The returned registry must be merged into the consumer's main registry and the main\n * registry must be bound to `ctx` via {@link @nhtio/adk!ToolRegistry.bindContext}:\n *\n * ```ts\n * const executor: DispatchExecutorFn = async (ctx) => {\n * const forged = SpooledArtifact.forgeTools(ctx)\n * const merged = ToolRegistry.merge([main, forged])\n * main.bindContext(ctx)\n * const result = await llm.invoke({ tools: merged.all(), ... })\n * ctx.ack() // ← ephemeral cleanup fires here\n * }\n * ```\n *\n * @warning You **must** call `registry.bindContext(ctx)` on the registry hosting these tools,\n * or ephemeral cleanup will not run and the `callId` enum in subsequent executor calls will\n * be stale (excluding new tool calls produced in the meantime).\n *\n * @param ctx - The execution context whose `turnToolCalls` snapshot defines the `callId` enum.\n * @returns A fresh `ToolRegistry`. Empty when `turnToolCalls` contains no compatible artifacts.\n *\n * @see {@link @nhtio/adk!ToolRegistry.bindContext}\n * @see {@link @nhtio/adk!ToolRegistry.merge}\n * @see {@link @nhtio/adk!DispatchContext.onAck}\n */\n public static forgeTools(ctx: DispatchContext): ToolRegistry {\n const requires: SpooledArtifactConstructor = SpooledArtifact\n const compatibleIds = collectArtifactCompatibleIds(ctx, requires)\n if (compatibleIds.length === 0) return new ToolRegistry([])\n\n const tools: ArtifactTool[] = []\n for (const descriptor of this.toolMethods) {\n const callIdSchema = validator\n .string()\n .valid(...compatibleIds)\n .required()\n .description('ToolCall id of the artifact to query.')\n\n const argsSchema = (descriptor.argsSchema ?? noArgsSchema).append({\n callId: callIdSchema,\n })\n\n const serialise = descriptor.serialise ?? defaultSerialise\n\n const tool = new ArtifactTool({\n name: descriptor.name,\n description: descriptor.description,\n inputSchema: argsSchema,\n ephemeral: true,\n onCollision: 'replace',\n handler: async (rawArgs, ctxInner) => {\n const args = rawArgs as Record<string, unknown> & { callId: string }\n const resolved = resolveArtifactById(ctxInner, args.callId, requires)\n if (!resolved) return `Error: no artifact with id ${args.callId} in this turn`\n const artifact = resolved.artifact\n const methodArgs: unknown[] = []\n if (descriptor.method === 'grep') {\n const pattern = args.pattern as string\n const flags = (args.flags as string | undefined) ?? ''\n methodArgs.push(new RegExp(pattern, flags))\n } else if (descriptor.method === 'head' || descriptor.method === 'tail') {\n methodArgs.push((args.n as number | undefined) ?? 10)\n } else if (descriptor.method === 'cat') {\n methodArgs.push(args.start as number | undefined, args.end as number | undefined)\n } else if (descriptor.method === 'estimateTokens') {\n methodArgs.push(args.encoding as TokenEncoding)\n }\n const fn = (artifact as unknown as Record<string, (...a: unknown[]) => unknown>)[\n descriptor.method\n ]\n if (typeof fn !== 'function') {\n return `Error: artifact has no method ${descriptor.method}`\n }\n const result = await Promise.resolve(fn.apply(artifact, methodArgs))\n return serialise(result)\n },\n })\n tools.push(tool)\n }\n return new ToolRegistry(tools)\n }\n}\n"],"mappings":"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"}