@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,253 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ require("../../chunk-KmRHZBOW.js");
3
+ const require_tool_registry = require("../../tool_registry-Dkfprsck.js");
4
+ require("../../common-Od8edUXU.js");
5
+ const require_tool = require("../../tool-COSeH8I6.js");
6
+ const require_spooled_markdown_artifact = require("../../spooled_markdown_artifact-RRB113sy.js");
7
+ require("../../guards.cjs");
8
+ let _nhtio_validation = require("@nhtio/validation");
9
+ let simple_statistics = require("simple-statistics");
10
+ //#region src/batteries/tools/statistics/index.ts
11
+ /**
12
+ * Pre-constructed tools for descriptive statistics, correlation, quantiles, and numeric summaries.
13
+ *
14
+ * @module @nhtio/adk/batteries/tools/statistics
15
+ *
16
+ * @remarks
17
+ * Pre-constructed bundled tools for the `statistics` category. Import individually, the whole
18
+ * category, or import every tool via `@nhtio/adk/batteries`.
19
+ */
20
+ function parseNumbers(input) {
21
+ let arr = input;
22
+ if (typeof input === "string") try {
23
+ arr = JSON.parse(input);
24
+ } catch {
25
+ return { error: "Invalid JSON — expected an array of numbers." };
26
+ }
27
+ if (!Array.isArray(arr)) return { error: "Input must be a JSON array of numbers." };
28
+ const nums = arr.filter((v) => typeof v === "number" && Number.isFinite(v));
29
+ if (nums.length === 0) return { error: "No finite numbers found in the array." };
30
+ return nums;
31
+ }
32
+ /**
33
+ * Compute descriptive statistics for a JSON array of numbers.
34
+ *
35
+ * @remarks
36
+ * Returns count, sum, min/max/range, mean, median, mode, variance, standard deviation,
37
+ * quartiles (Q1/Q2/Q3), IQR, and key percentiles (P10/P90/P95/P99) as a pretty-printed JSON
38
+ * object. Non-numeric and non-finite entries are silently filtered.
39
+ */
40
+ var statsDescribeTool = new require_tool.Tool({
41
+ name: "stats_describe",
42
+ description: "Compute descriptive statistics for a numeric array: count, sum, min, max, range, mean, median, mode, variance, standard deviation, quartiles (Q1–Q3), IQR, and key percentiles.",
43
+ inputSchema: _nhtio_validation.validator.object({ numbers: _nhtio_validation.validator.string().required().description("JSON array of numbers") }),
44
+ artifactConstructor: () => require_spooled_markdown_artifact.SpooledJsonArtifact,
45
+ handler: async (args) => {
46
+ const { numbers } = args;
47
+ const nums = parseNumbers(numbers);
48
+ if ("error" in nums) return `Error: ${nums.error}`;
49
+ const sorted = [...nums].sort((a, b) => a - b);
50
+ const modeVal = (0, simple_statistics.mode)(nums);
51
+ return JSON.stringify({
52
+ count: nums.length,
53
+ sum: Number.parseFloat((0, simple_statistics.sum)(nums).toPrecision(12)),
54
+ min: (0, simple_statistics.min)(nums),
55
+ max: (0, simple_statistics.max)(nums),
56
+ range: (0, simple_statistics.max)(nums) - (0, simple_statistics.min)(nums),
57
+ mean: Number.parseFloat((0, simple_statistics.mean)(nums).toPrecision(10)),
58
+ median: (0, simple_statistics.median)(nums),
59
+ mode: modeVal,
60
+ variance: Number.parseFloat((0, simple_statistics.variance)(nums).toPrecision(8)),
61
+ std_dev: Number.parseFloat((0, simple_statistics.standardDeviation)(nums).toPrecision(8)),
62
+ q1: (0, simple_statistics.quantile)(sorted, .25),
63
+ q2: (0, simple_statistics.quantile)(sorted, .5),
64
+ q3: (0, simple_statistics.quantile)(sorted, .75),
65
+ iqr: (0, simple_statistics.interquartileRange)(nums),
66
+ p10: (0, simple_statistics.quantile)(sorted, .1),
67
+ p90: (0, simple_statistics.quantile)(sorted, .9),
68
+ p95: (0, simple_statistics.quantile)(sorted, .95),
69
+ p99: (0, simple_statistics.quantile)(sorted, .99)
70
+ }, null, 2);
71
+ }
72
+ });
73
+ /**
74
+ * Compute the Pearson correlation coefficient between two numeric arrays.
75
+ *
76
+ * @remarks
77
+ * Returns `r`, `r²` (as a percentage of explained variance), and a plain-English interpretation
78
+ * of strength and direction. Arrays must be the same length and contain at least two points.
79
+ */
80
+ var statsCorrelateTool = new require_tool.Tool({
81
+ name: "stats_correlate",
82
+ description: "Compute the Pearson correlation coefficient between two numeric arrays. Returns the r value (-1 to 1), r², and a plain-English interpretation.",
83
+ inputSchema: _nhtio_validation.validator.object({
84
+ x: _nhtio_validation.validator.string().required().description("JSON array of numbers (first variable)"),
85
+ y: _nhtio_validation.validator.string().required().description("JSON array of numbers (second variable, same length as x)")
86
+ }),
87
+ handler: async (args) => {
88
+ const { x: rawX, y: rawY } = args;
89
+ const x = parseNumbers(rawX);
90
+ if ("error" in x) return `Error in x: ${x.error}`;
91
+ const y = parseNumbers(rawY);
92
+ if ("error" in y) return `Error in y: ${y.error}`;
93
+ if (x.length !== y.length) return `Error: Arrays must be the same length (x: ${x.length}, y: ${y.length}).`;
94
+ if (x.length < 2) return "Error: At least 2 data points required.";
95
+ try {
96
+ const r = (0, simple_statistics.sampleCorrelation)(x, y);
97
+ const absR = Math.abs(r);
98
+ const direction = r > 0 ? "positive" : r < 0 ? "negative" : "no";
99
+ const strength = absR >= .9 ? "very strong" : absR >= .7 ? "strong" : absR >= .5 ? "moderate" : absR >= .3 ? "weak" : "very weak / negligible";
100
+ return `r = ${r.toFixed(6)}\nr² = ${(r * r * 100).toFixed(2)}% (explained variance)\nInterpretation: ${strength} ${direction} correlation`;
101
+ } catch (err) {
102
+ return `Error: ${require_tool_registry.isError(err) ? err.message : String(err)}`;
103
+ }
104
+ }
105
+ });
106
+ /**
107
+ * Transform a numeric array — normalise, smooth, rank, or detect outliers.
108
+ *
109
+ * @remarks
110
+ * Supported operations: `normalize_min_max`, `normalize_z_score`, `normalize_percent_of_sum`,
111
+ * `running_total`, `rolling_avg`, `pct_change`, `rank`, `outliers_iqr`, `outliers_zscore`. Most
112
+ * operations return a JSON array of transformed values; outlier operations return a
113
+ * human-readable report.
114
+ */
115
+ var statsTransformTool = new require_tool.Tool({
116
+ name: "stats_transform",
117
+ description: "Transform a numeric array: normalize (min-max or z-score), compute running totals, rolling averages, percent change between consecutive values, rank each value, or detect outliers.",
118
+ inputSchema: _nhtio_validation.validator.object({
119
+ numbers: _nhtio_validation.validator.string().required().description("JSON array of numbers"),
120
+ operation: _nhtio_validation.validator.string().valid("normalize_min_max", "normalize_z_score", "normalize_percent_of_sum", "running_total", "rolling_avg", "pct_change", "rank", "outliers_iqr", "outliers_zscore").required().description("Transformation to apply"),
121
+ window: _nhtio_validation.validator.number().default(3).description("For rolling_avg: window size (default: 3)"),
122
+ threshold: _nhtio_validation.validator.number().default(3).description("For outliers_zscore: z-score threshold (default: 3.0)")
123
+ }),
124
+ handler: async (args) => {
125
+ const { numbers, operation, window, threshold } = args;
126
+ const nums = parseNumbers(numbers);
127
+ if ("error" in nums) return `Error: ${nums.error}`;
128
+ switch (operation) {
129
+ case "normalize_min_max": {
130
+ const lo = (0, simple_statistics.min)(nums);
131
+ const hi = (0, simple_statistics.max)(nums);
132
+ if (lo === hi) return JSON.stringify(nums.map(() => 0));
133
+ return JSON.stringify(nums.map((v) => Number.parseFloat(((v - lo) / (hi - lo)).toFixed(8))));
134
+ }
135
+ case "normalize_z_score": {
136
+ const m = (0, simple_statistics.mean)(nums);
137
+ const sd = (0, simple_statistics.standardDeviation)(nums);
138
+ if (sd === 0) return JSON.stringify(nums.map(() => 0));
139
+ return JSON.stringify(nums.map((v) => Number.parseFloat((0, simple_statistics.zScore)(v, m, sd).toFixed(8))));
140
+ }
141
+ case "normalize_percent_of_sum": {
142
+ const total = (0, simple_statistics.sum)(nums);
143
+ if (total === 0) return JSON.stringify(nums.map(() => 0));
144
+ return JSON.stringify(nums.map((v) => Number.parseFloat((v / total * 100).toFixed(4))));
145
+ }
146
+ case "running_total": {
147
+ const totals = [];
148
+ let acc = 0;
149
+ for (const v of nums) {
150
+ acc += v;
151
+ totals.push(Number.parseFloat(acc.toPrecision(12)));
152
+ }
153
+ return JSON.stringify(totals);
154
+ }
155
+ case "rolling_avg": {
156
+ const w = Math.max(1, Math.floor(window));
157
+ return JSON.stringify(nums.map((_, i) => {
158
+ const slice = nums.slice(Math.max(0, i - w + 1), i + 1);
159
+ return Number.parseFloat((0, simple_statistics.mean)(slice).toPrecision(8));
160
+ }));
161
+ }
162
+ case "pct_change": {
163
+ const changes = [null];
164
+ for (let i = 1; i < nums.length; i++) if (nums[i - 1] === 0) changes.push(null);
165
+ else changes.push(Number.parseFloat(((nums[i] - nums[i - 1]) / Math.abs(nums[i - 1]) * 100).toFixed(4)));
166
+ return JSON.stringify(changes);
167
+ }
168
+ case "rank": {
169
+ const sorted = [...nums].sort((a, b) => a - b);
170
+ return JSON.stringify(nums.map((v) => sorted.indexOf(v) + 1));
171
+ }
172
+ case "outliers_iqr": {
173
+ const sorted = [...nums].sort((a, b) => a - b);
174
+ const q1 = (0, simple_statistics.quantile)(sorted, .25);
175
+ const q3 = (0, simple_statistics.quantile)(sorted, .75);
176
+ const iqr = q3 - q1;
177
+ const lo = q1 - 1.5 * iqr;
178
+ const hi = q3 + 1.5 * iqr;
179
+ const outliers = nums.map((v, i) => ({
180
+ index: i,
181
+ value: v
182
+ })).filter(({ value }) => value < lo || value > hi);
183
+ if (outliers.length === 0) return "No outliers detected (IQR method).";
184
+ return `${outliers.length} outlier(s) detected:\n${outliers.map((o) => ` [${o.index}] = ${o.value}`).join("\n")}`;
185
+ }
186
+ case "outliers_zscore": {
187
+ const m = (0, simple_statistics.mean)(nums);
188
+ const sd = (0, simple_statistics.standardDeviation)(nums);
189
+ const outliers = nums.map((v, i) => ({
190
+ index: i,
191
+ value: v,
192
+ z: sd === 0 ? 0 : Math.abs((0, simple_statistics.zScore)(v, m, sd))
193
+ })).filter((o) => o.z > threshold);
194
+ if (outliers.length === 0) return `No outliers detected (|z| > ${threshold}).`;
195
+ return `${outliers.length} outlier(s) detected (|z| > ${threshold}):\n${outliers.map((o) => ` [${o.index}] = ${o.value} (z = ${o.z.toFixed(3)})`).join("\n")}`;
196
+ }
197
+ default: return `Error: Unknown operation "${operation}".`;
198
+ }
199
+ }
200
+ });
201
+ /**
202
+ * Bin a numeric array into equal-width histogram buckets.
203
+ *
204
+ * @remarks
205
+ * Output is a text histogram showing each bin's range, count, percentage of total, and a bar
206
+ * chart. The last bin is inclusive on both ends; preceding bins are half-open. `bins` is clamped
207
+ * to `[2, 100]`.
208
+ */
209
+ var statsHistogramTool = new require_tool.Tool({
210
+ name: "stats_histogram",
211
+ description: "Bin a numeric array into equal-width histogram buckets and display counts.",
212
+ inputSchema: _nhtio_validation.validator.object({
213
+ numbers: _nhtio_validation.validator.string().required().description("JSON array of numbers"),
214
+ bins: _nhtio_validation.validator.number().default(10).description("Number of bins (default: 10, max: 100)")
215
+ }),
216
+ handler: async (args) => {
217
+ const { numbers, bins } = args;
218
+ const nums = parseNumbers(numbers);
219
+ if ("error" in nums) return `Error: ${nums.error}`;
220
+ const binCount = Math.max(2, Math.min(100, Math.floor(bins)));
221
+ try {
222
+ const breaks = (0, simple_statistics.equalIntervalBreaks)(nums, binCount);
223
+ const rows = [];
224
+ const maxCount = (() => {
225
+ let m = 0;
226
+ for (let i = 0; i < breaks.length - 1; i++) {
227
+ const isLast = i === breaks.length - 2;
228
+ const count = nums.filter((v) => isLast ? v >= breaks[i] && v <= breaks[i + 1] : v >= breaks[i] && v < breaks[i + 1]).length;
229
+ if (count > m) m = count;
230
+ }
231
+ return m;
232
+ })();
233
+ for (let i = 0; i < breaks.length - 1; i++) {
234
+ const isLast = i === breaks.length - 2;
235
+ const count = nums.filter((v) => isLast ? v >= breaks[i] && v <= breaks[i + 1] : v >= breaks[i] && v < breaks[i + 1]).length;
236
+ const pct = (count / nums.length * 100).toFixed(1);
237
+ const bar = "█".repeat(maxCount > 0 ? Math.round(count / maxCount * 20) : 0);
238
+ const range = `[${breaks[i].toPrecision(4)}, ${breaks[i + 1].toPrecision(4)}${isLast ? "]" : ")"}`;
239
+ rows.push(`${range.padEnd(22)} ${String(count).padStart(4)} (${pct.padStart(5)}%) ${bar}`);
240
+ }
241
+ return rows.join("\n");
242
+ } catch (err) {
243
+ return `Error: ${require_tool_registry.isError(err) ? err.message : String(err)}`;
244
+ }
245
+ }
246
+ });
247
+ //#endregion
248
+ exports.statsCorrelateTool = statsCorrelateTool;
249
+ exports.statsDescribeTool = statsDescribeTool;
250
+ exports.statsHistogramTool = statsHistogramTool;
251
+ exports.statsTransformTool = statsTransformTool;
252
+
253
+ //# sourceMappingURL=statistics.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statistics.cjs","names":[],"sources":["../../../src/batteries/tools/statistics/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for descriptive statistics, correlation, quantiles, and numeric summaries.\n *\n * @module @nhtio/adk/batteries/tools/statistics\n *\n * @remarks\n * Pre-constructed bundled tools for the `statistics` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validator } from '@nhtio/validation'\nimport { Tool, SpooledJsonArtifact } from '@nhtio/adk/common'\nimport {\n equalIntervalBreaks,\n interquartileRange,\n max,\n mean,\n median,\n min,\n mode,\n quantile,\n sampleCorrelation,\n standardDeviation,\n sum,\n variance,\n zScore,\n} from 'simple-statistics'\n\nfunction parseNumbers(input: unknown): number[] | { error: string } {\n let arr: unknown = input\n if (typeof input === 'string') {\n try {\n arr = JSON.parse(input)\n } catch {\n return { error: 'Invalid JSON — expected an array of numbers.' }\n }\n }\n if (!Array.isArray(arr)) return { error: 'Input must be a JSON array of numbers.' }\n const nums = (arr as unknown[]).filter(\n (v): v is number => typeof v === 'number' && Number.isFinite(v)\n )\n if (nums.length === 0) return { error: 'No finite numbers found in the array.' }\n return nums\n}\n\n/**\n * Compute descriptive statistics for a JSON array of numbers.\n *\n * @remarks\n * Returns count, sum, min/max/range, mean, median, mode, variance, standard deviation,\n * quartiles (Q1/Q2/Q3), IQR, and key percentiles (P10/P90/P95/P99) as a pretty-printed JSON\n * object. Non-numeric and non-finite entries are silently filtered.\n */\nexport const statsDescribeTool = new Tool({\n name: 'stats_describe',\n description:\n 'Compute descriptive statistics for a numeric array: count, sum, min, max, range, mean, median, mode, variance, standard deviation, quartiles (Q1–Q3), IQR, and key percentiles.',\n inputSchema: validator.object({\n numbers: validator.string().required().description('JSON array of numbers'),\n }),\n artifactConstructor: () => SpooledJsonArtifact,\n handler: async (args) => {\n const { numbers } = args as { numbers: string }\n const nums = parseNumbers(numbers)\n if ('error' in nums) return `Error: ${nums.error}`\n\n const sorted = [...nums].sort((a, b) => a - b)\n const modeVal = mode(nums)\n\n return JSON.stringify(\n {\n count: nums.length,\n sum: Number.parseFloat(sum(nums).toPrecision(12)),\n min: min(nums),\n max: max(nums),\n range: max(nums) - min(nums),\n mean: Number.parseFloat(mean(nums).toPrecision(10)),\n median: median(nums),\n mode: modeVal,\n variance: Number.parseFloat(variance(nums).toPrecision(8)),\n std_dev: Number.parseFloat(standardDeviation(nums).toPrecision(8)),\n q1: quantile(sorted, 0.25),\n q2: quantile(sorted, 0.5),\n q3: quantile(sorted, 0.75),\n iqr: interquartileRange(nums),\n p10: quantile(sorted, 0.1),\n p90: quantile(sorted, 0.9),\n p95: quantile(sorted, 0.95),\n p99: quantile(sorted, 0.99),\n },\n null,\n 2\n )\n },\n})\n\n/**\n * Compute the Pearson correlation coefficient between two numeric arrays.\n *\n * @remarks\n * Returns `r`, `r²` (as a percentage of explained variance), and a plain-English interpretation\n * of strength and direction. Arrays must be the same length and contain at least two points.\n */\nexport const statsCorrelateTool = new Tool({\n name: 'stats_correlate',\n description:\n 'Compute the Pearson correlation coefficient between two numeric arrays. Returns the r value (-1 to 1), r², and a plain-English interpretation.',\n inputSchema: validator.object({\n x: validator.string().required().description('JSON array of numbers (first variable)'),\n y: validator\n .string()\n .required()\n .description('JSON array of numbers (second variable, same length as x)'),\n }),\n handler: async (args) => {\n const { x: rawX, y: rawY } = args as { x: string; y: string }\n const x = parseNumbers(rawX)\n if ('error' in x) return `Error in x: ${x.error}`\n const y = parseNumbers(rawY)\n if ('error' in y) return `Error in y: ${y.error}`\n\n if (x.length !== y.length)\n return `Error: Arrays must be the same length (x: ${x.length}, y: ${y.length}).`\n if (x.length < 2) return 'Error: At least 2 data points required.'\n\n try {\n const r = sampleCorrelation(x, y)\n const absR = Math.abs(r)\n const direction = r > 0 ? 'positive' : r < 0 ? 'negative' : 'no'\n const strength =\n absR >= 0.9\n ? 'very strong'\n : absR >= 0.7\n ? 'strong'\n : absR >= 0.5\n ? 'moderate'\n : absR >= 0.3\n ? 'weak'\n : 'very weak / negligible'\n return `r = ${r.toFixed(6)}\\nr² = ${(r * r * 100).toFixed(2)}% (explained variance)\\nInterpretation: ${strength} ${direction} correlation`\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Transform a numeric array — normalise, smooth, rank, or detect outliers.\n *\n * @remarks\n * Supported operations: `normalize_min_max`, `normalize_z_score`, `normalize_percent_of_sum`,\n * `running_total`, `rolling_avg`, `pct_change`, `rank`, `outliers_iqr`, `outliers_zscore`. Most\n * operations return a JSON array of transformed values; outlier operations return a\n * human-readable report.\n */\nexport const statsTransformTool = new Tool({\n name: 'stats_transform',\n description:\n 'Transform a numeric array: normalize (min-max or z-score), compute running totals, rolling averages, percent change between consecutive values, rank each value, or detect outliers.',\n inputSchema: validator.object({\n numbers: validator.string().required().description('JSON array of numbers'),\n operation: validator\n .string()\n .valid(\n 'normalize_min_max',\n 'normalize_z_score',\n 'normalize_percent_of_sum',\n 'running_total',\n 'rolling_avg',\n 'pct_change',\n 'rank',\n 'outliers_iqr',\n 'outliers_zscore'\n )\n .required()\n .description('Transformation to apply'),\n window: validator.number().default(3).description('For rolling_avg: window size (default: 3)'),\n threshold: validator\n .number()\n .default(3.0)\n .description('For outliers_zscore: z-score threshold (default: 3.0)'),\n }),\n handler: async (args) => {\n const { numbers, operation, window, threshold } = args as {\n numbers: string\n operation: string\n window: number\n threshold: number\n }\n const nums = parseNumbers(numbers)\n if ('error' in nums) return `Error: ${nums.error}`\n\n switch (operation) {\n case 'normalize_min_max': {\n const lo = min(nums)\n const hi = max(nums)\n if (lo === hi) return JSON.stringify(nums.map(() => 0))\n return JSON.stringify(nums.map((v) => Number.parseFloat(((v - lo) / (hi - lo)).toFixed(8))))\n }\n\n case 'normalize_z_score': {\n const m = mean(nums)\n const sd = standardDeviation(nums)\n if (sd === 0) return JSON.stringify(nums.map(() => 0))\n return JSON.stringify(nums.map((v) => Number.parseFloat(zScore(v, m, sd).toFixed(8))))\n }\n\n case 'normalize_percent_of_sum': {\n const total = sum(nums)\n if (total === 0) return JSON.stringify(nums.map(() => 0))\n return JSON.stringify(nums.map((v) => Number.parseFloat(((v / total) * 100).toFixed(4))))\n }\n\n case 'running_total': {\n const totals: number[] = []\n let acc = 0\n for (const v of nums) {\n acc += v\n totals.push(Number.parseFloat(acc.toPrecision(12)))\n }\n return JSON.stringify(totals)\n }\n\n case 'rolling_avg': {\n const w = Math.max(1, Math.floor(window))\n return JSON.stringify(\n nums.map((_, i) => {\n const slice = nums.slice(Math.max(0, i - w + 1), i + 1)\n return Number.parseFloat(mean(slice).toPrecision(8))\n })\n )\n }\n\n case 'pct_change': {\n const changes: (number | null)[] = [null]\n for (let i = 1; i < nums.length; i++) {\n if (nums[i - 1] === 0) {\n changes.push(null)\n } else {\n changes.push(\n Number.parseFloat(\n (((nums[i] - nums[i - 1]) / Math.abs(nums[i - 1])) * 100).toFixed(4)\n )\n )\n }\n }\n return JSON.stringify(changes)\n }\n\n case 'rank': {\n const sorted = [...nums].sort((a, b) => a - b)\n return JSON.stringify(nums.map((v) => sorted.indexOf(v) + 1))\n }\n\n case 'outliers_iqr': {\n const sorted = [...nums].sort((a, b) => a - b)\n const q1 = quantile(sorted, 0.25)\n const q3 = quantile(sorted, 0.75)\n const iqr = q3 - q1\n const lo = q1 - 1.5 * iqr\n const hi = q3 + 1.5 * iqr\n const outliers = nums\n .map((v, i) => ({ index: i, value: v }))\n .filter(({ value }) => value < lo || value > hi)\n if (outliers.length === 0) return 'No outliers detected (IQR method).'\n return `${outliers.length} outlier(s) detected:\\n${outliers.map((o) => ` [${o.index}] = ${o.value}`).join('\\n')}`\n }\n\n case 'outliers_zscore': {\n const m = mean(nums)\n const sd = standardDeviation(nums)\n const outliers = nums\n .map((v, i) => ({ index: i, value: v, z: sd === 0 ? 0 : Math.abs(zScore(v, m, sd)) }))\n .filter((o) => o.z > threshold)\n if (outliers.length === 0) return `No outliers detected (|z| > ${threshold}).`\n return `${outliers.length} outlier(s) detected (|z| > ${threshold}):\\n${outliers.map((o) => ` [${o.index}] = ${o.value} (z = ${o.z.toFixed(3)})`).join('\\n')}`\n }\n\n default:\n return `Error: Unknown operation \"${operation}\".`\n }\n },\n})\n\n/**\n * Bin a numeric array into equal-width histogram buckets.\n *\n * @remarks\n * Output is a text histogram showing each bin's range, count, percentage of total, and a bar\n * chart. The last bin is inclusive on both ends; preceding bins are half-open. `bins` is clamped\n * to `[2, 100]`.\n */\nexport const statsHistogramTool = new Tool({\n name: 'stats_histogram',\n description: 'Bin a numeric array into equal-width histogram buckets and display counts.',\n inputSchema: validator.object({\n numbers: validator.string().required().description('JSON array of numbers'),\n bins: validator.number().default(10).description('Number of bins (default: 10, max: 100)'),\n }),\n handler: async (args) => {\n const { numbers, bins } = args as { numbers: string; bins: number }\n const nums = parseNumbers(numbers)\n if ('error' in nums) return `Error: ${nums.error}`\n\n const binCount = Math.max(2, Math.min(100, Math.floor(bins)))\n\n try {\n const breaks = equalIntervalBreaks(nums, binCount)\n const rows: string[] = []\n const maxCount = (() => {\n let m = 0\n for (let i = 0; i < breaks.length - 1; i++) {\n const isLast = i === breaks.length - 2\n const count = nums.filter((v) =>\n isLast ? v >= breaks[i] && v <= breaks[i + 1] : v >= breaks[i] && v < breaks[i + 1]\n ).length\n if (count > m) m = count\n }\n return m\n })()\n\n for (let i = 0; i < breaks.length - 1; i++) {\n const isLast = i === breaks.length - 2\n const count = nums.filter((v) =>\n isLast ? v >= breaks[i] && v <= breaks[i + 1] : v >= breaks[i] && v < breaks[i + 1]\n ).length\n const pct = ((count / nums.length) * 100).toFixed(1)\n const bar = '█'.repeat(maxCount > 0 ? Math.round((count / maxCount) * 20) : 0)\n const range = `[${breaks[i].toPrecision(4)}, ${breaks[i + 1].toPrecision(4)}${isLast ? ']' : ')'}`\n rows.push(`${range.padEnd(22)} ${String(count).padStart(4)} (${pct.padStart(5)}%) ${bar}`)\n }\n\n return rows.join('\\n')\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n"],"mappings":"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"}
@@ -0,0 +1,248 @@
1
+ import { o as isError } from "../../tool_registry-DqLOyGyG.mjs";
2
+ import "../../common-DeZaonK1.mjs";
3
+ import { t as Tool } from "../../tool-D2WB1EA1.mjs";
4
+ import { n as SpooledJsonArtifact } from "../../spooled_markdown_artifact-BpUJol0W.mjs";
5
+ import "../../guards.mjs";
6
+ import { validator } from "@nhtio/validation";
7
+ import { equalIntervalBreaks, interquartileRange, max, mean, median, min, mode, quantile, sampleCorrelation, standardDeviation, sum, variance, zScore } from "simple-statistics";
8
+ //#region src/batteries/tools/statistics/index.ts
9
+ /**
10
+ * Pre-constructed tools for descriptive statistics, correlation, quantiles, and numeric summaries.
11
+ *
12
+ * @module @nhtio/adk/batteries/tools/statistics
13
+ *
14
+ * @remarks
15
+ * Pre-constructed bundled tools for the `statistics` category. Import individually, the whole
16
+ * category, or import every tool via `@nhtio/adk/batteries`.
17
+ */
18
+ function parseNumbers(input) {
19
+ let arr = input;
20
+ if (typeof input === "string") try {
21
+ arr = JSON.parse(input);
22
+ } catch {
23
+ return { error: "Invalid JSON — expected an array of numbers." };
24
+ }
25
+ if (!Array.isArray(arr)) return { error: "Input must be a JSON array of numbers." };
26
+ const nums = arr.filter((v) => typeof v === "number" && Number.isFinite(v));
27
+ if (nums.length === 0) return { error: "No finite numbers found in the array." };
28
+ return nums;
29
+ }
30
+ /**
31
+ * Compute descriptive statistics for a JSON array of numbers.
32
+ *
33
+ * @remarks
34
+ * Returns count, sum, min/max/range, mean, median, mode, variance, standard deviation,
35
+ * quartiles (Q1/Q2/Q3), IQR, and key percentiles (P10/P90/P95/P99) as a pretty-printed JSON
36
+ * object. Non-numeric and non-finite entries are silently filtered.
37
+ */
38
+ var statsDescribeTool = new Tool({
39
+ name: "stats_describe",
40
+ description: "Compute descriptive statistics for a numeric array: count, sum, min, max, range, mean, median, mode, variance, standard deviation, quartiles (Q1–Q3), IQR, and key percentiles.",
41
+ inputSchema: validator.object({ numbers: validator.string().required().description("JSON array of numbers") }),
42
+ artifactConstructor: () => SpooledJsonArtifact,
43
+ handler: async (args) => {
44
+ const { numbers } = args;
45
+ const nums = parseNumbers(numbers);
46
+ if ("error" in nums) return `Error: ${nums.error}`;
47
+ const sorted = [...nums].sort((a, b) => a - b);
48
+ const modeVal = mode(nums);
49
+ return JSON.stringify({
50
+ count: nums.length,
51
+ sum: Number.parseFloat(sum(nums).toPrecision(12)),
52
+ min: min(nums),
53
+ max: max(nums),
54
+ range: max(nums) - min(nums),
55
+ mean: Number.parseFloat(mean(nums).toPrecision(10)),
56
+ median: median(nums),
57
+ mode: modeVal,
58
+ variance: Number.parseFloat(variance(nums).toPrecision(8)),
59
+ std_dev: Number.parseFloat(standardDeviation(nums).toPrecision(8)),
60
+ q1: quantile(sorted, .25),
61
+ q2: quantile(sorted, .5),
62
+ q3: quantile(sorted, .75),
63
+ iqr: interquartileRange(nums),
64
+ p10: quantile(sorted, .1),
65
+ p90: quantile(sorted, .9),
66
+ p95: quantile(sorted, .95),
67
+ p99: quantile(sorted, .99)
68
+ }, null, 2);
69
+ }
70
+ });
71
+ /**
72
+ * Compute the Pearson correlation coefficient between two numeric arrays.
73
+ *
74
+ * @remarks
75
+ * Returns `r`, `r²` (as a percentage of explained variance), and a plain-English interpretation
76
+ * of strength and direction. Arrays must be the same length and contain at least two points.
77
+ */
78
+ var statsCorrelateTool = new Tool({
79
+ name: "stats_correlate",
80
+ description: "Compute the Pearson correlation coefficient between two numeric arrays. Returns the r value (-1 to 1), r², and a plain-English interpretation.",
81
+ inputSchema: validator.object({
82
+ x: validator.string().required().description("JSON array of numbers (first variable)"),
83
+ y: validator.string().required().description("JSON array of numbers (second variable, same length as x)")
84
+ }),
85
+ handler: async (args) => {
86
+ const { x: rawX, y: rawY } = args;
87
+ const x = parseNumbers(rawX);
88
+ if ("error" in x) return `Error in x: ${x.error}`;
89
+ const y = parseNumbers(rawY);
90
+ if ("error" in y) return `Error in y: ${y.error}`;
91
+ if (x.length !== y.length) return `Error: Arrays must be the same length (x: ${x.length}, y: ${y.length}).`;
92
+ if (x.length < 2) return "Error: At least 2 data points required.";
93
+ try {
94
+ const r = sampleCorrelation(x, y);
95
+ const absR = Math.abs(r);
96
+ const direction = r > 0 ? "positive" : r < 0 ? "negative" : "no";
97
+ const strength = absR >= .9 ? "very strong" : absR >= .7 ? "strong" : absR >= .5 ? "moderate" : absR >= .3 ? "weak" : "very weak / negligible";
98
+ return `r = ${r.toFixed(6)}\nr² = ${(r * r * 100).toFixed(2)}% (explained variance)\nInterpretation: ${strength} ${direction} correlation`;
99
+ } catch (err) {
100
+ return `Error: ${isError(err) ? err.message : String(err)}`;
101
+ }
102
+ }
103
+ });
104
+ /**
105
+ * Transform a numeric array — normalise, smooth, rank, or detect outliers.
106
+ *
107
+ * @remarks
108
+ * Supported operations: `normalize_min_max`, `normalize_z_score`, `normalize_percent_of_sum`,
109
+ * `running_total`, `rolling_avg`, `pct_change`, `rank`, `outliers_iqr`, `outliers_zscore`. Most
110
+ * operations return a JSON array of transformed values; outlier operations return a
111
+ * human-readable report.
112
+ */
113
+ var statsTransformTool = new Tool({
114
+ name: "stats_transform",
115
+ description: "Transform a numeric array: normalize (min-max or z-score), compute running totals, rolling averages, percent change between consecutive values, rank each value, or detect outliers.",
116
+ inputSchema: validator.object({
117
+ numbers: validator.string().required().description("JSON array of numbers"),
118
+ operation: validator.string().valid("normalize_min_max", "normalize_z_score", "normalize_percent_of_sum", "running_total", "rolling_avg", "pct_change", "rank", "outliers_iqr", "outliers_zscore").required().description("Transformation to apply"),
119
+ window: validator.number().default(3).description("For rolling_avg: window size (default: 3)"),
120
+ threshold: validator.number().default(3).description("For outliers_zscore: z-score threshold (default: 3.0)")
121
+ }),
122
+ handler: async (args) => {
123
+ const { numbers, operation, window, threshold } = args;
124
+ const nums = parseNumbers(numbers);
125
+ if ("error" in nums) return `Error: ${nums.error}`;
126
+ switch (operation) {
127
+ case "normalize_min_max": {
128
+ const lo = min(nums);
129
+ const hi = max(nums);
130
+ if (lo === hi) return JSON.stringify(nums.map(() => 0));
131
+ return JSON.stringify(nums.map((v) => Number.parseFloat(((v - lo) / (hi - lo)).toFixed(8))));
132
+ }
133
+ case "normalize_z_score": {
134
+ const m = mean(nums);
135
+ const sd = standardDeviation(nums);
136
+ if (sd === 0) return JSON.stringify(nums.map(() => 0));
137
+ return JSON.stringify(nums.map((v) => Number.parseFloat(zScore(v, m, sd).toFixed(8))));
138
+ }
139
+ case "normalize_percent_of_sum": {
140
+ const total = sum(nums);
141
+ if (total === 0) return JSON.stringify(nums.map(() => 0));
142
+ return JSON.stringify(nums.map((v) => Number.parseFloat((v / total * 100).toFixed(4))));
143
+ }
144
+ case "running_total": {
145
+ const totals = [];
146
+ let acc = 0;
147
+ for (const v of nums) {
148
+ acc += v;
149
+ totals.push(Number.parseFloat(acc.toPrecision(12)));
150
+ }
151
+ return JSON.stringify(totals);
152
+ }
153
+ case "rolling_avg": {
154
+ const w = Math.max(1, Math.floor(window));
155
+ return JSON.stringify(nums.map((_, i) => {
156
+ const slice = nums.slice(Math.max(0, i - w + 1), i + 1);
157
+ return Number.parseFloat(mean(slice).toPrecision(8));
158
+ }));
159
+ }
160
+ case "pct_change": {
161
+ const changes = [null];
162
+ for (let i = 1; i < nums.length; i++) if (nums[i - 1] === 0) changes.push(null);
163
+ else changes.push(Number.parseFloat(((nums[i] - nums[i - 1]) / Math.abs(nums[i - 1]) * 100).toFixed(4)));
164
+ return JSON.stringify(changes);
165
+ }
166
+ case "rank": {
167
+ const sorted = [...nums].sort((a, b) => a - b);
168
+ return JSON.stringify(nums.map((v) => sorted.indexOf(v) + 1));
169
+ }
170
+ case "outliers_iqr": {
171
+ const sorted = [...nums].sort((a, b) => a - b);
172
+ const q1 = quantile(sorted, .25);
173
+ const q3 = quantile(sorted, .75);
174
+ const iqr = q3 - q1;
175
+ const lo = q1 - 1.5 * iqr;
176
+ const hi = q3 + 1.5 * iqr;
177
+ const outliers = nums.map((v, i) => ({
178
+ index: i,
179
+ value: v
180
+ })).filter(({ value }) => value < lo || value > hi);
181
+ if (outliers.length === 0) return "No outliers detected (IQR method).";
182
+ return `${outliers.length} outlier(s) detected:\n${outliers.map((o) => ` [${o.index}] = ${o.value}`).join("\n")}`;
183
+ }
184
+ case "outliers_zscore": {
185
+ const m = mean(nums);
186
+ const sd = standardDeviation(nums);
187
+ const outliers = nums.map((v, i) => ({
188
+ index: i,
189
+ value: v,
190
+ z: sd === 0 ? 0 : Math.abs(zScore(v, m, sd))
191
+ })).filter((o) => o.z > threshold);
192
+ if (outliers.length === 0) return `No outliers detected (|z| > ${threshold}).`;
193
+ return `${outliers.length} outlier(s) detected (|z| > ${threshold}):\n${outliers.map((o) => ` [${o.index}] = ${o.value} (z = ${o.z.toFixed(3)})`).join("\n")}`;
194
+ }
195
+ default: return `Error: Unknown operation "${operation}".`;
196
+ }
197
+ }
198
+ });
199
+ /**
200
+ * Bin a numeric array into equal-width histogram buckets.
201
+ *
202
+ * @remarks
203
+ * Output is a text histogram showing each bin's range, count, percentage of total, and a bar
204
+ * chart. The last bin is inclusive on both ends; preceding bins are half-open. `bins` is clamped
205
+ * to `[2, 100]`.
206
+ */
207
+ var statsHistogramTool = new Tool({
208
+ name: "stats_histogram",
209
+ description: "Bin a numeric array into equal-width histogram buckets and display counts.",
210
+ inputSchema: validator.object({
211
+ numbers: validator.string().required().description("JSON array of numbers"),
212
+ bins: validator.number().default(10).description("Number of bins (default: 10, max: 100)")
213
+ }),
214
+ handler: async (args) => {
215
+ const { numbers, bins } = args;
216
+ const nums = parseNumbers(numbers);
217
+ if ("error" in nums) return `Error: ${nums.error}`;
218
+ const binCount = Math.max(2, Math.min(100, Math.floor(bins)));
219
+ try {
220
+ const breaks = equalIntervalBreaks(nums, binCount);
221
+ const rows = [];
222
+ const maxCount = (() => {
223
+ let m = 0;
224
+ for (let i = 0; i < breaks.length - 1; i++) {
225
+ const isLast = i === breaks.length - 2;
226
+ const count = nums.filter((v) => isLast ? v >= breaks[i] && v <= breaks[i + 1] : v >= breaks[i] && v < breaks[i + 1]).length;
227
+ if (count > m) m = count;
228
+ }
229
+ return m;
230
+ })();
231
+ for (let i = 0; i < breaks.length - 1; i++) {
232
+ const isLast = i === breaks.length - 2;
233
+ const count = nums.filter((v) => isLast ? v >= breaks[i] && v <= breaks[i + 1] : v >= breaks[i] && v < breaks[i + 1]).length;
234
+ const pct = (count / nums.length * 100).toFixed(1);
235
+ const bar = "█".repeat(maxCount > 0 ? Math.round(count / maxCount * 20) : 0);
236
+ const range = `[${breaks[i].toPrecision(4)}, ${breaks[i + 1].toPrecision(4)}${isLast ? "]" : ")"}`;
237
+ rows.push(`${range.padEnd(22)} ${String(count).padStart(4)} (${pct.padStart(5)}%) ${bar}`);
238
+ }
239
+ return rows.join("\n");
240
+ } catch (err) {
241
+ return `Error: ${isError(err) ? err.message : String(err)}`;
242
+ }
243
+ }
244
+ });
245
+ //#endregion
246
+ export { statsCorrelateTool, statsDescribeTool, statsHistogramTool, statsTransformTool };
247
+
248
+ //# sourceMappingURL=statistics.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statistics.mjs","names":[],"sources":["../../../src/batteries/tools/statistics/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for descriptive statistics, correlation, quantiles, and numeric summaries.\n *\n * @module @nhtio/adk/batteries/tools/statistics\n *\n * @remarks\n * Pre-constructed bundled tools for the `statistics` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validator } from '@nhtio/validation'\nimport { Tool, SpooledJsonArtifact } from '@nhtio/adk/common'\nimport {\n equalIntervalBreaks,\n interquartileRange,\n max,\n mean,\n median,\n min,\n mode,\n quantile,\n sampleCorrelation,\n standardDeviation,\n sum,\n variance,\n zScore,\n} from 'simple-statistics'\n\nfunction parseNumbers(input: unknown): number[] | { error: string } {\n let arr: unknown = input\n if (typeof input === 'string') {\n try {\n arr = JSON.parse(input)\n } catch {\n return { error: 'Invalid JSON — expected an array of numbers.' }\n }\n }\n if (!Array.isArray(arr)) return { error: 'Input must be a JSON array of numbers.' }\n const nums = (arr as unknown[]).filter(\n (v): v is number => typeof v === 'number' && Number.isFinite(v)\n )\n if (nums.length === 0) return { error: 'No finite numbers found in the array.' }\n return nums\n}\n\n/**\n * Compute descriptive statistics for a JSON array of numbers.\n *\n * @remarks\n * Returns count, sum, min/max/range, mean, median, mode, variance, standard deviation,\n * quartiles (Q1/Q2/Q3), IQR, and key percentiles (P10/P90/P95/P99) as a pretty-printed JSON\n * object. Non-numeric and non-finite entries are silently filtered.\n */\nexport const statsDescribeTool = new Tool({\n name: 'stats_describe',\n description:\n 'Compute descriptive statistics for a numeric array: count, sum, min, max, range, mean, median, mode, variance, standard deviation, quartiles (Q1–Q3), IQR, and key percentiles.',\n inputSchema: validator.object({\n numbers: validator.string().required().description('JSON array of numbers'),\n }),\n artifactConstructor: () => SpooledJsonArtifact,\n handler: async (args) => {\n const { numbers } = args as { numbers: string }\n const nums = parseNumbers(numbers)\n if ('error' in nums) return `Error: ${nums.error}`\n\n const sorted = [...nums].sort((a, b) => a - b)\n const modeVal = mode(nums)\n\n return JSON.stringify(\n {\n count: nums.length,\n sum: Number.parseFloat(sum(nums).toPrecision(12)),\n min: min(nums),\n max: max(nums),\n range: max(nums) - min(nums),\n mean: Number.parseFloat(mean(nums).toPrecision(10)),\n median: median(nums),\n mode: modeVal,\n variance: Number.parseFloat(variance(nums).toPrecision(8)),\n std_dev: Number.parseFloat(standardDeviation(nums).toPrecision(8)),\n q1: quantile(sorted, 0.25),\n q2: quantile(sorted, 0.5),\n q3: quantile(sorted, 0.75),\n iqr: interquartileRange(nums),\n p10: quantile(sorted, 0.1),\n p90: quantile(sorted, 0.9),\n p95: quantile(sorted, 0.95),\n p99: quantile(sorted, 0.99),\n },\n null,\n 2\n )\n },\n})\n\n/**\n * Compute the Pearson correlation coefficient between two numeric arrays.\n *\n * @remarks\n * Returns `r`, `r²` (as a percentage of explained variance), and a plain-English interpretation\n * of strength and direction. Arrays must be the same length and contain at least two points.\n */\nexport const statsCorrelateTool = new Tool({\n name: 'stats_correlate',\n description:\n 'Compute the Pearson correlation coefficient between two numeric arrays. Returns the r value (-1 to 1), r², and a plain-English interpretation.',\n inputSchema: validator.object({\n x: validator.string().required().description('JSON array of numbers (first variable)'),\n y: validator\n .string()\n .required()\n .description('JSON array of numbers (second variable, same length as x)'),\n }),\n handler: async (args) => {\n const { x: rawX, y: rawY } = args as { x: string; y: string }\n const x = parseNumbers(rawX)\n if ('error' in x) return `Error in x: ${x.error}`\n const y = parseNumbers(rawY)\n if ('error' in y) return `Error in y: ${y.error}`\n\n if (x.length !== y.length)\n return `Error: Arrays must be the same length (x: ${x.length}, y: ${y.length}).`\n if (x.length < 2) return 'Error: At least 2 data points required.'\n\n try {\n const r = sampleCorrelation(x, y)\n const absR = Math.abs(r)\n const direction = r > 0 ? 'positive' : r < 0 ? 'negative' : 'no'\n const strength =\n absR >= 0.9\n ? 'very strong'\n : absR >= 0.7\n ? 'strong'\n : absR >= 0.5\n ? 'moderate'\n : absR >= 0.3\n ? 'weak'\n : 'very weak / negligible'\n return `r = ${r.toFixed(6)}\\nr² = ${(r * r * 100).toFixed(2)}% (explained variance)\\nInterpretation: ${strength} ${direction} correlation`\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Transform a numeric array — normalise, smooth, rank, or detect outliers.\n *\n * @remarks\n * Supported operations: `normalize_min_max`, `normalize_z_score`, `normalize_percent_of_sum`,\n * `running_total`, `rolling_avg`, `pct_change`, `rank`, `outliers_iqr`, `outliers_zscore`. Most\n * operations return a JSON array of transformed values; outlier operations return a\n * human-readable report.\n */\nexport const statsTransformTool = new Tool({\n name: 'stats_transform',\n description:\n 'Transform a numeric array: normalize (min-max or z-score), compute running totals, rolling averages, percent change between consecutive values, rank each value, or detect outliers.',\n inputSchema: validator.object({\n numbers: validator.string().required().description('JSON array of numbers'),\n operation: validator\n .string()\n .valid(\n 'normalize_min_max',\n 'normalize_z_score',\n 'normalize_percent_of_sum',\n 'running_total',\n 'rolling_avg',\n 'pct_change',\n 'rank',\n 'outliers_iqr',\n 'outliers_zscore'\n )\n .required()\n .description('Transformation to apply'),\n window: validator.number().default(3).description('For rolling_avg: window size (default: 3)'),\n threshold: validator\n .number()\n .default(3.0)\n .description('For outliers_zscore: z-score threshold (default: 3.0)'),\n }),\n handler: async (args) => {\n const { numbers, operation, window, threshold } = args as {\n numbers: string\n operation: string\n window: number\n threshold: number\n }\n const nums = parseNumbers(numbers)\n if ('error' in nums) return `Error: ${nums.error}`\n\n switch (operation) {\n case 'normalize_min_max': {\n const lo = min(nums)\n const hi = max(nums)\n if (lo === hi) return JSON.stringify(nums.map(() => 0))\n return JSON.stringify(nums.map((v) => Number.parseFloat(((v - lo) / (hi - lo)).toFixed(8))))\n }\n\n case 'normalize_z_score': {\n const m = mean(nums)\n const sd = standardDeviation(nums)\n if (sd === 0) return JSON.stringify(nums.map(() => 0))\n return JSON.stringify(nums.map((v) => Number.parseFloat(zScore(v, m, sd).toFixed(8))))\n }\n\n case 'normalize_percent_of_sum': {\n const total = sum(nums)\n if (total === 0) return JSON.stringify(nums.map(() => 0))\n return JSON.stringify(nums.map((v) => Number.parseFloat(((v / total) * 100).toFixed(4))))\n }\n\n case 'running_total': {\n const totals: number[] = []\n let acc = 0\n for (const v of nums) {\n acc += v\n totals.push(Number.parseFloat(acc.toPrecision(12)))\n }\n return JSON.stringify(totals)\n }\n\n case 'rolling_avg': {\n const w = Math.max(1, Math.floor(window))\n return JSON.stringify(\n nums.map((_, i) => {\n const slice = nums.slice(Math.max(0, i - w + 1), i + 1)\n return Number.parseFloat(mean(slice).toPrecision(8))\n })\n )\n }\n\n case 'pct_change': {\n const changes: (number | null)[] = [null]\n for (let i = 1; i < nums.length; i++) {\n if (nums[i - 1] === 0) {\n changes.push(null)\n } else {\n changes.push(\n Number.parseFloat(\n (((nums[i] - nums[i - 1]) / Math.abs(nums[i - 1])) * 100).toFixed(4)\n )\n )\n }\n }\n return JSON.stringify(changes)\n }\n\n case 'rank': {\n const sorted = [...nums].sort((a, b) => a - b)\n return JSON.stringify(nums.map((v) => sorted.indexOf(v) + 1))\n }\n\n case 'outliers_iqr': {\n const sorted = [...nums].sort((a, b) => a - b)\n const q1 = quantile(sorted, 0.25)\n const q3 = quantile(sorted, 0.75)\n const iqr = q3 - q1\n const lo = q1 - 1.5 * iqr\n const hi = q3 + 1.5 * iqr\n const outliers = nums\n .map((v, i) => ({ index: i, value: v }))\n .filter(({ value }) => value < lo || value > hi)\n if (outliers.length === 0) return 'No outliers detected (IQR method).'\n return `${outliers.length} outlier(s) detected:\\n${outliers.map((o) => ` [${o.index}] = ${o.value}`).join('\\n')}`\n }\n\n case 'outliers_zscore': {\n const m = mean(nums)\n const sd = standardDeviation(nums)\n const outliers = nums\n .map((v, i) => ({ index: i, value: v, z: sd === 0 ? 0 : Math.abs(zScore(v, m, sd)) }))\n .filter((o) => o.z > threshold)\n if (outliers.length === 0) return `No outliers detected (|z| > ${threshold}).`\n return `${outliers.length} outlier(s) detected (|z| > ${threshold}):\\n${outliers.map((o) => ` [${o.index}] = ${o.value} (z = ${o.z.toFixed(3)})`).join('\\n')}`\n }\n\n default:\n return `Error: Unknown operation \"${operation}\".`\n }\n },\n})\n\n/**\n * Bin a numeric array into equal-width histogram buckets.\n *\n * @remarks\n * Output is a text histogram showing each bin's range, count, percentage of total, and a bar\n * chart. The last bin is inclusive on both ends; preceding bins are half-open. `bins` is clamped\n * to `[2, 100]`.\n */\nexport const statsHistogramTool = new Tool({\n name: 'stats_histogram',\n description: 'Bin a numeric array into equal-width histogram buckets and display counts.',\n inputSchema: validator.object({\n numbers: validator.string().required().description('JSON array of numbers'),\n bins: validator.number().default(10).description('Number of bins (default: 10, max: 100)'),\n }),\n handler: async (args) => {\n const { numbers, bins } = args as { numbers: string; bins: number }\n const nums = parseNumbers(numbers)\n if ('error' in nums) return `Error: ${nums.error}`\n\n const binCount = Math.max(2, Math.min(100, Math.floor(bins)))\n\n try {\n const breaks = equalIntervalBreaks(nums, binCount)\n const rows: string[] = []\n const maxCount = (() => {\n let m = 0\n for (let i = 0; i < breaks.length - 1; i++) {\n const isLast = i === breaks.length - 2\n const count = nums.filter((v) =>\n isLast ? v >= breaks[i] && v <= breaks[i + 1] : v >= breaks[i] && v < breaks[i + 1]\n ).length\n if (count > m) m = count\n }\n return m\n })()\n\n for (let i = 0; i < breaks.length - 1; i++) {\n const isLast = i === breaks.length - 2\n const count = nums.filter((v) =>\n isLast ? v >= breaks[i] && v <= breaks[i + 1] : v >= breaks[i] && v < breaks[i + 1]\n ).length\n const pct = ((count / nums.length) * 100).toFixed(1)\n const bar = '█'.repeat(maxCount > 0 ? Math.round((count / maxCount) * 20) : 0)\n const range = `[${breaks[i].toPrecision(4)}, ${breaks[i + 1].toPrecision(4)}${isLast ? ']' : ')'}`\n rows.push(`${range.padEnd(22)} ${String(count).padStart(4)} (${pct.padStart(5)}%) ${bar}`)\n }\n\n return rows.join('\\n')\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n"],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Pre-constructed tools for casing, trimming, normalizing, and transforming strings.
3
+ *
4
+ * @module @nhtio/adk/batteries/tools/string_processing
5
+ *
6
+ * @remarks
7
+ * Pre-constructed bundled tools for the `string_processing` category. Import individually, the whole
8
+ * category, or import every tool via `@nhtio/adk/batteries`.
9
+ */
10
+ import { Tool } from "../../../common";
11
+ /**
12
+ * Apply an ordered pipeline of string transformations.
13
+ *
14
+ * @remarks
15
+ * Each operation reads the previous step's output. Most operations return strings; `count_*`
16
+ * return numbers and `split` returns an array — once a non-string flows through, subsequent
17
+ * operations report an error rather than coercing. The result is always serialised to a string
18
+ * (arrays become JSON; numbers/booleans are stringified).
19
+ */
20
+ export declare const stringTransformTool: Tool<import("../../../common").SpooledArtifact>;
21
+ /**
22
+ * Extract all matches of a regular expression from a string.
23
+ *
24
+ * @remarks
25
+ * The `g` flag is always enabled. `group` selects which capture group to return per match (0 =
26
+ * full match). Output is at most 500 matches; if truncated, the suffix `(truncated at 500)` is
27
+ * appended.
28
+ */
29
+ export declare const stringExtractTool: Tool<import("../../../common").SpooledArtifact>;