@nhtio/adk 0.1.0-master-f0aa531d

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 (297) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +3 -0
  3. package/batteries/index.d.ts +28 -0
  4. package/batteries/llm/index.d.ts +11 -0
  5. package/batteries/llm/openai_chat_completions/adapter.cjs +916 -0
  6. package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -0
  7. package/batteries/llm/openai_chat_completions/adapter.d.ts +101 -0
  8. package/batteries/llm/openai_chat_completions/adapter.mjs +914 -0
  9. package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -0
  10. package/batteries/llm/openai_chat_completions/exceptions.cjs +89 -0
  11. package/batteries/llm/openai_chat_completions/exceptions.cjs.map +1 -0
  12. package/batteries/llm/openai_chat_completions/exceptions.d.ts +97 -0
  13. package/batteries/llm/openai_chat_completions/exceptions.mjs +81 -0
  14. package/batteries/llm/openai_chat_completions/exceptions.mjs.map +1 -0
  15. package/batteries/llm/openai_chat_completions/helpers.cjs +819 -0
  16. package/batteries/llm/openai_chat_completions/helpers.cjs.map +1 -0
  17. package/batteries/llm/openai_chat_completions/helpers.d.ts +233 -0
  18. package/batteries/llm/openai_chat_completions/helpers.mjs +783 -0
  19. package/batteries/llm/openai_chat_completions/helpers.mjs.map +1 -0
  20. package/batteries/llm/openai_chat_completions/index.d.ts +27 -0
  21. package/batteries/llm/openai_chat_completions/types.cjs +1 -0
  22. package/batteries/llm/openai_chat_completions/types.d.ts +524 -0
  23. package/batteries/llm/openai_chat_completions/types.mjs +0 -0
  24. package/batteries/llm/openai_chat_completions/validation.cjs +190 -0
  25. package/batteries/llm/openai_chat_completions/validation.cjs.map +1 -0
  26. package/batteries/llm/openai_chat_completions/validation.d.ts +31 -0
  27. package/batteries/llm/openai_chat_completions/validation.mjs +187 -0
  28. package/batteries/llm/openai_chat_completions/validation.mjs.map +1 -0
  29. package/batteries/llm/openai_chat_completions.cjs +51 -0
  30. package/batteries/llm/openai_chat_completions.mjs +5 -0
  31. package/batteries/llm/webllm_chat_completions/adapter.cjs +658 -0
  32. package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -0
  33. package/batteries/llm/webllm_chat_completions/adapter.d.ts +103 -0
  34. package/batteries/llm/webllm_chat_completions/adapter.mjs +656 -0
  35. package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -0
  36. package/batteries/llm/webllm_chat_completions/exceptions.cjs +70 -0
  37. package/batteries/llm/webllm_chat_completions/exceptions.cjs.map +1 -0
  38. package/batteries/llm/webllm_chat_completions/exceptions.d.ts +74 -0
  39. package/batteries/llm/webllm_chat_completions/exceptions.mjs +65 -0
  40. package/batteries/llm/webllm_chat_completions/exceptions.mjs.map +1 -0
  41. package/batteries/llm/webllm_chat_completions/helpers.cjs +38 -0
  42. package/batteries/llm/webllm_chat_completions/helpers.d.ts +6 -0
  43. package/batteries/llm/webllm_chat_completions/helpers.mjs +2 -0
  44. package/batteries/llm/webllm_chat_completions/index.d.ts +25 -0
  45. package/batteries/llm/webllm_chat_completions/types.d.ts +31 -0
  46. package/batteries/llm/webllm_chat_completions/validation.cjs +115 -0
  47. package/batteries/llm/webllm_chat_completions/validation.cjs.map +1 -0
  48. package/batteries/llm/webllm_chat_completions/validation.d.ts +8 -0
  49. package/batteries/llm/webllm_chat_completions/validation.mjs +112 -0
  50. package/batteries/llm/webllm_chat_completions/validation.mjs.map +1 -0
  51. package/batteries/llm/webllm_chat_completions.cjs +50 -0
  52. package/batteries/llm/webllm_chat_completions.mjs +6 -0
  53. package/batteries/llm.cjs +63 -0
  54. package/batteries/llm.mjs +10 -0
  55. package/batteries/storage/flydrive/index.d.ts +167 -0
  56. package/batteries/storage/flydrive.cjs +249 -0
  57. package/batteries/storage/flydrive.cjs.map +1 -0
  58. package/batteries/storage/flydrive.mjs +249 -0
  59. package/batteries/storage/flydrive.mjs.map +1 -0
  60. package/batteries/storage/in_memory/index.d.ts +106 -0
  61. package/batteries/storage/in_memory.cjs +121 -0
  62. package/batteries/storage/in_memory.cjs.map +1 -0
  63. package/batteries/storage/in_memory.mjs +119 -0
  64. package/batteries/storage/in_memory.mjs.map +1 -0
  65. package/batteries/storage/index.d.ts +18 -0
  66. package/batteries/storage/opfs/index.d.ts +299 -0
  67. package/batteries/storage/opfs.cjs +368 -0
  68. package/batteries/storage/opfs.cjs.map +1 -0
  69. package/batteries/storage/opfs.mjs +366 -0
  70. package/batteries/storage/opfs.mjs.map +1 -0
  71. package/batteries/storage.cjs +4 -0
  72. package/batteries/storage.mjs +2 -0
  73. package/batteries/tools/color/index.d.ts +37 -0
  74. package/batteries/tools/color.cjs +659 -0
  75. package/batteries/tools/color.cjs.map +1 -0
  76. package/batteries/tools/color.mjs +655 -0
  77. package/batteries/tools/color.mjs.map +1 -0
  78. package/batteries/tools/comparison/index.d.ts +29 -0
  79. package/batteries/tools/comparison.cjs +171 -0
  80. package/batteries/tools/comparison.cjs.map +1 -0
  81. package/batteries/tools/comparison.mjs +168 -0
  82. package/batteries/tools/comparison.mjs.map +1 -0
  83. package/batteries/tools/data_structure/index.d.ts +30 -0
  84. package/batteries/tools/data_structure.cjs +270 -0
  85. package/batteries/tools/data_structure.cjs.map +1 -0
  86. package/batteries/tools/data_structure.mjs +267 -0
  87. package/batteries/tools/data_structure.mjs.map +1 -0
  88. package/batteries/tools/datetime_extended/index.d.ts +51 -0
  89. package/batteries/tools/datetime_extended.cjs +309 -0
  90. package/batteries/tools/datetime_extended.cjs.map +1 -0
  91. package/batteries/tools/datetime_extended.mjs +302 -0
  92. package/batteries/tools/datetime_extended.mjs.map +1 -0
  93. package/batteries/tools/datetime_math/index.d.ts +36 -0
  94. package/batteries/tools/datetime_math.cjs +175 -0
  95. package/batteries/tools/datetime_math.cjs.map +1 -0
  96. package/batteries/tools/datetime_math.mjs +171 -0
  97. package/batteries/tools/datetime_math.mjs.map +1 -0
  98. package/batteries/tools/encoding/index.d.ts +36 -0
  99. package/batteries/tools/encoding.cjs +156 -0
  100. package/batteries/tools/encoding.cjs.map +1 -0
  101. package/batteries/tools/encoding.mjs +152 -0
  102. package/batteries/tools/encoding.mjs.map +1 -0
  103. package/batteries/tools/formatting/index.d.ts +28 -0
  104. package/batteries/tools/formatting.cjs +120 -0
  105. package/batteries/tools/formatting.cjs.map +1 -0
  106. package/batteries/tools/formatting.mjs +117 -0
  107. package/batteries/tools/formatting.mjs.map +1 -0
  108. package/batteries/tools/geo_basics/index.d.ts +33 -0
  109. package/batteries/tools/geo_basics.cjs +136 -0
  110. package/batteries/tools/geo_basics.cjs.map +1 -0
  111. package/batteries/tools/geo_basics.mjs +132 -0
  112. package/batteries/tools/geo_basics.mjs.map +1 -0
  113. package/batteries/tools/index.d.ts +32 -0
  114. package/batteries/tools/math/index.d.ts +37 -0
  115. package/batteries/tools/math.cjs +136 -0
  116. package/batteries/tools/math.cjs.map +1 -0
  117. package/batteries/tools/math.mjs +133 -0
  118. package/batteries/tools/math.mjs.map +1 -0
  119. package/batteries/tools/memory/index.d.ts +73 -0
  120. package/batteries/tools/memory.cjs +193 -0
  121. package/batteries/tools/memory.cjs.map +1 -0
  122. package/batteries/tools/memory.mjs +187 -0
  123. package/batteries/tools/memory.mjs.map +1 -0
  124. package/batteries/tools/parsing/index.d.ts +47 -0
  125. package/batteries/tools/parsing.cjs +191 -0
  126. package/batteries/tools/parsing.cjs.map +1 -0
  127. package/batteries/tools/parsing.mjs +185 -0
  128. package/batteries/tools/parsing.mjs.map +1 -0
  129. package/batteries/tools/retrievables/index.d.ts +81 -0
  130. package/batteries/tools/retrievables.cjs +215 -0
  131. package/batteries/tools/retrievables.cjs.map +1 -0
  132. package/batteries/tools/retrievables.mjs +209 -0
  133. package/batteries/tools/retrievables.mjs.map +1 -0
  134. package/batteries/tools/standing_instructions/index.d.ts +64 -0
  135. package/batteries/tools/standing_instructions.cjs +126 -0
  136. package/batteries/tools/standing_instructions.cjs.map +1 -0
  137. package/batteries/tools/standing_instructions.mjs +121 -0
  138. package/batteries/tools/standing_instructions.mjs.map +1 -0
  139. package/batteries/tools/statistics/index.d.ts +46 -0
  140. package/batteries/tools/statistics.cjs +253 -0
  141. package/batteries/tools/statistics.cjs.map +1 -0
  142. package/batteries/tools/statistics.mjs +248 -0
  143. package/batteries/tools/statistics.mjs.map +1 -0
  144. package/batteries/tools/string_processing/index.d.ts +29 -0
  145. package/batteries/tools/string_processing.cjs +154 -0
  146. package/batteries/tools/string_processing.cjs.map +1 -0
  147. package/batteries/tools/string_processing.mjs +151 -0
  148. package/batteries/tools/string_processing.mjs.map +1 -0
  149. package/batteries/tools/structured_data/index.d.ts +34 -0
  150. package/batteries/tools/structured_data.cjs +189 -0
  151. package/batteries/tools/structured_data.cjs.map +1 -0
  152. package/batteries/tools/structured_data.mjs +185 -0
  153. package/batteries/tools/structured_data.mjs.map +1 -0
  154. package/batteries/tools/text_analysis/index.d.ts +31 -0
  155. package/batteries/tools/text_analysis.cjs +120 -0
  156. package/batteries/tools/text_analysis.cjs.map +1 -0
  157. package/batteries/tools/text_analysis.mjs +117 -0
  158. package/batteries/tools/text_analysis.mjs.map +1 -0
  159. package/batteries/tools/text_comparison/index.d.ts +28 -0
  160. package/batteries/tools/text_comparison.cjs +96 -0
  161. package/batteries/tools/text_comparison.cjs.map +1 -0
  162. package/batteries/tools/text_comparison.mjs +93 -0
  163. package/batteries/tools/text_comparison.mjs.map +1 -0
  164. package/batteries/tools/time/index.d.ts +27 -0
  165. package/batteries/tools/time.cjs +63 -0
  166. package/batteries/tools/time.cjs.map +1 -0
  167. package/batteries/tools/time.mjs +60 -0
  168. package/batteries/tools/time.mjs.map +1 -0
  169. package/batteries/tools/unit_conversion/index.d.ts +19 -0
  170. package/batteries/tools/unit_conversion.cjs +452 -0
  171. package/batteries/tools/unit_conversion.cjs.map +1 -0
  172. package/batteries/tools/unit_conversion.mjs +450 -0
  173. package/batteries/tools/unit_conversion.mjs.map +1 -0
  174. package/batteries/tools.cjs +80 -0
  175. package/batteries/tools.mjs +21 -0
  176. package/batteries.cjs +142 -0
  177. package/batteries.mjs +30 -0
  178. package/chunk-KmRHZBOW.js +35 -0
  179. package/common-DeZaonK1.mjs +208 -0
  180. package/common-DeZaonK1.mjs.map +1 -0
  181. package/common-Od8edUXU.js +232 -0
  182. package/common-Od8edUXU.js.map +1 -0
  183. package/common.cjs +31 -0
  184. package/common.d.ts +108 -0
  185. package/common.mjs +8 -0
  186. package/dispatch_runner-9j6bXHL3.mjs +1609 -0
  187. package/dispatch_runner-9j6bXHL3.mjs.map +1 -0
  188. package/dispatch_runner-CsoH0nld.js +1627 -0
  189. package/dispatch_runner-CsoH0nld.js.map +1 -0
  190. package/dispatch_runner.cjs +3 -0
  191. package/dispatch_runner.d.ts +17 -0
  192. package/dispatch_runner.mjs +2 -0
  193. package/exceptions-D5YrO9Vm.js +280 -0
  194. package/exceptions-D5YrO9Vm.js.map +1 -0
  195. package/exceptions-NrzIHw_R.mjs +244 -0
  196. package/exceptions-NrzIHw_R.mjs.map +1 -0
  197. package/exceptions.cjs +33 -0
  198. package/exceptions.d.ts +52 -0
  199. package/exceptions.mjs +3 -0
  200. package/factories.cjs +4 -0
  201. package/factories.d.ts +39 -0
  202. package/factories.mjs +2 -0
  203. package/forge.cjs +9 -0
  204. package/forge.d.ts +49 -0
  205. package/forge.mjs +5 -0
  206. package/guards.cjs +96 -0
  207. package/guards.cjs.map +1 -0
  208. package/guards.d.ts +83 -0
  209. package/guards.mjs +72 -0
  210. package/guards.mjs.map +1 -0
  211. package/index.cjs +107 -0
  212. package/index.cjs.map +1 -0
  213. package/index.d.ts +18 -0
  214. package/index.mjs +31 -0
  215. package/index.mjs.map +1 -0
  216. package/lib/classes/artifact_tool.d.ts +129 -0
  217. package/lib/classes/base_exception.d.ts +83 -0
  218. package/lib/classes/identity.d.ts +71 -0
  219. package/lib/classes/media.d.ts +326 -0
  220. package/lib/classes/memory.d.ts +72 -0
  221. package/lib/classes/message.d.ts +137 -0
  222. package/lib/classes/registry.d.ts +79 -0
  223. package/lib/classes/retrievable.d.ts +100 -0
  224. package/lib/classes/spooled_artifact.d.ts +296 -0
  225. package/lib/classes/spooled_json_artifact.d.ts +158 -0
  226. package/lib/classes/spooled_markdown_artifact.d.ts +202 -0
  227. package/lib/classes/thought.d.ts +142 -0
  228. package/lib/classes/tokenizable.d.ts +124 -0
  229. package/lib/classes/tool.d.ts +228 -0
  230. package/lib/classes/tool_call.d.ts +190 -0
  231. package/lib/classes/tool_registry.d.ts +159 -0
  232. package/lib/classes/turn_gate.d.ts +109 -0
  233. package/lib/contracts/dispatch_context.d.ts +345 -0
  234. package/lib/contracts/media_reader.d.ts +60 -0
  235. package/lib/contracts/spool_reader.d.ts +80 -0
  236. package/lib/contracts/spooled_artifact_constructor.d.ts +38 -0
  237. package/lib/contracts/turn_runner_config.d.ts +101 -0
  238. package/lib/contracts/turn_runner_context.d.ts +267 -0
  239. package/lib/dispatch_runner.d.ts +98 -0
  240. package/lib/exceptions/runtime.d.ts +370 -0
  241. package/lib/helpers/media_readers.d.ts +39 -0
  242. package/lib/turn_runner.d.ts +144 -0
  243. package/lib/types/dispatch_context.d.ts +233 -0
  244. package/lib/types/dispatch_runner.d.ts +387 -0
  245. package/lib/types/turn_runner.d.ts +322 -0
  246. package/lib/utils/canonical_json.d.ts +18 -0
  247. package/lib/utils/exceptions.d.ts +78 -0
  248. package/lib/utils/guards.d.ts +32 -0
  249. package/lib/utils/validation.d.ts +77 -0
  250. package/package.json +334 -0
  251. package/runtime-BJVkrGQe.js +519 -0
  252. package/runtime-BJVkrGQe.js.map +1 -0
  253. package/runtime-CrEPIFgr.mjs +346 -0
  254. package/runtime-CrEPIFgr.mjs.map +1 -0
  255. package/skills/adk-assembly/SKILL.md +109 -0
  256. package/skills/adk-assembly/references/assembly-contract.md +66 -0
  257. package/skills/adk-assembly/references/executors-tools-pipelines-events.md +113 -0
  258. package/skills/adk-assembly/references/first-integration.md +93 -0
  259. package/skills/adk-assembly/references/storage-and-context.md +102 -0
  260. package/spooled_artifact-C5ZtGxuJ.mjs +544 -0
  261. package/spooled_artifact-C5ZtGxuJ.mjs.map +1 -0
  262. package/spooled_artifact-Cm9Te22K.js +568 -0
  263. package/spooled_artifact-Cm9Te22K.js.map +1 -0
  264. package/spooled_artifact.cjs +7 -0
  265. package/spooled_artifact.d.ts +40 -0
  266. package/spooled_artifact.mjs +3 -0
  267. package/spooled_markdown_artifact-BpUJol0W.mjs +771 -0
  268. package/spooled_markdown_artifact-BpUJol0W.mjs.map +1 -0
  269. package/spooled_markdown_artifact-RRB113sy.js +786 -0
  270. package/spooled_markdown_artifact-RRB113sy.js.map +1 -0
  271. package/thought-CDb457b4.mjs +470 -0
  272. package/thought-CDb457b4.mjs.map +1 -0
  273. package/thought-DuN2PgdO.js +494 -0
  274. package/thought-DuN2PgdO.js.map +1 -0
  275. package/tool-COSeH8I6.js +302 -0
  276. package/tool-COSeH8I6.js.map +1 -0
  277. package/tool-D2WB1EA1.mjs +296 -0
  278. package/tool-D2WB1EA1.mjs.map +1 -0
  279. package/tool_call-BKyyxGaZ.mjs +578 -0
  280. package/tool_call-BKyyxGaZ.mjs.map +1 -0
  281. package/tool_call-DFgzcVcU.js +608 -0
  282. package/tool_call-DFgzcVcU.js.map +1 -0
  283. package/tool_registry-Dkfprsck.js +641 -0
  284. package/tool_registry-Dkfprsck.js.map +1 -0
  285. package/tool_registry-DqLOyGyG.mjs +592 -0
  286. package/tool_registry-DqLOyGyG.mjs.map +1 -0
  287. package/turn_runner-CMm2BHdX.js +615 -0
  288. package/turn_runner-CMm2BHdX.js.map +1 -0
  289. package/turn_runner-y7eyEcJH.mjs +603 -0
  290. package/turn_runner-y7eyEcJH.mjs.map +1 -0
  291. package/turn_runner.cjs +3 -0
  292. package/turn_runner.d.ts +21 -0
  293. package/turn_runner.mjs +2 -0
  294. package/types.cjs +1 -0
  295. package/types.d.ts +56 -0
  296. package/types.mjs +0 -0
  297. package/vite-env.d.ts +23 -0
@@ -0,0 +1,296 @@
1
+ import { ToolRegistry } from "./tool_registry";
2
+ import { TokenEncoding } from "./tokenizable";
3
+ import type { ObjectSchema } from '@nhtio/validation';
4
+ import type { SpoolReader } from "../contracts/spool_reader";
5
+ import type { DispatchContext } from "../contracts/dispatch_context";
6
+ /**
7
+ * Constructor signature for {@link SpooledArtifact} and any subclass.
8
+ *
9
+ * @remarks
10
+ * Used by {@link @nhtio/adk!Tool} to declare the artifact subclass the consumer should use when wrapping
11
+ * the handler's serialised output. The variadic rest parameter accommodates subclass-specific
12
+ * constructor arguments (e.g. `SpooledJsonArtifact(reader, format?)`).
13
+ *
14
+ * @typeParam A - The {@link SpooledArtifact} subtype the constructor produces.
15
+ */
16
+ export type SpooledArtifactConstructor<A extends SpooledArtifact = SpooledArtifact> = new (reader: SpoolReader, ...rest: any[]) => A;
17
+ /**
18
+ * Metadata table entry for one of the artifact's existing query methods, used by
19
+ * {@link SpooledArtifact.forgeTools} to surface that method as an {@link @nhtio/adk!ArtifactTool}.
20
+ *
21
+ * @remarks
22
+ * This is a metadata shape, not a general method → tool pipeline. `forgeTools` knows how to
23
+ * marshal arguments for a fixed, closed set of method names (the base seven on
24
+ * {@link SpooledArtifact} and the JSON/Markdown methods on the bundled subclasses); a
25
+ * descriptor is the place to attach a tool name, description, args schema, and optional
26
+ * serializer to one of those methods. Adding a descriptor for a method whose name is not
27
+ * in that closed set will produce a tool whose handler invokes the method with no arguments.
28
+ *
29
+ * For new methods that require custom argument marshalling, branching, multi-step logic,
30
+ * cross-artifact joins, or any other behaviour beyond "call this existing method," override
31
+ * {@link SpooledArtifact.forgeTools} and mint the {@link @nhtio/adk!ArtifactTool} directly — do not try
32
+ * to express it through a descriptor.
33
+ *
34
+ * Zero-arg methods are the exception: a descriptor with no `argsSchema` (or one that adds
35
+ * only `callId`-adjacent fields you don't consume) works for any method that takes no
36
+ * arguments, regardless of name.
37
+ */
38
+ export interface ToolMethodDescriptor {
39
+ /** Absolute tool name as exposed to the LLM (e.g. `'artifact_head'`). */
40
+ name: string;
41
+ /** Method to invoke on the resolved artifact instance (e.g. `'head'`, `'json_get'`). */
42
+ method: string;
43
+ /** Human-readable description passed to the model. Should mention "in this turn" so the model understands the artifact's lifecycle scope. */
44
+ description: string;
45
+ /** Schema for the method's own args, NOT including `callId`. `forgeTools()` injects `callId`. */
46
+ argsSchema?: ObjectSchema;
47
+ /** Optional formatter for non-string return values. Defaults: string → as-is; string[] → newline-join; number → `String(n)`; otherwise `JSON.stringify(value, null, 2)`. */
48
+ serialise?: (result: unknown) => string;
49
+ }
50
+ /**
51
+ * Default serialiser for {@link @nhtio/adk!ArtifactTool} handler return values when a descriptor does not
52
+ * provide its own. Exported for reuse by subclass `forgeTools` overrides.
53
+ *
54
+ * @param result - The artifact-method return value.
55
+ * @returns A string suitable for inclusion in an LLM tool-call response.
56
+ */
57
+ export declare const defaultSerialise: (result: unknown) => string;
58
+ /**
59
+ * A lazy, line-oriented view over an arbitrary backing store.
60
+ *
61
+ * @remarks
62
+ * All I/O methods are async to remain compatible with both in-memory and streaming
63
+ * {@link @nhtio/adk!SpoolReader} implementations. Token estimation delegates to
64
+ * {@link @nhtio/adk!Tokenizable.estimateTokens} — the same backends used elsewhere in the ADK.
65
+ *
66
+ * The class is read-only by design: mutation of the underlying data is the responsibility of the
67
+ * producer that created the {@link @nhtio/adk!SpoolReader}, not the consumer reading from this artifact.
68
+ */
69
+ export declare class SpooledArtifact {
70
+ #private;
71
+ /**
72
+ * The set of artifact-query methods this class surfaces via {@link SpooledArtifact.forgeTools}.
73
+ *
74
+ * @remarks
75
+ * The base set covers the generic line-oriented operations every artifact supports:
76
+ * `artifact_head`, `artifact_tail`, `artifact_grep`, `artifact_cat`, `artifact_byte_length`,
77
+ * `artifact_line_count`, `artifact_estimate_tokens`. Each `toolMethods` array lists **only**
78
+ * its own class's descriptors — subclasses do not concatenate inherited descriptors. The
79
+ * subclass instead overrides {@link SpooledArtifact.forgeTools} to merge the base registry
80
+ * (produced by `SpooledArtifact.forgeTools(ctx)`) with its own — see
81
+ * {@link @nhtio/adk!SpooledJsonArtifact.forgeTools} and {@link @nhtio/adk!SpooledMarkdownArtifact.forgeTools} for
82
+ * the canonical shape and the pattern downstream consumers should follow when building
83
+ * their own `SpooledArtifact` subclasses.
84
+ *
85
+ * Tool names are absolute (not subclass-prefixed). Forged tools carry
86
+ * `Tool.onCollision = 'replace'` so merging multiple subclasses' `forgeTools()` outputs is
87
+ * silent — every same-named tool dispatches the same method on whatever artifact the
88
+ * `callId` resolves to, so the overlap is behaviourally interchangeable.
89
+ *
90
+ * Frozen at module load.
91
+ */
92
+ static toolMethods: ReadonlyArray<ToolMethodDescriptor>;
93
+ /**
94
+ * @param reader - The backing store to read from.
95
+ * @throws {@link @nhtio/adk!E_NOT_A_SPOOL_READER} when `reader` does not implement {@link @nhtio/adk!SpoolReader}.
96
+ */
97
+ constructor(reader: SpoolReader);
98
+ /**
99
+ * Returns the line at the given 0-based index, or `undefined` when out of range.
100
+ *
101
+ * @remarks
102
+ * Protected so subclasses can scan the backing store line-by-line without allocating
103
+ * intermediate arrays. Delegates directly to the {@link @nhtio/adk!SpoolReader}.
104
+ *
105
+ * @param index - 0-based line index.
106
+ * @returns The raw line string, or `undefined` when out of range.
107
+ */
108
+ protected line(index: number): Promise<string | undefined>;
109
+ /**
110
+ * Returns `true` if `value` is a {@link SpooledArtifact} instance (including any subclass).
111
+ *
112
+ * @remarks
113
+ * Uses the cross-realm-safe {@link @nhtio/adk!isInstanceOf} guard: `instanceof` first, then
114
+ * `Symbol.hasInstance`, then a `constructor.name` fallback. Subclass instances (e.g.
115
+ * {@link @nhtio/adk!SpooledJsonArtifact}) satisfy this guard because `instanceof` walks the prototype
116
+ * chain. The fallbacks handle the dual-module-copy case where two distinct `SpooledArtifact`
117
+ * classes coexist in the same realm (e.g. one bundled into a downstream library, one in the
118
+ * consumer's `node_modules`).
119
+ *
120
+ * @param value - The value to test.
121
+ * @returns `true` when `value` is a {@link SpooledArtifact} instance.
122
+ */
123
+ static isSpooledArtifact(value: unknown): value is SpooledArtifact;
124
+ /**
125
+ * Returns `true` if `value` is a constructor function whose prototype chain includes
126
+ * {@link SpooledArtifact} (including `SpooledArtifact` itself).
127
+ *
128
+ * @remarks
129
+ * Used by {@link @nhtio/adk!Tool} to validate the optional `artifactConstructor` field. Performs an
130
+ * `instanceof`-based check on the prototype chain; falls back to a duck-type test that looks
131
+ * for the canonical SpooledArtifact instance methods on `value.prototype` for cross-realm
132
+ * safety (constructors passed from a different module copy or VM context).
133
+ *
134
+ * @param value - The value to test.
135
+ * @returns `true` when `value` is a constructor for `SpooledArtifact` or a subclass.
136
+ */
137
+ static isSpooledArtifactConstructor(value: unknown): value is SpooledArtifactConstructor<SpooledArtifact>;
138
+ /**
139
+ * Returns the first `n` lines of the artifact.
140
+ *
141
+ * @remarks
142
+ * If the artifact contains fewer than `n` lines, all available lines are returned. Matches the
143
+ * behaviour of POSIX `head -n`.
144
+ *
145
+ * @param n - Number of lines to return. Defaults to 10.
146
+ * @returns Array of line strings, without trailing newlines.
147
+ */
148
+ head(n?: number): Promise<string[]>;
149
+ /**
150
+ * Returns the last `n` lines of the artifact.
151
+ *
152
+ * @remarks
153
+ * If the artifact contains fewer than `n` lines, all available lines are returned. Matches the
154
+ * behaviour of POSIX `tail -n`.
155
+ *
156
+ * @param n - Number of lines to return. Defaults to 10.
157
+ * @returns Array of line strings, without trailing newlines.
158
+ */
159
+ tail(n?: number): Promise<string[]>;
160
+ /**
161
+ * Returns all lines that match `pattern`.
162
+ *
163
+ * @remarks
164
+ * Behaves like POSIX `grep`: each line is tested against the pattern and included in the result
165
+ * when it matches. The pattern is applied as a JavaScript `RegExp`; flags (e.g. case-
166
+ * insensitivity) should be encoded in the expression itself.
167
+ *
168
+ * Stateful flags (`g`, `y`) on the supplied `RegExp` would normally cause `pattern.test()` to
169
+ * advance `lastIndex` across calls, producing skipped matches and order-dependent results. To
170
+ * keep the per-line semantics stateless, `grep` resets `pattern.lastIndex` to `0` before each
171
+ * line test. The forged `artifact_grep` tool also rejects `g` and `y` flags up-front at schema
172
+ * validation time.
173
+ *
174
+ * @param pattern - The regular expression to test each line against.
175
+ * @returns Array of matching line strings, in order.
176
+ */
177
+ grep(pattern: RegExp): Promise<string[]>;
178
+ /**
179
+ * Returns lines from the artifact, optionally bounded to a range.
180
+ *
181
+ * @remarks
182
+ * Without arguments, returns all lines — equivalent to POSIX `cat`. With `start` and/or `end`,
183
+ * behaves like `Array.prototype.slice`: `start` defaults to `0`, `end` defaults to the total
184
+ * line count, and only lines in `[start, end)` are fetched from the backing store. For large
185
+ * artifacts, prefer a bounded range or {@link SpooledArtifact.head} / {@link SpooledArtifact.tail}.
186
+ *
187
+ * @param start - 0-based start line index (inclusive). Defaults to `0`.
188
+ * @param end - 0-based end line index (exclusive). Defaults to `lineCount()`.
189
+ * @returns Array of line strings in the requested range.
190
+ */
191
+ cat(start?: number, end?: number): Promise<string[]>;
192
+ /**
193
+ * Returns the total byte length of the underlying data.
194
+ *
195
+ * @returns The byte length as reported by the {@link @nhtio/adk!SpoolReader}.
196
+ */
197
+ byteLength(): Promise<number>;
198
+ /**
199
+ * Returns the total number of lines in the artifact.
200
+ *
201
+ * @returns The line count as reported by the {@link @nhtio/adk!SpoolReader}.
202
+ */
203
+ lineCount(): Promise<number>;
204
+ /**
205
+ * Estimates the total token count of the artifact under `encoding`.
206
+ *
207
+ * @remarks
208
+ * Reads the full byte-faithful content via {@link SpooledArtifact.asString} (which delegates to
209
+ * {@link @nhtio/adk!SpoolReader.readAll}) and delegates to {@link @nhtio/adk!Tokenizable.estimateTokens}. The estimate
210
+ * therefore reflects the actual source bytes — including trailing newlines and non-`\n` line
211
+ * terminators that the line-based {@link SpooledArtifact.cat} view would otherwise discard or
212
+ * misrepresent.
213
+ *
214
+ * @param encoding - The encoding identifier to use for counting.
215
+ * @returns The estimated number of tokens.
216
+ */
217
+ estimateTokens(encoding: TokenEncoding): Promise<number>;
218
+ /**
219
+ * Returns the full artifact body as a single byte-faithful string.
220
+ *
221
+ * @remarks
222
+ * Round-trip faithful to whatever bytes the {@link @nhtio/adk!SpoolReader} was constructed over —
223
+ * preserves trailing newlines and non-`\n` line terminators that {@link SpooledArtifact.cat}
224
+ * discards via its line-based view. This is the canonical primitive for "inline the artifact
225
+ * content directly into a message" use cases.
226
+ *
227
+ * `asString()` and the static `forgeTools(ctx)` factory on each subclass are independent
228
+ * alternatives — a consumer chooses per turn whether to inline the body in a message
229
+ * (`await tc.results.asString()`) or hand the model query tools
230
+ * (`SpooledArtifact.forgeTools(ctx)`). Neither calls the other; either works with neither.
231
+ *
232
+ * @returns The full content as a single string.
233
+ */
234
+ asString(): Promise<string>;
235
+ /**
236
+ * Forges a fresh {@link @nhtio/adk!ToolRegistry} of ephemeral {@link @nhtio/adk!ArtifactTool} instances that let the
237
+ * LLM query artifacts already present in `ctx.turnToolCalls`.
238
+ *
239
+ * @remarks
240
+ * Standard subclass extension pattern — each class owns only its own `toolMethods` and its
241
+ * own `forgeTools`. The base `SpooledArtifact.forgeTools(ctx)` narrows the `callId` enum to
242
+ * any `tc.results instanceof SpooledArtifact` (so subclass instances are included — that's
243
+ * the whole point of inheritance) and dispatches the seven base methods (`head`, `tail`,
244
+ * `grep`, `cat`, `byteLength`, `lineCount`, `estimateTokens`) on the resolved artifact.
245
+ * Subclasses override `forgeTools` to call this static first and then register their own
246
+ * tools on the returned registry — see {@link @nhtio/adk!SpooledJsonArtifact.forgeTools} and
247
+ * {@link @nhtio/adk!SpooledMarkdownArtifact.forgeTools} for the canonical shape. There is no
248
+ * `requiresSubclass` field, no helper indirection, and no `this`-based class narrowing —
249
+ * just plain `instanceof ThisClass` at each subclass's own filter site.
250
+ *
251
+ * For each descriptor in this class's `toolMethods`, the factory:
252
+ *
253
+ * 1. Walks `ctx.turnToolCalls` to find `ToolCall`s whose `results instanceof SpooledArtifact`.
254
+ * `ToolCall`s flagged `fromArtifactTool === true` are excluded — they carry a
255
+ * {@link @nhtio/adk!Tokenizable}, not a `SpooledArtifact`, and including them would let the model
256
+ * `artifact_grep` on a previous `artifact_grep` result (an infinite-recursion hazard with
257
+ * no semantic value).
258
+ * 2. Returns an empty registry if no compatible callIds are found — no point shipping tools
259
+ * whose `callId` enum is empty.
260
+ * 3. Otherwise mints an {@link @nhtio/adk!ArtifactTool} with `ephemeral: true` and `onCollision: 'replace'`
261
+ * so multiple `Subclass.forgeTools(ctx)` outputs merge silently. The tool's `inputSchema`
262
+ * includes a required `callId` field with `.valid(...compatibleIds)`, plus the descriptor's
263
+ * own `argsSchema` fields.
264
+ *
265
+ * The handler resolves the artifact via `[...ctx.turnToolCalls].find(t => t.id === callId)`,
266
+ * dispatches the descriptor's method, and serialises the return value (string → as-is;
267
+ * string[] → newline-join; number → `String(n)`; otherwise `JSON.stringify(value, null, 2)`;
268
+ * `descriptor.serialise` overrides the defaults). `grep` is special-cased: the handler
269
+ * constructs `new RegExp(pattern, flags ?? '')` before invoking the artifact's `grep` method.
270
+ *
271
+ * The returned registry must be merged into the consumer's main registry and the main
272
+ * registry must be bound to `ctx` via {@link @nhtio/adk!ToolRegistry.bindContext}:
273
+ *
274
+ * ```ts
275
+ * const executor: DispatchExecutorFn = async (ctx) => {
276
+ * const forged = SpooledArtifact.forgeTools(ctx)
277
+ * const merged = ToolRegistry.merge([main, forged])
278
+ * main.bindContext(ctx)
279
+ * const result = await llm.invoke({ tools: merged.all(), ... })
280
+ * ctx.ack() // ← ephemeral cleanup fires here
281
+ * }
282
+ * ```
283
+ *
284
+ * @warning You **must** call `registry.bindContext(ctx)` on the registry hosting these tools,
285
+ * or ephemeral cleanup will not run and the `callId` enum in subsequent executor calls will
286
+ * be stale (excluding new tool calls produced in the meantime).
287
+ *
288
+ * @param ctx - The execution context whose `turnToolCalls` snapshot defines the `callId` enum.
289
+ * @returns A fresh `ToolRegistry`. Empty when `turnToolCalls` contains no compatible artifacts.
290
+ *
291
+ * @see {@link @nhtio/adk!ToolRegistry.bindContext}
292
+ * @see {@link @nhtio/adk!ToolRegistry.merge}
293
+ * @see {@link @nhtio/adk!DispatchContext.onAck}
294
+ */
295
+ static forgeTools(ctx: DispatchContext): ToolRegistry;
296
+ }
@@ -0,0 +1,158 @@
1
+ import { ToolRegistry } from "./tool_registry";
2
+ import { SpooledArtifact } from "./spooled_artifact";
3
+ import type { SpoolReader } from "../contracts/spool_reader";
4
+ import type { ToolMethodDescriptor } from "./spooled_artifact";
5
+ import type { DispatchContext } from "../contracts/dispatch_context";
6
+ /**
7
+ * The set of JSON-derived formats that {@link SpooledJsonArtifact} can handle.
8
+ *
9
+ * @remarks
10
+ * - `json` — a single JSON value spanning the entire artifact (strict RFC 8259).
11
+ * - `json5` — a single JSON5 value spanning the entire artifact; permits comments, trailing
12
+ * commas, unquoted keys, and other relaxed syntax via the `json5` package.
13
+ * - `jsonl` — newline-delimited JSON; each non-empty line is an independent JSON value.
14
+ * - `ndjson` — alias for `jsonl`; both names are accepted and behave identically.
15
+ */
16
+ export type JsonArtifactFormat = 'json' | 'json5' | 'jsonl' | 'ndjson';
17
+ /**
18
+ * A {@link @nhtio/adk!SpooledArtifact} specialisation that adds JSON-aware read operations.
19
+ *
20
+ * @typeParam T - The expected shape of each parsed record. Defaults to `unknown`.
21
+ *
22
+ * @remarks
23
+ * Construct with an optional `format` hint. When omitted the format is auto-detected on first
24
+ * access by reading the full artifact and running {@link inferFormat}. Once detected (or
25
+ * provided), the format is cached for the lifetime of the instance.
26
+ *
27
+ * All JSON methods are async, consistent with {@link @nhtio/adk!SpooledArtifact}.
28
+ *
29
+ * Path-based methods (`json_get`, `json_filter`, `json_pluck`) use
30
+ * [JSONPath-Plus](https://github.com/JSONPath-Plus/JSONPath) expressions. Full JSONPath syntax
31
+ * is supported, including recursive descent (`..`), filter expressions (`[?(@.age > 18)]`),
32
+ * and union selectors.
33
+ */
34
+ export declare class SpooledJsonArtifact<T = unknown> extends SpooledArtifact {
35
+ #private;
36
+ /**
37
+ * @param reader - The backing store to read from.
38
+ * @param format - Optional format hint. When omitted, the format is inferred on first access.
39
+ */
40
+ constructor(reader: SpoolReader, format?: JsonArtifactFormat);
41
+ /**
42
+ * Returns `true` if `value` is a {@link SpooledJsonArtifact} instance.
43
+ *
44
+ * @remarks
45
+ * Uses the cross-realm-safe {@link @nhtio/adk!isInstanceOf} guard: `instanceof` first, then
46
+ * `Symbol.hasInstance`, then a `constructor.name` fallback. Matches the pattern used by every
47
+ * other class guard in the ADK; safe against the dual-module-copy case where two distinct
48
+ * `SpooledJsonArtifact` classes coexist in the same realm.
49
+ *
50
+ * @param value - The value to test.
51
+ * @returns `true` when `value` is a {@link SpooledJsonArtifact} instance.
52
+ */
53
+ static isSpooledJsonArtifact(value: unknown): value is SpooledJsonArtifact;
54
+ /**
55
+ * The JSON-specific artifact-query descriptors this class adds on top of the base set.
56
+ *
57
+ * @remarks
58
+ * Lists `artifact_json_type`, `artifact_json_keys`, `artifact_json_length`,
59
+ * `artifact_json_get`, `artifact_json_filter`, `artifact_json_slice`, `artifact_json_pluck`.
60
+ * The base seven descriptors (`artifact_head`, etc.) are NOT included here — they are
61
+ * forged separately by {@link SpooledJsonArtifact.forgeTools}, which calls
62
+ * `SpooledArtifact.forgeTools(ctx)` to produce the base-narrowed tools and then registers
63
+ * its own JSON tools on the result. Downstream consumers building custom subclasses
64
+ * should follow the same pattern: own only your own descriptors; override `forgeTools` to
65
+ * compose with the base output.
66
+ */
67
+ static toolMethods: ReadonlyArray<ToolMethodDescriptor>;
68
+ /**
69
+ * Forges base-class tools plus JSON-specific tools narrowed to {@link SpooledJsonArtifact}.
70
+ *
71
+ * @remarks
72
+ * Standard subclass extension pattern: call `SpooledArtifact.forgeTools(ctx)` to produce
73
+ * the base seven `artifact_*` tools narrowed to any `SpooledArtifact` in the turn, then
74
+ * register one `ArtifactTool` per JSON-specific descriptor narrowed to JSON artifacts.
75
+ * Downstream consumers building their own subclasses should follow the same shape.
76
+ */
77
+ static forgeTools(ctx: DispatchContext): ToolRegistry;
78
+ /**
79
+ * Returns the detected or provided format for this artifact.
80
+ *
81
+ * @returns One of `'json'`, `'json5'`, `'jsonl'`, or `'ndjson'`.
82
+ */
83
+ json_type(): Promise<JsonArtifactFormat>;
84
+ /**
85
+ * Returns the top-level keys of the parsed content.
86
+ *
87
+ * @remarks
88
+ * - For `json`/`json5`: returns the keys of the root object, or `undefined` when the root is
89
+ * not a plain object (e.g. an array or scalar).
90
+ * - For `jsonl`/`ndjson`: returns the union of keys across all records that are plain objects.
91
+ * Duplicate keys are deduplicated.
92
+ *
93
+ * @returns Array of key strings, or `undefined` when no object keys are present.
94
+ */
95
+ json_keys(): Promise<string[] | undefined>;
96
+ /**
97
+ * Returns the total number of records in the artifact.
98
+ *
99
+ * @remarks
100
+ * - For `json`/`json5`: always `1` (the entire artifact is a single value).
101
+ * - For `jsonl`/`ndjson`: the number of non-empty lines.
102
+ *
103
+ * @returns The record count.
104
+ */
105
+ json_length(): Promise<number>;
106
+ /**
107
+ * Evaluates a JSONPath expression against the parsed content.
108
+ *
109
+ * @remarks
110
+ * Uses [JSONPath-Plus](https://github.com/JSONPath-Plus/JSONPath). Full JSONPath syntax is
111
+ * supported: recursive descent (`$..*`), filter expressions (`$[?(@.age > 18)]`), union
112
+ * selectors, and more.
113
+ *
114
+ * - For `json`/`json5`: evaluates the expression against the root value.
115
+ * - For `jsonl`/`ndjson`: evaluates the expression against each record and returns a flat
116
+ * array of all matches across all records.
117
+ *
118
+ * @param path - A JSONPath expression (e.g. `'$.user.address.city'`, `'$..name'`).
119
+ * @returns Array of matched values. Empty array when no matches are found.
120
+ */
121
+ json_get(path: string): Promise<unknown[]>;
122
+ /**
123
+ * Returns a slice of the parsed records by index range.
124
+ *
125
+ * @remarks
126
+ * For `json`/`json5`: always returns `[root]` — the artifact is a single record so slicing is
127
+ * not meaningful. For `jsonl`/`ndjson`: behaves like `Array.prototype.slice`.
128
+ *
129
+ * @param start - Start index (inclusive). Defaults to `0`.
130
+ * @param end - End index (exclusive). Defaults to the record count.
131
+ * @returns Array of sliced records.
132
+ */
133
+ json_slice(start?: number, end?: number): Promise<T[]>;
134
+ /**
135
+ * Returns records matched by a JSONPath filter expression.
136
+ *
137
+ * @remarks
138
+ * Evaluates `path` against each record and returns those for which the expression produces at
139
+ * least one match. For `json`/`json5`, evaluates against the root value and returns it in an
140
+ * array if matched.
141
+ *
142
+ * @param path - A JSONPath expression (e.g. `'$[?(@.status === "active")]'`).
143
+ * @returns Array of matching records.
144
+ */
145
+ json_filter(path: string): Promise<T[]>;
146
+ /**
147
+ * Returns all values matched by a JSONPath expression across every record.
148
+ *
149
+ * @remarks
150
+ * Convenience over {@link SpooledJsonArtifact.json_get} with an identical signature — use
151
+ * whichever name better communicates intent at the call site. `json_pluck` reads well for
152
+ * extracting a single field column; `json_get` reads well for structured queries.
153
+ *
154
+ * @param path - A JSONPath expression (e.g. `'$..name'`).
155
+ * @returns Array of matched values.
156
+ */
157
+ json_pluck(path: string): Promise<unknown[]>;
158
+ }
@@ -0,0 +1,202 @@
1
+ import { ToolRegistry } from "./tool_registry";
2
+ import { SpooledArtifact } from "./spooled_artifact";
3
+ import type { Root } from 'mdast';
4
+ import type { SpoolReader } from "../contracts/spool_reader";
5
+ import type { ToolMethodDescriptor } from "./spooled_artifact";
6
+ import type { DispatchContext } from "../contracts/dispatch_context";
7
+ /**
8
+ * A single heading entry in the document's structural index.
9
+ *
10
+ * @remarks
11
+ * `startLine` is the 0-based line of the heading itself. `endLine` is the 0-based index of the
12
+ * last line belonging to this section (inclusive) — the line immediately before the next heading
13
+ * of equal or lesser depth, or the last line of the document.
14
+ */
15
+ export interface MarkdownHeadingEntry {
16
+ /** ATX heading depth: 1 (`#`) through 6 (`######`). */
17
+ depth: 1 | 2 | 3 | 4 | 5 | 6;
18
+ /** The heading text with the leading `#` prefix stripped and trimmed. */
19
+ text: string;
20
+ /** 0-based line index of the heading line itself. */
21
+ startLine: number;
22
+ /** 0-based line index of the last line in this section (inclusive). */
23
+ endLine: number;
24
+ }
25
+ /**
26
+ * A single fenced code block entry in the document's structural index.
27
+ */
28
+ export interface MarkdownCodeEntry {
29
+ /** The language identifier immediately after the opening fence, or `null` when absent. */
30
+ lang: string | null;
31
+ /** 0-based line index of the opening fence line. */
32
+ startLine: number;
33
+ /** 0-based line index of the closing fence line. */
34
+ endLine: number;
35
+ }
36
+ /**
37
+ * A section of a markdown document as returned by {@link SpooledMarkdownArtifact.md_sections}.
38
+ *
39
+ * @remarks
40
+ * Contains only line-range metadata — no content is fetched until the caller explicitly
41
+ * requests it via `cat(bodyStartLine, bodyEndLine + 1)`.
42
+ */
43
+ export interface MarkdownSection {
44
+ depth: 1 | 2 | 3 | 4 | 5 | 6;
45
+ /** The heading text. */
46
+ heading: string;
47
+ /** 0-based line of the heading itself. */
48
+ headingLine: number;
49
+ /** 0-based line of the first body line (heading line + 1). */
50
+ bodyStartLine: number;
51
+ /** 0-based line of the last body line (inclusive). */
52
+ bodyEndLine: number;
53
+ }
54
+ /**
55
+ * A {@link @nhtio/adk!SpooledArtifact} specialisation that adds markdown-aware structural queries.
56
+ *
57
+ * @remarks
58
+ * Designed for large markdown documents where loading the full content into memory is
59
+ * impractical. The structural index (heading positions, code block positions) is built by a
60
+ * single line-by-line scan of the {@link @nhtio/adk!SpoolReader} without retaining any content. Only the
61
+ * tiny metadata index and the parsed frontmatter object are cached.
62
+ *
63
+ * Content retrieval is always bounded — use `cat(start, end)` or the `startLine`/`endLine`
64
+ * parameters on inline methods to fetch only the lines you need.
65
+ *
66
+ * Inline methods (`md_links`, `md_images`, `md_text`, `md_ast`) accept optional line-range
67
+ * arguments. Without a range they read the full document — documented trade-off, caller
68
+ * responsibility to bound the range for large documents.
69
+ *
70
+ * The processor always applies `remark-gfm` (tables, task lists, strikethrough, autolinks)
71
+ * in addition to standard CommonMark and YAML frontmatter.
72
+ */
73
+ export declare class SpooledMarkdownArtifact extends SpooledArtifact {
74
+ #private;
75
+ /**
76
+ * @param reader - The backing store to read from.
77
+ */
78
+ constructor(reader: SpoolReader);
79
+ /**
80
+ * Returns `true` if `value` is a {@link SpooledMarkdownArtifact} instance.
81
+ *
82
+ * @remarks
83
+ * Uses the cross-realm-safe {@link @nhtio/adk!isInstanceOf} guard: `instanceof` first, then
84
+ * `Symbol.hasInstance`, then a `constructor.name` fallback. Matches the pattern used by every
85
+ * other class guard in the ADK; safe against the dual-module-copy case where two distinct
86
+ * `SpooledMarkdownArtifact` classes coexist in the same realm.
87
+ */
88
+ static isSpooledMarkdownArtifact(value: unknown): value is SpooledMarkdownArtifact;
89
+ /**
90
+ * The markdown-specific artifact-query descriptors this class adds on top of the base set.
91
+ *
92
+ * @remarks
93
+ * Lists `artifact_md_frontmatter`, `artifact_md_headings`, `artifact_md_code_blocks`,
94
+ * `artifact_md_sections`, `artifact_md_links`, `artifact_md_images`, `artifact_md_text`,
95
+ * `artifact_md_ast`. The base seven descriptors (`artifact_head`, etc.) are NOT included
96
+ * here — they are forged separately by {@link SpooledMarkdownArtifact.forgeTools}, which
97
+ * calls `SpooledArtifact.forgeTools(ctx)` to produce the base-narrowed tools and then
98
+ * registers its own markdown tools on the result. Downstream consumers building custom
99
+ * subclasses should follow the same pattern: own only your own descriptors; override
100
+ * `forgeTools` to compose with the base output.
101
+ */
102
+ static toolMethods: ReadonlyArray<ToolMethodDescriptor>;
103
+ /**
104
+ * Forges base-class tools plus markdown-specific tools narrowed to
105
+ * {@link SpooledMarkdownArtifact}.
106
+ *
107
+ * @remarks
108
+ * Standard subclass extension pattern: call `SpooledArtifact.forgeTools(ctx)` to produce
109
+ * the base seven `artifact_*` tools narrowed to any `SpooledArtifact` in the turn, then
110
+ * register one `ArtifactTool` per markdown-specific descriptor narrowed to markdown
111
+ * artifacts. Downstream consumers building their own subclasses should follow the same
112
+ * shape.
113
+ */
114
+ static forgeTools(ctx: DispatchContext): ToolRegistry;
115
+ /**
116
+ * Returns the parsed YAML frontmatter, or `undefined` when no frontmatter block is present.
117
+ *
118
+ * @remarks
119
+ * Short-circuits after reading the frontmatter block — never reads the document body. Caches
120
+ * the result so subsequent calls are free. The result is `undefined` (not an empty object)
121
+ * when no frontmatter is found, distinguishing "no frontmatter" from "empty frontmatter".
122
+ */
123
+ md_frontmatter(): Promise<Record<string, unknown> | undefined>;
124
+ /**
125
+ * Returns all headings in document order, optionally filtered by depth.
126
+ *
127
+ * @remarks
128
+ * Uses the cached structural index — no content is fetched from the {@link @nhtio/adk!SpoolReader}.
129
+ *
130
+ * @param depth - When provided, only headings at this ATX depth (1–6) are returned.
131
+ */
132
+ md_headings(depth?: 1 | 2 | 3 | 4 | 5 | 6): Promise<MarkdownHeadingEntry[]>;
133
+ /**
134
+ * Returns all fenced code block entries, optionally filtered by language identifier.
135
+ *
136
+ * @remarks
137
+ * Returns line-range metadata only — no content is fetched. Use `cat(entry.startLine + 1,
138
+ * entry.endLine)` to retrieve the code body (excluding fence lines).
139
+ *
140
+ * @param lang - When provided, only blocks with this exact lang identifier are returned.
141
+ * Pass an empty string to match blocks with no lang identifier.
142
+ */
143
+ md_code_blocks(lang?: string): Promise<MarkdownCodeEntry[]>;
144
+ /**
145
+ * Returns document sections derived from the structural index.
146
+ *
147
+ * @remarks
148
+ * Returns only line-range metadata — body content is never fetched. To retrieve the body of a
149
+ * section, call `cat(section.bodyStartLine, section.bodyEndLine + 1)`.
150
+ *
151
+ * When `depth` is provided, only sections introduced by a heading at that depth are returned;
152
+ * deeper headings become part of the body.
153
+ *
154
+ * @param depth - When provided, only sections at this ATX depth (1–6) are returned.
155
+ */
156
+ md_sections(depth?: 1 | 2 | 3 | 4 | 5 | 6): Promise<MarkdownSection[]>;
157
+ /**
158
+ * Returns the full MDAST Root for the specified line range.
159
+ *
160
+ * @remarks
161
+ * Without a range, reads the full document — for large documents, use
162
+ * {@link SpooledMarkdownArtifact.md_sections} to locate sections and pass
163
+ * bounded line ranges here.
164
+ *
165
+ * @param startLine - 0-based start line (inclusive). Defaults to `0`.
166
+ * @param endLine - 0-based end line (exclusive). Defaults to `lineCount()`.
167
+ */
168
+ md_ast(startLine?: number, endLine?: number): Promise<Root>;
169
+ /**
170
+ * Returns all inline and reference links in the specified line range.
171
+ *
172
+ * @param startLine - 0-based start line (inclusive). Defaults to `0`.
173
+ * @param endLine - 0-based end line (exclusive). Defaults to `lineCount()`.
174
+ */
175
+ md_links(startLine?: number, endLine?: number): Promise<Array<{
176
+ text: string;
177
+ url: string;
178
+ title?: string;
179
+ }>>;
180
+ /**
181
+ * Returns all images in the specified line range.
182
+ *
183
+ * @param startLine - 0-based start line (inclusive). Defaults to `0`.
184
+ * @param endLine - 0-based end line (exclusive). Defaults to `lineCount()`.
185
+ */
186
+ md_images(startLine?: number, endLine?: number): Promise<Array<{
187
+ alt: string;
188
+ url: string;
189
+ title?: string;
190
+ }>>;
191
+ /**
192
+ * Returns all document text with markup stripped, for the specified line range.
193
+ *
194
+ * @remarks
195
+ * Uses `mdast-util-to-string` to extract plain text from the AST — code, link text, and
196
+ * alt text are included; markdown syntax is removed.
197
+ *
198
+ * @param startLine - 0-based start line (inclusive). Defaults to `0`.
199
+ * @param endLine - 0-based end line (exclusive). Defaults to `lineCount()`.
200
+ */
201
+ md_text(startLine?: number, endLine?: number): Promise<string>;
202
+ }