@nhtio/adk 0.1.0-master-2a4e1bd2 → 0.1.0-master-cd595e6f

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 (413) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/artifact_methods-CJDQ5Lv-.mjs +1 -0
  3. package/artifact_methods-D6k_82r3.js +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 +2 -2
  17. package/batteries/dev-tools.mjs +2 -2
  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/browser.d.ts +1 -1
  27. package/batteries/isolation/child_process/transport.d.ts +2 -2
  28. package/batteries/isolation/child_process.cjs +4 -4
  29. package/batteries/isolation/child_process.cjs.map +1 -1
  30. package/batteries/isolation/child_process.mjs +4 -4
  31. package/batteries/isolation/child_process.mjs.map +1 -1
  32. package/batteries/isolation/codec.d.ts +2 -2
  33. package/batteries/isolation/crash_policy.d.ts +1 -1
  34. package/batteries/isolation/isolate_function.d.ts +2 -2
  35. package/batteries/isolation/protocol.d.ts +4 -4
  36. package/batteries/isolation/serve.d.ts +2 -2
  37. package/batteries/isolation/types.d.ts +4 -4
  38. package/batteries/isolation.cjs +1 -1
  39. package/batteries/isolation.mjs +1 -1
  40. package/batteries/llm/anthropic_messages/adapter.cjs +6 -6
  41. package/batteries/llm/anthropic_messages/adapter.cjs.map +1 -1
  42. package/batteries/llm/anthropic_messages/adapter.mjs +6 -6
  43. package/batteries/llm/anthropic_messages/adapter.mjs.map +1 -1
  44. package/batteries/llm/anthropic_messages/count_tokens.cjs +1 -1
  45. package/batteries/llm/anthropic_messages/count_tokens.mjs +1 -1
  46. package/batteries/llm/anthropic_messages/helpers.cjs +3 -3
  47. package/batteries/llm/anthropic_messages/helpers.mjs +3 -3
  48. package/batteries/llm/anthropic_messages/types.d.ts +2 -2
  49. package/batteries/llm/anthropic_messages/validation.cjs +3 -3
  50. package/batteries/llm/anthropic_messages/validation.cjs.map +1 -1
  51. package/batteries/llm/anthropic_messages/validation.mjs +3 -3
  52. package/batteries/llm/anthropic_messages/validation.mjs.map +1 -1
  53. package/batteries/llm/anthropic_messages.cjs +2 -2
  54. package/batteries/llm/anthropic_messages.mjs +2 -2
  55. package/batteries/llm/bedrock_converse/adapter.cjs +29 -7
  56. package/batteries/llm/bedrock_converse/adapter.cjs.map +1 -1
  57. package/batteries/llm/bedrock_converse/adapter.mjs +30 -8
  58. package/batteries/llm/bedrock_converse/adapter.mjs.map +1 -1
  59. package/batteries/llm/bedrock_converse/exceptions.cjs +3 -0
  60. package/batteries/llm/bedrock_converse/exceptions.cjs.map +1 -1
  61. package/batteries/llm/bedrock_converse/exceptions.d.ts +6 -0
  62. package/batteries/llm/bedrock_converse/exceptions.mjs +3 -1
  63. package/batteries/llm/bedrock_converse/exceptions.mjs.map +1 -1
  64. package/batteries/llm/bedrock_converse/helpers.cjs +1 -1
  65. package/batteries/llm/bedrock_converse/helpers.mjs +1 -1
  66. package/batteries/llm/bedrock_converse/types.d.ts +6 -2
  67. package/batteries/llm/bedrock_converse/validation.cjs +7 -1
  68. package/batteries/llm/bedrock_converse/validation.cjs.map +1 -1
  69. package/batteries/llm/bedrock_converse/validation.mjs +7 -1
  70. package/batteries/llm/bedrock_converse/validation.mjs.map +1 -1
  71. package/batteries/llm/bedrock_converse.cjs +2 -2
  72. package/batteries/llm/bedrock_converse.mjs +2 -2
  73. package/batteries/llm/claude_code_cli/adapter.cjs +6 -6
  74. package/batteries/llm/claude_code_cli/adapter.cjs.map +1 -1
  75. package/batteries/llm/claude_code_cli/adapter.mjs +6 -6
  76. package/batteries/llm/claude_code_cli/adapter.mjs.map +1 -1
  77. package/batteries/llm/claude_code_cli/helpers.cjs +3 -3
  78. package/batteries/llm/claude_code_cli/helpers.mjs +3 -3
  79. package/batteries/llm/claude_code_cli/types.d.ts +3 -2
  80. package/batteries/llm/claude_code_cli/validation.cjs +3 -3
  81. package/batteries/llm/claude_code_cli/validation.cjs.map +1 -1
  82. package/batteries/llm/claude_code_cli/validation.mjs +3 -3
  83. package/batteries/llm/claude_code_cli/validation.mjs.map +1 -1
  84. package/batteries/llm/claude_code_cli.cjs +1 -1
  85. package/batteries/llm/claude_code_cli.mjs +1 -1
  86. package/batteries/llm/gemini_generate_content/adapter.cjs +29 -7
  87. package/batteries/llm/gemini_generate_content/adapter.cjs.map +1 -1
  88. package/batteries/llm/gemini_generate_content/adapter.mjs +30 -8
  89. package/batteries/llm/gemini_generate_content/adapter.mjs.map +1 -1
  90. package/batteries/llm/gemini_generate_content/exceptions.cjs +3 -0
  91. package/batteries/llm/gemini_generate_content/exceptions.cjs.map +1 -1
  92. package/batteries/llm/gemini_generate_content/exceptions.d.ts +6 -0
  93. package/batteries/llm/gemini_generate_content/exceptions.mjs +3 -1
  94. package/batteries/llm/gemini_generate_content/exceptions.mjs.map +1 -1
  95. package/batteries/llm/gemini_generate_content/helpers.cjs +1 -1
  96. package/batteries/llm/gemini_generate_content/helpers.mjs +1 -1
  97. package/batteries/llm/gemini_generate_content/types.d.ts +7 -3
  98. package/batteries/llm/gemini_generate_content/validation.cjs +11 -2
  99. package/batteries/llm/gemini_generate_content/validation.cjs.map +1 -1
  100. package/batteries/llm/gemini_generate_content/validation.mjs +11 -2
  101. package/batteries/llm/gemini_generate_content/validation.mjs.map +1 -1
  102. package/batteries/llm/gemini_generate_content.cjs +1 -1
  103. package/batteries/llm/gemini_generate_content.mjs +1 -1
  104. package/batteries/llm/litert_lm/adapter.cjs +6 -6
  105. package/batteries/llm/litert_lm/adapter.cjs.map +1 -1
  106. package/batteries/llm/litert_lm/adapter.mjs +6 -6
  107. package/batteries/llm/litert_lm/adapter.mjs.map +1 -1
  108. package/batteries/llm/litert_lm/helpers.cjs +3 -3
  109. package/batteries/llm/litert_lm/helpers.mjs +3 -3
  110. package/batteries/llm/litert_lm/types.d.ts +2 -2
  111. package/batteries/llm/litert_lm/validation.cjs +3 -3
  112. package/batteries/llm/litert_lm/validation.cjs.map +1 -1
  113. package/batteries/llm/litert_lm/validation.mjs +3 -3
  114. package/batteries/llm/litert_lm/validation.mjs.map +1 -1
  115. package/batteries/llm/litert_lm.cjs +1 -1
  116. package/batteries/llm/litert_lm.mjs +1 -1
  117. package/batteries/llm/ollama/adapter.cjs +6 -6
  118. package/batteries/llm/ollama/adapter.cjs.map +1 -1
  119. package/batteries/llm/ollama/adapter.mjs +6 -6
  120. package/batteries/llm/ollama/adapter.mjs.map +1 -1
  121. package/batteries/llm/ollama/helpers.cjs +4 -4
  122. package/batteries/llm/ollama/helpers.mjs +4 -4
  123. package/batteries/llm/ollama/types.d.ts +2 -2
  124. package/batteries/llm/ollama/validation.cjs +3 -3
  125. package/batteries/llm/ollama/validation.cjs.map +1 -1
  126. package/batteries/llm/ollama/validation.mjs +3 -3
  127. package/batteries/llm/ollama/validation.mjs.map +1 -1
  128. package/batteries/llm/ollama.cjs +2 -2
  129. package/batteries/llm/ollama.mjs +2 -2
  130. package/batteries/llm/openai_chat_completions/adapter.cjs +6 -6
  131. package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -1
  132. package/batteries/llm/openai_chat_completions/adapter.mjs +6 -6
  133. package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -1
  134. package/batteries/llm/openai_chat_completions/helpers.cjs +4 -4
  135. package/batteries/llm/openai_chat_completions/helpers.mjs +4 -4
  136. package/batteries/llm/openai_chat_completions/types.d.ts +2 -2
  137. package/batteries/llm/openai_chat_completions/validation.cjs +3 -3
  138. package/batteries/llm/openai_chat_completions/validation.cjs.map +1 -1
  139. package/batteries/llm/openai_chat_completions/validation.mjs +3 -3
  140. package/batteries/llm/openai_chat_completions/validation.mjs.map +1 -1
  141. package/batteries/llm/openai_chat_completions.cjs +2 -2
  142. package/batteries/llm/openai_chat_completions.mjs +2 -2
  143. package/batteries/llm/openai_responses/adapter.cjs +6 -6
  144. package/batteries/llm/openai_responses/adapter.cjs.map +1 -1
  145. package/batteries/llm/openai_responses/adapter.mjs +6 -6
  146. package/batteries/llm/openai_responses/adapter.mjs.map +1 -1
  147. package/batteries/llm/openai_responses/helpers.cjs +3 -3
  148. package/batteries/llm/openai_responses/helpers.mjs +3 -3
  149. package/batteries/llm/openai_responses/types.d.ts +2 -2
  150. package/batteries/llm/openai_responses/validation.cjs +3 -3
  151. package/batteries/llm/openai_responses/validation.cjs.map +1 -1
  152. package/batteries/llm/openai_responses/validation.mjs +3 -3
  153. package/batteries/llm/openai_responses/validation.mjs.map +1 -1
  154. package/batteries/llm/openai_responses.cjs +2 -2
  155. package/batteries/llm/openai_responses.mjs +2 -2
  156. package/batteries/llm/transformers_js/adapter.cjs +6 -6
  157. package/batteries/llm/transformers_js/adapter.cjs.map +1 -1
  158. package/batteries/llm/transformers_js/adapter.mjs +6 -6
  159. package/batteries/llm/transformers_js/adapter.mjs.map +1 -1
  160. package/batteries/llm/transformers_js/helpers.cjs +3 -3
  161. package/batteries/llm/transformers_js/helpers.mjs +3 -3
  162. package/batteries/llm/transformers_js/types.d.ts +2 -2
  163. package/batteries/llm/transformers_js/validation.cjs +3 -3
  164. package/batteries/llm/transformers_js/validation.cjs.map +1 -1
  165. package/batteries/llm/transformers_js/validation.mjs +3 -3
  166. package/batteries/llm/transformers_js/validation.mjs.map +1 -1
  167. package/batteries/llm/transformers_js.cjs +1 -1
  168. package/batteries/llm/transformers_js.mjs +1 -1
  169. package/batteries/llm/webllm_chat_completions/adapter.cjs +6 -6
  170. package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -1
  171. package/batteries/llm/webllm_chat_completions/adapter.mjs +6 -6
  172. package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -1
  173. package/batteries/llm/webllm_chat_completions/helpers.cjs +1 -1
  174. package/batteries/llm/webllm_chat_completions/helpers.mjs +1 -1
  175. package/batteries/llm/webllm_chat_completions/validation.cjs +3 -3
  176. package/batteries/llm/webllm_chat_completions/validation.cjs.map +1 -1
  177. package/batteries/llm/webllm_chat_completions/validation.mjs +3 -3
  178. package/batteries/llm/webllm_chat_completions/validation.mjs.map +1 -1
  179. package/batteries/llm/webllm_chat_completions.cjs +2 -2
  180. package/batteries/llm/webllm_chat_completions.mjs +2 -2
  181. package/batteries/llm.cjs +2 -2
  182. package/batteries/llm.mjs +2 -2
  183. package/batteries/media/builder.d.ts +3 -0
  184. package/batteries/media/contracts.cjs.map +1 -1
  185. package/batteries/media/contracts.d.ts +40 -1
  186. package/batteries/media/contracts.mjs.map +1 -1
  187. package/batteries/media/engines/sharp.cjs +36 -2
  188. package/batteries/media/engines/sharp.cjs.map +1 -1
  189. package/batteries/media/engines/sharp.mjs +36 -2
  190. package/batteries/media/engines/sharp.mjs.map +1 -1
  191. package/batteries/media/forge.cjs +5 -5
  192. package/batteries/media/forge.mjs +5 -5
  193. package/batteries/media/index.d.ts +1 -1
  194. package/batteries/media/lint.cjs +3 -2
  195. package/batteries/media/lint.cjs.map +1 -1
  196. package/batteries/media/lint.mjs +3 -2
  197. package/batteries/media/lint.mjs.map +1 -1
  198. package/batteries/media.cjs +66 -2
  199. package/batteries/media.cjs.map +1 -1
  200. package/batteries/media.mjs +66 -2
  201. package/batteries/media.mjs.map +1 -1
  202. package/batteries/orchestration/conformance.cjs +123 -74
  203. package/batteries/orchestration/conformance.cjs.map +1 -1
  204. package/batteries/orchestration/conformance.d.ts +10 -8
  205. package/batteries/orchestration/conformance.mjs +54 -5
  206. package/batteries/orchestration/conformance.mjs.map +1 -1
  207. package/batteries/orchestration/dispatch_reasoner.cjs +4 -4
  208. package/batteries/orchestration/dispatch_reasoner.mjs +4 -4
  209. package/batteries/orchestration/executor.cjs +2 -2
  210. package/batteries/orchestration/executor.mjs +2 -2
  211. package/batteries/orchestration/forge.cjs +4 -4
  212. package/batteries/orchestration/forge.mjs +4 -4
  213. package/batteries/orchestration/validation.cjs +2 -2
  214. package/batteries/orchestration/validation.mjs +2 -2
  215. package/batteries/orchestration.cjs +4 -4
  216. package/batteries/orchestration.mjs +4 -4
  217. package/batteries/sandbox/contracts/policy_enforcer.d.ts +13 -1
  218. package/batteries/sandbox/js/compartment.d.ts +7 -2
  219. package/batteries/sandbox/js/exceptions.d.ts +4 -0
  220. package/batteries/sandbox/js/runner.d.ts +1 -1
  221. package/batteries/sandbox/js/service.d.ts +1 -1
  222. package/batteries/sandbox/js/ses_contracts.d.ts +4 -3
  223. package/batteries/sandbox/js.cjs +17 -8
  224. package/batteries/sandbox/js.cjs.map +1 -1
  225. package/batteries/sandbox/js.mjs +17 -9
  226. package/batteries/sandbox/js.mjs.map +1 -1
  227. package/batteries/sandbox/manager.d.ts +4 -3
  228. package/batteries/sandbox/node/srt_enforcer.d.ts +1 -1
  229. package/batteries/sandbox/node.cjs +36 -12
  230. package/batteries/sandbox/node.cjs.map +1 -1
  231. package/batteries/sandbox/node.mjs +36 -12
  232. package/batteries/sandbox/node.mjs.map +1 -1
  233. package/batteries/sandbox/tools.cjs +1 -1
  234. package/batteries/sandbox/tools.mjs +1 -1
  235. package/batteries/sandbox/types.d.ts +10 -1
  236. package/batteries/sandbox.cjs +27 -9
  237. package/batteries/sandbox.cjs.map +1 -1
  238. package/batteries/sandbox.mjs +28 -11
  239. package/batteries/sandbox.mjs.map +1 -1
  240. package/batteries/skills.cjs +9 -9
  241. package/batteries/skills.mjs +9 -9
  242. package/batteries/tools/_shared.cjs +1 -1
  243. package/batteries/tools/_shared.mjs +1 -1
  244. package/batteries/tools/color.cjs +2 -2
  245. package/batteries/tools/color.mjs +2 -2
  246. package/batteries/tools/comparison.cjs +2 -2
  247. package/batteries/tools/comparison.mjs +2 -2
  248. package/batteries/tools/data_structure.cjs +2 -2
  249. package/batteries/tools/data_structure.mjs +2 -2
  250. package/batteries/tools/datetime_extended.cjs +3 -3
  251. package/batteries/tools/datetime_extended.mjs +3 -3
  252. package/batteries/tools/datetime_math.cjs +3 -3
  253. package/batteries/tools/datetime_math.mjs +3 -3
  254. package/batteries/tools/encoding.cjs +2 -2
  255. package/batteries/tools/encoding.mjs +2 -2
  256. package/batteries/tools/formatting.cjs +2 -2
  257. package/batteries/tools/formatting.mjs +2 -2
  258. package/batteries/tools/geo_basics.cjs +2 -2
  259. package/batteries/tools/geo_basics.mjs +2 -2
  260. package/batteries/tools/math.cjs +2 -2
  261. package/batteries/tools/math.mjs +2 -2
  262. package/batteries/tools/memory.cjs +5 -5
  263. package/batteries/tools/memory.mjs +5 -5
  264. package/batteries/tools/parsing.cjs +3 -3
  265. package/batteries/tools/parsing.mjs +3 -3
  266. package/batteries/tools/retrievables.cjs +5 -5
  267. package/batteries/tools/retrievables.mjs +5 -5
  268. package/batteries/tools/scrapper.cjs +1 -1
  269. package/batteries/tools/scrapper.mjs +1 -1
  270. package/batteries/tools/searxng.cjs +1 -1
  271. package/batteries/tools/searxng.mjs +1 -1
  272. package/batteries/tools/standing_instructions.cjs +3 -3
  273. package/batteries/tools/standing_instructions.mjs +3 -3
  274. package/batteries/tools/statistics.cjs +3 -3
  275. package/batteries/tools/statistics.mjs +3 -3
  276. package/batteries/tools/string_processing.cjs +2 -2
  277. package/batteries/tools/string_processing.mjs +2 -2
  278. package/batteries/tools/structured_data.cjs +2 -2
  279. package/batteries/tools/structured_data.mjs +2 -2
  280. package/batteries/tools/text_analysis.cjs +3 -3
  281. package/batteries/tools/text_analysis.mjs +3 -3
  282. package/batteries/tools/text_comparison.cjs +2 -2
  283. package/batteries/tools/text_comparison.mjs +2 -2
  284. package/batteries/tools/time.cjs +3 -3
  285. package/batteries/tools/time.mjs +3 -3
  286. package/batteries/tools/unit_conversion.cjs +2 -2
  287. package/batteries/tools/unit_conversion.mjs +2 -2
  288. package/batteries/tools.cjs +2 -2
  289. package/batteries/tools.mjs +2 -2
  290. package/batteries/validation.cjs +5 -5
  291. package/batteries/validation.mjs +5 -5
  292. package/batteries/vector/conformance/index.d.ts +11 -16
  293. package/batteries/vector/conformance.cjs +107 -36
  294. package/batteries/vector/conformance.cjs.map +1 -1
  295. package/batteries/vector/conformance.mjs +84 -13
  296. package/batteries/vector/conformance.mjs.map +1 -1
  297. package/batteries/vector/retrievable.cjs +1 -1
  298. package/batteries/vector/retrievable.mjs +1 -1
  299. package/batteries.cjs +5 -5
  300. package/batteries.mjs +5 -5
  301. package/{chat_common-DbbIESdo.mjs → chat_common-CmKV5Dz4.mjs} +2 -2
  302. package/{chat_common-DbbIESdo.mjs.map → chat_common-CmKV5Dz4.mjs.map} +1 -1
  303. package/{chat_common-B3O3zz-i.js → chat_common-Dpan9moo.js} +2 -2
  304. package/{chat_common-B3O3zz-i.js.map → chat_common-Dpan9moo.js.map} +1 -1
  305. package/{common-v9Jo9M5k.mjs → common-BpdHIpQE.mjs} +7 -7
  306. package/{common-v9Jo9M5k.mjs.map → common-BpdHIpQE.mjs.map} +1 -1
  307. package/{common-BV3HGeLj.js → common-H44Ik9ou.js} +7 -7
  308. package/{common-BV3HGeLj.js.map → common-H44Ik9ou.js.map} +1 -1
  309. package/common.cjs +7 -7
  310. package/common.mjs +7 -7
  311. package/{dispatch_runner-CbNyqSMy.mjs → dispatch_runner-BZDXUe0G.mjs} +5 -5
  312. package/{dispatch_runner-CbNyqSMy.mjs.map → dispatch_runner-BZDXUe0G.mjs.map} +1 -1
  313. package/{dispatch_runner-Bl3Xwebu.js → dispatch_runner-CKhm-scw.js} +5 -5
  314. package/{dispatch_runner-Bl3Xwebu.js.map → dispatch_runner-CKhm-scw.js.map} +1 -1
  315. package/dispatch_runner.cjs +1 -1
  316. package/dispatch_runner.mjs +1 -1
  317. package/{ecmascript-BSnvyY8T.js → ecmascript-CCtgamDh.js} +3 -3
  318. package/{ecmascript-BSnvyY8T.js.map → ecmascript-CCtgamDh.js.map} +1 -1
  319. package/{ecmascript-CZ7_YKfZ.mjs → ecmascript-DcmUQ9Jx.mjs} +3 -3
  320. package/{ecmascript-CZ7_YKfZ.mjs.map → ecmascript-DcmUQ9Jx.mjs.map} +1 -1
  321. package/eslint.cjs +1 -1
  322. package/eslint.mjs +1 -1
  323. package/exceptions.cjs +1 -1
  324. package/exceptions.mjs +1 -1
  325. package/forge.cjs +2 -2
  326. package/forge.mjs +2 -2
  327. package/guards.cjs +7 -7
  328. package/guards.mjs +7 -7
  329. package/{helpers-CDmLDBq5.mjs → helpers-BH7HTtkD.mjs} +3 -3
  330. package/{helpers-CDmLDBq5.mjs.map → helpers-BH7HTtkD.mjs.map} +1 -1
  331. package/{helpers-Tvvwpx1M.js → helpers-CEjjkXso.js} +3 -3
  332. package/{helpers-Tvvwpx1M.js.map → helpers-CEjjkXso.js.map} +1 -1
  333. package/index.cjs +10 -10
  334. package/index.mjs +10 -10
  335. package/{isolation-BQCTQYZ_.js → isolation-7Jrcucgc.js} +11 -11
  336. package/isolation-7Jrcucgc.js.map +1 -0
  337. package/{isolation-7xbkc12r.mjs → isolation-CO0NiK8R.mjs} +11 -11
  338. package/isolation-CO0NiK8R.mjs.map +1 -0
  339. package/lib/classes/tokenizable.d.ts +2 -3
  340. package/mcp/adk-docs-corpus.json +2 -2
  341. package/package.json +469 -469
  342. package/{retrievable-C5dXuDhD.js → retrievable-BTwjmPnl.js} +3 -3
  343. package/{retrievable-C5dXuDhD.js.map → retrievable-BTwjmPnl.js.map} +1 -1
  344. package/{retrievable-gl_TIHnX.mjs → retrievable-CXTAUuuv.mjs} +3 -3
  345. package/{retrievable-gl_TIHnX.mjs.map → retrievable-CXTAUuuv.mjs.map} +1 -1
  346. package/{scrapper-DD6-_2u-.js → scrapper-CJexXXK-.js} +4 -4
  347. package/{scrapper-DD6-_2u-.js.map → scrapper-CJexXXK-.js.map} +1 -1
  348. package/{scrapper-u_orpxIB.mjs → scrapper-DiQ5FfDL.mjs} +4 -4
  349. package/{scrapper-u_orpxIB.mjs.map → scrapper-DiQ5FfDL.mjs.map} +1 -1
  350. package/{searxng-fVdJUCK2.mjs → searxng-BFTJ6rTE.mjs} +4 -4
  351. package/{searxng-fVdJUCK2.mjs.map → searxng-BFTJ6rTE.mjs.map} +1 -1
  352. package/{searxng-C7GK0Nrz.js → searxng-DzlGZG4V.js} +4 -4
  353. package/{searxng-C7GK0Nrz.js.map → searxng-DzlGZG4V.js.map} +1 -1
  354. package/server.json +2 -2
  355. package/skills/adk-assembly/SKILL.md +2 -2
  356. package/{spooled_artifact-DriNQRj7.js → spooled_artifact-BpcesRBv.js} +384 -384
  357. package/spooled_artifact-BpcesRBv.js.map +1 -0
  358. package/{spooled_artifact-BkueYJhR.mjs → spooled_artifact-Bw_7swIp.mjs} +385 -385
  359. package/spooled_artifact-Bw_7swIp.mjs.map +1 -0
  360. package/spooled_artifact.cjs +2 -2
  361. package/spooled_artifact.mjs +2 -2
  362. package/{spooled_markdown_artifact-CfHRZUkl.mjs → spooled_markdown_artifact-vd6eNtIP.mjs} +3 -3
  363. package/{spooled_markdown_artifact-CfHRZUkl.mjs.map → spooled_markdown_artifact-vd6eNtIP.mjs.map} +1 -1
  364. package/{spooled_markdown_artifact-C_VkCDhF.js → spooled_markdown_artifact-wJPnE8Ij.js} +3 -3
  365. package/{spooled_markdown_artifact-C_VkCDhF.js.map → spooled_markdown_artifact-wJPnE8Ij.js.map} +1 -1
  366. package/{thought-B8JAi3-W.mjs → thought-BE1KGEhV.mjs} +3 -3
  367. package/{thought-B8JAi3-W.mjs.map → thought-BE1KGEhV.mjs.map} +1 -1
  368. package/{thought--fRgOwTP.js → thought-bS7O9O5H.js} +3 -3
  369. package/{thought--fRgOwTP.js.map → thought-bS7O9O5H.js.map} +1 -1
  370. package/{tokenizable-CWW7iSrD.js → tokenizable-BMZuGWRd.js} +35 -29
  371. package/tokenizable-BMZuGWRd.js.map +1 -0
  372. package/{tokenizable-DLMP68ZV.mjs → tokenizable-VB4Av8GF.mjs} +36 -30
  373. package/tokenizable-VB4Av8GF.mjs.map +1 -0
  374. package/{tool_call-CPjyvkm4.mjs → tool_call-Cfaj-6zK.mjs} +4 -4
  375. package/{tool_call-CPjyvkm4.mjs.map → tool_call-Cfaj-6zK.mjs.map} +1 -1
  376. package/{tool_call-DgqVwL5n.js → tool_call-Fs_Uh5wQ.js} +4 -4
  377. package/{tool_call-DgqVwL5n.js.map → tool_call-Fs_Uh5wQ.js.map} +1 -1
  378. package/{tools-BmLzkvNr.mjs → tools-B3_8C78Q.mjs} +6 -6
  379. package/{tools-BmLzkvNr.mjs.map → tools-B3_8C78Q.mjs.map} +1 -1
  380. package/{tools-DmcIe2Cb.js → tools-CqOcmHR8.js} +6 -6
  381. package/{tools-DmcIe2Cb.js.map → tools-CqOcmHR8.js.map} +1 -1
  382. package/{toon-BvTQsKdN.mjs → toon-BSlr88px.mjs} +5 -5
  383. package/{toon-BvTQsKdN.mjs.map → toon-BSlr88px.mjs.map} +1 -1
  384. package/{toon-B05eKx-q.js → toon-D71tkyI3.js} +5 -5
  385. package/{toon-B05eKx-q.js.map → toon-D71tkyI3.js.map} +1 -1
  386. package/{turn_runner-DEGCvfVZ.mjs → turn_runner-BHHD6h77.mjs} +5 -5
  387. package/{turn_runner-DEGCvfVZ.mjs.map → turn_runner-BHHD6h77.mjs.map} +1 -1
  388. package/{turn_runner-DT8TseR4.js → turn_runner-DhLI7OTH.js} +5 -5
  389. package/{turn_runner-DT8TseR4.js.map → turn_runner-DhLI7OTH.js.map} +1 -1
  390. package/turn_runner.cjs +1 -1
  391. package/turn_runner.mjs +1 -1
  392. package/types-D6X_aUIb.mjs.map +1 -1
  393. package/types-DrSosVaM.js.map +1 -1
  394. package/{validate-lzy9nG_E.mjs → validate-Bi7FGjoq.mjs} +13 -1
  395. package/{validate-lzy9nG_E.mjs.map → validate-Bi7FGjoq.mjs.map} +1 -1
  396. package/{validate-CdOS7S2u.js → validate-CkQI-48O.js} +13 -1
  397. package/{validate-CdOS7S2u.js.map → validate-CkQI-48O.js.map} +1 -1
  398. package/{xml-DDTIMpY3.js → xml-BeNvlifb.js} +5 -5
  399. package/{xml-DDTIMpY3.js.map → xml-BeNvlifb.js.map} +1 -1
  400. package/{xml-VhJ4NrMB.mjs → xml-vyCZZiF_.mjs} +5 -5
  401. package/{xml-VhJ4NrMB.mjs.map → xml-vyCZZiF_.mjs.map} +1 -1
  402. package/{yaml-Cx16IYJq.js → yaml-DhLLa2cj.js} +5 -5
  403. package/{yaml-Cx16IYJq.js.map → yaml-DhLLa2cj.js.map} +1 -1
  404. package/{yaml-Du4wFGzL.mjs → yaml-Dtz0Bd7J.mjs} +5 -5
  405. package/{yaml-Du4wFGzL.mjs.map → yaml-Dtz0Bd7J.mjs.map} +1 -1
  406. package/artifact_methods-BMCahBLn.mjs +0 -1
  407. package/artifact_methods-f_bSy4kX.js +0 -1
  408. package/isolation-7xbkc12r.mjs.map +0 -1
  409. package/isolation-BQCTQYZ_.js.map +0 -1
  410. package/spooled_artifact-BkueYJhR.mjs.map +0 -1
  411. package/spooled_artifact-DriNQRj7.js.map +0 -1
  412. package/tokenizable-CWW7iSrD.js.map +0 -1
  413. package/tokenizable-DLMP68ZV.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"validate-CdOS7S2u.js","names":[],"sources":["../src/batteries/media/plan.ts","../src/batteries/media/verbs.ts","../src/batteries/media/validate.ts"],"sourcesContent":["/**\n * The neutral `MediaPlan` intermediate representation and its canonical serializers.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. All three front-ends — the\n * chainable builder, the pipe-string parser, and the JSON ops array — compile to this one IR,\n * and the step runtime consumes only this IR. Invariants (frozen design, section 0.7):\n *\n * - **Serializable.** No live `RegExp`, `Media`, or function values — regexes are\n * `{ source, flags }`, media refs are typed handles. A plan can be logged, content-hashed,\n * and embedded in a tool result.\n * - **Round-trip is fixed-point.** `parsePipe(toPipe(plan))` produces an equal plan and\n * `toPipe` is idempotent. `toPipe(parsePipe(s)) === s` is NOT promised (e.g. `2,3,4,5`\n * renders as `2-5`).\n * - **Engine-agnostic.** Steps name verbs, never engines.\n */\n\nimport { isObject } from '@nhtio/adk/guards'\nimport { E_MEDIA_NOT_PIPE_EXPRESSIBLE } from './exceptions'\n\n/**\n * A serializable regex reference. Never a live `RegExp` in the IR.\n */\nexport interface RegExpRef {\n /** The regex source, exactly as `RegExp.prototype.source` would report it. */\n source: string\n /** Sorted flag characters (canonicalized — `gi`, never `ig`). */\n flags: string\n}\n\n/**\n * A reference to another media participating in a multi-input verb (`merge`, `diff`,\n * `apply_patch`, `slides.update_image`).\n *\n * @remarks\n * The `id` variant is the canonical model-facing form — the pipe syntax is an inline\n * `@id` token (`merge with=@018f…`) and the ops form carries the same id. The `builder`\n * variant is implementor-only (a nested chain: `mp(a).diff(mp(b).convert('txt'))`) and is\n * not expressible in a flat pipe string.\n */\nexport type MediaRef = { kind: 'id'; id: string } | { kind: 'builder'; plan: MediaPlan }\n\n/** Scalar arg values the flat pipe grammar can express directly. */\nexport type MediaArgScalar = string | number | boolean | RegExpRef | MediaRef\n\n/**\n * A structured (JSON-shaped) arg value. In the pipe surface these are written as quoted JSON\n * (`updates='[{\"address\":\"B2\",\"value\":3}]'`); in ops they are plain JSON. `null` is legal only\n * inside structured values (cell values), never as a top-level scalar.\n */\nexport type MediaArgJson =\n | string\n | number\n | boolean\n | null\n | MediaArgJson[]\n | { [key: string]: MediaArgJson }\n\n/**\n * The value space of a single verb arg in the IR.\n *\n * @remarks\n * Flat lists (`types=image,font` → `['image','font']`) are `MediaArgScalar[]`. Whether a\n * value parsed from quoted JSON or a flat token is decided by the verb's arg schema — the IR\n * stores the final shape only.\n */\nexport type MediaArgValue = MediaArgScalar | MediaArgScalar[] | MediaArgJson\n\n/** Source span carried by steps parsed from a pipe string, for error mapping. */\nexport interface SourceSpan {\n /** Zero-based character offset into the source string. */\n offset: number\n /** One-based line number. */\n line: number\n /** One-based column number. */\n col: number\n /** Length of the spanned text in characters. */\n length: number\n}\n\n/** One transform step: a canonical verb id plus its validated content args. */\nexport interface MediaStep {\n /**\n * Canonical verb id — dot-namespaced snake_case (`convert`, `select`, `extract.text`,\n * `sheet.update_cells`, `image.resize`).\n */\n verb: string\n /** Validated content args for this verb. */\n args: Record<string, MediaArgValue>\n /** Present when the step came from a pipe string; absent for builder/ops origins. */\n span?: SourceSpan\n}\n\n/** The neutral plan: an ordered, linear list of steps. No branching. */\nexport interface MediaPlan {\n /** The ordered transform steps. */\n steps: MediaStep[]\n}\n\n/** The JSON ops front-end's step shape — identical to {@link MediaStep} minus the span. */\nexport interface MediaOp {\n /** The canonical (or foldable) verb id. */\n verb: string\n /** The verb's named args. */\n args: Record<string, MediaArgValue>\n}\n\n// ── guards ───────────────────────────────────────────────────────────────────\n\n/** `true` when `value` is a {@link RegExpRef}. */\nexport const isRegExpRef = (value: unknown): value is RegExpRef => {\n if (!isObject(value)) return false\n const v = value as Record<string, unknown>\n return typeof v.source === 'string' && typeof v.flags === 'string' && Object.keys(v).length === 2\n}\n\n/** `true` when `value` is a {@link MediaRef}. */\nexport const isMediaRef = (value: unknown): value is MediaRef => {\n if (!isObject(value)) return false\n const v = value as MediaRef\n if (v.kind === 'id') return typeof (v as { id?: unknown }).id === 'string'\n if (v.kind === 'builder') return isObject((v as { plan?: unknown }).plan)\n return false\n}\n\n// ── canonical rendering helpers ──────────────────────────────────────────────\n\n/** Characters legal in an unquoted bareword value. */\nconst BAREWORD = /^[A-Za-z0-9_]+$/\n/** Strings that would lex as a non-ident token and therefore must be quoted. */\nconst LEXES_AS_OTHER = /^(?:\\d+(?:-\\d+)?|\\d+\\.\\d+|true|false|@.*)$/\n\n/**\n * The frozen quoting predicate: quote any string that is empty, would lex as a number, range,\n * boolean, or `@id` token, starts with `/`, or contains a character outside `[A-Za-z0-9_]`.\n */\nconst renderString = (s: string): string => {\n if (s.length === 0 || !BAREWORD.test(s) || LEXES_AS_OTHER.test(s) || s.startsWith('/')) {\n return `\"${s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n')}\"`\n }\n return s\n}\n\n/** Canonicalize regex flags: validate against JS flags and sort. */\nexport const canonicalFlags = (flags: string): string => Array.from(flags).sort().join('')\n\n/** Render a {@link RegExpRef} back to a pipe regex literal, re-escaping bare slashes. */\nconst renderRegExp = (ref: RegExpRef): string => {\n const source = ref.source.length === 0 ? '(?:)' : ref.source\n // Escape bare `/` that are not already escaped and not inside a character class.\n let out = ''\n let inClass = false\n for (let i = 0; i < source.length; i++) {\n const ch = source[i]\n if (ch === '\\\\') {\n out += ch + (source[i + 1] ?? '')\n i++\n continue\n }\n if (ch === '[') inClass = true\n else if (ch === ']') inClass = false\n if (ch === '/' && !inClass) {\n out += '\\\\/'\n continue\n }\n out += ch\n }\n return `/${out}/${canonicalFlags(ref.flags)}`\n}\n\n/**\n * Compress maximal ascending consecutive runs in a number list to `a-b` range tokens.\n * Order-preserving and lossless on the array; never sorts or dedupes.\n */\nconst renderNumberList = (nums: number[]): string => {\n const parts: string[] = []\n let i = 0\n while (i < nums.length) {\n let j = i\n while (\n j + 1 < nums.length &&\n Number.isInteger(nums[j]) &&\n nums[j + 1] === (nums[j] as number) + 1\n ) {\n j++\n }\n if (j - i >= 1 && Number.isInteger(nums[i])) {\n parts.push(`${nums[i]}-${nums[j]}`)\n } else {\n parts.push(String(nums[i]))\n j = i\n }\n i = j + 1\n }\n return parts.join(',')\n}\n\nconst renderScalar = (value: MediaArgScalar): string => {\n if (typeof value === 'number') return String(value)\n if (typeof value === 'boolean') return String(value)\n if (typeof value === 'string') return renderString(value)\n if (isRegExpRef(value)) return renderRegExp(value)\n // MediaRef\n if (value.kind === 'id') return `@${value.id}`\n throw new E_MEDIA_NOT_PIPE_EXPRESSIBLE(['nested builder refs have no pipe form; use toOps()'])\n}\n\nconst isScalar = (value: MediaArgValue): value is MediaArgScalar =>\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean' ||\n isRegExpRef(value) ||\n isMediaRef(value)\n\nconst renderValue = (value: MediaArgValue): string => {\n if (value === null) {\n // null is only legal inside structured JSON values\n throw new E_MEDIA_NOT_PIPE_EXPRESSIBLE(['null is not a flat pipe value; use toOps()'])\n }\n if (Array.isArray(value)) {\n const arr = value as MediaArgScalar[]\n if (arr.length > 0 && arr.every((v) => typeof v === 'number')) {\n return renderNumberList(arr as number[])\n }\n if (arr.every(isScalar)) {\n return arr.map(renderScalar).join(',')\n }\n // structured (nested) array -> quoted JSON\n return `'${JSON.stringify(value)}'`\n }\n if (isScalar(value)) return renderScalar(value)\n // structured object -> quoted JSON\n return `'${JSON.stringify(value)}'`\n}\n\n/**\n * Render a {@link MediaPlan} to its canonical pipe string.\n *\n * @remarks\n * Total for every plan except those containing builder-variant media refs, which throw\n * {@link E_MEDIA_NOT_PIPE_EXPRESSIBLE}. Structured args render as quoted JSON. The output is\n * canonical: dot-namespaced verbs render as space-separated words, number runs compress to\n * ranges, strings quote per the frozen predicate.\n *\n * @param plan - The plan to render.\n * @returns The canonical pipe expression.\n */\nexport const toPipe = (plan: MediaPlan): string =>\n plan.steps\n .map((step) => {\n const verb = step.verb.replace(/\\./g, ' ')\n const args = Object.entries(step.args)\n .map(([k, v]) => `${k}=${renderValue(v)}`)\n .join(' ')\n return args.length > 0 ? `${verb} ${args}` : verb\n })\n .join(' | ')\n\n/**\n * Render a {@link MediaPlan} to its JSON ops array. Total — every plan has an ops form.\n *\n * @param plan - The plan to render.\n * @returns The ops array (spans stripped).\n */\nexport const toOps = (plan: MediaPlan): MediaOp[] =>\n plan.steps.map((step) => ({ verb: step.verb, args: step.args }))\n\n/**\n * Build a {@link MediaPlan} from a JSON ops array. The inverse of {@link toOps}.\n *\n * @remarks\n * Performs structural normalization only (verb-id folding via the caller's verb table happens\n * in validation, not here). Steps carry no spans.\n *\n * @param ops - The ops array.\n * @returns The equivalent plan.\n */\nexport const fromOps = (ops: MediaOp[]): MediaPlan => ({\n steps: ops.map((op) => ({ verb: op.verb, args: op.args })),\n})\n","/**\n * The canonical verb table: every verb the media DSL knows, with arg schemas, engine\n * requirements, format-family applicability, and output kinds.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. This table is the single source\n * of truth consumed by:\n *\n * - the pipe parser's semantic validator (unknown-verb/arg detection, did-you-mean),\n * - the plan compiler (arg coercion + constraint checks),\n * - the engine-narrowing pass (which verbs a deployment advertises),\n * - the forge (generating the `media_query` tool description and few-shot examples),\n * - the builder (typed front-end methods map 1:1 onto entries here).\n *\n * Frozen design decisions (design doc section 0): canonical verb ids are dot-namespaced\n * snake_case; verb matching is separator-insensitive (space/`_`/`.` fold); args are named-only;\n * indices are 1-based everywhere; arg names follow one-meaning-one-name (`to`, `with`, `match`,\n * `replace`, `order`, `pages`, `at`).\n */\n\nimport { PCM_MIME } from './contracts'\n\n/** The value type of a single declared arg. */\nexport type VerbArgType =\n | 'string'\n | 'number'\n | 'boolean'\n | 'enum'\n | 'number-list'\n | 'string-list'\n | 'regex-or-string-list'\n | 'name-or-index'\n | 'media-ref'\n | 'media-ref-list'\n | 'json'\n\n/** Declaration of one named arg on a verb. */\nexport interface VerbArgSpec {\n /** The arg's value type. */\n type: VerbArgType\n /** Whether the statement must supply this arg. */\n required?: boolean\n /** Legal values when `type === 'enum'` (or per-element for list types). */\n values?: readonly string[]\n /** Inclusive minimum for numbers / per-element for number lists. */\n min?: number\n /** Inclusive maximum for numbers / per-element for number lists. */\n max?: number\n /** Model-facing description used in generated tool grammar text. */\n description: string\n}\n\n/**\n * A verb's capability requirement against the deployment's engine registry. Verbs with no\n * requirement are always advertised; input-conditional engine needs (e.g. `extract.text`\n * needing OCR only for images) stay runtime checks inside the step implementation.\n */\nexport type VerbRequirement =\n | { capability: 'convert'; from?: string; to?: string }\n | { capability: 'mutate' }\n | { capability: 'edit'; op?: string }\n\n/** Broad input families used for verb-applicability checks. */\nexport type FormatFamily =\n | 'document' // pdf/docx/odt/rtf/txt/md/html...\n | 'spreadsheet' // xlsx/ods/xls/csv\n | 'presentation' // pptx/odp/ppt\n | 'image'\n | 'audio'\n | 'any'\n\n/** What awaiting a chain ending in this verb resolves to. */\nexport type VerbOutput = 'media' | 'media-list' | 'text' | 'json'\n\n/** One verb table entry. */\nexport interface VerbSpec {\n /** Canonical id: dot-namespaced snake_case (`extract.text`, `sheet.update_cells`). */\n id: string\n /** Model-facing one-line description. */\n description: string\n /** Named args (named-only grammar; no positionals). */\n args: Record<string, VerbArgSpec>\n /**\n * Capability the verb always requires, if any — gates whether the verb is advertised and\n * accepted under a given engine configuration. Input-conditional needs are handled (and\n * error-messaged) by the step implementation at runtime.\n */\n requires?: VerbRequirement\n /** Input families the verb applies to. */\n appliesTo: readonly FormatFamily[]\n /** Output kind. May be refined by an `out`-style arg (documented per verb). */\n output: VerbOutput\n}\n\n/** Conversion targets supported by `convert` (the server's enum plus the SheetJS/data matrix). */\nexport const CONVERT_TARGETS = [\n 'pdf',\n 'html',\n 'txt',\n 'md',\n 'csv',\n 'json',\n 'yaml',\n 'docx',\n 'doc',\n 'rtf',\n 'odt',\n 'xlsx',\n 'xls',\n 'ods',\n 'xlsm',\n 'xlsb',\n 'fods',\n 'sylk',\n 'dif',\n 'dbf',\n 'numbers',\n 'pptx',\n 'ppt',\n 'odp',\n] as const\n\n/** Image output formats supported by `image.format`. */\nexport const IMAGE_FORMATS = ['png', 'jpg', 'jpeg', 'webp', 'tiff', 'avif'] as const\n\n/** The canonical verb table. Order is presentation order in generated grammar text. */\nexport const VERBS: readonly VerbSpec[] = [\n // ── root: document transforms ──────────────────────────────────────────────\n {\n id: 'convert',\n description: 'Convert the media to another format.',\n args: {\n to: {\n type: 'enum',\n required: true,\n values: CONVERT_TARGETS,\n description: 'Target format.',\n },\n },\n requires: { capability: 'convert' },\n appliesTo: ['document', 'spreadsheet', 'presentation'],\n output: 'media',\n },\n {\n id: 'select',\n description: 'Keep only the listed pages/slides/sections (1-based), producing one file.',\n args: {\n pages: {\n type: 'number-list',\n required: true,\n min: 1,\n description: 'Pages (or slides/sections) to keep, 1-based. Ranges allowed: 2-5,8.',\n },\n },\n appliesTo: ['document', 'presentation'],\n output: 'media',\n },\n {\n id: 'split',\n description: 'Split the media into multiple files by page or section.',\n args: {\n by: {\n type: 'enum',\n values: ['page', 'section'],\n description: 'Split unit. Default: page.',\n },\n ranges: {\n type: 'json',\n description:\n \"Explicit grouping as a JSON array of [start,end] pairs (1-based), e.g. '[[1,3],[5,7]]'.\",\n },\n },\n appliesTo: ['document', 'presentation'],\n output: 'media-list',\n },\n {\n id: 'merge',\n description: 'Merge other media into this one, in order.',\n args: {\n with: {\n type: 'media-ref-list',\n required: true,\n description: 'Other media to append, as @id refs: with=@<media id>,@<media id>.',\n },\n },\n appliesTo: ['document', 'presentation'],\n output: 'media',\n },\n {\n id: 'reorder',\n description: 'Reorder pages/slides/sections by the given 1-based index order.',\n args: {\n order: {\n type: 'number-list',\n required: true,\n min: 1,\n description: 'New order of existing 1-based indices.',\n },\n },\n appliesTo: ['document', 'presentation'],\n output: 'media',\n },\n {\n id: 'redact',\n description:\n 'Redact matching text. Prefer literal strings; /regex/ is supported. PDF redaction is VISUAL (draw-over + metadata strip; content streams keep the text) — for content-level PDF redaction, extract text first.',\n args: {\n match: {\n type: 'regex-or-string-list',\n required: true,\n description: 'Literal string(s) or a /regex/ to redact.',\n },\n replace: {\n type: 'string',\n description:\n 'Replacement text. Omit for the blackout/removal default; send an empty string to blank the match out with nothing.',\n },\n },\n appliesTo: ['document', 'spreadsheet', 'presentation'],\n output: 'media',\n },\n {\n id: 'sanitize',\n description: 'Remove potentially unsafe embedded content from the media.',\n args: {},\n appliesTo: ['document', 'spreadsheet', 'presentation'],\n output: 'media',\n },\n {\n id: 'normalize',\n description: 'Normalize the media structure/encoding for downstream consistency.',\n args: {},\n appliesTo: ['document', 'spreadsheet', 'presentation'],\n output: 'media',\n },\n {\n id: 'update_text',\n description: 'Replace the first occurrence of an anchor text.',\n args: {\n anchor: {\n type: 'string',\n required: true,\n description: 'Existing text to find.',\n },\n replace: {\n type: 'string',\n required: true,\n description: 'Replacement text (empty string deletes).',\n },\n },\n appliesTo: ['document', 'presentation'],\n output: 'media',\n },\n {\n id: 'diff',\n description:\n 'Compare this media against another; returns a structured diff whose patch text feeds apply_patch directly.',\n args: {\n with: {\n type: 'media-ref',\n required: true,\n description: 'The media to compare against, as an @id ref.',\n },\n },\n appliesTo: ['document', 'spreadsheet', 'presentation'],\n output: 'json',\n },\n {\n id: 'apply_patch',\n description:\n 'Apply a patch to the media text: a unified diff (as produced by the diff verb — that output feeds this verb directly), or a structured \"*** Begin Patch\" envelope (Add/Delete/Update File) for multi-file changes. In the structured envelope, add-file content lines must start with \"+\" (the unified-diff convention).',\n args: {\n patch: {\n type: 'string',\n required: true,\n description:\n 'The patch content: unified diff, or a structured envelope starting with \"*** Begin Patch\". Add-file content lines must start with \"+\".',\n },\n with: {\n type: 'media-ref-list',\n description: 'Optional additional context media, as @id refs.',\n },\n },\n appliesTo: ['document'],\n output: 'media',\n },\n {\n id: 'append',\n description: 'Append text to text-family media (txt/md/csv/yaml).',\n args: {\n text: { type: 'string', required: true, description: 'The text to append.' },\n newline: {\n type: 'boolean',\n description: 'Terminate with a newline (and separate from existing content). Default true.',\n },\n },\n appliesTo: ['document', 'spreadsheet'],\n output: 'media',\n },\n // ── data namespace (JSON/YAML structural ops) ───────────────────────────────\n {\n id: 'data.set',\n description: 'Set a value at a path in JSON/YAML media (creates missing containers).',\n args: {\n path: {\n type: 'string',\n required: true,\n description: 'Dot/bracket path, e.g. a.b[2].c',\n },\n value: {\n type: 'string',\n required: true,\n description: \"JSON-encoded value: '42', '\\\"text\\\"', '{\\\"k\\\":1}'. Bare strings accepted.\",\n },\n },\n appliesTo: ['document'],\n output: 'media',\n },\n {\n id: 'data.merge',\n description: 'Merge a JSON object fragment into JSON/YAML media.',\n args: {\n fragment: {\n type: 'string',\n required: true,\n description: 'The JSON object to merge, e.g. \\'{\"a\":{\"b\":1}}\\'.',\n },\n strategy: {\n type: 'enum',\n values: ['deep', 'shallow'],\n description: 'Merge strategy. Default deep.',\n },\n },\n appliesTo: ['document'],\n output: 'media',\n },\n {\n id: 'data.delete',\n description: 'Delete a key or array element at a path in JSON/YAML media.',\n args: {\n path: {\n type: 'string',\n required: true,\n description: 'Dot/bracket path of the key/element to remove.',\n },\n },\n appliesTo: ['document'],\n output: 'media',\n },\n // ── root: extraction ────────────────────────────────────────────────────────\n {\n id: 'extract.text',\n description:\n 'Extract text from any supported media (document, spreadsheet, image). To limit pages: select pages=… | extract text.',\n args: {\n ocr: {\n type: 'enum',\n values: ['off', 'auto', 'force'],\n description: 'OCR behavior. Default auto (OCR only when there is no text layer).',\n },\n ocr_out: {\n type: 'enum',\n values: ['txt', 'hocr', 'json'],\n description: 'OCR output structure when OCR runs. Default txt.',\n },\n lang: {\n type: 'string-list',\n description: 'OCR language hint(s), e.g. lang=eng,deu. Quote tags with dashes.',\n },\n },\n appliesTo: ['document', 'spreadsheet', 'presentation', 'image'],\n output: 'text',\n },\n {\n id: 'extract.metadata',\n description: 'Extract document metadata (author, dates, page count) as JSON.',\n args: {},\n appliesTo: ['document', 'spreadsheet', 'presentation', 'image', 'audio'],\n output: 'json',\n },\n {\n id: 'extract.assets',\n description: 'Extract embedded assets (images, fonts, attachments) as separate media.',\n args: {\n types: {\n type: 'string-list',\n values: ['image', 'font', 'attachment', 'all'],\n description: 'Asset kinds to extract. Default all.',\n },\n format: {\n type: 'enum',\n values: IMAGE_FORMATS,\n description:\n 'Re-encode extracted images to this format. Default: native encoding as stored.',\n },\n },\n appliesTo: ['document', 'presentation', 'spreadsheet'],\n output: 'media-list',\n },\n {\n id: 'chunk',\n description: 'Split extracted text into chunks for retrieval/indexing.',\n args: {\n by: {\n type: 'enum',\n values: ['sentence', 'paragraph', 'fixed'],\n description: 'Chunking strategy. Default paragraph.',\n },\n size: {\n type: 'number',\n min: 1,\n description: 'Chunk size for fixed strategy / max size otherwise.',\n },\n overlap: {\n type: 'number',\n min: 0,\n description: 'Overlap between consecutive chunks.',\n },\n },\n appliesTo: ['document', 'any'],\n output: 'json',\n },\n // ── sheet namespace ─────────────────────────────────────────────────────────\n {\n id: 'sheet.add_rows',\n description: 'Insert rows into a worksheet.',\n args: {\n sheet: {\n type: 'name-or-index',\n description: 'Target worksheet: bare number = 1-based index, quoted string = name.',\n },\n rows: {\n type: 'json',\n required: true,\n description: 'Rows as a JSON array of arrays of cell values, e.g. \\'[[\"a\",1],[\"b\",2]]\\'.',\n },\n before: { type: 'number', min: 1, description: 'Insert before this 1-based row.' },\n after: { type: 'number', min: 1, description: 'Insert after this 1-based row.' },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.add_columns',\n description: 'Insert columns into a worksheet.',\n args: {\n sheet: { type: 'name-or-index', description: 'Target worksheet (index or quoted name).' },\n headers: {\n type: 'string-list',\n description: 'Header names for the new columns (values empty).',\n },\n columns: {\n type: 'json',\n description: 'Full column descriptors as JSON: \\'[{\"header\":\"X\",\"values\":[1,2]}]\\'.',\n },\n before: { type: 'number', min: 1, description: 'Insert before this 1-based column.' },\n after: { type: 'number', min: 1, description: 'Insert after this 1-based column.' },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.update_cells',\n description: 'Update specific cells.',\n args: {\n sheet: { type: 'name-or-index', description: 'Target worksheet (index or quoted name).' },\n updates: {\n type: 'json',\n required: true,\n description:\n 'JSON array of updates: \\'[{\"address\":\"B2\",\"value\":42}]\\' or \\'[{\"row\":2,\"col\":3,\"value\":\"x\"}]\\'.',\n },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.delete_rows',\n description: 'Delete rows by 1-based index.',\n args: {\n sheet: { type: 'name-or-index', description: 'Target worksheet (index or quoted name).' },\n rows: {\n type: 'number-list',\n required: true,\n min: 1,\n description: '1-based row indices to delete.',\n },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.delete_columns',\n description: 'Delete columns by 1-based index.',\n args: {\n sheet: { type: 'name-or-index', description: 'Target worksheet (index or quoted name).' },\n columns: {\n type: 'number-list',\n required: true,\n min: 1,\n description: '1-based column indices to delete.',\n },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.rename_sheet',\n description: 'Rename a worksheet. The target must be a sheet NAME (quote it).',\n args: {\n sheet: {\n type: 'string',\n required: true,\n description: 'Current sheet name (names only for rename; quote it).',\n },\n to: { type: 'string', required: true, description: 'New sheet name.' },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.add_sheet',\n description: 'Add a new worksheet.',\n args: {\n name: { type: 'string', required: true, description: 'Name for the new worksheet.' },\n at: { type: 'number', min: 1, description: 'Insert at this 1-based position.' },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.remove_sheet',\n description: 'Remove a worksheet. The target must be a sheet NAME (quote it).',\n args: {\n sheet: {\n type: 'string',\n required: true,\n description: 'Sheet name to remove (names only; quote it).',\n },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.reorder_sheets',\n description: 'Reorder worksheets.',\n args: {\n order: {\n type: 'json',\n required: true,\n description:\n 'JSON array of sheet names and/or 1-based indices in the new order: \\'[\"Summary\",2,3]\\'.',\n },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.transform_table',\n description: 'Rename/select/drop table columns by header name.',\n args: {\n sheet: { type: 'name-or-index', description: 'Target worksheet (index or quoted name).' },\n header_row: { type: 'number', min: 1, description: '1-based header row. Default 1.' },\n select: { type: 'string-list', description: 'Column headers to keep.' },\n drop: { type: 'string-list', description: 'Column headers to drop.' },\n rename: {\n type: 'json',\n description: 'JSON array of renames: \\'[{\"from\":\"Old\",\"to\":\"New\"}]\\'.',\n },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n // ── slides namespace ────────────────────────────────────────────────────────\n {\n id: 'slides.add',\n description: 'Add a new slide.',\n args: {\n at: { type: 'number', min: 1, description: 'Insert at this 1-based position.' },\n title: { type: 'string', description: 'Title text for the new slide.' },\n layout: { type: 'string', description: 'Layout name (template-dependent).' },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n {\n id: 'slides.update_text',\n description: 'Update text on a slide.',\n args: {\n slide: {\n type: 'name-or-index',\n description: 'Target slide: bare number = 1-based index, quoted string = title.',\n },\n placeholder: { type: 'string', description: 'Placeholder/shape to target.' },\n text: { type: 'string', required: true, description: 'Replacement text.' },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n {\n id: 'slides.update_table',\n description: 'Update table cells on a slide.',\n args: {\n slide: { type: 'name-or-index', description: 'Target slide (index or quoted title).' },\n updates: {\n type: 'json',\n required: true,\n description: 'JSON array: \\'[{\"row\":1,\"col\":2,\"value\":\"x\"}]\\' (1-based).',\n },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n {\n id: 'slides.update_image',\n description: 'Replace an image on a slide with another media.',\n args: {\n slide: { type: 'name-or-index', description: 'Target slide (index or quoted title).' },\n placeholder: { type: 'string', description: 'Placeholder/shape to target.' },\n with: {\n type: 'media-ref',\n required: true,\n description: 'The replacement image, as an @id ref.',\n },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n {\n id: 'slides.update_chart',\n description: 'Update chart data on a slide.',\n args: {\n slide: { type: 'name-or-index', description: 'Target slide (index or quoted title).' },\n data: {\n type: 'json',\n description: 'JSON array-of-arrays of chart data: \\'[[\"Q1\",10],[\"Q2\",20]]\\'.',\n },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n {\n id: 'slides.delete',\n description: 'Delete slides by 1-based index.',\n args: {\n slides: {\n type: 'number-list',\n required: true,\n min: 1,\n description: '1-based slide indices to delete.',\n },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n {\n id: 'slides.reorder',\n description: 'Reorder slides.',\n args: {\n order: {\n type: 'number-list',\n required: true,\n min: 1,\n description: 'New order of existing 1-based slide indices.',\n },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n {\n id: 'slides.duplicate',\n description: 'Duplicate a slide.',\n args: {\n slide: { type: 'number', required: true, min: 1, description: '1-based slide to copy.' },\n at: { type: 'number', min: 1, description: 'Insert the copy at this position.' },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n // ── image namespace (split verbs; runtime fuses adjacent image.* steps) ─────\n {\n id: 'image.resize',\n description: 'Resize the image.',\n args: {\n width: { type: 'number', min: 1, max: 16384, description: 'Target width in px.' },\n height: { type: 'number', min: 1, max: 16384, description: 'Target height in px.' },\n fit: {\n type: 'enum',\n values: ['cover', 'contain', 'fill', 'inside', 'outside'],\n description: 'Resize fit mode. Default cover.',\n },\n },\n requires: { capability: 'mutate' },\n appliesTo: ['image'],\n output: 'media',\n },\n {\n id: 'image.format',\n description: 'Re-encode the image to another format.',\n args: {\n to: {\n type: 'enum',\n required: true,\n values: IMAGE_FORMATS,\n description: 'Target image format.',\n },\n quality: { type: 'number', min: 1, max: 100, description: 'Quality for lossy formats.' },\n strip_metadata: {\n type: 'boolean',\n description: 'Remove EXIF/ICC metadata from the output.',\n },\n },\n requires: { capability: 'mutate' },\n appliesTo: ['image'],\n output: 'media',\n },\n {\n id: 'image.rotate',\n description: 'Rotate the image.',\n args: {\n deg: {\n type: 'enum',\n required: true,\n values: ['90', '180', '270'],\n description: 'Rotation in degrees (clockwise).',\n },\n },\n requires: { capability: 'mutate' },\n appliesTo: ['image'],\n output: 'media',\n },\n {\n id: 'image.flip',\n description: 'Flip the image.',\n args: {\n axis: {\n type: 'enum',\n required: true,\n values: ['horizontal', 'vertical', 'both'],\n description: 'Flip axis.',\n },\n },\n requires: { capability: 'mutate' },\n appliesTo: ['image'],\n output: 'media',\n },\n {\n id: 'image.strip_metadata',\n description: 'Remove EXIF/ICC metadata from the image without other changes.',\n args: {},\n requires: { capability: 'mutate' },\n appliesTo: ['image'],\n output: 'media',\n },\n // ── audio namespace ─────────────────────────────────────────────────────────\n {\n id: 'audio.transcribe',\n description: 'Transcribe speech to text.',\n args: {\n lang: {\n type: 'string',\n description: 'Language hint, e.g. lang=en. Quote tags with dashes: lang=\"en-US\".',\n },\n out: {\n type: 'enum',\n values: ['txt', 'srt', 'vtt', 'json'],\n description: 'Output format. Default txt. srt/vtt produce subtitles.',\n },\n translate: {\n type: 'boolean',\n description: 'Translate the transcription to English.',\n },\n },\n requires: { capability: 'convert', from: PCM_MIME },\n appliesTo: ['audio'],\n output: 'text',\n },\n] as const\n\n/** Map of canonical verb id → spec, for direct lookup. */\nexport const VERB_INDEX: ReadonlyMap<string, VerbSpec> = new Map(VERBS.map((v) => [v.id, v]))\n\n/**\n * Fold a verb token sequence to canonical form: lowercase, separators (space/`_`/`.`)\n * normalized so `extract_text` ≡ `extract text` ≡ `extract.text` all match `extract.text`.\n *\n * @param words - The verb word tokens as written (1 or 2 words, possibly containing `_`/`.`).\n * @returns The canonical verb id when a fold-match exists, otherwise `undefined`.\n */\nexport const foldVerb = (words: string[]): string | undefined => {\n const flat = words\n .join(' ')\n .toLowerCase()\n .replace(/[._\\s]+/g, ' ')\n .trim()\n return FOLDED_INDEX.get(flat)\n}\n\n/** Internal: folded \"word word\" form → canonical id. */\nconst FOLDED_INDEX: ReadonlyMap<string, string> = (() => {\n const map = new Map<string, string>()\n for (const v of VERBS) {\n const folded = v.id.replace(/[._]+/g, ' ')\n if (map.has(folded)) {\n throw new Error(`verb table invariant violated: \"${folded}\" folds to multiple verbs`)\n }\n map.set(folded, v.id)\n }\n return map\n})()\n\n/**\n * All folded verb word-sequences, for the parser's longest-match verb recognition and for\n * generated grammar text.\n */\nexport const FOLDED_VERBS: readonly string[] = Array.from(FOLDED_INDEX.keys())\n\n/**\n * Suggest the nearest verbs to an unknown input, for did-you-mean errors. Matches whole folded\n * forms AND suffix words (`resize` suggests `image resize`), per the frozen error model.\n *\n * @param input - The unknown verb text as written.\n * @param candidates - The folded verb forms to search (pass the narrowed set to avoid\n * suggesting unconfigured verbs).\n * @returns Up to three suggestions, best first.\n */\nexport const suggestVerbs = (input: string, candidates: readonly string[]): string[] => {\n const folded = input\n .toLowerCase()\n .replace(/[._\\s]+/g, ' ')\n .trim()\n const scored: Array<{ name: string; score: number }> = []\n for (const cand of candidates) {\n const direct = levenshtein(folded, cand)\n const words = cand.split(' ')\n const suffix = words.length > 1 ? levenshtein(folded, words[words.length - 1]) : Infinity\n const score = Math.min(direct, suffix)\n if (score <= Math.max(2, Math.floor(folded.length / 3))) {\n scored.push({ name: cand, score })\n }\n }\n scored.sort((a, b) => a.score - b.score)\n return scored.slice(0, 3).map((s) => s.name)\n}\n\n/** Classic two-row Levenshtein distance. */\nconst levenshtein = (a: string, b: string): number => {\n if (a === b) return 0\n if (a.length === 0) return b.length\n if (b.length === 0) return a.length\n let prev = Array.from({ length: b.length + 1 }, (_, i) => i)\n let curr = new Array<number>(b.length + 1)\n for (let i = 1; i <= a.length; i++) {\n curr[0] = i\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1\n curr[j] = Math.min(prev[j] + 1, curr[j - 1] + 1, prev[j - 1] + cost)\n }\n ;[prev, curr] = [curr, prev]\n }\n return prev[b.length]\n}\n","/**\n * The semantic validator: checks raw parsed segments (or ops) against the verb table and the\n * deployment's configured engines, producing the validated {@link MediaPlan} or a\n * model-actionable error.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. This is the layer no parser\n * toolkit could supply — every error names what was wrong, suggests the nearest valid form,\n * and shows a corrective exemplar (frozen design 0.14). Engine narrowing happens HERE, never\n * at parse time (frozen 0.3): the same string parses identically in every deployment; only\n * validation differs.\n */\n\nimport { isMediaRef, isRegExpRef } from './plan'\nimport { isError, isObject } from '@nhtio/adk/guards'\nimport { VERB_INDEX, suggestVerbs, foldVerb } from './verbs'\nimport {\n E_MEDIA_UNKNOWN_VERB,\n E_MEDIA_UNKNOWN_ARG,\n E_MEDIA_BAD_ARG,\n E_MEDIA_MISSING_ARG,\n E_MEDIA_ENGINE_REQUIRED,\n} from './exceptions'\nimport type { RawSegment, RawArgValue } from './pipe'\nimport type { VerbSpec, VerbArgSpec, VerbRequirement } from './verbs'\nimport type { MediaPlan, MediaStep, MediaArgValue, MediaArgScalar, MediaOp } from './plan'\n\n/**\n * The minimal synchronous capability probe the validator narrows against. The pipeline's\n * engine registry implements it; tests stub it.\n */\nexport interface CapabilityProbe {\n /** `true` when some engine declares a matching convert edge (omit either side for \"any\"). */\n hasConvert(from?: string, to?: string): boolean\n /** `true` when some engine declares a mutate capability. */\n hasMutate(): boolean\n /**\n * `true` when some engine declares a matching edit capability (omit both for \"any\").\n * Optional so existing probe stubs stay valid; absent means \"no edit engines\".\n */\n hasEdit?(mime?: string, op?: string): boolean\n}\n\n/** Options for {@link validateSegments} / {@link validateOps}. */\nexport interface ValidateOptions {\n /** The deployment's capabilities. Narrows advertised verbs + error suggestions. */\n capabilities: CapabilityProbe\n}\n\n/** `true` when the deployment satisfies a verb's capability requirement. */\nconst satisfies = (capabilities: CapabilityProbe, requires: VerbRequirement): boolean => {\n if (requires.capability === 'mutate') return capabilities.hasMutate()\n if (requires.capability === 'edit') return capabilities.hasEdit?.(undefined, requires.op) ?? false\n return capabilities.hasConvert(requires.from, requires.to)\n}\n\n/** A human phrase for an unmet requirement, for the do-not-retry error. */\nconst requirementText = (requires: VerbRequirement): string => {\n if (requires.capability === 'mutate') return 'an engine that can mutate this media'\n if (requires.capability === 'edit') {\n return `an engine that can edit this media${requires.op ? ` (op \"${requires.op}\")` : ''}`\n }\n const from = requires.from ? ` from ${requires.from}` : ''\n const to = requires.to ? ` to ${requires.to}` : ''\n return `an engine that can convert${from}${to}`\n}\n\n/** The folded verb forms available under a given capability configuration. */\nexport const availableVerbs = (capabilities: CapabilityProbe): string[] => {\n const out: string[] = []\n for (const [id, spec] of VERB_INDEX) {\n if (spec.requires && !satisfies(capabilities, spec.requires)) continue\n out.push(id.replace(/[._]+/g, ' '))\n }\n return out\n}\n\nconst levSuggest = (verbText: string, capabilities: CapabilityProbe): string => {\n const suggestions = suggestVerbs(verbText, availableVerbs(capabilities))\n return suggestions.length > 0 ? ` did you mean \"${suggestions[0]}\"?` : ''\n}\n\nconst verbList = (capabilities: CapabilityProbe): string => availableVerbs(capabilities).join(', ')\n\nconst resolveVerb = (\n verbText: string,\n capabilities: CapabilityProbe,\n position: number\n): VerbSpec => {\n const canonical = foldVerb(verbText.split(' ')) ?? verbText\n const spec = VERB_INDEX.get(canonical)\n if (!spec) {\n throw new E_MEDIA_UNKNOWN_VERB([\n `unknown verb \"${verbText}\" at segment ${position}.${levSuggest(verbText, capabilities)} Available verbs: ${verbList(capabilities)}`,\n ])\n }\n if (spec.requires && !satisfies(capabilities, spec.requires)) {\n throw new E_MEDIA_ENGINE_REQUIRED([\n `verb \"${verbText}\" requires ${requirementText(spec.requires)}, and none is configured in this deployment. Do not retry this verb here. Available verbs: ${verbList(capabilities)}`,\n ])\n }\n return spec\n}\n\nconst suggestArg = (name: string, spec: VerbSpec): string => {\n const candidates = Object.keys(spec.args)\n const ranked = suggestVerbs(name, candidates)\n return ranked.length > 0 ? ` did you mean \"${ranked[0]}\"?` : ''\n}\n\nconst argList = (spec: VerbSpec): string => {\n const names = Object.keys(spec.args)\n return names.length > 0 ? names.join(', ') : '(none)'\n}\n\nconst exemplar = (spec: VerbSpec): string => {\n const verb = spec.id.replace(/\\./g, ' ')\n const parts: string[] = [verb]\n for (const [name, arg] of Object.entries(spec.args)) {\n if (!arg.required) continue\n parts.push(`${name}=${exampleValue(arg)}`)\n }\n return parts.join(' ')\n}\n\nconst exampleValue = (arg: VerbArgSpec): string => {\n switch (arg.type) {\n case 'enum':\n return arg.values?.[0] ?? 'value'\n case 'number':\n return String(arg.min ?? 1)\n case 'number-list':\n return '1-3,5'\n case 'string-list':\n return 'a,b'\n case 'boolean':\n return 'true'\n case 'regex-or-string-list':\n return '\"literal text\"'\n case 'media-ref':\n return '@<media id>'\n case 'media-ref-list':\n return '@<media id>'\n case 'json':\n return `'[…]'`\n default:\n return '\"value\"'\n }\n}\n\n/** Coerce + check one arg value against its spec. Returns the IR-final value. */\nconst checkArg = (\n verb: VerbSpec,\n name: string,\n raw: { value: MediaArgValue; quoted: boolean }\n): MediaArgValue => {\n const spec = verb.args[name]\n const verbText = verb.id.replace(/\\./g, ' ')\n const where = `arg \"${name}\" on \"${verbText}\"`\n const bad = (msg: string): never => {\n throw new E_MEDIA_BAD_ARG([`${where}: ${msg}. Write it like: ${exemplar(verb)}`])\n }\n const v = raw.value\n switch (spec.type) {\n case 'name-or-index': {\n if (typeof v === 'number') {\n if (!Number.isInteger(v) || v < 1) bad('indices are 1-based integers')\n return v\n }\n if (typeof v !== 'string') bad('expected a 1-based index or a quoted name')\n return v\n }\n case 'string': {\n if (typeof v === 'number' && !raw.quoted) return String(v)\n if (typeof v !== 'string')\n bad(`expected text${typeof v === 'object' ? ', got a structured value' : ''}`)\n return v\n }\n case 'number': {\n if (typeof v !== 'number') bad('expected a number')\n const n = v as number\n if (spec.min !== undefined && n < spec.min) bad(`must be ≥ ${spec.min} (indices are 1-based)`)\n if (spec.max !== undefined && n > spec.max) bad(`must be ≤ ${spec.max}`)\n return n\n }\n case 'boolean': {\n if (typeof v !== 'boolean') bad('expected true or false')\n return v\n }\n case 'enum': {\n const s = typeof v === 'number' ? String(v) : v\n if (typeof s !== 'string' || !spec.values?.includes(s)) {\n bad(`\"${String(v)}\" is not valid; valid values: ${spec.values?.join(', ')}`)\n }\n return s as string\n }\n case 'number-list': {\n const arr = Array.isArray(v) ? v : [v]\n if (!arr.every((x): x is number => typeof x === 'number'))\n bad('expected numbers (e.g. 1-3,5)')\n const nums = arr as number[]\n if (spec.min !== undefined && nums.some((n) => n < (spec.min as number))) {\n bad(`values must be ≥ ${spec.min} (indices are 1-based)`)\n }\n return nums\n }\n case 'string-list': {\n const arr = Array.isArray(v) ? v : [v]\n if (!arr.every((x): x is string => typeof x === 'string'))\n bad('expected names (quote values with special characters)')\n const strs = arr as string[]\n if (spec.values && !strs.every((s) => spec.values?.includes(s))) {\n bad(`valid values: ${spec.values.join(', ')}`)\n }\n return strs\n }\n case 'regex-or-string-list': {\n if (isRegExpRef(v)) return v\n const arr = Array.isArray(v) ? v : [v]\n if (arr.every((x) => typeof x === 'string' || isRegExpRef(x))) return arr as MediaArgScalar[]\n bad('expected literal text, a list of literals, or a /regex/')\n break\n }\n case 'media-ref': {\n if (isMediaRef(v)) return v\n bad('expected a media reference: with=@<media id> (get ids from list_media)')\n break\n }\n case 'media-ref-list': {\n const arr = Array.isArray(v) ? v : [v]\n if (arr.every(isMediaRef)) return arr as MediaArgScalar[]\n bad('expected media references: with=@<id>,@<id> (get ids from list_media)')\n break\n }\n case 'json': {\n // From pipe: a quoted string containing JSON. From ops: already-structured JSON.\n if (typeof v === 'string') {\n if (!raw.quoted) bad(`expected a quoted JSON value, e.g. ${name}='[…]'`)\n try {\n return JSON.parse(v) as MediaArgValue\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n bad(`the quoted value is not valid JSON (${detail})`)\n }\n }\n if (isObject(v) || Array.isArray(v)) return v\n bad(`expected a JSON value, e.g. ${name}='[…]'`)\n break\n }\n }\n /* unreachable */\n throw new E_MEDIA_BAD_ARG([`${where}: invalid value`])\n}\n\nconst checkStep = (\n spec: VerbSpec,\n args: ReadonlyMap<string, { value: MediaArgValue; quoted: boolean }>\n): MediaStep => {\n const verbText = spec.id.replace(/\\./g, ' ')\n const finalArgs: Record<string, MediaArgValue> = {}\n for (const [name, raw] of args) {\n if (!(name in spec.args)) {\n throw new E_MEDIA_UNKNOWN_ARG([\n `verb \"${verbText}\" has no arg \"${name}\".${suggestArg(name, spec)} Args: ${argList(spec)}. Write it like: ${exemplar(spec)}`,\n ])\n }\n finalArgs[name] = checkArg(spec, name, raw)\n }\n for (const [name, argSpec] of Object.entries(spec.args)) {\n if (argSpec.required && !(name in finalArgs)) {\n throw new E_MEDIA_MISSING_ARG([\n `verb \"${verbText}\" requires arg \"${name}\" (${argSpec.description}). Write it like: ${exemplar(spec)}`,\n ])\n }\n }\n return { verb: spec.id, args: finalArgs }\n}\n\n/**\n * Validate raw pipe segments into a {@link MediaPlan}.\n *\n * @param segments - Output of `parsePipeRaw`.\n * @param options - The deployment's capability probe.\n * @returns The validated plan, spans preserved.\n */\nexport const validateSegments = (\n segments: readonly RawSegment[],\n options: ValidateOptions\n): MediaPlan => {\n const steps: MediaStep[] = []\n segments.forEach((seg, i) => {\n const spec = resolveVerb(seg.verb.replace(/\\./g, ' '), options.capabilities, i + 1)\n const step = checkStep(spec, seg.args)\n step.span = seg.span\n steps.push(step)\n })\n return { steps }\n}\n\n/**\n * Validate a JSON ops array into a {@link MediaPlan}. The same checks as the pipe path —\n * verbs fold the same way, args validate against the same specs — so the two front-ends\n * produce identical plans for equivalent statements.\n *\n * @param ops - The ops array.\n * @param options - The deployment's capability probe.\n * @returns The validated plan (no spans).\n */\nexport const validateOps = (ops: readonly MediaOp[], options: ValidateOptions): MediaPlan => {\n const steps: MediaStep[] = []\n ops.forEach((op, i) => {\n const spec = resolveVerb(op.verb.replace(/[._]+/g, ' '), options.capabilities, i + 1)\n const args = new Map<string, RawArgValue>(\n Object.entries(op.args).map(([k, v]) => [\n k,\n {\n value: v,\n quoted: typeof v === 'string',\n span: { offset: 0, line: 1, col: 1, length: 0 },\n },\n ])\n )\n steps.push(checkStep(spec, args))\n })\n return { steps }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"validate-CkQI-48O.js","names":[],"sources":["../src/batteries/media/plan.ts","../src/batteries/media/verbs.ts","../src/batteries/media/validate.ts"],"sourcesContent":["/**\n * The neutral `MediaPlan` intermediate representation and its canonical serializers.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. All three front-ends — the\n * chainable builder, the pipe-string parser, and the JSON ops array — compile to this one IR,\n * and the step runtime consumes only this IR. Invariants (frozen design, section 0.7):\n *\n * - **Serializable.** No live `RegExp`, `Media`, or function values — regexes are\n * `{ source, flags }`, media refs are typed handles. A plan can be logged, content-hashed,\n * and embedded in a tool result.\n * - **Round-trip is fixed-point.** `parsePipe(toPipe(plan))` produces an equal plan and\n * `toPipe` is idempotent. `toPipe(parsePipe(s)) === s` is NOT promised (e.g. `2,3,4,5`\n * renders as `2-5`).\n * - **Engine-agnostic.** Steps name verbs, never engines.\n */\n\nimport { isObject } from '@nhtio/adk/guards'\nimport { E_MEDIA_NOT_PIPE_EXPRESSIBLE } from './exceptions'\n\n/**\n * A serializable regex reference. Never a live `RegExp` in the IR.\n */\nexport interface RegExpRef {\n /** The regex source, exactly as `RegExp.prototype.source` would report it. */\n source: string\n /** Sorted flag characters (canonicalized — `gi`, never `ig`). */\n flags: string\n}\n\n/**\n * A reference to another media participating in a multi-input verb (`merge`, `diff`,\n * `apply_patch`, `slides.update_image`).\n *\n * @remarks\n * The `id` variant is the canonical model-facing form — the pipe syntax is an inline\n * `@id` token (`merge with=@018f…`) and the ops form carries the same id. The `builder`\n * variant is implementor-only (a nested chain: `mp(a).diff(mp(b).convert('txt'))`) and is\n * not expressible in a flat pipe string.\n */\nexport type MediaRef = { kind: 'id'; id: string } | { kind: 'builder'; plan: MediaPlan }\n\n/** Scalar arg values the flat pipe grammar can express directly. */\nexport type MediaArgScalar = string | number | boolean | RegExpRef | MediaRef\n\n/**\n * A structured (JSON-shaped) arg value. In the pipe surface these are written as quoted JSON\n * (`updates='[{\"address\":\"B2\",\"value\":3}]'`); in ops they are plain JSON. `null` is legal only\n * inside structured values (cell values), never as a top-level scalar.\n */\nexport type MediaArgJson =\n | string\n | number\n | boolean\n | null\n | MediaArgJson[]\n | { [key: string]: MediaArgJson }\n\n/**\n * The value space of a single verb arg in the IR.\n *\n * @remarks\n * Flat lists (`types=image,font` → `['image','font']`) are `MediaArgScalar[]`. Whether a\n * value parsed from quoted JSON or a flat token is decided by the verb's arg schema — the IR\n * stores the final shape only.\n */\nexport type MediaArgValue = MediaArgScalar | MediaArgScalar[] | MediaArgJson\n\n/** Source span carried by steps parsed from a pipe string, for error mapping. */\nexport interface SourceSpan {\n /** Zero-based character offset into the source string. */\n offset: number\n /** One-based line number. */\n line: number\n /** One-based column number. */\n col: number\n /** Length of the spanned text in characters. */\n length: number\n}\n\n/** One transform step: a canonical verb id plus its validated content args. */\nexport interface MediaStep {\n /**\n * Canonical verb id — dot-namespaced snake_case (`convert`, `select`, `extract.text`,\n * `sheet.update_cells`, `image.resize`).\n */\n verb: string\n /** Validated content args for this verb. */\n args: Record<string, MediaArgValue>\n /** Present when the step came from a pipe string; absent for builder/ops origins. */\n span?: SourceSpan\n}\n\n/** The neutral plan: an ordered, linear list of steps. No branching. */\nexport interface MediaPlan {\n /** The ordered transform steps. */\n steps: MediaStep[]\n}\n\n/** The JSON ops front-end's step shape — identical to {@link MediaStep} minus the span. */\nexport interface MediaOp {\n /** The canonical (or foldable) verb id. */\n verb: string\n /** The verb's named args. */\n args: Record<string, MediaArgValue>\n}\n\n// ── guards ───────────────────────────────────────────────────────────────────\n\n/** `true` when `value` is a {@link RegExpRef}. */\nexport const isRegExpRef = (value: unknown): value is RegExpRef => {\n if (!isObject(value)) return false\n const v = value as Record<string, unknown>\n return typeof v.source === 'string' && typeof v.flags === 'string' && Object.keys(v).length === 2\n}\n\n/** `true` when `value` is a {@link MediaRef}. */\nexport const isMediaRef = (value: unknown): value is MediaRef => {\n if (!isObject(value)) return false\n const v = value as MediaRef\n if (v.kind === 'id') return typeof (v as { id?: unknown }).id === 'string'\n if (v.kind === 'builder') return isObject((v as { plan?: unknown }).plan)\n return false\n}\n\n// ── canonical rendering helpers ──────────────────────────────────────────────\n\n/** Characters legal in an unquoted bareword value. */\nconst BAREWORD = /^[A-Za-z0-9_]+$/\n/** Strings that would lex as a non-ident token and therefore must be quoted. */\nconst LEXES_AS_OTHER = /^(?:\\d+(?:-\\d+)?|\\d+\\.\\d+|true|false|@.*)$/\n\n/**\n * The frozen quoting predicate: quote any string that is empty, would lex as a number, range,\n * boolean, or `@id` token, starts with `/`, or contains a character outside `[A-Za-z0-9_]`.\n */\nconst renderString = (s: string): string => {\n if (s.length === 0 || !BAREWORD.test(s) || LEXES_AS_OTHER.test(s) || s.startsWith('/')) {\n return `\"${s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n')}\"`\n }\n return s\n}\n\n/** Canonicalize regex flags: validate against JS flags and sort. */\nexport const canonicalFlags = (flags: string): string => Array.from(flags).sort().join('')\n\n/** Render a {@link RegExpRef} back to a pipe regex literal, re-escaping bare slashes. */\nconst renderRegExp = (ref: RegExpRef): string => {\n const source = ref.source.length === 0 ? '(?:)' : ref.source\n // Escape bare `/` that are not already escaped and not inside a character class.\n let out = ''\n let inClass = false\n for (let i = 0; i < source.length; i++) {\n const ch = source[i]\n if (ch === '\\\\') {\n out += ch + (source[i + 1] ?? '')\n i++\n continue\n }\n if (ch === '[') inClass = true\n else if (ch === ']') inClass = false\n if (ch === '/' && !inClass) {\n out += '\\\\/'\n continue\n }\n out += ch\n }\n return `/${out}/${canonicalFlags(ref.flags)}`\n}\n\n/**\n * Compress maximal ascending consecutive runs in a number list to `a-b` range tokens.\n * Order-preserving and lossless on the array; never sorts or dedupes.\n */\nconst renderNumberList = (nums: number[]): string => {\n const parts: string[] = []\n let i = 0\n while (i < nums.length) {\n let j = i\n while (\n j + 1 < nums.length &&\n Number.isInteger(nums[j]) &&\n nums[j + 1] === (nums[j] as number) + 1\n ) {\n j++\n }\n if (j - i >= 1 && Number.isInteger(nums[i])) {\n parts.push(`${nums[i]}-${nums[j]}`)\n } else {\n parts.push(String(nums[i]))\n j = i\n }\n i = j + 1\n }\n return parts.join(',')\n}\n\nconst renderScalar = (value: MediaArgScalar): string => {\n if (typeof value === 'number') return String(value)\n if (typeof value === 'boolean') return String(value)\n if (typeof value === 'string') return renderString(value)\n if (isRegExpRef(value)) return renderRegExp(value)\n // MediaRef\n if (value.kind === 'id') return `@${value.id}`\n throw new E_MEDIA_NOT_PIPE_EXPRESSIBLE(['nested builder refs have no pipe form; use toOps()'])\n}\n\nconst isScalar = (value: MediaArgValue): value is MediaArgScalar =>\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean' ||\n isRegExpRef(value) ||\n isMediaRef(value)\n\nconst renderValue = (value: MediaArgValue): string => {\n if (value === null) {\n // null is only legal inside structured JSON values\n throw new E_MEDIA_NOT_PIPE_EXPRESSIBLE(['null is not a flat pipe value; use toOps()'])\n }\n if (Array.isArray(value)) {\n const arr = value as MediaArgScalar[]\n if (arr.length > 0 && arr.every((v) => typeof v === 'number')) {\n return renderNumberList(arr as number[])\n }\n if (arr.every(isScalar)) {\n return arr.map(renderScalar).join(',')\n }\n // structured (nested) array -> quoted JSON\n return `'${JSON.stringify(value)}'`\n }\n if (isScalar(value)) return renderScalar(value)\n // structured object -> quoted JSON\n return `'${JSON.stringify(value)}'`\n}\n\n/**\n * Render a {@link MediaPlan} to its canonical pipe string.\n *\n * @remarks\n * Total for every plan except those containing builder-variant media refs, which throw\n * {@link E_MEDIA_NOT_PIPE_EXPRESSIBLE}. Structured args render as quoted JSON. The output is\n * canonical: dot-namespaced verbs render as space-separated words, number runs compress to\n * ranges, strings quote per the frozen predicate.\n *\n * @param plan - The plan to render.\n * @returns The canonical pipe expression.\n */\nexport const toPipe = (plan: MediaPlan): string =>\n plan.steps\n .map((step) => {\n const verb = step.verb.replace(/\\./g, ' ')\n const args = Object.entries(step.args)\n .map(([k, v]) => `${k}=${renderValue(v)}`)\n .join(' ')\n return args.length > 0 ? `${verb} ${args}` : verb\n })\n .join(' | ')\n\n/**\n * Render a {@link MediaPlan} to its JSON ops array. Total — every plan has an ops form.\n *\n * @param plan - The plan to render.\n * @returns The ops array (spans stripped).\n */\nexport const toOps = (plan: MediaPlan): MediaOp[] =>\n plan.steps.map((step) => ({ verb: step.verb, args: step.args }))\n\n/**\n * Build a {@link MediaPlan} from a JSON ops array. The inverse of {@link toOps}.\n *\n * @remarks\n * Performs structural normalization only (verb-id folding via the caller's verb table happens\n * in validation, not here). Steps carry no spans.\n *\n * @param ops - The ops array.\n * @returns The equivalent plan.\n */\nexport const fromOps = (ops: MediaOp[]): MediaPlan => ({\n steps: ops.map((op) => ({ verb: op.verb, args: op.args })),\n})\n","/**\n * The canonical verb table: every verb the media DSL knows, with arg schemas, engine\n * requirements, format-family applicability, and output kinds.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. This table is the single source\n * of truth consumed by:\n *\n * - the pipe parser's semantic validator (unknown-verb/arg detection, did-you-mean),\n * - the plan compiler (arg coercion + constraint checks),\n * - the engine-narrowing pass (which verbs a deployment advertises),\n * - the forge (generating the `media_query` tool description and few-shot examples),\n * - the builder (typed front-end methods map 1:1 onto entries here).\n *\n * Frozen design decisions (design doc section 0): canonical verb ids are dot-namespaced\n * snake_case; verb matching is separator-insensitive (space/`_`/`.` fold); args are named-only;\n * indices are 1-based everywhere; arg names follow one-meaning-one-name (`to`, `with`, `match`,\n * `replace`, `order`, `pages`, `at`).\n */\n\nimport { PCM_MIME } from './contracts'\n\n/** The value type of a single declared arg. */\nexport type VerbArgType =\n | 'string'\n | 'number'\n | 'boolean'\n | 'enum'\n | 'number-list'\n | 'string-list'\n | 'regex-or-string-list'\n | 'name-or-index'\n | 'media-ref'\n | 'media-ref-list'\n | 'json'\n\n/** Declaration of one named arg on a verb. */\nexport interface VerbArgSpec {\n /** The arg's value type. */\n type: VerbArgType\n /** Whether the statement must supply this arg. */\n required?: boolean\n /** Legal values when `type === 'enum'` (or per-element for list types). */\n values?: readonly string[]\n /** Inclusive minimum for numbers / per-element for number lists. */\n min?: number\n /** Inclusive maximum for numbers / per-element for number lists. */\n max?: number\n /** Model-facing description used in generated tool grammar text. */\n description: string\n}\n\n/**\n * A verb's capability requirement against the deployment's engine registry. Verbs with no\n * requirement are always advertised; input-conditional engine needs (e.g. `extract.text`\n * needing OCR only for images) stay runtime checks inside the step implementation.\n */\nexport type VerbRequirement =\n | { capability: 'convert'; from?: string; to?: string }\n | { capability: 'mutate' }\n | { capability: 'edit'; op?: string }\n\n/** Broad input families used for verb-applicability checks. */\nexport type FormatFamily =\n | 'document' // pdf/docx/odt/rtf/txt/md/html...\n | 'spreadsheet' // xlsx/ods/xls/csv\n | 'presentation' // pptx/odp/ppt\n | 'image'\n | 'audio'\n | 'any'\n\n/** What awaiting a chain ending in this verb resolves to. */\nexport type VerbOutput = 'media' | 'media-list' | 'text' | 'json'\n\n/** One verb table entry. */\nexport interface VerbSpec {\n /** Canonical id: dot-namespaced snake_case (`extract.text`, `sheet.update_cells`). */\n id: string\n /** Model-facing one-line description. */\n description: string\n /** Named args (named-only grammar; no positionals). */\n args: Record<string, VerbArgSpec>\n /**\n * Capability the verb always requires, if any — gates whether the verb is advertised and\n * accepted under a given engine configuration. Input-conditional needs are handled (and\n * error-messaged) by the step implementation at runtime.\n */\n requires?: VerbRequirement\n /** Input families the verb applies to. */\n appliesTo: readonly FormatFamily[]\n /** Output kind. May be refined by an `out`-style arg (documented per verb). */\n output: VerbOutput\n}\n\n/** Conversion targets supported by `convert` (the server's enum plus the SheetJS/data matrix). */\nexport const CONVERT_TARGETS = [\n 'pdf',\n 'html',\n 'txt',\n 'md',\n 'csv',\n 'json',\n 'yaml',\n 'docx',\n 'doc',\n 'rtf',\n 'odt',\n 'xlsx',\n 'xls',\n 'ods',\n 'xlsm',\n 'xlsb',\n 'fods',\n 'sylk',\n 'dif',\n 'dbf',\n 'numbers',\n 'pptx',\n 'ppt',\n 'odp',\n] as const\n\n/** Image output formats supported by `image.format`. */\nexport const IMAGE_FORMATS = ['png', 'jpg', 'jpeg', 'webp', 'tiff', 'avif'] as const\n\n/** The canonical verb table. Order is presentation order in generated grammar text. */\nexport const VERBS: readonly VerbSpec[] = [\n // ── root: document transforms ──────────────────────────────────────────────\n {\n id: 'convert',\n description: 'Convert the media to another format.',\n args: {\n to: {\n type: 'enum',\n required: true,\n values: CONVERT_TARGETS,\n description: 'Target format.',\n },\n },\n requires: { capability: 'convert' },\n appliesTo: ['document', 'spreadsheet', 'presentation'],\n output: 'media',\n },\n {\n id: 'select',\n description: 'Keep only the listed pages/slides/sections (1-based), producing one file.',\n args: {\n pages: {\n type: 'number-list',\n required: true,\n min: 1,\n description: 'Pages (or slides/sections) to keep, 1-based. Ranges allowed: 2-5,8.',\n },\n },\n appliesTo: ['document', 'presentation'],\n output: 'media',\n },\n {\n id: 'split',\n description: 'Split the media into multiple files by page or section.',\n args: {\n by: {\n type: 'enum',\n values: ['page', 'section'],\n description: 'Split unit. Default: page.',\n },\n ranges: {\n type: 'json',\n description:\n \"Explicit grouping as a JSON array of [start,end] pairs (1-based), e.g. '[[1,3],[5,7]]'.\",\n },\n },\n appliesTo: ['document', 'presentation'],\n output: 'media-list',\n },\n {\n id: 'merge',\n description: 'Merge other media into this one, in order.',\n args: {\n with: {\n type: 'media-ref-list',\n required: true,\n description: 'Other media to append, as @id refs: with=@<media id>,@<media id>.',\n },\n },\n appliesTo: ['document', 'presentation'],\n output: 'media',\n },\n {\n id: 'reorder',\n description: 'Reorder pages/slides/sections by the given 1-based index order.',\n args: {\n order: {\n type: 'number-list',\n required: true,\n min: 1,\n description: 'New order of existing 1-based indices.',\n },\n },\n appliesTo: ['document', 'presentation'],\n output: 'media',\n },\n {\n id: 'redact',\n description:\n 'Redact matching text. Prefer literal strings; /regex/ is supported. PDF redaction is VISUAL (draw-over + metadata strip; content streams keep the text) — for content-level PDF redaction, extract text first.',\n args: {\n match: {\n type: 'regex-or-string-list',\n required: true,\n description: 'Literal string(s) or a /regex/ to redact.',\n },\n replace: {\n type: 'string',\n description:\n 'Replacement text. Omit for the blackout/removal default; send an empty string to blank the match out with nothing.',\n },\n },\n appliesTo: ['document', 'spreadsheet', 'presentation'],\n output: 'media',\n },\n {\n id: 'sanitize',\n description: 'Remove potentially unsafe embedded content from the media.',\n args: {},\n appliesTo: ['document', 'spreadsheet', 'presentation'],\n output: 'media',\n },\n {\n id: 'normalize',\n description: 'Normalize the media structure/encoding for downstream consistency.',\n args: {},\n appliesTo: ['document', 'spreadsheet', 'presentation'],\n output: 'media',\n },\n {\n id: 'update_text',\n description: 'Replace the first occurrence of an anchor text.',\n args: {\n anchor: {\n type: 'string',\n required: true,\n description: 'Existing text to find.',\n },\n replace: {\n type: 'string',\n required: true,\n description: 'Replacement text (empty string deletes).',\n },\n },\n appliesTo: ['document', 'presentation'],\n output: 'media',\n },\n {\n id: 'diff',\n description:\n 'Compare this media against another; returns a structured diff whose patch text feeds apply_patch directly.',\n args: {\n with: {\n type: 'media-ref',\n required: true,\n description: 'The media to compare against, as an @id ref.',\n },\n },\n appliesTo: ['document', 'spreadsheet', 'presentation'],\n output: 'json',\n },\n {\n id: 'apply_patch',\n description:\n 'Apply a patch to the media text: a unified diff (as produced by the diff verb — that output feeds this verb directly), or a structured \"*** Begin Patch\" envelope (Add/Delete/Update File) for multi-file changes. In the structured envelope, add-file content lines must start with \"+\" (the unified-diff convention).',\n args: {\n patch: {\n type: 'string',\n required: true,\n description:\n 'The patch content: unified diff, or a structured envelope starting with \"*** Begin Patch\". Add-file content lines must start with \"+\".',\n },\n with: {\n type: 'media-ref-list',\n description: 'Optional additional context media, as @id refs.',\n },\n },\n appliesTo: ['document'],\n output: 'media',\n },\n {\n id: 'append',\n description: 'Append text to text-family media (txt/md/csv/yaml).',\n args: {\n text: { type: 'string', required: true, description: 'The text to append.' },\n newline: {\n type: 'boolean',\n description: 'Terminate with a newline (and separate from existing content). Default true.',\n },\n },\n appliesTo: ['document', 'spreadsheet'],\n output: 'media',\n },\n // ── data namespace (JSON/YAML structural ops) ───────────────────────────────\n {\n id: 'data.set',\n description: 'Set a value at a path in JSON/YAML media (creates missing containers).',\n args: {\n path: {\n type: 'string',\n required: true,\n description: 'Dot/bracket path, e.g. a.b[2].c',\n },\n value: {\n type: 'string',\n required: true,\n description: \"JSON-encoded value: '42', '\\\"text\\\"', '{\\\"k\\\":1}'. Bare strings accepted.\",\n },\n },\n appliesTo: ['document'],\n output: 'media',\n },\n {\n id: 'data.merge',\n description: 'Merge a JSON object fragment into JSON/YAML media.',\n args: {\n fragment: {\n type: 'string',\n required: true,\n description: 'The JSON object to merge, e.g. \\'{\"a\":{\"b\":1}}\\'.',\n },\n strategy: {\n type: 'enum',\n values: ['deep', 'shallow'],\n description: 'Merge strategy. Default deep.',\n },\n },\n appliesTo: ['document'],\n output: 'media',\n },\n {\n id: 'data.delete',\n description: 'Delete a key or array element at a path in JSON/YAML media.',\n args: {\n path: {\n type: 'string',\n required: true,\n description: 'Dot/bracket path of the key/element to remove.',\n },\n },\n appliesTo: ['document'],\n output: 'media',\n },\n // ── root: extraction ────────────────────────────────────────────────────────\n {\n id: 'extract.text',\n description:\n 'Extract text from any supported media (document, spreadsheet, image). To limit pages: select pages=… | extract text.',\n args: {\n ocr: {\n type: 'enum',\n values: ['off', 'auto', 'force'],\n description: 'OCR behavior. Default auto (OCR only when there is no text layer).',\n },\n ocr_out: {\n type: 'enum',\n values: ['txt', 'hocr', 'json'],\n description: 'OCR output structure when OCR runs. Default txt.',\n },\n lang: {\n type: 'string-list',\n description: 'OCR language hint(s), e.g. lang=eng,deu. Quote tags with dashes.',\n },\n },\n appliesTo: ['document', 'spreadsheet', 'presentation', 'image'],\n output: 'text',\n },\n {\n id: 'extract.metadata',\n description: 'Extract document metadata (author, dates, page count) as JSON.',\n args: {},\n appliesTo: ['document', 'spreadsheet', 'presentation', 'image', 'audio'],\n output: 'json',\n },\n {\n id: 'extract.assets',\n description: 'Extract embedded assets (images, fonts, attachments) as separate media.',\n args: {\n types: {\n type: 'string-list',\n values: ['image', 'font', 'attachment', 'all'],\n description: 'Asset kinds to extract. Default all.',\n },\n format: {\n type: 'enum',\n values: IMAGE_FORMATS,\n description:\n 'Re-encode extracted images to this format. Default: native encoding as stored.',\n },\n },\n appliesTo: ['document', 'presentation', 'spreadsheet'],\n output: 'media-list',\n },\n {\n id: 'chunk',\n description: 'Split extracted text into chunks for retrieval/indexing.',\n args: {\n by: {\n type: 'enum',\n values: ['sentence', 'paragraph', 'fixed'],\n description: 'Chunking strategy. Default paragraph.',\n },\n size: {\n type: 'number',\n min: 1,\n description: 'Chunk size for fixed strategy / max size otherwise.',\n },\n overlap: {\n type: 'number',\n min: 0,\n description: 'Overlap between consecutive chunks.',\n },\n },\n appliesTo: ['document', 'any'],\n output: 'json',\n },\n // ── sheet namespace ─────────────────────────────────────────────────────────\n {\n id: 'sheet.add_rows',\n description: 'Insert rows into a worksheet.',\n args: {\n sheet: {\n type: 'name-or-index',\n description: 'Target worksheet: bare number = 1-based index, quoted string = name.',\n },\n rows: {\n type: 'json',\n required: true,\n description: 'Rows as a JSON array of arrays of cell values, e.g. \\'[[\"a\",1],[\"b\",2]]\\'.',\n },\n before: { type: 'number', min: 1, description: 'Insert before this 1-based row.' },\n after: { type: 'number', min: 1, description: 'Insert after this 1-based row.' },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.add_columns',\n description: 'Insert columns into a worksheet.',\n args: {\n sheet: { type: 'name-or-index', description: 'Target worksheet (index or quoted name).' },\n headers: {\n type: 'string-list',\n description: 'Header names for the new columns (values empty).',\n },\n columns: {\n type: 'json',\n description: 'Full column descriptors as JSON: \\'[{\"header\":\"X\",\"values\":[1,2]}]\\'.',\n },\n before: { type: 'number', min: 1, description: 'Insert before this 1-based column.' },\n after: { type: 'number', min: 1, description: 'Insert after this 1-based column.' },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.update_cells',\n description: 'Update specific cells.',\n args: {\n sheet: { type: 'name-or-index', description: 'Target worksheet (index or quoted name).' },\n updates: {\n type: 'json',\n required: true,\n description:\n 'JSON array of updates: \\'[{\"address\":\"B2\",\"value\":42}]\\' or \\'[{\"row\":2,\"col\":3,\"value\":\"x\"}]\\'.',\n },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.delete_rows',\n description: 'Delete rows by 1-based index.',\n args: {\n sheet: { type: 'name-or-index', description: 'Target worksheet (index or quoted name).' },\n rows: {\n type: 'number-list',\n required: true,\n min: 1,\n description: '1-based row indices to delete.',\n },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.delete_columns',\n description: 'Delete columns by 1-based index.',\n args: {\n sheet: { type: 'name-or-index', description: 'Target worksheet (index or quoted name).' },\n columns: {\n type: 'number-list',\n required: true,\n min: 1,\n description: '1-based column indices to delete.',\n },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.rename_sheet',\n description: 'Rename a worksheet. The target must be a sheet NAME (quote it).',\n args: {\n sheet: {\n type: 'string',\n required: true,\n description: 'Current sheet name (names only for rename; quote it).',\n },\n to: { type: 'string', required: true, description: 'New sheet name.' },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.add_sheet',\n description: 'Add a new worksheet.',\n args: {\n name: { type: 'string', required: true, description: 'Name for the new worksheet.' },\n at: { type: 'number', min: 1, description: 'Insert at this 1-based position.' },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.remove_sheet',\n description: 'Remove a worksheet. The target must be a sheet NAME (quote it).',\n args: {\n sheet: {\n type: 'string',\n required: true,\n description: 'Sheet name to remove (names only; quote it).',\n },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.reorder_sheets',\n description: 'Reorder worksheets.',\n args: {\n order: {\n type: 'json',\n required: true,\n description:\n 'JSON array of sheet names and/or 1-based indices in the new order: \\'[\"Summary\",2,3]\\'.',\n },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n {\n id: 'sheet.transform_table',\n description: 'Rename/select/drop table columns by header name.',\n args: {\n sheet: { type: 'name-or-index', description: 'Target worksheet (index or quoted name).' },\n header_row: { type: 'number', min: 1, description: '1-based header row. Default 1.' },\n select: { type: 'string-list', description: 'Column headers to keep.' },\n drop: { type: 'string-list', description: 'Column headers to drop.' },\n rename: {\n type: 'json',\n description: 'JSON array of renames: \\'[{\"from\":\"Old\",\"to\":\"New\"}]\\'.',\n },\n },\n requires: { capability: 'edit' },\n appliesTo: ['spreadsheet'],\n output: 'media',\n },\n // ── slides namespace ────────────────────────────────────────────────────────\n {\n id: 'slides.add',\n description: 'Add a new slide.',\n args: {\n at: { type: 'number', min: 1, description: 'Insert at this 1-based position.' },\n title: { type: 'string', description: 'Title text for the new slide.' },\n layout: { type: 'string', description: 'Layout name (template-dependent).' },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n {\n id: 'slides.update_text',\n description: 'Update text on a slide.',\n args: {\n slide: {\n type: 'name-or-index',\n description: 'Target slide: bare number = 1-based index, quoted string = title.',\n },\n placeholder: { type: 'string', description: 'Placeholder/shape to target.' },\n text: { type: 'string', required: true, description: 'Replacement text.' },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n {\n id: 'slides.update_table',\n description: 'Update table cells on a slide.',\n args: {\n slide: { type: 'name-or-index', description: 'Target slide (index or quoted title).' },\n updates: {\n type: 'json',\n required: true,\n description: 'JSON array: \\'[{\"row\":1,\"col\":2,\"value\":\"x\"}]\\' (1-based).',\n },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n {\n id: 'slides.update_image',\n description: 'Replace an image on a slide with another media.',\n args: {\n slide: { type: 'name-or-index', description: 'Target slide (index or quoted title).' },\n placeholder: { type: 'string', description: 'Placeholder/shape to target.' },\n with: {\n type: 'media-ref',\n required: true,\n description: 'The replacement image, as an @id ref.',\n },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n {\n id: 'slides.update_chart',\n description: 'Update chart data on a slide.',\n args: {\n slide: { type: 'name-or-index', description: 'Target slide (index or quoted title).' },\n data: {\n type: 'json',\n description: 'JSON array-of-arrays of chart data: \\'[[\"Q1\",10],[\"Q2\",20]]\\'.',\n },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n {\n id: 'slides.delete',\n description: 'Delete slides by 1-based index.',\n args: {\n slides: {\n type: 'number-list',\n required: true,\n min: 1,\n description: '1-based slide indices to delete.',\n },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n {\n id: 'slides.reorder',\n description: 'Reorder slides.',\n args: {\n order: {\n type: 'number-list',\n required: true,\n min: 1,\n description: 'New order of existing 1-based slide indices.',\n },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n {\n id: 'slides.duplicate',\n description: 'Duplicate a slide.',\n args: {\n slide: { type: 'number', required: true, min: 1, description: '1-based slide to copy.' },\n at: { type: 'number', min: 1, description: 'Insert the copy at this position.' },\n },\n appliesTo: ['presentation'],\n output: 'media',\n },\n // ── image namespace (split verbs; runtime fuses adjacent image.* steps) ─────\n {\n id: 'image.resize',\n description: 'Resize the image.',\n args: {\n width: { type: 'number', min: 1, max: 16384, description: 'Target width in px.' },\n height: { type: 'number', min: 1, max: 16384, description: 'Target height in px.' },\n fit: {\n type: 'enum',\n values: ['cover', 'contain', 'fill', 'inside', 'outside'],\n description: 'Resize fit mode. Default cover.',\n },\n },\n requires: { capability: 'mutate' },\n appliesTo: ['image'],\n output: 'media',\n },\n {\n id: 'image.format',\n description: 'Re-encode the image to another format.',\n args: {\n to: {\n type: 'enum',\n required: true,\n values: IMAGE_FORMATS,\n description: 'Target image format.',\n },\n quality: { type: 'number', min: 1, max: 100, description: 'Quality for lossy formats.' },\n strip_metadata: {\n type: 'boolean',\n description: 'Remove EXIF/ICC metadata from the output.',\n },\n },\n requires: { capability: 'mutate' },\n appliesTo: ['image'],\n output: 'media',\n },\n {\n id: 'image.rotate',\n description: 'Rotate the image.',\n args: {\n deg: {\n type: 'enum',\n required: true,\n values: ['90', '180', '270'],\n description: 'Rotation in degrees (clockwise).',\n },\n },\n requires: { capability: 'mutate' },\n appliesTo: ['image'],\n output: 'media',\n },\n {\n id: 'image.flip',\n description: 'Flip the image.',\n args: {\n axis: {\n type: 'enum',\n required: true,\n values: ['horizontal', 'vertical', 'both'],\n description: 'Flip axis.',\n },\n },\n requires: { capability: 'mutate' },\n appliesTo: ['image'],\n output: 'media',\n },\n {\n id: 'image.strip_metadata',\n description: 'Remove EXIF/ICC metadata from the image without other changes.',\n args: {},\n requires: { capability: 'mutate' },\n appliesTo: ['image'],\n output: 'media',\n },\n {\n id: 'image.annotate',\n description: 'Draw vector shapes and text over the image.',\n args: {\n shapes: {\n type: 'json',\n required: true,\n description: 'Array of rect, line, arrow, ellipse, or text primitives.',\n },\n },\n requires: { capability: 'mutate' },\n appliesTo: ['image'],\n output: 'media',\n },\n // ── audio namespace ─────────────────────────────────────────────────────────\n {\n id: 'audio.transcribe',\n description: 'Transcribe speech to text.',\n args: {\n lang: {\n type: 'string',\n description: 'Language hint, e.g. lang=en. Quote tags with dashes: lang=\"en-US\".',\n },\n out: {\n type: 'enum',\n values: ['txt', 'srt', 'vtt', 'json'],\n description: 'Output format. Default txt. srt/vtt produce subtitles.',\n },\n translate: {\n type: 'boolean',\n description: 'Translate the transcription to English.',\n },\n },\n requires: { capability: 'convert', from: PCM_MIME },\n appliesTo: ['audio'],\n output: 'text',\n },\n] as const\n\n/** Map of canonical verb id → spec, for direct lookup. */\nexport const VERB_INDEX: ReadonlyMap<string, VerbSpec> = new Map(VERBS.map((v) => [v.id, v]))\n\n/**\n * Fold a verb token sequence to canonical form: lowercase, separators (space/`_`/`.`)\n * normalized so `extract_text` ≡ `extract text` ≡ `extract.text` all match `extract.text`.\n *\n * @param words - The verb word tokens as written (1 or 2 words, possibly containing `_`/`.`).\n * @returns The canonical verb id when a fold-match exists, otherwise `undefined`.\n */\nexport const foldVerb = (words: string[]): string | undefined => {\n const flat = words\n .join(' ')\n .toLowerCase()\n .replace(/[._\\s]+/g, ' ')\n .trim()\n return FOLDED_INDEX.get(flat)\n}\n\n/** Internal: folded \"word word\" form → canonical id. */\nconst FOLDED_INDEX: ReadonlyMap<string, string> = (() => {\n const map = new Map<string, string>()\n for (const v of VERBS) {\n const folded = v.id.replace(/[._]+/g, ' ')\n if (map.has(folded)) {\n throw new Error(`verb table invariant violated: \"${folded}\" folds to multiple verbs`)\n }\n map.set(folded, v.id)\n }\n return map\n})()\n\n/**\n * All folded verb word-sequences, for the parser's longest-match verb recognition and for\n * generated grammar text.\n */\nexport const FOLDED_VERBS: readonly string[] = Array.from(FOLDED_INDEX.keys())\n\n/**\n * Suggest the nearest verbs to an unknown input, for did-you-mean errors. Matches whole folded\n * forms AND suffix words (`resize` suggests `image resize`), per the frozen error model.\n *\n * @param input - The unknown verb text as written.\n * @param candidates - The folded verb forms to search (pass the narrowed set to avoid\n * suggesting unconfigured verbs).\n * @returns Up to three suggestions, best first.\n */\nexport const suggestVerbs = (input: string, candidates: readonly string[]): string[] => {\n const folded = input\n .toLowerCase()\n .replace(/[._\\s]+/g, ' ')\n .trim()\n const scored: Array<{ name: string; score: number }> = []\n for (const cand of candidates) {\n const direct = levenshtein(folded, cand)\n const words = cand.split(' ')\n const suffix = words.length > 1 ? levenshtein(folded, words[words.length - 1]) : Infinity\n const score = Math.min(direct, suffix)\n if (score <= Math.max(2, Math.floor(folded.length / 3))) {\n scored.push({ name: cand, score })\n }\n }\n scored.sort((a, b) => a.score - b.score)\n return scored.slice(0, 3).map((s) => s.name)\n}\n\n/** Classic two-row Levenshtein distance. */\nconst levenshtein = (a: string, b: string): number => {\n if (a === b) return 0\n if (a.length === 0) return b.length\n if (b.length === 0) return a.length\n let prev = Array.from({ length: b.length + 1 }, (_, i) => i)\n let curr = new Array<number>(b.length + 1)\n for (let i = 1; i <= a.length; i++) {\n curr[0] = i\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1\n curr[j] = Math.min(prev[j] + 1, curr[j - 1] + 1, prev[j - 1] + cost)\n }\n ;[prev, curr] = [curr, prev]\n }\n return prev[b.length]\n}\n","/**\n * The semantic validator: checks raw parsed segments (or ops) against the verb table and the\n * deployment's configured engines, producing the validated {@link MediaPlan} or a\n * model-actionable error.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. This is the layer no parser\n * toolkit could supply — every error names what was wrong, suggests the nearest valid form,\n * and shows a corrective exemplar (frozen design 0.14). Engine narrowing happens HERE, never\n * at parse time (frozen 0.3): the same string parses identically in every deployment; only\n * validation differs.\n */\n\nimport { isMediaRef, isRegExpRef } from './plan'\nimport { isError, isObject } from '@nhtio/adk/guards'\nimport { VERB_INDEX, suggestVerbs, foldVerb } from './verbs'\nimport {\n E_MEDIA_UNKNOWN_VERB,\n E_MEDIA_UNKNOWN_ARG,\n E_MEDIA_BAD_ARG,\n E_MEDIA_MISSING_ARG,\n E_MEDIA_ENGINE_REQUIRED,\n} from './exceptions'\nimport type { RawSegment, RawArgValue } from './pipe'\nimport type { VerbSpec, VerbArgSpec, VerbRequirement } from './verbs'\nimport type { MediaPlan, MediaStep, MediaArgValue, MediaArgScalar, MediaOp } from './plan'\n\n/**\n * The minimal synchronous capability probe the validator narrows against. The pipeline's\n * engine registry implements it; tests stub it.\n */\nexport interface CapabilityProbe {\n /** `true` when some engine declares a matching convert edge (omit either side for \"any\"). */\n hasConvert(from?: string, to?: string): boolean\n /** `true` when some engine declares a mutate capability. */\n hasMutate(): boolean\n /**\n * `true` when some engine declares a matching edit capability (omit both for \"any\").\n * Optional so existing probe stubs stay valid; absent means \"no edit engines\".\n */\n hasEdit?(mime?: string, op?: string): boolean\n}\n\n/** Options for {@link validateSegments} / {@link validateOps}. */\nexport interface ValidateOptions {\n /** The deployment's capabilities. Narrows advertised verbs + error suggestions. */\n capabilities: CapabilityProbe\n}\n\n/** `true` when the deployment satisfies a verb's capability requirement. */\nconst satisfies = (capabilities: CapabilityProbe, requires: VerbRequirement): boolean => {\n if (requires.capability === 'mutate') return capabilities.hasMutate()\n if (requires.capability === 'edit') return capabilities.hasEdit?.(undefined, requires.op) ?? false\n return capabilities.hasConvert(requires.from, requires.to)\n}\n\n/** A human phrase for an unmet requirement, for the do-not-retry error. */\nconst requirementText = (requires: VerbRequirement): string => {\n if (requires.capability === 'mutate') return 'an engine that can mutate this media'\n if (requires.capability === 'edit') {\n return `an engine that can edit this media${requires.op ? ` (op \"${requires.op}\")` : ''}`\n }\n const from = requires.from ? ` from ${requires.from}` : ''\n const to = requires.to ? ` to ${requires.to}` : ''\n return `an engine that can convert${from}${to}`\n}\n\n/** The folded verb forms available under a given capability configuration. */\nexport const availableVerbs = (capabilities: CapabilityProbe): string[] => {\n const out: string[] = []\n for (const [id, spec] of VERB_INDEX) {\n if (spec.requires && !satisfies(capabilities, spec.requires)) continue\n out.push(id.replace(/[._]+/g, ' '))\n }\n return out\n}\n\nconst levSuggest = (verbText: string, capabilities: CapabilityProbe): string => {\n const suggestions = suggestVerbs(verbText, availableVerbs(capabilities))\n return suggestions.length > 0 ? ` did you mean \"${suggestions[0]}\"?` : ''\n}\n\nconst verbList = (capabilities: CapabilityProbe): string => availableVerbs(capabilities).join(', ')\n\nconst resolveVerb = (\n verbText: string,\n capabilities: CapabilityProbe,\n position: number\n): VerbSpec => {\n const canonical = foldVerb(verbText.split(' ')) ?? verbText\n const spec = VERB_INDEX.get(canonical)\n if (!spec) {\n throw new E_MEDIA_UNKNOWN_VERB([\n `unknown verb \"${verbText}\" at segment ${position}.${levSuggest(verbText, capabilities)} Available verbs: ${verbList(capabilities)}`,\n ])\n }\n if (spec.requires && !satisfies(capabilities, spec.requires)) {\n throw new E_MEDIA_ENGINE_REQUIRED([\n `verb \"${verbText}\" requires ${requirementText(spec.requires)}, and none is configured in this deployment. Do not retry this verb here. Available verbs: ${verbList(capabilities)}`,\n ])\n }\n return spec\n}\n\nconst suggestArg = (name: string, spec: VerbSpec): string => {\n const candidates = Object.keys(spec.args)\n const ranked = suggestVerbs(name, candidates)\n return ranked.length > 0 ? ` did you mean \"${ranked[0]}\"?` : ''\n}\n\nconst argList = (spec: VerbSpec): string => {\n const names = Object.keys(spec.args)\n return names.length > 0 ? names.join(', ') : '(none)'\n}\n\nconst exemplar = (spec: VerbSpec): string => {\n const verb = spec.id.replace(/\\./g, ' ')\n const parts: string[] = [verb]\n for (const [name, arg] of Object.entries(spec.args)) {\n if (!arg.required) continue\n parts.push(`${name}=${exampleValue(arg)}`)\n }\n return parts.join(' ')\n}\n\nconst exampleValue = (arg: VerbArgSpec): string => {\n switch (arg.type) {\n case 'enum':\n return arg.values?.[0] ?? 'value'\n case 'number':\n return String(arg.min ?? 1)\n case 'number-list':\n return '1-3,5'\n case 'string-list':\n return 'a,b'\n case 'boolean':\n return 'true'\n case 'regex-or-string-list':\n return '\"literal text\"'\n case 'media-ref':\n return '@<media id>'\n case 'media-ref-list':\n return '@<media id>'\n case 'json':\n return `'[…]'`\n default:\n return '\"value\"'\n }\n}\n\n/** Coerce + check one arg value against its spec. Returns the IR-final value. */\nconst checkArg = (\n verb: VerbSpec,\n name: string,\n raw: { value: MediaArgValue; quoted: boolean }\n): MediaArgValue => {\n const spec = verb.args[name]\n const verbText = verb.id.replace(/\\./g, ' ')\n const where = `arg \"${name}\" on \"${verbText}\"`\n const bad = (msg: string): never => {\n throw new E_MEDIA_BAD_ARG([`${where}: ${msg}. Write it like: ${exemplar(verb)}`])\n }\n const v = raw.value\n switch (spec.type) {\n case 'name-or-index': {\n if (typeof v === 'number') {\n if (!Number.isInteger(v) || v < 1) bad('indices are 1-based integers')\n return v\n }\n if (typeof v !== 'string') bad('expected a 1-based index or a quoted name')\n return v\n }\n case 'string': {\n if (typeof v === 'number' && !raw.quoted) return String(v)\n if (typeof v !== 'string')\n bad(`expected text${typeof v === 'object' ? ', got a structured value' : ''}`)\n return v\n }\n case 'number': {\n if (typeof v !== 'number') bad('expected a number')\n const n = v as number\n if (spec.min !== undefined && n < spec.min) bad(`must be ≥ ${spec.min} (indices are 1-based)`)\n if (spec.max !== undefined && n > spec.max) bad(`must be ≤ ${spec.max}`)\n return n\n }\n case 'boolean': {\n if (typeof v !== 'boolean') bad('expected true or false')\n return v\n }\n case 'enum': {\n const s = typeof v === 'number' ? String(v) : v\n if (typeof s !== 'string' || !spec.values?.includes(s)) {\n bad(`\"${String(v)}\" is not valid; valid values: ${spec.values?.join(', ')}`)\n }\n return s as string\n }\n case 'number-list': {\n const arr = Array.isArray(v) ? v : [v]\n if (!arr.every((x): x is number => typeof x === 'number'))\n bad('expected numbers (e.g. 1-3,5)')\n const nums = arr as number[]\n if (spec.min !== undefined && nums.some((n) => n < (spec.min as number))) {\n bad(`values must be ≥ ${spec.min} (indices are 1-based)`)\n }\n return nums\n }\n case 'string-list': {\n const arr = Array.isArray(v) ? v : [v]\n if (!arr.every((x): x is string => typeof x === 'string'))\n bad('expected names (quote values with special characters)')\n const strs = arr as string[]\n if (spec.values && !strs.every((s) => spec.values?.includes(s))) {\n bad(`valid values: ${spec.values.join(', ')}`)\n }\n return strs\n }\n case 'regex-or-string-list': {\n if (isRegExpRef(v)) return v\n const arr = Array.isArray(v) ? v : [v]\n if (arr.every((x) => typeof x === 'string' || isRegExpRef(x))) return arr as MediaArgScalar[]\n bad('expected literal text, a list of literals, or a /regex/')\n break\n }\n case 'media-ref': {\n if (isMediaRef(v)) return v\n bad('expected a media reference: with=@<media id> (get ids from list_media)')\n break\n }\n case 'media-ref-list': {\n const arr = Array.isArray(v) ? v : [v]\n if (arr.every(isMediaRef)) return arr as MediaArgScalar[]\n bad('expected media references: with=@<id>,@<id> (get ids from list_media)')\n break\n }\n case 'json': {\n // From pipe: a quoted string containing JSON. From ops: already-structured JSON.\n if (typeof v === 'string') {\n if (!raw.quoted) bad(`expected a quoted JSON value, e.g. ${name}='[…]'`)\n try {\n return JSON.parse(v) as MediaArgValue\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n bad(`the quoted value is not valid JSON (${detail})`)\n }\n }\n if (isObject(v) || Array.isArray(v)) return v\n bad(`expected a JSON value, e.g. ${name}='[…]'`)\n break\n }\n }\n /* unreachable */\n throw new E_MEDIA_BAD_ARG([`${where}: invalid value`])\n}\n\nconst checkStep = (\n spec: VerbSpec,\n args: ReadonlyMap<string, { value: MediaArgValue; quoted: boolean }>\n): MediaStep => {\n const verbText = spec.id.replace(/\\./g, ' ')\n const finalArgs: Record<string, MediaArgValue> = {}\n for (const [name, raw] of args) {\n if (!(name in spec.args)) {\n throw new E_MEDIA_UNKNOWN_ARG([\n `verb \"${verbText}\" has no arg \"${name}\".${suggestArg(name, spec)} Args: ${argList(spec)}. Write it like: ${exemplar(spec)}`,\n ])\n }\n finalArgs[name] = checkArg(spec, name, raw)\n }\n for (const [name, argSpec] of Object.entries(spec.args)) {\n if (argSpec.required && !(name in finalArgs)) {\n throw new E_MEDIA_MISSING_ARG([\n `verb \"${verbText}\" requires arg \"${name}\" (${argSpec.description}). Write it like: ${exemplar(spec)}`,\n ])\n }\n }\n return { verb: spec.id, args: finalArgs }\n}\n\n/**\n * Validate raw pipe segments into a {@link MediaPlan}.\n *\n * @param segments - Output of `parsePipeRaw`.\n * @param options - The deployment's capability probe.\n * @returns The validated plan, spans preserved.\n */\nexport const validateSegments = (\n segments: readonly RawSegment[],\n options: ValidateOptions\n): MediaPlan => {\n const steps: MediaStep[] = []\n segments.forEach((seg, i) => {\n const spec = resolveVerb(seg.verb.replace(/\\./g, ' '), options.capabilities, i + 1)\n const step = checkStep(spec, seg.args)\n step.span = seg.span\n steps.push(step)\n })\n return { steps }\n}\n\n/**\n * Validate a JSON ops array into a {@link MediaPlan}. The same checks as the pipe path —\n * verbs fold the same way, args validate against the same specs — so the two front-ends\n * produce identical plans for equivalent statements.\n *\n * @param ops - The ops array.\n * @param options - The deployment's capability probe.\n * @returns The validated plan (no spans).\n */\nexport const validateOps = (ops: readonly MediaOp[], options: ValidateOptions): MediaPlan => {\n const steps: MediaStep[] = []\n ops.forEach((op, i) => {\n const spec = resolveVerb(op.verb.replace(/[._]+/g, ' '), options.capabilities, i + 1)\n const args = new Map<string, RawArgValue>(\n Object.entries(op.args).map(([k, v]) => [\n k,\n {\n value: v,\n quoted: typeof v === 'string',\n span: { offset: 0, line: 1, col: 1, length: 0 },\n },\n ])\n )\n steps.push(checkStep(spec, args))\n })\n return { steps }\n}\n"],"mappings":"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"}
@@ -1,13 +1,13 @@
1
1
  const require_exceptions = require("./exceptions-DrHnAGQz.js");
2
2
  const require_guards = require("./guards-05Uq3J4M.js");
3
- const require_spooled_artifact = require("./spooled_artifact-DriNQRj7.js");
3
+ const require_spooled_artifact = require("./spooled_artifact-BpcesRBv.js");
4
+ require("./common-H44Ik9ou.js");
5
+ const require_spooled_markdown_artifact = require("./spooled_markdown_artifact-wJPnE8Ij.js");
4
6
  require("./factories.cjs");
5
- require("./common-BV3HGeLj.js");
6
- const require_spooled_markdown_artifact = require("./spooled_markdown_artifact-C_VkCDhF.js");
7
7
  require("./guards.cjs");
8
8
  require("./spooled_artifact.cjs");
9
- let uuid = require("uuid");
10
9
  let _nhtio_validation = require("@nhtio/validation");
10
+ let uuid = require("uuid");
11
11
  let jsonpath_plus = require("jsonpath-plus");
12
12
  //#region src/batteries/artifacts/xml/exceptions.ts
13
13
  /**
@@ -584,4 +584,4 @@ Object.defineProperty(exports, "xmlToJsonTool", {
584
584
  }
585
585
  });
586
586
 
587
- //# sourceMappingURL=xml-DDTIMpY3.js.map
587
+ //# sourceMappingURL=xml-BeNvlifb.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"xml-DDTIMpY3.js","names":["#attributeNamePrefix","#ignoreAttributes","#resolveParsed","#parsed"],"sources":["../src/batteries/artifacts/xml/exceptions.ts","../src/batteries/artifacts/xml/index.ts"],"sourcesContent":["/**\n * Battery-scoped exceptions for the XML artifact battery.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/artifacts/xml` entry — re-exported from the battery's\n * 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 fast-xml-parser optional peer is not installed or fails to load.\n *\n * @remarks\n * The message template includes the package name, a description of its purpose, the underlying\n * error, and the exact install command, so the consumer sees a complete, actionable message\n * regardless of call site.\n */\nexport const E_XML_PARSER_PEER_MISSING = createException<[string]>(\n 'E_XML_PARSER_PEER_MISSING',\n 'the XML battery could not load its peer dependency \"fast-xml-parser\" (needed for XML format artifact queries): %s — install it (pnpm add fast-xml-parser)',\n 'E_XML_PARSER_PEER_MISSING',\n 500,\n true\n)\n\n/**\n * Thrown when XML parsing fails due to malformed markup.\n *\n * @remarks\n * Printf args: `[errorDetail]` — includes the parser's own reason for the failure.\n */\nexport const E_XML_PARSE_FAILED = createException<[string]>(\n 'E_XML_PARSE_FAILED',\n 'XML parse failed: %s',\n 'E_XML_PARSE_FAILED',\n 422,\n false\n)\n","/**\n * A structured artifact battery for XML documents.\n *\n * @module @nhtio/adk/batteries/artifacts/xml\n *\n * @remarks\n * Provides {@link SpooledXmlArtifact} — a `SpooledArtifact` specialisation that parses XML\n * into a JSON projection and offers path-based query tools over that projection. The XML-to-JSON\n * mapping defaults to `ignoreAttributes: false` and `attributeNamePrefix: '_'`, both settable\n * per instance through the constructor; `preserveOrder: false` is fixed. Under the default\n * mapping:\n *\n * - Element attributes become keys prefixed with `_` (e.g., `root-element` with `href=\"x\"`\n * becomes `{ a: { _href: 'x', ... } }`).\n * - Element text content becomes a `#text` key when the element also has attributes or siblings.\n * - Repeated sibling elements collapse into an array.\n * - The full projection is queryable via JSONPath expressions (e.g., `$..name` finds all name\n * elements anywhere in the tree). Attributes are accessed via underscore-prefixed keys,\n * e.g. `$..[\"_href\"]` for the href attribute (recursive descent).\n *\n * The battery also exports two converter `Tool` constants: `xmlToJsonTool` and `jsonToXmlTool`.\n * These accept either inline XML/JSON text or a reference to an artifact produced earlier in\n * the turn, and return the converted result as a new `SpooledJsonArtifact` or\n * `SpooledXmlArtifact`.\n *\n * Battery exceptions are defined in this module's `exceptions.ts` file — `createException`\n * re-exported from `@nhtio/adk/factories`. Decoding a {@link SpooledXmlArtifact} instance via\n * `decode()` throws until `registerArtifactEncodables()` has run (see\n * {@link @nhtio/adk/batteries/artifacts!registerArtifactEncodables}).\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 { SpooledJsonArtifact } from '@nhtio/adk/common'\nimport { isInstanceOf, isError, isObject } from '@nhtio/adk/guards'\nimport { E_XML_PARSER_PEER_MISSING, E_XML_PARSE_FAILED } from './exceptions'\nimport { ArtifactTool, Tool, ToolRegistry, ReaderDescriptor } 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')\nimport {\n SpooledArtifact,\n collectArtifactCompatibleIds,\n resolveArtifactById,\n defaultSerialise,\n} from '@nhtio/adk/spooled_artifact'\nimport type { SpoolReader } from '@nhtio/adk/types'\nimport type { XMLParser, XMLBuilder } from 'fast-xml-parser'\nimport type { 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 * Lazy-loaded promise for the `fast-xml-parser` module, cached at module scope.\n */\nlet xmlParserPromise:\n | Promise<{ XMLParser: typeof XMLParser; XMLBuilder: typeof XMLBuilder }>\n | undefined\n\n/**\n * Lazily import and cache the `fast-xml-parser` module with battery-scoped error handling.\n *\n * @returns The imported module.\n * @throws {@link E_XML_PARSER_PEER_MISSING} when the module is unavailable.\n */\nasync function getXmlParser(): Promise<{\n XMLParser: typeof XMLParser\n XMLBuilder: typeof XMLBuilder\n}> {\n xmlParserPromise ??= import('fast-xml-parser').catch((err) => {\n const detail = isError(err) ? err.message : String(err)\n throw new E_XML_PARSER_PEER_MISSING([detail])\n })\n return xmlParserPromise\n}\n\n/**\n * A {@link @nhtio/adk!SpooledArtifact} specialisation that adds XML-aware read operations.\n *\n * @remarks\n * The artifact parses XML into a JSON projection on first access and caches it for the\n * lifetime of the instance. The projection uses `ignoreAttributes` and `attributeNamePrefix` as\n * supplied to the constructor — defaulting to `false` and `'_'` — with `preserveOrder: false`.\n *\n * Under this mapping, an XML element like:\n *\n * `root-element` with an `href` attribute and text content becomes a JSON object like:\n * `{ root: { element: { _href: 'value', '#text': 'content' } } }`\n *\n * Attributes are prefixed with `_` by default rather than the conventional `@_`, because\n * `jsonpath-plus` reads a leading `@` in a path segment as its type-selector sigil before\n * honouring quotes: `$..[\"@_href\"]` throws `Unknown value type _hr`, while `$..[\"_href\"]`\n * matches. Text nodes use the `#text` key.\n *\n * All XML methods are async, consistent with {@link @nhtio/adk!SpooledArtifact}.\n *\n * Path-based methods (`xml_get`, `xml_filter`, `xml_pluck`) use\n * [JSONPath-Plus](https://github.com/JSONPath-Plus/JSONPath) expressions over the projection.\n * Full JSONPath syntax is supported, including recursive descent (`..`), filter expressions,\n * and union selectors.\n */\nexport class SpooledXmlArtifact extends SpooledArtifact {\n #parsed: Record<string, unknown> | undefined\n #attributeNamePrefix: string\n #ignoreAttributes: boolean\n\n /**\n * @param reader - The backing store to read from.\n * @param options - Optional parser configuration.\n * @param options.attributeNamePrefix - Prefix for attribute keys (default: '_'). Set to '@_'\n * if you need the conventional XML-to-JSON mapping, but be aware that naming such a key in a\n * JSONPath segment fails — `$..[\"@_attr\"]` throws `Unknown value type _at`, and quoting does\n * not escape it. A filter expression still reaches it (`$..[?(@['@_attr'])]`); a wildcard\n * does too, but only when placed exactly one level above the key, so the working path\n * depends on whether repeated elements collapsed into an array.\n * @param options.ignoreAttributes - When true, ignore element attributes (default: false).\n */\n constructor(\n reader: SpoolReader,\n options?: {\n attributeNamePrefix?: string\n ignoreAttributes?: boolean\n }\n ) {\n super(reader)\n this.#attributeNamePrefix = options?.attributeNamePrefix ?? '_'\n this.#ignoreAttributes = options?.ignoreAttributes ?? false\n }\n\n /**\n * Returns `true` if `value` is a {@link SpooledXmlArtifact} instance.\n *\n * @remarks\n * Uses the cross-realm-safe {@link @nhtio/adk!isInstanceOf} guard. Safe against the\n * dual-module-copy case where two distinct `SpooledXmlArtifact` classes coexist in the same\n * realm.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link SpooledXmlArtifact} instance.\n */\n public static isSpooledXmlArtifact(value: unknown): value is SpooledXmlArtifact {\n return isInstanceOf(value, 'SpooledXmlArtifact', SpooledXmlArtifact)\n }\n\n /**\n * Returns the effective XML-to-JSON parser configuration for this artifact.\n *\n * @remarks\n * When converting an XML artifact to JSON by call_id, the converter inherits the source\n * artifact's attribute prefix and ignoreAttributes setting. This accessor exposes those\n * options so the converter can apply them consistently.\n *\n * @returns An object with `attributeNamePrefix` and `ignoreAttributes` keys.\n */\n public getParserOptions(): {\n attributeNamePrefix: string\n ignoreAttributes: boolean\n } {\n return {\n attributeNamePrefix: this.#attributeNamePrefix,\n ignoreAttributes: this.#ignoreAttributes,\n }\n }\n\n /**\n * The XML-specific artifact-query descriptors this class adds on top of the base set.\n *\n * @remarks\n * Lists `artifact_xml_root`, `artifact_xml_keys`, `artifact_xml_tags`, `artifact_xml_length`,\n * `artifact_xml_get`, `artifact_xml_filter`, `artifact_xml_pluck`. The base seven descriptors\n * (`artifact_head`, etc.) are NOT included here — they are forged separately by\n * {@link SpooledXmlArtifact.forgeTools}.\n */\n public static toolMethods: ReadonlyArray<ToolMethodDescriptor> = Object.freeze([\n {\n name: 'artifact_xml_root',\n method: 'xml_root',\n description: 'The root element name of the XML document produced earlier in this turn.',\n },\n {\n name: 'artifact_xml_keys',\n method: 'xml_keys',\n description:\n 'Keys directly under the root element of the XML document produced earlier in this turn.',\n },\n {\n name: 'artifact_xml_tags',\n method: 'xml_tags',\n description:\n 'Every distinct element name in the XML document produced earlier in this turn, deduplicated. ' +\n 'Call this before writing a path to an unfamiliar document — it tells you what elements are present.',\n },\n {\n name: 'artifact_xml_length',\n method: 'xml_length',\n description:\n 'Element count when the root element contains an array of children; otherwise 1. ' +\n 'The XML document was produced earlier in this turn.',\n },\n {\n name: 'artifact_xml_get',\n method: 'xml_get',\n argsSchema: validator.object({\n path: validator\n .string()\n .required()\n .description(\n 'JSONPath expression to query the document. Attributes appear with a leading underscore (e.g., _href). Use bracket notation for recursive descent: $..[\"_href\"].'\n ),\n }),\n description:\n 'Query the XML document via JSONPath. The document was produced earlier in this turn. ' +\n 'Attributes appear as underscore-prefixed keys (e.g., _href for an href attribute). Use bracket notation in recursive-descent queries: $..[\"_href\"].',\n },\n {\n name: 'artifact_xml_filter',\n method: 'xml_filter',\n argsSchema: validator.object({\n path: validator\n .string()\n .required()\n .description(\n 'JSONPath expression to filter the document. Attributes appear with a leading underscore (e.g., _href).'\n ),\n }),\n description:\n 'Return XML elements whose content matches a JSONPath filter. Differs from artifact_xml_get: get returns matched values; filter returns the element objects containing them. The document was produced earlier in this turn. Attributes appear as underscore-prefixed keys (e.g., _href).',\n },\n {\n name: 'artifact_xml_pluck',\n method: 'xml_pluck',\n argsSchema: validator.object({\n path: validator\n .string()\n .required()\n .description(\n 'JSONPath expression to pluck values. Attributes appear with a leading underscore (e.g., _href).'\n ),\n }),\n description:\n 'Alias for artifact_xml_get — extract values matching a JSONPath. The document was produced earlier in this turn. ' +\n 'Attributes appear as underscore-prefixed keys (e.g., _href).',\n },\n ])\n\n /**\n * The root element name of the XML document.\n *\n * @returns The name of the root element.\n * @throws Error when the document is malformed or empty.\n */\n async xml_root(): Promise<string> {\n const parsed = await this.#resolveParsed()\n const keys = Object.keys(parsed)\n if (keys.length === 0) {\n throw new Error('XML document is empty')\n }\n return keys[0]\n }\n\n /**\n * Keys directly under the root element.\n *\n * @returns Array of key names at the root level.\n */\n async xml_keys(): Promise<string[]> {\n const parsed = await this.#resolveParsed()\n const rootKey = Object.keys(parsed)[0]\n if (!rootKey) return []\n const rootContent = parsed[rootKey]\n if (!isObject(rootContent)) return []\n return Object.keys(rootContent)\n }\n\n /**\n * Every distinct element name in the document, deduplicated.\n *\n * @remarks\n * Walks the entire projection recursively, excluding attribute keys (prefixed with the\n * configured `attributeNamePrefix`, default `_`) and `#text` keys. This is what a model\n * calls before it can write a path into an unfamiliar document.\n *\n * @returns Sorted array of unique element names.\n */\n async xml_tags(): Promise<string[]> {\n const parsed = await this.#resolveParsed()\n const tags = new Set<string>()\n const attributePrefix = this.#attributeNamePrefix\n\n function walk(obj: unknown): void {\n if (!isObject(obj)) return\n for (const [key, value] of Object.entries(obj)) {\n // Skip attribute keys and text nodes\n if (key.startsWith(attributePrefix) || key === '#text') {\n continue\n }\n tags.add(key)\n if (Array.isArray(value)) {\n for (const item of value) {\n walk(item)\n }\n } else {\n walk(value)\n }\n }\n }\n\n walk(parsed)\n return Array.from(tags).sort()\n }\n\n /**\n * Element count when the root contains an array of children; otherwise 1.\n *\n * @returns Number of elements.\n */\n async xml_length(): Promise<number> {\n const parsed = await this.#resolveParsed()\n const rootKey = Object.keys(parsed)[0]\n if (!rootKey) return 0\n const rootContent = parsed[rootKey]\n if (Array.isArray(rootContent)) {\n return rootContent.length\n }\n return 1\n }\n\n /**\n * Query the document via JSONPath expression.\n *\n * @param path - A JSONPath expression (e.g., `'$..name'`).\n * @returns Array of matched values.\n */\n async xml_get(path: string): Promise<unknown[]> {\n const parsed = await this.#resolveParsed()\n const results = JSONPath({ path, json: parsed })\n return results\n }\n\n /**\n * Returns the elements (subtrees) that match a JSONPath expression.\n *\n * @remarks\n * Evaluates the path against the XML projection and returns the elements that\n * contain matching values. Unlike xml_get (which returns matched values), xml_filter\n * returns the element objects containing those matches.\n *\n * Candidate set definition for XML's single-rooted projection:\n * - If the root element contains an array of repeated siblings (e.g., root.item\n * where item is an array property), filters across those siblings and returns\n * elements that have matching content.\n * - If the root element contains a single object, evaluates the path against it\n * and returns it when matched.\n *\n * The path is evaluated using JSONPath-Plus with resultType 'all' to extract\n * parent elements of matched values. The immediate parent object of any matched\n * value is included in the result, deduplicating elements.\n *\n * Example: for XML with root containing multiple 'item' elements each with an\n * 'id' attribute, xml_filter('$.root.item[*]._id') returns the item elements\n * that have an id attribute, whereas xml_get would return the id values themselves.\n *\n * @param path - A JSONPath expression (e.g. '$.root.item[*]._id' or '$[?(@.status)]').\n * @returns Array of matching element subtrees. Empty array when no matches found.\n */\n async xml_filter(path: string): Promise<unknown[]> {\n const parsed = await this.#resolveParsed()\n const rootKey = Object.keys(parsed)[0]\n if (!rootKey) return []\n\n const rootContent = parsed[rootKey]\n\n // If the root content is an array of siblings, filter the array elements\n if (Array.isArray(rootContent)) {\n // Evaluate the path against each sibling element to see if it matches\n return rootContent.filter((element) => {\n const matches = JSONPath({ path, json: element as object })\n return Array.isArray(matches) && matches.length > 0\n })\n }\n\n // If the root content is a single object, use 'all' resultType to get parent objects\n if (isObject(rootContent)) {\n // Evaluate the path against the full parsed document to get match information\n const allMatches = JSONPath({\n path,\n json: parsed,\n resultType: 'all',\n }) as unknown\n\n if (!Array.isArray(allMatches) || allMatches.length === 0) {\n return []\n }\n\n // Extract parent objects, deduplicating by reference\n const parentSet = new Set<object>()\n for (const match of allMatches) {\n const m = match as Record<string, unknown>\n if (isObject(m.parent)) {\n parentSet.add(m.parent as object)\n }\n }\n\n return Array.from(parentSet)\n }\n\n // For scalar or other types, return empty\n return []\n }\n\n /**\n * Alias for xml_get — extract values matching a JSONPath.\n *\n * @param path - A JSONPath expression (e.g., `'$..name'`).\n * @returns Array of matched values.\n */\n async xml_pluck(path: string): Promise<unknown[]> {\n return this.xml_get(path)\n }\n\n /**\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 XML-specific descriptor narrowed to XML artifacts.\n */\n public static override forgeTools(ctx: DispatchContext): ToolRegistry {\n const registry = SpooledArtifact.forgeTools(ctx)\n const requires = SpooledXmlArtifact\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 === 'xml_get' ||\n descriptor.method === 'xml_filter' ||\n descriptor.method === 'xml_pluck'\n ) {\n methodArgs.push(args.path as string)\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 XML projection.\n *\n * @returns The parsed projection as a JSON object.\n * @throws {@link E_XML_PARSE_FAILED} when XML parsing fails.\n */\n async #resolveParsed(): Promise<Record<string, unknown>> {\n if (this.#parsed !== undefined) {\n return this.#parsed\n }\n\n const parser = await getXmlParser()\n const xmlParser = new parser.XMLParser({\n ignoreAttributes: this.#ignoreAttributes,\n attributeNamePrefix: this.#attributeNamePrefix,\n preserveOrder: false,\n })\n\n const content = await this.asString()\n try {\n this.#parsed = xmlParser.parse(content) as Record<string, unknown>\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n throw new E_XML_PARSE_FAILED([detail])\n }\n return this.#parsed\n }\n\n /**\n * Serialise this SpooledXmlArtifact into an `@nhtio/encoder` snapshot — the reader **handle**\n * plus the constructor options for `attributeNamePrefix` and `ignoreAttributes`.\n *\n * @remarks\n * Overrides {@link SpooledArtifact.[ENCODE_METHOD]} to carry the constructor's options\n * (the parsed projection cache is derived and not encoded). Round-trips via\n * {@link SpooledXmlArtifact.[DECODE_METHOD]}.\n *\n * @returns A snapshot consumed by {@link SpooledXmlArtifact.[DECODE_METHOD]}.\n */\n [ENCODE_METHOD](): AdkEncodableSnapshot {\n return {\n reader: this.readerDescriptor(),\n attributeNamePrefix: this.#attributeNamePrefix,\n ignoreAttributes: this.#ignoreAttributes,\n }\n }\n\n /**\n * Reconstruct a {@link SpooledXmlArtifact} from a {@link SpooledXmlArtifact.[ENCODE_METHOD]}\n * snapshot.\n *\n * @param data - The snapshot produced by {@link SpooledXmlArtifact.[ENCODE_METHOD]}.\n * @returns A fresh {@link SpooledXmlArtifact} backed by a freshly-resolved reader.\n */\n static [DECODE_METHOD](data: AdkEncodableSnapshot): SpooledXmlArtifact {\n const snapshot = data as {\n reader: ReaderDescriptor\n attributeNamePrefix?: string\n ignoreAttributes?: boolean\n }\n return new SpooledXmlArtifact(resolveSpoolReader(snapshot.reader), {\n attributeNamePrefix: snapshot.attributeNamePrefix,\n ignoreAttributes: snapshot.ignoreAttributes,\n })\n }\n}\n\n/**\n * A tool that converts XML (inline or from an artifact) to JSON.\n *\n * @remarks\n * Input is either `text` (inline XML) or `call_id` (an XML artifact from earlier in this turn).\n * Provide exactly one. Returns a new {@link SpooledJsonArtifact}.\n */\nexport const xmlToJsonTool = new Tool({\n name: 'xml_to_json',\n description:\n 'Convert XML (inline or from an artifact produced earlier in this turn) to JSON. ' +\n 'Returns a queryable JSON artifact.',\n inputSchema: validator.object({\n text: validator\n .string()\n .optional()\n .allow('')\n .description('Inline XML text. Provide this or call_id, not both.'),\n call_id: validator\n .string()\n .optional()\n .allow('')\n .description('ToolCall id of an XML artifact produced earlier in this turn.'),\n }),\n artifactConstructor: () => SpooledJsonArtifact,\n handler: async (rawArgs, ctx) => {\n const args = rawArgs as { text?: string; call_id?: string }\n const text = (args.text ?? '').trim()\n const callId = (args.call_id ?? '').trim()\n\n // Validate input\n if (!text && !callId) {\n return 'Error: provide either text or call_id, not both or neither'\n }\n if (text && callId) {\n return 'Error: provide either text or call_id, not both'\n }\n\n let xmlContent: string\n let sourceId: string\n let attributeNamePrefix: string\n let ignoreAttributes: boolean\n\n if (callId) {\n const resolved = resolveArtifactById(ctx, callId, SpooledXmlArtifact)\n if (!resolved) {\n return `Error: no artifact with id ${callId} in this turn`\n }\n const xmlArtifact = resolved.artifact as SpooledXmlArtifact\n xmlContent = await xmlArtifact.asString()\n sourceId = callId\n // Inherit the source artifact's parser configuration\n const sourceOptions = xmlArtifact.getParserOptions()\n attributeNamePrefix = sourceOptions.attributeNamePrefix\n ignoreAttributes = sourceOptions.ignoreAttributes\n } else {\n xmlContent = text\n sourceId = uuidv6()\n // Use defaults for inline conversions\n attributeNamePrefix = '_'\n ignoreAttributes = false\n }\n\n // Parse XML to JSON projection\n const parser = await getXmlParser()\n const xmlParser = new parser.XMLParser({\n ignoreAttributes,\n attributeNamePrefix,\n preserveOrder: false,\n })\n\n let parsed: unknown\n try {\n parsed = xmlParser.parse(xmlContent)\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n return `Error: XML parse failed: ${detail}`\n }\n\n // Convert to JSON string\n const jsonString = JSON.stringify(parsed)\n\n // Spool and return\n const reader = await ctx.storeRetrievableBytes(`${ctx.id}:xml_to_json:${sourceId}`, jsonString)\n return new SpooledJsonArtifact(reader)\n },\n})\n\n/**\n * A tool that converts JSON (inline or from an artifact) to XML.\n *\n * @remarks\n * Input is either `text` (inline JSON) or `call_id` (a JSON artifact from earlier in this turn).\n * Provide exactly one. Returns a new {@link SpooledXmlArtifact}.\n *\n * Note: XML has no faithful JSON inverse. A JSON document that never came from XML may not\n * rebuild into sensible markup. This tool converts on a best-effort basis; the result may not\n * round-trip perfectly back to the original JSON.\n */\nexport const jsonToXmlTool = new Tool({\n name: 'json_to_xml',\n description:\n 'Convert JSON (inline or from an artifact produced earlier in this turn) to XML. ' +\n 'Returns a queryable XML artifact. ' +\n 'Note: XML has no faithful JSON inverse — a JSON document that never came from XML may not rebuild into sensible markup.',\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: () => SpooledXmlArtifact,\n handler: async (rawArgs, ctx) => {\n const args = rawArgs as { text?: string; call_id?: string }\n const text = (args.text ?? '').trim()\n const callId = (args.call_id ?? '').trim()\n\n // Validate input\n if (!text && !callId) {\n return 'Error: provide either text or call_id, not both or neither'\n }\n if (text && callId) {\n return 'Error: provide either text or call_id, not both'\n }\n\n let jsonContent: unknown\n let sourceId: string\n\n if (callId) {\n const resolved = resolveArtifactById(ctx, callId, SpooledJsonArtifact)\n if (!resolved) {\n return `Error: no artifact with id ${callId} in this turn`\n }\n const jsonString = await resolved.artifact.asString()\n try {\n jsonContent = JSON.parse(jsonString)\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n return `Error: JSON parse failed: ${detail}`\n }\n sourceId = callId\n } else {\n try {\n jsonContent = JSON.parse(text)\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n return `Error: JSON parse failed: ${detail}`\n }\n sourceId = uuidv6()\n }\n\n // Convert JSON to XML via builder\n const parser = await getXmlParser()\n const xmlBuilder = new parser.XMLBuilder({\n ignoreAttributes: false,\n attributeNamePrefix: '_',\n format: false,\n })\n\n let xmlString: string\n try {\n xmlString = xmlBuilder.build(jsonContent) as string\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n return `Error: XML build failed: ${detail}`\n }\n\n // Spool and return\n const reader = await ctx.storeRetrievableBytes(`${ctx.id}:json_to_xml:${sourceId}`, xmlString)\n return new SpooledXmlArtifact(reader)\n },\n})\n\n/**\n * Re-export the exceptions for battery-scoped error handling.\n *\n * @remarks\n * Battery exceptions are defined in `exceptions.ts` and re-exported here per the\n * battery-scoped-exceptions pattern — consumers of `@nhtio/adk/batteries/artifacts/xml`\n * can import these exception classes directly.\n */\nexport { E_XML_PARSER_PEER_MISSING, E_XML_PARSE_FAILED } from './exceptions'\n"],"mappings":"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"}
1
+ {"version":3,"file":"xml-BeNvlifb.js","names":["#attributeNamePrefix","#ignoreAttributes","#resolveParsed","#parsed"],"sources":["../src/batteries/artifacts/xml/exceptions.ts","../src/batteries/artifacts/xml/index.ts"],"sourcesContent":["/**\n * Battery-scoped exceptions for the XML artifact battery.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/artifacts/xml` entry — re-exported from the battery's\n * 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 fast-xml-parser optional peer is not installed or fails to load.\n *\n * @remarks\n * The message template includes the package name, a description of its purpose, the underlying\n * error, and the exact install command, so the consumer sees a complete, actionable message\n * regardless of call site.\n */\nexport const E_XML_PARSER_PEER_MISSING = createException<[string]>(\n 'E_XML_PARSER_PEER_MISSING',\n 'the XML battery could not load its peer dependency \"fast-xml-parser\" (needed for XML format artifact queries): %s — install it (pnpm add fast-xml-parser)',\n 'E_XML_PARSER_PEER_MISSING',\n 500,\n true\n)\n\n/**\n * Thrown when XML parsing fails due to malformed markup.\n *\n * @remarks\n * Printf args: `[errorDetail]` — includes the parser's own reason for the failure.\n */\nexport const E_XML_PARSE_FAILED = createException<[string]>(\n 'E_XML_PARSE_FAILED',\n 'XML parse failed: %s',\n 'E_XML_PARSE_FAILED',\n 422,\n false\n)\n","/**\n * A structured artifact battery for XML documents.\n *\n * @module @nhtio/adk/batteries/artifacts/xml\n *\n * @remarks\n * Provides {@link SpooledXmlArtifact} — a `SpooledArtifact` specialisation that parses XML\n * into a JSON projection and offers path-based query tools over that projection. The XML-to-JSON\n * mapping defaults to `ignoreAttributes: false` and `attributeNamePrefix: '_'`, both settable\n * per instance through the constructor; `preserveOrder: false` is fixed. Under the default\n * mapping:\n *\n * - Element attributes become keys prefixed with `_` (e.g., `root-element` with `href=\"x\"`\n * becomes `{ a: { _href: 'x', ... } }`).\n * - Element text content becomes a `#text` key when the element also has attributes or siblings.\n * - Repeated sibling elements collapse into an array.\n * - The full projection is queryable via JSONPath expressions (e.g., `$..name` finds all name\n * elements anywhere in the tree). Attributes are accessed via underscore-prefixed keys,\n * e.g. `$..[\"_href\"]` for the href attribute (recursive descent).\n *\n * The battery also exports two converter `Tool` constants: `xmlToJsonTool` and `jsonToXmlTool`.\n * These accept either inline XML/JSON text or a reference to an artifact produced earlier in\n * the turn, and return the converted result as a new `SpooledJsonArtifact` or\n * `SpooledXmlArtifact`.\n *\n * Battery exceptions are defined in this module's `exceptions.ts` file — `createException`\n * re-exported from `@nhtio/adk/factories`. Decoding a {@link SpooledXmlArtifact} instance via\n * `decode()` throws until `registerArtifactEncodables()` has run (see\n * {@link @nhtio/adk/batteries/artifacts!registerArtifactEncodables}).\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 { SpooledJsonArtifact } from '@nhtio/adk/common'\nimport { isInstanceOf, isError, isObject } from '@nhtio/adk/guards'\nimport { E_XML_PARSER_PEER_MISSING, E_XML_PARSE_FAILED } from './exceptions'\nimport { ArtifactTool, Tool, ToolRegistry, ReaderDescriptor } 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')\nimport {\n SpooledArtifact,\n collectArtifactCompatibleIds,\n resolveArtifactById,\n defaultSerialise,\n} from '@nhtio/adk/spooled_artifact'\nimport type { SpoolReader } from '@nhtio/adk/types'\nimport type { XMLParser, XMLBuilder } from 'fast-xml-parser'\nimport type { 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 * Lazy-loaded promise for the `fast-xml-parser` module, cached at module scope.\n */\nlet xmlParserPromise:\n | Promise<{ XMLParser: typeof XMLParser; XMLBuilder: typeof XMLBuilder }>\n | undefined\n\n/**\n * Lazily import and cache the `fast-xml-parser` module with battery-scoped error handling.\n *\n * @returns The imported module.\n * @throws {@link E_XML_PARSER_PEER_MISSING} when the module is unavailable.\n */\nasync function getXmlParser(): Promise<{\n XMLParser: typeof XMLParser\n XMLBuilder: typeof XMLBuilder\n}> {\n xmlParserPromise ??= import('fast-xml-parser').catch((err) => {\n const detail = isError(err) ? err.message : String(err)\n throw new E_XML_PARSER_PEER_MISSING([detail])\n })\n return xmlParserPromise\n}\n\n/**\n * A {@link @nhtio/adk!SpooledArtifact} specialisation that adds XML-aware read operations.\n *\n * @remarks\n * The artifact parses XML into a JSON projection on first access and caches it for the\n * lifetime of the instance. The projection uses `ignoreAttributes` and `attributeNamePrefix` as\n * supplied to the constructor — defaulting to `false` and `'_'` — with `preserveOrder: false`.\n *\n * Under this mapping, an XML element like:\n *\n * `root-element` with an `href` attribute and text content becomes a JSON object like:\n * `{ root: { element: { _href: 'value', '#text': 'content' } } }`\n *\n * Attributes are prefixed with `_` by default rather than the conventional `@_`, because\n * `jsonpath-plus` reads a leading `@` in a path segment as its type-selector sigil before\n * honouring quotes: `$..[\"@_href\"]` throws `Unknown value type _hr`, while `$..[\"_href\"]`\n * matches. Text nodes use the `#text` key.\n *\n * All XML methods are async, consistent with {@link @nhtio/adk!SpooledArtifact}.\n *\n * Path-based methods (`xml_get`, `xml_filter`, `xml_pluck`) use\n * [JSONPath-Plus](https://github.com/JSONPath-Plus/JSONPath) expressions over the projection.\n * Full JSONPath syntax is supported, including recursive descent (`..`), filter expressions,\n * and union selectors.\n */\nexport class SpooledXmlArtifact extends SpooledArtifact {\n #parsed: Record<string, unknown> | undefined\n #attributeNamePrefix: string\n #ignoreAttributes: boolean\n\n /**\n * @param reader - The backing store to read from.\n * @param options - Optional parser configuration.\n * @param options.attributeNamePrefix - Prefix for attribute keys (default: '_'). Set to '@_'\n * if you need the conventional XML-to-JSON mapping, but be aware that naming such a key in a\n * JSONPath segment fails — `$..[\"@_attr\"]` throws `Unknown value type _at`, and quoting does\n * not escape it. A filter expression still reaches it (`$..[?(@['@_attr'])]`); a wildcard\n * does too, but only when placed exactly one level above the key, so the working path\n * depends on whether repeated elements collapsed into an array.\n * @param options.ignoreAttributes - When true, ignore element attributes (default: false).\n */\n constructor(\n reader: SpoolReader,\n options?: {\n attributeNamePrefix?: string\n ignoreAttributes?: boolean\n }\n ) {\n super(reader)\n this.#attributeNamePrefix = options?.attributeNamePrefix ?? '_'\n this.#ignoreAttributes = options?.ignoreAttributes ?? false\n }\n\n /**\n * Returns `true` if `value` is a {@link SpooledXmlArtifact} instance.\n *\n * @remarks\n * Uses the cross-realm-safe {@link @nhtio/adk!isInstanceOf} guard. Safe against the\n * dual-module-copy case where two distinct `SpooledXmlArtifact` classes coexist in the same\n * realm.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link SpooledXmlArtifact} instance.\n */\n public static isSpooledXmlArtifact(value: unknown): value is SpooledXmlArtifact {\n return isInstanceOf(value, 'SpooledXmlArtifact', SpooledXmlArtifact)\n }\n\n /**\n * Returns the effective XML-to-JSON parser configuration for this artifact.\n *\n * @remarks\n * When converting an XML artifact to JSON by call_id, the converter inherits the source\n * artifact's attribute prefix and ignoreAttributes setting. This accessor exposes those\n * options so the converter can apply them consistently.\n *\n * @returns An object with `attributeNamePrefix` and `ignoreAttributes` keys.\n */\n public getParserOptions(): {\n attributeNamePrefix: string\n ignoreAttributes: boolean\n } {\n return {\n attributeNamePrefix: this.#attributeNamePrefix,\n ignoreAttributes: this.#ignoreAttributes,\n }\n }\n\n /**\n * The XML-specific artifact-query descriptors this class adds on top of the base set.\n *\n * @remarks\n * Lists `artifact_xml_root`, `artifact_xml_keys`, `artifact_xml_tags`, `artifact_xml_length`,\n * `artifact_xml_get`, `artifact_xml_filter`, `artifact_xml_pluck`. The base seven descriptors\n * (`artifact_head`, etc.) are NOT included here — they are forged separately by\n * {@link SpooledXmlArtifact.forgeTools}.\n */\n public static toolMethods: ReadonlyArray<ToolMethodDescriptor> = Object.freeze([\n {\n name: 'artifact_xml_root',\n method: 'xml_root',\n description: 'The root element name of the XML document produced earlier in this turn.',\n },\n {\n name: 'artifact_xml_keys',\n method: 'xml_keys',\n description:\n 'Keys directly under the root element of the XML document produced earlier in this turn.',\n },\n {\n name: 'artifact_xml_tags',\n method: 'xml_tags',\n description:\n 'Every distinct element name in the XML document produced earlier in this turn, deduplicated. ' +\n 'Call this before writing a path to an unfamiliar document — it tells you what elements are present.',\n },\n {\n name: 'artifact_xml_length',\n method: 'xml_length',\n description:\n 'Element count when the root element contains an array of children; otherwise 1. ' +\n 'The XML document was produced earlier in this turn.',\n },\n {\n name: 'artifact_xml_get',\n method: 'xml_get',\n argsSchema: validator.object({\n path: validator\n .string()\n .required()\n .description(\n 'JSONPath expression to query the document. Attributes appear with a leading underscore (e.g., _href). Use bracket notation for recursive descent: $..[\"_href\"].'\n ),\n }),\n description:\n 'Query the XML document via JSONPath. The document was produced earlier in this turn. ' +\n 'Attributes appear as underscore-prefixed keys (e.g., _href for an href attribute). Use bracket notation in recursive-descent queries: $..[\"_href\"].',\n },\n {\n name: 'artifact_xml_filter',\n method: 'xml_filter',\n argsSchema: validator.object({\n path: validator\n .string()\n .required()\n .description(\n 'JSONPath expression to filter the document. Attributes appear with a leading underscore (e.g., _href).'\n ),\n }),\n description:\n 'Return XML elements whose content matches a JSONPath filter. Differs from artifact_xml_get: get returns matched values; filter returns the element objects containing them. The document was produced earlier in this turn. Attributes appear as underscore-prefixed keys (e.g., _href).',\n },\n {\n name: 'artifact_xml_pluck',\n method: 'xml_pluck',\n argsSchema: validator.object({\n path: validator\n .string()\n .required()\n .description(\n 'JSONPath expression to pluck values. Attributes appear with a leading underscore (e.g., _href).'\n ),\n }),\n description:\n 'Alias for artifact_xml_get — extract values matching a JSONPath. The document was produced earlier in this turn. ' +\n 'Attributes appear as underscore-prefixed keys (e.g., _href).',\n },\n ])\n\n /**\n * The root element name of the XML document.\n *\n * @returns The name of the root element.\n * @throws Error when the document is malformed or empty.\n */\n async xml_root(): Promise<string> {\n const parsed = await this.#resolveParsed()\n const keys = Object.keys(parsed)\n if (keys.length === 0) {\n throw new Error('XML document is empty')\n }\n return keys[0]\n }\n\n /**\n * Keys directly under the root element.\n *\n * @returns Array of key names at the root level.\n */\n async xml_keys(): Promise<string[]> {\n const parsed = await this.#resolveParsed()\n const rootKey = Object.keys(parsed)[0]\n if (!rootKey) return []\n const rootContent = parsed[rootKey]\n if (!isObject(rootContent)) return []\n return Object.keys(rootContent)\n }\n\n /**\n * Every distinct element name in the document, deduplicated.\n *\n * @remarks\n * Walks the entire projection recursively, excluding attribute keys (prefixed with the\n * configured `attributeNamePrefix`, default `_`) and `#text` keys. This is what a model\n * calls before it can write a path into an unfamiliar document.\n *\n * @returns Sorted array of unique element names.\n */\n async xml_tags(): Promise<string[]> {\n const parsed = await this.#resolveParsed()\n const tags = new Set<string>()\n const attributePrefix = this.#attributeNamePrefix\n\n function walk(obj: unknown): void {\n if (!isObject(obj)) return\n for (const [key, value] of Object.entries(obj)) {\n // Skip attribute keys and text nodes\n if (key.startsWith(attributePrefix) || key === '#text') {\n continue\n }\n tags.add(key)\n if (Array.isArray(value)) {\n for (const item of value) {\n walk(item)\n }\n } else {\n walk(value)\n }\n }\n }\n\n walk(parsed)\n return Array.from(tags).sort()\n }\n\n /**\n * Element count when the root contains an array of children; otherwise 1.\n *\n * @returns Number of elements.\n */\n async xml_length(): Promise<number> {\n const parsed = await this.#resolveParsed()\n const rootKey = Object.keys(parsed)[0]\n if (!rootKey) return 0\n const rootContent = parsed[rootKey]\n if (Array.isArray(rootContent)) {\n return rootContent.length\n }\n return 1\n }\n\n /**\n * Query the document via JSONPath expression.\n *\n * @param path - A JSONPath expression (e.g., `'$..name'`).\n * @returns Array of matched values.\n */\n async xml_get(path: string): Promise<unknown[]> {\n const parsed = await this.#resolveParsed()\n const results = JSONPath({ path, json: parsed })\n return results\n }\n\n /**\n * Returns the elements (subtrees) that match a JSONPath expression.\n *\n * @remarks\n * Evaluates the path against the XML projection and returns the elements that\n * contain matching values. Unlike xml_get (which returns matched values), xml_filter\n * returns the element objects containing those matches.\n *\n * Candidate set definition for XML's single-rooted projection:\n * - If the root element contains an array of repeated siblings (e.g., root.item\n * where item is an array property), filters across those siblings and returns\n * elements that have matching content.\n * - If the root element contains a single object, evaluates the path against it\n * and returns it when matched.\n *\n * The path is evaluated using JSONPath-Plus with resultType 'all' to extract\n * parent elements of matched values. The immediate parent object of any matched\n * value is included in the result, deduplicating elements.\n *\n * Example: for XML with root containing multiple 'item' elements each with an\n * 'id' attribute, xml_filter('$.root.item[*]._id') returns the item elements\n * that have an id attribute, whereas xml_get would return the id values themselves.\n *\n * @param path - A JSONPath expression (e.g. '$.root.item[*]._id' or '$[?(@.status)]').\n * @returns Array of matching element subtrees. Empty array when no matches found.\n */\n async xml_filter(path: string): Promise<unknown[]> {\n const parsed = await this.#resolveParsed()\n const rootKey = Object.keys(parsed)[0]\n if (!rootKey) return []\n\n const rootContent = parsed[rootKey]\n\n // If the root content is an array of siblings, filter the array elements\n if (Array.isArray(rootContent)) {\n // Evaluate the path against each sibling element to see if it matches\n return rootContent.filter((element) => {\n const matches = JSONPath({ path, json: element as object })\n return Array.isArray(matches) && matches.length > 0\n })\n }\n\n // If the root content is a single object, use 'all' resultType to get parent objects\n if (isObject(rootContent)) {\n // Evaluate the path against the full parsed document to get match information\n const allMatches = JSONPath({\n path,\n json: parsed,\n resultType: 'all',\n }) as unknown\n\n if (!Array.isArray(allMatches) || allMatches.length === 0) {\n return []\n }\n\n // Extract parent objects, deduplicating by reference\n const parentSet = new Set<object>()\n for (const match of allMatches) {\n const m = match as Record<string, unknown>\n if (isObject(m.parent)) {\n parentSet.add(m.parent as object)\n }\n }\n\n return Array.from(parentSet)\n }\n\n // For scalar or other types, return empty\n return []\n }\n\n /**\n * Alias for xml_get — extract values matching a JSONPath.\n *\n * @param path - A JSONPath expression (e.g., `'$..name'`).\n * @returns Array of matched values.\n */\n async xml_pluck(path: string): Promise<unknown[]> {\n return this.xml_get(path)\n }\n\n /**\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 XML-specific descriptor narrowed to XML artifacts.\n */\n public static override forgeTools(ctx: DispatchContext): ToolRegistry {\n const registry = SpooledArtifact.forgeTools(ctx)\n const requires = SpooledXmlArtifact\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 === 'xml_get' ||\n descriptor.method === 'xml_filter' ||\n descriptor.method === 'xml_pluck'\n ) {\n methodArgs.push(args.path as string)\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 XML projection.\n *\n * @returns The parsed projection as a JSON object.\n * @throws {@link E_XML_PARSE_FAILED} when XML parsing fails.\n */\n async #resolveParsed(): Promise<Record<string, unknown>> {\n if (this.#parsed !== undefined) {\n return this.#parsed\n }\n\n const parser = await getXmlParser()\n const xmlParser = new parser.XMLParser({\n ignoreAttributes: this.#ignoreAttributes,\n attributeNamePrefix: this.#attributeNamePrefix,\n preserveOrder: false,\n })\n\n const content = await this.asString()\n try {\n this.#parsed = xmlParser.parse(content) as Record<string, unknown>\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n throw new E_XML_PARSE_FAILED([detail])\n }\n return this.#parsed\n }\n\n /**\n * Serialise this SpooledXmlArtifact into an `@nhtio/encoder` snapshot — the reader **handle**\n * plus the constructor options for `attributeNamePrefix` and `ignoreAttributes`.\n *\n * @remarks\n * Overrides {@link SpooledArtifact.[ENCODE_METHOD]} to carry the constructor's options\n * (the parsed projection cache is derived and not encoded). Round-trips via\n * {@link SpooledXmlArtifact.[DECODE_METHOD]}.\n *\n * @returns A snapshot consumed by {@link SpooledXmlArtifact.[DECODE_METHOD]}.\n */\n [ENCODE_METHOD](): AdkEncodableSnapshot {\n return {\n reader: this.readerDescriptor(),\n attributeNamePrefix: this.#attributeNamePrefix,\n ignoreAttributes: this.#ignoreAttributes,\n }\n }\n\n /**\n * Reconstruct a {@link SpooledXmlArtifact} from a {@link SpooledXmlArtifact.[ENCODE_METHOD]}\n * snapshot.\n *\n * @param data - The snapshot produced by {@link SpooledXmlArtifact.[ENCODE_METHOD]}.\n * @returns A fresh {@link SpooledXmlArtifact} backed by a freshly-resolved reader.\n */\n static [DECODE_METHOD](data: AdkEncodableSnapshot): SpooledXmlArtifact {\n const snapshot = data as {\n reader: ReaderDescriptor\n attributeNamePrefix?: string\n ignoreAttributes?: boolean\n }\n return new SpooledXmlArtifact(resolveSpoolReader(snapshot.reader), {\n attributeNamePrefix: snapshot.attributeNamePrefix,\n ignoreAttributes: snapshot.ignoreAttributes,\n })\n }\n}\n\n/**\n * A tool that converts XML (inline or from an artifact) to JSON.\n *\n * @remarks\n * Input is either `text` (inline XML) or `call_id` (an XML artifact from earlier in this turn).\n * Provide exactly one. Returns a new {@link SpooledJsonArtifact}.\n */\nexport const xmlToJsonTool = new Tool({\n name: 'xml_to_json',\n description:\n 'Convert XML (inline or from an artifact produced earlier in this turn) to JSON. ' +\n 'Returns a queryable JSON artifact.',\n inputSchema: validator.object({\n text: validator\n .string()\n .optional()\n .allow('')\n .description('Inline XML text. Provide this or call_id, not both.'),\n call_id: validator\n .string()\n .optional()\n .allow('')\n .description('ToolCall id of an XML artifact produced earlier in this turn.'),\n }),\n artifactConstructor: () => SpooledJsonArtifact,\n handler: async (rawArgs, ctx) => {\n const args = rawArgs as { text?: string; call_id?: string }\n const text = (args.text ?? '').trim()\n const callId = (args.call_id ?? '').trim()\n\n // Validate input\n if (!text && !callId) {\n return 'Error: provide either text or call_id, not both or neither'\n }\n if (text && callId) {\n return 'Error: provide either text or call_id, not both'\n }\n\n let xmlContent: string\n let sourceId: string\n let attributeNamePrefix: string\n let ignoreAttributes: boolean\n\n if (callId) {\n const resolved = resolveArtifactById(ctx, callId, SpooledXmlArtifact)\n if (!resolved) {\n return `Error: no artifact with id ${callId} in this turn`\n }\n const xmlArtifact = resolved.artifact as SpooledXmlArtifact\n xmlContent = await xmlArtifact.asString()\n sourceId = callId\n // Inherit the source artifact's parser configuration\n const sourceOptions = xmlArtifact.getParserOptions()\n attributeNamePrefix = sourceOptions.attributeNamePrefix\n ignoreAttributes = sourceOptions.ignoreAttributes\n } else {\n xmlContent = text\n sourceId = uuidv6()\n // Use defaults for inline conversions\n attributeNamePrefix = '_'\n ignoreAttributes = false\n }\n\n // Parse XML to JSON projection\n const parser = await getXmlParser()\n const xmlParser = new parser.XMLParser({\n ignoreAttributes,\n attributeNamePrefix,\n preserveOrder: false,\n })\n\n let parsed: unknown\n try {\n parsed = xmlParser.parse(xmlContent)\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n return `Error: XML parse failed: ${detail}`\n }\n\n // Convert to JSON string\n const jsonString = JSON.stringify(parsed)\n\n // Spool and return\n const reader = await ctx.storeRetrievableBytes(`${ctx.id}:xml_to_json:${sourceId}`, jsonString)\n return new SpooledJsonArtifact(reader)\n },\n})\n\n/**\n * A tool that converts JSON (inline or from an artifact) to XML.\n *\n * @remarks\n * Input is either `text` (inline JSON) or `call_id` (a JSON artifact from earlier in this turn).\n * Provide exactly one. Returns a new {@link SpooledXmlArtifact}.\n *\n * Note: XML has no faithful JSON inverse. A JSON document that never came from XML may not\n * rebuild into sensible markup. This tool converts on a best-effort basis; the result may not\n * round-trip perfectly back to the original JSON.\n */\nexport const jsonToXmlTool = new Tool({\n name: 'json_to_xml',\n description:\n 'Convert JSON (inline or from an artifact produced earlier in this turn) to XML. ' +\n 'Returns a queryable XML artifact. ' +\n 'Note: XML has no faithful JSON inverse — a JSON document that never came from XML may not rebuild into sensible markup.',\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: () => SpooledXmlArtifact,\n handler: async (rawArgs, ctx) => {\n const args = rawArgs as { text?: string; call_id?: string }\n const text = (args.text ?? '').trim()\n const callId = (args.call_id ?? '').trim()\n\n // Validate input\n if (!text && !callId) {\n return 'Error: provide either text or call_id, not both or neither'\n }\n if (text && callId) {\n return 'Error: provide either text or call_id, not both'\n }\n\n let jsonContent: unknown\n let sourceId: string\n\n if (callId) {\n const resolved = resolveArtifactById(ctx, callId, SpooledJsonArtifact)\n if (!resolved) {\n return `Error: no artifact with id ${callId} in this turn`\n }\n const jsonString = await resolved.artifact.asString()\n try {\n jsonContent = JSON.parse(jsonString)\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n return `Error: JSON parse failed: ${detail}`\n }\n sourceId = callId\n } else {\n try {\n jsonContent = JSON.parse(text)\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n return `Error: JSON parse failed: ${detail}`\n }\n sourceId = uuidv6()\n }\n\n // Convert JSON to XML via builder\n const parser = await getXmlParser()\n const xmlBuilder = new parser.XMLBuilder({\n ignoreAttributes: false,\n attributeNamePrefix: '_',\n format: false,\n })\n\n let xmlString: string\n try {\n xmlString = xmlBuilder.build(jsonContent) as string\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n return `Error: XML build failed: ${detail}`\n }\n\n // Spool and return\n const reader = await ctx.storeRetrievableBytes(`${ctx.id}:json_to_xml:${sourceId}`, xmlString)\n return new SpooledXmlArtifact(reader)\n },\n})\n\n/**\n * Re-export the exceptions for battery-scoped error handling.\n *\n * @remarks\n * Battery exceptions are defined in `exceptions.ts` and re-exported here per the\n * battery-scoped-exceptions pattern — consumers of `@nhtio/adk/batteries/artifacts/xml`\n * can import these exception classes directly.\n */\nexport { E_XML_PARSER_PEER_MISSING, E_XML_PARSE_FAILED } from './exceptions'\n"],"mappings":"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"}
@@ -1,13 +1,13 @@
1
1
  import { t as createException } from "./exceptions-DRYLe-J4.mjs";
2
2
  import { n as isInstanceOf, r as isObject, t as isError } from "./guards-BEpY7lBI.mjs";
3
- import { a as resolveArtifactById, d as ArtifactTool, f as Tool, l as resolveSpoolReader, n as collectArtifactCompatibleIds, r as defaultSerialise, t as SpooledArtifact } from "./spooled_artifact-BkueYJhR.mjs";
3
+ import { a as resolveArtifactById, f as ArtifactTool, l as resolveSpoolReader, n as collectArtifactCompatibleIds, p as Tool, r as defaultSerialise, t as SpooledArtifact } from "./spooled_artifact-Bw_7swIp.mjs";
4
+ import "./common-BpdHIpQE.mjs";
5
+ import { n as SpooledJsonArtifact } from "./spooled_markdown_artifact-vd6eNtIP.mjs";
4
6
  import "./factories.mjs";
5
- import "./common-v9Jo9M5k.mjs";
6
- import { n as SpooledJsonArtifact } from "./spooled_markdown_artifact-CfHRZUkl.mjs";
7
7
  import "./guards.mjs";
8
8
  import "./spooled_artifact.mjs";
9
- import { v6 } from "uuid";
10
9
  import { validator } from "@nhtio/validation";
10
+ import { v6 } from "uuid";
11
11
  import { JSONPath } from "jsonpath-plus";
12
12
  //#region src/batteries/artifacts/xml/exceptions.ts
13
13
  /**
@@ -555,4 +555,4 @@ var jsonToXmlTool = new Tool({
555
555
  //#endregion
556
556
  export { E_XML_PARSE_FAILED as a, E_XML_PARSER_PEER_MISSING as i, jsonToXmlTool as n, xmlToJsonTool as r, SpooledXmlArtifact as t };
557
557
 
558
- //# sourceMappingURL=xml-VhJ4NrMB.mjs.map
558
+ //# sourceMappingURL=xml-vyCZZiF_.mjs.map