@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,270 @@
|
|
|
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
|
+
require("../../guards.cjs");
|
|
7
|
+
let _nhtio_validation = require("@nhtio/validation");
|
|
8
|
+
//#region src/batteries/tools/data_structure/index.ts
|
|
9
|
+
/**
|
|
10
|
+
* Pre-constructed tools for querying, filtering, grouping, and reshaping structured values.
|
|
11
|
+
*
|
|
12
|
+
* @module @nhtio/adk/batteries/tools/data_structure
|
|
13
|
+
*
|
|
14
|
+
* @remarks
|
|
15
|
+
* Pre-constructed bundled tools for the `data_structure` category. Import individually, the whole
|
|
16
|
+
* category, or import every tool via `@nhtio/adk/batteries`.
|
|
17
|
+
*/
|
|
18
|
+
function getPath(obj, path) {
|
|
19
|
+
const parts = path.split(".");
|
|
20
|
+
let current = obj;
|
|
21
|
+
for (const part of parts) {
|
|
22
|
+
if (current === null || current === void 0 || typeof current !== "object") return void 0;
|
|
23
|
+
current = current[part];
|
|
24
|
+
}
|
|
25
|
+
return current;
|
|
26
|
+
}
|
|
27
|
+
function matchesFilter(item, key, operator, value) {
|
|
28
|
+
const actual = getPath(item, key);
|
|
29
|
+
switch (operator) {
|
|
30
|
+
case "eq": return actual === value;
|
|
31
|
+
case "ne": return actual !== value;
|
|
32
|
+
case "gt": return typeof actual === "number" && actual > value;
|
|
33
|
+
case "gte": return typeof actual === "number" && actual >= value;
|
|
34
|
+
case "lt": return typeof actual === "number" && actual < value;
|
|
35
|
+
case "lte": return typeof actual === "number" && actual <= value;
|
|
36
|
+
case "contains": return typeof actual === "string" && actual.includes(String(value));
|
|
37
|
+
case "starts_with": return typeof actual === "string" && actual.startsWith(String(value));
|
|
38
|
+
case "ends_with": return typeof actual === "string" && actual.endsWith(String(value));
|
|
39
|
+
case "exists": return actual !== void 0 && actual !== null;
|
|
40
|
+
default: return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function medianOf(nums) {
|
|
44
|
+
const sorted = [...nums].sort((a, b) => a - b);
|
|
45
|
+
const mid = Math.floor(sorted.length / 2);
|
|
46
|
+
return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
47
|
+
}
|
|
48
|
+
function applyTemplate(template, item) {
|
|
49
|
+
if (typeof item !== "object" || item === null) return String(item);
|
|
50
|
+
return template.replace(/\{\{([^}]+)\}\}/g, (_, key) => {
|
|
51
|
+
const val = getPath(item, key.trim());
|
|
52
|
+
return val === void 0 || val === null ? "" : String(val);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function applyOperation(data, op) {
|
|
56
|
+
if (op.op === "count") {
|
|
57
|
+
if (Array.isArray(data)) return data.length;
|
|
58
|
+
if (require_tool_registry.isObject(data)) return Object.keys(data).length;
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
if (!Array.isArray(data)) throw new Error(`Operation "${op.op}" requires an array input.`);
|
|
62
|
+
const arr = data;
|
|
63
|
+
switch (op.op) {
|
|
64
|
+
case "filter": return arr.filter((item) => matchesFilter(item, op.key, op.operator, op.value));
|
|
65
|
+
case "sort": {
|
|
66
|
+
const dir = op.direction === "desc" ? -1 : 1;
|
|
67
|
+
return [...arr].sort((a, b) => {
|
|
68
|
+
const av = getPath(a, op.key);
|
|
69
|
+
const bv = getPath(b, op.key);
|
|
70
|
+
if (av === bv) return 0;
|
|
71
|
+
if (av === void 0 || av === null) return 1;
|
|
72
|
+
if (bv === void 0 || bv === null) return -1;
|
|
73
|
+
if (typeof av === "number" && typeof bv === "number") return (av - bv) * dir;
|
|
74
|
+
return String(av).localeCompare(String(bv)) * dir;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
case "select_keys": return arr.map((item) => {
|
|
78
|
+
if (typeof item !== "object" || item === null) return item;
|
|
79
|
+
const result = {};
|
|
80
|
+
for (const key of op.keys) result[key] = item[key];
|
|
81
|
+
return result;
|
|
82
|
+
});
|
|
83
|
+
case "pluck": return arr.map((item) => getPath(item, op.key));
|
|
84
|
+
case "slice": return arr.slice(op.start, op.end);
|
|
85
|
+
case "unique": {
|
|
86
|
+
const seen = /* @__PURE__ */ new Set();
|
|
87
|
+
return arr.filter((item) => {
|
|
88
|
+
const key = typeof item === "object" ? JSON.stringify(item) : String(item);
|
|
89
|
+
if (seen.has(key)) return false;
|
|
90
|
+
seen.add(key);
|
|
91
|
+
return true;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
case "unique_by": {
|
|
95
|
+
const seen = /* @__PURE__ */ new Set();
|
|
96
|
+
return arr.filter((item) => {
|
|
97
|
+
const key = getPath(item, op.key);
|
|
98
|
+
if (seen.has(key)) return false;
|
|
99
|
+
seen.add(key);
|
|
100
|
+
return true;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
case "group_by": {
|
|
104
|
+
const groups = {};
|
|
105
|
+
for (const item of arr) {
|
|
106
|
+
const key = String(getPath(item, op.key) ?? "__undefined__");
|
|
107
|
+
if (!groups[key]) groups[key] = [];
|
|
108
|
+
groups[key].push(item);
|
|
109
|
+
}
|
|
110
|
+
return groups;
|
|
111
|
+
}
|
|
112
|
+
case "flatten": return arr.flat(op.depth ?? 1);
|
|
113
|
+
case "reverse": return [...arr].reverse();
|
|
114
|
+
case "sum": return (op.key ? arr.map((i) => getPath(i, op.key)) : arr).reduce((acc, v) => acc + (typeof v === "number" ? v : 0), 0);
|
|
115
|
+
case "avg": {
|
|
116
|
+
const nums = (op.key ? arr.map((i) => getPath(i, op.key)) : arr).filter((v) => typeof v === "number");
|
|
117
|
+
if (nums.length === 0) return null;
|
|
118
|
+
return nums.reduce((a, b) => a + b, 0) / nums.length;
|
|
119
|
+
}
|
|
120
|
+
case "median": {
|
|
121
|
+
const nums = (op.key ? arr.map((i) => getPath(i, op.key)) : arr).filter((v) => typeof v === "number");
|
|
122
|
+
if (nums.length === 0) return null;
|
|
123
|
+
return medianOf(nums);
|
|
124
|
+
}
|
|
125
|
+
case "min": {
|
|
126
|
+
const nums = (op.key ? arr.map((i) => getPath(i, op.key)) : arr).filter((v) => typeof v === "number");
|
|
127
|
+
if (nums.length === 0) return null;
|
|
128
|
+
return Math.min(...nums);
|
|
129
|
+
}
|
|
130
|
+
case "max": {
|
|
131
|
+
const nums = (op.key ? arr.map((i) => getPath(i, op.key)) : arr).filter((v) => typeof v === "number");
|
|
132
|
+
if (nums.length === 0) return null;
|
|
133
|
+
return Math.max(...nums);
|
|
134
|
+
}
|
|
135
|
+
case "first": return op.n !== void 0 ? arr.slice(0, op.n) : arr[0];
|
|
136
|
+
case "last": return op.n !== void 0 ? arr.slice(-op.n) : arr[arr.length - 1];
|
|
137
|
+
case "chunk": {
|
|
138
|
+
const size = Math.max(1, Math.floor(op.size));
|
|
139
|
+
const chunks = [];
|
|
140
|
+
for (let i = 0; i < arr.length; i += size) chunks.push(arr.slice(i, i + size));
|
|
141
|
+
return chunks;
|
|
142
|
+
}
|
|
143
|
+
case "frequency_count": {
|
|
144
|
+
const freq = {};
|
|
145
|
+
for (const item of arr) {
|
|
146
|
+
const key = op.key ? String(getPath(item, op.key) ?? "__undefined__") : String(item);
|
|
147
|
+
freq[key] = (freq[key] ?? 0) + 1;
|
|
148
|
+
}
|
|
149
|
+
return freq;
|
|
150
|
+
}
|
|
151
|
+
case "top_n": {
|
|
152
|
+
const dir = op.direction === "asc" ? 1 : -1;
|
|
153
|
+
return [...arr].sort((a, b) => {
|
|
154
|
+
const av = getPath(a, op.key);
|
|
155
|
+
const bv = getPath(b, op.key);
|
|
156
|
+
if (typeof av === "number" && typeof bv === "number") return (bv - av) * dir;
|
|
157
|
+
return String(bv).localeCompare(String(av)) * dir;
|
|
158
|
+
}).slice(0, op.n);
|
|
159
|
+
}
|
|
160
|
+
case "map_template": return arr.map((item) => applyTemplate(op.template, item));
|
|
161
|
+
default: throw new Error(`Unknown operation: ${op.op}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Apply a pipeline of operations to a JSON array or object.
|
|
166
|
+
*
|
|
167
|
+
* @remarks
|
|
168
|
+
* Operations are applied in order; each step transforms the output of the previous. Supported
|
|
169
|
+
* operations: `filter`, `sort`, `select_keys`, `pluck`, `slice`, `unique`, `unique_by`,
|
|
170
|
+
* `group_by`, `flatten`, `reverse`, `count`, `sum`, `avg`, `median`, `min`, `max`, `first`,
|
|
171
|
+
* `last`, `chunk`, `frequency_count`, `top_n`, `map_template`. Dot-notation paths are supported
|
|
172
|
+
* for nested key access in every operation that takes a `key` field.
|
|
173
|
+
*/
|
|
174
|
+
var jsonTransformTool = new require_tool.Tool({
|
|
175
|
+
name: "json_transform",
|
|
176
|
+
description: "Apply a pipeline of operations to a JSON array or object: filter, sort, group, aggregate (sum/avg/median/min/max), pluck fields, deduplicate, flatten, chunk, frequency count, top-N, and more.",
|
|
177
|
+
inputSchema: _nhtio_validation.validator.object({
|
|
178
|
+
data: _nhtio_validation.validator.string().required().description("JSON data as a string (array or object)"),
|
|
179
|
+
operations: _nhtio_validation.validator.array().items(_nhtio_validation.validator.object().unknown(true)).required().description("Pipeline of operations to apply in order. Each step transforms the output of the previous.")
|
|
180
|
+
}),
|
|
181
|
+
handler: async (args) => {
|
|
182
|
+
const { data: dataStr, operations } = args;
|
|
183
|
+
let data;
|
|
184
|
+
try {
|
|
185
|
+
data = JSON.parse(dataStr);
|
|
186
|
+
} catch {
|
|
187
|
+
return "Error: Invalid JSON input.";
|
|
188
|
+
}
|
|
189
|
+
let current = data;
|
|
190
|
+
for (const [i, operation] of operations.entries()) try {
|
|
191
|
+
current = applyOperation(current, operation);
|
|
192
|
+
} catch (err) {
|
|
193
|
+
return `Error in operation ${i + 1} ("${operation.op}"): ${require_tool_registry.isError(err) ? err.message : String(err)}`;
|
|
194
|
+
}
|
|
195
|
+
if (typeof current === "string") return current;
|
|
196
|
+
return JSON.stringify(current, null, 2);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
/**
|
|
200
|
+
* Perform set operations on two JSON arrays.
|
|
201
|
+
*
|
|
202
|
+
* @remarks
|
|
203
|
+
* Supported operations: `intersection`, `union`, `difference`, `symmetric_difference`,
|
|
204
|
+
* `is_member`, `is_subset`, `is_superset`. For arrays of objects, an optional `compare_key`
|
|
205
|
+
* narrows equality to a single property rather than deep structural comparison.
|
|
206
|
+
*/
|
|
207
|
+
var setOperationsTool = new require_tool.Tool({
|
|
208
|
+
name: "set_operations",
|
|
209
|
+
description: "Perform set operations on two JSON arrays: intersection (common elements), union (all elements), difference (in A but not B), symmetric difference, or membership check.",
|
|
210
|
+
inputSchema: _nhtio_validation.validator.object({
|
|
211
|
+
data_a: _nhtio_validation.validator.string().required().description("First JSON array"),
|
|
212
|
+
data_b: _nhtio_validation.validator.string().optional().description("Second JSON array"),
|
|
213
|
+
operation: _nhtio_validation.validator.string().valid("intersection", "union", "difference", "symmetric_difference", "is_member", "is_subset", "is_superset").required().description("Set operation to perform"),
|
|
214
|
+
item: _nhtio_validation.validator.any().optional().description("For is_member: the value to look up in data_a."),
|
|
215
|
+
compare_key: _nhtio_validation.validator.string().optional().description("For arrays of objects: use this key for equality comparison instead of deep equality.")
|
|
216
|
+
}),
|
|
217
|
+
handler: async (args) => {
|
|
218
|
+
const { data_a: dataA, data_b: dataB, operation, item, compare_key: compareKey } = args;
|
|
219
|
+
let a;
|
|
220
|
+
let b = [];
|
|
221
|
+
try {
|
|
222
|
+
a = JSON.parse(dataA);
|
|
223
|
+
} catch {
|
|
224
|
+
return "Error: data_a is not valid JSON.";
|
|
225
|
+
}
|
|
226
|
+
if (!Array.isArray(a)) return "Error: data_a must be a JSON array.";
|
|
227
|
+
if (dataB !== void 0) {
|
|
228
|
+
try {
|
|
229
|
+
b = JSON.parse(dataB);
|
|
230
|
+
} catch {
|
|
231
|
+
return "Error: data_b is not valid JSON.";
|
|
232
|
+
}
|
|
233
|
+
if (!Array.isArray(b)) return "Error: data_b must be a JSON array.";
|
|
234
|
+
}
|
|
235
|
+
const toKey = (val) => compareKey && require_tool_registry.isObject(val) ? String(val[compareKey]) : JSON.stringify(val);
|
|
236
|
+
if (operation === "is_member") {
|
|
237
|
+
const needle = JSON.stringify(item);
|
|
238
|
+
return a.some((entry) => JSON.stringify(entry) === needle) ? `Found: item is in the array.` : `Not found: item is not in the array.`;
|
|
239
|
+
}
|
|
240
|
+
const setA = new Set(a.map(toKey));
|
|
241
|
+
const setB = new Set(b.map(toKey));
|
|
242
|
+
const indexA = new Map(a.map((entry) => [toKey(entry), entry]));
|
|
243
|
+
switch (operation) {
|
|
244
|
+
case "intersection": {
|
|
245
|
+
const result = [...setA].filter((k) => setB.has(k)).map((k) => indexA.get(k));
|
|
246
|
+
return JSON.stringify(result, null, 2);
|
|
247
|
+
}
|
|
248
|
+
case "union": {
|
|
249
|
+
const result = [...a, ...b.filter((entry) => !setA.has(toKey(entry)))];
|
|
250
|
+
return JSON.stringify(result, null, 2);
|
|
251
|
+
}
|
|
252
|
+
case "difference": {
|
|
253
|
+
const result = a.filter((entry) => !setB.has(toKey(entry)));
|
|
254
|
+
return JSON.stringify(result, null, 2);
|
|
255
|
+
}
|
|
256
|
+
case "symmetric_difference": {
|
|
257
|
+
const result = [...a.filter((entry) => !setB.has(toKey(entry))), ...b.filter((entry) => !setA.has(toKey(entry)))];
|
|
258
|
+
return JSON.stringify(result, null, 2);
|
|
259
|
+
}
|
|
260
|
+
case "is_subset": return [...setA].every((k) => setB.has(k)) ? `Yes: A is a subset of B (all ${a.length} elements of A are in B).` : `No: A is not a subset of B.`;
|
|
261
|
+
case "is_superset": return [...setB].every((k) => setA.has(k)) ? `Yes: A is a superset of B (A contains all ${b.length} elements of B).` : `No: A is not a superset of B.`;
|
|
262
|
+
default: return `Error: Unknown operation "${operation}".`;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
//#endregion
|
|
267
|
+
exports.jsonTransformTool = jsonTransformTool;
|
|
268
|
+
exports.setOperationsTool = setOperationsTool;
|
|
269
|
+
|
|
270
|
+
//# sourceMappingURL=data_structure.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data_structure.cjs","names":[],"sources":["../../../src/batteries/tools/data_structure/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for querying, filtering, grouping, and reshaping structured values.\n *\n * @module @nhtio/adk/batteries/tools/data_structure\n *\n * @remarks\n * Pre-constructed bundled tools for the `data_structure` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport { Tool } from '@nhtio/adk/common'\nimport { validator } from '@nhtio/validation'\nimport { isError, isObject } from '@nhtio/adk/guards'\n\nfunction getPath(obj: unknown, path: string): unknown {\n const parts = path.split('.')\n let current = obj\n for (const part of parts) {\n if (current === null || current === undefined || typeof current !== 'object') return undefined\n current = (current as Record<string, unknown>)[part]\n }\n return current\n}\n\ntype FilterOperator =\n | 'eq'\n | 'ne'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | 'contains'\n | 'starts_with'\n | 'ends_with'\n | 'exists'\n\nfunction matchesFilter(\n item: unknown,\n key: string,\n operator: FilterOperator,\n value: unknown\n): boolean {\n const actual = getPath(item, key)\n switch (operator) {\n case 'eq':\n return actual === value\n case 'ne':\n return actual !== value\n case 'gt':\n return typeof actual === 'number' && actual > (value as number)\n case 'gte':\n return typeof actual === 'number' && actual >= (value as number)\n case 'lt':\n return typeof actual === 'number' && actual < (value as number)\n case 'lte':\n return typeof actual === 'number' && actual <= (value as number)\n case 'contains':\n return typeof actual === 'string' && actual.includes(String(value))\n case 'starts_with':\n return typeof actual === 'string' && actual.startsWith(String(value))\n case 'ends_with':\n return typeof actual === 'string' && actual.endsWith(String(value))\n case 'exists':\n return actual !== undefined && actual !== null\n default:\n return false\n }\n}\n\nfunction medianOf(nums: number[]): number {\n const sorted = [...nums].sort((a, b) => a - b)\n const mid = Math.floor(sorted.length / 2)\n return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid]\n}\n\nfunction applyTemplate(template: string, item: unknown): string {\n if (typeof item !== 'object' || item === null) return String(item)\n return template.replace(/\\{\\{([^}]+)\\}\\}/g, (_, key) => {\n const val = getPath(item, key.trim())\n return val === undefined || val === null ? '' : String(val)\n })\n}\n\ntype Operation =\n | { op: 'filter'; key: string; operator: FilterOperator; value?: unknown }\n | { op: 'sort'; key: string; direction?: 'asc' | 'desc' }\n | { op: 'select_keys'; keys: string[] }\n | { op: 'pluck'; key: string }\n | { op: 'slice'; start: number; end?: number }\n | { op: 'unique' }\n | { op: 'unique_by'; key: string }\n | { op: 'group_by'; key: string }\n | { op: 'flatten'; depth?: number }\n | { op: 'reverse' }\n | { op: 'count' }\n | { op: 'sum'; key?: string }\n | { op: 'avg'; key?: string }\n | { op: 'median'; key?: string }\n | { op: 'min'; key?: string }\n | { op: 'max'; key?: string }\n | { op: 'first'; n?: number }\n | { op: 'last'; n?: number }\n | { op: 'chunk'; size: number }\n | { op: 'frequency_count'; key?: string }\n | { op: 'top_n'; n: number; key: string; direction?: 'asc' | 'desc' }\n | { op: 'map_template'; template: string }\n\nfunction applyOperation(data: unknown, op: Operation): unknown {\n if (op.op === 'count') {\n if (Array.isArray(data)) return data.length\n if (isObject(data)) return Object.keys(data).length\n return 0\n }\n\n if (!Array.isArray(data)) {\n throw new Error(`Operation \"${op.op}\" requires an array input.`)\n }\n\n const arr = data as unknown[]\n\n switch (op.op) {\n case 'filter':\n return arr.filter((item) => matchesFilter(item, op.key, op.operator, op.value))\n\n case 'sort': {\n const dir = op.direction === 'desc' ? -1 : 1\n return [...arr].sort((a, b) => {\n const av = getPath(a, op.key)\n const bv = getPath(b, op.key)\n if (av === bv) return 0\n if (av === undefined || av === null) return 1\n if (bv === undefined || bv === null) return -1\n if (typeof av === 'number' && typeof bv === 'number') return (av - bv) * dir\n return String(av).localeCompare(String(bv)) * dir\n })\n }\n\n case 'select_keys':\n return arr.map((item) => {\n if (typeof item !== 'object' || item === null) return item\n const result: Record<string, unknown> = {}\n for (const key of op.keys) result[key] = (item as Record<string, unknown>)[key]\n return result\n })\n\n case 'pluck':\n return arr.map((item) => getPath(item, op.key))\n\n case 'slice':\n return arr.slice(op.start, op.end)\n\n case 'unique': {\n const seen = new Set<string>()\n return arr.filter((item) => {\n const key = typeof item === 'object' ? JSON.stringify(item) : String(item)\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n }\n\n case 'unique_by': {\n const seen = new Set<unknown>()\n return arr.filter((item) => {\n const key = getPath(item, op.key)\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n }\n\n case 'group_by': {\n const groups: Record<string, unknown[]> = {}\n for (const item of arr) {\n const key = String(getPath(item, op.key) ?? '__undefined__')\n if (!groups[key]) groups[key] = []\n groups[key].push(item)\n }\n return groups\n }\n\n case 'flatten':\n return arr.flat(op.depth ?? 1)\n\n case 'reverse':\n return [...arr].reverse()\n\n case 'sum': {\n const values = op.key ? arr.map((i) => getPath(i, op.key!)) : arr\n return values.reduce<number>((acc, v) => acc + (typeof v === 'number' ? v : 0), 0)\n }\n\n case 'avg': {\n const values = op.key ? arr.map((i) => getPath(i, op.key!)) : arr\n const nums = values.filter((v): v is number => typeof v === 'number')\n if (nums.length === 0) return null\n return nums.reduce((a, b) => a + b, 0) / nums.length\n }\n\n case 'median': {\n const values = op.key ? arr.map((i) => getPath(i, op.key!)) : arr\n const nums = values.filter((v): v is number => typeof v === 'number')\n if (nums.length === 0) return null\n return medianOf(nums)\n }\n\n case 'min': {\n const values = op.key ? arr.map((i) => getPath(i, op.key!)) : arr\n const nums = values.filter((v): v is number => typeof v === 'number')\n if (nums.length === 0) return null\n return Math.min(...nums)\n }\n\n case 'max': {\n const values = op.key ? arr.map((i) => getPath(i, op.key!)) : arr\n const nums = values.filter((v): v is number => typeof v === 'number')\n if (nums.length === 0) return null\n return Math.max(...nums)\n }\n\n case 'first':\n return op.n !== undefined ? arr.slice(0, op.n) : arr[0]\n\n case 'last':\n return op.n !== undefined ? arr.slice(-op.n) : arr[arr.length - 1]\n\n case 'chunk': {\n const size = Math.max(1, Math.floor(op.size))\n const chunks: unknown[][] = []\n for (let i = 0; i < arr.length; i += size) chunks.push(arr.slice(i, i + size))\n return chunks\n }\n\n case 'frequency_count': {\n const freq: Record<string, number> = {}\n for (const item of arr) {\n const key = op.key ? String(getPath(item, op.key) ?? '__undefined__') : String(item)\n freq[key] = (freq[key] ?? 0) + 1\n }\n return freq\n }\n\n case 'top_n': {\n const dir = op.direction === 'asc' ? 1 : -1\n return [...arr]\n .sort((a, b) => {\n const av = getPath(a, op.key)\n const bv = getPath(b, op.key)\n if (typeof av === 'number' && typeof bv === 'number') return (bv - av) * dir\n return String(bv).localeCompare(String(av)) * dir\n })\n .slice(0, op.n)\n }\n\n case 'map_template':\n return arr.map((item) => applyTemplate(op.template, item))\n\n default:\n throw new Error(`Unknown operation: ${(op as { op: string }).op}`)\n }\n}\n\n/**\n * Apply a pipeline of operations to a JSON array or object.\n *\n * @remarks\n * Operations are applied in order; each step transforms the output of the previous. Supported\n * operations: `filter`, `sort`, `select_keys`, `pluck`, `slice`, `unique`, `unique_by`,\n * `group_by`, `flatten`, `reverse`, `count`, `sum`, `avg`, `median`, `min`, `max`, `first`,\n * `last`, `chunk`, `frequency_count`, `top_n`, `map_template`. Dot-notation paths are supported\n * for nested key access in every operation that takes a `key` field.\n */\nexport const jsonTransformTool = new Tool({\n name: 'json_transform',\n description:\n 'Apply a pipeline of operations to a JSON array or object: filter, sort, group, aggregate (sum/avg/median/min/max), pluck fields, deduplicate, flatten, chunk, frequency count, top-N, and more.',\n inputSchema: validator.object({\n data: validator.string().required().description('JSON data as a string (array or object)'),\n operations: validator\n .array()\n .items(validator.object().unknown(true))\n .required()\n .description(\n 'Pipeline of operations to apply in order. Each step transforms the output of the previous.'\n ),\n }),\n handler: async (args) => {\n const { data: dataStr, operations } = args as {\n data: string\n operations: Operation[]\n }\n\n let data: unknown\n try {\n data = JSON.parse(dataStr)\n } catch {\n return 'Error: Invalid JSON input.'\n }\n\n let current: unknown = data\n\n for (const [i, operation] of operations.entries()) {\n try {\n current = applyOperation(current, operation)\n } catch (err) {\n return `Error in operation ${i + 1} (\"${operation.op}\"): ${isError(err) ? err.message : String(err)}`\n }\n }\n\n if (typeof current === 'string') return current\n return JSON.stringify(current, null, 2)\n },\n})\n\n/**\n * Perform set operations on two JSON arrays.\n *\n * @remarks\n * Supported operations: `intersection`, `union`, `difference`, `symmetric_difference`,\n * `is_member`, `is_subset`, `is_superset`. For arrays of objects, an optional `compare_key`\n * narrows equality to a single property rather than deep structural comparison.\n */\nexport const setOperationsTool = new Tool({\n name: 'set_operations',\n description:\n 'Perform set operations on two JSON arrays: intersection (common elements), union (all elements), difference (in A but not B), symmetric difference, or membership check.',\n inputSchema: validator.object({\n data_a: validator.string().required().description('First JSON array'),\n data_b: validator.string().optional().description('Second JSON array'),\n operation: validator\n .string()\n .valid(\n 'intersection',\n 'union',\n 'difference',\n 'symmetric_difference',\n 'is_member',\n 'is_subset',\n 'is_superset'\n )\n .required()\n .description('Set operation to perform'),\n item: validator.any().optional().description('For is_member: the value to look up in data_a.'),\n compare_key: validator\n .string()\n .optional()\n .description(\n 'For arrays of objects: use this key for equality comparison instead of deep equality.'\n ),\n }),\n handler: async (args) => {\n const {\n data_a: dataA,\n data_b: dataB,\n operation,\n item,\n compare_key: compareKey,\n } = args as {\n data_a: string\n data_b?: string\n operation: string\n item?: unknown\n compare_key?: string\n }\n\n let a: unknown[]\n let b: unknown[] = []\n\n try {\n a = JSON.parse(dataA)\n } catch {\n return 'Error: data_a is not valid JSON.'\n }\n if (!Array.isArray(a)) return 'Error: data_a must be a JSON array.'\n\n if (dataB !== undefined) {\n try {\n b = JSON.parse(dataB)\n } catch {\n return 'Error: data_b is not valid JSON.'\n }\n if (!Array.isArray(b)) return 'Error: data_b must be a JSON array.'\n }\n\n const toKey = (val: unknown): string =>\n compareKey && isObject(val)\n ? String((val as Record<string, unknown>)[compareKey])\n : JSON.stringify(val)\n\n if (operation === 'is_member') {\n const needle = JSON.stringify(item)\n const found = a.some((entry) => JSON.stringify(entry) === needle)\n return found ? `Found: item is in the array.` : `Not found: item is not in the array.`\n }\n\n const setA = new Set(a.map(toKey))\n const setB = new Set(b.map(toKey))\n const indexA = new Map(a.map((entry) => [toKey(entry), entry]))\n\n switch (operation) {\n case 'intersection': {\n const result = [...setA].filter((k) => setB.has(k)).map((k) => indexA.get(k))\n return JSON.stringify(result, null, 2)\n }\n case 'union': {\n const result = [...a, ...b.filter((entry) => !setA.has(toKey(entry)))]\n return JSON.stringify(result, null, 2)\n }\n case 'difference': {\n const result = a.filter((entry) => !setB.has(toKey(entry)))\n return JSON.stringify(result, null, 2)\n }\n case 'symmetric_difference': {\n const result = [\n ...a.filter((entry) => !setB.has(toKey(entry))),\n ...b.filter((entry) => !setA.has(toKey(entry))),\n ]\n return JSON.stringify(result, null, 2)\n }\n case 'is_subset':\n return [...setA].every((k) => setB.has(k))\n ? `Yes: A is a subset of B (all ${a.length} elements of A are in B).`\n : `No: A is not a subset of B.`\n case 'is_superset':\n return [...setB].every((k) => setA.has(k))\n ? `Yes: A is a superset of B (A contains all ${b.length} elements of B).`\n : `No: A is not a superset of B.`\n default:\n return `Error: Unknown operation \"${operation}\".`\n }\n },\n})\n"],"mappings":"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"}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { c as isObject, o as isError } from "../../tool_registry-DqLOyGyG.mjs";
|
|
2
|
+
import "../../common-DeZaonK1.mjs";
|
|
3
|
+
import { t as Tool } from "../../tool-D2WB1EA1.mjs";
|
|
4
|
+
import "../../guards.mjs";
|
|
5
|
+
import { validator } from "@nhtio/validation";
|
|
6
|
+
//#region src/batteries/tools/data_structure/index.ts
|
|
7
|
+
/**
|
|
8
|
+
* Pre-constructed tools for querying, filtering, grouping, and reshaping structured values.
|
|
9
|
+
*
|
|
10
|
+
* @module @nhtio/adk/batteries/tools/data_structure
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* Pre-constructed bundled tools for the `data_structure` category. Import individually, the whole
|
|
14
|
+
* category, or import every tool via `@nhtio/adk/batteries`.
|
|
15
|
+
*/
|
|
16
|
+
function getPath(obj, path) {
|
|
17
|
+
const parts = path.split(".");
|
|
18
|
+
let current = obj;
|
|
19
|
+
for (const part of parts) {
|
|
20
|
+
if (current === null || current === void 0 || typeof current !== "object") return void 0;
|
|
21
|
+
current = current[part];
|
|
22
|
+
}
|
|
23
|
+
return current;
|
|
24
|
+
}
|
|
25
|
+
function matchesFilter(item, key, operator, value) {
|
|
26
|
+
const actual = getPath(item, key);
|
|
27
|
+
switch (operator) {
|
|
28
|
+
case "eq": return actual === value;
|
|
29
|
+
case "ne": return actual !== value;
|
|
30
|
+
case "gt": return typeof actual === "number" && actual > value;
|
|
31
|
+
case "gte": return typeof actual === "number" && actual >= value;
|
|
32
|
+
case "lt": return typeof actual === "number" && actual < value;
|
|
33
|
+
case "lte": return typeof actual === "number" && actual <= value;
|
|
34
|
+
case "contains": return typeof actual === "string" && actual.includes(String(value));
|
|
35
|
+
case "starts_with": return typeof actual === "string" && actual.startsWith(String(value));
|
|
36
|
+
case "ends_with": return typeof actual === "string" && actual.endsWith(String(value));
|
|
37
|
+
case "exists": return actual !== void 0 && actual !== null;
|
|
38
|
+
default: return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function medianOf(nums) {
|
|
42
|
+
const sorted = [...nums].sort((a, b) => a - b);
|
|
43
|
+
const mid = Math.floor(sorted.length / 2);
|
|
44
|
+
return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
45
|
+
}
|
|
46
|
+
function applyTemplate(template, item) {
|
|
47
|
+
if (typeof item !== "object" || item === null) return String(item);
|
|
48
|
+
return template.replace(/\{\{([^}]+)\}\}/g, (_, key) => {
|
|
49
|
+
const val = getPath(item, key.trim());
|
|
50
|
+
return val === void 0 || val === null ? "" : String(val);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function applyOperation(data, op) {
|
|
54
|
+
if (op.op === "count") {
|
|
55
|
+
if (Array.isArray(data)) return data.length;
|
|
56
|
+
if (isObject(data)) return Object.keys(data).length;
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
if (!Array.isArray(data)) throw new Error(`Operation "${op.op}" requires an array input.`);
|
|
60
|
+
const arr = data;
|
|
61
|
+
switch (op.op) {
|
|
62
|
+
case "filter": return arr.filter((item) => matchesFilter(item, op.key, op.operator, op.value));
|
|
63
|
+
case "sort": {
|
|
64
|
+
const dir = op.direction === "desc" ? -1 : 1;
|
|
65
|
+
return [...arr].sort((a, b) => {
|
|
66
|
+
const av = getPath(a, op.key);
|
|
67
|
+
const bv = getPath(b, op.key);
|
|
68
|
+
if (av === bv) return 0;
|
|
69
|
+
if (av === void 0 || av === null) return 1;
|
|
70
|
+
if (bv === void 0 || bv === null) return -1;
|
|
71
|
+
if (typeof av === "number" && typeof bv === "number") return (av - bv) * dir;
|
|
72
|
+
return String(av).localeCompare(String(bv)) * dir;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
case "select_keys": return arr.map((item) => {
|
|
76
|
+
if (typeof item !== "object" || item === null) return item;
|
|
77
|
+
const result = {};
|
|
78
|
+
for (const key of op.keys) result[key] = item[key];
|
|
79
|
+
return result;
|
|
80
|
+
});
|
|
81
|
+
case "pluck": return arr.map((item) => getPath(item, op.key));
|
|
82
|
+
case "slice": return arr.slice(op.start, op.end);
|
|
83
|
+
case "unique": {
|
|
84
|
+
const seen = /* @__PURE__ */ new Set();
|
|
85
|
+
return arr.filter((item) => {
|
|
86
|
+
const key = typeof item === "object" ? JSON.stringify(item) : String(item);
|
|
87
|
+
if (seen.has(key)) return false;
|
|
88
|
+
seen.add(key);
|
|
89
|
+
return true;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
case "unique_by": {
|
|
93
|
+
const seen = /* @__PURE__ */ new Set();
|
|
94
|
+
return arr.filter((item) => {
|
|
95
|
+
const key = getPath(item, op.key);
|
|
96
|
+
if (seen.has(key)) return false;
|
|
97
|
+
seen.add(key);
|
|
98
|
+
return true;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
case "group_by": {
|
|
102
|
+
const groups = {};
|
|
103
|
+
for (const item of arr) {
|
|
104
|
+
const key = String(getPath(item, op.key) ?? "__undefined__");
|
|
105
|
+
if (!groups[key]) groups[key] = [];
|
|
106
|
+
groups[key].push(item);
|
|
107
|
+
}
|
|
108
|
+
return groups;
|
|
109
|
+
}
|
|
110
|
+
case "flatten": return arr.flat(op.depth ?? 1);
|
|
111
|
+
case "reverse": return [...arr].reverse();
|
|
112
|
+
case "sum": return (op.key ? arr.map((i) => getPath(i, op.key)) : arr).reduce((acc, v) => acc + (typeof v === "number" ? v : 0), 0);
|
|
113
|
+
case "avg": {
|
|
114
|
+
const nums = (op.key ? arr.map((i) => getPath(i, op.key)) : arr).filter((v) => typeof v === "number");
|
|
115
|
+
if (nums.length === 0) return null;
|
|
116
|
+
return nums.reduce((a, b) => a + b, 0) / nums.length;
|
|
117
|
+
}
|
|
118
|
+
case "median": {
|
|
119
|
+
const nums = (op.key ? arr.map((i) => getPath(i, op.key)) : arr).filter((v) => typeof v === "number");
|
|
120
|
+
if (nums.length === 0) return null;
|
|
121
|
+
return medianOf(nums);
|
|
122
|
+
}
|
|
123
|
+
case "min": {
|
|
124
|
+
const nums = (op.key ? arr.map((i) => getPath(i, op.key)) : arr).filter((v) => typeof v === "number");
|
|
125
|
+
if (nums.length === 0) return null;
|
|
126
|
+
return Math.min(...nums);
|
|
127
|
+
}
|
|
128
|
+
case "max": {
|
|
129
|
+
const nums = (op.key ? arr.map((i) => getPath(i, op.key)) : arr).filter((v) => typeof v === "number");
|
|
130
|
+
if (nums.length === 0) return null;
|
|
131
|
+
return Math.max(...nums);
|
|
132
|
+
}
|
|
133
|
+
case "first": return op.n !== void 0 ? arr.slice(0, op.n) : arr[0];
|
|
134
|
+
case "last": return op.n !== void 0 ? arr.slice(-op.n) : arr[arr.length - 1];
|
|
135
|
+
case "chunk": {
|
|
136
|
+
const size = Math.max(1, Math.floor(op.size));
|
|
137
|
+
const chunks = [];
|
|
138
|
+
for (let i = 0; i < arr.length; i += size) chunks.push(arr.slice(i, i + size));
|
|
139
|
+
return chunks;
|
|
140
|
+
}
|
|
141
|
+
case "frequency_count": {
|
|
142
|
+
const freq = {};
|
|
143
|
+
for (const item of arr) {
|
|
144
|
+
const key = op.key ? String(getPath(item, op.key) ?? "__undefined__") : String(item);
|
|
145
|
+
freq[key] = (freq[key] ?? 0) + 1;
|
|
146
|
+
}
|
|
147
|
+
return freq;
|
|
148
|
+
}
|
|
149
|
+
case "top_n": {
|
|
150
|
+
const dir = op.direction === "asc" ? 1 : -1;
|
|
151
|
+
return [...arr].sort((a, b) => {
|
|
152
|
+
const av = getPath(a, op.key);
|
|
153
|
+
const bv = getPath(b, op.key);
|
|
154
|
+
if (typeof av === "number" && typeof bv === "number") return (bv - av) * dir;
|
|
155
|
+
return String(bv).localeCompare(String(av)) * dir;
|
|
156
|
+
}).slice(0, op.n);
|
|
157
|
+
}
|
|
158
|
+
case "map_template": return arr.map((item) => applyTemplate(op.template, item));
|
|
159
|
+
default: throw new Error(`Unknown operation: ${op.op}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Apply a pipeline of operations to a JSON array or object.
|
|
164
|
+
*
|
|
165
|
+
* @remarks
|
|
166
|
+
* Operations are applied in order; each step transforms the output of the previous. Supported
|
|
167
|
+
* operations: `filter`, `sort`, `select_keys`, `pluck`, `slice`, `unique`, `unique_by`,
|
|
168
|
+
* `group_by`, `flatten`, `reverse`, `count`, `sum`, `avg`, `median`, `min`, `max`, `first`,
|
|
169
|
+
* `last`, `chunk`, `frequency_count`, `top_n`, `map_template`. Dot-notation paths are supported
|
|
170
|
+
* for nested key access in every operation that takes a `key` field.
|
|
171
|
+
*/
|
|
172
|
+
var jsonTransformTool = new Tool({
|
|
173
|
+
name: "json_transform",
|
|
174
|
+
description: "Apply a pipeline of operations to a JSON array or object: filter, sort, group, aggregate (sum/avg/median/min/max), pluck fields, deduplicate, flatten, chunk, frequency count, top-N, and more.",
|
|
175
|
+
inputSchema: validator.object({
|
|
176
|
+
data: validator.string().required().description("JSON data as a string (array or object)"),
|
|
177
|
+
operations: validator.array().items(validator.object().unknown(true)).required().description("Pipeline of operations to apply in order. Each step transforms the output of the previous.")
|
|
178
|
+
}),
|
|
179
|
+
handler: async (args) => {
|
|
180
|
+
const { data: dataStr, operations } = args;
|
|
181
|
+
let data;
|
|
182
|
+
try {
|
|
183
|
+
data = JSON.parse(dataStr);
|
|
184
|
+
} catch {
|
|
185
|
+
return "Error: Invalid JSON input.";
|
|
186
|
+
}
|
|
187
|
+
let current = data;
|
|
188
|
+
for (const [i, operation] of operations.entries()) try {
|
|
189
|
+
current = applyOperation(current, operation);
|
|
190
|
+
} catch (err) {
|
|
191
|
+
return `Error in operation ${i + 1} ("${operation.op}"): ${isError(err) ? err.message : String(err)}`;
|
|
192
|
+
}
|
|
193
|
+
if (typeof current === "string") return current;
|
|
194
|
+
return JSON.stringify(current, null, 2);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
/**
|
|
198
|
+
* Perform set operations on two JSON arrays.
|
|
199
|
+
*
|
|
200
|
+
* @remarks
|
|
201
|
+
* Supported operations: `intersection`, `union`, `difference`, `symmetric_difference`,
|
|
202
|
+
* `is_member`, `is_subset`, `is_superset`. For arrays of objects, an optional `compare_key`
|
|
203
|
+
* narrows equality to a single property rather than deep structural comparison.
|
|
204
|
+
*/
|
|
205
|
+
var setOperationsTool = new Tool({
|
|
206
|
+
name: "set_operations",
|
|
207
|
+
description: "Perform set operations on two JSON arrays: intersection (common elements), union (all elements), difference (in A but not B), symmetric difference, or membership check.",
|
|
208
|
+
inputSchema: validator.object({
|
|
209
|
+
data_a: validator.string().required().description("First JSON array"),
|
|
210
|
+
data_b: validator.string().optional().description("Second JSON array"),
|
|
211
|
+
operation: validator.string().valid("intersection", "union", "difference", "symmetric_difference", "is_member", "is_subset", "is_superset").required().description("Set operation to perform"),
|
|
212
|
+
item: validator.any().optional().description("For is_member: the value to look up in data_a."),
|
|
213
|
+
compare_key: validator.string().optional().description("For arrays of objects: use this key for equality comparison instead of deep equality.")
|
|
214
|
+
}),
|
|
215
|
+
handler: async (args) => {
|
|
216
|
+
const { data_a: dataA, data_b: dataB, operation, item, compare_key: compareKey } = args;
|
|
217
|
+
let a;
|
|
218
|
+
let b = [];
|
|
219
|
+
try {
|
|
220
|
+
a = JSON.parse(dataA);
|
|
221
|
+
} catch {
|
|
222
|
+
return "Error: data_a is not valid JSON.";
|
|
223
|
+
}
|
|
224
|
+
if (!Array.isArray(a)) return "Error: data_a must be a JSON array.";
|
|
225
|
+
if (dataB !== void 0) {
|
|
226
|
+
try {
|
|
227
|
+
b = JSON.parse(dataB);
|
|
228
|
+
} catch {
|
|
229
|
+
return "Error: data_b is not valid JSON.";
|
|
230
|
+
}
|
|
231
|
+
if (!Array.isArray(b)) return "Error: data_b must be a JSON array.";
|
|
232
|
+
}
|
|
233
|
+
const toKey = (val) => compareKey && isObject(val) ? String(val[compareKey]) : JSON.stringify(val);
|
|
234
|
+
if (operation === "is_member") {
|
|
235
|
+
const needle = JSON.stringify(item);
|
|
236
|
+
return a.some((entry) => JSON.stringify(entry) === needle) ? `Found: item is in the array.` : `Not found: item is not in the array.`;
|
|
237
|
+
}
|
|
238
|
+
const setA = new Set(a.map(toKey));
|
|
239
|
+
const setB = new Set(b.map(toKey));
|
|
240
|
+
const indexA = new Map(a.map((entry) => [toKey(entry), entry]));
|
|
241
|
+
switch (operation) {
|
|
242
|
+
case "intersection": {
|
|
243
|
+
const result = [...setA].filter((k) => setB.has(k)).map((k) => indexA.get(k));
|
|
244
|
+
return JSON.stringify(result, null, 2);
|
|
245
|
+
}
|
|
246
|
+
case "union": {
|
|
247
|
+
const result = [...a, ...b.filter((entry) => !setA.has(toKey(entry)))];
|
|
248
|
+
return JSON.stringify(result, null, 2);
|
|
249
|
+
}
|
|
250
|
+
case "difference": {
|
|
251
|
+
const result = a.filter((entry) => !setB.has(toKey(entry)));
|
|
252
|
+
return JSON.stringify(result, null, 2);
|
|
253
|
+
}
|
|
254
|
+
case "symmetric_difference": {
|
|
255
|
+
const result = [...a.filter((entry) => !setB.has(toKey(entry))), ...b.filter((entry) => !setA.has(toKey(entry)))];
|
|
256
|
+
return JSON.stringify(result, null, 2);
|
|
257
|
+
}
|
|
258
|
+
case "is_subset": return [...setA].every((k) => setB.has(k)) ? `Yes: A is a subset of B (all ${a.length} elements of A are in B).` : `No: A is not a subset of B.`;
|
|
259
|
+
case "is_superset": return [...setB].every((k) => setA.has(k)) ? `Yes: A is a superset of B (A contains all ${b.length} elements of B).` : `No: A is not a superset of B.`;
|
|
260
|
+
default: return `Error: Unknown operation "${operation}".`;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
//#endregion
|
|
265
|
+
export { jsonTransformTool, setOperationsTool };
|
|
266
|
+
|
|
267
|
+
//# sourceMappingURL=data_structure.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data_structure.mjs","names":[],"sources":["../../../src/batteries/tools/data_structure/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for querying, filtering, grouping, and reshaping structured values.\n *\n * @module @nhtio/adk/batteries/tools/data_structure\n *\n * @remarks\n * Pre-constructed bundled tools for the `data_structure` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport { Tool } from '@nhtio/adk/common'\nimport { validator } from '@nhtio/validation'\nimport { isError, isObject } from '@nhtio/adk/guards'\n\nfunction getPath(obj: unknown, path: string): unknown {\n const parts = path.split('.')\n let current = obj\n for (const part of parts) {\n if (current === null || current === undefined || typeof current !== 'object') return undefined\n current = (current as Record<string, unknown>)[part]\n }\n return current\n}\n\ntype FilterOperator =\n | 'eq'\n | 'ne'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | 'contains'\n | 'starts_with'\n | 'ends_with'\n | 'exists'\n\nfunction matchesFilter(\n item: unknown,\n key: string,\n operator: FilterOperator,\n value: unknown\n): boolean {\n const actual = getPath(item, key)\n switch (operator) {\n case 'eq':\n return actual === value\n case 'ne':\n return actual !== value\n case 'gt':\n return typeof actual === 'number' && actual > (value as number)\n case 'gte':\n return typeof actual === 'number' && actual >= (value as number)\n case 'lt':\n return typeof actual === 'number' && actual < (value as number)\n case 'lte':\n return typeof actual === 'number' && actual <= (value as number)\n case 'contains':\n return typeof actual === 'string' && actual.includes(String(value))\n case 'starts_with':\n return typeof actual === 'string' && actual.startsWith(String(value))\n case 'ends_with':\n return typeof actual === 'string' && actual.endsWith(String(value))\n case 'exists':\n return actual !== undefined && actual !== null\n default:\n return false\n }\n}\n\nfunction medianOf(nums: number[]): number {\n const sorted = [...nums].sort((a, b) => a - b)\n const mid = Math.floor(sorted.length / 2)\n return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid]\n}\n\nfunction applyTemplate(template: string, item: unknown): string {\n if (typeof item !== 'object' || item === null) return String(item)\n return template.replace(/\\{\\{([^}]+)\\}\\}/g, (_, key) => {\n const val = getPath(item, key.trim())\n return val === undefined || val === null ? '' : String(val)\n })\n}\n\ntype Operation =\n | { op: 'filter'; key: string; operator: FilterOperator; value?: unknown }\n | { op: 'sort'; key: string; direction?: 'asc' | 'desc' }\n | { op: 'select_keys'; keys: string[] }\n | { op: 'pluck'; key: string }\n | { op: 'slice'; start: number; end?: number }\n | { op: 'unique' }\n | { op: 'unique_by'; key: string }\n | { op: 'group_by'; key: string }\n | { op: 'flatten'; depth?: number }\n | { op: 'reverse' }\n | { op: 'count' }\n | { op: 'sum'; key?: string }\n | { op: 'avg'; key?: string }\n | { op: 'median'; key?: string }\n | { op: 'min'; key?: string }\n | { op: 'max'; key?: string }\n | { op: 'first'; n?: number }\n | { op: 'last'; n?: number }\n | { op: 'chunk'; size: number }\n | { op: 'frequency_count'; key?: string }\n | { op: 'top_n'; n: number; key: string; direction?: 'asc' | 'desc' }\n | { op: 'map_template'; template: string }\n\nfunction applyOperation(data: unknown, op: Operation): unknown {\n if (op.op === 'count') {\n if (Array.isArray(data)) return data.length\n if (isObject(data)) return Object.keys(data).length\n return 0\n }\n\n if (!Array.isArray(data)) {\n throw new Error(`Operation \"${op.op}\" requires an array input.`)\n }\n\n const arr = data as unknown[]\n\n switch (op.op) {\n case 'filter':\n return arr.filter((item) => matchesFilter(item, op.key, op.operator, op.value))\n\n case 'sort': {\n const dir = op.direction === 'desc' ? -1 : 1\n return [...arr].sort((a, b) => {\n const av = getPath(a, op.key)\n const bv = getPath(b, op.key)\n if (av === bv) return 0\n if (av === undefined || av === null) return 1\n if (bv === undefined || bv === null) return -1\n if (typeof av === 'number' && typeof bv === 'number') return (av - bv) * dir\n return String(av).localeCompare(String(bv)) * dir\n })\n }\n\n case 'select_keys':\n return arr.map((item) => {\n if (typeof item !== 'object' || item === null) return item\n const result: Record<string, unknown> = {}\n for (const key of op.keys) result[key] = (item as Record<string, unknown>)[key]\n return result\n })\n\n case 'pluck':\n return arr.map((item) => getPath(item, op.key))\n\n case 'slice':\n return arr.slice(op.start, op.end)\n\n case 'unique': {\n const seen = new Set<string>()\n return arr.filter((item) => {\n const key = typeof item === 'object' ? JSON.stringify(item) : String(item)\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n }\n\n case 'unique_by': {\n const seen = new Set<unknown>()\n return arr.filter((item) => {\n const key = getPath(item, op.key)\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n }\n\n case 'group_by': {\n const groups: Record<string, unknown[]> = {}\n for (const item of arr) {\n const key = String(getPath(item, op.key) ?? '__undefined__')\n if (!groups[key]) groups[key] = []\n groups[key].push(item)\n }\n return groups\n }\n\n case 'flatten':\n return arr.flat(op.depth ?? 1)\n\n case 'reverse':\n return [...arr].reverse()\n\n case 'sum': {\n const values = op.key ? arr.map((i) => getPath(i, op.key!)) : arr\n return values.reduce<number>((acc, v) => acc + (typeof v === 'number' ? v : 0), 0)\n }\n\n case 'avg': {\n const values = op.key ? arr.map((i) => getPath(i, op.key!)) : arr\n const nums = values.filter((v): v is number => typeof v === 'number')\n if (nums.length === 0) return null\n return nums.reduce((a, b) => a + b, 0) / nums.length\n }\n\n case 'median': {\n const values = op.key ? arr.map((i) => getPath(i, op.key!)) : arr\n const nums = values.filter((v): v is number => typeof v === 'number')\n if (nums.length === 0) return null\n return medianOf(nums)\n }\n\n case 'min': {\n const values = op.key ? arr.map((i) => getPath(i, op.key!)) : arr\n const nums = values.filter((v): v is number => typeof v === 'number')\n if (nums.length === 0) return null\n return Math.min(...nums)\n }\n\n case 'max': {\n const values = op.key ? arr.map((i) => getPath(i, op.key!)) : arr\n const nums = values.filter((v): v is number => typeof v === 'number')\n if (nums.length === 0) return null\n return Math.max(...nums)\n }\n\n case 'first':\n return op.n !== undefined ? arr.slice(0, op.n) : arr[0]\n\n case 'last':\n return op.n !== undefined ? arr.slice(-op.n) : arr[arr.length - 1]\n\n case 'chunk': {\n const size = Math.max(1, Math.floor(op.size))\n const chunks: unknown[][] = []\n for (let i = 0; i < arr.length; i += size) chunks.push(arr.slice(i, i + size))\n return chunks\n }\n\n case 'frequency_count': {\n const freq: Record<string, number> = {}\n for (const item of arr) {\n const key = op.key ? String(getPath(item, op.key) ?? '__undefined__') : String(item)\n freq[key] = (freq[key] ?? 0) + 1\n }\n return freq\n }\n\n case 'top_n': {\n const dir = op.direction === 'asc' ? 1 : -1\n return [...arr]\n .sort((a, b) => {\n const av = getPath(a, op.key)\n const bv = getPath(b, op.key)\n if (typeof av === 'number' && typeof bv === 'number') return (bv - av) * dir\n return String(bv).localeCompare(String(av)) * dir\n })\n .slice(0, op.n)\n }\n\n case 'map_template':\n return arr.map((item) => applyTemplate(op.template, item))\n\n default:\n throw new Error(`Unknown operation: ${(op as { op: string }).op}`)\n }\n}\n\n/**\n * Apply a pipeline of operations to a JSON array or object.\n *\n * @remarks\n * Operations are applied in order; each step transforms the output of the previous. Supported\n * operations: `filter`, `sort`, `select_keys`, `pluck`, `slice`, `unique`, `unique_by`,\n * `group_by`, `flatten`, `reverse`, `count`, `sum`, `avg`, `median`, `min`, `max`, `first`,\n * `last`, `chunk`, `frequency_count`, `top_n`, `map_template`. Dot-notation paths are supported\n * for nested key access in every operation that takes a `key` field.\n */\nexport const jsonTransformTool = new Tool({\n name: 'json_transform',\n description:\n 'Apply a pipeline of operations to a JSON array or object: filter, sort, group, aggregate (sum/avg/median/min/max), pluck fields, deduplicate, flatten, chunk, frequency count, top-N, and more.',\n inputSchema: validator.object({\n data: validator.string().required().description('JSON data as a string (array or object)'),\n operations: validator\n .array()\n .items(validator.object().unknown(true))\n .required()\n .description(\n 'Pipeline of operations to apply in order. Each step transforms the output of the previous.'\n ),\n }),\n handler: async (args) => {\n const { data: dataStr, operations } = args as {\n data: string\n operations: Operation[]\n }\n\n let data: unknown\n try {\n data = JSON.parse(dataStr)\n } catch {\n return 'Error: Invalid JSON input.'\n }\n\n let current: unknown = data\n\n for (const [i, operation] of operations.entries()) {\n try {\n current = applyOperation(current, operation)\n } catch (err) {\n return `Error in operation ${i + 1} (\"${operation.op}\"): ${isError(err) ? err.message : String(err)}`\n }\n }\n\n if (typeof current === 'string') return current\n return JSON.stringify(current, null, 2)\n },\n})\n\n/**\n * Perform set operations on two JSON arrays.\n *\n * @remarks\n * Supported operations: `intersection`, `union`, `difference`, `symmetric_difference`,\n * `is_member`, `is_subset`, `is_superset`. For arrays of objects, an optional `compare_key`\n * narrows equality to a single property rather than deep structural comparison.\n */\nexport const setOperationsTool = new Tool({\n name: 'set_operations',\n description:\n 'Perform set operations on two JSON arrays: intersection (common elements), union (all elements), difference (in A but not B), symmetric difference, or membership check.',\n inputSchema: validator.object({\n data_a: validator.string().required().description('First JSON array'),\n data_b: validator.string().optional().description('Second JSON array'),\n operation: validator\n .string()\n .valid(\n 'intersection',\n 'union',\n 'difference',\n 'symmetric_difference',\n 'is_member',\n 'is_subset',\n 'is_superset'\n )\n .required()\n .description('Set operation to perform'),\n item: validator.any().optional().description('For is_member: the value to look up in data_a.'),\n compare_key: validator\n .string()\n .optional()\n .description(\n 'For arrays of objects: use this key for equality comparison instead of deep equality.'\n ),\n }),\n handler: async (args) => {\n const {\n data_a: dataA,\n data_b: dataB,\n operation,\n item,\n compare_key: compareKey,\n } = args as {\n data_a: string\n data_b?: string\n operation: string\n item?: unknown\n compare_key?: string\n }\n\n let a: unknown[]\n let b: unknown[] = []\n\n try {\n a = JSON.parse(dataA)\n } catch {\n return 'Error: data_a is not valid JSON.'\n }\n if (!Array.isArray(a)) return 'Error: data_a must be a JSON array.'\n\n if (dataB !== undefined) {\n try {\n b = JSON.parse(dataB)\n } catch {\n return 'Error: data_b is not valid JSON.'\n }\n if (!Array.isArray(b)) return 'Error: data_b must be a JSON array.'\n }\n\n const toKey = (val: unknown): string =>\n compareKey && isObject(val)\n ? String((val as Record<string, unknown>)[compareKey])\n : JSON.stringify(val)\n\n if (operation === 'is_member') {\n const needle = JSON.stringify(item)\n const found = a.some((entry) => JSON.stringify(entry) === needle)\n return found ? `Found: item is in the array.` : `Not found: item is not in the array.`\n }\n\n const setA = new Set(a.map(toKey))\n const setB = new Set(b.map(toKey))\n const indexA = new Map(a.map((entry) => [toKey(entry), entry]))\n\n switch (operation) {\n case 'intersection': {\n const result = [...setA].filter((k) => setB.has(k)).map((k) => indexA.get(k))\n return JSON.stringify(result, null, 2)\n }\n case 'union': {\n const result = [...a, ...b.filter((entry) => !setA.has(toKey(entry)))]\n return JSON.stringify(result, null, 2)\n }\n case 'difference': {\n const result = a.filter((entry) => !setB.has(toKey(entry)))\n return JSON.stringify(result, null, 2)\n }\n case 'symmetric_difference': {\n const result = [\n ...a.filter((entry) => !setB.has(toKey(entry))),\n ...b.filter((entry) => !setA.has(toKey(entry))),\n ]\n return JSON.stringify(result, null, 2)\n }\n case 'is_subset':\n return [...setA].every((k) => setB.has(k))\n ? `Yes: A is a subset of B (all ${a.length} elements of A are in B).`\n : `No: A is not a subset of B.`\n case 'is_superset':\n return [...setB].every((k) => setA.has(k))\n ? `Yes: A is a superset of B (A contains all ${b.length} elements of B).`\n : `No: A is not a superset of B.`\n default:\n return `Error: Unknown operation \"${operation}\".`\n }\n },\n})\n"],"mappings":"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"}
|