@nhtio/adk 1.20260924.0 → 1.20260928.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/artifact_methods-Cg0go7Q4.mjs +1 -0
  3. package/artifact_methods-CxeKTocm.cjs +1 -0
  4. package/batteries/artifacts/ecmascript.cjs +1 -1
  5. package/batteries/artifacts/ecmascript.mjs +1 -1
  6. package/batteries/artifacts/toon.cjs +1 -1
  7. package/batteries/artifacts/toon.mjs +1 -1
  8. package/batteries/artifacts/xml.cjs +1 -1
  9. package/batteries/artifacts/xml.mjs +1 -1
  10. package/batteries/artifacts/yaml.cjs +1 -1
  11. package/batteries/artifacts/yaml.mjs +1 -1
  12. package/batteries/artifacts.cjs +4 -4
  13. package/batteries/artifacts.mjs +4 -4
  14. package/batteries/dev-tools/forge.cjs +3 -3
  15. package/batteries/dev-tools/forge.mjs +3 -3
  16. package/batteries/dev-tools.cjs +3 -3
  17. package/batteries/dev-tools.mjs +3 -3
  18. package/batteries/encoding.cjs +7 -7
  19. package/batteries/encoding.mjs +7 -7
  20. package/batteries/generation/gemini/adapter.cjs +1 -1
  21. package/batteries/generation/gemini/adapter.mjs +1 -1
  22. package/batteries/generation/local_diffusion/adapter.cjs +1 -1
  23. package/batteries/generation/local_diffusion/adapter.mjs +1 -1
  24. package/batteries/generation/openai/adapter.cjs +1 -1
  25. package/batteries/generation/openai/adapter.mjs +1 -1
  26. package/batteries/llm/anthropic_messages/adapter.cjs +6 -6
  27. package/batteries/llm/anthropic_messages/adapter.mjs +6 -6
  28. package/batteries/llm/anthropic_messages/count_tokens.cjs +1 -1
  29. package/batteries/llm/anthropic_messages/count_tokens.mjs +1 -1
  30. package/batteries/llm/anthropic_messages/helpers.cjs +3 -3
  31. package/batteries/llm/anthropic_messages/helpers.mjs +3 -3
  32. package/batteries/llm/anthropic_messages/validation.cjs +2 -2
  33. package/batteries/llm/anthropic_messages/validation.mjs +2 -2
  34. package/batteries/llm/anthropic_messages.cjs +2 -2
  35. package/batteries/llm/anthropic_messages.mjs +2 -2
  36. package/batteries/llm/bedrock_converse/adapter.cjs +162 -21
  37. package/batteries/llm/bedrock_converse/adapter.cjs.map +1 -1
  38. package/batteries/llm/bedrock_converse/adapter.mjs +162 -21
  39. package/batteries/llm/bedrock_converse/adapter.mjs.map +1 -1
  40. package/batteries/llm/bedrock_converse/helpers.cjs +1 -1
  41. package/batteries/llm/bedrock_converse/helpers.mjs +1 -1
  42. package/batteries/llm/bedrock_converse/validation.cjs +2 -2
  43. package/batteries/llm/bedrock_converse/validation.mjs +2 -2
  44. package/batteries/llm/bedrock_converse.cjs +2 -2
  45. package/batteries/llm/bedrock_converse.mjs +2 -2
  46. package/batteries/llm/claude_code_cli/adapter.cjs +66 -25
  47. package/batteries/llm/claude_code_cli/adapter.cjs.map +1 -1
  48. package/batteries/llm/claude_code_cli/adapter.mjs +66 -25
  49. package/batteries/llm/claude_code_cli/adapter.mjs.map +1 -1
  50. package/batteries/llm/claude_code_cli/helpers.cjs +3 -3
  51. package/batteries/llm/claude_code_cli/helpers.mjs +3 -3
  52. package/batteries/llm/claude_code_cli/line_queue.d.ts +39 -0
  53. package/batteries/llm/claude_code_cli/message_id_state.d.ts +48 -0
  54. package/batteries/llm/claude_code_cli/types.d.ts +76 -0
  55. package/batteries/llm/claude_code_cli/validation.cjs +5 -2
  56. package/batteries/llm/claude_code_cli/validation.cjs.map +1 -1
  57. package/batteries/llm/claude_code_cli/validation.mjs +5 -2
  58. package/batteries/llm/claude_code_cli/validation.mjs.map +1 -1
  59. package/batteries/llm/claude_code_cli/wire.cjs.map +1 -1
  60. package/batteries/llm/claude_code_cli/wire.d.ts +45 -1
  61. package/batteries/llm/claude_code_cli/wire.mjs.map +1 -1
  62. package/batteries/llm/claude_code_cli/wrapper.d.ts +5 -4
  63. package/batteries/llm/claude_code_cli.cjs +2 -2
  64. package/batteries/llm/claude_code_cli.mjs +2 -2
  65. package/batteries/llm/gemini_generate_content/adapter.cjs +160 -19
  66. package/batteries/llm/gemini_generate_content/adapter.cjs.map +1 -1
  67. package/batteries/llm/gemini_generate_content/adapter.mjs +160 -19
  68. package/batteries/llm/gemini_generate_content/adapter.mjs.map +1 -1
  69. package/batteries/llm/gemini_generate_content/helpers.cjs +1 -1
  70. package/batteries/llm/gemini_generate_content/helpers.mjs +1 -1
  71. package/batteries/llm/gemini_generate_content/validation.cjs +2 -2
  72. package/batteries/llm/gemini_generate_content/validation.mjs +2 -2
  73. package/batteries/llm/gemini_generate_content.cjs +1 -1
  74. package/batteries/llm/gemini_generate_content.mjs +1 -1
  75. package/batteries/llm/litert_lm/adapter.cjs +6 -6
  76. package/batteries/llm/litert_lm/adapter.mjs +6 -6
  77. package/batteries/llm/litert_lm/helpers.cjs +3 -3
  78. package/batteries/llm/litert_lm/helpers.mjs +3 -3
  79. package/batteries/llm/litert_lm/validation.cjs +2 -2
  80. package/batteries/llm/litert_lm/validation.mjs +2 -2
  81. package/batteries/llm/litert_lm.cjs +1 -1
  82. package/batteries/llm/litert_lm.mjs +1 -1
  83. package/batteries/llm/ollama/adapter.cjs +6 -6
  84. package/batteries/llm/ollama/adapter.mjs +6 -6
  85. package/batteries/llm/ollama/helpers.cjs +4 -4
  86. package/batteries/llm/ollama/helpers.mjs +4 -4
  87. package/batteries/llm/ollama/validation.cjs +2 -2
  88. package/batteries/llm/ollama/validation.mjs +2 -2
  89. package/batteries/llm/ollama.cjs +2 -2
  90. package/batteries/llm/ollama.mjs +2 -2
  91. package/batteries/llm/openai_chat_completions/adapter.cjs +6 -6
  92. package/batteries/llm/openai_chat_completions/adapter.mjs +6 -6
  93. package/batteries/llm/openai_chat_completions/helpers.cjs +4 -4
  94. package/batteries/llm/openai_chat_completions/helpers.mjs +4 -4
  95. package/batteries/llm/openai_chat_completions/validation.cjs +2 -2
  96. package/batteries/llm/openai_chat_completions/validation.mjs +2 -2
  97. package/batteries/llm/openai_chat_completions.cjs +2 -2
  98. package/batteries/llm/openai_chat_completions.mjs +2 -2
  99. package/batteries/llm/openai_responses/adapter.cjs +6 -6
  100. package/batteries/llm/openai_responses/adapter.mjs +6 -6
  101. package/batteries/llm/openai_responses/helpers.cjs +3 -3
  102. package/batteries/llm/openai_responses/helpers.mjs +3 -3
  103. package/batteries/llm/openai_responses/validation.cjs +2 -2
  104. package/batteries/llm/openai_responses/validation.mjs +2 -2
  105. package/batteries/llm/openai_responses.cjs +2 -2
  106. package/batteries/llm/openai_responses.mjs +2 -2
  107. package/batteries/llm/transformers_js/adapter.cjs +6 -6
  108. package/batteries/llm/transformers_js/adapter.mjs +6 -6
  109. package/batteries/llm/transformers_js/helpers.cjs +3 -3
  110. package/batteries/llm/transformers_js/helpers.mjs +3 -3
  111. package/batteries/llm/transformers_js/validation.cjs +2 -2
  112. package/batteries/llm/transformers_js/validation.mjs +2 -2
  113. package/batteries/llm/transformers_js.cjs +1 -1
  114. package/batteries/llm/transformers_js.mjs +1 -1
  115. package/batteries/llm/webllm_chat_completions/adapter.cjs +6 -6
  116. package/batteries/llm/webllm_chat_completions/adapter.mjs +6 -6
  117. package/batteries/llm/webllm_chat_completions/helpers.cjs +1 -1
  118. package/batteries/llm/webllm_chat_completions/helpers.mjs +1 -1
  119. package/batteries/llm/webllm_chat_completions/validation.cjs +2 -2
  120. package/batteries/llm/webllm_chat_completions/validation.mjs +2 -2
  121. package/batteries/llm/webllm_chat_completions.cjs +2 -2
  122. package/batteries/llm/webllm_chat_completions.mjs +2 -2
  123. package/batteries/llm.cjs +2 -2
  124. package/batteries/llm.mjs +2 -2
  125. package/batteries/media/forge.cjs +4 -4
  126. package/batteries/media/forge.mjs +4 -4
  127. package/batteries/media/lint.cjs +1 -1
  128. package/batteries/media/lint.mjs +1 -1
  129. package/batteries/orchestration/dispatch_reasoner.cjs +4 -4
  130. package/batteries/orchestration/dispatch_reasoner.mjs +4 -4
  131. package/batteries/orchestration/executor.cjs +2 -2
  132. package/batteries/orchestration/executor.mjs +2 -2
  133. package/batteries/orchestration/forge.cjs +4 -4
  134. package/batteries/orchestration/forge.mjs +4 -4
  135. package/batteries/orchestration/validation.cjs +2 -2
  136. package/batteries/orchestration/validation.mjs +2 -2
  137. package/batteries/orchestration.cjs +4 -4
  138. package/batteries/orchestration.mjs +4 -4
  139. package/batteries/sandbox/js.cjs +1 -1
  140. package/batteries/sandbox/js.mjs +1 -1
  141. package/batteries/sandbox/tools.cjs +1 -1
  142. package/batteries/sandbox/tools.mjs +1 -1
  143. package/batteries/sandbox.cjs +3 -3
  144. package/batteries/sandbox.mjs +3 -3
  145. package/batteries/skills.cjs +9 -9
  146. package/batteries/skills.mjs +9 -9
  147. package/batteries/tools/_shared.cjs +1 -1
  148. package/batteries/tools/_shared.mjs +1 -1
  149. package/batteries/tools/color.cjs +2 -2
  150. package/batteries/tools/color.mjs +2 -2
  151. package/batteries/tools/comparison.cjs +2 -2
  152. package/batteries/tools/comparison.mjs +2 -2
  153. package/batteries/tools/data_structure.cjs +2 -2
  154. package/batteries/tools/data_structure.mjs +2 -2
  155. package/batteries/tools/datetime_extended.cjs +3 -3
  156. package/batteries/tools/datetime_extended.mjs +3 -3
  157. package/batteries/tools/datetime_math.cjs +3 -3
  158. package/batteries/tools/datetime_math.mjs +3 -3
  159. package/batteries/tools/encoding.cjs +2 -2
  160. package/batteries/tools/encoding.mjs +2 -2
  161. package/batteries/tools/formatting.cjs +2 -2
  162. package/batteries/tools/formatting.mjs +2 -2
  163. package/batteries/tools/geo_basics.cjs +2 -2
  164. package/batteries/tools/geo_basics.mjs +2 -2
  165. package/batteries/tools/math.cjs +2 -2
  166. package/batteries/tools/math.mjs +2 -2
  167. package/batteries/tools/memory.cjs +5 -5
  168. package/batteries/tools/memory.mjs +5 -5
  169. package/batteries/tools/parsing.cjs +3 -3
  170. package/batteries/tools/parsing.mjs +3 -3
  171. package/batteries/tools/retrievables.cjs +5 -5
  172. package/batteries/tools/retrievables.mjs +5 -5
  173. package/batteries/tools/scrapper.cjs +1 -1
  174. package/batteries/tools/scrapper.mjs +1 -1
  175. package/batteries/tools/searxng.cjs +1 -1
  176. package/batteries/tools/searxng.mjs +1 -1
  177. package/batteries/tools/standing_instructions.cjs +3 -3
  178. package/batteries/tools/standing_instructions.mjs +3 -3
  179. package/batteries/tools/statistics.cjs +3 -3
  180. package/batteries/tools/statistics.mjs +3 -3
  181. package/batteries/tools/string_processing.cjs +2 -2
  182. package/batteries/tools/string_processing.mjs +2 -2
  183. package/batteries/tools/structured_data.cjs +2 -2
  184. package/batteries/tools/structured_data.mjs +2 -2
  185. package/batteries/tools/text_analysis.cjs +3 -3
  186. package/batteries/tools/text_analysis.mjs +3 -3
  187. package/batteries/tools/text_comparison.cjs +2 -2
  188. package/batteries/tools/text_comparison.mjs +2 -2
  189. package/batteries/tools/time.cjs +3 -3
  190. package/batteries/tools/time.mjs +3 -3
  191. package/batteries/tools/unit_conversion.cjs +2 -2
  192. package/batteries/tools/unit_conversion.mjs +2 -2
  193. package/batteries/tools.cjs +2 -2
  194. package/batteries/tools.mjs +2 -2
  195. package/batteries/validation.cjs +4 -4
  196. package/batteries/validation.mjs +4 -4
  197. package/batteries/vector/conformance.cjs +59 -0
  198. package/batteries/vector/conformance.cjs.map +1 -1
  199. package/batteries/vector/conformance.mjs +59 -0
  200. package/batteries/vector/conformance.mjs.map +1 -1
  201. package/batteries/vector/lancedb.cjs +1 -1
  202. package/batteries/vector/lancedb.cjs.map +1 -1
  203. package/batteries/vector/lancedb.mjs +1 -1
  204. package/batteries/vector/lancedb.mjs.map +1 -1
  205. package/batteries/vector/retrievable.cjs +1 -1
  206. package/batteries/vector/retrievable.mjs +1 -1
  207. package/batteries/vector/sqlite_vec/index.d.ts +1 -1
  208. package/batteries/vector/sqlite_vec.cjs +19 -30
  209. package/batteries/vector/sqlite_vec.cjs.map +1 -1
  210. package/batteries/vector/sqlite_vec.mjs +20 -31
  211. package/batteries/vector/sqlite_vec.mjs.map +1 -1
  212. package/batteries.cjs +4 -4
  213. package/batteries.mjs +4 -4
  214. package/{chat_common-B7fvGTKv.cjs → chat_common-CNayzS1V.cjs} +2 -2
  215. package/{chat_common-B7fvGTKv.cjs.map → chat_common-CNayzS1V.cjs.map} +1 -1
  216. package/{chat_common-CeoHwSsz.mjs → chat_common-DKw8FDol.mjs} +2 -2
  217. package/{chat_common-CeoHwSsz.mjs.map → chat_common-DKw8FDol.mjs.map} +1 -1
  218. package/claude-code-cli-wrapper.cjs +104 -22
  219. package/claude-code-cli-wrapper.cjs.map +1 -1
  220. package/claude-code-cli-wrapper.mjs +104 -22
  221. package/claude-code-cli-wrapper.mjs.map +1 -1
  222. package/{common-7gCR3zQu.cjs → common-CqetsItm.cjs} +7 -7
  223. package/{common-7gCR3zQu.cjs.map → common-CqetsItm.cjs.map} +1 -1
  224. package/{common-B5maOoF_.mjs → common-oI1niK9Z.mjs} +7 -7
  225. package/{common-B5maOoF_.mjs.map → common-oI1niK9Z.mjs.map} +1 -1
  226. package/common.cjs +7 -7
  227. package/common.mjs +7 -7
  228. package/{dispatch_runner-DO7jo_gl.mjs → dispatch_runner-BZDXUe0G.mjs} +5 -5
  229. package/{dispatch_runner-DO7jo_gl.mjs.map → dispatch_runner-BZDXUe0G.mjs.map} +1 -1
  230. package/{dispatch_runner-FlriTyoq.cjs → dispatch_runner-DDUxXJC3.cjs} +5 -5
  231. package/{dispatch_runner-FlriTyoq.cjs.map → dispatch_runner-DDUxXJC3.cjs.map} +1 -1
  232. package/dispatch_runner.cjs +1 -1
  233. package/dispatch_runner.mjs +1 -1
  234. package/{ecmascript-bgwVyZG1.mjs → ecmascript-B9Z2C24U.mjs} +3 -3
  235. package/{ecmascript-bgwVyZG1.mjs.map → ecmascript-B9Z2C24U.mjs.map} +1 -1
  236. package/{ecmascript-BydSB03Y.cjs → ecmascript-BYfmjg7y.cjs} +3 -3
  237. package/{ecmascript-BydSB03Y.cjs.map → ecmascript-BYfmjg7y.cjs.map} +1 -1
  238. package/eslint/rules.cjs +1 -1
  239. package/eslint/rules.mjs +1 -1
  240. package/eslint.cjs +2 -2
  241. package/eslint.mjs +2 -2
  242. package/exceptions.cjs +1 -1
  243. package/exceptions.mjs +1 -1
  244. package/forge.cjs +2 -2
  245. package/forge.mjs +2 -2
  246. package/guards.cjs +7 -7
  247. package/guards.mjs +7 -7
  248. package/{helpers-Dcp4CrOz.cjs → helpers-DPlh_7Bn.cjs} +3 -3
  249. package/{helpers-Dcp4CrOz.cjs.map → helpers-DPlh_7Bn.cjs.map} +1 -1
  250. package/{helpers-C1T0DV8Q.mjs → helpers-mbn_EsDV.mjs} +3 -3
  251. package/{helpers-C1T0DV8Q.mjs.map → helpers-mbn_EsDV.mjs.map} +1 -1
  252. package/index.cjs +11 -11
  253. package/index.mjs +11 -11
  254. package/mcp/adk-docs-corpus.json +2 -2
  255. package/package.json +425 -425
  256. package/{retrievable-BBwiACtw.cjs → retrievable-Bq-O3k6r.cjs} +3 -3
  257. package/{retrievable-BBwiACtw.cjs.map → retrievable-Bq-O3k6r.cjs.map} +1 -1
  258. package/{retrievable-CrGKx4sc.mjs → retrievable-CXTAUuuv.mjs} +3 -3
  259. package/{retrievable-CrGKx4sc.mjs.map → retrievable-CXTAUuuv.mjs.map} +1 -1
  260. package/{scrapper-BibKj8qE.cjs → scrapper-B8xG9lTD.cjs} +4 -4
  261. package/{scrapper-BibKj8qE.cjs.map → scrapper-B8xG9lTD.cjs.map} +1 -1
  262. package/{scrapper-_JzgbLG5.mjs → scrapper-DiQ5FfDL.mjs} +4 -4
  263. package/{scrapper-_JzgbLG5.mjs.map → scrapper-DiQ5FfDL.mjs.map} +1 -1
  264. package/{searxng-D-nA2gEI.mjs → searxng-BFTJ6rTE.mjs} +4 -4
  265. package/{searxng-D-nA2gEI.mjs.map → searxng-BFTJ6rTE.mjs.map} +1 -1
  266. package/{searxng-C6xrLW-v.cjs → searxng-EJhWRnIE.cjs} +4 -4
  267. package/{searxng-C6xrLW-v.cjs.map → searxng-EJhWRnIE.cjs.map} +1 -1
  268. package/server.json +2 -2
  269. package/skills/adk-assembly/SKILL.md +2 -2
  270. package/{spooled_artifact-BLgbGT8b.cjs → spooled_artifact---DmicFW.cjs} +384 -384
  271. package/spooled_artifact---DmicFW.cjs.map +1 -0
  272. package/{spooled_artifact-BkOe4-j-.mjs → spooled_artifact-Bw_7swIp.mjs} +385 -385
  273. package/spooled_artifact-Bw_7swIp.mjs.map +1 -0
  274. package/spooled_artifact.cjs +2 -2
  275. package/spooled_artifact.mjs +2 -2
  276. package/{spooled_markdown_artifact-8zdejfcJ.cjs → spooled_markdown_artifact-Rjzj-kyh.cjs} +3 -3
  277. package/{spooled_markdown_artifact-8zdejfcJ.cjs.map → spooled_markdown_artifact-Rjzj-kyh.cjs.map} +1 -1
  278. package/{spooled_markdown_artifact-Dnl-lCGv.mjs → spooled_markdown_artifact-vd6eNtIP.mjs} +3 -3
  279. package/{spooled_markdown_artifact-Dnl-lCGv.mjs.map → spooled_markdown_artifact-vd6eNtIP.mjs.map} +1 -1
  280. package/{thought-BrQt6HAb.mjs → thought-CxSaF6Xf.mjs} +3 -3
  281. package/{thought-BrQt6HAb.mjs.map → thought-CxSaF6Xf.mjs.map} +1 -1
  282. package/{thought-COeZTQ-B.cjs → thought-Dp3sMWW6.cjs} +3 -3
  283. package/{thought-COeZTQ-B.cjs.map → thought-Dp3sMWW6.cjs.map} +1 -1
  284. package/{tokenizable-DDIdXbJN.cjs → tokenizable-BcodRtoW.cjs} +29 -29
  285. package/{tokenizable-DDIdXbJN.cjs.map → tokenizable-BcodRtoW.cjs.map} +1 -1
  286. package/{tokenizable-xPXj1AQX.mjs → tokenizable-VB4Av8GF.mjs} +30 -30
  287. package/{tokenizable-xPXj1AQX.mjs.map → tokenizable-VB4Av8GF.mjs.map} +1 -1
  288. package/{tool_call-JbjeUpRK.cjs → tool_call-B9px4W9k.cjs} +4 -4
  289. package/{tool_call-JbjeUpRK.cjs.map → tool_call-B9px4W9k.cjs.map} +1 -1
  290. package/{tool_call-8crmZsO8.mjs → tool_call-Cfaj-6zK.mjs} +4 -4
  291. package/{tool_call-8crmZsO8.mjs.map → tool_call-Cfaj-6zK.mjs.map} +1 -1
  292. package/{tools-BC4NJqZD.mjs → tools-D0MBDh2R.mjs} +6 -6
  293. package/{tools-BC4NJqZD.mjs.map → tools-D0MBDh2R.mjs.map} +1 -1
  294. package/{tools-D4mdzi0a.cjs → tools-aNbi6JyA.cjs} +6 -6
  295. package/{tools-D4mdzi0a.cjs.map → tools-aNbi6JyA.cjs.map} +1 -1
  296. package/{toon-BA9Q7NHG.mjs → toon-BSTQnHed.mjs} +5 -5
  297. package/{toon-BA9Q7NHG.mjs.map → toon-BSTQnHed.mjs.map} +1 -1
  298. package/{toon-b-0pFKZ8.cjs → toon-DmLwZ6H1.cjs} +5 -5
  299. package/{toon-b-0pFKZ8.cjs.map → toon-DmLwZ6H1.cjs.map} +1 -1
  300. package/{turn_runner-BmVXcBZ2.mjs → turn_runner-BHHD6h77.mjs} +5 -5
  301. package/{turn_runner-BmVXcBZ2.mjs.map → turn_runner-BHHD6h77.mjs.map} +1 -1
  302. package/{turn_runner-DX-3s3ih.cjs → turn_runner-Dj7JsUTQ.cjs} +5 -5
  303. package/{turn_runner-DX-3s3ih.cjs.map → turn_runner-Dj7JsUTQ.cjs.map} +1 -1
  304. package/turn_runner.cjs +1 -1
  305. package/turn_runner.mjs +1 -1
  306. package/{xml-B1JIGLpU.mjs → xml-CYseDztH.mjs} +5 -5
  307. package/{xml-B1JIGLpU.mjs.map → xml-CYseDztH.mjs.map} +1 -1
  308. package/{xml-fvwTsoRv.cjs → xml-zJul8jMQ.cjs} +5 -5
  309. package/{xml-fvwTsoRv.cjs.map → xml-zJul8jMQ.cjs.map} +1 -1
  310. package/{yaml-1mP4uxdf.mjs → yaml-BPBoiOjx.mjs} +5 -5
  311. package/{yaml-1mP4uxdf.mjs.map → yaml-BPBoiOjx.mjs.map} +1 -1
  312. package/{yaml-DPUTumla.cjs → yaml-D0PzoRAr.cjs} +5 -5
  313. package/{yaml-DPUTumla.cjs.map → yaml-D0PzoRAr.cjs.map} +1 -1
  314. package/artifact_methods-7KatxCSd.cjs +0 -1
  315. package/artifact_methods-q52ETLwI.mjs +0 -1
  316. package/spooled_artifact-BLgbGT8b.cjs.map +0 -1
  317. package/spooled_artifact-BkOe4-j-.mjs.map +0 -1
@@ -1,7 +1,7 @@
1
1
  const require_exceptions = require("./exceptions-DrHnAGQz.cjs");
2
2
  const require_guards = require("./guards-5-XmJgD2.cjs");
3
- const require_tokenizable = require("./tokenizable-DDIdXbJN.cjs");
4
- const require_spooled_artifact = require("./spooled_artifact-BLgbGT8b.cjs");
3
+ const require_tokenizable = require("./tokenizable-BcodRtoW.cjs");
4
+ const require_spooled_artifact = require("./spooled_artifact---DmicFW.cjs");
5
5
  let _nhtio_validation = require("@nhtio/validation");
6
6
  //#region src/lib/classes/retrievable.ts
7
7
  /**
@@ -228,4 +228,4 @@ Object.defineProperty(exports, "Retrievable", {
228
228
  }
229
229
  });
230
230
 
231
- //# sourceMappingURL=retrievable-BBwiACtw.cjs.map
231
+ //# sourceMappingURL=retrievable-Bq-O3k6r.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"retrievable-BBwiACtw.cjs","names":["#id","#content","#trustTier","#source","#kind","#score","#createdAt","#updatedAt","#inline","#artifactConstructor"],"sources":["../src/lib/classes/retrievable.ts"],"sourcesContent":["import { Tokenizable } from './tokenizable'\nimport { validator } from '@nhtio/validation'\nimport { SpooledArtifact } from './spooled_artifact'\nimport { validateOrThrow } from '../utils/validation'\nimport { isInstanceOf, isError } from '../utils/guards'\nimport { ENCODE_METHOD, DECODE_METHOD } from '../utils/encoder_symbols'\nimport { E_INVALID_INITIAL_RETRIEVABLE_VALUE } from '../exceptions/runtime'\nimport { artifactConstructorResolverSchema } from '../contracts/spooled_artifact_constructor'\nimport type { DateTime } from 'luxon'\nimport type { TokenEncoding } from './tokenizable'\nimport type { AdkEncodableSnapshot } from './encodable'\nimport type { ArtifactConstructorResolver } from './tool'\n\n/**\n * Trust-tier discriminator declared by the retrieval middleware at construction time. Drives\n * which envelope the LLM battery wraps the record in.\n *\n * @remarks\n * Vocabulary deliberately mirrors the published security-research taxonomy (\"first-party /\n * third-party\" per *Hidden-in-Plain-Text* WWW '26 and *When AI Meets the Web* IEEE S&P 2026)\n * and explicitly avoids the words \"user\" or \"system\" so the names cannot leak into the model's\n * OpenAI-Model-Spec role-tier authority resolution.\n *\n * - `'first-party'` — deployer-vetted corpora (signed internal docs, policy KBs, curated\n * reference material). Rendered as a `<retrieved_corpus>` parent with per-record nonce-keyed\n * `<retrieved>` children. The label \"first-party\" never appears in the envelope itself.\n * - `'third-party-public'` — open-web scrapes, search results, public APIs. Rendered through\n * the untrusted-content envelope with `kind: 'retrieved-third-party-public'`.\n * - `'third-party-private'` — user uploads, pasted attachments, partner APIs. Rendered through\n * the untrusted-content envelope with `kind: 'retrieved-third-party-private'`.\n */\nexport type RetrievableTrustTier = 'first-party' | 'third-party-public' | 'third-party-private'\n\n/**\n * Plain input object supplied to {@link Retrievable} at construction time.\n *\n * @remarks\n * Validated against `rawRetrievableSchema` before the `Retrievable` instance is created.\n * Temporal fields accept any value that Luxon can parse — ISO strings, Unix timestamps,\n * `Date` objects, or existing `DateTime` instances.\n */\nexport interface RawRetrievable {\n /**\n * Stable unique identifier for this retrieved record. Used as the closing-tag nonce in the\n * rendered envelope, so it must be unguessable from the payload.\n */\n id: string\n /**\n * The retrieved content. A plain `string` or {@link @nhtio/adk!Tokenizable} for small inline text, or a\n * {@link @nhtio/adk!SpooledArtifact} when the extracted text is large and lives in a consumer\n * {@link @nhtio/adk/common!ByteStore} (persist it via {@link @nhtio/adk!DispatchContext.storeRetrievableBytes}, wrap\n * the returned reader in a `SpooledArtifact`, and pass it here). Reader-backed content keeps the\n * body out of the permanent heap, but token estimation and render still materialise it\n * transiently (see {@link Retrievable.estimateTokens}).\n */\n content: string | Tokenizable | SpooledArtifact\n /**\n * Trust tier declared by the retrieval middleware at construction time. Required — there is\n * NO default. The decision must be conscious. See {@link RetrievableTrustTier}.\n */\n trustTier: RetrievableTrustTier\n /** Optional provenance string: URL, document path, knowledge-base id, etc. */\n source?: string\n /** Optional semantic label: 'policy' | 'reference' | 'web-page' | 'pdf' | etc. */\n kind?: string\n /** Optional relevance / similarity score in `[0, 1]` from the retrieval middleware. */\n score?: number\n /** When the source record was created (publication date, upload date, etc.). */\n createdAt: string | number | Date | DateTime\n /** When the source record was last modified. */\n updatedAt: string | number | Date | DateTime\n /** Whether to render this record inline rather than as a retrievable handle; defaults to `false`. */\n inline?: boolean\n /** Resolver for the spooled-artifact constructor used when plain content is auto-spooled; defaults to `undefined` (the base artifact). */\n artifactConstructor?: ArtifactConstructorResolver\n}\n\n/**\n * A fully-resolved {@link RawRetrievable} where all fields have been validated and temporal\n * values normalised to Luxon `DateTime` instances.\n */\ninterface ResolvedRetrievable {\n id: string\n content: Tokenizable | SpooledArtifact\n trustTier: RetrievableTrustTier\n source?: string\n kind?: string\n score?: number\n createdAt: DateTime\n updatedAt: DateTime\n inline: boolean\n artifactConstructor?: ArtifactConstructorResolver\n}\n\n/**\n * Validator schema used to validate a {@link RawRetrievable} before constructing a\n * {@link Retrievable}.\n *\n * @remarks\n * - `id` — required non-empty string.\n * - `content` — required {@link @nhtio/adk!Tokenizable.schema}.\n * - `trustTier` — required, one of `'first-party'`, `'third-party-public'`,\n * `'third-party-private'`. Unknown / missing values reject.\n * - `source` / `kind` — optional strings.\n * - `score` — optional number in `[0, 1]`.\n * - `createdAt` / `updatedAt` — required datetime-parseable values.\n *\n * Throws {@link @nhtio/adk/exceptions!E_INVALID_INITIAL_RETRIEVABLE_VALUE} (via the {@link Retrievable} constructor)\n * when validation fails.\n */\nconst contentSchema = validator.alternatives(\n validator.string(),\n validator.custom((value, helpers) => {\n if (Tokenizable.isTokenizable(value) || SpooledArtifact.isSpooledArtifact(value)) {\n return value\n }\n return helpers.error('any.invalid')\n })\n)\n\nconst rawRetrievableSchema = validator.object<RawRetrievable>({\n id: validator.string().required(),\n content: contentSchema.required(),\n trustTier: validator\n .string()\n .valid('first-party', 'third-party-public', 'third-party-private')\n .required(),\n source: validator.string().optional(),\n kind: validator.string().optional(),\n score: validator.number().min(0).max(1).optional(),\n createdAt: validator.datetime().required(),\n updatedAt: validator.datetime().required(),\n inline: validator.boolean().default(false),\n artifactConstructor: artifactConstructorResolverSchema().optional(),\n})\n\n/**\n * An immutable, validated retrieved record (RAG content) held by the agent.\n *\n * @remarks\n * Peer of {@link @nhtio/adk!Memory} / `Message` / `Thought` / `ToolCall`. Carries an explicit `trustTier`\n * that LLM batteries branch on to choose the rendering envelope. The retrieval middleware that\n * produced the record is the only party that knows its provenance — batteries MUST NOT\n * auto-classify or infer the tier from `source`.\n */\nexport class Retrievable {\n /**\n * Validator schema that accepts a {@link RawRetrievable} object.\n *\n * @remarks\n * Reusable fragment for any schema that needs to validate or nest a retrievable record.\n */\n public static schema = rawRetrievableSchema\n\n /**\n * Returns `true` if `value` is a {@link Retrievable} instance.\n *\n * @remarks\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety.\n */\n public static isRetrievable(value: unknown): value is Retrievable {\n return isInstanceOf(value, 'Retrievable', Retrievable)\n }\n\n /** Stable unique identifier for this retrieved record. */\n declare readonly id: string\n /**\n * The retrieved content: a {@link @nhtio/adk!Tokenizable} (inline text) or a\n * {@link @nhtio/adk!SpooledArtifact} (reader-backed, large text living in a consumer store). Use\n * {@link Retrievable.estimateTokens} for budgeting and {@link Retrievable.contentString} to\n * materialise the body at render time.\n */\n declare readonly content: Tokenizable | SpooledArtifact\n /** Trust tier declared by the retrieval middleware. */\n declare readonly trustTier: RetrievableTrustTier\n /** Optional provenance string. */\n declare readonly source: string | undefined\n /** Optional semantic label. */\n declare readonly kind: string | undefined\n /** Optional relevance / similarity score in `[0, 1]`. */\n declare readonly score: number | undefined\n /** When the source record was created. */\n declare readonly createdAt: DateTime\n /** When the source record was last modified. */\n declare readonly updatedAt: DateTime\n /** Whether this record is rendered inline; defaults to `false` (handle mode for spooled content). */\n declare readonly inline: boolean\n /** Producer-declared resolver for the artifact subclass used during auto-spooling, if any. */\n declare readonly artifactConstructor: ArtifactConstructorResolver | undefined\n /** Whether a non-inline spooled artifact lacks cached size metadata. */\n declare readonly sizeUnknown: boolean\n\n #id: string\n #content: Tokenizable | SpooledArtifact\n #trustTier: RetrievableTrustTier\n #source: string | undefined\n #kind: string | undefined\n #score: number | undefined\n #createdAt: DateTime\n #updatedAt: DateTime\n #inline: boolean\n #artifactConstructor: ArtifactConstructorResolver | undefined\n\n /**\n * @param raw - The raw retrievable input validated against `rawRetrievableSchema`.\n * @throws {@link @nhtio/adk/exceptions!E_INVALID_INITIAL_RETRIEVABLE_VALUE} when `raw` does not satisfy the schema.\n */\n constructor(raw: RawRetrievable) {\n let resolved: ResolvedRetrievable\n try {\n resolved = validateOrThrow<ResolvedRetrievable>(rawRetrievableSchema, raw, true)\n } catch (err) {\n throw new E_INVALID_INITIAL_RETRIEVABLE_VALUE({\n cause: isError(err) ? err : undefined,\n })\n }\n this.#id = resolved.id\n this.#content =\n Tokenizable.isTokenizable(resolved.content) ||\n SpooledArtifact.isSpooledArtifact(resolved.content)\n ? resolved.content\n : new Tokenizable(resolved.content)\n this.#trustTier = resolved.trustTier\n this.#source = resolved.source\n this.#kind = resolved.kind\n this.#score = resolved.score\n this.#createdAt = resolved.createdAt\n this.#updatedAt = resolved.updatedAt\n this.#inline = resolved.inline\n this.#artifactConstructor = resolved.artifactConstructor\n\n Object.defineProperties(this, {\n id: {\n get: () => this.#id,\n enumerable: true,\n configurable: false,\n },\n content: {\n get: () => this.#content,\n enumerable: true,\n configurable: false,\n },\n trustTier: {\n get: () => this.#trustTier,\n enumerable: true,\n configurable: false,\n },\n source: {\n get: () => this.#source,\n enumerable: true,\n configurable: false,\n },\n kind: {\n get: () => this.#kind,\n enumerable: true,\n configurable: false,\n },\n score: {\n get: () => this.#score,\n enumerable: true,\n configurable: false,\n },\n createdAt: {\n get: () => this.#createdAt,\n enumerable: true,\n configurable: false,\n },\n updatedAt: {\n get: () => this.#updatedAt,\n enumerable: true,\n configurable: false,\n },\n inline: {\n get: () => this.#inline,\n enumerable: true,\n configurable: false,\n },\n artifactConstructor: {\n get: () => this.#artifactConstructor,\n enumerable: true,\n configurable: false,\n },\n sizeUnknown: {\n get: () =>\n SpooledArtifact.isSpooledArtifact(this.#content) &&\n !this.#inline &&\n !this.#content.hasSizeHints(),\n enumerable: true,\n configurable: false,\n },\n })\n }\n\n /**\n * Estimates the token count of the content under `encoding`.\n *\n * @remarks\n * Delegates to the content's own `estimateTokens`: synchronous for a {@link @nhtio/adk!Tokenizable}\n * (returns `number`), asynchronous for a {@link @nhtio/adk!SpooledArtifact} (returns\n * `Promise<number>`, reading the bytes from the backing store on demand). Both shapes satisfy the\n * adapter's token-budget path, which already awaits estimates.\n *\n * Note: the `SpooledArtifact` branch materialises the full decoded string transiently to count\n * tokens — reader-backing keeps the body off the *permanent* heap, but does not eliminate the\n * transient allocation at budgeting time.\n *\n * @param encoding - The encoding identifier to use for counting.\n * @returns The estimated token count.\n */\n estimateTokens(encoding: TokenEncoding): number | Promise<number> {\n if (\n SpooledArtifact.isSpooledArtifact(this.#content) &&\n !this.#inline &&\n this.#content.hasSizeHints()\n ) {\n return this.#content.estimateHandleTokens(this.#id, encoding)\n }\n return this.#content.estimateTokens(encoding)\n }\n\n /**\n * Returns the content body as a single string.\n *\n * @remarks\n * For a {@link @nhtio/adk!Tokenizable} this is synchronous in effect (resolved immediately); for a\n * {@link @nhtio/adk!SpooledArtifact} it reads the full body from the backing store via\n * {@link @nhtio/adk!SpooledArtifact.asString}. Always returns a `Promise` so callers have one\n * code path; render helpers `await` it at the point the trust-tier envelope is built.\n *\n * @returns The full content body as a string.\n */\n async contentString(): Promise<string> {\n return SpooledArtifact.isSpooledArtifact(this.#content)\n ? this.#content.asString()\n : this.#content.toString()\n }\n\n /**\n * Serialise this Retrievable into an `@nhtio/encoder` snapshot.\n *\n * @remarks\n * Emits a {@link RawRetrievable}-shaped object; `content` is the live {@link @nhtio/adk!Tokenizable} or\n * {@link @nhtio/adk!SpooledArtifact} (the encoder recurses — a reader-backed artifact round-trips as a\n * handle, throwing {@link @nhtio/adk!E_READER_NOT_DESCRIBABLE} if its reader cannot describe itself).\n * Round-trips via {@link Retrievable.[DECODE_METHOD]}, which re-validates through the constructor.\n *\n * @returns A {@link RawRetrievable}-shaped snapshot.\n */\n [ENCODE_METHOD](): AdkEncodableSnapshot {\n return {\n id: this.#id,\n content: this.#content,\n trustTier: this.#trustTier,\n source: this.#source,\n kind: this.#kind,\n score: this.#score,\n createdAt: this.#createdAt,\n updatedAt: this.#updatedAt,\n inline: this.#inline,\n artifactConstructor: this.#artifactConstructor,\n }\n }\n\n /**\n * Reconstruct a {@link Retrievable} from a {@link Retrievable.[ENCODE_METHOD]} snapshot.\n *\n * @param data - The snapshot produced by {@link Retrievable.[ENCODE_METHOD]}.\n * @returns A fully-validated {@link Retrievable}.\n */\n static [DECODE_METHOD](data: AdkEncodableSnapshot): Retrievable {\n return new Retrievable(data as RawRetrievable)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA8GA,IAAM,gBAAgB,kBAAA,UAAU,aAC9B,kBAAA,UAAU,OAAO,GACjB,kBAAA,UAAU,QAAQ,OAAO,YAAY;CACnC,IAAI,oBAAA,YAAY,cAAc,KAAK,KAAK,yBAAA,gBAAgB,kBAAkB,KAAK,GAC7E,OAAO;CAET,OAAO,QAAQ,MAAM,aAAa;AACpC,CAAC,CACH;AAEA,IAAM,uBAAuB,kBAAA,UAAU,OAAuB;CAC5D,IAAI,kBAAA,UAAU,OAAO,EAAE,SAAS;CAChC,SAAS,cAAc,SAAS;CAChC,WAAW,kBAAA,UACR,OAAO,EACP,MAAM,eAAe,sBAAsB,qBAAqB,EAChE,SAAS;CACZ,QAAQ,kBAAA,UAAU,OAAO,EAAE,SAAS;CACpC,MAAM,kBAAA,UAAU,OAAO,EAAE,SAAS;CAClC,OAAO,kBAAA,UAAU,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;CACjD,WAAW,kBAAA,UAAU,SAAS,EAAE,SAAS;CACzC,WAAW,kBAAA,UAAU,SAAS,EAAE,SAAS;CACzC,QAAQ,kBAAA,UAAU,QAAQ,EAAE,QAAQ,KAAK;CACzC,qBAAqB,yBAAA,kCAAkC,EAAE,SAAS;AACpE,CAAC;;;;;;;;;;AAWD,IAAa,cAAb,MAAa,YAAY;;;;;;;CAOvB,OAAc,SAAS;;;;;;;CAQvB,OAAc,cAAc,OAAsC;EAChE,OAAO,eAAA,aAAa,OAAO,eAAe,WAAW;CACvD;CA8BA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;;;;;CAMA,YAAY,KAAqB;EAC/B,IAAI;EACJ,IAAI;GACF,WAAW,mBAAA,gBAAqC,sBAAsB,KAAK,IAAI;EACjF,SAAS,KAAK;GACZ,MAAM,IAAI,oBAAA,oCAAoC,EAC5C,OAAO,eAAA,QAAQ,GAAG,IAAI,MAAM,KAAA,EAC9B,CAAC;EACH;EACA,KAAKA,MAAM,SAAS;EACpB,KAAKC,WACH,oBAAA,YAAY,cAAc,SAAS,OAAO,KAC1C,yBAAA,gBAAgB,kBAAkB,SAAS,OAAO,IAC9C,SAAS,UACT,IAAI,oBAAA,YAAY,SAAS,OAAO;EACtC,KAAKC,aAAa,SAAS;EAC3B,KAAKC,UAAU,SAAS;EACxB,KAAKC,QAAQ,SAAS;EACtB,KAAKC,SAAS,SAAS;EACvB,KAAKC,aAAa,SAAS;EAC3B,KAAKC,aAAa,SAAS;EAC3B,KAAKC,UAAU,SAAS;EACxB,KAAKC,uBAAuB,SAAS;EAErC,OAAO,iBAAiB,MAAM;GAC5B,IAAI;IACF,WAAW,KAAKT;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,SAAS;IACP,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,WAAW;IACT,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,QAAQ;IACN,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,MAAM;IACJ,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,OAAO;IACL,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,WAAW;IACT,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,WAAW;IACT,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,QAAQ;IACN,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,qBAAqB;IACnB,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,aAAa;IACX,WACE,yBAAA,gBAAgB,kBAAkB,KAAKR,QAAQ,KAC/C,CAAC,KAAKO,WACN,CAAC,KAAKP,SAAS,aAAa;IAC9B,YAAY;IACZ,cAAc;GAChB;EACF,CAAC;CACH;;;;;;;;;;;;;;;;;CAkBA,eAAe,UAAmD;EAChE,IACE,yBAAA,gBAAgB,kBAAkB,KAAKA,QAAQ,KAC/C,CAAC,KAAKO,WACN,KAAKP,SAAS,aAAa,GAE3B,OAAO,KAAKA,SAAS,qBAAqB,KAAKD,KAAK,QAAQ;EAE9D,OAAO,KAAKC,SAAS,eAAe,QAAQ;CAC9C;;;;;;;;;;;;CAaA,MAAM,gBAAiC;EACrC,OAAO,yBAAA,gBAAgB,kBAAkB,KAAKA,QAAQ,IAClD,KAAKA,SAAS,SAAS,IACvB,KAAKA,SAAS,SAAS;CAC7B;;;;;;;;;;;;CAaA,CAAC,oBAAA,iBAAuC;EACtC,OAAO;GACL,IAAI,KAAKD;GACT,SAAS,KAAKC;GACd,WAAW,KAAKC;GAChB,QAAQ,KAAKC;GACb,MAAM,KAAKC;GACX,OAAO,KAAKC;GACZ,WAAW,KAAKC;GAChB,WAAW,KAAKC;GAChB,QAAQ,KAAKC;GACb,qBAAqB,KAAKC;EAC5B;CACF;;;;;;;CAQA,QAAQ,oBAAA,eAAe,MAAyC;EAC9D,OAAO,IAAI,YAAY,IAAsB;CAC/C;AACF"}
1
+ {"version":3,"file":"retrievable-Bq-O3k6r.cjs","names":["#id","#content","#trustTier","#source","#kind","#score","#createdAt","#updatedAt","#inline","#artifactConstructor"],"sources":["../src/lib/classes/retrievable.ts"],"sourcesContent":["import { Tokenizable } from './tokenizable'\nimport { validator } from '@nhtio/validation'\nimport { SpooledArtifact } from './spooled_artifact'\nimport { validateOrThrow } from '../utils/validation'\nimport { isInstanceOf, isError } from '../utils/guards'\nimport { ENCODE_METHOD, DECODE_METHOD } from '../utils/encoder_symbols'\nimport { E_INVALID_INITIAL_RETRIEVABLE_VALUE } from '../exceptions/runtime'\nimport { artifactConstructorResolverSchema } from '../contracts/spooled_artifact_constructor'\nimport type { DateTime } from 'luxon'\nimport type { TokenEncoding } from './tokenizable'\nimport type { AdkEncodableSnapshot } from './encodable'\nimport type { ArtifactConstructorResolver } from './tool'\n\n/**\n * Trust-tier discriminator declared by the retrieval middleware at construction time. Drives\n * which envelope the LLM battery wraps the record in.\n *\n * @remarks\n * Vocabulary deliberately mirrors the published security-research taxonomy (\"first-party /\n * third-party\" per *Hidden-in-Plain-Text* WWW '26 and *When AI Meets the Web* IEEE S&P 2026)\n * and explicitly avoids the words \"user\" or \"system\" so the names cannot leak into the model's\n * OpenAI-Model-Spec role-tier authority resolution.\n *\n * - `'first-party'` — deployer-vetted corpora (signed internal docs, policy KBs, curated\n * reference material). Rendered as a `<retrieved_corpus>` parent with per-record nonce-keyed\n * `<retrieved>` children. The label \"first-party\" never appears in the envelope itself.\n * - `'third-party-public'` — open-web scrapes, search results, public APIs. Rendered through\n * the untrusted-content envelope with `kind: 'retrieved-third-party-public'`.\n * - `'third-party-private'` — user uploads, pasted attachments, partner APIs. Rendered through\n * the untrusted-content envelope with `kind: 'retrieved-third-party-private'`.\n */\nexport type RetrievableTrustTier = 'first-party' | 'third-party-public' | 'third-party-private'\n\n/**\n * Plain input object supplied to {@link Retrievable} at construction time.\n *\n * @remarks\n * Validated against `rawRetrievableSchema` before the `Retrievable` instance is created.\n * Temporal fields accept any value that Luxon can parse — ISO strings, Unix timestamps,\n * `Date` objects, or existing `DateTime` instances.\n */\nexport interface RawRetrievable {\n /**\n * Stable unique identifier for this retrieved record. Used as the closing-tag nonce in the\n * rendered envelope, so it must be unguessable from the payload.\n */\n id: string\n /**\n * The retrieved content. A plain `string` or {@link @nhtio/adk!Tokenizable} for small inline text, or a\n * {@link @nhtio/adk!SpooledArtifact} when the extracted text is large and lives in a consumer\n * {@link @nhtio/adk/common!ByteStore} (persist it via {@link @nhtio/adk!DispatchContext.storeRetrievableBytes}, wrap\n * the returned reader in a `SpooledArtifact`, and pass it here). Reader-backed content keeps the\n * body out of the permanent heap, but token estimation and render still materialise it\n * transiently (see {@link Retrievable.estimateTokens}).\n */\n content: string | Tokenizable | SpooledArtifact\n /**\n * Trust tier declared by the retrieval middleware at construction time. Required — there is\n * NO default. The decision must be conscious. See {@link RetrievableTrustTier}.\n */\n trustTier: RetrievableTrustTier\n /** Optional provenance string: URL, document path, knowledge-base id, etc. */\n source?: string\n /** Optional semantic label: 'policy' | 'reference' | 'web-page' | 'pdf' | etc. */\n kind?: string\n /** Optional relevance / similarity score in `[0, 1]` from the retrieval middleware. */\n score?: number\n /** When the source record was created (publication date, upload date, etc.). */\n createdAt: string | number | Date | DateTime\n /** When the source record was last modified. */\n updatedAt: string | number | Date | DateTime\n /** Whether to render this record inline rather than as a retrievable handle; defaults to `false`. */\n inline?: boolean\n /** Resolver for the spooled-artifact constructor used when plain content is auto-spooled; defaults to `undefined` (the base artifact). */\n artifactConstructor?: ArtifactConstructorResolver\n}\n\n/**\n * A fully-resolved {@link RawRetrievable} where all fields have been validated and temporal\n * values normalised to Luxon `DateTime` instances.\n */\ninterface ResolvedRetrievable {\n id: string\n content: Tokenizable | SpooledArtifact\n trustTier: RetrievableTrustTier\n source?: string\n kind?: string\n score?: number\n createdAt: DateTime\n updatedAt: DateTime\n inline: boolean\n artifactConstructor?: ArtifactConstructorResolver\n}\n\n/**\n * Validator schema used to validate a {@link RawRetrievable} before constructing a\n * {@link Retrievable}.\n *\n * @remarks\n * - `id` — required non-empty string.\n * - `content` — required {@link @nhtio/adk!Tokenizable.schema}.\n * - `trustTier` — required, one of `'first-party'`, `'third-party-public'`,\n * `'third-party-private'`. Unknown / missing values reject.\n * - `source` / `kind` — optional strings.\n * - `score` — optional number in `[0, 1]`.\n * - `createdAt` / `updatedAt` — required datetime-parseable values.\n *\n * Throws {@link @nhtio/adk/exceptions!E_INVALID_INITIAL_RETRIEVABLE_VALUE} (via the {@link Retrievable} constructor)\n * when validation fails.\n */\nconst contentSchema = validator.alternatives(\n validator.string(),\n validator.custom((value, helpers) => {\n if (Tokenizable.isTokenizable(value) || SpooledArtifact.isSpooledArtifact(value)) {\n return value\n }\n return helpers.error('any.invalid')\n })\n)\n\nconst rawRetrievableSchema = validator.object<RawRetrievable>({\n id: validator.string().required(),\n content: contentSchema.required(),\n trustTier: validator\n .string()\n .valid('first-party', 'third-party-public', 'third-party-private')\n .required(),\n source: validator.string().optional(),\n kind: validator.string().optional(),\n score: validator.number().min(0).max(1).optional(),\n createdAt: validator.datetime().required(),\n updatedAt: validator.datetime().required(),\n inline: validator.boolean().default(false),\n artifactConstructor: artifactConstructorResolverSchema().optional(),\n})\n\n/**\n * An immutable, validated retrieved record (RAG content) held by the agent.\n *\n * @remarks\n * Peer of {@link @nhtio/adk!Memory} / `Message` / `Thought` / `ToolCall`. Carries an explicit `trustTier`\n * that LLM batteries branch on to choose the rendering envelope. The retrieval middleware that\n * produced the record is the only party that knows its provenance — batteries MUST NOT\n * auto-classify or infer the tier from `source`.\n */\nexport class Retrievable {\n /**\n * Validator schema that accepts a {@link RawRetrievable} object.\n *\n * @remarks\n * Reusable fragment for any schema that needs to validate or nest a retrievable record.\n */\n public static schema = rawRetrievableSchema\n\n /**\n * Returns `true` if `value` is a {@link Retrievable} instance.\n *\n * @remarks\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety.\n */\n public static isRetrievable(value: unknown): value is Retrievable {\n return isInstanceOf(value, 'Retrievable', Retrievable)\n }\n\n /** Stable unique identifier for this retrieved record. */\n declare readonly id: string\n /**\n * The retrieved content: a {@link @nhtio/adk!Tokenizable} (inline text) or a\n * {@link @nhtio/adk!SpooledArtifact} (reader-backed, large text living in a consumer store). Use\n * {@link Retrievable.estimateTokens} for budgeting and {@link Retrievable.contentString} to\n * materialise the body at render time.\n */\n declare readonly content: Tokenizable | SpooledArtifact\n /** Trust tier declared by the retrieval middleware. */\n declare readonly trustTier: RetrievableTrustTier\n /** Optional provenance string. */\n declare readonly source: string | undefined\n /** Optional semantic label. */\n declare readonly kind: string | undefined\n /** Optional relevance / similarity score in `[0, 1]`. */\n declare readonly score: number | undefined\n /** When the source record was created. */\n declare readonly createdAt: DateTime\n /** When the source record was last modified. */\n declare readonly updatedAt: DateTime\n /** Whether this record is rendered inline; defaults to `false` (handle mode for spooled content). */\n declare readonly inline: boolean\n /** Producer-declared resolver for the artifact subclass used during auto-spooling, if any. */\n declare readonly artifactConstructor: ArtifactConstructorResolver | undefined\n /** Whether a non-inline spooled artifact lacks cached size metadata. */\n declare readonly sizeUnknown: boolean\n\n #id: string\n #content: Tokenizable | SpooledArtifact\n #trustTier: RetrievableTrustTier\n #source: string | undefined\n #kind: string | undefined\n #score: number | undefined\n #createdAt: DateTime\n #updatedAt: DateTime\n #inline: boolean\n #artifactConstructor: ArtifactConstructorResolver | undefined\n\n /**\n * @param raw - The raw retrievable input validated against `rawRetrievableSchema`.\n * @throws {@link @nhtio/adk/exceptions!E_INVALID_INITIAL_RETRIEVABLE_VALUE} when `raw` does not satisfy the schema.\n */\n constructor(raw: RawRetrievable) {\n let resolved: ResolvedRetrievable\n try {\n resolved = validateOrThrow<ResolvedRetrievable>(rawRetrievableSchema, raw, true)\n } catch (err) {\n throw new E_INVALID_INITIAL_RETRIEVABLE_VALUE({\n cause: isError(err) ? err : undefined,\n })\n }\n this.#id = resolved.id\n this.#content =\n Tokenizable.isTokenizable(resolved.content) ||\n SpooledArtifact.isSpooledArtifact(resolved.content)\n ? resolved.content\n : new Tokenizable(resolved.content)\n this.#trustTier = resolved.trustTier\n this.#source = resolved.source\n this.#kind = resolved.kind\n this.#score = resolved.score\n this.#createdAt = resolved.createdAt\n this.#updatedAt = resolved.updatedAt\n this.#inline = resolved.inline\n this.#artifactConstructor = resolved.artifactConstructor\n\n Object.defineProperties(this, {\n id: {\n get: () => this.#id,\n enumerable: true,\n configurable: false,\n },\n content: {\n get: () => this.#content,\n enumerable: true,\n configurable: false,\n },\n trustTier: {\n get: () => this.#trustTier,\n enumerable: true,\n configurable: false,\n },\n source: {\n get: () => this.#source,\n enumerable: true,\n configurable: false,\n },\n kind: {\n get: () => this.#kind,\n enumerable: true,\n configurable: false,\n },\n score: {\n get: () => this.#score,\n enumerable: true,\n configurable: false,\n },\n createdAt: {\n get: () => this.#createdAt,\n enumerable: true,\n configurable: false,\n },\n updatedAt: {\n get: () => this.#updatedAt,\n enumerable: true,\n configurable: false,\n },\n inline: {\n get: () => this.#inline,\n enumerable: true,\n configurable: false,\n },\n artifactConstructor: {\n get: () => this.#artifactConstructor,\n enumerable: true,\n configurable: false,\n },\n sizeUnknown: {\n get: () =>\n SpooledArtifact.isSpooledArtifact(this.#content) &&\n !this.#inline &&\n !this.#content.hasSizeHints(),\n enumerable: true,\n configurable: false,\n },\n })\n }\n\n /**\n * Estimates the token count of the content under `encoding`.\n *\n * @remarks\n * Delegates to the content's own `estimateTokens`: synchronous for a {@link @nhtio/adk!Tokenizable}\n * (returns `number`), asynchronous for a {@link @nhtio/adk!SpooledArtifact} (returns\n * `Promise<number>`, reading the bytes from the backing store on demand). Both shapes satisfy the\n * adapter's token-budget path, which already awaits estimates.\n *\n * Note: the `SpooledArtifact` branch materialises the full decoded string transiently to count\n * tokens — reader-backing keeps the body off the *permanent* heap, but does not eliminate the\n * transient allocation at budgeting time.\n *\n * @param encoding - The encoding identifier to use for counting.\n * @returns The estimated token count.\n */\n estimateTokens(encoding: TokenEncoding): number | Promise<number> {\n if (\n SpooledArtifact.isSpooledArtifact(this.#content) &&\n !this.#inline &&\n this.#content.hasSizeHints()\n ) {\n return this.#content.estimateHandleTokens(this.#id, encoding)\n }\n return this.#content.estimateTokens(encoding)\n }\n\n /**\n * Returns the content body as a single string.\n *\n * @remarks\n * For a {@link @nhtio/adk!Tokenizable} this is synchronous in effect (resolved immediately); for a\n * {@link @nhtio/adk!SpooledArtifact} it reads the full body from the backing store via\n * {@link @nhtio/adk!SpooledArtifact.asString}. Always returns a `Promise` so callers have one\n * code path; render helpers `await` it at the point the trust-tier envelope is built.\n *\n * @returns The full content body as a string.\n */\n async contentString(): Promise<string> {\n return SpooledArtifact.isSpooledArtifact(this.#content)\n ? this.#content.asString()\n : this.#content.toString()\n }\n\n /**\n * Serialise this Retrievable into an `@nhtio/encoder` snapshot.\n *\n * @remarks\n * Emits a {@link RawRetrievable}-shaped object; `content` is the live {@link @nhtio/adk!Tokenizable} or\n * {@link @nhtio/adk!SpooledArtifact} (the encoder recurses — a reader-backed artifact round-trips as a\n * handle, throwing {@link @nhtio/adk!E_READER_NOT_DESCRIBABLE} if its reader cannot describe itself).\n * Round-trips via {@link Retrievable.[DECODE_METHOD]}, which re-validates through the constructor.\n *\n * @returns A {@link RawRetrievable}-shaped snapshot.\n */\n [ENCODE_METHOD](): AdkEncodableSnapshot {\n return {\n id: this.#id,\n content: this.#content,\n trustTier: this.#trustTier,\n source: this.#source,\n kind: this.#kind,\n score: this.#score,\n createdAt: this.#createdAt,\n updatedAt: this.#updatedAt,\n inline: this.#inline,\n artifactConstructor: this.#artifactConstructor,\n }\n }\n\n /**\n * Reconstruct a {@link Retrievable} from a {@link Retrievable.[ENCODE_METHOD]} snapshot.\n *\n * @param data - The snapshot produced by {@link Retrievable.[ENCODE_METHOD]}.\n * @returns A fully-validated {@link Retrievable}.\n */\n static [DECODE_METHOD](data: AdkEncodableSnapshot): Retrievable {\n return new Retrievable(data as RawRetrievable)\n }\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { o as validateOrThrow } from "./exceptions-DRYLe-J4.mjs";
2
2
  import { n as isInstanceOf, t as isError } from "./guards-BEpY7lBI.mjs";
3
- import { g as E_INVALID_INITIAL_RETRIEVABLE_VALUE, o as DECODE_METHOD, r as Tokenizable, s as ENCODE_METHOD } from "./tokenizable-xPXj1AQX.mjs";
4
- import { p as artifactConstructorResolverSchema, t as SpooledArtifact } from "./spooled_artifact-BkOe4-j-.mjs";
3
+ import { B as ENCODE_METHOD, m as E_INVALID_INITIAL_RETRIEVABLE_VALUE, r as Tokenizable, z as DECODE_METHOD } from "./tokenizable-VB4Av8GF.mjs";
4
+ import { m as artifactConstructorResolverSchema, t as SpooledArtifact } from "./spooled_artifact-Bw_7swIp.mjs";
5
5
  import { validator } from "@nhtio/validation";
6
6
  //#region src/lib/classes/retrievable.ts
7
7
  /**
@@ -223,4 +223,4 @@ var Retrievable = class Retrievable {
223
223
  //#endregion
224
224
  export { Retrievable as t };
225
225
 
226
- //# sourceMappingURL=retrievable-CrGKx4sc.mjs.map
226
+ //# sourceMappingURL=retrievable-CXTAUuuv.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"retrievable-CrGKx4sc.mjs","names":["#id","#content","#trustTier","#source","#kind","#score","#createdAt","#updatedAt","#inline","#artifactConstructor"],"sources":["../src/lib/classes/retrievable.ts"],"sourcesContent":["import { Tokenizable } from './tokenizable'\nimport { validator } from '@nhtio/validation'\nimport { SpooledArtifact } from './spooled_artifact'\nimport { validateOrThrow } from '../utils/validation'\nimport { isInstanceOf, isError } from '../utils/guards'\nimport { ENCODE_METHOD, DECODE_METHOD } from '../utils/encoder_symbols'\nimport { E_INVALID_INITIAL_RETRIEVABLE_VALUE } from '../exceptions/runtime'\nimport { artifactConstructorResolverSchema } from '../contracts/spooled_artifact_constructor'\nimport type { DateTime } from 'luxon'\nimport type { TokenEncoding } from './tokenizable'\nimport type { AdkEncodableSnapshot } from './encodable'\nimport type { ArtifactConstructorResolver } from './tool'\n\n/**\n * Trust-tier discriminator declared by the retrieval middleware at construction time. Drives\n * which envelope the LLM battery wraps the record in.\n *\n * @remarks\n * Vocabulary deliberately mirrors the published security-research taxonomy (\"first-party /\n * third-party\" per *Hidden-in-Plain-Text* WWW '26 and *When AI Meets the Web* IEEE S&P 2026)\n * and explicitly avoids the words \"user\" or \"system\" so the names cannot leak into the model's\n * OpenAI-Model-Spec role-tier authority resolution.\n *\n * - `'first-party'` — deployer-vetted corpora (signed internal docs, policy KBs, curated\n * reference material). Rendered as a `<retrieved_corpus>` parent with per-record nonce-keyed\n * `<retrieved>` children. The label \"first-party\" never appears in the envelope itself.\n * - `'third-party-public'` — open-web scrapes, search results, public APIs. Rendered through\n * the untrusted-content envelope with `kind: 'retrieved-third-party-public'`.\n * - `'third-party-private'` — user uploads, pasted attachments, partner APIs. Rendered through\n * the untrusted-content envelope with `kind: 'retrieved-third-party-private'`.\n */\nexport type RetrievableTrustTier = 'first-party' | 'third-party-public' | 'third-party-private'\n\n/**\n * Plain input object supplied to {@link Retrievable} at construction time.\n *\n * @remarks\n * Validated against `rawRetrievableSchema` before the `Retrievable` instance is created.\n * Temporal fields accept any value that Luxon can parse — ISO strings, Unix timestamps,\n * `Date` objects, or existing `DateTime` instances.\n */\nexport interface RawRetrievable {\n /**\n * Stable unique identifier for this retrieved record. Used as the closing-tag nonce in the\n * rendered envelope, so it must be unguessable from the payload.\n */\n id: string\n /**\n * The retrieved content. A plain `string` or {@link @nhtio/adk!Tokenizable} for small inline text, or a\n * {@link @nhtio/adk!SpooledArtifact} when the extracted text is large and lives in a consumer\n * {@link @nhtio/adk/common!ByteStore} (persist it via {@link @nhtio/adk!DispatchContext.storeRetrievableBytes}, wrap\n * the returned reader in a `SpooledArtifact`, and pass it here). Reader-backed content keeps the\n * body out of the permanent heap, but token estimation and render still materialise it\n * transiently (see {@link Retrievable.estimateTokens}).\n */\n content: string | Tokenizable | SpooledArtifact\n /**\n * Trust tier declared by the retrieval middleware at construction time. Required — there is\n * NO default. The decision must be conscious. See {@link RetrievableTrustTier}.\n */\n trustTier: RetrievableTrustTier\n /** Optional provenance string: URL, document path, knowledge-base id, etc. */\n source?: string\n /** Optional semantic label: 'policy' | 'reference' | 'web-page' | 'pdf' | etc. */\n kind?: string\n /** Optional relevance / similarity score in `[0, 1]` from the retrieval middleware. */\n score?: number\n /** When the source record was created (publication date, upload date, etc.). */\n createdAt: string | number | Date | DateTime\n /** When the source record was last modified. */\n updatedAt: string | number | Date | DateTime\n /** Whether to render this record inline rather than as a retrievable handle; defaults to `false`. */\n inline?: boolean\n /** Resolver for the spooled-artifact constructor used when plain content is auto-spooled; defaults to `undefined` (the base artifact). */\n artifactConstructor?: ArtifactConstructorResolver\n}\n\n/**\n * A fully-resolved {@link RawRetrievable} where all fields have been validated and temporal\n * values normalised to Luxon `DateTime` instances.\n */\ninterface ResolvedRetrievable {\n id: string\n content: Tokenizable | SpooledArtifact\n trustTier: RetrievableTrustTier\n source?: string\n kind?: string\n score?: number\n createdAt: DateTime\n updatedAt: DateTime\n inline: boolean\n artifactConstructor?: ArtifactConstructorResolver\n}\n\n/**\n * Validator schema used to validate a {@link RawRetrievable} before constructing a\n * {@link Retrievable}.\n *\n * @remarks\n * - `id` — required non-empty string.\n * - `content` — required {@link @nhtio/adk!Tokenizable.schema}.\n * - `trustTier` — required, one of `'first-party'`, `'third-party-public'`,\n * `'third-party-private'`. Unknown / missing values reject.\n * - `source` / `kind` — optional strings.\n * - `score` — optional number in `[0, 1]`.\n * - `createdAt` / `updatedAt` — required datetime-parseable values.\n *\n * Throws {@link @nhtio/adk/exceptions!E_INVALID_INITIAL_RETRIEVABLE_VALUE} (via the {@link Retrievable} constructor)\n * when validation fails.\n */\nconst contentSchema = validator.alternatives(\n validator.string(),\n validator.custom((value, helpers) => {\n if (Tokenizable.isTokenizable(value) || SpooledArtifact.isSpooledArtifact(value)) {\n return value\n }\n return helpers.error('any.invalid')\n })\n)\n\nconst rawRetrievableSchema = validator.object<RawRetrievable>({\n id: validator.string().required(),\n content: contentSchema.required(),\n trustTier: validator\n .string()\n .valid('first-party', 'third-party-public', 'third-party-private')\n .required(),\n source: validator.string().optional(),\n kind: validator.string().optional(),\n score: validator.number().min(0).max(1).optional(),\n createdAt: validator.datetime().required(),\n updatedAt: validator.datetime().required(),\n inline: validator.boolean().default(false),\n artifactConstructor: artifactConstructorResolverSchema().optional(),\n})\n\n/**\n * An immutable, validated retrieved record (RAG content) held by the agent.\n *\n * @remarks\n * Peer of {@link @nhtio/adk!Memory} / `Message` / `Thought` / `ToolCall`. Carries an explicit `trustTier`\n * that LLM batteries branch on to choose the rendering envelope. The retrieval middleware that\n * produced the record is the only party that knows its provenance — batteries MUST NOT\n * auto-classify or infer the tier from `source`.\n */\nexport class Retrievable {\n /**\n * Validator schema that accepts a {@link RawRetrievable} object.\n *\n * @remarks\n * Reusable fragment for any schema that needs to validate or nest a retrievable record.\n */\n public static schema = rawRetrievableSchema\n\n /**\n * Returns `true` if `value` is a {@link Retrievable} instance.\n *\n * @remarks\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety.\n */\n public static isRetrievable(value: unknown): value is Retrievable {\n return isInstanceOf(value, 'Retrievable', Retrievable)\n }\n\n /** Stable unique identifier for this retrieved record. */\n declare readonly id: string\n /**\n * The retrieved content: a {@link @nhtio/adk!Tokenizable} (inline text) or a\n * {@link @nhtio/adk!SpooledArtifact} (reader-backed, large text living in a consumer store). Use\n * {@link Retrievable.estimateTokens} for budgeting and {@link Retrievable.contentString} to\n * materialise the body at render time.\n */\n declare readonly content: Tokenizable | SpooledArtifact\n /** Trust tier declared by the retrieval middleware. */\n declare readonly trustTier: RetrievableTrustTier\n /** Optional provenance string. */\n declare readonly source: string | undefined\n /** Optional semantic label. */\n declare readonly kind: string | undefined\n /** Optional relevance / similarity score in `[0, 1]`. */\n declare readonly score: number | undefined\n /** When the source record was created. */\n declare readonly createdAt: DateTime\n /** When the source record was last modified. */\n declare readonly updatedAt: DateTime\n /** Whether this record is rendered inline; defaults to `false` (handle mode for spooled content). */\n declare readonly inline: boolean\n /** Producer-declared resolver for the artifact subclass used during auto-spooling, if any. */\n declare readonly artifactConstructor: ArtifactConstructorResolver | undefined\n /** Whether a non-inline spooled artifact lacks cached size metadata. */\n declare readonly sizeUnknown: boolean\n\n #id: string\n #content: Tokenizable | SpooledArtifact\n #trustTier: RetrievableTrustTier\n #source: string | undefined\n #kind: string | undefined\n #score: number | undefined\n #createdAt: DateTime\n #updatedAt: DateTime\n #inline: boolean\n #artifactConstructor: ArtifactConstructorResolver | undefined\n\n /**\n * @param raw - The raw retrievable input validated against `rawRetrievableSchema`.\n * @throws {@link @nhtio/adk/exceptions!E_INVALID_INITIAL_RETRIEVABLE_VALUE} when `raw` does not satisfy the schema.\n */\n constructor(raw: RawRetrievable) {\n let resolved: ResolvedRetrievable\n try {\n resolved = validateOrThrow<ResolvedRetrievable>(rawRetrievableSchema, raw, true)\n } catch (err) {\n throw new E_INVALID_INITIAL_RETRIEVABLE_VALUE({\n cause: isError(err) ? err : undefined,\n })\n }\n this.#id = resolved.id\n this.#content =\n Tokenizable.isTokenizable(resolved.content) ||\n SpooledArtifact.isSpooledArtifact(resolved.content)\n ? resolved.content\n : new Tokenizable(resolved.content)\n this.#trustTier = resolved.trustTier\n this.#source = resolved.source\n this.#kind = resolved.kind\n this.#score = resolved.score\n this.#createdAt = resolved.createdAt\n this.#updatedAt = resolved.updatedAt\n this.#inline = resolved.inline\n this.#artifactConstructor = resolved.artifactConstructor\n\n Object.defineProperties(this, {\n id: {\n get: () => this.#id,\n enumerable: true,\n configurable: false,\n },\n content: {\n get: () => this.#content,\n enumerable: true,\n configurable: false,\n },\n trustTier: {\n get: () => this.#trustTier,\n enumerable: true,\n configurable: false,\n },\n source: {\n get: () => this.#source,\n enumerable: true,\n configurable: false,\n },\n kind: {\n get: () => this.#kind,\n enumerable: true,\n configurable: false,\n },\n score: {\n get: () => this.#score,\n enumerable: true,\n configurable: false,\n },\n createdAt: {\n get: () => this.#createdAt,\n enumerable: true,\n configurable: false,\n },\n updatedAt: {\n get: () => this.#updatedAt,\n enumerable: true,\n configurable: false,\n },\n inline: {\n get: () => this.#inline,\n enumerable: true,\n configurable: false,\n },\n artifactConstructor: {\n get: () => this.#artifactConstructor,\n enumerable: true,\n configurable: false,\n },\n sizeUnknown: {\n get: () =>\n SpooledArtifact.isSpooledArtifact(this.#content) &&\n !this.#inline &&\n !this.#content.hasSizeHints(),\n enumerable: true,\n configurable: false,\n },\n })\n }\n\n /**\n * Estimates the token count of the content under `encoding`.\n *\n * @remarks\n * Delegates to the content's own `estimateTokens`: synchronous for a {@link @nhtio/adk!Tokenizable}\n * (returns `number`), asynchronous for a {@link @nhtio/adk!SpooledArtifact} (returns\n * `Promise<number>`, reading the bytes from the backing store on demand). Both shapes satisfy the\n * adapter's token-budget path, which already awaits estimates.\n *\n * Note: the `SpooledArtifact` branch materialises the full decoded string transiently to count\n * tokens — reader-backing keeps the body off the *permanent* heap, but does not eliminate the\n * transient allocation at budgeting time.\n *\n * @param encoding - The encoding identifier to use for counting.\n * @returns The estimated token count.\n */\n estimateTokens(encoding: TokenEncoding): number | Promise<number> {\n if (\n SpooledArtifact.isSpooledArtifact(this.#content) &&\n !this.#inline &&\n this.#content.hasSizeHints()\n ) {\n return this.#content.estimateHandleTokens(this.#id, encoding)\n }\n return this.#content.estimateTokens(encoding)\n }\n\n /**\n * Returns the content body as a single string.\n *\n * @remarks\n * For a {@link @nhtio/adk!Tokenizable} this is synchronous in effect (resolved immediately); for a\n * {@link @nhtio/adk!SpooledArtifact} it reads the full body from the backing store via\n * {@link @nhtio/adk!SpooledArtifact.asString}. Always returns a `Promise` so callers have one\n * code path; render helpers `await` it at the point the trust-tier envelope is built.\n *\n * @returns The full content body as a string.\n */\n async contentString(): Promise<string> {\n return SpooledArtifact.isSpooledArtifact(this.#content)\n ? this.#content.asString()\n : this.#content.toString()\n }\n\n /**\n * Serialise this Retrievable into an `@nhtio/encoder` snapshot.\n *\n * @remarks\n * Emits a {@link RawRetrievable}-shaped object; `content` is the live {@link @nhtio/adk!Tokenizable} or\n * {@link @nhtio/adk!SpooledArtifact} (the encoder recurses — a reader-backed artifact round-trips as a\n * handle, throwing {@link @nhtio/adk!E_READER_NOT_DESCRIBABLE} if its reader cannot describe itself).\n * Round-trips via {@link Retrievable.[DECODE_METHOD]}, which re-validates through the constructor.\n *\n * @returns A {@link RawRetrievable}-shaped snapshot.\n */\n [ENCODE_METHOD](): AdkEncodableSnapshot {\n return {\n id: this.#id,\n content: this.#content,\n trustTier: this.#trustTier,\n source: this.#source,\n kind: this.#kind,\n score: this.#score,\n createdAt: this.#createdAt,\n updatedAt: this.#updatedAt,\n inline: this.#inline,\n artifactConstructor: this.#artifactConstructor,\n }\n }\n\n /**\n * Reconstruct a {@link Retrievable} from a {@link Retrievable.[ENCODE_METHOD]} snapshot.\n *\n * @param data - The snapshot produced by {@link Retrievable.[ENCODE_METHOD]}.\n * @returns A fully-validated {@link Retrievable}.\n */\n static [DECODE_METHOD](data: AdkEncodableSnapshot): Retrievable {\n return new Retrievable(data as RawRetrievable)\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"retrievable-CXTAUuuv.mjs","names":["#id","#content","#trustTier","#source","#kind","#score","#createdAt","#updatedAt","#inline","#artifactConstructor"],"sources":["../src/lib/classes/retrievable.ts"],"sourcesContent":["import { Tokenizable } from './tokenizable'\nimport { validator } from '@nhtio/validation'\nimport { SpooledArtifact } from './spooled_artifact'\nimport { validateOrThrow } from '../utils/validation'\nimport { isInstanceOf, isError } from '../utils/guards'\nimport { ENCODE_METHOD, DECODE_METHOD } from '../utils/encoder_symbols'\nimport { E_INVALID_INITIAL_RETRIEVABLE_VALUE } from '../exceptions/runtime'\nimport { artifactConstructorResolverSchema } from '../contracts/spooled_artifact_constructor'\nimport type { DateTime } from 'luxon'\nimport type { TokenEncoding } from './tokenizable'\nimport type { AdkEncodableSnapshot } from './encodable'\nimport type { ArtifactConstructorResolver } from './tool'\n\n/**\n * Trust-tier discriminator declared by the retrieval middleware at construction time. Drives\n * which envelope the LLM battery wraps the record in.\n *\n * @remarks\n * Vocabulary deliberately mirrors the published security-research taxonomy (\"first-party /\n * third-party\" per *Hidden-in-Plain-Text* WWW '26 and *When AI Meets the Web* IEEE S&P 2026)\n * and explicitly avoids the words \"user\" or \"system\" so the names cannot leak into the model's\n * OpenAI-Model-Spec role-tier authority resolution.\n *\n * - `'first-party'` — deployer-vetted corpora (signed internal docs, policy KBs, curated\n * reference material). Rendered as a `<retrieved_corpus>` parent with per-record nonce-keyed\n * `<retrieved>` children. The label \"first-party\" never appears in the envelope itself.\n * - `'third-party-public'` — open-web scrapes, search results, public APIs. Rendered through\n * the untrusted-content envelope with `kind: 'retrieved-third-party-public'`.\n * - `'third-party-private'` — user uploads, pasted attachments, partner APIs. Rendered through\n * the untrusted-content envelope with `kind: 'retrieved-third-party-private'`.\n */\nexport type RetrievableTrustTier = 'first-party' | 'third-party-public' | 'third-party-private'\n\n/**\n * Plain input object supplied to {@link Retrievable} at construction time.\n *\n * @remarks\n * Validated against `rawRetrievableSchema` before the `Retrievable` instance is created.\n * Temporal fields accept any value that Luxon can parse — ISO strings, Unix timestamps,\n * `Date` objects, or existing `DateTime` instances.\n */\nexport interface RawRetrievable {\n /**\n * Stable unique identifier for this retrieved record. Used as the closing-tag nonce in the\n * rendered envelope, so it must be unguessable from the payload.\n */\n id: string\n /**\n * The retrieved content. A plain `string` or {@link @nhtio/adk!Tokenizable} for small inline text, or a\n * {@link @nhtio/adk!SpooledArtifact} when the extracted text is large and lives in a consumer\n * {@link @nhtio/adk/common!ByteStore} (persist it via {@link @nhtio/adk!DispatchContext.storeRetrievableBytes}, wrap\n * the returned reader in a `SpooledArtifact`, and pass it here). Reader-backed content keeps the\n * body out of the permanent heap, but token estimation and render still materialise it\n * transiently (see {@link Retrievable.estimateTokens}).\n */\n content: string | Tokenizable | SpooledArtifact\n /**\n * Trust tier declared by the retrieval middleware at construction time. Required — there is\n * NO default. The decision must be conscious. See {@link RetrievableTrustTier}.\n */\n trustTier: RetrievableTrustTier\n /** Optional provenance string: URL, document path, knowledge-base id, etc. */\n source?: string\n /** Optional semantic label: 'policy' | 'reference' | 'web-page' | 'pdf' | etc. */\n kind?: string\n /** Optional relevance / similarity score in `[0, 1]` from the retrieval middleware. */\n score?: number\n /** When the source record was created (publication date, upload date, etc.). */\n createdAt: string | number | Date | DateTime\n /** When the source record was last modified. */\n updatedAt: string | number | Date | DateTime\n /** Whether to render this record inline rather than as a retrievable handle; defaults to `false`. */\n inline?: boolean\n /** Resolver for the spooled-artifact constructor used when plain content is auto-spooled; defaults to `undefined` (the base artifact). */\n artifactConstructor?: ArtifactConstructorResolver\n}\n\n/**\n * A fully-resolved {@link RawRetrievable} where all fields have been validated and temporal\n * values normalised to Luxon `DateTime` instances.\n */\ninterface ResolvedRetrievable {\n id: string\n content: Tokenizable | SpooledArtifact\n trustTier: RetrievableTrustTier\n source?: string\n kind?: string\n score?: number\n createdAt: DateTime\n updatedAt: DateTime\n inline: boolean\n artifactConstructor?: ArtifactConstructorResolver\n}\n\n/**\n * Validator schema used to validate a {@link RawRetrievable} before constructing a\n * {@link Retrievable}.\n *\n * @remarks\n * - `id` — required non-empty string.\n * - `content` — required {@link @nhtio/adk!Tokenizable.schema}.\n * - `trustTier` — required, one of `'first-party'`, `'third-party-public'`,\n * `'third-party-private'`. Unknown / missing values reject.\n * - `source` / `kind` — optional strings.\n * - `score` — optional number in `[0, 1]`.\n * - `createdAt` / `updatedAt` — required datetime-parseable values.\n *\n * Throws {@link @nhtio/adk/exceptions!E_INVALID_INITIAL_RETRIEVABLE_VALUE} (via the {@link Retrievable} constructor)\n * when validation fails.\n */\nconst contentSchema = validator.alternatives(\n validator.string(),\n validator.custom((value, helpers) => {\n if (Tokenizable.isTokenizable(value) || SpooledArtifact.isSpooledArtifact(value)) {\n return value\n }\n return helpers.error('any.invalid')\n })\n)\n\nconst rawRetrievableSchema = validator.object<RawRetrievable>({\n id: validator.string().required(),\n content: contentSchema.required(),\n trustTier: validator\n .string()\n .valid('first-party', 'third-party-public', 'third-party-private')\n .required(),\n source: validator.string().optional(),\n kind: validator.string().optional(),\n score: validator.number().min(0).max(1).optional(),\n createdAt: validator.datetime().required(),\n updatedAt: validator.datetime().required(),\n inline: validator.boolean().default(false),\n artifactConstructor: artifactConstructorResolverSchema().optional(),\n})\n\n/**\n * An immutable, validated retrieved record (RAG content) held by the agent.\n *\n * @remarks\n * Peer of {@link @nhtio/adk!Memory} / `Message` / `Thought` / `ToolCall`. Carries an explicit `trustTier`\n * that LLM batteries branch on to choose the rendering envelope. The retrieval middleware that\n * produced the record is the only party that knows its provenance — batteries MUST NOT\n * auto-classify or infer the tier from `source`.\n */\nexport class Retrievable {\n /**\n * Validator schema that accepts a {@link RawRetrievable} object.\n *\n * @remarks\n * Reusable fragment for any schema that needs to validate or nest a retrievable record.\n */\n public static schema = rawRetrievableSchema\n\n /**\n * Returns `true` if `value` is a {@link Retrievable} instance.\n *\n * @remarks\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety.\n */\n public static isRetrievable(value: unknown): value is Retrievable {\n return isInstanceOf(value, 'Retrievable', Retrievable)\n }\n\n /** Stable unique identifier for this retrieved record. */\n declare readonly id: string\n /**\n * The retrieved content: a {@link @nhtio/adk!Tokenizable} (inline text) or a\n * {@link @nhtio/adk!SpooledArtifact} (reader-backed, large text living in a consumer store). Use\n * {@link Retrievable.estimateTokens} for budgeting and {@link Retrievable.contentString} to\n * materialise the body at render time.\n */\n declare readonly content: Tokenizable | SpooledArtifact\n /** Trust tier declared by the retrieval middleware. */\n declare readonly trustTier: RetrievableTrustTier\n /** Optional provenance string. */\n declare readonly source: string | undefined\n /** Optional semantic label. */\n declare readonly kind: string | undefined\n /** Optional relevance / similarity score in `[0, 1]`. */\n declare readonly score: number | undefined\n /** When the source record was created. */\n declare readonly createdAt: DateTime\n /** When the source record was last modified. */\n declare readonly updatedAt: DateTime\n /** Whether this record is rendered inline; defaults to `false` (handle mode for spooled content). */\n declare readonly inline: boolean\n /** Producer-declared resolver for the artifact subclass used during auto-spooling, if any. */\n declare readonly artifactConstructor: ArtifactConstructorResolver | undefined\n /** Whether a non-inline spooled artifact lacks cached size metadata. */\n declare readonly sizeUnknown: boolean\n\n #id: string\n #content: Tokenizable | SpooledArtifact\n #trustTier: RetrievableTrustTier\n #source: string | undefined\n #kind: string | undefined\n #score: number | undefined\n #createdAt: DateTime\n #updatedAt: DateTime\n #inline: boolean\n #artifactConstructor: ArtifactConstructorResolver | undefined\n\n /**\n * @param raw - The raw retrievable input validated against `rawRetrievableSchema`.\n * @throws {@link @nhtio/adk/exceptions!E_INVALID_INITIAL_RETRIEVABLE_VALUE} when `raw` does not satisfy the schema.\n */\n constructor(raw: RawRetrievable) {\n let resolved: ResolvedRetrievable\n try {\n resolved = validateOrThrow<ResolvedRetrievable>(rawRetrievableSchema, raw, true)\n } catch (err) {\n throw new E_INVALID_INITIAL_RETRIEVABLE_VALUE({\n cause: isError(err) ? err : undefined,\n })\n }\n this.#id = resolved.id\n this.#content =\n Tokenizable.isTokenizable(resolved.content) ||\n SpooledArtifact.isSpooledArtifact(resolved.content)\n ? resolved.content\n : new Tokenizable(resolved.content)\n this.#trustTier = resolved.trustTier\n this.#source = resolved.source\n this.#kind = resolved.kind\n this.#score = resolved.score\n this.#createdAt = resolved.createdAt\n this.#updatedAt = resolved.updatedAt\n this.#inline = resolved.inline\n this.#artifactConstructor = resolved.artifactConstructor\n\n Object.defineProperties(this, {\n id: {\n get: () => this.#id,\n enumerable: true,\n configurable: false,\n },\n content: {\n get: () => this.#content,\n enumerable: true,\n configurable: false,\n },\n trustTier: {\n get: () => this.#trustTier,\n enumerable: true,\n configurable: false,\n },\n source: {\n get: () => this.#source,\n enumerable: true,\n configurable: false,\n },\n kind: {\n get: () => this.#kind,\n enumerable: true,\n configurable: false,\n },\n score: {\n get: () => this.#score,\n enumerable: true,\n configurable: false,\n },\n createdAt: {\n get: () => this.#createdAt,\n enumerable: true,\n configurable: false,\n },\n updatedAt: {\n get: () => this.#updatedAt,\n enumerable: true,\n configurable: false,\n },\n inline: {\n get: () => this.#inline,\n enumerable: true,\n configurable: false,\n },\n artifactConstructor: {\n get: () => this.#artifactConstructor,\n enumerable: true,\n configurable: false,\n },\n sizeUnknown: {\n get: () =>\n SpooledArtifact.isSpooledArtifact(this.#content) &&\n !this.#inline &&\n !this.#content.hasSizeHints(),\n enumerable: true,\n configurable: false,\n },\n })\n }\n\n /**\n * Estimates the token count of the content under `encoding`.\n *\n * @remarks\n * Delegates to the content's own `estimateTokens`: synchronous for a {@link @nhtio/adk!Tokenizable}\n * (returns `number`), asynchronous for a {@link @nhtio/adk!SpooledArtifact} (returns\n * `Promise<number>`, reading the bytes from the backing store on demand). Both shapes satisfy the\n * adapter's token-budget path, which already awaits estimates.\n *\n * Note: the `SpooledArtifact` branch materialises the full decoded string transiently to count\n * tokens — reader-backing keeps the body off the *permanent* heap, but does not eliminate the\n * transient allocation at budgeting time.\n *\n * @param encoding - The encoding identifier to use for counting.\n * @returns The estimated token count.\n */\n estimateTokens(encoding: TokenEncoding): number | Promise<number> {\n if (\n SpooledArtifact.isSpooledArtifact(this.#content) &&\n !this.#inline &&\n this.#content.hasSizeHints()\n ) {\n return this.#content.estimateHandleTokens(this.#id, encoding)\n }\n return this.#content.estimateTokens(encoding)\n }\n\n /**\n * Returns the content body as a single string.\n *\n * @remarks\n * For a {@link @nhtio/adk!Tokenizable} this is synchronous in effect (resolved immediately); for a\n * {@link @nhtio/adk!SpooledArtifact} it reads the full body from the backing store via\n * {@link @nhtio/adk!SpooledArtifact.asString}. Always returns a `Promise` so callers have one\n * code path; render helpers `await` it at the point the trust-tier envelope is built.\n *\n * @returns The full content body as a string.\n */\n async contentString(): Promise<string> {\n return SpooledArtifact.isSpooledArtifact(this.#content)\n ? this.#content.asString()\n : this.#content.toString()\n }\n\n /**\n * Serialise this Retrievable into an `@nhtio/encoder` snapshot.\n *\n * @remarks\n * Emits a {@link RawRetrievable}-shaped object; `content` is the live {@link @nhtio/adk!Tokenizable} or\n * {@link @nhtio/adk!SpooledArtifact} (the encoder recurses — a reader-backed artifact round-trips as a\n * handle, throwing {@link @nhtio/adk!E_READER_NOT_DESCRIBABLE} if its reader cannot describe itself).\n * Round-trips via {@link Retrievable.[DECODE_METHOD]}, which re-validates through the constructor.\n *\n * @returns A {@link RawRetrievable}-shaped snapshot.\n */\n [ENCODE_METHOD](): AdkEncodableSnapshot {\n return {\n id: this.#id,\n content: this.#content,\n trustTier: this.#trustTier,\n source: this.#source,\n kind: this.#kind,\n score: this.#score,\n createdAt: this.#createdAt,\n updatedAt: this.#updatedAt,\n inline: this.#inline,\n artifactConstructor: this.#artifactConstructor,\n }\n }\n\n /**\n * Reconstruct a {@link Retrievable} from a {@link Retrievable.[ENCODE_METHOD]} snapshot.\n *\n * @param data - The snapshot produced by {@link Retrievable.[ENCODE_METHOD]}.\n * @returns A fully-validated {@link Retrievable}.\n */\n static [DECODE_METHOD](data: AdkEncodableSnapshot): Retrievable {\n return new Retrievable(data as RawRetrievable)\n }\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  const require_exceptions = require("./exceptions-DrHnAGQz.cjs");
2
2
  const require_guards = require("./guards-5-XmJgD2.cjs");
3
- const require_spooled_artifact = require("./spooled_artifact-BLgbGT8b.cjs");
4
- const require_spooled_markdown_artifact = require("./spooled_markdown_artifact-8zdejfcJ.cjs");
5
- require("./factories.cjs");
3
+ const require_spooled_artifact = require("./spooled_artifact---DmicFW.cjs");
4
+ const require_spooled_markdown_artifact = require("./spooled_markdown_artifact-Rjzj-kyh.cjs");
6
5
  require("./forge.cjs");
6
+ require("./factories.cjs");
7
7
  require("./guards.cjs");
8
8
  require("./spooled_artifact.cjs");
9
9
  const require_batteries_tools__shared = require("./batteries/tools/_shared.cjs");
@@ -467,4 +467,4 @@ Object.defineProperty(exports, "createScrapperLinksToolSync", {
467
467
  }
468
468
  });
469
469
 
470
- //# sourceMappingURL=scrapper-BibKj8qE.cjs.map
470
+ //# sourceMappingURL=scrapper-B8xG9lTD.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"scrapper-BibKj8qE.cjs","names":[],"sources":["../src/batteries/tools/scrapper/exceptions.ts","../src/batteries/tools/scrapper/shared.ts","../src/batteries/tools/scrapper/index.ts"],"sourcesContent":["/**\n * Battery-scoped exception constructors for the Scrapper web-extraction tool.\n *\n * @remarks\n * Battery-scoped exception classes owned by the Scrapper tool battery (not the ADK core). Minted\n * via `createException` from `@nhtio/adk/factories` and re-exported from the battery's barrel\n * (`@nhtio/adk/batteries/tools/scrapper`). This file intentionally carries **no** `@module` tag:\n * it is an internal sibling relative-imported by `index.ts`, so it does not mint its own\n * `…/scrapper/exceptions` entrypoint (whose `exceptions` leaf basename would collide with sibling\n * batteries under the `vite-plugin-dts` rolled-up `.d.ts` rule).\n */\n\nimport { createException } from '@nhtio/adk/factories'\n\n/**\n * Thrown when a Scrapper factory receives invalid configuration.\n *\n * @remarks\n * Fatal: config bugs (missing/unparseable `instanceUrl`, a bad `artifact` resolver, or an async\n * resolver passed to a `*Sync` factory) fail loud at factory-call time rather than at first scrape.\n */\nexport const E_INVALID_SCRAPPER_CONFIG = createException<[string]>(\n 'E_INVALID_SCRAPPER_CONFIG',\n 'Invalid Scrapper tool config: %s',\n 'E_INVALID_SCRAPPER_CONFIG',\n 529,\n true\n)\n","/**\n * Internal core shared by both Scrapper verbs (article / links).\n *\n * @remarks\n * No `@module` tag — this is a sibling of `index.ts`, relative-imported, not its own entrypoint.\n * Houses the per-parameter disposition machinery (schema building from `fixed`/`defaults`), the\n * snake→kebab wire mapping, the request/response contexts, and the `fetch`+pipeline handler core.\n * Generic harness helpers (artifact/header resolution, pipeline runners) come from `../_shared`.\n */\n\nimport { Tool } from '@nhtio/adk/forge'\nimport { isError } from '@nhtio/adk/guards'\nimport { validator } from '@nhtio/validation'\nimport { Middleware } from '@nhtio/middleware'\nimport { E_INVALID_SCRAPPER_CONFIG } from './exceptions'\nimport {\n resolveHeaders,\n makeShortCircuit,\n isShortCircuit,\n runInputPipeline,\n runOutputPipeline,\n runToolGate,\n type ToolGateFn,\n type ToolHeaders,\n type ToolHeadersResolver,\n type SpooledArtifactCtor,\n type MiddlewareFn,\n} from '../_shared'\nimport type { Schema } from '@nhtio/validation'\nimport type { NextFn } from '@nhtio/middleware'\n\nconst DEFAULT_REQUEST_TIMEOUT = 65_000\n\n/** Throw the battery-scoped config error. */\nexport const failConfig = (reason: string): never => {\n throw new E_INVALID_SCRAPPER_CONFIG([reason])\n}\n\n// ── Parameter specs (per-parameter disposition) ──────────────────────────────\n\n/** The wire type of a Scrapper query parameter — controls serialisation. */\nexport type ScrapperParamType = 'string' | 'number' | 'boolean'\n\n/**\n * One curated, model-facing Scrapper parameter: its snake_case key (used in the model schema and\n * in `fixed`/`defaults`), its kebab-case wire name, its type, the base validator, and a description.\n */\nexport interface ScrapperParamSpec {\n /** snake_case key as seen by the model and in `config.fixed` / `config.defaults`. */\n key: string\n /** kebab-case name sent to the Scrapper API. */\n wire: string\n /** Wire type, controlling string/number/boolean serialisation. */\n type: ScrapperParamType\n /** Base `@nhtio/validation` schema (no `.required()`/`.default()`/`.optional()` applied yet). */\n schema: Schema\n /** Human-readable description surfaced to the model. */\n description: string\n}\n\n/** Serialise a parameter value to its wire string. */\nconst toWire = (value: unknown): string => String(value)\n\n/**\n * Build the model-facing input schema from a verb's param specs and the factory's disposition.\n * `url` is always required. A `fixed` param is omitted (the model can't set it); a `defaults` param\n * gets `.default(value)`; everything else is `.optional()`.\n */\nexport const buildScrapperSchema = (\n specs: ScrapperParamSpec[],\n fixed: Record<string, unknown> | undefined,\n defaults: Record<string, unknown> | undefined,\n extra: Record<string, Schema> = {}\n): Schema => {\n const shape: Record<string, Schema> = {\n url: validator.string().required().description('The absolute URL of the page to load.'),\n }\n for (const spec of specs) {\n if (fixed && spec.key in fixed) continue // pinned → not model-visible\n let sch = spec.schema\n if (defaults && spec.key in defaults) {\n sch = sch.default(defaults[spec.key] as never)\n } else {\n sch = sch.optional()\n }\n shape[spec.key] = sch.description(spec.description)\n }\n return validator.object({ ...shape, ...extra })\n}\n\n/**\n * Assemble the wire-kebab query params for one request: each spec's value is `fixed` (if pinned)\n * else the validated model/default value; then `fixedQuery` raw passthrough is layered on. `url`\n * is handled separately (it is the search target, never pinned).\n *\n * @remarks\n * An empty string (`''`) is deliberately treated the same as `undefined`/`null` and never\n * forwarded — this is what lets the schema's `.allow('')` on optional string specs actually\n * mean \"don't set this,\" instead of sending e.g. `user-agent=` to the wire. This applies\n * generically to every spec (no per-spec-type branching), including a `fixed`-pinned value that\n * happens to be `''` — an explicitly pinned empty string still means \"don't send it.\"\n */\nexport const buildWireParams = (\n args: Record<string, unknown>,\n specs: ScrapperParamSpec[],\n fixed: Record<string, unknown> | undefined,\n fixedQuery: Record<string, string> | undefined\n): Record<string, string> => {\n const out: Record<string, string> = {}\n for (const spec of specs) {\n const value = fixed && spec.key in fixed ? fixed[spec.key] : args[spec.key]\n const isEmptyString = typeof value === 'string' && value.length === 0\n if (value !== undefined && value !== null && !isEmptyString) out[spec.wire] = toWire(value)\n }\n for (const [k, v] of Object.entries(fixedQuery ?? {})) out[k] = v\n return out\n}\n\n// ── Contexts ─────────────────────────────────────────────────────────────────\n\n/**\n * Mutable context handed to each input-pipeline stage **before** the HTTP request is sent.\n * Identical for both verbs.\n */\nexport interface ScrapperRequestContext {\n /** The tool's name (read-only). */\n readonly toolName: string\n /** The target page URL (the `url` argument). Mutable. */\n url: string\n /** Wire-kebab query params (everything except `url`). Mutable. */\n params: Record<string, string>\n /** Resolved request headers sent to the SCRAPPER INSTANCE (auth). Mutable. */\n headers: ToolHeaders\n /** The Scrapper instance base URL (read-only). */\n readonly instanceUrl: string\n /** Cross-stage scratch space; also carried onto the response context. */\n readonly stash: Map<string, unknown>\n /** Skip the fetch and return `result` verbatim as the tool's output (e.g. a cache hit). */\n shortCircuit(result: string): void\n}\n\n/**\n * Mutable context handed to each output-pipeline stage **after** the response JSON is parsed.\n *\n * @typeParam R - The verb's normalised result type (article object or links payload).\n */\nexport interface ScrapperResponseContext<R> {\n /** The tool's name (read-only). */\n readonly toolName: string\n /** The request context as it was sent (post-input-pipeline). */\n readonly request: ScrapperRequestContext\n /** The parsed Scrapper JSON body. Mutable (used when `format` is `raw`). */\n raw: unknown\n /** The normalised result. Mutable — reshape, redact, enrich. */\n result: R\n /** The effective payload shape for this call. */\n format: 'normalized' | 'raw'\n /** When set, used verbatim as the tool's output (overrides serialisation). */\n output?: string\n /** Cross-stage scratch space; carried over from the request context. */\n readonly stash: Map<string, unknown>\n}\n\n/** An input-pipeline stage. Onion middleware over {@link ScrapperRequestContext}. */\nexport type ScrapperInputMiddlewareFn = (\n ctx: ScrapperRequestContext,\n next: NextFn\n) => void | Promise<void>\n\n/** An output-pipeline stage over a verb's {@link ScrapperResponseContext}. */\nexport type ScrapperOutputMiddlewareFn<R> = (\n ctx: ScrapperResponseContext<R>,\n next: NextFn\n) => void | Promise<void>\n\n// ── Config (shared shape; `artifact` variant supplied by the verb factory) ────\n\n/** Configuration common to every Scrapper factory. `A` is the accepted `artifact` resolver type. */\nexport interface ScrapperBaseConfig<P, R, A> {\n /** Base URL of the Scrapper instance, e.g. `https://scrapper.example.org`. Required. */\n instanceUrl: string\n /** Headers sent to the Scrapper INSTANCE for auth (X-API-Key / Basic) — static or resolver. */\n headers?: ToolHeaders | ToolHeadersResolver\n /** The tool's own `fetch` AbortController timeout in ms. Default `65_000` (> Scrapper's 60s browser default). */\n requestTimeoutMs?: number\n /** Output shape. `normalized`/`raw` pin it; `either` (default) exposes a `format` arg to the model. */\n resultFormat?: 'normalized' | 'raw' | 'either'\n /** Spool-artifact resolver for the output. Default `() => SpooledJsonArtifact`. */\n artifact?: A\n /** Tool name override. */\n name?: string\n /** Tool description override. */\n description?: string\n /** Pinned params — sent always, removed from the model schema. */\n fixed?: Partial<P>\n /** Model-overridable default param values. */\n defaults?: Partial<P>\n /** Raw, un-modeled wire params (kebab keys) — always sent, never model-visible. Keeps the battery generic. */\n fixedQuery?: Record<string, string>\n /**\n * Optional per-call gate run before the HTTP request — the seam for human-approval/RBAC\n * flows built on `ctx.waitFor` (the ADK gates primitive). Throwing aborts the call through\n * the standard tool-error path. Scraping reaches the network on the agent's behalf, which\n * makes every call a candidate for gating.\n */\n gate?: ToolGateFn\n /** Stages run before the HTTP request. See {@link ScrapperRequestContext}. */\n inputPipeline?: ScrapperInputMiddlewareFn[]\n /** Stages run after the response is parsed. See {@link ScrapperResponseContext}. */\n outputPipeline?: ScrapperOutputMiddlewareFn<R>[]\n}\n\n/** Verb-specific wiring passed to {@link assembleScrapperTool}. */\nexport interface ScrapperVerb<R> {\n /** Scrapper endpoint path, e.g. `/api/article`. */\n endpoint: string\n /** The curated param specs for this verb. */\n specs: ScrapperParamSpec[]\n /** Default tool name (`scrapper_article` / `scrapper_links`). */\n defaultName: string\n /** Default tool description. */\n defaultDescription: string\n /** Map a parsed Scrapper body to the verb's normalised result. */\n normalize: (body: Record<string, unknown>) => R\n}\n\n/** Parse a Scrapper error body (`{ detail: [{ msg }] }`) into a single message, best-effort. */\nconst parseScrapperError = (body: unknown, status: number, statusText: string): string => {\n if (body && typeof body === 'object' && Array.isArray((body as { detail?: unknown }).detail)) {\n const detail = (body as { detail: Array<{ msg?: unknown; loc?: unknown }> }).detail\n const msgs = detail\n .map((d) => {\n const loc = Array.isArray(d.loc) ? d.loc.join('.') : undefined\n const msg = typeof d.msg === 'string' ? d.msg : undefined\n if (msg && loc) return `${loc}: ${msg}`\n return msg ?? loc\n })\n .filter((m): m is string => typeof m === 'string')\n if (msgs.length) return msgs.join('; ')\n }\n return `HTTP ${status} ${statusText}`.trim()\n}\n\n/**\n * Build a configured Scrapper {@link Tool} from validated config + an already-resolved sync\n * artifact constructor. Shared by every verb and by both the async and sync factories.\n */\nexport const assembleScrapperTool = <P, R>(\n verb: ScrapperVerb<R>,\n config: ScrapperBaseConfig<P, R, unknown>,\n instanceUrl: string,\n artifactConstructor: () => SpooledArtifactCtor\n): Tool => {\n const requestTimeoutMs = config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT\n const resultFormat = config.resultFormat ?? 'either'\n const toolName = config.name ?? verb.defaultName\n const fixed = config.fixed as Record<string, unknown> | undefined\n const defaults = config.defaults as Record<string, unknown> | undefined\n\n const inputMw = new Middleware<MiddlewareFn<ScrapperRequestContext>>()\n for (const fn of config.inputPipeline ?? []) inputMw.add(fn)\n const outputMw = new Middleware<MiddlewareFn<ScrapperResponseContext<R>>>()\n for (const fn of config.outputPipeline ?? [])\n outputMw.add(fn as MiddlewareFn<ScrapperResponseContext<R>>)\n const hasInput = (config.inputPipeline ?? []).length > 0\n const hasOutput = (config.outputPipeline ?? []).length > 0\n\n // Build the schema, conditionally exposing `format` only when the factory is neutral.\n const extra: Record<string, Schema> =\n resultFormat === 'either'\n ? {\n format: validator\n .string()\n .valid('normalized', 'raw')\n .default('normalized')\n .description('Output shape: \"normalized\" (trimmed) or \"raw\" (full Scrapper JSON).'),\n }\n : {}\n const inputSchema = buildScrapperSchema(verb.specs, fixed, defaults, extra)\n\n return new Tool({\n name: toolName,\n description: config.description ?? verb.defaultDescription,\n inputSchema,\n artifactConstructor,\n handler: async (args, handlerCtx) => {\n const a = args as Record<string, unknown> & { url: string; format?: 'normalized' | 'raw' }\n await runToolGate(config.gate, handlerCtx, toolName, args)\n try {\n const format: 'normalized' | 'raw' =\n resultFormat === 'either' ? (a.format ?? 'normalized') : resultFormat\n\n const headers: ToolHeaders = {\n Accept: 'application/json',\n ...(await resolveHeaders(config.headers)),\n }\n\n const params = buildWireParams(a, verb.specs, fixed, config.fixedQuery)\n const stash = new Map<string, unknown>()\n\n const requestCtx: ScrapperRequestContext = {\n toolName,\n url: a.url,\n params,\n headers,\n instanceUrl,\n stash,\n shortCircuit: makeShortCircuit(),\n }\n\n if (hasInput) {\n const short = await runInputPipeline(inputMw, requestCtx, 'Scrapper')\n if (short !== undefined) return short\n }\n\n const url = new URL(verb.endpoint, instanceUrl + '/')\n url.searchParams.set('url', requestCtx.url)\n for (const [k, v] of Object.entries(requestCtx.params)) url.searchParams.set(k, v)\n\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), requestTimeoutMs)\n let response: Response\n try {\n response = await fetch(url, {\n method: 'GET',\n headers: requestCtx.headers,\n signal: controller.signal,\n })\n } finally {\n clearTimeout(timer)\n }\n\n if (!response.ok) {\n let body: unknown\n try {\n body = await response.json()\n } catch {\n body = undefined\n }\n return `Error: Scrapper request failed — ${parseScrapperError(body, response.status, response.statusText)}.`\n }\n\n const body = (await response.json()) as Record<string, unknown>\n\n const responseCtx: ScrapperResponseContext<R> = {\n toolName,\n request: requestCtx,\n raw: body,\n result: verb.normalize(body),\n format,\n stash,\n }\n\n if (hasOutput) await runOutputPipeline(outputMw, responseCtx, 'Scrapper')\n\n if (typeof responseCtx.output === 'string') return responseCtx.output\n if (responseCtx.format === 'raw') return JSON.stringify(responseCtx.raw, null, 2)\n return JSON.stringify(responseCtx.result, null, 2)\n } catch (err) {\n if (isShortCircuit(err)) return err.result\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n })\n}\n\n/** Validate `instanceUrl` and return the trailing-slash-normalised base. */\nexport const validateScrapperInstanceUrl = (config: { instanceUrl?: string }): string => {\n if (typeof config?.instanceUrl !== 'string' || config.instanceUrl.trim() === '') {\n failConfig('instanceUrl is required')\n }\n try {\n new URL(config.instanceUrl as string)\n } catch {\n failConfig(`instanceUrl is not a valid URL: ${config.instanceUrl}`)\n }\n return (config.instanceUrl as string).replace(/\\/+$/, '')\n}\n","/**\n * Factories for configured Scrapper web-extraction tools (article + links).\n *\n * @module @nhtio/adk/batteries/tools/scrapper\n *\n * @remarks\n * [Scrapper](https://github.com/amerkurev/scrapper) is a self-hosted service that loads a page in a\n * real headless browser and extracts either the readable article (`/api/article`) or the page's\n * links (`/api/links`). It gives an agent browser-grade reading power — JS-rendered pages a\n * renderless fetcher can't see — but as a **stateless** HTTP call: each request runs in a fresh\n * incognito context, stores no session or credentials, and shares nothing with any other call.\n *\n * Like the SearXNG battery, this exports **factories** (not ready-made `Tool` constants), because a\n * scrape tool needs per-deployment config (instance URL + custom auth headers). Two verbs, each with\n * an async factory ({@link createScrapperArticleTool} / {@link createScrapperLinksTool}, accepting a\n * dynamic-import `artifact` resolver) and a sync variant ({@link createScrapperArticleToolSync} /\n * {@link createScrapperLinksToolSync}). Because these are factories, they MUST NOT be bulk-registered\n * via `Object.values(batteries)` — call one, then register the returned tool.\n *\n * @see https://github.com/amerkurev/scrapper\n */\n\nimport { validator } from '@nhtio/validation'\nimport { SpooledJsonArtifact } from '@nhtio/adk/spooled_artifact'\nimport { resolveArtifact, resolveArtifactSync } from '../_shared'\nimport {\n failConfig,\n validateScrapperInstanceUrl,\n assembleScrapperTool,\n type ScrapperBaseConfig,\n type ScrapperParamSpec,\n type ScrapperVerb,\n} from './shared'\nimport type { Tool } from '@nhtio/adk/forge'\nimport type { ArtifactResolver, SyncArtifactResolver } from '../_shared'\n\nexport { E_INVALID_SCRAPPER_CONFIG } from './exceptions'\nexport type {\n ScrapperRequestContext,\n ScrapperResponseContext,\n ScrapperInputMiddlewareFn,\n ScrapperOutputMiddlewareFn,\n} from './shared'\n\n// ── Param sets ───────────────────────────────────────────────────────────────\n\n/** Model-facing params common to both verbs (snake_case; mapped to kebab on the wire). */\nexport interface ScrapperCommonParams {\n /** Return a cached result when available instead of re-scraping. */\n cache?: boolean\n /** Capture a screenshot; the result carries a `screenshotUri`. */\n screenshot?: boolean\n /** Run in an incognito browser context (no persisted browsing data). Default true upstream. */\n incognito?: boolean\n /** Browser navigation timeout in ms (`0` disables). Distinct from the tool's own fetch timeout. */\n timeout?: number\n /** When navigation is considered finished. */\n wait_until?: 'load' | 'domcontentloaded' | 'networkidle' | 'commit'\n /** Wait this many ms after load before parsing. */\n sleep?: number\n /** Scroll down N pixels for lazy-loading pages. Requires a positive `sleep`. */\n scroll_down?: number\n /** Emulated device, e.g. `Desktop Chrome`. Overrides individual viewport/UA settings. */\n device?: string\n /** Explicit user-agent (prefer `device`). */\n user_agent?: string\n /** Extra headers the SCRAPER's browser sends to the TARGET site, `K:v;K2:v2` (NOT instance auth). */\n extra_http_headers?: string\n /** Upstream proxy, e.g. `http://host:3128` or `socks5://host:1080`. */\n proxy_server?: string\n}\n\n/** Model-facing params for `/api/article`. */\nexport interface ScrapperArticleParams extends ScrapperCommonParams {\n /** Populate `fullContent` with the page's full HTML. */\n full_content?: boolean\n}\n\n/** Model-facing params for `/api/links`. */\nexport interface ScrapperLinksParams extends ScrapperCommonParams {\n /** Median link-text length threshold for the link parser. */\n text_len_threshold?: number\n /** Median words-per-link threshold for the link parser. */\n words_threshold?: number\n}\n\nconst commonSpecs: ScrapperParamSpec[] = [\n {\n key: 'cache',\n wire: 'cache',\n type: 'boolean',\n schema: validator.boolean(),\n description: 'Return a cached result when available instead of re-scraping.',\n },\n {\n key: 'screenshot',\n wire: 'screenshot',\n type: 'boolean',\n schema: validator.boolean(),\n description: 'Capture a screenshot; the result carries a screenshotUri.',\n },\n {\n key: 'incognito',\n wire: 'incognito',\n type: 'boolean',\n schema: validator.boolean(),\n description: 'Run in an incognito browser context (no persisted data).',\n },\n {\n key: 'timeout',\n wire: 'timeout',\n type: 'number',\n schema: validator.number().min(0),\n description: 'Browser navigation timeout in ms (0 disables).',\n },\n {\n key: 'wait_until',\n wire: 'wait-until',\n type: 'string',\n schema: validator.string().valid('load', 'domcontentloaded', 'networkidle', 'commit'),\n description: 'When navigation is considered finished.',\n },\n {\n key: 'sleep',\n wire: 'sleep',\n type: 'number',\n schema: validator.number().min(0),\n description: 'Wait this many ms after load before parsing.',\n },\n {\n key: 'scroll_down',\n wire: 'scroll-down',\n type: 'number',\n schema: validator.number().min(0),\n description: 'Scroll down N pixels for lazy-loading pages (requires a positive sleep).',\n },\n {\n key: 'device',\n wire: 'device',\n type: 'string',\n schema: validator.string().allow(''),\n description:\n 'Emulated device, e.g. \"Desktop Chrome\". Omit or send an empty string to leave it unset.',\n },\n {\n key: 'user_agent',\n wire: 'user-agent',\n type: 'string',\n schema: validator.string().allow(''),\n description:\n 'Explicit user-agent (prefer device). Omit or send an empty string to leave it unset.',\n },\n {\n key: 'extra_http_headers',\n wire: 'extra-http-headers',\n type: 'string',\n schema: validator.string().allow(''),\n description:\n 'Extra headers the scraper sends to the TARGET site, formatted \"K:v;K2:v2\". Omit or send an empty string to send none.',\n },\n {\n key: 'proxy_server',\n wire: 'proxy-server',\n type: 'string',\n schema: validator.string().allow(''),\n description:\n 'Upstream proxy, e.g. \"http://host:3128\" or \"socks5://host:1080\". Omit or send an empty string to use no proxy.',\n },\n]\n\nconst articleSpecs: ScrapperParamSpec[] = [\n ...commonSpecs,\n {\n key: 'full_content',\n wire: 'full-content',\n type: 'boolean',\n schema: validator.boolean(),\n description: 'Populate fullContent with the page full HTML.',\n },\n]\n\nconst linksSpecs: ScrapperParamSpec[] = [\n ...commonSpecs,\n {\n key: 'text_len_threshold',\n wire: 'text-len-threshold',\n type: 'number',\n schema: validator.number().min(0),\n description: 'Median link-text length threshold for the link parser.',\n },\n {\n key: 'words_threshold',\n wire: 'words-threshold',\n type: 'number',\n schema: validator.number().min(0),\n description: 'Median words-per-link threshold for the link parser.',\n },\n]\n\n// ── Normalised result shapes ─────────────────────────────────────────────────\n\n/** A normalised Scrapper article (loose/nullable upstream). */\nexport interface ScrapperArticle {\n /** The page URL the article was extracted from. */\n url?: string\n /** Article title. */\n title?: string\n /** Author / byline metadata. */\n byline?: string\n /** Short excerpt or description of the article. */\n excerpt?: string\n /** Name of the site the article came from. */\n siteName?: string\n /** Detected content language. */\n lang?: string\n /** Character count of the extracted article text. */\n length?: number\n /** Publication time, when the page exposed one. */\n publishedTime?: string\n /** Scrapper's own date field for the result. */\n date?: string\n /** Article text with HTML stripped. */\n textContent?: string\n /** Processed article HTML; present when the caller requested it. */\n content?: string\n /** Full page HTML; present only when `full_content` was set. */\n fullContent?: string\n /** Screenshot URI; present only when `screenshot` was set. */\n screenshotUri?: string\n}\n\n/** A single link from `/api/links` (verified live: `{ url, text }`). */\nexport interface ScrapperLink {\n /** The link's target URL. */\n url?: string\n /** The link's anchor text. */\n text?: string\n}\n\n/** A normalised Scrapper links payload. */\nexport interface ScrapperLinks {\n /** The page URL the links were collected from. */\n url?: string\n /** The page title. */\n title?: string\n /** The page's domain. */\n domain?: string\n /** Scrapper's own date field for the result. */\n date?: string\n /** The collected links, each `{ url, text }`. */\n links: ScrapperLink[]\n /** Screenshot URI; present only when `screenshot` was set. */\n screenshotUri?: string\n}\n\nconst str = (v: unknown): string | undefined => (typeof v === 'string' ? v : undefined)\nconst num = (v: unknown): number | undefined => (typeof v === 'number' ? v : undefined)\n\nconst normalizeArticle = (body: Record<string, unknown>): ScrapperArticle => {\n const out: ScrapperArticle = {}\n out.url = str(body.url)\n out.title = str(body.title)\n out.byline = str(body.byline)\n out.excerpt = str(body.excerpt)\n out.siteName = str(body.siteName)\n out.lang = str(body.lang)\n out.length = num(body.length)\n out.publishedTime = str(body.publishedTime)\n out.date = str(body.date)\n out.textContent = str(body.textContent)\n if (str(body.content)) out.content = str(body.content)\n if (str(body.fullContent)) out.fullContent = str(body.fullContent)\n if (str(body.screenshotUri)) out.screenshotUri = str(body.screenshotUri)\n // Drop undefined keys so the serialised payload stays tight.\n return JSON.parse(JSON.stringify(out)) as ScrapperArticle\n}\n\nconst normalizeLinks = (body: Record<string, unknown>): ScrapperLinks => {\n const rawLinks = Array.isArray(body.links) ? body.links : []\n const links: ScrapperLink[] = rawLinks.map((l) => {\n const r = (l ?? {}) as Record<string, unknown>\n const item: ScrapperLink = {}\n if (str(r.url)) item.url = str(r.url)\n if (str(r.text)) item.text = str(r.text)\n return item\n })\n const out: ScrapperLinks = { links }\n if (str(body.url)) out.url = str(body.url)\n if (str(body.title)) out.title = str(body.title)\n if (str(body.domain)) out.domain = str(body.domain)\n if (str(body.date)) out.date = str(body.date)\n if (str(body.screenshotUri)) out.screenshotUri = str(body.screenshotUri)\n return out\n}\n\nconst articleVerb: ScrapperVerb<ScrapperArticle> = {\n endpoint: '/api/article',\n specs: articleSpecs,\n defaultName: 'scrapper_article',\n defaultDescription:\n 'Load a web page in a real (headless) browser and extract its readable article — title, ' +\n 'byline, text content, and metadata. Renders JavaScript-heavy pages a plain fetch cannot. ' +\n 'Each call is stateless (fresh incognito context, no stored session).',\n normalize: normalizeArticle,\n}\n\nconst linksVerb: ScrapperVerb<ScrapperLinks> = {\n endpoint: '/api/links',\n specs: linksSpecs,\n defaultName: 'scrapper_links',\n defaultDescription:\n 'Load a web page in a real (headless) browser and collect its article/navigation links ' +\n '(each { url, text }). Renders JavaScript-heavy index pages a plain fetch cannot. ' +\n 'Each call is stateless (fresh incognito context, no stored session).',\n normalize: normalizeLinks,\n}\n\n// ── Config aliases ────────────────────────────────────────────────────────────\n\nexport type { ScrapperBaseConfig } from './shared'\n\n/** Async-factory config for `/api/article` (full `artifact` resolver, incl. dynamic import). */\nexport type ScrapperArticleConfig = ScrapperBaseConfig<\n ScrapperArticleParams,\n ScrapperArticle,\n ArtifactResolver\n>\n/** Sync-factory config for `/api/article` (`artifact` narrowed to the sync subset). */\nexport type ScrapperArticleConfigSync = ScrapperBaseConfig<\n ScrapperArticleParams,\n ScrapperArticle,\n SyncArtifactResolver\n>\n/** Async-factory config for `/api/links`. */\nexport type ScrapperLinksConfig = ScrapperBaseConfig<\n ScrapperLinksParams,\n ScrapperLinks,\n ArtifactResolver\n>\n/** Sync-factory config for `/api/links`. */\nexport type ScrapperLinksConfigSync = ScrapperBaseConfig<\n ScrapperLinksParams,\n ScrapperLinks,\n SyncArtifactResolver\n>\n\nconst defaultArtifact = () => SpooledJsonArtifact\n\n// ── Factories ──────────────────────────────────────────────────────────────────\n\n/**\n * Create a configured Scrapper **article** {@link Tool} (async — accepts a dynamic-import `artifact`).\n *\n * @remarks\n * Async because `artifact` may be an async / dynamic-import resolver, which must resolve to the sync\n * `() => Ctor` `Tool.artifactConstructor` requires before the tool is built. For the common case,\n * use {@link createScrapperArticleToolSync} and skip the `await`.\n *\n * @warning\n * Two distinct \"headers\": `config.headers` authenticates to the Scrapper *instance*; the\n * `extra_http_headers` *parameter* is what the scraper's browser sends to the *target site* — do not\n * conflate them. Also note `scroll_down` requires a positive `sleep`, and `resultUri`/`screenshotUri`\n * are instance-relative and may come back `http://` even over HTTPS — do not assume they match\n * `instanceUrl`.\n *\n * @param config - Instance URL, instance-auth headers, output policy, `artifact` resolver,\n * per-parameter disposition (`fixed`/`defaults`/`fixedQuery`), and middleware pipelines.\n * @returns A promise of a `Tool` ready to register in a `ToolRegistry`.\n * @throws {@link E_INVALID_SCRAPPER_CONFIG} when `instanceUrl` or `artifact` is invalid.\n */\nexport const createScrapperArticleTool = async (config: ScrapperArticleConfig): Promise<Tool> => {\n const instanceUrl = validateScrapperInstanceUrl(config)\n const artifact = await resolveArtifact(config.artifact ?? defaultArtifact, failConfig)\n return assembleScrapperTool(articleVerb, config, instanceUrl, artifact)\n}\n\n/**\n * Synchronous {@link createScrapperArticleTool} — `artifact` narrowed to the sync subset.\n *\n * @param config - Same as {@link createScrapperArticleTool}, with a sync-only `artifact`.\n * @returns A `Tool` ready to register in a `ToolRegistry`.\n * @throws {@link E_INVALID_SCRAPPER_CONFIG} when `instanceUrl` or `artifact` is invalid (incl. an async resolver).\n */\nexport const createScrapperArticleToolSync = (config: ScrapperArticleConfigSync): Tool => {\n const instanceUrl = validateScrapperInstanceUrl(config)\n const artifact = resolveArtifactSync(config.artifact ?? defaultArtifact, failConfig)\n return assembleScrapperTool(articleVerb, config, instanceUrl, artifact)\n}\n\n/**\n * Create a configured Scrapper **links** {@link Tool} (async — accepts a dynamic-import `artifact`).\n *\n * @remarks\n * See {@link createScrapperArticleTool} for the two-headers caveat and the async rationale. Each\n * `links` item is `{ url, text }`.\n *\n * @param config - Instance URL, instance-auth headers, output policy, `artifact` resolver,\n * per-parameter disposition, and middleware pipelines.\n * @returns A promise of a `Tool` ready to register in a `ToolRegistry`.\n * @throws {@link E_INVALID_SCRAPPER_CONFIG} when `instanceUrl` or `artifact` is invalid.\n */\nexport const createScrapperLinksTool = async (config: ScrapperLinksConfig): Promise<Tool> => {\n const instanceUrl = validateScrapperInstanceUrl(config)\n const artifact = await resolveArtifact(config.artifact ?? defaultArtifact, failConfig)\n return assembleScrapperTool(linksVerb, config, instanceUrl, artifact)\n}\n\n/**\n * Synchronous {@link createScrapperLinksTool} — `artifact` narrowed to the sync subset.\n *\n * @param config - Same as {@link createScrapperLinksTool}, with a sync-only `artifact`.\n * @returns A `Tool` ready to register in a `ToolRegistry`.\n * @throws {@link E_INVALID_SCRAPPER_CONFIG} when `instanceUrl` or `artifact` is invalid (incl. an async resolver).\n */\nexport const createScrapperLinksToolSync = (config: ScrapperLinksConfigSync): Tool => {\n const instanceUrl = validateScrapperInstanceUrl(config)\n const artifact = resolveArtifactSync(config.artifact ?? defaultArtifact, failConfig)\n return assembleScrapperTool(linksVerb, config, instanceUrl, artifact)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"scrapper-B8xG9lTD.cjs","names":[],"sources":["../src/batteries/tools/scrapper/exceptions.ts","../src/batteries/tools/scrapper/shared.ts","../src/batteries/tools/scrapper/index.ts"],"sourcesContent":["/**\n * Battery-scoped exception constructors for the Scrapper web-extraction tool.\n *\n * @remarks\n * Battery-scoped exception classes owned by the Scrapper tool battery (not the ADK core). Minted\n * via `createException` from `@nhtio/adk/factories` and re-exported from the battery's barrel\n * (`@nhtio/adk/batteries/tools/scrapper`). This file intentionally carries **no** `@module` tag:\n * it is an internal sibling relative-imported by `index.ts`, so it does not mint its own\n * `…/scrapper/exceptions` entrypoint (whose `exceptions` leaf basename would collide with sibling\n * batteries under the `vite-plugin-dts` rolled-up `.d.ts` rule).\n */\n\nimport { createException } from '@nhtio/adk/factories'\n\n/**\n * Thrown when a Scrapper factory receives invalid configuration.\n *\n * @remarks\n * Fatal: config bugs (missing/unparseable `instanceUrl`, a bad `artifact` resolver, or an async\n * resolver passed to a `*Sync` factory) fail loud at factory-call time rather than at first scrape.\n */\nexport const E_INVALID_SCRAPPER_CONFIG = createException<[string]>(\n 'E_INVALID_SCRAPPER_CONFIG',\n 'Invalid Scrapper tool config: %s',\n 'E_INVALID_SCRAPPER_CONFIG',\n 529,\n true\n)\n","/**\n * Internal core shared by both Scrapper verbs (article / links).\n *\n * @remarks\n * No `@module` tag — this is a sibling of `index.ts`, relative-imported, not its own entrypoint.\n * Houses the per-parameter disposition machinery (schema building from `fixed`/`defaults`), the\n * snake→kebab wire mapping, the request/response contexts, and the `fetch`+pipeline handler core.\n * Generic harness helpers (artifact/header resolution, pipeline runners) come from `../_shared`.\n */\n\nimport { Tool } from '@nhtio/adk/forge'\nimport { isError } from '@nhtio/adk/guards'\nimport { validator } from '@nhtio/validation'\nimport { Middleware } from '@nhtio/middleware'\nimport { E_INVALID_SCRAPPER_CONFIG } from './exceptions'\nimport {\n resolveHeaders,\n makeShortCircuit,\n isShortCircuit,\n runInputPipeline,\n runOutputPipeline,\n runToolGate,\n type ToolGateFn,\n type ToolHeaders,\n type ToolHeadersResolver,\n type SpooledArtifactCtor,\n type MiddlewareFn,\n} from '../_shared'\nimport type { Schema } from '@nhtio/validation'\nimport type { NextFn } from '@nhtio/middleware'\n\nconst DEFAULT_REQUEST_TIMEOUT = 65_000\n\n/** Throw the battery-scoped config error. */\nexport const failConfig = (reason: string): never => {\n throw new E_INVALID_SCRAPPER_CONFIG([reason])\n}\n\n// ── Parameter specs (per-parameter disposition) ──────────────────────────────\n\n/** The wire type of a Scrapper query parameter — controls serialisation. */\nexport type ScrapperParamType = 'string' | 'number' | 'boolean'\n\n/**\n * One curated, model-facing Scrapper parameter: its snake_case key (used in the model schema and\n * in `fixed`/`defaults`), its kebab-case wire name, its type, the base validator, and a description.\n */\nexport interface ScrapperParamSpec {\n /** snake_case key as seen by the model and in `config.fixed` / `config.defaults`. */\n key: string\n /** kebab-case name sent to the Scrapper API. */\n wire: string\n /** Wire type, controlling string/number/boolean serialisation. */\n type: ScrapperParamType\n /** Base `@nhtio/validation` schema (no `.required()`/`.default()`/`.optional()` applied yet). */\n schema: Schema\n /** Human-readable description surfaced to the model. */\n description: string\n}\n\n/** Serialise a parameter value to its wire string. */\nconst toWire = (value: unknown): string => String(value)\n\n/**\n * Build the model-facing input schema from a verb's param specs and the factory's disposition.\n * `url` is always required. A `fixed` param is omitted (the model can't set it); a `defaults` param\n * gets `.default(value)`; everything else is `.optional()`.\n */\nexport const buildScrapperSchema = (\n specs: ScrapperParamSpec[],\n fixed: Record<string, unknown> | undefined,\n defaults: Record<string, unknown> | undefined,\n extra: Record<string, Schema> = {}\n): Schema => {\n const shape: Record<string, Schema> = {\n url: validator.string().required().description('The absolute URL of the page to load.'),\n }\n for (const spec of specs) {\n if (fixed && spec.key in fixed) continue // pinned → not model-visible\n let sch = spec.schema\n if (defaults && spec.key in defaults) {\n sch = sch.default(defaults[spec.key] as never)\n } else {\n sch = sch.optional()\n }\n shape[spec.key] = sch.description(spec.description)\n }\n return validator.object({ ...shape, ...extra })\n}\n\n/**\n * Assemble the wire-kebab query params for one request: each spec's value is `fixed` (if pinned)\n * else the validated model/default value; then `fixedQuery` raw passthrough is layered on. `url`\n * is handled separately (it is the search target, never pinned).\n *\n * @remarks\n * An empty string (`''`) is deliberately treated the same as `undefined`/`null` and never\n * forwarded — this is what lets the schema's `.allow('')` on optional string specs actually\n * mean \"don't set this,\" instead of sending e.g. `user-agent=` to the wire. This applies\n * generically to every spec (no per-spec-type branching), including a `fixed`-pinned value that\n * happens to be `''` — an explicitly pinned empty string still means \"don't send it.\"\n */\nexport const buildWireParams = (\n args: Record<string, unknown>,\n specs: ScrapperParamSpec[],\n fixed: Record<string, unknown> | undefined,\n fixedQuery: Record<string, string> | undefined\n): Record<string, string> => {\n const out: Record<string, string> = {}\n for (const spec of specs) {\n const value = fixed && spec.key in fixed ? fixed[spec.key] : args[spec.key]\n const isEmptyString = typeof value === 'string' && value.length === 0\n if (value !== undefined && value !== null && !isEmptyString) out[spec.wire] = toWire(value)\n }\n for (const [k, v] of Object.entries(fixedQuery ?? {})) out[k] = v\n return out\n}\n\n// ── Contexts ─────────────────────────────────────────────────────────────────\n\n/**\n * Mutable context handed to each input-pipeline stage **before** the HTTP request is sent.\n * Identical for both verbs.\n */\nexport interface ScrapperRequestContext {\n /** The tool's name (read-only). */\n readonly toolName: string\n /** The target page URL (the `url` argument). Mutable. */\n url: string\n /** Wire-kebab query params (everything except `url`). Mutable. */\n params: Record<string, string>\n /** Resolved request headers sent to the SCRAPPER INSTANCE (auth). Mutable. */\n headers: ToolHeaders\n /** The Scrapper instance base URL (read-only). */\n readonly instanceUrl: string\n /** Cross-stage scratch space; also carried onto the response context. */\n readonly stash: Map<string, unknown>\n /** Skip the fetch and return `result` verbatim as the tool's output (e.g. a cache hit). */\n shortCircuit(result: string): void\n}\n\n/**\n * Mutable context handed to each output-pipeline stage **after** the response JSON is parsed.\n *\n * @typeParam R - The verb's normalised result type (article object or links payload).\n */\nexport interface ScrapperResponseContext<R> {\n /** The tool's name (read-only). */\n readonly toolName: string\n /** The request context as it was sent (post-input-pipeline). */\n readonly request: ScrapperRequestContext\n /** The parsed Scrapper JSON body. Mutable (used when `format` is `raw`). */\n raw: unknown\n /** The normalised result. Mutable — reshape, redact, enrich. */\n result: R\n /** The effective payload shape for this call. */\n format: 'normalized' | 'raw'\n /** When set, used verbatim as the tool's output (overrides serialisation). */\n output?: string\n /** Cross-stage scratch space; carried over from the request context. */\n readonly stash: Map<string, unknown>\n}\n\n/** An input-pipeline stage. Onion middleware over {@link ScrapperRequestContext}. */\nexport type ScrapperInputMiddlewareFn = (\n ctx: ScrapperRequestContext,\n next: NextFn\n) => void | Promise<void>\n\n/** An output-pipeline stage over a verb's {@link ScrapperResponseContext}. */\nexport type ScrapperOutputMiddlewareFn<R> = (\n ctx: ScrapperResponseContext<R>,\n next: NextFn\n) => void | Promise<void>\n\n// ── Config (shared shape; `artifact` variant supplied by the verb factory) ────\n\n/** Configuration common to every Scrapper factory. `A` is the accepted `artifact` resolver type. */\nexport interface ScrapperBaseConfig<P, R, A> {\n /** Base URL of the Scrapper instance, e.g. `https://scrapper.example.org`. Required. */\n instanceUrl: string\n /** Headers sent to the Scrapper INSTANCE for auth (X-API-Key / Basic) — static or resolver. */\n headers?: ToolHeaders | ToolHeadersResolver\n /** The tool's own `fetch` AbortController timeout in ms. Default `65_000` (> Scrapper's 60s browser default). */\n requestTimeoutMs?: number\n /** Output shape. `normalized`/`raw` pin it; `either` (default) exposes a `format` arg to the model. */\n resultFormat?: 'normalized' | 'raw' | 'either'\n /** Spool-artifact resolver for the output. Default `() => SpooledJsonArtifact`. */\n artifact?: A\n /** Tool name override. */\n name?: string\n /** Tool description override. */\n description?: string\n /** Pinned params — sent always, removed from the model schema. */\n fixed?: Partial<P>\n /** Model-overridable default param values. */\n defaults?: Partial<P>\n /** Raw, un-modeled wire params (kebab keys) — always sent, never model-visible. Keeps the battery generic. */\n fixedQuery?: Record<string, string>\n /**\n * Optional per-call gate run before the HTTP request — the seam for human-approval/RBAC\n * flows built on `ctx.waitFor` (the ADK gates primitive). Throwing aborts the call through\n * the standard tool-error path. Scraping reaches the network on the agent's behalf, which\n * makes every call a candidate for gating.\n */\n gate?: ToolGateFn\n /** Stages run before the HTTP request. See {@link ScrapperRequestContext}. */\n inputPipeline?: ScrapperInputMiddlewareFn[]\n /** Stages run after the response is parsed. See {@link ScrapperResponseContext}. */\n outputPipeline?: ScrapperOutputMiddlewareFn<R>[]\n}\n\n/** Verb-specific wiring passed to {@link assembleScrapperTool}. */\nexport interface ScrapperVerb<R> {\n /** Scrapper endpoint path, e.g. `/api/article`. */\n endpoint: string\n /** The curated param specs for this verb. */\n specs: ScrapperParamSpec[]\n /** Default tool name (`scrapper_article` / `scrapper_links`). */\n defaultName: string\n /** Default tool description. */\n defaultDescription: string\n /** Map a parsed Scrapper body to the verb's normalised result. */\n normalize: (body: Record<string, unknown>) => R\n}\n\n/** Parse a Scrapper error body (`{ detail: [{ msg }] }`) into a single message, best-effort. */\nconst parseScrapperError = (body: unknown, status: number, statusText: string): string => {\n if (body && typeof body === 'object' && Array.isArray((body as { detail?: unknown }).detail)) {\n const detail = (body as { detail: Array<{ msg?: unknown; loc?: unknown }> }).detail\n const msgs = detail\n .map((d) => {\n const loc = Array.isArray(d.loc) ? d.loc.join('.') : undefined\n const msg = typeof d.msg === 'string' ? d.msg : undefined\n if (msg && loc) return `${loc}: ${msg}`\n return msg ?? loc\n })\n .filter((m): m is string => typeof m === 'string')\n if (msgs.length) return msgs.join('; ')\n }\n return `HTTP ${status} ${statusText}`.trim()\n}\n\n/**\n * Build a configured Scrapper {@link Tool} from validated config + an already-resolved sync\n * artifact constructor. Shared by every verb and by both the async and sync factories.\n */\nexport const assembleScrapperTool = <P, R>(\n verb: ScrapperVerb<R>,\n config: ScrapperBaseConfig<P, R, unknown>,\n instanceUrl: string,\n artifactConstructor: () => SpooledArtifactCtor\n): Tool => {\n const requestTimeoutMs = config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT\n const resultFormat = config.resultFormat ?? 'either'\n const toolName = config.name ?? verb.defaultName\n const fixed = config.fixed as Record<string, unknown> | undefined\n const defaults = config.defaults as Record<string, unknown> | undefined\n\n const inputMw = new Middleware<MiddlewareFn<ScrapperRequestContext>>()\n for (const fn of config.inputPipeline ?? []) inputMw.add(fn)\n const outputMw = new Middleware<MiddlewareFn<ScrapperResponseContext<R>>>()\n for (const fn of config.outputPipeline ?? [])\n outputMw.add(fn as MiddlewareFn<ScrapperResponseContext<R>>)\n const hasInput = (config.inputPipeline ?? []).length > 0\n const hasOutput = (config.outputPipeline ?? []).length > 0\n\n // Build the schema, conditionally exposing `format` only when the factory is neutral.\n const extra: Record<string, Schema> =\n resultFormat === 'either'\n ? {\n format: validator\n .string()\n .valid('normalized', 'raw')\n .default('normalized')\n .description('Output shape: \"normalized\" (trimmed) or \"raw\" (full Scrapper JSON).'),\n }\n : {}\n const inputSchema = buildScrapperSchema(verb.specs, fixed, defaults, extra)\n\n return new Tool({\n name: toolName,\n description: config.description ?? verb.defaultDescription,\n inputSchema,\n artifactConstructor,\n handler: async (args, handlerCtx) => {\n const a = args as Record<string, unknown> & { url: string; format?: 'normalized' | 'raw' }\n await runToolGate(config.gate, handlerCtx, toolName, args)\n try {\n const format: 'normalized' | 'raw' =\n resultFormat === 'either' ? (a.format ?? 'normalized') : resultFormat\n\n const headers: ToolHeaders = {\n Accept: 'application/json',\n ...(await resolveHeaders(config.headers)),\n }\n\n const params = buildWireParams(a, verb.specs, fixed, config.fixedQuery)\n const stash = new Map<string, unknown>()\n\n const requestCtx: ScrapperRequestContext = {\n toolName,\n url: a.url,\n params,\n headers,\n instanceUrl,\n stash,\n shortCircuit: makeShortCircuit(),\n }\n\n if (hasInput) {\n const short = await runInputPipeline(inputMw, requestCtx, 'Scrapper')\n if (short !== undefined) return short\n }\n\n const url = new URL(verb.endpoint, instanceUrl + '/')\n url.searchParams.set('url', requestCtx.url)\n for (const [k, v] of Object.entries(requestCtx.params)) url.searchParams.set(k, v)\n\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), requestTimeoutMs)\n let response: Response\n try {\n response = await fetch(url, {\n method: 'GET',\n headers: requestCtx.headers,\n signal: controller.signal,\n })\n } finally {\n clearTimeout(timer)\n }\n\n if (!response.ok) {\n let body: unknown\n try {\n body = await response.json()\n } catch {\n body = undefined\n }\n return `Error: Scrapper request failed — ${parseScrapperError(body, response.status, response.statusText)}.`\n }\n\n const body = (await response.json()) as Record<string, unknown>\n\n const responseCtx: ScrapperResponseContext<R> = {\n toolName,\n request: requestCtx,\n raw: body,\n result: verb.normalize(body),\n format,\n stash,\n }\n\n if (hasOutput) await runOutputPipeline(outputMw, responseCtx, 'Scrapper')\n\n if (typeof responseCtx.output === 'string') return responseCtx.output\n if (responseCtx.format === 'raw') return JSON.stringify(responseCtx.raw, null, 2)\n return JSON.stringify(responseCtx.result, null, 2)\n } catch (err) {\n if (isShortCircuit(err)) return err.result\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n })\n}\n\n/** Validate `instanceUrl` and return the trailing-slash-normalised base. */\nexport const validateScrapperInstanceUrl = (config: { instanceUrl?: string }): string => {\n if (typeof config?.instanceUrl !== 'string' || config.instanceUrl.trim() === '') {\n failConfig('instanceUrl is required')\n }\n try {\n new URL(config.instanceUrl as string)\n } catch {\n failConfig(`instanceUrl is not a valid URL: ${config.instanceUrl}`)\n }\n return (config.instanceUrl as string).replace(/\\/+$/, '')\n}\n","/**\n * Factories for configured Scrapper web-extraction tools (article + links).\n *\n * @module @nhtio/adk/batteries/tools/scrapper\n *\n * @remarks\n * [Scrapper](https://github.com/amerkurev/scrapper) is a self-hosted service that loads a page in a\n * real headless browser and extracts either the readable article (`/api/article`) or the page's\n * links (`/api/links`). It gives an agent browser-grade reading power — JS-rendered pages a\n * renderless fetcher can't see — but as a **stateless** HTTP call: each request runs in a fresh\n * incognito context, stores no session or credentials, and shares nothing with any other call.\n *\n * Like the SearXNG battery, this exports **factories** (not ready-made `Tool` constants), because a\n * scrape tool needs per-deployment config (instance URL + custom auth headers). Two verbs, each with\n * an async factory ({@link createScrapperArticleTool} / {@link createScrapperLinksTool}, accepting a\n * dynamic-import `artifact` resolver) and a sync variant ({@link createScrapperArticleToolSync} /\n * {@link createScrapperLinksToolSync}). Because these are factories, they MUST NOT be bulk-registered\n * via `Object.values(batteries)` — call one, then register the returned tool.\n *\n * @see https://github.com/amerkurev/scrapper\n */\n\nimport { validator } from '@nhtio/validation'\nimport { SpooledJsonArtifact } from '@nhtio/adk/spooled_artifact'\nimport { resolveArtifact, resolveArtifactSync } from '../_shared'\nimport {\n failConfig,\n validateScrapperInstanceUrl,\n assembleScrapperTool,\n type ScrapperBaseConfig,\n type ScrapperParamSpec,\n type ScrapperVerb,\n} from './shared'\nimport type { Tool } from '@nhtio/adk/forge'\nimport type { ArtifactResolver, SyncArtifactResolver } from '../_shared'\n\nexport { E_INVALID_SCRAPPER_CONFIG } from './exceptions'\nexport type {\n ScrapperRequestContext,\n ScrapperResponseContext,\n ScrapperInputMiddlewareFn,\n ScrapperOutputMiddlewareFn,\n} from './shared'\n\n// ── Param sets ───────────────────────────────────────────────────────────────\n\n/** Model-facing params common to both verbs (snake_case; mapped to kebab on the wire). */\nexport interface ScrapperCommonParams {\n /** Return a cached result when available instead of re-scraping. */\n cache?: boolean\n /** Capture a screenshot; the result carries a `screenshotUri`. */\n screenshot?: boolean\n /** Run in an incognito browser context (no persisted browsing data). Default true upstream. */\n incognito?: boolean\n /** Browser navigation timeout in ms (`0` disables). Distinct from the tool's own fetch timeout. */\n timeout?: number\n /** When navigation is considered finished. */\n wait_until?: 'load' | 'domcontentloaded' | 'networkidle' | 'commit'\n /** Wait this many ms after load before parsing. */\n sleep?: number\n /** Scroll down N pixels for lazy-loading pages. Requires a positive `sleep`. */\n scroll_down?: number\n /** Emulated device, e.g. `Desktop Chrome`. Overrides individual viewport/UA settings. */\n device?: string\n /** Explicit user-agent (prefer `device`). */\n user_agent?: string\n /** Extra headers the SCRAPER's browser sends to the TARGET site, `K:v;K2:v2` (NOT instance auth). */\n extra_http_headers?: string\n /** Upstream proxy, e.g. `http://host:3128` or `socks5://host:1080`. */\n proxy_server?: string\n}\n\n/** Model-facing params for `/api/article`. */\nexport interface ScrapperArticleParams extends ScrapperCommonParams {\n /** Populate `fullContent` with the page's full HTML. */\n full_content?: boolean\n}\n\n/** Model-facing params for `/api/links`. */\nexport interface ScrapperLinksParams extends ScrapperCommonParams {\n /** Median link-text length threshold for the link parser. */\n text_len_threshold?: number\n /** Median words-per-link threshold for the link parser. */\n words_threshold?: number\n}\n\nconst commonSpecs: ScrapperParamSpec[] = [\n {\n key: 'cache',\n wire: 'cache',\n type: 'boolean',\n schema: validator.boolean(),\n description: 'Return a cached result when available instead of re-scraping.',\n },\n {\n key: 'screenshot',\n wire: 'screenshot',\n type: 'boolean',\n schema: validator.boolean(),\n description: 'Capture a screenshot; the result carries a screenshotUri.',\n },\n {\n key: 'incognito',\n wire: 'incognito',\n type: 'boolean',\n schema: validator.boolean(),\n description: 'Run in an incognito browser context (no persisted data).',\n },\n {\n key: 'timeout',\n wire: 'timeout',\n type: 'number',\n schema: validator.number().min(0),\n description: 'Browser navigation timeout in ms (0 disables).',\n },\n {\n key: 'wait_until',\n wire: 'wait-until',\n type: 'string',\n schema: validator.string().valid('load', 'domcontentloaded', 'networkidle', 'commit'),\n description: 'When navigation is considered finished.',\n },\n {\n key: 'sleep',\n wire: 'sleep',\n type: 'number',\n schema: validator.number().min(0),\n description: 'Wait this many ms after load before parsing.',\n },\n {\n key: 'scroll_down',\n wire: 'scroll-down',\n type: 'number',\n schema: validator.number().min(0),\n description: 'Scroll down N pixels for lazy-loading pages (requires a positive sleep).',\n },\n {\n key: 'device',\n wire: 'device',\n type: 'string',\n schema: validator.string().allow(''),\n description:\n 'Emulated device, e.g. \"Desktop Chrome\". Omit or send an empty string to leave it unset.',\n },\n {\n key: 'user_agent',\n wire: 'user-agent',\n type: 'string',\n schema: validator.string().allow(''),\n description:\n 'Explicit user-agent (prefer device). Omit or send an empty string to leave it unset.',\n },\n {\n key: 'extra_http_headers',\n wire: 'extra-http-headers',\n type: 'string',\n schema: validator.string().allow(''),\n description:\n 'Extra headers the scraper sends to the TARGET site, formatted \"K:v;K2:v2\". Omit or send an empty string to send none.',\n },\n {\n key: 'proxy_server',\n wire: 'proxy-server',\n type: 'string',\n schema: validator.string().allow(''),\n description:\n 'Upstream proxy, e.g. \"http://host:3128\" or \"socks5://host:1080\". Omit or send an empty string to use no proxy.',\n },\n]\n\nconst articleSpecs: ScrapperParamSpec[] = [\n ...commonSpecs,\n {\n key: 'full_content',\n wire: 'full-content',\n type: 'boolean',\n schema: validator.boolean(),\n description: 'Populate fullContent with the page full HTML.',\n },\n]\n\nconst linksSpecs: ScrapperParamSpec[] = [\n ...commonSpecs,\n {\n key: 'text_len_threshold',\n wire: 'text-len-threshold',\n type: 'number',\n schema: validator.number().min(0),\n description: 'Median link-text length threshold for the link parser.',\n },\n {\n key: 'words_threshold',\n wire: 'words-threshold',\n type: 'number',\n schema: validator.number().min(0),\n description: 'Median words-per-link threshold for the link parser.',\n },\n]\n\n// ── Normalised result shapes ─────────────────────────────────────────────────\n\n/** A normalised Scrapper article (loose/nullable upstream). */\nexport interface ScrapperArticle {\n /** The page URL the article was extracted from. */\n url?: string\n /** Article title. */\n title?: string\n /** Author / byline metadata. */\n byline?: string\n /** Short excerpt or description of the article. */\n excerpt?: string\n /** Name of the site the article came from. */\n siteName?: string\n /** Detected content language. */\n lang?: string\n /** Character count of the extracted article text. */\n length?: number\n /** Publication time, when the page exposed one. */\n publishedTime?: string\n /** Scrapper's own date field for the result. */\n date?: string\n /** Article text with HTML stripped. */\n textContent?: string\n /** Processed article HTML; present when the caller requested it. */\n content?: string\n /** Full page HTML; present only when `full_content` was set. */\n fullContent?: string\n /** Screenshot URI; present only when `screenshot` was set. */\n screenshotUri?: string\n}\n\n/** A single link from `/api/links` (verified live: `{ url, text }`). */\nexport interface ScrapperLink {\n /** The link's target URL. */\n url?: string\n /** The link's anchor text. */\n text?: string\n}\n\n/** A normalised Scrapper links payload. */\nexport interface ScrapperLinks {\n /** The page URL the links were collected from. */\n url?: string\n /** The page title. */\n title?: string\n /** The page's domain. */\n domain?: string\n /** Scrapper's own date field for the result. */\n date?: string\n /** The collected links, each `{ url, text }`. */\n links: ScrapperLink[]\n /** Screenshot URI; present only when `screenshot` was set. */\n screenshotUri?: string\n}\n\nconst str = (v: unknown): string | undefined => (typeof v === 'string' ? v : undefined)\nconst num = (v: unknown): number | undefined => (typeof v === 'number' ? v : undefined)\n\nconst normalizeArticle = (body: Record<string, unknown>): ScrapperArticle => {\n const out: ScrapperArticle = {}\n out.url = str(body.url)\n out.title = str(body.title)\n out.byline = str(body.byline)\n out.excerpt = str(body.excerpt)\n out.siteName = str(body.siteName)\n out.lang = str(body.lang)\n out.length = num(body.length)\n out.publishedTime = str(body.publishedTime)\n out.date = str(body.date)\n out.textContent = str(body.textContent)\n if (str(body.content)) out.content = str(body.content)\n if (str(body.fullContent)) out.fullContent = str(body.fullContent)\n if (str(body.screenshotUri)) out.screenshotUri = str(body.screenshotUri)\n // Drop undefined keys so the serialised payload stays tight.\n return JSON.parse(JSON.stringify(out)) as ScrapperArticle\n}\n\nconst normalizeLinks = (body: Record<string, unknown>): ScrapperLinks => {\n const rawLinks = Array.isArray(body.links) ? body.links : []\n const links: ScrapperLink[] = rawLinks.map((l) => {\n const r = (l ?? {}) as Record<string, unknown>\n const item: ScrapperLink = {}\n if (str(r.url)) item.url = str(r.url)\n if (str(r.text)) item.text = str(r.text)\n return item\n })\n const out: ScrapperLinks = { links }\n if (str(body.url)) out.url = str(body.url)\n if (str(body.title)) out.title = str(body.title)\n if (str(body.domain)) out.domain = str(body.domain)\n if (str(body.date)) out.date = str(body.date)\n if (str(body.screenshotUri)) out.screenshotUri = str(body.screenshotUri)\n return out\n}\n\nconst articleVerb: ScrapperVerb<ScrapperArticle> = {\n endpoint: '/api/article',\n specs: articleSpecs,\n defaultName: 'scrapper_article',\n defaultDescription:\n 'Load a web page in a real (headless) browser and extract its readable article — title, ' +\n 'byline, text content, and metadata. Renders JavaScript-heavy pages a plain fetch cannot. ' +\n 'Each call is stateless (fresh incognito context, no stored session).',\n normalize: normalizeArticle,\n}\n\nconst linksVerb: ScrapperVerb<ScrapperLinks> = {\n endpoint: '/api/links',\n specs: linksSpecs,\n defaultName: 'scrapper_links',\n defaultDescription:\n 'Load a web page in a real (headless) browser and collect its article/navigation links ' +\n '(each { url, text }). Renders JavaScript-heavy index pages a plain fetch cannot. ' +\n 'Each call is stateless (fresh incognito context, no stored session).',\n normalize: normalizeLinks,\n}\n\n// ── Config aliases ────────────────────────────────────────────────────────────\n\nexport type { ScrapperBaseConfig } from './shared'\n\n/** Async-factory config for `/api/article` (full `artifact` resolver, incl. dynamic import). */\nexport type ScrapperArticleConfig = ScrapperBaseConfig<\n ScrapperArticleParams,\n ScrapperArticle,\n ArtifactResolver\n>\n/** Sync-factory config for `/api/article` (`artifact` narrowed to the sync subset). */\nexport type ScrapperArticleConfigSync = ScrapperBaseConfig<\n ScrapperArticleParams,\n ScrapperArticle,\n SyncArtifactResolver\n>\n/** Async-factory config for `/api/links`. */\nexport type ScrapperLinksConfig = ScrapperBaseConfig<\n ScrapperLinksParams,\n ScrapperLinks,\n ArtifactResolver\n>\n/** Sync-factory config for `/api/links`. */\nexport type ScrapperLinksConfigSync = ScrapperBaseConfig<\n ScrapperLinksParams,\n ScrapperLinks,\n SyncArtifactResolver\n>\n\nconst defaultArtifact = () => SpooledJsonArtifact\n\n// ── Factories ──────────────────────────────────────────────────────────────────\n\n/**\n * Create a configured Scrapper **article** {@link Tool} (async — accepts a dynamic-import `artifact`).\n *\n * @remarks\n * Async because `artifact` may be an async / dynamic-import resolver, which must resolve to the sync\n * `() => Ctor` `Tool.artifactConstructor` requires before the tool is built. For the common case,\n * use {@link createScrapperArticleToolSync} and skip the `await`.\n *\n * @warning\n * Two distinct \"headers\": `config.headers` authenticates to the Scrapper *instance*; the\n * `extra_http_headers` *parameter* is what the scraper's browser sends to the *target site* — do not\n * conflate them. Also note `scroll_down` requires a positive `sleep`, and `resultUri`/`screenshotUri`\n * are instance-relative and may come back `http://` even over HTTPS — do not assume they match\n * `instanceUrl`.\n *\n * @param config - Instance URL, instance-auth headers, output policy, `artifact` resolver,\n * per-parameter disposition (`fixed`/`defaults`/`fixedQuery`), and middleware pipelines.\n * @returns A promise of a `Tool` ready to register in a `ToolRegistry`.\n * @throws {@link E_INVALID_SCRAPPER_CONFIG} when `instanceUrl` or `artifact` is invalid.\n */\nexport const createScrapperArticleTool = async (config: ScrapperArticleConfig): Promise<Tool> => {\n const instanceUrl = validateScrapperInstanceUrl(config)\n const artifact = await resolveArtifact(config.artifact ?? defaultArtifact, failConfig)\n return assembleScrapperTool(articleVerb, config, instanceUrl, artifact)\n}\n\n/**\n * Synchronous {@link createScrapperArticleTool} — `artifact` narrowed to the sync subset.\n *\n * @param config - Same as {@link createScrapperArticleTool}, with a sync-only `artifact`.\n * @returns A `Tool` ready to register in a `ToolRegistry`.\n * @throws {@link E_INVALID_SCRAPPER_CONFIG} when `instanceUrl` or `artifact` is invalid (incl. an async resolver).\n */\nexport const createScrapperArticleToolSync = (config: ScrapperArticleConfigSync): Tool => {\n const instanceUrl = validateScrapperInstanceUrl(config)\n const artifact = resolveArtifactSync(config.artifact ?? defaultArtifact, failConfig)\n return assembleScrapperTool(articleVerb, config, instanceUrl, artifact)\n}\n\n/**\n * Create a configured Scrapper **links** {@link Tool} (async — accepts a dynamic-import `artifact`).\n *\n * @remarks\n * See {@link createScrapperArticleTool} for the two-headers caveat and the async rationale. Each\n * `links` item is `{ url, text }`.\n *\n * @param config - Instance URL, instance-auth headers, output policy, `artifact` resolver,\n * per-parameter disposition, and middleware pipelines.\n * @returns A promise of a `Tool` ready to register in a `ToolRegistry`.\n * @throws {@link E_INVALID_SCRAPPER_CONFIG} when `instanceUrl` or `artifact` is invalid.\n */\nexport const createScrapperLinksTool = async (config: ScrapperLinksConfig): Promise<Tool> => {\n const instanceUrl = validateScrapperInstanceUrl(config)\n const artifact = await resolveArtifact(config.artifact ?? defaultArtifact, failConfig)\n return assembleScrapperTool(linksVerb, config, instanceUrl, artifact)\n}\n\n/**\n * Synchronous {@link createScrapperLinksTool} — `artifact` narrowed to the sync subset.\n *\n * @param config - Same as {@link createScrapperLinksTool}, with a sync-only `artifact`.\n * @returns A `Tool` ready to register in a `ToolRegistry`.\n * @throws {@link E_INVALID_SCRAPPER_CONFIG} when `instanceUrl` or `artifact` is invalid (incl. an async resolver).\n */\nexport const createScrapperLinksToolSync = (config: ScrapperLinksConfigSync): Tool => {\n const instanceUrl = validateScrapperInstanceUrl(config)\n const artifact = resolveArtifactSync(config.artifact ?? defaultArtifact, failConfig)\n return assembleScrapperTool(linksVerb, config, instanceUrl, artifact)\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  import { t as createException } from "./exceptions-DRYLe-J4.mjs";
2
2
  import { t as isError } from "./guards-BEpY7lBI.mjs";
3
- import { f as Tool } from "./spooled_artifact-BkOe4-j-.mjs";
4
- import { n as SpooledJsonArtifact } from "./spooled_markdown_artifact-Dnl-lCGv.mjs";
5
- import "./factories.mjs";
3
+ import { p as Tool } from "./spooled_artifact-Bw_7swIp.mjs";
4
+ import { n as SpooledJsonArtifact } from "./spooled_markdown_artifact-vd6eNtIP.mjs";
6
5
  import "./forge.mjs";
6
+ import "./factories.mjs";
7
7
  import "./guards.mjs";
8
8
  import "./spooled_artifact.mjs";
9
9
  import { isShortCircuit, makeShortCircuit, resolveArtifact, resolveArtifactSync, resolveHeaders, runInputPipeline, runOutputPipeline, runToolGate } from "./batteries/tools/_shared.mjs";
@@ -438,4 +438,4 @@ var createScrapperLinksToolSync = (config) => {
438
438
  //#endregion
439
439
  export { E_INVALID_SCRAPPER_CONFIG as a, createScrapperLinksToolSync as i, createScrapperArticleToolSync as n, createScrapperLinksTool as r, createScrapperArticleTool as t };
440
440
 
441
- //# sourceMappingURL=scrapper-_JzgbLG5.mjs.map
441
+ //# sourceMappingURL=scrapper-DiQ5FfDL.mjs.map