@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.
- package/LICENSE.md +9 -0
- package/README.md +3 -0
- package/batteries/index.d.ts +28 -0
- package/batteries/llm/index.d.ts +11 -0
- package/batteries/llm/openai_chat_completions/adapter.cjs +916 -0
- package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -0
- package/batteries/llm/openai_chat_completions/adapter.d.ts +101 -0
- package/batteries/llm/openai_chat_completions/adapter.mjs +914 -0
- package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -0
- package/batteries/llm/openai_chat_completions/exceptions.cjs +89 -0
- package/batteries/llm/openai_chat_completions/exceptions.cjs.map +1 -0
- package/batteries/llm/openai_chat_completions/exceptions.d.ts +97 -0
- package/batteries/llm/openai_chat_completions/exceptions.mjs +81 -0
- package/batteries/llm/openai_chat_completions/exceptions.mjs.map +1 -0
- package/batteries/llm/openai_chat_completions/helpers.cjs +819 -0
- package/batteries/llm/openai_chat_completions/helpers.cjs.map +1 -0
- package/batteries/llm/openai_chat_completions/helpers.d.ts +233 -0
- package/batteries/llm/openai_chat_completions/helpers.mjs +783 -0
- package/batteries/llm/openai_chat_completions/helpers.mjs.map +1 -0
- package/batteries/llm/openai_chat_completions/index.d.ts +27 -0
- package/batteries/llm/openai_chat_completions/types.cjs +1 -0
- package/batteries/llm/openai_chat_completions/types.d.ts +524 -0
- package/batteries/llm/openai_chat_completions/types.mjs +0 -0
- package/batteries/llm/openai_chat_completions/validation.cjs +190 -0
- package/batteries/llm/openai_chat_completions/validation.cjs.map +1 -0
- package/batteries/llm/openai_chat_completions/validation.d.ts +31 -0
- package/batteries/llm/openai_chat_completions/validation.mjs +187 -0
- package/batteries/llm/openai_chat_completions/validation.mjs.map +1 -0
- package/batteries/llm/openai_chat_completions.cjs +51 -0
- package/batteries/llm/openai_chat_completions.mjs +5 -0
- package/batteries/llm/webllm_chat_completions/adapter.cjs +658 -0
- package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -0
- package/batteries/llm/webllm_chat_completions/adapter.d.ts +103 -0
- package/batteries/llm/webllm_chat_completions/adapter.mjs +656 -0
- package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -0
- package/batteries/llm/webllm_chat_completions/exceptions.cjs +70 -0
- package/batteries/llm/webllm_chat_completions/exceptions.cjs.map +1 -0
- package/batteries/llm/webllm_chat_completions/exceptions.d.ts +74 -0
- package/batteries/llm/webllm_chat_completions/exceptions.mjs +65 -0
- package/batteries/llm/webllm_chat_completions/exceptions.mjs.map +1 -0
- package/batteries/llm/webllm_chat_completions/helpers.cjs +38 -0
- package/batteries/llm/webllm_chat_completions/helpers.d.ts +6 -0
- package/batteries/llm/webllm_chat_completions/helpers.mjs +2 -0
- package/batteries/llm/webllm_chat_completions/index.d.ts +25 -0
- package/batteries/llm/webllm_chat_completions/types.d.ts +31 -0
- package/batteries/llm/webllm_chat_completions/validation.cjs +115 -0
- package/batteries/llm/webllm_chat_completions/validation.cjs.map +1 -0
- package/batteries/llm/webllm_chat_completions/validation.d.ts +8 -0
- package/batteries/llm/webllm_chat_completions/validation.mjs +112 -0
- package/batteries/llm/webllm_chat_completions/validation.mjs.map +1 -0
- package/batteries/llm/webllm_chat_completions.cjs +50 -0
- package/batteries/llm/webllm_chat_completions.mjs +6 -0
- package/batteries/llm.cjs +63 -0
- package/batteries/llm.mjs +10 -0
- package/batteries/storage/flydrive/index.d.ts +167 -0
- package/batteries/storage/flydrive.cjs +249 -0
- package/batteries/storage/flydrive.cjs.map +1 -0
- package/batteries/storage/flydrive.mjs +249 -0
- package/batteries/storage/flydrive.mjs.map +1 -0
- package/batteries/storage/in_memory/index.d.ts +106 -0
- package/batteries/storage/in_memory.cjs +121 -0
- package/batteries/storage/in_memory.cjs.map +1 -0
- package/batteries/storage/in_memory.mjs +119 -0
- package/batteries/storage/in_memory.mjs.map +1 -0
- package/batteries/storage/index.d.ts +18 -0
- package/batteries/storage/opfs/index.d.ts +299 -0
- package/batteries/storage/opfs.cjs +368 -0
- package/batteries/storage/opfs.cjs.map +1 -0
- package/batteries/storage/opfs.mjs +366 -0
- package/batteries/storage/opfs.mjs.map +1 -0
- package/batteries/storage.cjs +4 -0
- package/batteries/storage.mjs +2 -0
- package/batteries/tools/color/index.d.ts +37 -0
- package/batteries/tools/color.cjs +659 -0
- package/batteries/tools/color.cjs.map +1 -0
- package/batteries/tools/color.mjs +655 -0
- package/batteries/tools/color.mjs.map +1 -0
- package/batteries/tools/comparison/index.d.ts +29 -0
- package/batteries/tools/comparison.cjs +171 -0
- package/batteries/tools/comparison.cjs.map +1 -0
- package/batteries/tools/comparison.mjs +168 -0
- package/batteries/tools/comparison.mjs.map +1 -0
- package/batteries/tools/data_structure/index.d.ts +30 -0
- package/batteries/tools/data_structure.cjs +270 -0
- package/batteries/tools/data_structure.cjs.map +1 -0
- package/batteries/tools/data_structure.mjs +267 -0
- package/batteries/tools/data_structure.mjs.map +1 -0
- package/batteries/tools/datetime_extended/index.d.ts +51 -0
- package/batteries/tools/datetime_extended.cjs +309 -0
- package/batteries/tools/datetime_extended.cjs.map +1 -0
- package/batteries/tools/datetime_extended.mjs +302 -0
- package/batteries/tools/datetime_extended.mjs.map +1 -0
- package/batteries/tools/datetime_math/index.d.ts +36 -0
- package/batteries/tools/datetime_math.cjs +175 -0
- package/batteries/tools/datetime_math.cjs.map +1 -0
- package/batteries/tools/datetime_math.mjs +171 -0
- package/batteries/tools/datetime_math.mjs.map +1 -0
- package/batteries/tools/encoding/index.d.ts +36 -0
- package/batteries/tools/encoding.cjs +156 -0
- package/batteries/tools/encoding.cjs.map +1 -0
- package/batteries/tools/encoding.mjs +152 -0
- package/batteries/tools/encoding.mjs.map +1 -0
- package/batteries/tools/formatting/index.d.ts +28 -0
- package/batteries/tools/formatting.cjs +120 -0
- package/batteries/tools/formatting.cjs.map +1 -0
- package/batteries/tools/formatting.mjs +117 -0
- package/batteries/tools/formatting.mjs.map +1 -0
- package/batteries/tools/geo_basics/index.d.ts +33 -0
- package/batteries/tools/geo_basics.cjs +136 -0
- package/batteries/tools/geo_basics.cjs.map +1 -0
- package/batteries/tools/geo_basics.mjs +132 -0
- package/batteries/tools/geo_basics.mjs.map +1 -0
- package/batteries/tools/index.d.ts +32 -0
- package/batteries/tools/math/index.d.ts +37 -0
- package/batteries/tools/math.cjs +136 -0
- package/batteries/tools/math.cjs.map +1 -0
- package/batteries/tools/math.mjs +133 -0
- package/batteries/tools/math.mjs.map +1 -0
- package/batteries/tools/memory/index.d.ts +73 -0
- package/batteries/tools/memory.cjs +193 -0
- package/batteries/tools/memory.cjs.map +1 -0
- package/batteries/tools/memory.mjs +187 -0
- package/batteries/tools/memory.mjs.map +1 -0
- package/batteries/tools/parsing/index.d.ts +47 -0
- package/batteries/tools/parsing.cjs +191 -0
- package/batteries/tools/parsing.cjs.map +1 -0
- package/batteries/tools/parsing.mjs +185 -0
- package/batteries/tools/parsing.mjs.map +1 -0
- package/batteries/tools/retrievables/index.d.ts +81 -0
- package/batteries/tools/retrievables.cjs +215 -0
- package/batteries/tools/retrievables.cjs.map +1 -0
- package/batteries/tools/retrievables.mjs +209 -0
- package/batteries/tools/retrievables.mjs.map +1 -0
- package/batteries/tools/standing_instructions/index.d.ts +64 -0
- package/batteries/tools/standing_instructions.cjs +126 -0
- package/batteries/tools/standing_instructions.cjs.map +1 -0
- package/batteries/tools/standing_instructions.mjs +121 -0
- package/batteries/tools/standing_instructions.mjs.map +1 -0
- package/batteries/tools/statistics/index.d.ts +46 -0
- package/batteries/tools/statistics.cjs +253 -0
- package/batteries/tools/statistics.cjs.map +1 -0
- package/batteries/tools/statistics.mjs +248 -0
- package/batteries/tools/statistics.mjs.map +1 -0
- package/batteries/tools/string_processing/index.d.ts +29 -0
- package/batteries/tools/string_processing.cjs +154 -0
- package/batteries/tools/string_processing.cjs.map +1 -0
- package/batteries/tools/string_processing.mjs +151 -0
- package/batteries/tools/string_processing.mjs.map +1 -0
- package/batteries/tools/structured_data/index.d.ts +34 -0
- package/batteries/tools/structured_data.cjs +189 -0
- package/batteries/tools/structured_data.cjs.map +1 -0
- package/batteries/tools/structured_data.mjs +185 -0
- package/batteries/tools/structured_data.mjs.map +1 -0
- package/batteries/tools/text_analysis/index.d.ts +31 -0
- package/batteries/tools/text_analysis.cjs +120 -0
- package/batteries/tools/text_analysis.cjs.map +1 -0
- package/batteries/tools/text_analysis.mjs +117 -0
- package/batteries/tools/text_analysis.mjs.map +1 -0
- package/batteries/tools/text_comparison/index.d.ts +28 -0
- package/batteries/tools/text_comparison.cjs +96 -0
- package/batteries/tools/text_comparison.cjs.map +1 -0
- package/batteries/tools/text_comparison.mjs +93 -0
- package/batteries/tools/text_comparison.mjs.map +1 -0
- package/batteries/tools/time/index.d.ts +27 -0
- package/batteries/tools/time.cjs +63 -0
- package/batteries/tools/time.cjs.map +1 -0
- package/batteries/tools/time.mjs +60 -0
- package/batteries/tools/time.mjs.map +1 -0
- package/batteries/tools/unit_conversion/index.d.ts +19 -0
- package/batteries/tools/unit_conversion.cjs +452 -0
- package/batteries/tools/unit_conversion.cjs.map +1 -0
- package/batteries/tools/unit_conversion.mjs +450 -0
- package/batteries/tools/unit_conversion.mjs.map +1 -0
- package/batteries/tools.cjs +80 -0
- package/batteries/tools.mjs +21 -0
- package/batteries.cjs +142 -0
- package/batteries.mjs +30 -0
- package/chunk-KmRHZBOW.js +35 -0
- package/common-DeZaonK1.mjs +208 -0
- package/common-DeZaonK1.mjs.map +1 -0
- package/common-Od8edUXU.js +232 -0
- package/common-Od8edUXU.js.map +1 -0
- package/common.cjs +31 -0
- package/common.d.ts +108 -0
- package/common.mjs +8 -0
- package/dispatch_runner-9j6bXHL3.mjs +1609 -0
- package/dispatch_runner-9j6bXHL3.mjs.map +1 -0
- package/dispatch_runner-CsoH0nld.js +1627 -0
- package/dispatch_runner-CsoH0nld.js.map +1 -0
- package/dispatch_runner.cjs +3 -0
- package/dispatch_runner.d.ts +17 -0
- package/dispatch_runner.mjs +2 -0
- package/exceptions-D5YrO9Vm.js +280 -0
- package/exceptions-D5YrO9Vm.js.map +1 -0
- package/exceptions-NrzIHw_R.mjs +244 -0
- package/exceptions-NrzIHw_R.mjs.map +1 -0
- package/exceptions.cjs +33 -0
- package/exceptions.d.ts +52 -0
- package/exceptions.mjs +3 -0
- package/factories.cjs +4 -0
- package/factories.d.ts +39 -0
- package/factories.mjs +2 -0
- package/forge.cjs +9 -0
- package/forge.d.ts +49 -0
- package/forge.mjs +5 -0
- package/guards.cjs +96 -0
- package/guards.cjs.map +1 -0
- package/guards.d.ts +83 -0
- package/guards.mjs +72 -0
- package/guards.mjs.map +1 -0
- package/index.cjs +107 -0
- package/index.cjs.map +1 -0
- package/index.d.ts +18 -0
- package/index.mjs +31 -0
- package/index.mjs.map +1 -0
- package/lib/classes/artifact_tool.d.ts +129 -0
- package/lib/classes/base_exception.d.ts +83 -0
- package/lib/classes/identity.d.ts +71 -0
- package/lib/classes/media.d.ts +326 -0
- package/lib/classes/memory.d.ts +72 -0
- package/lib/classes/message.d.ts +137 -0
- package/lib/classes/registry.d.ts +79 -0
- package/lib/classes/retrievable.d.ts +100 -0
- package/lib/classes/spooled_artifact.d.ts +296 -0
- package/lib/classes/spooled_json_artifact.d.ts +158 -0
- package/lib/classes/spooled_markdown_artifact.d.ts +202 -0
- package/lib/classes/thought.d.ts +142 -0
- package/lib/classes/tokenizable.d.ts +124 -0
- package/lib/classes/tool.d.ts +228 -0
- package/lib/classes/tool_call.d.ts +190 -0
- package/lib/classes/tool_registry.d.ts +159 -0
- package/lib/classes/turn_gate.d.ts +109 -0
- package/lib/contracts/dispatch_context.d.ts +345 -0
- package/lib/contracts/media_reader.d.ts +60 -0
- package/lib/contracts/spool_reader.d.ts +80 -0
- package/lib/contracts/spooled_artifact_constructor.d.ts +38 -0
- package/lib/contracts/turn_runner_config.d.ts +101 -0
- package/lib/contracts/turn_runner_context.d.ts +267 -0
- package/lib/dispatch_runner.d.ts +98 -0
- package/lib/exceptions/runtime.d.ts +370 -0
- package/lib/helpers/media_readers.d.ts +39 -0
- package/lib/turn_runner.d.ts +144 -0
- package/lib/types/dispatch_context.d.ts +233 -0
- package/lib/types/dispatch_runner.d.ts +387 -0
- package/lib/types/turn_runner.d.ts +322 -0
- package/lib/utils/canonical_json.d.ts +18 -0
- package/lib/utils/exceptions.d.ts +78 -0
- package/lib/utils/guards.d.ts +32 -0
- package/lib/utils/validation.d.ts +77 -0
- package/package.json +334 -0
- package/runtime-BJVkrGQe.js +519 -0
- package/runtime-BJVkrGQe.js.map +1 -0
- package/runtime-CrEPIFgr.mjs +346 -0
- package/runtime-CrEPIFgr.mjs.map +1 -0
- package/skills/adk-assembly/SKILL.md +109 -0
- package/skills/adk-assembly/references/assembly-contract.md +66 -0
- package/skills/adk-assembly/references/executors-tools-pipelines-events.md +113 -0
- package/skills/adk-assembly/references/first-integration.md +93 -0
- package/skills/adk-assembly/references/storage-and-context.md +102 -0
- package/spooled_artifact-C5ZtGxuJ.mjs +544 -0
- package/spooled_artifact-C5ZtGxuJ.mjs.map +1 -0
- package/spooled_artifact-Cm9Te22K.js +568 -0
- package/spooled_artifact-Cm9Te22K.js.map +1 -0
- package/spooled_artifact.cjs +7 -0
- package/spooled_artifact.d.ts +40 -0
- package/spooled_artifact.mjs +3 -0
- package/spooled_markdown_artifact-BpUJol0W.mjs +771 -0
- package/spooled_markdown_artifact-BpUJol0W.mjs.map +1 -0
- package/spooled_markdown_artifact-RRB113sy.js +786 -0
- package/spooled_markdown_artifact-RRB113sy.js.map +1 -0
- package/thought-CDb457b4.mjs +470 -0
- package/thought-CDb457b4.mjs.map +1 -0
- package/thought-DuN2PgdO.js +494 -0
- package/thought-DuN2PgdO.js.map +1 -0
- package/tool-COSeH8I6.js +302 -0
- package/tool-COSeH8I6.js.map +1 -0
- package/tool-D2WB1EA1.mjs +296 -0
- package/tool-D2WB1EA1.mjs.map +1 -0
- package/tool_call-BKyyxGaZ.mjs +578 -0
- package/tool_call-BKyyxGaZ.mjs.map +1 -0
- package/tool_call-DFgzcVcU.js +608 -0
- package/tool_call-DFgzcVcU.js.map +1 -0
- package/tool_registry-Dkfprsck.js +641 -0
- package/tool_registry-Dkfprsck.js.map +1 -0
- package/tool_registry-DqLOyGyG.mjs +592 -0
- package/tool_registry-DqLOyGyG.mjs.map +1 -0
- package/turn_runner-CMm2BHdX.js +615 -0
- package/turn_runner-CMm2BHdX.js.map +1 -0
- package/turn_runner-y7eyEcJH.mjs +603 -0
- package/turn_runner-y7eyEcJH.mjs.map +1 -0
- package/turn_runner.cjs +3 -0
- package/turn_runner.d.ts +21 -0
- package/turn_runner.mjs +2 -0
- package/types.cjs +1 -0
- package/types.d.ts +56 -0
- package/types.mjs +0 -0
- 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>;
|