@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 +1 @@
1
- {"version":3,"file":"toon-B7Q9RWJF.cjs","names":["#options","#resolveParsed","#hasParsed","#parsed","#loadToonModule","#formatToonError"],"sources":["../src/batteries/artifacts/toon/exceptions.ts","../src/batteries/artifacts/toon/index.ts"],"sourcesContent":["/**\n * Battery-scoped exceptions for the TOON artifact battery.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/artifacts/toon` entry — re-exported from the\n * battery's own barrel per the battery-scoped-exceptions rule. These are the typed errors the\n * implementor-facing API throws; the agent-facing forge catches them and renders readable\n * failure strings the model can act on.\n */\n\nimport { createException } from '@nhtio/adk/factories'\n\n/**\n * Thrown when the TOON peer dependency cannot be loaded.\n *\n * @remarks\n * The @toon-format/toon package is an optional peer. If it is not installed, methods requiring\n * it throw this exception with installation instructions. The message template includes the package\n * name, a description of its purpose, the underlying error, and the exact install command, so the\n * consumer sees a complete, actionable message regardless of call site.\n */\nexport const E_TOON_PEER_MISSING = createException<[string]>(\n 'E_TOON_PEER_MISSING',\n 'the toon battery could not load its peer dependency \"@toon-format/toon\" (needed for TOON format artifact queries): %s — install it (pnpm add @toon-format/toon)',\n 'E_TOON_PEER_MISSING',\n 500\n)\n\n/**\n * Thrown when TOON decoding fails.\n *\n * @remarks\n * Wraps the underlying `ToonDecodeError` from the `@toon-format/toon` package, surfacing its\n * `line` and `source` properties so the model can self-correct.\n */\nexport const E_TOON_DECODE_FAILED = createException<[string]>(\n 'E_TOON_DECODE_FAILED',\n 'TOON decode error: %s',\n 'E_TOON_DECODE_FAILED',\n 422\n)\n","/**\n * TOON artifact battery — structured queries over TOON format artifacts.\n *\n * @module @nhtio/adk/batteries/artifacts/toon\n *\n * @remarks\n * Adds {@link SpooledToonArtifact}, a {@link @nhtio/adk!SpooledArtifact} specialisation for\n * structured TOON queries. TOON encodes the JSON data model in a compact text format; parsing\n * produces the same values as decoding JSON, so queries use {@link https://github.com/JSONPath-Plus/JSONPath JSONPath-Plus} for path navigation, exactly as {@link @nhtio/adk!SpooledJsonArtifact} does.\n *\n * Requires the optional peer `@toon-format/toon` (version `^4.1.1`). If it is not installed,\n * methods requiring it throw {@link E_TOON_PEER_MISSING} with installation instructions.\n *\n * Export note: {@link registerArtifactEncodables} must be called before any attempt to\n * `decode()` a spooled TOON artifact. Call it once at startup:\n *\n * ```ts\n * import { registerArtifactEncodables } from '@nhtio/adk/batteries/artifacts'\n * await registerArtifactEncodables()\n * ```\n */\n\nimport { v6 as uuidv6 } from 'uuid'\nimport { JSONPath } from 'jsonpath-plus'\nimport { validator } from '@nhtio/validation'\nimport { resolveSpoolReader } from '@nhtio/adk/common'\nimport { isInstanceOf, isObject } from '@nhtio/adk/guards'\nimport { E_TOON_PEER_MISSING, E_TOON_DECODE_FAILED } from './exceptions'\nimport {\n ArtifactTool,\n SpooledJsonArtifact,\n Tool,\n ToolRegistry,\n ReaderDescriptor,\n} from '@nhtio/adk/common'\n\n// Well-known @nhtio/encoder contract keys, resolved through the global symbol registry.\n// These are identical to the symbols core uses, with no import edge on the optional peer.\nconst ENCODE_METHOD: unique symbol = Symbol.for('@nhtio/encoder:toEncoded')\nconst DECODE_METHOD: unique symbol = Symbol.for('@nhtio/encoder:fromEncoded')\n\n/**\n * Lazily-loaded TOON module, cached as a module-level promise.\n *\n * @remarks\n * Shared across all instances of SpooledToonArtifact. Once the promise resolves or rejects,\n * the same promise is reused for all subsequent calls, ensuring the in-flight promise and\n * any error state are preserved globally.\n */\nlet toonModulePromise: Promise<Record<string, unknown>> | undefined\nimport {\n SpooledArtifact,\n collectArtifactCompatibleIds,\n resolveArtifactById,\n defaultSerialise,\n} from '@nhtio/adk/spooled_artifact'\nimport type { SpoolReader, ToolMethodDescriptor, DispatchContext } from '@nhtio/adk/types'\n\n/** Snapshot payload for the encoder contract; the encoder treats it as opaque. */\ntype AdkEncodableSnapshot = unknown\n\n/**\n * TOON decode options.\n *\n * @remarks\n * Passed to the `@toon-format/toon` `decode` function.\n */\nexport interface ToonDecodeOptions {\n /** The indent size used in the TOON encoding (default: 2). */\n indentSize?: number\n /** When `true`, reject non-standard TOON (default: `true`). */\n strict?: boolean\n}\n\n/**\n * A {@link @nhtio/adk!SpooledArtifact} specialisation that adds TOON-aware read operations.\n *\n * @remarks\n * Construct with an optional `options` object to control decoding. When omitted, the TOON is\n * decoded with `strict: true` (default). Once decoded (on first access), the parsed value is\n * cached for the lifetime of the instance.\n *\n * All TOON methods are async, consistent with {@link @nhtio/adk!SpooledArtifact}.\n *\n * Path-based methods (`toon_get`, `toon_filter`, `toon_pluck`) use\n * [JSONPath-Plus](https://github.com/JSONPath-Plus/JSONPath) expressions. Full JSONPath syntax\n * is supported, including recursive descent (`..`), filter expressions (`[?(@.age > 18)]`),\n * and union selectors.\n */\nexport class SpooledToonArtifact extends SpooledArtifact {\n #parsed: unknown\n #hasParsed: boolean = false\n #options: ToonDecodeOptions | undefined\n\n /**\n * @param reader - The backing store to read from.\n * @param options - Optional TOON decode options.\n */\n constructor(reader: SpoolReader, options?: ToonDecodeOptions) {\n super(reader)\n this.#options = options\n }\n\n /**\n * Returns `true` if `value` is a {@link SpooledToonArtifact} instance.\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. Matches the pattern used by every\n * other class guard in the ADK; safe against the dual-module-copy case where two distinct\n * `SpooledToonArtifact` classes coexist in the same realm.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link SpooledToonArtifact} instance.\n */\n public static isSpooledToonArtifact(value: unknown): value is SpooledToonArtifact {\n return isInstanceOf(value, 'SpooledToonArtifact', SpooledToonArtifact)\n }\n\n /**\n * The TOON-specific artifact-query descriptors this class adds on top of the base set.\n *\n * @remarks\n * Lists `artifact_toon_type`, `artifact_toon_keys`, `artifact_toon_length`,\n * `artifact_toon_get`, `artifact_toon_filter`, `artifact_toon_slice`, `artifact_toon_pluck`.\n * The base seven descriptors (`artifact_head`, etc.) are NOT included here — they are\n * forged separately by {@link SpooledToonArtifact.forgeTools}, which calls\n * `SpooledArtifact.forgeTools(ctx)` to produce the base-narrowed tools and then registers\n * its own TOON tools on the result. Downstream consumers building custom subclasses\n * should follow the same pattern: own only your own descriptors; override `forgeTools` to\n * compose with the base output.\n */\n public static toolMethods: ReadonlyArray<ToolMethodDescriptor> = Object.freeze([\n {\n name: 'artifact_toon_type',\n method: 'toon_type',\n description: 'Return the format of a TOON artifact produced earlier in this turn.',\n argsSchema: validator.object({}),\n },\n {\n name: 'artifact_toon_keys',\n method: 'toon_keys',\n description: 'Return the top-level keys of a TOON artifact produced earlier in this turn.',\n argsSchema: validator.object({}),\n },\n {\n name: 'artifact_toon_length',\n method: 'toon_length',\n description:\n 'Return the element count of a TOON artifact produced earlier in this turn (1 if the root is not an array).',\n argsSchema: validator.object({}),\n },\n {\n name: 'artifact_toon_get',\n method: 'toon_get',\n description:\n 'Evaluate a JSONPath expression against a TOON artifact produced earlier in this turn.',\n argsSchema: validator.object({\n path: validator.string().required().description(\"JSONPath expression, e.g. '$.user.name'.\"),\n }),\n },\n {\n name: 'artifact_toon_filter',\n method: 'toon_filter',\n description:\n 'Return elements of a TOON artifact (produced earlier in this turn) matched by a JSONPath filter.',\n argsSchema: validator.object({\n path: validator\n .string()\n .required()\n .description(\"JSONPath filter expression, e.g. '$[?(@.age>18)]'.\"),\n }),\n },\n {\n name: 'artifact_toon_slice',\n method: 'toon_slice',\n description:\n 'Return a slice of elements by index range from a TOON artifact produced earlier in this turn.',\n argsSchema: validator.object({\n start: validator\n .number()\n .integer()\n .min(0)\n .optional()\n .description('Start index (inclusive).'),\n end: validator.number().integer().min(0).optional().description('End index (exclusive).'),\n }),\n },\n {\n name: 'artifact_toon_pluck',\n method: 'toon_pluck',\n description:\n 'Return all values matched by a JSONPath expression across a TOON artifact produced earlier in this turn.',\n argsSchema: validator.object({\n path: validator.string().required().description(\"JSONPath expression, e.g. '$..name'.\"),\n }),\n },\n ])\n\n /**\n * Forges base-class tools plus TOON-specific tools narrowed to {@link SpooledToonArtifact}.\n *\n * @remarks\n * Standard subclass extension pattern: call `SpooledArtifact.forgeTools(ctx)` to produce\n * the base seven `artifact_*` tools narrowed to any `SpooledArtifact` in the turn, then\n * register one `ArtifactTool` per TOON-specific descriptor narrowed to TOON artifacts.\n * Downstream consumers building their own subclasses should follow the same shape.\n */\n public static override forgeTools(ctx: DispatchContext): ToolRegistry {\n const registry = SpooledArtifact.forgeTools(ctx)\n const requires = SpooledToonArtifact\n const compatibleIds = collectArtifactCompatibleIds(ctx, requires)\n if (compatibleIds.length === 0) return registry\n\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 = (\n descriptor.argsSchema ?? validator.object<Record<string, never>>({})\n ).append({\n callId: callIdSchema,\n })\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 (\n descriptor.method === 'toon_get' ||\n descriptor.method === 'toon_filter' ||\n descriptor.method === 'toon_pluck'\n ) {\n methodArgs.push(args.path as string)\n } else if (descriptor.method === 'toon_slice') {\n methodArgs.push(args.start as number | undefined, args.end as number | undefined)\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 const serialise = descriptor.serialise ?? defaultSerialise\n return serialise(result)\n },\n })\n registry.register(tool)\n }\n return registry\n }\n\n /**\n * Parses and caches the TOON content.\n *\n * @remarks\n * On first access, decodes the TOON source and caches the parsed value. Subsequent calls\n * return the cached value without re-parsing.\n *\n * @returns The parsed TOON value.\n */\n async #resolveParsed(): Promise<unknown> {\n if (this.#hasParsed) {\n return this.#parsed\n }\n const toonModule = await this.#loadToonModule()\n const text = await this.asString()\n try {\n const decode = toonModule.decode as (text: string, opts: Record<string, unknown>) => unknown\n this.#parsed = decode(text, {\n indentSize: this.#options?.indentSize ?? 2,\n strict: this.#options?.strict ?? true,\n })\n } catch (err) {\n const message = this.#formatToonError(err)\n throw new E_TOON_DECODE_FAILED([message])\n }\n this.#hasParsed = true\n return this.#parsed\n }\n\n /**\n * Formats an error from the TOON decoder, including line number and source.\n */\n #formatToonError(err: unknown): string {\n if (isObject(err) && (err as Record<string, unknown>).name === 'ToonDecodeError') {\n const toonErr = err as { line?: number; source?: string; message?: string }\n const line = toonErr.line ?? '?'\n const source = toonErr.source ?? '(no source)'\n return `line ${line}: ${source}`\n }\n return String((err as Record<string, unknown>).message ?? err)\n }\n\n /**\n * Loads the TOON module lazily, with error handling.\n *\n * @remarks\n * Uses the module-level `toonModulePromise` to ensure the in-flight promise and error state\n * are shared across all instances of SpooledToonArtifact.\n */\n async #loadToonModule() {\n toonModulePromise ??= import('@toon-format/toon').catch((err: unknown) => {\n throw new E_TOON_PEER_MISSING([String(err)])\n })\n return (await toonModulePromise) as Record<string, unknown>\n }\n\n /**\n * Returns the format of a TOON artifact.\n *\n * @remarks\n * Reports only the format name. The delimiter is deliberately not reported: the TOON decoder\n * exposes no delimiter information, and every method of inferring one from the source proved\n * unreliable for some class of strict-valid document. Four distinct approaches were attempted,\n * each defeated by its own edge case:\n * - Lexical scanning for the delimiter character failed on unquoted pipes inside values\n * - Anchored header regex requiring a word key failed on quoted keys and keyless root arrays\n * - Widened regex accepting quoted keys failed on escaped quotes within the key (e.g., \"a\\\"b\")\n * - Byte-exact round-trip re-encoding failed on non-canonical formatting (indentation, line\n * endings, trailing newlines)\n *\n * Delimiter inference is no longer attempted: nothing in the model's workflow needs it, and\n * the TOON decoder is the source of truth for all document metadata.\n *\n * This result is cached after the first parse and returned identically on every call.\n *\n * @returns An object with `format: 'toon'`.\n */\n async toon_type(): Promise<{ format: string }> {\n await this.#resolveParsed()\n return { format: 'toon' }\n }\n\n /**\n * Returns the top-level keys of the parsed TOON content.\n *\n * @remarks\n * - If the root is an object, returns its keys.\n * - If the root is not a plain object (e.g. an array or scalar), returns `undefined`.\n *\n * @returns Array of key strings, or `undefined` when the root is not an object.\n */\n async toon_keys(): Promise<string[] | undefined> {\n const value = await this.#resolveParsed()\n if (isObject(value)) {\n return Object.keys(value as object)\n }\n return undefined\n }\n\n /**\n * Returns the element count of the parsed TOON content.\n *\n * @remarks\n * - If the root is an array, returns the array length.\n * - Otherwise, returns `1` (the root is a single element).\n *\n * @returns The element count.\n */\n async toon_length(): Promise<number> {\n const value = await this.#resolveParsed()\n if (Array.isArray(value)) {\n return value.length\n }\n return 1\n }\n\n /**\n * Evaluates a JSONPath expression against the parsed TOON content.\n *\n * @remarks\n * Uses [JSONPath-Plus](https://github.com/JSONPath-Plus/JSONPath). Full JSONPath syntax is\n * supported: recursive descent (`$..*`), filter expressions (`$[?(@.age > 18)]`), union\n * selectors, and more.\n *\n * @param path - A JSONPath expression (e.g. `'$.user.address.city'`, `'$..name'`).\n * @returns Array of matched values. Empty array when no matches are found.\n */\n async toon_get(path: string): Promise<unknown[]> {\n const value = await this.#resolveParsed()\n return JSONPath({ path, json: value as object })\n }\n\n /**\n * Returns elements matched by a JSONPath filter expression.\n *\n * @remarks\n * Evaluates `path` against the root value and returns it in an array if matched.\n *\n * @param path - A JSONPath expression (e.g. `'$[?(@.status === \"active\")]'`).\n * @returns Array of matching elements (at most one element, the root if matched).\n */\n async toon_filter(path: string): Promise<unknown[]> {\n const value = await this.#resolveParsed()\n const matches = JSONPath({ path, json: value as object })\n return Array.isArray(matches) && matches.length > 0 ? [value] : []\n }\n\n /**\n * Returns a slice of the parsed content by index range.\n *\n * @remarks\n * - If the root is an array, behaves like `Array.prototype.slice`.\n * - If the root is not an array, returns the entire root in an array.\n *\n * @param start - Start index (inclusive). Defaults to `0`.\n * @param end - End index (exclusive). Defaults to the element count.\n * @returns Array of sliced elements.\n */\n async toon_slice(start?: number, end?: number): Promise<unknown[]> {\n const value = await this.#resolveParsed()\n if (Array.isArray(value)) {\n return value.slice(start, end)\n }\n return [value]\n }\n\n /**\n * Returns all values matched by a JSONPath expression.\n *\n * @remarks\n * Convenience over {@link SpooledToonArtifact.toon_get} with an identical signature — use\n * whichever name better communicates intent at the call site. `toon_pluck` reads well for\n * extracting a single field; `toon_get` reads well for structured queries.\n *\n * @param path - A JSONPath expression (e.g. `'$..name'`).\n * @returns Array of matched values.\n */\n async toon_pluck(path: string): Promise<unknown[]> {\n return this.toon_get(path)\n }\n\n /**\n * Serialise this SpooledToonArtifact into an `@nhtio/encoder` snapshot — the reader **handle** plus\n * the decode `options`.\n *\n * @remarks\n * Overrides {@link SpooledArtifact.[ENCODE_METHOD]} to carry the constructor's `options` (the\n * parsed-value cache is derived and not encoded). Round-trips via\n * {@link SpooledToonArtifact.[DECODE_METHOD]}.\n *\n * @returns A snapshot consumed by {@link SpooledToonArtifact.[DECODE_METHOD]}.\n */\n [ENCODE_METHOD](): AdkEncodableSnapshot {\n return { reader: this.readerDescriptor(), options: this.#options }\n }\n\n /**\n * Reconstruct a {@link SpooledToonArtifact} from a {@link SpooledToonArtifact.[ENCODE_METHOD]}\n * snapshot.\n *\n * @param data - The snapshot produced by {@link SpooledToonArtifact.[ENCODE_METHOD]}.\n * @returns A fresh {@link SpooledToonArtifact}} backed by a freshly-resolved reader.\n */\n static [DECODE_METHOD](data: AdkEncodableSnapshot): SpooledToonArtifact {\n const snapshot = data as {\n reader: ReaderDescriptor\n options?: ToonDecodeOptions\n }\n return new SpooledToonArtifact(resolveSpoolReader(snapshot.reader), snapshot.options)\n }\n}\n\n/**\n * Converter tool: TOON to JSON.\n *\n * @remarks\n * Accepts either inline TOON text or a reference to an artifact produced earlier in this turn.\n * Converts to JSON and returns a new {@link @nhtio/adk!SpooledJsonArtifact}.\n *\n * This is a plain {@link @nhtio/adk!Tool}, not an {@link @nhtio/adk!ArtifactTool} — the handler\n * returns the new artifact directly, allowing the forge to discover and query it on the next\n * iteration without explicit wiring.\n */\nexport const toonToJsonTool: Tool = new Tool({\n name: 'toon_to_json',\n description: 'Convert inline TOON text or a TOON artifact to JSON.',\n inputSchema: validator.object({\n text: validator\n .string()\n .optional()\n .allow('')\n .description('Inline TOON text. Provide this or call_id, not both.'),\n call_id: validator\n .string()\n .optional()\n .allow('')\n .description('ToolCall id of a TOON artifact produced earlier in this turn.'),\n }),\n artifactConstructor: () => SpooledJsonArtifact,\n handler: async (rawArgs: unknown, ctx: DispatchContext) => {\n const args = rawArgs as { text?: string; call_id?: string }\n const text = args.text ?? ''\n const callId = args.call_id ?? ''\n\n const hasText = text.length > 0\n const hasCallId = callId.length > 0\n\n if (!hasText && !hasCallId) {\n return 'Error: provide either text or call_id, not neither'\n }\n if (hasText && hasCallId) {\n return 'Error: provide either text or call_id, not both'\n }\n\n let toonContent: string\n if (hasCallId) {\n const resolved = resolveArtifactById(ctx, callId, SpooledToonArtifact)\n if (!resolved) {\n return `Error: no TOON artifact with id ${callId} in this turn`\n }\n toonContent = await resolved.artifact.asString()\n } else {\n toonContent = text\n }\n\n const toonModule = await import('@toon-format/toon').catch((err: unknown) => {\n throw new E_TOON_PEER_MISSING([String(err)])\n })\n\n let parsed: unknown\n try {\n const decode = toonModule.decode as (text: string, opts: Record<string, unknown>) => unknown\n parsed = decode(toonContent, { indentSize: 2, strict: true })\n } catch (err) {\n const message =\n isObject(err) && (err as Record<string, unknown>).name === 'ToonDecodeError'\n ? `line ${(err as { line?: number }).line ?? '?'}: ${(err as { source?: string }).source ?? '(no source)'}`\n : String((err as Record<string, unknown>).message ?? err)\n return `Error: failed to decode TOON: ${message}`\n }\n\n const json = JSON.stringify(parsed, null, 2)\n const sourceId = hasCallId ? callId : uuidv6()\n const reader = await ctx.storeRetrievableBytes(`${ctx.id}:toon_to_json:${sourceId}`, json)\n return new SpooledJsonArtifact(reader)\n },\n})\n\n/**\n * Converter tool: JSON to TOON.\n *\n * @remarks\n * Accepts either inline JSON text or a reference to a JSON artifact produced earlier in this turn.\n * Converts to TOON and returns a new {@link SpooledToonArtifact}.\n *\n * This is a plain {@link @nhtio/adk!Tool}, not an {@link @nhtio/adk!ArtifactTool} — the handler\n * returns the new artifact directly, allowing the forge to discover and query it on the next\n * iteration without explicit wiring.\n */\nexport const jsonToToonTool: Tool = new Tool({\n name: 'json_to_toon',\n description: 'Convert inline JSON text or a JSON artifact to TOON.',\n inputSchema: validator.object({\n text: validator\n .string()\n .optional()\n .allow('')\n .description('Inline JSON text. Provide this or call_id, not both.'),\n call_id: validator\n .string()\n .optional()\n .allow('')\n .description('ToolCall id of a JSON artifact produced earlier in this turn.'),\n }),\n artifactConstructor: () => SpooledToonArtifact,\n handler: async (rawArgs: unknown, ctx: DispatchContext) => {\n const args = rawArgs as { text?: string; call_id?: string }\n const text = args.text ?? ''\n const callId = args.call_id ?? ''\n\n const hasText = text.length > 0\n const hasCallId = callId.length > 0\n\n if (!hasText && !hasCallId) {\n return 'Error: provide either text or call_id, not neither'\n }\n if (hasText && hasCallId) {\n return 'Error: provide either text or call_id, not both'\n }\n\n let jsonContent: string\n if (hasCallId) {\n const resolved = resolveArtifactById(ctx, callId, SpooledJsonArtifact)\n if (!resolved) {\n return `Error: no JSON artifact with id ${callId} in this turn`\n }\n jsonContent = await resolved.artifact.asString()\n } else {\n jsonContent = text\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(jsonContent)\n } catch (err) {\n return `Error: failed to parse JSON: ${String((err as Record<string, unknown>).message ?? err)}`\n }\n\n const toonModule = await import('@toon-format/toon').catch((err: unknown) => {\n throw new E_TOON_PEER_MISSING([String(err)])\n })\n\n let toon: string\n try {\n const encode = toonModule.encode as (val: unknown, opts: Record<string, unknown>) => string\n toon = encode(parsed, { indentSize: 2 })\n } catch (err) {\n return `Error: failed to encode TOON: ${String((err as Record<string, unknown>).message ?? err)}`\n }\n\n const sourceId = hasCallId ? callId : uuidv6()\n const reader = await ctx.storeRetrievableBytes(`${ctx.id}:json_to_toon:${sourceId}`, toon)\n return new SpooledToonArtifact(reader)\n },\n})\n\n/**\n * Exports for the public barrel.\n */\nexport { E_TOON_PEER_MISSING, E_TOON_DECODE_FAILED } from './exceptions'\n"],"mappings":"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"}
1
+ {"version":3,"file":"toon-DmLwZ6H1.cjs","names":["#options","#resolveParsed","#hasParsed","#parsed","#loadToonModule","#formatToonError"],"sources":["../src/batteries/artifacts/toon/exceptions.ts","../src/batteries/artifacts/toon/index.ts"],"sourcesContent":["/**\n * Battery-scoped exceptions for the TOON artifact battery.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/artifacts/toon` entry — re-exported from the\n * battery's own barrel per the battery-scoped-exceptions rule. These are the typed errors the\n * implementor-facing API throws; the agent-facing forge catches them and renders readable\n * failure strings the model can act on.\n */\n\nimport { createException } from '@nhtio/adk/factories'\n\n/**\n * Thrown when the TOON peer dependency cannot be loaded.\n *\n * @remarks\n * The @toon-format/toon package is an optional peer. If it is not installed, methods requiring\n * it throw this exception with installation instructions. The message template includes the package\n * name, a description of its purpose, the underlying error, and the exact install command, so the\n * consumer sees a complete, actionable message regardless of call site.\n */\nexport const E_TOON_PEER_MISSING = createException<[string]>(\n 'E_TOON_PEER_MISSING',\n 'the toon battery could not load its peer dependency \"@toon-format/toon\" (needed for TOON format artifact queries): %s — install it (pnpm add @toon-format/toon)',\n 'E_TOON_PEER_MISSING',\n 500\n)\n\n/**\n * Thrown when TOON decoding fails.\n *\n * @remarks\n * Wraps the underlying `ToonDecodeError` from the `@toon-format/toon` package, surfacing its\n * `line` and `source` properties so the model can self-correct.\n */\nexport const E_TOON_DECODE_FAILED = createException<[string]>(\n 'E_TOON_DECODE_FAILED',\n 'TOON decode error: %s',\n 'E_TOON_DECODE_FAILED',\n 422\n)\n","/**\n * TOON artifact battery — structured queries over TOON format artifacts.\n *\n * @module @nhtio/adk/batteries/artifacts/toon\n *\n * @remarks\n * Adds {@link SpooledToonArtifact}, a {@link @nhtio/adk!SpooledArtifact} specialisation for\n * structured TOON queries. TOON encodes the JSON data model in a compact text format; parsing\n * produces the same values as decoding JSON, so queries use {@link https://github.com/JSONPath-Plus/JSONPath JSONPath-Plus} for path navigation, exactly as {@link @nhtio/adk!SpooledJsonArtifact} does.\n *\n * Requires the optional peer `@toon-format/toon` (version `^4.1.1`). If it is not installed,\n * methods requiring it throw {@link E_TOON_PEER_MISSING} with installation instructions.\n *\n * Export note: {@link registerArtifactEncodables} must be called before any attempt to\n * `decode()` a spooled TOON artifact. Call it once at startup:\n *\n * ```ts\n * import { registerArtifactEncodables } from '@nhtio/adk/batteries/artifacts'\n * await registerArtifactEncodables()\n * ```\n */\n\nimport { v6 as uuidv6 } from 'uuid'\nimport { JSONPath } from 'jsonpath-plus'\nimport { validator } from '@nhtio/validation'\nimport { resolveSpoolReader } from '@nhtio/adk/common'\nimport { isInstanceOf, isObject } from '@nhtio/adk/guards'\nimport { E_TOON_PEER_MISSING, E_TOON_DECODE_FAILED } from './exceptions'\nimport {\n ArtifactTool,\n SpooledJsonArtifact,\n Tool,\n ToolRegistry,\n ReaderDescriptor,\n} from '@nhtio/adk/common'\n\n// Well-known @nhtio/encoder contract keys, resolved through the global symbol registry.\n// These are identical to the symbols core uses, with no import edge on the optional peer.\nconst ENCODE_METHOD: unique symbol = Symbol.for('@nhtio/encoder:toEncoded')\nconst DECODE_METHOD: unique symbol = Symbol.for('@nhtio/encoder:fromEncoded')\n\n/**\n * Lazily-loaded TOON module, cached as a module-level promise.\n *\n * @remarks\n * Shared across all instances of SpooledToonArtifact. Once the promise resolves or rejects,\n * the same promise is reused for all subsequent calls, ensuring the in-flight promise and\n * any error state are preserved globally.\n */\nlet toonModulePromise: Promise<Record<string, unknown>> | undefined\nimport {\n SpooledArtifact,\n collectArtifactCompatibleIds,\n resolveArtifactById,\n defaultSerialise,\n} from '@nhtio/adk/spooled_artifact'\nimport type { SpoolReader, ToolMethodDescriptor, DispatchContext } from '@nhtio/adk/types'\n\n/** Snapshot payload for the encoder contract; the encoder treats it as opaque. */\ntype AdkEncodableSnapshot = unknown\n\n/**\n * TOON decode options.\n *\n * @remarks\n * Passed to the `@toon-format/toon` `decode` function.\n */\nexport interface ToonDecodeOptions {\n /** The indent size used in the TOON encoding (default: 2). */\n indentSize?: number\n /** When `true`, reject non-standard TOON (default: `true`). */\n strict?: boolean\n}\n\n/**\n * A {@link @nhtio/adk!SpooledArtifact} specialisation that adds TOON-aware read operations.\n *\n * @remarks\n * Construct with an optional `options` object to control decoding. When omitted, the TOON is\n * decoded with `strict: true` (default). Once decoded (on first access), the parsed value is\n * cached for the lifetime of the instance.\n *\n * All TOON methods are async, consistent with {@link @nhtio/adk!SpooledArtifact}.\n *\n * Path-based methods (`toon_get`, `toon_filter`, `toon_pluck`) use\n * [JSONPath-Plus](https://github.com/JSONPath-Plus/JSONPath) expressions. Full JSONPath syntax\n * is supported, including recursive descent (`..`), filter expressions (`[?(@.age > 18)]`),\n * and union selectors.\n */\nexport class SpooledToonArtifact extends SpooledArtifact {\n #parsed: unknown\n #hasParsed: boolean = false\n #options: ToonDecodeOptions | undefined\n\n /**\n * @param reader - The backing store to read from.\n * @param options - Optional TOON decode options.\n */\n constructor(reader: SpoolReader, options?: ToonDecodeOptions) {\n super(reader)\n this.#options = options\n }\n\n /**\n * Returns `true` if `value` is a {@link SpooledToonArtifact} instance.\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. Matches the pattern used by every\n * other class guard in the ADK; safe against the dual-module-copy case where two distinct\n * `SpooledToonArtifact` classes coexist in the same realm.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link SpooledToonArtifact} instance.\n */\n public static isSpooledToonArtifact(value: unknown): value is SpooledToonArtifact {\n return isInstanceOf(value, 'SpooledToonArtifact', SpooledToonArtifact)\n }\n\n /**\n * The TOON-specific artifact-query descriptors this class adds on top of the base set.\n *\n * @remarks\n * Lists `artifact_toon_type`, `artifact_toon_keys`, `artifact_toon_length`,\n * `artifact_toon_get`, `artifact_toon_filter`, `artifact_toon_slice`, `artifact_toon_pluck`.\n * The base seven descriptors (`artifact_head`, etc.) are NOT included here — they are\n * forged separately by {@link SpooledToonArtifact.forgeTools}, which calls\n * `SpooledArtifact.forgeTools(ctx)` to produce the base-narrowed tools and then registers\n * its own TOON tools on the result. Downstream consumers building custom subclasses\n * should follow the same pattern: own only your own descriptors; override `forgeTools` to\n * compose with the base output.\n */\n public static toolMethods: ReadonlyArray<ToolMethodDescriptor> = Object.freeze([\n {\n name: 'artifact_toon_type',\n method: 'toon_type',\n description: 'Return the format of a TOON artifact produced earlier in this turn.',\n argsSchema: validator.object({}),\n },\n {\n name: 'artifact_toon_keys',\n method: 'toon_keys',\n description: 'Return the top-level keys of a TOON artifact produced earlier in this turn.',\n argsSchema: validator.object({}),\n },\n {\n name: 'artifact_toon_length',\n method: 'toon_length',\n description:\n 'Return the element count of a TOON artifact produced earlier in this turn (1 if the root is not an array).',\n argsSchema: validator.object({}),\n },\n {\n name: 'artifact_toon_get',\n method: 'toon_get',\n description:\n 'Evaluate a JSONPath expression against a TOON artifact produced earlier in this turn.',\n argsSchema: validator.object({\n path: validator.string().required().description(\"JSONPath expression, e.g. '$.user.name'.\"),\n }),\n },\n {\n name: 'artifact_toon_filter',\n method: 'toon_filter',\n description:\n 'Return elements of a TOON artifact (produced earlier in this turn) matched by a JSONPath filter.',\n argsSchema: validator.object({\n path: validator\n .string()\n .required()\n .description(\"JSONPath filter expression, e.g. '$[?(@.age>18)]'.\"),\n }),\n },\n {\n name: 'artifact_toon_slice',\n method: 'toon_slice',\n description:\n 'Return a slice of elements by index range from a TOON artifact produced earlier in this turn.',\n argsSchema: validator.object({\n start: validator\n .number()\n .integer()\n .min(0)\n .optional()\n .description('Start index (inclusive).'),\n end: validator.number().integer().min(0).optional().description('End index (exclusive).'),\n }),\n },\n {\n name: 'artifact_toon_pluck',\n method: 'toon_pluck',\n description:\n 'Return all values matched by a JSONPath expression across a TOON artifact produced earlier in this turn.',\n argsSchema: validator.object({\n path: validator.string().required().description(\"JSONPath expression, e.g. '$..name'.\"),\n }),\n },\n ])\n\n /**\n * Forges base-class tools plus TOON-specific tools narrowed to {@link SpooledToonArtifact}.\n *\n * @remarks\n * Standard subclass extension pattern: call `SpooledArtifact.forgeTools(ctx)` to produce\n * the base seven `artifact_*` tools narrowed to any `SpooledArtifact` in the turn, then\n * register one `ArtifactTool` per TOON-specific descriptor narrowed to TOON artifacts.\n * Downstream consumers building their own subclasses should follow the same shape.\n */\n public static override forgeTools(ctx: DispatchContext): ToolRegistry {\n const registry = SpooledArtifact.forgeTools(ctx)\n const requires = SpooledToonArtifact\n const compatibleIds = collectArtifactCompatibleIds(ctx, requires)\n if (compatibleIds.length === 0) return registry\n\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 = (\n descriptor.argsSchema ?? validator.object<Record<string, never>>({})\n ).append({\n callId: callIdSchema,\n })\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 (\n descriptor.method === 'toon_get' ||\n descriptor.method === 'toon_filter' ||\n descriptor.method === 'toon_pluck'\n ) {\n methodArgs.push(args.path as string)\n } else if (descriptor.method === 'toon_slice') {\n methodArgs.push(args.start as number | undefined, args.end as number | undefined)\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 const serialise = descriptor.serialise ?? defaultSerialise\n return serialise(result)\n },\n })\n registry.register(tool)\n }\n return registry\n }\n\n /**\n * Parses and caches the TOON content.\n *\n * @remarks\n * On first access, decodes the TOON source and caches the parsed value. Subsequent calls\n * return the cached value without re-parsing.\n *\n * @returns The parsed TOON value.\n */\n async #resolveParsed(): Promise<unknown> {\n if (this.#hasParsed) {\n return this.#parsed\n }\n const toonModule = await this.#loadToonModule()\n const text = await this.asString()\n try {\n const decode = toonModule.decode as (text: string, opts: Record<string, unknown>) => unknown\n this.#parsed = decode(text, {\n indentSize: this.#options?.indentSize ?? 2,\n strict: this.#options?.strict ?? true,\n })\n } catch (err) {\n const message = this.#formatToonError(err)\n throw new E_TOON_DECODE_FAILED([message])\n }\n this.#hasParsed = true\n return this.#parsed\n }\n\n /**\n * Formats an error from the TOON decoder, including line number and source.\n */\n #formatToonError(err: unknown): string {\n if (isObject(err) && (err as Record<string, unknown>).name === 'ToonDecodeError') {\n const toonErr = err as { line?: number; source?: string; message?: string }\n const line = toonErr.line ?? '?'\n const source = toonErr.source ?? '(no source)'\n return `line ${line}: ${source}`\n }\n return String((err as Record<string, unknown>).message ?? err)\n }\n\n /**\n * Loads the TOON module lazily, with error handling.\n *\n * @remarks\n * Uses the module-level `toonModulePromise` to ensure the in-flight promise and error state\n * are shared across all instances of SpooledToonArtifact.\n */\n async #loadToonModule() {\n toonModulePromise ??= import('@toon-format/toon').catch((err: unknown) => {\n throw new E_TOON_PEER_MISSING([String(err)])\n })\n return (await toonModulePromise) as Record<string, unknown>\n }\n\n /**\n * Returns the format of a TOON artifact.\n *\n * @remarks\n * Reports only the format name. The delimiter is deliberately not reported: the TOON decoder\n * exposes no delimiter information, and every method of inferring one from the source proved\n * unreliable for some class of strict-valid document. Four distinct approaches were attempted,\n * each defeated by its own edge case:\n * - Lexical scanning for the delimiter character failed on unquoted pipes inside values\n * - Anchored header regex requiring a word key failed on quoted keys and keyless root arrays\n * - Widened regex accepting quoted keys failed on escaped quotes within the key (e.g., \"a\\\"b\")\n * - Byte-exact round-trip re-encoding failed on non-canonical formatting (indentation, line\n * endings, trailing newlines)\n *\n * Delimiter inference is no longer attempted: nothing in the model's workflow needs it, and\n * the TOON decoder is the source of truth for all document metadata.\n *\n * This result is cached after the first parse and returned identically on every call.\n *\n * @returns An object with `format: 'toon'`.\n */\n async toon_type(): Promise<{ format: string }> {\n await this.#resolveParsed()\n return { format: 'toon' }\n }\n\n /**\n * Returns the top-level keys of the parsed TOON content.\n *\n * @remarks\n * - If the root is an object, returns its keys.\n * - If the root is not a plain object (e.g. an array or scalar), returns `undefined`.\n *\n * @returns Array of key strings, or `undefined` when the root is not an object.\n */\n async toon_keys(): Promise<string[] | undefined> {\n const value = await this.#resolveParsed()\n if (isObject(value)) {\n return Object.keys(value as object)\n }\n return undefined\n }\n\n /**\n * Returns the element count of the parsed TOON content.\n *\n * @remarks\n * - If the root is an array, returns the array length.\n * - Otherwise, returns `1` (the root is a single element).\n *\n * @returns The element count.\n */\n async toon_length(): Promise<number> {\n const value = await this.#resolveParsed()\n if (Array.isArray(value)) {\n return value.length\n }\n return 1\n }\n\n /**\n * Evaluates a JSONPath expression against the parsed TOON content.\n *\n * @remarks\n * Uses [JSONPath-Plus](https://github.com/JSONPath-Plus/JSONPath). Full JSONPath syntax is\n * supported: recursive descent (`$..*`), filter expressions (`$[?(@.age > 18)]`), union\n * selectors, and more.\n *\n * @param path - A JSONPath expression (e.g. `'$.user.address.city'`, `'$..name'`).\n * @returns Array of matched values. Empty array when no matches are found.\n */\n async toon_get(path: string): Promise<unknown[]> {\n const value = await this.#resolveParsed()\n return JSONPath({ path, json: value as object })\n }\n\n /**\n * Returns elements matched by a JSONPath filter expression.\n *\n * @remarks\n * Evaluates `path` against the root value and returns it in an array if matched.\n *\n * @param path - A JSONPath expression (e.g. `'$[?(@.status === \"active\")]'`).\n * @returns Array of matching elements (at most one element, the root if matched).\n */\n async toon_filter(path: string): Promise<unknown[]> {\n const value = await this.#resolveParsed()\n const matches = JSONPath({ path, json: value as object })\n return Array.isArray(matches) && matches.length > 0 ? [value] : []\n }\n\n /**\n * Returns a slice of the parsed content by index range.\n *\n * @remarks\n * - If the root is an array, behaves like `Array.prototype.slice`.\n * - If the root is not an array, returns the entire root in an array.\n *\n * @param start - Start index (inclusive). Defaults to `0`.\n * @param end - End index (exclusive). Defaults to the element count.\n * @returns Array of sliced elements.\n */\n async toon_slice(start?: number, end?: number): Promise<unknown[]> {\n const value = await this.#resolveParsed()\n if (Array.isArray(value)) {\n return value.slice(start, end)\n }\n return [value]\n }\n\n /**\n * Returns all values matched by a JSONPath expression.\n *\n * @remarks\n * Convenience over {@link SpooledToonArtifact.toon_get} with an identical signature — use\n * whichever name better communicates intent at the call site. `toon_pluck` reads well for\n * extracting a single field; `toon_get` reads well for structured queries.\n *\n * @param path - A JSONPath expression (e.g. `'$..name'`).\n * @returns Array of matched values.\n */\n async toon_pluck(path: string): Promise<unknown[]> {\n return this.toon_get(path)\n }\n\n /**\n * Serialise this SpooledToonArtifact into an `@nhtio/encoder` snapshot — the reader **handle** plus\n * the decode `options`.\n *\n * @remarks\n * Overrides {@link SpooledArtifact.[ENCODE_METHOD]} to carry the constructor's `options` (the\n * parsed-value cache is derived and not encoded). Round-trips via\n * {@link SpooledToonArtifact.[DECODE_METHOD]}.\n *\n * @returns A snapshot consumed by {@link SpooledToonArtifact.[DECODE_METHOD]}.\n */\n [ENCODE_METHOD](): AdkEncodableSnapshot {\n return { reader: this.readerDescriptor(), options: this.#options }\n }\n\n /**\n * Reconstruct a {@link SpooledToonArtifact} from a {@link SpooledToonArtifact.[ENCODE_METHOD]}\n * snapshot.\n *\n * @param data - The snapshot produced by {@link SpooledToonArtifact.[ENCODE_METHOD]}.\n * @returns A fresh {@link SpooledToonArtifact}} backed by a freshly-resolved reader.\n */\n static [DECODE_METHOD](data: AdkEncodableSnapshot): SpooledToonArtifact {\n const snapshot = data as {\n reader: ReaderDescriptor\n options?: ToonDecodeOptions\n }\n return new SpooledToonArtifact(resolveSpoolReader(snapshot.reader), snapshot.options)\n }\n}\n\n/**\n * Converter tool: TOON to JSON.\n *\n * @remarks\n * Accepts either inline TOON text or a reference to an artifact produced earlier in this turn.\n * Converts to JSON and returns a new {@link @nhtio/adk!SpooledJsonArtifact}.\n *\n * This is a plain {@link @nhtio/adk!Tool}, not an {@link @nhtio/adk!ArtifactTool} — the handler\n * returns the new artifact directly, allowing the forge to discover and query it on the next\n * iteration without explicit wiring.\n */\nexport const toonToJsonTool: Tool = new Tool({\n name: 'toon_to_json',\n description: 'Convert inline TOON text or a TOON artifact to JSON.',\n inputSchema: validator.object({\n text: validator\n .string()\n .optional()\n .allow('')\n .description('Inline TOON text. Provide this or call_id, not both.'),\n call_id: validator\n .string()\n .optional()\n .allow('')\n .description('ToolCall id of a TOON artifact produced earlier in this turn.'),\n }),\n artifactConstructor: () => SpooledJsonArtifact,\n handler: async (rawArgs: unknown, ctx: DispatchContext) => {\n const args = rawArgs as { text?: string; call_id?: string }\n const text = args.text ?? ''\n const callId = args.call_id ?? ''\n\n const hasText = text.length > 0\n const hasCallId = callId.length > 0\n\n if (!hasText && !hasCallId) {\n return 'Error: provide either text or call_id, not neither'\n }\n if (hasText && hasCallId) {\n return 'Error: provide either text or call_id, not both'\n }\n\n let toonContent: string\n if (hasCallId) {\n const resolved = resolveArtifactById(ctx, callId, SpooledToonArtifact)\n if (!resolved) {\n return `Error: no TOON artifact with id ${callId} in this turn`\n }\n toonContent = await resolved.artifact.asString()\n } else {\n toonContent = text\n }\n\n const toonModule = await import('@toon-format/toon').catch((err: unknown) => {\n throw new E_TOON_PEER_MISSING([String(err)])\n })\n\n let parsed: unknown\n try {\n const decode = toonModule.decode as (text: string, opts: Record<string, unknown>) => unknown\n parsed = decode(toonContent, { indentSize: 2, strict: true })\n } catch (err) {\n const message =\n isObject(err) && (err as Record<string, unknown>).name === 'ToonDecodeError'\n ? `line ${(err as { line?: number }).line ?? '?'}: ${(err as { source?: string }).source ?? '(no source)'}`\n : String((err as Record<string, unknown>).message ?? err)\n return `Error: failed to decode TOON: ${message}`\n }\n\n const json = JSON.stringify(parsed, null, 2)\n const sourceId = hasCallId ? callId : uuidv6()\n const reader = await ctx.storeRetrievableBytes(`${ctx.id}:toon_to_json:${sourceId}`, json)\n return new SpooledJsonArtifact(reader)\n },\n})\n\n/**\n * Converter tool: JSON to TOON.\n *\n * @remarks\n * Accepts either inline JSON text or a reference to a JSON artifact produced earlier in this turn.\n * Converts to TOON and returns a new {@link SpooledToonArtifact}.\n *\n * This is a plain {@link @nhtio/adk!Tool}, not an {@link @nhtio/adk!ArtifactTool} — the handler\n * returns the new artifact directly, allowing the forge to discover and query it on the next\n * iteration without explicit wiring.\n */\nexport const jsonToToonTool: Tool = new Tool({\n name: 'json_to_toon',\n description: 'Convert inline JSON text or a JSON artifact to TOON.',\n inputSchema: validator.object({\n text: validator\n .string()\n .optional()\n .allow('')\n .description('Inline JSON text. Provide this or call_id, not both.'),\n call_id: validator\n .string()\n .optional()\n .allow('')\n .description('ToolCall id of a JSON artifact produced earlier in this turn.'),\n }),\n artifactConstructor: () => SpooledToonArtifact,\n handler: async (rawArgs: unknown, ctx: DispatchContext) => {\n const args = rawArgs as { text?: string; call_id?: string }\n const text = args.text ?? ''\n const callId = args.call_id ?? ''\n\n const hasText = text.length > 0\n const hasCallId = callId.length > 0\n\n if (!hasText && !hasCallId) {\n return 'Error: provide either text or call_id, not neither'\n }\n if (hasText && hasCallId) {\n return 'Error: provide either text or call_id, not both'\n }\n\n let jsonContent: string\n if (hasCallId) {\n const resolved = resolveArtifactById(ctx, callId, SpooledJsonArtifact)\n if (!resolved) {\n return `Error: no JSON artifact with id ${callId} in this turn`\n }\n jsonContent = await resolved.artifact.asString()\n } else {\n jsonContent = text\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(jsonContent)\n } catch (err) {\n return `Error: failed to parse JSON: ${String((err as Record<string, unknown>).message ?? err)}`\n }\n\n const toonModule = await import('@toon-format/toon').catch((err: unknown) => {\n throw new E_TOON_PEER_MISSING([String(err)])\n })\n\n let toon: string\n try {\n const encode = toonModule.encode as (val: unknown, opts: Record<string, unknown>) => string\n toon = encode(parsed, { indentSize: 2 })\n } catch (err) {\n return `Error: failed to encode TOON: ${String((err as Record<string, unknown>).message ?? err)}`\n }\n\n const sourceId = hasCallId ? callId : uuidv6()\n const reader = await ctx.storeRetrievableBytes(`${ctx.id}:json_to_toon:${sourceId}`, toon)\n return new SpooledToonArtifact(reader)\n },\n})\n\n/**\n * Exports for the public barrel.\n */\nexport { E_TOON_PEER_MISSING, E_TOON_DECODE_FAILED } from './exceptions'\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  const require_exceptions = require("./exceptions-DrHnAGQz.cjs");
2
- require("./factories.cjs");
3
2
  const require_guards = require("./guards-5-XmJgD2.cjs");
3
+ require("./factories.cjs");
4
4
  require("./guards.cjs");
5
5
  const require_lib_utils_audio = require("./lib/utils/audio.cjs");
6
6
  const require_lifecycle = require("./lifecycle-vYQJ2rmf.cjs");
@@ -290,4 +290,4 @@ Object.defineProperty(exports, "validateOptions", {
290
290
  }
291
291
  });
292
292
 
293
- //# sourceMappingURL=transformers_js-DM01eAzh.cjs.map
293
+ //# sourceMappingURL=transformers_js-7OzeS_Tp.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"transformers_js-DM01eAzh.cjs","names":["#options","#pipeline","#resolvePipeline","#pipelinePromise","#toPcm16k"],"sources":["../src/batteries/specialists/stt/transformers_js/exceptions.ts","../src/batteries/specialists/stt/transformers_js/validation.ts","../src/batteries/specialists/stt/transformers_js/adapter.ts"],"sourcesContent":["/**\n * Battery-scoped exception constructors for the transformers.js STT adapter.\n *\n * @remarks\n * Battery-scoped exception classes for the transformers.js (`@huggingface/transformers`)\n * speech-to-text adapter, minted via `createException` from `@nhtio/adk/factories`. Categories mirror\n * the transformers.js Embeddings battery one-to-one — only the engine-specific failure differs.\n */\n\nimport { createException } from '@nhtio/adk/factories'\n\n/**\n * Thrown when the resolved adapter options fail validation against\n * `transformersJsSttAdapterOptionsSchema` — e.g. a missing/empty `model` or an unknown option key.\n * Fatal: config bugs fail loud, not at transcribe time.\n */\nexport const E_INVALID_TRANSFORMERS_JS_STT_OPTIONS = createException<[string]>(\n 'E_INVALID_TRANSFORMERS_JS_STT_OPTIONS',\n 'Invalid transformers.js STT adapter options: %s',\n 'E_INVALID_TRANSFORMERS_JS_STT_OPTIONS',\n 529,\n true\n)\n\n/**\n * Thrown when the transformers.js pipeline fails to load (e.g. the `@huggingface/transformers` peer\n * is not installed) or the `automatic-speech-recognition` call throws/returns a malformed result.\n * Non-fatal. Printf arg: `[detail]`.\n */\nexport const E_TRANSFORMERS_JS_STT_ENGINE_ERROR = createException<[string]>(\n 'E_TRANSFORMERS_JS_STT_ENGINE_ERROR',\n 'transformers.js STT engine error: %s',\n 'E_TRANSFORMERS_JS_STT_ENGINE_ERROR',\n 502,\n false\n)\n","/**\n * Runtime validation schema and wrapper for transformers.js STT adapter options.\n *\n * @remarks\n * Validates `TransformersJsSttAdapterOptions` at construction time. Throws\n * `E_INVALID_TRANSFORMERS_JS_STT_OPTIONS` on failure. `model` is required; unknown top-level keys are\n * rejected so typos fail loud.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validator, ValidationError } from '@nhtio/validation'\nimport { E_INVALID_TRANSFORMERS_JS_STT_OPTIONS } from './exceptions'\nimport type { TransformersJsSttAdapterOptions } from './types'\n\n/** Validator schema for `TransformersJsSttAdapterOptions`. Rejects unknown top-level keys. */\nexport const transformersJsSttAdapterOptionsSchema = validator\n .object<TransformersJsSttAdapterOptions>({\n model: validator.string().min(1).required(),\n // Pipeline knobs (the transformers.js pipeline is a callable object — accept function or object)\n pipeline: validator\n .alternatives(validator.function(), validator.object().unknown(true))\n .optional(),\n createPipeline: validator.function().optional(),\n device: validator.string().optional(),\n dtype: validator.string().optional(),\n chunkLengthS: validator.number().positive().default(30),\n decodeAudio: validator.function().optional(),\n modelSource: validator.function().optional(),\n onInitProgress: validator.function().optional(),\n isAvailable: validator.function().optional(),\n // ── Lifecycle hooks (opt-in, normalized phase machine; additive over onInitProgress) ──\n onLifecycle: validator.function().optional(),\n onLoading: validator.function().optional(),\n onCompiling: validator.function().optional(),\n onReady: validator.function().optional(),\n onGenerating: validator.function().optional(),\n onComplete: validator.function().optional(),\n onError: validator.function().optional(),\n })\n .unknown(false)\n\nconst isValidationError = (value: unknown): value is ValidationError =>\n isError(value) && Array.isArray((value as ValidationError).details)\n\nconst formatValidationDetails = (err: ValidationError): string =>\n err.details.map((d) => d.message).join(' and ')\n\n/**\n * Validates an arbitrary input against `transformersJsSttAdapterOptionsSchema`.\n *\n * @param input - The raw options object to validate.\n * @returns The resolved options object with defaults filled in.\n * @throws {@link @nhtio/adk/batteries!E_INVALID_TRANSFORMERS_JS_STT_OPTIONS} when invalid.\n */\nexport const validateOptions = (input: unknown): TransformersJsSttAdapterOptions => {\n const { value, error } = transformersJsSttAdapterOptionsSchema.validate(input, {\n abortEarly: false,\n convert: false,\n })\n if (error && isValidationError(error)) {\n throw new E_INVALID_TRANSFORMERS_JS_STT_OPTIONS([formatValidationDetails(error)], {\n cause: error,\n })\n }\n return value as TransformersJsSttAdapterOptions\n}\n","/**\n * transformers.js (ONNX, dual-environment) STT (speech-to-text) adapter battery.\n *\n * @remarks\n * Specialist battery backed by transformers.js's `automatic-speech-recognition` (Whisper-family)\n * pipeline. **Environment-neutral** — runs in Node (via `onnxruntime-node`) and the browser (via\n * `onnxruntime-web` / WebGPU), auto-selected by the package; there is no WebGPU requirement, mirroring\n * the transformers.js Embeddings battery this adapter is modeled on.\n *\n * Accepts any {@link @nhtio/adk/batteries/specialists/_shared!SpecialistAudioInput} form: already-\n * decoded mono PCM (skips decoding), or an encoded container (bytes / bytes+mime / a duck-typed\n * `Media`) decoded via an injectable {@link DecodeAudioFn}. Either path is resampled to the 16 kHz mono\n * PCM Whisper expects before the pipeline call.\n *\n * `@huggingface/transformers` is an optional peer dependency, imported lazily.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validateOptions } from './validation'\nimport { resampleTo } from '../../../../lib/utils/audio'\nimport { emitLifecycle } from '../../../llm/chat_common/lifecycle'\nimport { isPcmInput, toBytes, defaultDecodeAudio } from '../../_shared'\nimport { withModelSource } from '../../../llm/transformers_js/model_source'\nimport {\n E_INVALID_TRANSFORMERS_JS_STT_OPTIONS,\n E_TRANSFORMERS_JS_STT_ENGINE_ERROR,\n} from './exceptions'\nimport type { SpecialistAudioInput } from '../../_shared'\nimport type {\n TransformersJsSttAdapterOptions,\n TransformersJsSttPipeline,\n CreateTransformersJsSttPipeline,\n TranscribeOptions,\n TranscribeResult,\n SttSegment,\n} from './types'\n\n/** The shape the transformers.js ASR pipeline resolves to (a subset of its documented output). */\ninterface AsrChunk {\n /** `[start, end]` in seconds; `end` may be `null` when the engine cannot bound the chunk. */\n timestamp: [number, number | null]\n /** The chunk's recognized text. */\n text: string\n}\n\ninterface AsrPipelineOutput {\n text: string\n chunks?: AsrChunk[]\n}\n\nconst makeDefaultCreatePipeline = (\n modelSource: TransformersJsSttAdapterOptions['modelSource']\n): CreateTransformersJsSttPipeline => {\n return async ({ model, device, dtype, onInitProgress }) => {\n const transformers = await import('@huggingface/transformers')\n const { pipeline, env } = transformers\n const load = async () =>\n (await pipeline('automatic-speech-recognition', model, {\n ...(device ? { device } : {}),\n ...(dtype ? { dtype } : {}),\n ...(onInitProgress ? { progress_callback: onInitProgress } : {}),\n } as never)) as unknown as TransformersJsSttPipeline\n // When a custom model source is configured, serve files through it behind the global-`env` mutex.\n return modelSource ? withModelSource(env as never, modelSource, load) : load()\n }\n}\n\n/**\n * STT adapter for transformers.js's automatic-speech-recognition (Whisper-family) pipeline.\n *\n * @remarks\n * Reusable: construct once, call {@link TransformersJsSttAdapter.transcribe} as many times as needed.\n * The pipeline is resolved lazily on first use (or via {@link preload}) and cached with single-flight\n * semantics so concurrent calls share one load.\n */\nexport class TransformersJsSttAdapter {\n readonly #options: TransformersJsSttAdapterOptions\n #pipeline: TransformersJsSttPipeline | undefined\n #pipelinePromise: Promise<TransformersJsSttPipeline> | undefined\n\n /**\n * Whether this battery is available. transformers.js is environment-neutral (Node + browser), so\n * this is `true` whenever the runtime can import the peer — there is no WebGPU requirement.\n */\n public static isAvailable(): boolean {\n return true\n }\n\n /**\n * @param options - Constructor options. Validated eagerly.\n * @throws {@link @nhtio/adk/batteries!E_INVALID_TRANSFORMERS_JS_STT_OPTIONS} when invalid.\n */\n constructor(options: unknown) {\n this.#options = validateOptions(options)\n this.#pipeline = this.#options.pipeline\n }\n\n /** Instance availability probe (honours an injected `isAvailable`). */\n isAvailable(): boolean {\n return (this.#options.isAvailable ?? TransformersJsSttAdapter.isAvailable)()\n }\n\n /** Eagerly loads (and caches) the pipeline so the first `transcribe` call is fast. Idempotent. */\n async preload(): Promise<void> {\n await this.#resolvePipeline()\n }\n\n /** Drops the cached pipeline and in-flight load so the next call reloads. */\n reset(): void {\n this.#pipeline = undefined\n this.#pipelinePromise = undefined\n }\n\n /**\n * Release the loaded model's ONNX sessions + GPU/wasm buffers, then drop the cached pipeline.\n *\n * @remarks\n * `reset()` only nulls the JS reference; the native ONNX Runtime sessions and WebGPU/wasm device\n * memory stay alive until GC. `AutomaticSpeechRecognitionPipeline` extends `Pipeline`, which exposes\n * `dispose()` — this awaits it so the memory is reclaimed between loads, swallows a disposal error\n * (teardown must not throw), and finishes with `reset()`. Idempotent.\n */\n async dispose(): Promise<void> {\n const pipeline = this.#pipeline ?? (await this.#pipelinePromise?.catch(() => undefined))\n const pipeWithDispose = pipeline as { dispose?: () => Promise<unknown> } | undefined\n if (typeof pipeWithDispose?.dispose === 'function') {\n await Promise.resolve(pipeWithDispose.dispose()).catch(() => undefined)\n }\n this.reset()\n }\n\n async #resolvePipeline(): Promise<TransformersJsSttPipeline> {\n if (this.#pipeline) return this.#pipeline\n if (!this.isAvailable()) {\n throw new E_INVALID_TRANSFORMERS_JS_STT_OPTIONS([\n 'the transformers.js STT battery is not available in this runtime',\n ])\n }\n const opts = this.#options\n this.#pipelinePromise ??= (async () => {\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'loading', {\n detail: 'loading automatic-speech-recognition pipeline',\n })\n // Forward each provider download event into a normalized `loading` lifecycle report.\n const hasLifecycle =\n opts.onLifecycle ?? opts.onLoading ?? opts.onReady ?? opts.onGenerating ?? opts.onError\n const forwardedInitProgress = hasLifecycle\n ? (info: unknown) => {\n const p = (info as { progress?: number } | undefined)?.progress\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'loading', {\n ...(typeof p === 'number' ? { progress: p / 100 } : {}),\n raw: info,\n })\n opts.onInitProgress?.(info as never)\n }\n : opts.onInitProgress\n const createPipeline = opts.createPipeline ?? makeDefaultCreatePipeline(opts.modelSource)\n try {\n // `from_pretrained` covers both fetch (reported via progress_callback → `loading`) and the\n // ONNX-graph / WebGPU-WASM warmup. Mark the latter as `compiling` — a COARSE upper-bound marker\n // (fetch + compile overlap inside the call), consistent with the LLM/embeddings batteries.\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'compiling', {\n detail: 'compiling automatic-speech-recognition graph',\n })\n const pipe = await createPipeline({\n model: opts.model,\n device: opts.device,\n dtype: opts.dtype,\n onInitProgress: forwardedInitProgress,\n })\n this.#pipeline = pipe\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'ready', {\n detail: 'automatic-speech-recognition pipeline ready',\n })\n return pipe\n } catch (err) {\n this.#pipelinePromise = undefined\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'error', { error: err })\n throw new E_TRANSFORMERS_JS_STT_ENGINE_ERROR([\n `could not load the transformers.js pipeline: ${isError(err) ? err.message : String(err)} — install the peer dependency (pnpm add @huggingface/transformers)`,\n ])\n }\n })()\n return this.#pipelinePromise\n }\n\n /**\n * Normalizes any accepted audio input form to 16 kHz mono PCM, the shape the Whisper pipeline\n * expects.\n *\n * @remarks\n * Already-decoded {@link @nhtio/adk/batteries/specialists/_shared!SpecialistPcmInput} is resampled\n * directly (a no-op when already 16 kHz — {@link resampleTo} returns the same reference in that\n * case). Any encoded-container form is normalized to bytes via\n * {@link @nhtio/adk/batteries/specialists/_shared!toBytes}, decoded via the injected/default\n * {@link @nhtio/adk/batteries/specialists/_shared!DecodeAudioFn} (already mono per that seam's\n * contract), then resampled.\n *\n * @param input - The audio input in any accepted form.\n * @returns 16 kHz mono PCM samples.\n */\n async #toPcm16k(input: SpecialistAudioInput): Promise<Float32Array> {\n if (isPcmInput(input)) {\n return resampleTo(input.pcm, input.sampleRate, 16000)\n }\n const { bytes } = await toBytes(input)\n const decode = this.#options.decodeAudio ?? defaultDecodeAudio\n const decoded = await decode(bytes)\n return resampleTo(decoded.pcm, decoded.sampleRate, 16000)\n }\n\n /**\n * Transcribes an audio clip.\n *\n * @param input - The audio input, in any {@link @nhtio/adk/batteries/specialists/_shared!SpecialistAudioInput}\n * form (pre-decoded PCM or an encoded container).\n * @param opts - Per-call transcription options (language / translate / timestamps).\n * @returns The recognized text, plus per-segment timing when `opts.timestamps` was set.\n * @throws {@link @nhtio/adk/batteries!E_TRANSFORMERS_JS_STT_ENGINE_ERROR} when the pipeline fails to\n * load or the transcription call fails.\n */\n async transcribe(\n input: SpecialistAudioInput,\n opts?: TranscribeOptions\n ): Promise<TranscribeResult> {\n const pcm = await this.#toPcm16k(input)\n const pipe = await this.#resolvePipeline()\n const chunkLengthS = this.#options.chunkLengthS ?? 30\n\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'generating')\n\n let output: AsrPipelineOutput\n try {\n const result = await (\n pipe as unknown as (\n audio: Float32Array,\n options: Record<string, unknown>\n ) => Promise<AsrPipelineOutput | AsrPipelineOutput[]>\n )(pcm, {\n chunk_length_s: chunkLengthS,\n ...(opts?.language ? { language: opts.language } : {}),\n ...(opts?.translate ? { task: 'translate' } : {}),\n ...(opts?.timestamps ? { return_timestamps: true } : {}),\n })\n output = Array.isArray(result) ? result[0] : result\n } catch (err) {\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'error', {\n error: err,\n })\n throw new E_TRANSFORMERS_JS_STT_ENGINE_ERROR([isError(err) ? err.message : String(err)])\n }\n\n if (!output || typeof output.text !== 'string') {\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'error', {\n error: new Error('automatic-speech-recognition returned a malformed result'),\n })\n throw new E_TRANSFORMERS_JS_STT_ENGINE_ERROR([\n 'automatic-speech-recognition returned a malformed result',\n ])\n }\n\n let segments: SttSegment[] | undefined\n if (opts?.timestamps && Array.isArray(output.chunks)) {\n segments = output.chunks.map((chunk) => ({\n start: chunk.timestamp[0],\n end: chunk.timestamp[1] ?? null,\n text: chunk.text,\n }))\n }\n\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'complete')\n return segments ? { text: output.text, segments } : { text: output.text }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"transformers_js-7OzeS_Tp.cjs","names":["#options","#pipeline","#resolvePipeline","#pipelinePromise","#toPcm16k"],"sources":["../src/batteries/specialists/stt/transformers_js/exceptions.ts","../src/batteries/specialists/stt/transformers_js/validation.ts","../src/batteries/specialists/stt/transformers_js/adapter.ts"],"sourcesContent":["/**\n * Battery-scoped exception constructors for the transformers.js STT adapter.\n *\n * @remarks\n * Battery-scoped exception classes for the transformers.js (`@huggingface/transformers`)\n * speech-to-text adapter, minted via `createException` from `@nhtio/adk/factories`. Categories mirror\n * the transformers.js Embeddings battery one-to-one — only the engine-specific failure differs.\n */\n\nimport { createException } from '@nhtio/adk/factories'\n\n/**\n * Thrown when the resolved adapter options fail validation against\n * `transformersJsSttAdapterOptionsSchema` — e.g. a missing/empty `model` or an unknown option key.\n * Fatal: config bugs fail loud, not at transcribe time.\n */\nexport const E_INVALID_TRANSFORMERS_JS_STT_OPTIONS = createException<[string]>(\n 'E_INVALID_TRANSFORMERS_JS_STT_OPTIONS',\n 'Invalid transformers.js STT adapter options: %s',\n 'E_INVALID_TRANSFORMERS_JS_STT_OPTIONS',\n 529,\n true\n)\n\n/**\n * Thrown when the transformers.js pipeline fails to load (e.g. the `@huggingface/transformers` peer\n * is not installed) or the `automatic-speech-recognition` call throws/returns a malformed result.\n * Non-fatal. Printf arg: `[detail]`.\n */\nexport const E_TRANSFORMERS_JS_STT_ENGINE_ERROR = createException<[string]>(\n 'E_TRANSFORMERS_JS_STT_ENGINE_ERROR',\n 'transformers.js STT engine error: %s',\n 'E_TRANSFORMERS_JS_STT_ENGINE_ERROR',\n 502,\n false\n)\n","/**\n * Runtime validation schema and wrapper for transformers.js STT adapter options.\n *\n * @remarks\n * Validates `TransformersJsSttAdapterOptions` at construction time. Throws\n * `E_INVALID_TRANSFORMERS_JS_STT_OPTIONS` on failure. `model` is required; unknown top-level keys are\n * rejected so typos fail loud.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validator, ValidationError } from '@nhtio/validation'\nimport { E_INVALID_TRANSFORMERS_JS_STT_OPTIONS } from './exceptions'\nimport type { TransformersJsSttAdapterOptions } from './types'\n\n/** Validator schema for `TransformersJsSttAdapterOptions`. Rejects unknown top-level keys. */\nexport const transformersJsSttAdapterOptionsSchema = validator\n .object<TransformersJsSttAdapterOptions>({\n model: validator.string().min(1).required(),\n // Pipeline knobs (the transformers.js pipeline is a callable object — accept function or object)\n pipeline: validator\n .alternatives(validator.function(), validator.object().unknown(true))\n .optional(),\n createPipeline: validator.function().optional(),\n device: validator.string().optional(),\n dtype: validator.string().optional(),\n chunkLengthS: validator.number().positive().default(30),\n decodeAudio: validator.function().optional(),\n modelSource: validator.function().optional(),\n onInitProgress: validator.function().optional(),\n isAvailable: validator.function().optional(),\n // ── Lifecycle hooks (opt-in, normalized phase machine; additive over onInitProgress) ──\n onLifecycle: validator.function().optional(),\n onLoading: validator.function().optional(),\n onCompiling: validator.function().optional(),\n onReady: validator.function().optional(),\n onGenerating: validator.function().optional(),\n onComplete: validator.function().optional(),\n onError: validator.function().optional(),\n })\n .unknown(false)\n\nconst isValidationError = (value: unknown): value is ValidationError =>\n isError(value) && Array.isArray((value as ValidationError).details)\n\nconst formatValidationDetails = (err: ValidationError): string =>\n err.details.map((d) => d.message).join(' and ')\n\n/**\n * Validates an arbitrary input against `transformersJsSttAdapterOptionsSchema`.\n *\n * @param input - The raw options object to validate.\n * @returns The resolved options object with defaults filled in.\n * @throws {@link @nhtio/adk/batteries!E_INVALID_TRANSFORMERS_JS_STT_OPTIONS} when invalid.\n */\nexport const validateOptions = (input: unknown): TransformersJsSttAdapterOptions => {\n const { value, error } = transformersJsSttAdapterOptionsSchema.validate(input, {\n abortEarly: false,\n convert: false,\n })\n if (error && isValidationError(error)) {\n throw new E_INVALID_TRANSFORMERS_JS_STT_OPTIONS([formatValidationDetails(error)], {\n cause: error,\n })\n }\n return value as TransformersJsSttAdapterOptions\n}\n","/**\n * transformers.js (ONNX, dual-environment) STT (speech-to-text) adapter battery.\n *\n * @remarks\n * Specialist battery backed by transformers.js's `automatic-speech-recognition` (Whisper-family)\n * pipeline. **Environment-neutral** — runs in Node (via `onnxruntime-node`) and the browser (via\n * `onnxruntime-web` / WebGPU), auto-selected by the package; there is no WebGPU requirement, mirroring\n * the transformers.js Embeddings battery this adapter is modeled on.\n *\n * Accepts any {@link @nhtio/adk/batteries/specialists/_shared!SpecialistAudioInput} form: already-\n * decoded mono PCM (skips decoding), or an encoded container (bytes / bytes+mime / a duck-typed\n * `Media`) decoded via an injectable {@link DecodeAudioFn}. Either path is resampled to the 16 kHz mono\n * PCM Whisper expects before the pipeline call.\n *\n * `@huggingface/transformers` is an optional peer dependency, imported lazily.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validateOptions } from './validation'\nimport { resampleTo } from '../../../../lib/utils/audio'\nimport { emitLifecycle } from '../../../llm/chat_common/lifecycle'\nimport { isPcmInput, toBytes, defaultDecodeAudio } from '../../_shared'\nimport { withModelSource } from '../../../llm/transformers_js/model_source'\nimport {\n E_INVALID_TRANSFORMERS_JS_STT_OPTIONS,\n E_TRANSFORMERS_JS_STT_ENGINE_ERROR,\n} from './exceptions'\nimport type { SpecialistAudioInput } from '../../_shared'\nimport type {\n TransformersJsSttAdapterOptions,\n TransformersJsSttPipeline,\n CreateTransformersJsSttPipeline,\n TranscribeOptions,\n TranscribeResult,\n SttSegment,\n} from './types'\n\n/** The shape the transformers.js ASR pipeline resolves to (a subset of its documented output). */\ninterface AsrChunk {\n /** `[start, end]` in seconds; `end` may be `null` when the engine cannot bound the chunk. */\n timestamp: [number, number | null]\n /** The chunk's recognized text. */\n text: string\n}\n\ninterface AsrPipelineOutput {\n text: string\n chunks?: AsrChunk[]\n}\n\nconst makeDefaultCreatePipeline = (\n modelSource: TransformersJsSttAdapterOptions['modelSource']\n): CreateTransformersJsSttPipeline => {\n return async ({ model, device, dtype, onInitProgress }) => {\n const transformers = await import('@huggingface/transformers')\n const { pipeline, env } = transformers\n const load = async () =>\n (await pipeline('automatic-speech-recognition', model, {\n ...(device ? { device } : {}),\n ...(dtype ? { dtype } : {}),\n ...(onInitProgress ? { progress_callback: onInitProgress } : {}),\n } as never)) as unknown as TransformersJsSttPipeline\n // When a custom model source is configured, serve files through it behind the global-`env` mutex.\n return modelSource ? withModelSource(env as never, modelSource, load) : load()\n }\n}\n\n/**\n * STT adapter for transformers.js's automatic-speech-recognition (Whisper-family) pipeline.\n *\n * @remarks\n * Reusable: construct once, call {@link TransformersJsSttAdapter.transcribe} as many times as needed.\n * The pipeline is resolved lazily on first use (or via {@link preload}) and cached with single-flight\n * semantics so concurrent calls share one load.\n */\nexport class TransformersJsSttAdapter {\n readonly #options: TransformersJsSttAdapterOptions\n #pipeline: TransformersJsSttPipeline | undefined\n #pipelinePromise: Promise<TransformersJsSttPipeline> | undefined\n\n /**\n * Whether this battery is available. transformers.js is environment-neutral (Node + browser), so\n * this is `true` whenever the runtime can import the peer — there is no WebGPU requirement.\n */\n public static isAvailable(): boolean {\n return true\n }\n\n /**\n * @param options - Constructor options. Validated eagerly.\n * @throws {@link @nhtio/adk/batteries!E_INVALID_TRANSFORMERS_JS_STT_OPTIONS} when invalid.\n */\n constructor(options: unknown) {\n this.#options = validateOptions(options)\n this.#pipeline = this.#options.pipeline\n }\n\n /** Instance availability probe (honours an injected `isAvailable`). */\n isAvailable(): boolean {\n return (this.#options.isAvailable ?? TransformersJsSttAdapter.isAvailable)()\n }\n\n /** Eagerly loads (and caches) the pipeline so the first `transcribe` call is fast. Idempotent. */\n async preload(): Promise<void> {\n await this.#resolvePipeline()\n }\n\n /** Drops the cached pipeline and in-flight load so the next call reloads. */\n reset(): void {\n this.#pipeline = undefined\n this.#pipelinePromise = undefined\n }\n\n /**\n * Release the loaded model's ONNX sessions + GPU/wasm buffers, then drop the cached pipeline.\n *\n * @remarks\n * `reset()` only nulls the JS reference; the native ONNX Runtime sessions and WebGPU/wasm device\n * memory stay alive until GC. `AutomaticSpeechRecognitionPipeline` extends `Pipeline`, which exposes\n * `dispose()` — this awaits it so the memory is reclaimed between loads, swallows a disposal error\n * (teardown must not throw), and finishes with `reset()`. Idempotent.\n */\n async dispose(): Promise<void> {\n const pipeline = this.#pipeline ?? (await this.#pipelinePromise?.catch(() => undefined))\n const pipeWithDispose = pipeline as { dispose?: () => Promise<unknown> } | undefined\n if (typeof pipeWithDispose?.dispose === 'function') {\n await Promise.resolve(pipeWithDispose.dispose()).catch(() => undefined)\n }\n this.reset()\n }\n\n async #resolvePipeline(): Promise<TransformersJsSttPipeline> {\n if (this.#pipeline) return this.#pipeline\n if (!this.isAvailable()) {\n throw new E_INVALID_TRANSFORMERS_JS_STT_OPTIONS([\n 'the transformers.js STT battery is not available in this runtime',\n ])\n }\n const opts = this.#options\n this.#pipelinePromise ??= (async () => {\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'loading', {\n detail: 'loading automatic-speech-recognition pipeline',\n })\n // Forward each provider download event into a normalized `loading` lifecycle report.\n const hasLifecycle =\n opts.onLifecycle ?? opts.onLoading ?? opts.onReady ?? opts.onGenerating ?? opts.onError\n const forwardedInitProgress = hasLifecycle\n ? (info: unknown) => {\n const p = (info as { progress?: number } | undefined)?.progress\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'loading', {\n ...(typeof p === 'number' ? { progress: p / 100 } : {}),\n raw: info,\n })\n opts.onInitProgress?.(info as never)\n }\n : opts.onInitProgress\n const createPipeline = opts.createPipeline ?? makeDefaultCreatePipeline(opts.modelSource)\n try {\n // `from_pretrained` covers both fetch (reported via progress_callback → `loading`) and the\n // ONNX-graph / WebGPU-WASM warmup. Mark the latter as `compiling` — a COARSE upper-bound marker\n // (fetch + compile overlap inside the call), consistent with the LLM/embeddings batteries.\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'compiling', {\n detail: 'compiling automatic-speech-recognition graph',\n })\n const pipe = await createPipeline({\n model: opts.model,\n device: opts.device,\n dtype: opts.dtype,\n onInitProgress: forwardedInitProgress,\n })\n this.#pipeline = pipe\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'ready', {\n detail: 'automatic-speech-recognition pipeline ready',\n })\n return pipe\n } catch (err) {\n this.#pipelinePromise = undefined\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'error', { error: err })\n throw new E_TRANSFORMERS_JS_STT_ENGINE_ERROR([\n `could not load the transformers.js pipeline: ${isError(err) ? err.message : String(err)} — install the peer dependency (pnpm add @huggingface/transformers)`,\n ])\n }\n })()\n return this.#pipelinePromise\n }\n\n /**\n * Normalizes any accepted audio input form to 16 kHz mono PCM, the shape the Whisper pipeline\n * expects.\n *\n * @remarks\n * Already-decoded {@link @nhtio/adk/batteries/specialists/_shared!SpecialistPcmInput} is resampled\n * directly (a no-op when already 16 kHz — {@link resampleTo} returns the same reference in that\n * case). Any encoded-container form is normalized to bytes via\n * {@link @nhtio/adk/batteries/specialists/_shared!toBytes}, decoded via the injected/default\n * {@link @nhtio/adk/batteries/specialists/_shared!DecodeAudioFn} (already mono per that seam's\n * contract), then resampled.\n *\n * @param input - The audio input in any accepted form.\n * @returns 16 kHz mono PCM samples.\n */\n async #toPcm16k(input: SpecialistAudioInput): Promise<Float32Array> {\n if (isPcmInput(input)) {\n return resampleTo(input.pcm, input.sampleRate, 16000)\n }\n const { bytes } = await toBytes(input)\n const decode = this.#options.decodeAudio ?? defaultDecodeAudio\n const decoded = await decode(bytes)\n return resampleTo(decoded.pcm, decoded.sampleRate, 16000)\n }\n\n /**\n * Transcribes an audio clip.\n *\n * @param input - The audio input, in any {@link @nhtio/adk/batteries/specialists/_shared!SpecialistAudioInput}\n * form (pre-decoded PCM or an encoded container).\n * @param opts - Per-call transcription options (language / translate / timestamps).\n * @returns The recognized text, plus per-segment timing when `opts.timestamps` was set.\n * @throws {@link @nhtio/adk/batteries!E_TRANSFORMERS_JS_STT_ENGINE_ERROR} when the pipeline fails to\n * load or the transcription call fails.\n */\n async transcribe(\n input: SpecialistAudioInput,\n opts?: TranscribeOptions\n ): Promise<TranscribeResult> {\n const pcm = await this.#toPcm16k(input)\n const pipe = await this.#resolvePipeline()\n const chunkLengthS = this.#options.chunkLengthS ?? 30\n\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'generating')\n\n let output: AsrPipelineOutput\n try {\n const result = await (\n pipe as unknown as (\n audio: Float32Array,\n options: Record<string, unknown>\n ) => Promise<AsrPipelineOutput | AsrPipelineOutput[]>\n )(pcm, {\n chunk_length_s: chunkLengthS,\n ...(opts?.language ? { language: opts.language } : {}),\n ...(opts?.translate ? { task: 'translate' } : {}),\n ...(opts?.timestamps ? { return_timestamps: true } : {}),\n })\n output = Array.isArray(result) ? result[0] : result\n } catch (err) {\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'error', {\n error: err,\n })\n throw new E_TRANSFORMERS_JS_STT_ENGINE_ERROR([isError(err) ? err.message : String(err)])\n }\n\n if (!output || typeof output.text !== 'string') {\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'error', {\n error: new Error('automatic-speech-recognition returned a malformed result'),\n })\n throw new E_TRANSFORMERS_JS_STT_ENGINE_ERROR([\n 'automatic-speech-recognition returned a malformed result',\n ])\n }\n\n let segments: SttSegment[] | undefined\n if (opts?.timestamps && Array.isArray(output.chunks)) {\n segments = output.chunks.map((chunk) => ({\n start: chunk.timestamp[0],\n end: chunk.timestamp[1] ?? null,\n text: chunk.text,\n }))\n }\n\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'complete')\n return segments ? { text: output.text, segments } : { text: output.text }\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { t as createException } from "./exceptions-DRYLe-J4.mjs";
2
- import "./factories.mjs";
3
2
  import { t as isError } from "./guards-BEpY7lBI.mjs";
3
+ import "./factories.mjs";
4
4
  import "./guards.mjs";
5
5
  import { resampleTo } from "./lib/utils/audio.mjs";
6
6
  import { n as emitLifecycle } from "./lifecycle-C4kwYJ-N.mjs";
@@ -261,4 +261,4 @@ var TransformersJsSttAdapter = class TransformersJsSttAdapter {
261
261
  //#endregion
262
262
  export { E_TRANSFORMERS_JS_STT_ENGINE_ERROR as a, E_INVALID_TRANSFORMERS_JS_STT_OPTIONS as i, transformersJsSttAdapterOptionsSchema as n, validateOptions as r, TransformersJsSttAdapter as t };
263
263
 
264
- //# sourceMappingURL=transformers_js-BR2Ov0Su.mjs.map
264
+ //# sourceMappingURL=transformers_js-p3lAkHFH.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"transformers_js-BR2Ov0Su.mjs","names":["#options","#pipeline","#resolvePipeline","#pipelinePromise","#toPcm16k"],"sources":["../src/batteries/specialists/stt/transformers_js/exceptions.ts","../src/batteries/specialists/stt/transformers_js/validation.ts","../src/batteries/specialists/stt/transformers_js/adapter.ts"],"sourcesContent":["/**\n * Battery-scoped exception constructors for the transformers.js STT adapter.\n *\n * @remarks\n * Battery-scoped exception classes for the transformers.js (`@huggingface/transformers`)\n * speech-to-text adapter, minted via `createException` from `@nhtio/adk/factories`. Categories mirror\n * the transformers.js Embeddings battery one-to-one — only the engine-specific failure differs.\n */\n\nimport { createException } from '@nhtio/adk/factories'\n\n/**\n * Thrown when the resolved adapter options fail validation against\n * `transformersJsSttAdapterOptionsSchema` — e.g. a missing/empty `model` or an unknown option key.\n * Fatal: config bugs fail loud, not at transcribe time.\n */\nexport const E_INVALID_TRANSFORMERS_JS_STT_OPTIONS = createException<[string]>(\n 'E_INVALID_TRANSFORMERS_JS_STT_OPTIONS',\n 'Invalid transformers.js STT adapter options: %s',\n 'E_INVALID_TRANSFORMERS_JS_STT_OPTIONS',\n 529,\n true\n)\n\n/**\n * Thrown when the transformers.js pipeline fails to load (e.g. the `@huggingface/transformers` peer\n * is not installed) or the `automatic-speech-recognition` call throws/returns a malformed result.\n * Non-fatal. Printf arg: `[detail]`.\n */\nexport const E_TRANSFORMERS_JS_STT_ENGINE_ERROR = createException<[string]>(\n 'E_TRANSFORMERS_JS_STT_ENGINE_ERROR',\n 'transformers.js STT engine error: %s',\n 'E_TRANSFORMERS_JS_STT_ENGINE_ERROR',\n 502,\n false\n)\n","/**\n * Runtime validation schema and wrapper for transformers.js STT adapter options.\n *\n * @remarks\n * Validates `TransformersJsSttAdapterOptions` at construction time. Throws\n * `E_INVALID_TRANSFORMERS_JS_STT_OPTIONS` on failure. `model` is required; unknown top-level keys are\n * rejected so typos fail loud.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validator, ValidationError } from '@nhtio/validation'\nimport { E_INVALID_TRANSFORMERS_JS_STT_OPTIONS } from './exceptions'\nimport type { TransformersJsSttAdapterOptions } from './types'\n\n/** Validator schema for `TransformersJsSttAdapterOptions`. Rejects unknown top-level keys. */\nexport const transformersJsSttAdapterOptionsSchema = validator\n .object<TransformersJsSttAdapterOptions>({\n model: validator.string().min(1).required(),\n // Pipeline knobs (the transformers.js pipeline is a callable object — accept function or object)\n pipeline: validator\n .alternatives(validator.function(), validator.object().unknown(true))\n .optional(),\n createPipeline: validator.function().optional(),\n device: validator.string().optional(),\n dtype: validator.string().optional(),\n chunkLengthS: validator.number().positive().default(30),\n decodeAudio: validator.function().optional(),\n modelSource: validator.function().optional(),\n onInitProgress: validator.function().optional(),\n isAvailable: validator.function().optional(),\n // ── Lifecycle hooks (opt-in, normalized phase machine; additive over onInitProgress) ──\n onLifecycle: validator.function().optional(),\n onLoading: validator.function().optional(),\n onCompiling: validator.function().optional(),\n onReady: validator.function().optional(),\n onGenerating: validator.function().optional(),\n onComplete: validator.function().optional(),\n onError: validator.function().optional(),\n })\n .unknown(false)\n\nconst isValidationError = (value: unknown): value is ValidationError =>\n isError(value) && Array.isArray((value as ValidationError).details)\n\nconst formatValidationDetails = (err: ValidationError): string =>\n err.details.map((d) => d.message).join(' and ')\n\n/**\n * Validates an arbitrary input against `transformersJsSttAdapterOptionsSchema`.\n *\n * @param input - The raw options object to validate.\n * @returns The resolved options object with defaults filled in.\n * @throws {@link @nhtio/adk/batteries!E_INVALID_TRANSFORMERS_JS_STT_OPTIONS} when invalid.\n */\nexport const validateOptions = (input: unknown): TransformersJsSttAdapterOptions => {\n const { value, error } = transformersJsSttAdapterOptionsSchema.validate(input, {\n abortEarly: false,\n convert: false,\n })\n if (error && isValidationError(error)) {\n throw new E_INVALID_TRANSFORMERS_JS_STT_OPTIONS([formatValidationDetails(error)], {\n cause: error,\n })\n }\n return value as TransformersJsSttAdapterOptions\n}\n","/**\n * transformers.js (ONNX, dual-environment) STT (speech-to-text) adapter battery.\n *\n * @remarks\n * Specialist battery backed by transformers.js's `automatic-speech-recognition` (Whisper-family)\n * pipeline. **Environment-neutral** — runs in Node (via `onnxruntime-node`) and the browser (via\n * `onnxruntime-web` / WebGPU), auto-selected by the package; there is no WebGPU requirement, mirroring\n * the transformers.js Embeddings battery this adapter is modeled on.\n *\n * Accepts any {@link @nhtio/adk/batteries/specialists/_shared!SpecialistAudioInput} form: already-\n * decoded mono PCM (skips decoding), or an encoded container (bytes / bytes+mime / a duck-typed\n * `Media`) decoded via an injectable {@link DecodeAudioFn}. Either path is resampled to the 16 kHz mono\n * PCM Whisper expects before the pipeline call.\n *\n * `@huggingface/transformers` is an optional peer dependency, imported lazily.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validateOptions } from './validation'\nimport { resampleTo } from '../../../../lib/utils/audio'\nimport { emitLifecycle } from '../../../llm/chat_common/lifecycle'\nimport { isPcmInput, toBytes, defaultDecodeAudio } from '../../_shared'\nimport { withModelSource } from '../../../llm/transformers_js/model_source'\nimport {\n E_INVALID_TRANSFORMERS_JS_STT_OPTIONS,\n E_TRANSFORMERS_JS_STT_ENGINE_ERROR,\n} from './exceptions'\nimport type { SpecialistAudioInput } from '../../_shared'\nimport type {\n TransformersJsSttAdapterOptions,\n TransformersJsSttPipeline,\n CreateTransformersJsSttPipeline,\n TranscribeOptions,\n TranscribeResult,\n SttSegment,\n} from './types'\n\n/** The shape the transformers.js ASR pipeline resolves to (a subset of its documented output). */\ninterface AsrChunk {\n /** `[start, end]` in seconds; `end` may be `null` when the engine cannot bound the chunk. */\n timestamp: [number, number | null]\n /** The chunk's recognized text. */\n text: string\n}\n\ninterface AsrPipelineOutput {\n text: string\n chunks?: AsrChunk[]\n}\n\nconst makeDefaultCreatePipeline = (\n modelSource: TransformersJsSttAdapterOptions['modelSource']\n): CreateTransformersJsSttPipeline => {\n return async ({ model, device, dtype, onInitProgress }) => {\n const transformers = await import('@huggingface/transformers')\n const { pipeline, env } = transformers\n const load = async () =>\n (await pipeline('automatic-speech-recognition', model, {\n ...(device ? { device } : {}),\n ...(dtype ? { dtype } : {}),\n ...(onInitProgress ? { progress_callback: onInitProgress } : {}),\n } as never)) as unknown as TransformersJsSttPipeline\n // When a custom model source is configured, serve files through it behind the global-`env` mutex.\n return modelSource ? withModelSource(env as never, modelSource, load) : load()\n }\n}\n\n/**\n * STT adapter for transformers.js's automatic-speech-recognition (Whisper-family) pipeline.\n *\n * @remarks\n * Reusable: construct once, call {@link TransformersJsSttAdapter.transcribe} as many times as needed.\n * The pipeline is resolved lazily on first use (or via {@link preload}) and cached with single-flight\n * semantics so concurrent calls share one load.\n */\nexport class TransformersJsSttAdapter {\n readonly #options: TransformersJsSttAdapterOptions\n #pipeline: TransformersJsSttPipeline | undefined\n #pipelinePromise: Promise<TransformersJsSttPipeline> | undefined\n\n /**\n * Whether this battery is available. transformers.js is environment-neutral (Node + browser), so\n * this is `true` whenever the runtime can import the peer — there is no WebGPU requirement.\n */\n public static isAvailable(): boolean {\n return true\n }\n\n /**\n * @param options - Constructor options. Validated eagerly.\n * @throws {@link @nhtio/adk/batteries!E_INVALID_TRANSFORMERS_JS_STT_OPTIONS} when invalid.\n */\n constructor(options: unknown) {\n this.#options = validateOptions(options)\n this.#pipeline = this.#options.pipeline\n }\n\n /** Instance availability probe (honours an injected `isAvailable`). */\n isAvailable(): boolean {\n return (this.#options.isAvailable ?? TransformersJsSttAdapter.isAvailable)()\n }\n\n /** Eagerly loads (and caches) the pipeline so the first `transcribe` call is fast. Idempotent. */\n async preload(): Promise<void> {\n await this.#resolvePipeline()\n }\n\n /** Drops the cached pipeline and in-flight load so the next call reloads. */\n reset(): void {\n this.#pipeline = undefined\n this.#pipelinePromise = undefined\n }\n\n /**\n * Release the loaded model's ONNX sessions + GPU/wasm buffers, then drop the cached pipeline.\n *\n * @remarks\n * `reset()` only nulls the JS reference; the native ONNX Runtime sessions and WebGPU/wasm device\n * memory stay alive until GC. `AutomaticSpeechRecognitionPipeline` extends `Pipeline`, which exposes\n * `dispose()` — this awaits it so the memory is reclaimed between loads, swallows a disposal error\n * (teardown must not throw), and finishes with `reset()`. Idempotent.\n */\n async dispose(): Promise<void> {\n const pipeline = this.#pipeline ?? (await this.#pipelinePromise?.catch(() => undefined))\n const pipeWithDispose = pipeline as { dispose?: () => Promise<unknown> } | undefined\n if (typeof pipeWithDispose?.dispose === 'function') {\n await Promise.resolve(pipeWithDispose.dispose()).catch(() => undefined)\n }\n this.reset()\n }\n\n async #resolvePipeline(): Promise<TransformersJsSttPipeline> {\n if (this.#pipeline) return this.#pipeline\n if (!this.isAvailable()) {\n throw new E_INVALID_TRANSFORMERS_JS_STT_OPTIONS([\n 'the transformers.js STT battery is not available in this runtime',\n ])\n }\n const opts = this.#options\n this.#pipelinePromise ??= (async () => {\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'loading', {\n detail: 'loading automatic-speech-recognition pipeline',\n })\n // Forward each provider download event into a normalized `loading` lifecycle report.\n const hasLifecycle =\n opts.onLifecycle ?? opts.onLoading ?? opts.onReady ?? opts.onGenerating ?? opts.onError\n const forwardedInitProgress = hasLifecycle\n ? (info: unknown) => {\n const p = (info as { progress?: number } | undefined)?.progress\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'loading', {\n ...(typeof p === 'number' ? { progress: p / 100 } : {}),\n raw: info,\n })\n opts.onInitProgress?.(info as never)\n }\n : opts.onInitProgress\n const createPipeline = opts.createPipeline ?? makeDefaultCreatePipeline(opts.modelSource)\n try {\n // `from_pretrained` covers both fetch (reported via progress_callback → `loading`) and the\n // ONNX-graph / WebGPU-WASM warmup. Mark the latter as `compiling` — a COARSE upper-bound marker\n // (fetch + compile overlap inside the call), consistent with the LLM/embeddings batteries.\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'compiling', {\n detail: 'compiling automatic-speech-recognition graph',\n })\n const pipe = await createPipeline({\n model: opts.model,\n device: opts.device,\n dtype: opts.dtype,\n onInitProgress: forwardedInitProgress,\n })\n this.#pipeline = pipe\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'ready', {\n detail: 'automatic-speech-recognition pipeline ready',\n })\n return pipe\n } catch (err) {\n this.#pipelinePromise = undefined\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'error', { error: err })\n throw new E_TRANSFORMERS_JS_STT_ENGINE_ERROR([\n `could not load the transformers.js pipeline: ${isError(err) ? err.message : String(err)} — install the peer dependency (pnpm add @huggingface/transformers)`,\n ])\n }\n })()\n return this.#pipelinePromise\n }\n\n /**\n * Normalizes any accepted audio input form to 16 kHz mono PCM, the shape the Whisper pipeline\n * expects.\n *\n * @remarks\n * Already-decoded {@link @nhtio/adk/batteries/specialists/_shared!SpecialistPcmInput} is resampled\n * directly (a no-op when already 16 kHz — {@link resampleTo} returns the same reference in that\n * case). Any encoded-container form is normalized to bytes via\n * {@link @nhtio/adk/batteries/specialists/_shared!toBytes}, decoded via the injected/default\n * {@link @nhtio/adk/batteries/specialists/_shared!DecodeAudioFn} (already mono per that seam's\n * contract), then resampled.\n *\n * @param input - The audio input in any accepted form.\n * @returns 16 kHz mono PCM samples.\n */\n async #toPcm16k(input: SpecialistAudioInput): Promise<Float32Array> {\n if (isPcmInput(input)) {\n return resampleTo(input.pcm, input.sampleRate, 16000)\n }\n const { bytes } = await toBytes(input)\n const decode = this.#options.decodeAudio ?? defaultDecodeAudio\n const decoded = await decode(bytes)\n return resampleTo(decoded.pcm, decoded.sampleRate, 16000)\n }\n\n /**\n * Transcribes an audio clip.\n *\n * @param input - The audio input, in any {@link @nhtio/adk/batteries/specialists/_shared!SpecialistAudioInput}\n * form (pre-decoded PCM or an encoded container).\n * @param opts - Per-call transcription options (language / translate / timestamps).\n * @returns The recognized text, plus per-segment timing when `opts.timestamps` was set.\n * @throws {@link @nhtio/adk/batteries!E_TRANSFORMERS_JS_STT_ENGINE_ERROR} when the pipeline fails to\n * load or the transcription call fails.\n */\n async transcribe(\n input: SpecialistAudioInput,\n opts?: TranscribeOptions\n ): Promise<TranscribeResult> {\n const pcm = await this.#toPcm16k(input)\n const pipe = await this.#resolvePipeline()\n const chunkLengthS = this.#options.chunkLengthS ?? 30\n\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'generating')\n\n let output: AsrPipelineOutput\n try {\n const result = await (\n pipe as unknown as (\n audio: Float32Array,\n options: Record<string, unknown>\n ) => Promise<AsrPipelineOutput | AsrPipelineOutput[]>\n )(pcm, {\n chunk_length_s: chunkLengthS,\n ...(opts?.language ? { language: opts.language } : {}),\n ...(opts?.translate ? { task: 'translate' } : {}),\n ...(opts?.timestamps ? { return_timestamps: true } : {}),\n })\n output = Array.isArray(result) ? result[0] : result\n } catch (err) {\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'error', {\n error: err,\n })\n throw new E_TRANSFORMERS_JS_STT_ENGINE_ERROR([isError(err) ? err.message : String(err)])\n }\n\n if (!output || typeof output.text !== 'string') {\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'error', {\n error: new Error('automatic-speech-recognition returned a malformed result'),\n })\n throw new E_TRANSFORMERS_JS_STT_ENGINE_ERROR([\n 'automatic-speech-recognition returned a malformed result',\n ])\n }\n\n let segments: SttSegment[] | undefined\n if (opts?.timestamps && Array.isArray(output.chunks)) {\n segments = output.chunks.map((chunk) => ({\n start: chunk.timestamp[0],\n end: chunk.timestamp[1] ?? null,\n text: chunk.text,\n }))\n }\n\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'complete')\n return segments ? { text: output.text, segments } : { text: output.text }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"transformers_js-p3lAkHFH.mjs","names":["#options","#pipeline","#resolvePipeline","#pipelinePromise","#toPcm16k"],"sources":["../src/batteries/specialists/stt/transformers_js/exceptions.ts","../src/batteries/specialists/stt/transformers_js/validation.ts","../src/batteries/specialists/stt/transformers_js/adapter.ts"],"sourcesContent":["/**\n * Battery-scoped exception constructors for the transformers.js STT adapter.\n *\n * @remarks\n * Battery-scoped exception classes for the transformers.js (`@huggingface/transformers`)\n * speech-to-text adapter, minted via `createException` from `@nhtio/adk/factories`. Categories mirror\n * the transformers.js Embeddings battery one-to-one — only the engine-specific failure differs.\n */\n\nimport { createException } from '@nhtio/adk/factories'\n\n/**\n * Thrown when the resolved adapter options fail validation against\n * `transformersJsSttAdapterOptionsSchema` — e.g. a missing/empty `model` or an unknown option key.\n * Fatal: config bugs fail loud, not at transcribe time.\n */\nexport const E_INVALID_TRANSFORMERS_JS_STT_OPTIONS = createException<[string]>(\n 'E_INVALID_TRANSFORMERS_JS_STT_OPTIONS',\n 'Invalid transformers.js STT adapter options: %s',\n 'E_INVALID_TRANSFORMERS_JS_STT_OPTIONS',\n 529,\n true\n)\n\n/**\n * Thrown when the transformers.js pipeline fails to load (e.g. the `@huggingface/transformers` peer\n * is not installed) or the `automatic-speech-recognition` call throws/returns a malformed result.\n * Non-fatal. Printf arg: `[detail]`.\n */\nexport const E_TRANSFORMERS_JS_STT_ENGINE_ERROR = createException<[string]>(\n 'E_TRANSFORMERS_JS_STT_ENGINE_ERROR',\n 'transformers.js STT engine error: %s',\n 'E_TRANSFORMERS_JS_STT_ENGINE_ERROR',\n 502,\n false\n)\n","/**\n * Runtime validation schema and wrapper for transformers.js STT adapter options.\n *\n * @remarks\n * Validates `TransformersJsSttAdapterOptions` at construction time. Throws\n * `E_INVALID_TRANSFORMERS_JS_STT_OPTIONS` on failure. `model` is required; unknown top-level keys are\n * rejected so typos fail loud.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validator, ValidationError } from '@nhtio/validation'\nimport { E_INVALID_TRANSFORMERS_JS_STT_OPTIONS } from './exceptions'\nimport type { TransformersJsSttAdapterOptions } from './types'\n\n/** Validator schema for `TransformersJsSttAdapterOptions`. Rejects unknown top-level keys. */\nexport const transformersJsSttAdapterOptionsSchema = validator\n .object<TransformersJsSttAdapterOptions>({\n model: validator.string().min(1).required(),\n // Pipeline knobs (the transformers.js pipeline is a callable object — accept function or object)\n pipeline: validator\n .alternatives(validator.function(), validator.object().unknown(true))\n .optional(),\n createPipeline: validator.function().optional(),\n device: validator.string().optional(),\n dtype: validator.string().optional(),\n chunkLengthS: validator.number().positive().default(30),\n decodeAudio: validator.function().optional(),\n modelSource: validator.function().optional(),\n onInitProgress: validator.function().optional(),\n isAvailable: validator.function().optional(),\n // ── Lifecycle hooks (opt-in, normalized phase machine; additive over onInitProgress) ──\n onLifecycle: validator.function().optional(),\n onLoading: validator.function().optional(),\n onCompiling: validator.function().optional(),\n onReady: validator.function().optional(),\n onGenerating: validator.function().optional(),\n onComplete: validator.function().optional(),\n onError: validator.function().optional(),\n })\n .unknown(false)\n\nconst isValidationError = (value: unknown): value is ValidationError =>\n isError(value) && Array.isArray((value as ValidationError).details)\n\nconst formatValidationDetails = (err: ValidationError): string =>\n err.details.map((d) => d.message).join(' and ')\n\n/**\n * Validates an arbitrary input against `transformersJsSttAdapterOptionsSchema`.\n *\n * @param input - The raw options object to validate.\n * @returns The resolved options object with defaults filled in.\n * @throws {@link @nhtio/adk/batteries!E_INVALID_TRANSFORMERS_JS_STT_OPTIONS} when invalid.\n */\nexport const validateOptions = (input: unknown): TransformersJsSttAdapterOptions => {\n const { value, error } = transformersJsSttAdapterOptionsSchema.validate(input, {\n abortEarly: false,\n convert: false,\n })\n if (error && isValidationError(error)) {\n throw new E_INVALID_TRANSFORMERS_JS_STT_OPTIONS([formatValidationDetails(error)], {\n cause: error,\n })\n }\n return value as TransformersJsSttAdapterOptions\n}\n","/**\n * transformers.js (ONNX, dual-environment) STT (speech-to-text) adapter battery.\n *\n * @remarks\n * Specialist battery backed by transformers.js's `automatic-speech-recognition` (Whisper-family)\n * pipeline. **Environment-neutral** — runs in Node (via `onnxruntime-node`) and the browser (via\n * `onnxruntime-web` / WebGPU), auto-selected by the package; there is no WebGPU requirement, mirroring\n * the transformers.js Embeddings battery this adapter is modeled on.\n *\n * Accepts any {@link @nhtio/adk/batteries/specialists/_shared!SpecialistAudioInput} form: already-\n * decoded mono PCM (skips decoding), or an encoded container (bytes / bytes+mime / a duck-typed\n * `Media`) decoded via an injectable {@link DecodeAudioFn}. Either path is resampled to the 16 kHz mono\n * PCM Whisper expects before the pipeline call.\n *\n * `@huggingface/transformers` is an optional peer dependency, imported lazily.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validateOptions } from './validation'\nimport { resampleTo } from '../../../../lib/utils/audio'\nimport { emitLifecycle } from '../../../llm/chat_common/lifecycle'\nimport { isPcmInput, toBytes, defaultDecodeAudio } from '../../_shared'\nimport { withModelSource } from '../../../llm/transformers_js/model_source'\nimport {\n E_INVALID_TRANSFORMERS_JS_STT_OPTIONS,\n E_TRANSFORMERS_JS_STT_ENGINE_ERROR,\n} from './exceptions'\nimport type { SpecialistAudioInput } from '../../_shared'\nimport type {\n TransformersJsSttAdapterOptions,\n TransformersJsSttPipeline,\n CreateTransformersJsSttPipeline,\n TranscribeOptions,\n TranscribeResult,\n SttSegment,\n} from './types'\n\n/** The shape the transformers.js ASR pipeline resolves to (a subset of its documented output). */\ninterface AsrChunk {\n /** `[start, end]` in seconds; `end` may be `null` when the engine cannot bound the chunk. */\n timestamp: [number, number | null]\n /** The chunk's recognized text. */\n text: string\n}\n\ninterface AsrPipelineOutput {\n text: string\n chunks?: AsrChunk[]\n}\n\nconst makeDefaultCreatePipeline = (\n modelSource: TransformersJsSttAdapterOptions['modelSource']\n): CreateTransformersJsSttPipeline => {\n return async ({ model, device, dtype, onInitProgress }) => {\n const transformers = await import('@huggingface/transformers')\n const { pipeline, env } = transformers\n const load = async () =>\n (await pipeline('automatic-speech-recognition', model, {\n ...(device ? { device } : {}),\n ...(dtype ? { dtype } : {}),\n ...(onInitProgress ? { progress_callback: onInitProgress } : {}),\n } as never)) as unknown as TransformersJsSttPipeline\n // When a custom model source is configured, serve files through it behind the global-`env` mutex.\n return modelSource ? withModelSource(env as never, modelSource, load) : load()\n }\n}\n\n/**\n * STT adapter for transformers.js's automatic-speech-recognition (Whisper-family) pipeline.\n *\n * @remarks\n * Reusable: construct once, call {@link TransformersJsSttAdapter.transcribe} as many times as needed.\n * The pipeline is resolved lazily on first use (or via {@link preload}) and cached with single-flight\n * semantics so concurrent calls share one load.\n */\nexport class TransformersJsSttAdapter {\n readonly #options: TransformersJsSttAdapterOptions\n #pipeline: TransformersJsSttPipeline | undefined\n #pipelinePromise: Promise<TransformersJsSttPipeline> | undefined\n\n /**\n * Whether this battery is available. transformers.js is environment-neutral (Node + browser), so\n * this is `true` whenever the runtime can import the peer — there is no WebGPU requirement.\n */\n public static isAvailable(): boolean {\n return true\n }\n\n /**\n * @param options - Constructor options. Validated eagerly.\n * @throws {@link @nhtio/adk/batteries!E_INVALID_TRANSFORMERS_JS_STT_OPTIONS} when invalid.\n */\n constructor(options: unknown) {\n this.#options = validateOptions(options)\n this.#pipeline = this.#options.pipeline\n }\n\n /** Instance availability probe (honours an injected `isAvailable`). */\n isAvailable(): boolean {\n return (this.#options.isAvailable ?? TransformersJsSttAdapter.isAvailable)()\n }\n\n /** Eagerly loads (and caches) the pipeline so the first `transcribe` call is fast. Idempotent. */\n async preload(): Promise<void> {\n await this.#resolvePipeline()\n }\n\n /** Drops the cached pipeline and in-flight load so the next call reloads. */\n reset(): void {\n this.#pipeline = undefined\n this.#pipelinePromise = undefined\n }\n\n /**\n * Release the loaded model's ONNX sessions + GPU/wasm buffers, then drop the cached pipeline.\n *\n * @remarks\n * `reset()` only nulls the JS reference; the native ONNX Runtime sessions and WebGPU/wasm device\n * memory stay alive until GC. `AutomaticSpeechRecognitionPipeline` extends `Pipeline`, which exposes\n * `dispose()` — this awaits it so the memory is reclaimed between loads, swallows a disposal error\n * (teardown must not throw), and finishes with `reset()`. Idempotent.\n */\n async dispose(): Promise<void> {\n const pipeline = this.#pipeline ?? (await this.#pipelinePromise?.catch(() => undefined))\n const pipeWithDispose = pipeline as { dispose?: () => Promise<unknown> } | undefined\n if (typeof pipeWithDispose?.dispose === 'function') {\n await Promise.resolve(pipeWithDispose.dispose()).catch(() => undefined)\n }\n this.reset()\n }\n\n async #resolvePipeline(): Promise<TransformersJsSttPipeline> {\n if (this.#pipeline) return this.#pipeline\n if (!this.isAvailable()) {\n throw new E_INVALID_TRANSFORMERS_JS_STT_OPTIONS([\n 'the transformers.js STT battery is not available in this runtime',\n ])\n }\n const opts = this.#options\n this.#pipelinePromise ??= (async () => {\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'loading', {\n detail: 'loading automatic-speech-recognition pipeline',\n })\n // Forward each provider download event into a normalized `loading` lifecycle report.\n const hasLifecycle =\n opts.onLifecycle ?? opts.onLoading ?? opts.onReady ?? opts.onGenerating ?? opts.onError\n const forwardedInitProgress = hasLifecycle\n ? (info: unknown) => {\n const p = (info as { progress?: number } | undefined)?.progress\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'loading', {\n ...(typeof p === 'number' ? { progress: p / 100 } : {}),\n raw: info,\n })\n opts.onInitProgress?.(info as never)\n }\n : opts.onInitProgress\n const createPipeline = opts.createPipeline ?? makeDefaultCreatePipeline(opts.modelSource)\n try {\n // `from_pretrained` covers both fetch (reported via progress_callback → `loading`) and the\n // ONNX-graph / WebGPU-WASM warmup. Mark the latter as `compiling` — a COARSE upper-bound marker\n // (fetch + compile overlap inside the call), consistent with the LLM/embeddings batteries.\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'compiling', {\n detail: 'compiling automatic-speech-recognition graph',\n })\n const pipe = await createPipeline({\n model: opts.model,\n device: opts.device,\n dtype: opts.dtype,\n onInitProgress: forwardedInitProgress,\n })\n this.#pipeline = pipe\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'ready', {\n detail: 'automatic-speech-recognition pipeline ready',\n })\n return pipe\n } catch (err) {\n this.#pipelinePromise = undefined\n emitLifecycle(opts, 'transformers_js_stt', opts.model, 'error', { error: err })\n throw new E_TRANSFORMERS_JS_STT_ENGINE_ERROR([\n `could not load the transformers.js pipeline: ${isError(err) ? err.message : String(err)} — install the peer dependency (pnpm add @huggingface/transformers)`,\n ])\n }\n })()\n return this.#pipelinePromise\n }\n\n /**\n * Normalizes any accepted audio input form to 16 kHz mono PCM, the shape the Whisper pipeline\n * expects.\n *\n * @remarks\n * Already-decoded {@link @nhtio/adk/batteries/specialists/_shared!SpecialistPcmInput} is resampled\n * directly (a no-op when already 16 kHz — {@link resampleTo} returns the same reference in that\n * case). Any encoded-container form is normalized to bytes via\n * {@link @nhtio/adk/batteries/specialists/_shared!toBytes}, decoded via the injected/default\n * {@link @nhtio/adk/batteries/specialists/_shared!DecodeAudioFn} (already mono per that seam's\n * contract), then resampled.\n *\n * @param input - The audio input in any accepted form.\n * @returns 16 kHz mono PCM samples.\n */\n async #toPcm16k(input: SpecialistAudioInput): Promise<Float32Array> {\n if (isPcmInput(input)) {\n return resampleTo(input.pcm, input.sampleRate, 16000)\n }\n const { bytes } = await toBytes(input)\n const decode = this.#options.decodeAudio ?? defaultDecodeAudio\n const decoded = await decode(bytes)\n return resampleTo(decoded.pcm, decoded.sampleRate, 16000)\n }\n\n /**\n * Transcribes an audio clip.\n *\n * @param input - The audio input, in any {@link @nhtio/adk/batteries/specialists/_shared!SpecialistAudioInput}\n * form (pre-decoded PCM or an encoded container).\n * @param opts - Per-call transcription options (language / translate / timestamps).\n * @returns The recognized text, plus per-segment timing when `opts.timestamps` was set.\n * @throws {@link @nhtio/adk/batteries!E_TRANSFORMERS_JS_STT_ENGINE_ERROR} when the pipeline fails to\n * load or the transcription call fails.\n */\n async transcribe(\n input: SpecialistAudioInput,\n opts?: TranscribeOptions\n ): Promise<TranscribeResult> {\n const pcm = await this.#toPcm16k(input)\n const pipe = await this.#resolvePipeline()\n const chunkLengthS = this.#options.chunkLengthS ?? 30\n\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'generating')\n\n let output: AsrPipelineOutput\n try {\n const result = await (\n pipe as unknown as (\n audio: Float32Array,\n options: Record<string, unknown>\n ) => Promise<AsrPipelineOutput | AsrPipelineOutput[]>\n )(pcm, {\n chunk_length_s: chunkLengthS,\n ...(opts?.language ? { language: opts.language } : {}),\n ...(opts?.translate ? { task: 'translate' } : {}),\n ...(opts?.timestamps ? { return_timestamps: true } : {}),\n })\n output = Array.isArray(result) ? result[0] : result\n } catch (err) {\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'error', {\n error: err,\n })\n throw new E_TRANSFORMERS_JS_STT_ENGINE_ERROR([isError(err) ? err.message : String(err)])\n }\n\n if (!output || typeof output.text !== 'string') {\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'error', {\n error: new Error('automatic-speech-recognition returned a malformed result'),\n })\n throw new E_TRANSFORMERS_JS_STT_ENGINE_ERROR([\n 'automatic-speech-recognition returned a malformed result',\n ])\n }\n\n let segments: SttSegment[] | undefined\n if (opts?.timestamps && Array.isArray(output.chunks)) {\n segments = output.chunks.map((chunk) => ({\n start: chunk.timestamp[0],\n end: chunk.timestamp[1] ?? null,\n text: chunk.text,\n }))\n }\n\n emitLifecycle(this.#options, 'transformers_js_stt', this.#options.model, 'complete')\n return segments ? { text: output.text, segments } : { text: output.text }\n }\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { o as validateOrThrow } from "./exceptions-DRYLe-J4.mjs";
2
2
  import { n as isInstanceOf, r as isObject, t as isError } from "./guards-BEpY7lBI.mjs";
3
- import { B as E_TURN_GATE_TIMEOUT, E as E_INVALID_TURN_RUNNER_CONFIG, N as E_OUTPUT_PIPELINE_ERROR, P as E_PIPELINE_SHORT_CIRCUITED, T as E_INVALID_TURN_GATE_RESOLUTION, a as runWithEstimationWarnings, b as E_INVALID_INITIAL_TURN_GATE_VALUE, u as E_INPUT_PIPELINE_ERROR, z as E_TURN_GATE_ABORTED } from "./tokenizable-xPXj1AQX.mjs";
4
- import { f as Tool, g as ToolRegistry } from "./spooled_artifact-B710Rb0d.mjs";
5
- import { r as TurnContext, t as DispatchRunner } from "./dispatch_runner-DDH_dGPU.mjs";
3
+ import { C as E_INVALID_TURN_GATE_RESOLUTION, L as E_TURN_GATE_ABORTED, M as E_PIPELINE_SHORT_CIRCUITED, R as E_TURN_GATE_TIMEOUT, a as runWithEstimationWarnings, c as E_INPUT_PIPELINE_ERROR, j as E_OUTPUT_PIPELINE_ERROR, v as E_INVALID_INITIAL_TURN_GATE_VALUE, w as E_INVALID_TURN_RUNNER_CONFIG } from "./tokenizable-VB4Av8GF.mjs";
4
+ import { d as ToolRegistry, p as Tool } from "./spooled_artifact-Bw_7swIp.mjs";
5
+ import { r as TurnContext, t as DispatchRunner } from "./dispatch_runner-BZDXUe0G.mjs";
6
6
  import { validator } from "@nhtio/validation";
7
7
  import { DateTime } from "luxon";
8
8
  import { Middleware } from "@nhtio/middleware";
@@ -626,4 +626,4 @@ var TurnRunner = class TurnRunner {
626
626
  //#endregion
627
627
  export { TurnGate as n, TurnRunner as t };
628
628
 
629
- //# sourceMappingURL=turn_runner-BgPw9uqb.mjs.map
629
+ //# sourceMappingURL=turn_runner-BHHD6h77.mjs.map