@nhtio/adk 0.1.0-master-f0aa531d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +3 -0
  3. package/batteries/index.d.ts +28 -0
  4. package/batteries/llm/index.d.ts +11 -0
  5. package/batteries/llm/openai_chat_completions/adapter.cjs +916 -0
  6. package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -0
  7. package/batteries/llm/openai_chat_completions/adapter.d.ts +101 -0
  8. package/batteries/llm/openai_chat_completions/adapter.mjs +914 -0
  9. package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -0
  10. package/batteries/llm/openai_chat_completions/exceptions.cjs +89 -0
  11. package/batteries/llm/openai_chat_completions/exceptions.cjs.map +1 -0
  12. package/batteries/llm/openai_chat_completions/exceptions.d.ts +97 -0
  13. package/batteries/llm/openai_chat_completions/exceptions.mjs +81 -0
  14. package/batteries/llm/openai_chat_completions/exceptions.mjs.map +1 -0
  15. package/batteries/llm/openai_chat_completions/helpers.cjs +819 -0
  16. package/batteries/llm/openai_chat_completions/helpers.cjs.map +1 -0
  17. package/batteries/llm/openai_chat_completions/helpers.d.ts +233 -0
  18. package/batteries/llm/openai_chat_completions/helpers.mjs +783 -0
  19. package/batteries/llm/openai_chat_completions/helpers.mjs.map +1 -0
  20. package/batteries/llm/openai_chat_completions/index.d.ts +27 -0
  21. package/batteries/llm/openai_chat_completions/types.cjs +1 -0
  22. package/batteries/llm/openai_chat_completions/types.d.ts +524 -0
  23. package/batteries/llm/openai_chat_completions/types.mjs +0 -0
  24. package/batteries/llm/openai_chat_completions/validation.cjs +190 -0
  25. package/batteries/llm/openai_chat_completions/validation.cjs.map +1 -0
  26. package/batteries/llm/openai_chat_completions/validation.d.ts +31 -0
  27. package/batteries/llm/openai_chat_completions/validation.mjs +187 -0
  28. package/batteries/llm/openai_chat_completions/validation.mjs.map +1 -0
  29. package/batteries/llm/openai_chat_completions.cjs +51 -0
  30. package/batteries/llm/openai_chat_completions.mjs +5 -0
  31. package/batteries/llm/webllm_chat_completions/adapter.cjs +658 -0
  32. package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -0
  33. package/batteries/llm/webllm_chat_completions/adapter.d.ts +103 -0
  34. package/batteries/llm/webllm_chat_completions/adapter.mjs +656 -0
  35. package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -0
  36. package/batteries/llm/webllm_chat_completions/exceptions.cjs +70 -0
  37. package/batteries/llm/webllm_chat_completions/exceptions.cjs.map +1 -0
  38. package/batteries/llm/webllm_chat_completions/exceptions.d.ts +74 -0
  39. package/batteries/llm/webllm_chat_completions/exceptions.mjs +65 -0
  40. package/batteries/llm/webllm_chat_completions/exceptions.mjs.map +1 -0
  41. package/batteries/llm/webllm_chat_completions/helpers.cjs +38 -0
  42. package/batteries/llm/webllm_chat_completions/helpers.d.ts +6 -0
  43. package/batteries/llm/webllm_chat_completions/helpers.mjs +2 -0
  44. package/batteries/llm/webllm_chat_completions/index.d.ts +25 -0
  45. package/batteries/llm/webllm_chat_completions/types.d.ts +31 -0
  46. package/batteries/llm/webllm_chat_completions/validation.cjs +115 -0
  47. package/batteries/llm/webllm_chat_completions/validation.cjs.map +1 -0
  48. package/batteries/llm/webllm_chat_completions/validation.d.ts +8 -0
  49. package/batteries/llm/webllm_chat_completions/validation.mjs +112 -0
  50. package/batteries/llm/webllm_chat_completions/validation.mjs.map +1 -0
  51. package/batteries/llm/webllm_chat_completions.cjs +50 -0
  52. package/batteries/llm/webllm_chat_completions.mjs +6 -0
  53. package/batteries/llm.cjs +63 -0
  54. package/batteries/llm.mjs +10 -0
  55. package/batteries/storage/flydrive/index.d.ts +167 -0
  56. package/batteries/storage/flydrive.cjs +249 -0
  57. package/batteries/storage/flydrive.cjs.map +1 -0
  58. package/batteries/storage/flydrive.mjs +249 -0
  59. package/batteries/storage/flydrive.mjs.map +1 -0
  60. package/batteries/storage/in_memory/index.d.ts +106 -0
  61. package/batteries/storage/in_memory.cjs +121 -0
  62. package/batteries/storage/in_memory.cjs.map +1 -0
  63. package/batteries/storage/in_memory.mjs +119 -0
  64. package/batteries/storage/in_memory.mjs.map +1 -0
  65. package/batteries/storage/index.d.ts +18 -0
  66. package/batteries/storage/opfs/index.d.ts +299 -0
  67. package/batteries/storage/opfs.cjs +368 -0
  68. package/batteries/storage/opfs.cjs.map +1 -0
  69. package/batteries/storage/opfs.mjs +366 -0
  70. package/batteries/storage/opfs.mjs.map +1 -0
  71. package/batteries/storage.cjs +4 -0
  72. package/batteries/storage.mjs +2 -0
  73. package/batteries/tools/color/index.d.ts +37 -0
  74. package/batteries/tools/color.cjs +659 -0
  75. package/batteries/tools/color.cjs.map +1 -0
  76. package/batteries/tools/color.mjs +655 -0
  77. package/batteries/tools/color.mjs.map +1 -0
  78. package/batteries/tools/comparison/index.d.ts +29 -0
  79. package/batteries/tools/comparison.cjs +171 -0
  80. package/batteries/tools/comparison.cjs.map +1 -0
  81. package/batteries/tools/comparison.mjs +168 -0
  82. package/batteries/tools/comparison.mjs.map +1 -0
  83. package/batteries/tools/data_structure/index.d.ts +30 -0
  84. package/batteries/tools/data_structure.cjs +270 -0
  85. package/batteries/tools/data_structure.cjs.map +1 -0
  86. package/batteries/tools/data_structure.mjs +267 -0
  87. package/batteries/tools/data_structure.mjs.map +1 -0
  88. package/batteries/tools/datetime_extended/index.d.ts +51 -0
  89. package/batteries/tools/datetime_extended.cjs +309 -0
  90. package/batteries/tools/datetime_extended.cjs.map +1 -0
  91. package/batteries/tools/datetime_extended.mjs +302 -0
  92. package/batteries/tools/datetime_extended.mjs.map +1 -0
  93. package/batteries/tools/datetime_math/index.d.ts +36 -0
  94. package/batteries/tools/datetime_math.cjs +175 -0
  95. package/batteries/tools/datetime_math.cjs.map +1 -0
  96. package/batteries/tools/datetime_math.mjs +171 -0
  97. package/batteries/tools/datetime_math.mjs.map +1 -0
  98. package/batteries/tools/encoding/index.d.ts +36 -0
  99. package/batteries/tools/encoding.cjs +156 -0
  100. package/batteries/tools/encoding.cjs.map +1 -0
  101. package/batteries/tools/encoding.mjs +152 -0
  102. package/batteries/tools/encoding.mjs.map +1 -0
  103. package/batteries/tools/formatting/index.d.ts +28 -0
  104. package/batteries/tools/formatting.cjs +120 -0
  105. package/batteries/tools/formatting.cjs.map +1 -0
  106. package/batteries/tools/formatting.mjs +117 -0
  107. package/batteries/tools/formatting.mjs.map +1 -0
  108. package/batteries/tools/geo_basics/index.d.ts +33 -0
  109. package/batteries/tools/geo_basics.cjs +136 -0
  110. package/batteries/tools/geo_basics.cjs.map +1 -0
  111. package/batteries/tools/geo_basics.mjs +132 -0
  112. package/batteries/tools/geo_basics.mjs.map +1 -0
  113. package/batteries/tools/index.d.ts +32 -0
  114. package/batteries/tools/math/index.d.ts +37 -0
  115. package/batteries/tools/math.cjs +136 -0
  116. package/batteries/tools/math.cjs.map +1 -0
  117. package/batteries/tools/math.mjs +133 -0
  118. package/batteries/tools/math.mjs.map +1 -0
  119. package/batteries/tools/memory/index.d.ts +73 -0
  120. package/batteries/tools/memory.cjs +193 -0
  121. package/batteries/tools/memory.cjs.map +1 -0
  122. package/batteries/tools/memory.mjs +187 -0
  123. package/batteries/tools/memory.mjs.map +1 -0
  124. package/batteries/tools/parsing/index.d.ts +47 -0
  125. package/batteries/tools/parsing.cjs +191 -0
  126. package/batteries/tools/parsing.cjs.map +1 -0
  127. package/batteries/tools/parsing.mjs +185 -0
  128. package/batteries/tools/parsing.mjs.map +1 -0
  129. package/batteries/tools/retrievables/index.d.ts +81 -0
  130. package/batteries/tools/retrievables.cjs +215 -0
  131. package/batteries/tools/retrievables.cjs.map +1 -0
  132. package/batteries/tools/retrievables.mjs +209 -0
  133. package/batteries/tools/retrievables.mjs.map +1 -0
  134. package/batteries/tools/standing_instructions/index.d.ts +64 -0
  135. package/batteries/tools/standing_instructions.cjs +126 -0
  136. package/batteries/tools/standing_instructions.cjs.map +1 -0
  137. package/batteries/tools/standing_instructions.mjs +121 -0
  138. package/batteries/tools/standing_instructions.mjs.map +1 -0
  139. package/batteries/tools/statistics/index.d.ts +46 -0
  140. package/batteries/tools/statistics.cjs +253 -0
  141. package/batteries/tools/statistics.cjs.map +1 -0
  142. package/batteries/tools/statistics.mjs +248 -0
  143. package/batteries/tools/statistics.mjs.map +1 -0
  144. package/batteries/tools/string_processing/index.d.ts +29 -0
  145. package/batteries/tools/string_processing.cjs +154 -0
  146. package/batteries/tools/string_processing.cjs.map +1 -0
  147. package/batteries/tools/string_processing.mjs +151 -0
  148. package/batteries/tools/string_processing.mjs.map +1 -0
  149. package/batteries/tools/structured_data/index.d.ts +34 -0
  150. package/batteries/tools/structured_data.cjs +189 -0
  151. package/batteries/tools/structured_data.cjs.map +1 -0
  152. package/batteries/tools/structured_data.mjs +185 -0
  153. package/batteries/tools/structured_data.mjs.map +1 -0
  154. package/batteries/tools/text_analysis/index.d.ts +31 -0
  155. package/batteries/tools/text_analysis.cjs +120 -0
  156. package/batteries/tools/text_analysis.cjs.map +1 -0
  157. package/batteries/tools/text_analysis.mjs +117 -0
  158. package/batteries/tools/text_analysis.mjs.map +1 -0
  159. package/batteries/tools/text_comparison/index.d.ts +28 -0
  160. package/batteries/tools/text_comparison.cjs +96 -0
  161. package/batteries/tools/text_comparison.cjs.map +1 -0
  162. package/batteries/tools/text_comparison.mjs +93 -0
  163. package/batteries/tools/text_comparison.mjs.map +1 -0
  164. package/batteries/tools/time/index.d.ts +27 -0
  165. package/batteries/tools/time.cjs +63 -0
  166. package/batteries/tools/time.cjs.map +1 -0
  167. package/batteries/tools/time.mjs +60 -0
  168. package/batteries/tools/time.mjs.map +1 -0
  169. package/batteries/tools/unit_conversion/index.d.ts +19 -0
  170. package/batteries/tools/unit_conversion.cjs +452 -0
  171. package/batteries/tools/unit_conversion.cjs.map +1 -0
  172. package/batteries/tools/unit_conversion.mjs +450 -0
  173. package/batteries/tools/unit_conversion.mjs.map +1 -0
  174. package/batteries/tools.cjs +80 -0
  175. package/batteries/tools.mjs +21 -0
  176. package/batteries.cjs +142 -0
  177. package/batteries.mjs +30 -0
  178. package/chunk-KmRHZBOW.js +35 -0
  179. package/common-DeZaonK1.mjs +208 -0
  180. package/common-DeZaonK1.mjs.map +1 -0
  181. package/common-Od8edUXU.js +232 -0
  182. package/common-Od8edUXU.js.map +1 -0
  183. package/common.cjs +31 -0
  184. package/common.d.ts +108 -0
  185. package/common.mjs +8 -0
  186. package/dispatch_runner-9j6bXHL3.mjs +1609 -0
  187. package/dispatch_runner-9j6bXHL3.mjs.map +1 -0
  188. package/dispatch_runner-CsoH0nld.js +1627 -0
  189. package/dispatch_runner-CsoH0nld.js.map +1 -0
  190. package/dispatch_runner.cjs +3 -0
  191. package/dispatch_runner.d.ts +17 -0
  192. package/dispatch_runner.mjs +2 -0
  193. package/exceptions-D5YrO9Vm.js +280 -0
  194. package/exceptions-D5YrO9Vm.js.map +1 -0
  195. package/exceptions-NrzIHw_R.mjs +244 -0
  196. package/exceptions-NrzIHw_R.mjs.map +1 -0
  197. package/exceptions.cjs +33 -0
  198. package/exceptions.d.ts +52 -0
  199. package/exceptions.mjs +3 -0
  200. package/factories.cjs +4 -0
  201. package/factories.d.ts +39 -0
  202. package/factories.mjs +2 -0
  203. package/forge.cjs +9 -0
  204. package/forge.d.ts +49 -0
  205. package/forge.mjs +5 -0
  206. package/guards.cjs +96 -0
  207. package/guards.cjs.map +1 -0
  208. package/guards.d.ts +83 -0
  209. package/guards.mjs +72 -0
  210. package/guards.mjs.map +1 -0
  211. package/index.cjs +107 -0
  212. package/index.cjs.map +1 -0
  213. package/index.d.ts +18 -0
  214. package/index.mjs +31 -0
  215. package/index.mjs.map +1 -0
  216. package/lib/classes/artifact_tool.d.ts +129 -0
  217. package/lib/classes/base_exception.d.ts +83 -0
  218. package/lib/classes/identity.d.ts +71 -0
  219. package/lib/classes/media.d.ts +326 -0
  220. package/lib/classes/memory.d.ts +72 -0
  221. package/lib/classes/message.d.ts +137 -0
  222. package/lib/classes/registry.d.ts +79 -0
  223. package/lib/classes/retrievable.d.ts +100 -0
  224. package/lib/classes/spooled_artifact.d.ts +296 -0
  225. package/lib/classes/spooled_json_artifact.d.ts +158 -0
  226. package/lib/classes/spooled_markdown_artifact.d.ts +202 -0
  227. package/lib/classes/thought.d.ts +142 -0
  228. package/lib/classes/tokenizable.d.ts +124 -0
  229. package/lib/classes/tool.d.ts +228 -0
  230. package/lib/classes/tool_call.d.ts +190 -0
  231. package/lib/classes/tool_registry.d.ts +159 -0
  232. package/lib/classes/turn_gate.d.ts +109 -0
  233. package/lib/contracts/dispatch_context.d.ts +345 -0
  234. package/lib/contracts/media_reader.d.ts +60 -0
  235. package/lib/contracts/spool_reader.d.ts +80 -0
  236. package/lib/contracts/spooled_artifact_constructor.d.ts +38 -0
  237. package/lib/contracts/turn_runner_config.d.ts +101 -0
  238. package/lib/contracts/turn_runner_context.d.ts +267 -0
  239. package/lib/dispatch_runner.d.ts +98 -0
  240. package/lib/exceptions/runtime.d.ts +370 -0
  241. package/lib/helpers/media_readers.d.ts +39 -0
  242. package/lib/turn_runner.d.ts +144 -0
  243. package/lib/types/dispatch_context.d.ts +233 -0
  244. package/lib/types/dispatch_runner.d.ts +387 -0
  245. package/lib/types/turn_runner.d.ts +322 -0
  246. package/lib/utils/canonical_json.d.ts +18 -0
  247. package/lib/utils/exceptions.d.ts +78 -0
  248. package/lib/utils/guards.d.ts +32 -0
  249. package/lib/utils/validation.d.ts +77 -0
  250. package/package.json +334 -0
  251. package/runtime-BJVkrGQe.js +519 -0
  252. package/runtime-BJVkrGQe.js.map +1 -0
  253. package/runtime-CrEPIFgr.mjs +346 -0
  254. package/runtime-CrEPIFgr.mjs.map +1 -0
  255. package/skills/adk-assembly/SKILL.md +109 -0
  256. package/skills/adk-assembly/references/assembly-contract.md +66 -0
  257. package/skills/adk-assembly/references/executors-tools-pipelines-events.md +113 -0
  258. package/skills/adk-assembly/references/first-integration.md +93 -0
  259. package/skills/adk-assembly/references/storage-and-context.md +102 -0
  260. package/spooled_artifact-C5ZtGxuJ.mjs +544 -0
  261. package/spooled_artifact-C5ZtGxuJ.mjs.map +1 -0
  262. package/spooled_artifact-Cm9Te22K.js +568 -0
  263. package/spooled_artifact-Cm9Te22K.js.map +1 -0
  264. package/spooled_artifact.cjs +7 -0
  265. package/spooled_artifact.d.ts +40 -0
  266. package/spooled_artifact.mjs +3 -0
  267. package/spooled_markdown_artifact-BpUJol0W.mjs +771 -0
  268. package/spooled_markdown_artifact-BpUJol0W.mjs.map +1 -0
  269. package/spooled_markdown_artifact-RRB113sy.js +786 -0
  270. package/spooled_markdown_artifact-RRB113sy.js.map +1 -0
  271. package/thought-CDb457b4.mjs +470 -0
  272. package/thought-CDb457b4.mjs.map +1 -0
  273. package/thought-DuN2PgdO.js +494 -0
  274. package/thought-DuN2PgdO.js.map +1 -0
  275. package/tool-COSeH8I6.js +302 -0
  276. package/tool-COSeH8I6.js.map +1 -0
  277. package/tool-D2WB1EA1.mjs +296 -0
  278. package/tool-D2WB1EA1.mjs.map +1 -0
  279. package/tool_call-BKyyxGaZ.mjs +578 -0
  280. package/tool_call-BKyyxGaZ.mjs.map +1 -0
  281. package/tool_call-DFgzcVcU.js +608 -0
  282. package/tool_call-DFgzcVcU.js.map +1 -0
  283. package/tool_registry-Dkfprsck.js +641 -0
  284. package/tool_registry-Dkfprsck.js.map +1 -0
  285. package/tool_registry-DqLOyGyG.mjs +592 -0
  286. package/tool_registry-DqLOyGyG.mjs.map +1 -0
  287. package/turn_runner-CMm2BHdX.js +615 -0
  288. package/turn_runner-CMm2BHdX.js.map +1 -0
  289. package/turn_runner-y7eyEcJH.mjs +603 -0
  290. package/turn_runner-y7eyEcJH.mjs.map +1 -0
  291. package/turn_runner.cjs +3 -0
  292. package/turn_runner.d.ts +21 -0
  293. package/turn_runner.mjs +2 -0
  294. package/types.cjs +1 -0
  295. package/types.d.ts +56 -0
  296. package/types.mjs +0 -0
  297. package/vite-env.d.ts +23 -0
@@ -0,0 +1,154 @@
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
+ let case_anything = require("case-anything");
9
+ //#region src/batteries/tools/string_processing/index.ts
10
+ /**
11
+ * Pre-constructed tools for casing, trimming, normalizing, and transforming strings.
12
+ *
13
+ * @module @nhtio/adk/batteries/tools/string_processing
14
+ *
15
+ * @remarks
16
+ * Pre-constructed bundled tools for the `string_processing` category. Import individually, the whole
17
+ * category, or import every tool via `@nhtio/adk/batteries`.
18
+ */
19
+ function applyStringOp(text, op) {
20
+ switch (op.op) {
21
+ case "uppercase": return text.toUpperCase();
22
+ case "lowercase": return text.toLowerCase();
23
+ case "capitalize": return text.charAt(0).toUpperCase() + text.slice(1);
24
+ case "titlecase": return (0, case_anything.capitalCase)(text);
25
+ case "sentence_case": return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
26
+ case "camel_case": return (0, case_anything.camelCase)(text);
27
+ case "pascal_case": return (0, case_anything.pascalCase)(text);
28
+ case "snake_case": return (0, case_anything.snakeCase)(text);
29
+ case "kebab_case": return (0, case_anything.kebabCase)(text);
30
+ case "train_case": return (0, case_anything.trainCase)(text);
31
+ case "constant_case": return (0, case_anything.snakeCase)(text).toUpperCase();
32
+ case "trim": return text.trim();
33
+ case "trim_start": return text.trimStart();
34
+ case "trim_end": return text.trimEnd();
35
+ case "normalize_whitespace": return text.replace(/\s+/g, " ").trim();
36
+ case "reverse": return text.split("").reverse().join("");
37
+ case "slug": return text.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
38
+ case "strip_html": return text.replace(/<[^>]*>/g, "");
39
+ case "count_words": return text.trim() === "" ? 0 : text.trim().split(/\s+/).length;
40
+ case "count_chars": return text.length;
41
+ case "count_lines": return text === "" ? 0 : text.split("\n").length;
42
+ case "repeat": return text.repeat(Math.max(0, Math.min(100, Math.floor(op.count))));
43
+ case "pad_start": return text.padStart(op.length, op.char ?? " ");
44
+ case "pad_end": return text.padEnd(op.length, op.char ?? " ");
45
+ case "slice": return text.slice(op.start, op.end);
46
+ case "truncate": {
47
+ const suffix = op.suffix ?? "…";
48
+ if (text.length <= op.length) return text;
49
+ return text.slice(0, Math.max(0, op.length - suffix.length)) + suffix;
50
+ }
51
+ case "replace": return text.replace(op.from, op.to);
52
+ case "replace_all": return text.split(op.from).join(op.to);
53
+ case "regex_replace": {
54
+ const flags = (op.flags ?? "g").replace(/[^gimsuy]/g, "");
55
+ let re;
56
+ try {
57
+ re = new RegExp(op.pattern, flags);
58
+ } catch (e) {
59
+ throw new Error(`Invalid regex: ${require_tool_registry.isError(e) ? e.message : String(e)}`);
60
+ }
61
+ return text.replace(re, op.replacement);
62
+ }
63
+ case "split": return text.split(op.delimiter);
64
+ case "indent": {
65
+ const size = op.size ?? 2;
66
+ const pad = (op.char ?? " ").repeat(size);
67
+ return text.split("\n").map((l) => l === "" ? l : pad + l).join("\n");
68
+ }
69
+ case "dedent": {
70
+ const lines = text.split("\n");
71
+ const nonEmpty = lines.filter((l) => l.trim() !== "");
72
+ if (nonEmpty.length === 0) return text;
73
+ const minIndent = Math.min(...nonEmpty.map((l) => l.match(/^(\s*)/)?.[1].length ?? 0));
74
+ return lines.map((l) => l.slice(minIndent)).join("\n");
75
+ }
76
+ default: throw new Error(`Unknown operation: ${op.op}`);
77
+ }
78
+ }
79
+ /**
80
+ * Apply an ordered pipeline of string transformations.
81
+ *
82
+ * @remarks
83
+ * Each operation reads the previous step's output. Most operations return strings; `count_*`
84
+ * return numbers and `split` returns an array — once a non-string flows through, subsequent
85
+ * operations report an error rather than coercing. The result is always serialised to a string
86
+ * (arrays become JSON; numbers/booleans are stringified).
87
+ */
88
+ var stringTransformTool = new require_tool.Tool({
89
+ name: "string_transform",
90
+ description: "Apply one or more string transformations in sequence. Supports case conversion (camelCase, snake_case, kebab-case, etc.), trimming, truncation, replacement, splitting, indentation, and more.",
91
+ inputSchema: _nhtio_validation.validator.object({
92
+ text: _nhtio_validation.validator.string().required().allow("").description("Input string to transform"),
93
+ operations: _nhtio_validation.validator.array().items(_nhtio_validation.validator.object().unknown(true)).required().description("Ordered list of operations to apply. Each operation has an \"op\" field.")
94
+ }),
95
+ handler: async (args) => {
96
+ const { text, operations } = args;
97
+ let current = text;
98
+ for (const [i, op] of operations.entries()) {
99
+ if (typeof current !== "string") return `Error: Operation ${i + 1} ("${op.op}") requires a string input, but the previous operation returned ${Array.isArray(current) ? "an array" : typeof current}.`;
100
+ try {
101
+ current = applyStringOp(current, op);
102
+ } catch (err) {
103
+ return `Error in operation ${i + 1} ("${op.op}"): ${require_tool_registry.isError(err) ? err.message : String(err)}`;
104
+ }
105
+ }
106
+ if (Array.isArray(current)) return JSON.stringify(current);
107
+ return String(current);
108
+ }
109
+ });
110
+ /**
111
+ * Extract all matches of a regular expression from a string.
112
+ *
113
+ * @remarks
114
+ * The `g` flag is always enabled. `group` selects which capture group to return per match (0 =
115
+ * full match). Output is at most 500 matches; if truncated, the suffix `(truncated at 500)` is
116
+ * appended.
117
+ */
118
+ var stringExtractTool = new require_tool.Tool({
119
+ name: "string_extract",
120
+ description: "Extract all matches of a regex pattern from text. Returns a JSON array of matched strings. Use capture groups to pull out specific parts.",
121
+ inputSchema: _nhtio_validation.validator.object({
122
+ text: _nhtio_validation.validator.string().required().allow("").description("Input text to search"),
123
+ pattern: _nhtio_validation.validator.string().required().description("Regular expression pattern (no surrounding slashes)"),
124
+ flags: _nhtio_validation.validator.string().default("g").description("Regex flags (default: \"g\"). \"g\" is always included."),
125
+ group: _nhtio_validation.validator.number().default(0).description("Capture group index to return (0 = full match, 1 = first group). Default: 0.")
126
+ }),
127
+ handler: async (args) => {
128
+ const { text, pattern, flags: rawFlags, group } = args;
129
+ const flags = rawFlags.replace(/[^gimsuy]/g, "");
130
+ const flagsWithG = flags.includes("g") ? flags : flags + "g";
131
+ let regex;
132
+ try {
133
+ regex = new RegExp(pattern, flagsWithG);
134
+ } catch (err) {
135
+ return `Error: Invalid regex — ${require_tool_registry.isError(err) ? err.message : String(err)}`;
136
+ }
137
+ const matches = [];
138
+ let match;
139
+ const MAX_MATCHES = 500;
140
+ while ((match = regex.exec(text)) !== null && matches.length < MAX_MATCHES) {
141
+ const value = match[group];
142
+ if (value !== void 0) matches.push(value);
143
+ if (match.index === regex.lastIndex) regex.lastIndex++;
144
+ }
145
+ if (matches.length === 0) return "No matches found.";
146
+ const truncated = matches.length === MAX_MATCHES ? " (truncated at 500)" : "";
147
+ return JSON.stringify(matches) + truncated;
148
+ }
149
+ });
150
+ //#endregion
151
+ exports.stringExtractTool = stringExtractTool;
152
+ exports.stringTransformTool = stringTransformTool;
153
+
154
+ //# sourceMappingURL=string_processing.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string_processing.cjs","names":[],"sources":["../../../src/batteries/tools/string_processing/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for casing, trimming, normalizing, and transforming strings.\n *\n * @module @nhtio/adk/batteries/tools/string_processing\n *\n * @remarks\n * Pre-constructed bundled tools for the `string_processing` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport { Tool } from '@nhtio/adk/common'\nimport { isError } from '@nhtio/adk/guards'\nimport { validator } from '@nhtio/validation'\nimport { camelCase, capitalCase, kebabCase, pascalCase, snakeCase, trainCase } from 'case-anything'\n\ntype StringOp =\n | { op: 'uppercase' }\n | { op: 'lowercase' }\n | { op: 'titlecase' }\n | { op: 'sentence_case' }\n | { op: 'capitalize' }\n | { op: 'camel_case' }\n | { op: 'pascal_case' }\n | { op: 'snake_case' }\n | { op: 'kebab_case' }\n | { op: 'train_case' }\n | { op: 'constant_case' }\n | { op: 'trim' }\n | { op: 'trim_start' }\n | { op: 'trim_end' }\n | { op: 'normalize_whitespace' }\n | { op: 'reverse' }\n | { op: 'slug' }\n | { op: 'strip_html' }\n | { op: 'count_words' }\n | { op: 'count_chars' }\n | { op: 'count_lines' }\n | { op: 'repeat'; count: number }\n | { op: 'pad_start'; length: number; char?: string }\n | { op: 'pad_end'; length: number; char?: string }\n | { op: 'slice'; start: number; end?: number }\n | { op: 'truncate'; length: number; suffix?: string }\n | { op: 'replace'; from: string; to: string }\n | { op: 'replace_all'; from: string; to: string }\n | { op: 'regex_replace'; pattern: string; replacement: string; flags?: string }\n | { op: 'split'; delimiter: string }\n | { op: 'indent'; size?: number; char?: string }\n | { op: 'dedent' }\n\nfunction applyStringOp(text: string, op: StringOp): string | number | string[] {\n switch (op.op) {\n case 'uppercase':\n return text.toUpperCase()\n case 'lowercase':\n return text.toLowerCase()\n case 'capitalize':\n return text.charAt(0).toUpperCase() + text.slice(1)\n case 'titlecase':\n return capitalCase(text)\n case 'sentence_case':\n return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase()\n case 'camel_case':\n return camelCase(text)\n case 'pascal_case':\n return pascalCase(text)\n case 'snake_case':\n return snakeCase(text)\n case 'kebab_case':\n return kebabCase(text)\n case 'train_case':\n return trainCase(text)\n case 'constant_case':\n return snakeCase(text).toUpperCase()\n case 'trim':\n return text.trim()\n case 'trim_start':\n return text.trimStart()\n case 'trim_end':\n return text.trimEnd()\n case 'normalize_whitespace':\n return text.replace(/\\s+/g, ' ').trim()\n case 'reverse':\n return text.split('').reverse().join('')\n case 'slug':\n return text\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n case 'strip_html':\n return text.replace(/<[^>]*>/g, '')\n case 'count_words':\n return text.trim() === '' ? 0 : text.trim().split(/\\s+/).length\n case 'count_chars':\n return text.length\n case 'count_lines':\n return text === '' ? 0 : text.split('\\n').length\n case 'repeat':\n return text.repeat(Math.max(0, Math.min(100, Math.floor(op.count))))\n case 'pad_start':\n return text.padStart(op.length, op.char ?? ' ')\n case 'pad_end':\n return text.padEnd(op.length, op.char ?? ' ')\n case 'slice':\n return text.slice(op.start, op.end)\n case 'truncate': {\n const suffix = op.suffix ?? '…'\n if (text.length <= op.length) return text\n return text.slice(0, Math.max(0, op.length - suffix.length)) + suffix\n }\n case 'replace':\n return text.replace(op.from, op.to)\n case 'replace_all':\n return text.split(op.from).join(op.to)\n case 'regex_replace': {\n const flags = (op.flags ?? 'g').replace(/[^gimsuy]/g, '')\n let re: RegExp\n try {\n re = new RegExp(op.pattern, flags)\n } catch (e) {\n throw new Error(`Invalid regex: ${isError(e) ? e.message : String(e)}`)\n }\n return text.replace(re, op.replacement)\n }\n case 'split':\n return text.split(op.delimiter)\n case 'indent': {\n const size = op.size ?? 2\n const ch = op.char ?? ' '\n const pad = ch.repeat(size)\n return text\n .split('\\n')\n .map((l) => (l === '' ? l : pad + l))\n .join('\\n')\n }\n case 'dedent': {\n const lines = text.split('\\n')\n const nonEmpty = lines.filter((l) => l.trim() !== '')\n if (nonEmpty.length === 0) return text\n const minIndent = Math.min(...nonEmpty.map((l) => l.match(/^(\\s*)/)?.[1].length ?? 0))\n return lines.map((l) => l.slice(minIndent)).join('\\n')\n }\n default:\n throw new Error(`Unknown operation: ${(op as { op: string }).op}`)\n }\n}\n\n/**\n * Apply an ordered pipeline of string transformations.\n *\n * @remarks\n * Each operation reads the previous step's output. Most operations return strings; `count_*`\n * return numbers and `split` returns an array — once a non-string flows through, subsequent\n * operations report an error rather than coercing. The result is always serialised to a string\n * (arrays become JSON; numbers/booleans are stringified).\n */\nexport const stringTransformTool = new Tool({\n name: 'string_transform',\n description:\n 'Apply one or more string transformations in sequence. Supports case conversion (camelCase, snake_case, kebab-case, etc.), trimming, truncation, replacement, splitting, indentation, and more.',\n inputSchema: validator.object({\n text: validator.string().required().allow('').description('Input string to transform'),\n operations: validator\n .array()\n .items(validator.object().unknown(true))\n .required()\n .description('Ordered list of operations to apply. Each operation has an \"op\" field.'),\n }),\n handler: async (args) => {\n const { text, operations } = args as { text: string; operations: StringOp[] }\n let current: string | number | string[] = text\n\n for (const [i, op] of operations.entries()) {\n if (typeof current !== 'string') {\n return `Error: Operation ${i + 1} (\"${op.op}\") requires a string input, but the previous operation returned ${Array.isArray(current) ? 'an array' : typeof current}.`\n }\n try {\n current = applyStringOp(current, op)\n } catch (err) {\n return `Error in operation ${i + 1} (\"${op.op}\"): ${isError(err) ? err.message : String(err)}`\n }\n }\n\n if (Array.isArray(current)) return JSON.stringify(current)\n return String(current)\n },\n})\n\n/**\n * Extract all matches of a regular expression from a string.\n *\n * @remarks\n * The `g` flag is always enabled. `group` selects which capture group to return per match (0 =\n * full match). Output is at most 500 matches; if truncated, the suffix `(truncated at 500)` is\n * appended.\n */\nexport const stringExtractTool = new Tool({\n name: 'string_extract',\n description:\n 'Extract all matches of a regex pattern from text. Returns a JSON array of matched strings. Use capture groups to pull out specific parts.',\n inputSchema: validator.object({\n text: validator.string().required().allow('').description('Input text to search'),\n pattern: validator\n .string()\n .required()\n .description('Regular expression pattern (no surrounding slashes)'),\n flags: validator\n .string()\n .default('g')\n .description('Regex flags (default: \"g\"). \"g\" is always included.'),\n group: validator\n .number()\n .default(0)\n .description('Capture group index to return (0 = full match, 1 = first group). Default: 0.'),\n }),\n handler: async (args) => {\n const {\n text,\n pattern,\n flags: rawFlags,\n group,\n } = args as {\n text: string\n pattern: string\n flags: string\n group: number\n }\n const flags = rawFlags.replace(/[^gimsuy]/g, '')\n const flagsWithG = flags.includes('g') ? flags : flags + 'g'\n\n let regex: RegExp\n try {\n regex = new RegExp(pattern, flagsWithG)\n } catch (err) {\n return `Error: Invalid regex — ${isError(err) ? err.message : String(err)}`\n }\n\n const matches: string[] = []\n let match: RegExpExecArray | null\n const MAX_MATCHES = 500\n\n while ((match = regex.exec(text)) !== null && matches.length < MAX_MATCHES) {\n const value = match[group]\n if (value !== undefined) matches.push(value)\n if (match.index === regex.lastIndex) regex.lastIndex++\n }\n\n if (matches.length === 0) return 'No matches found.'\n const truncated = matches.length === MAX_MATCHES ? ' (truncated at 500)' : ''\n return JSON.stringify(matches) + truncated\n },\n})\n"],"mappings":"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"}
@@ -0,0 +1,151 @@
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 "../../guards.mjs";
5
+ import { validator } from "@nhtio/validation";
6
+ import { camelCase, capitalCase, kebabCase, pascalCase, snakeCase, trainCase } from "case-anything";
7
+ //#region src/batteries/tools/string_processing/index.ts
8
+ /**
9
+ * Pre-constructed tools for casing, trimming, normalizing, and transforming strings.
10
+ *
11
+ * @module @nhtio/adk/batteries/tools/string_processing
12
+ *
13
+ * @remarks
14
+ * Pre-constructed bundled tools for the `string_processing` category. Import individually, the whole
15
+ * category, or import every tool via `@nhtio/adk/batteries`.
16
+ */
17
+ function applyStringOp(text, op) {
18
+ switch (op.op) {
19
+ case "uppercase": return text.toUpperCase();
20
+ case "lowercase": return text.toLowerCase();
21
+ case "capitalize": return text.charAt(0).toUpperCase() + text.slice(1);
22
+ case "titlecase": return capitalCase(text);
23
+ case "sentence_case": return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
24
+ case "camel_case": return camelCase(text);
25
+ case "pascal_case": return pascalCase(text);
26
+ case "snake_case": return snakeCase(text);
27
+ case "kebab_case": return kebabCase(text);
28
+ case "train_case": return trainCase(text);
29
+ case "constant_case": return snakeCase(text).toUpperCase();
30
+ case "trim": return text.trim();
31
+ case "trim_start": return text.trimStart();
32
+ case "trim_end": return text.trimEnd();
33
+ case "normalize_whitespace": return text.replace(/\s+/g, " ").trim();
34
+ case "reverse": return text.split("").reverse().join("");
35
+ case "slug": return text.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
36
+ case "strip_html": return text.replace(/<[^>]*>/g, "");
37
+ case "count_words": return text.trim() === "" ? 0 : text.trim().split(/\s+/).length;
38
+ case "count_chars": return text.length;
39
+ case "count_lines": return text === "" ? 0 : text.split("\n").length;
40
+ case "repeat": return text.repeat(Math.max(0, Math.min(100, Math.floor(op.count))));
41
+ case "pad_start": return text.padStart(op.length, op.char ?? " ");
42
+ case "pad_end": return text.padEnd(op.length, op.char ?? " ");
43
+ case "slice": return text.slice(op.start, op.end);
44
+ case "truncate": {
45
+ const suffix = op.suffix ?? "…";
46
+ if (text.length <= op.length) return text;
47
+ return text.slice(0, Math.max(0, op.length - suffix.length)) + suffix;
48
+ }
49
+ case "replace": return text.replace(op.from, op.to);
50
+ case "replace_all": return text.split(op.from).join(op.to);
51
+ case "regex_replace": {
52
+ const flags = (op.flags ?? "g").replace(/[^gimsuy]/g, "");
53
+ let re;
54
+ try {
55
+ re = new RegExp(op.pattern, flags);
56
+ } catch (e) {
57
+ throw new Error(`Invalid regex: ${isError(e) ? e.message : String(e)}`);
58
+ }
59
+ return text.replace(re, op.replacement);
60
+ }
61
+ case "split": return text.split(op.delimiter);
62
+ case "indent": {
63
+ const size = op.size ?? 2;
64
+ const pad = (op.char ?? " ").repeat(size);
65
+ return text.split("\n").map((l) => l === "" ? l : pad + l).join("\n");
66
+ }
67
+ case "dedent": {
68
+ const lines = text.split("\n");
69
+ const nonEmpty = lines.filter((l) => l.trim() !== "");
70
+ if (nonEmpty.length === 0) return text;
71
+ const minIndent = Math.min(...nonEmpty.map((l) => l.match(/^(\s*)/)?.[1].length ?? 0));
72
+ return lines.map((l) => l.slice(minIndent)).join("\n");
73
+ }
74
+ default: throw new Error(`Unknown operation: ${op.op}`);
75
+ }
76
+ }
77
+ /**
78
+ * Apply an ordered pipeline of string transformations.
79
+ *
80
+ * @remarks
81
+ * Each operation reads the previous step's output. Most operations return strings; `count_*`
82
+ * return numbers and `split` returns an array — once a non-string flows through, subsequent
83
+ * operations report an error rather than coercing. The result is always serialised to a string
84
+ * (arrays become JSON; numbers/booleans are stringified).
85
+ */
86
+ var stringTransformTool = new Tool({
87
+ name: "string_transform",
88
+ description: "Apply one or more string transformations in sequence. Supports case conversion (camelCase, snake_case, kebab-case, etc.), trimming, truncation, replacement, splitting, indentation, and more.",
89
+ inputSchema: validator.object({
90
+ text: validator.string().required().allow("").description("Input string to transform"),
91
+ operations: validator.array().items(validator.object().unknown(true)).required().description("Ordered list of operations to apply. Each operation has an \"op\" field.")
92
+ }),
93
+ handler: async (args) => {
94
+ const { text, operations } = args;
95
+ let current = text;
96
+ for (const [i, op] of operations.entries()) {
97
+ if (typeof current !== "string") return `Error: Operation ${i + 1} ("${op.op}") requires a string input, but the previous operation returned ${Array.isArray(current) ? "an array" : typeof current}.`;
98
+ try {
99
+ current = applyStringOp(current, op);
100
+ } catch (err) {
101
+ return `Error in operation ${i + 1} ("${op.op}"): ${isError(err) ? err.message : String(err)}`;
102
+ }
103
+ }
104
+ if (Array.isArray(current)) return JSON.stringify(current);
105
+ return String(current);
106
+ }
107
+ });
108
+ /**
109
+ * Extract all matches of a regular expression from a string.
110
+ *
111
+ * @remarks
112
+ * The `g` flag is always enabled. `group` selects which capture group to return per match (0 =
113
+ * full match). Output is at most 500 matches; if truncated, the suffix `(truncated at 500)` is
114
+ * appended.
115
+ */
116
+ var stringExtractTool = new Tool({
117
+ name: "string_extract",
118
+ description: "Extract all matches of a regex pattern from text. Returns a JSON array of matched strings. Use capture groups to pull out specific parts.",
119
+ inputSchema: validator.object({
120
+ text: validator.string().required().allow("").description("Input text to search"),
121
+ pattern: validator.string().required().description("Regular expression pattern (no surrounding slashes)"),
122
+ flags: validator.string().default("g").description("Regex flags (default: \"g\"). \"g\" is always included."),
123
+ group: validator.number().default(0).description("Capture group index to return (0 = full match, 1 = first group). Default: 0.")
124
+ }),
125
+ handler: async (args) => {
126
+ const { text, pattern, flags: rawFlags, group } = args;
127
+ const flags = rawFlags.replace(/[^gimsuy]/g, "");
128
+ const flagsWithG = flags.includes("g") ? flags : flags + "g";
129
+ let regex;
130
+ try {
131
+ regex = new RegExp(pattern, flagsWithG);
132
+ } catch (err) {
133
+ return `Error: Invalid regex — ${isError(err) ? err.message : String(err)}`;
134
+ }
135
+ const matches = [];
136
+ let match;
137
+ const MAX_MATCHES = 500;
138
+ while ((match = regex.exec(text)) !== null && matches.length < MAX_MATCHES) {
139
+ const value = match[group];
140
+ if (value !== void 0) matches.push(value);
141
+ if (match.index === regex.lastIndex) regex.lastIndex++;
142
+ }
143
+ if (matches.length === 0) return "No matches found.";
144
+ const truncated = matches.length === MAX_MATCHES ? " (truncated at 500)" : "";
145
+ return JSON.stringify(matches) + truncated;
146
+ }
147
+ });
148
+ //#endregion
149
+ export { stringExtractTool, stringTransformTool };
150
+
151
+ //# sourceMappingURL=string_processing.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string_processing.mjs","names":[],"sources":["../../../src/batteries/tools/string_processing/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for casing, trimming, normalizing, and transforming strings.\n *\n * @module @nhtio/adk/batteries/tools/string_processing\n *\n * @remarks\n * Pre-constructed bundled tools for the `string_processing` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport { Tool } from '@nhtio/adk/common'\nimport { isError } from '@nhtio/adk/guards'\nimport { validator } from '@nhtio/validation'\nimport { camelCase, capitalCase, kebabCase, pascalCase, snakeCase, trainCase } from 'case-anything'\n\ntype StringOp =\n | { op: 'uppercase' }\n | { op: 'lowercase' }\n | { op: 'titlecase' }\n | { op: 'sentence_case' }\n | { op: 'capitalize' }\n | { op: 'camel_case' }\n | { op: 'pascal_case' }\n | { op: 'snake_case' }\n | { op: 'kebab_case' }\n | { op: 'train_case' }\n | { op: 'constant_case' }\n | { op: 'trim' }\n | { op: 'trim_start' }\n | { op: 'trim_end' }\n | { op: 'normalize_whitespace' }\n | { op: 'reverse' }\n | { op: 'slug' }\n | { op: 'strip_html' }\n | { op: 'count_words' }\n | { op: 'count_chars' }\n | { op: 'count_lines' }\n | { op: 'repeat'; count: number }\n | { op: 'pad_start'; length: number; char?: string }\n | { op: 'pad_end'; length: number; char?: string }\n | { op: 'slice'; start: number; end?: number }\n | { op: 'truncate'; length: number; suffix?: string }\n | { op: 'replace'; from: string; to: string }\n | { op: 'replace_all'; from: string; to: string }\n | { op: 'regex_replace'; pattern: string; replacement: string; flags?: string }\n | { op: 'split'; delimiter: string }\n | { op: 'indent'; size?: number; char?: string }\n | { op: 'dedent' }\n\nfunction applyStringOp(text: string, op: StringOp): string | number | string[] {\n switch (op.op) {\n case 'uppercase':\n return text.toUpperCase()\n case 'lowercase':\n return text.toLowerCase()\n case 'capitalize':\n return text.charAt(0).toUpperCase() + text.slice(1)\n case 'titlecase':\n return capitalCase(text)\n case 'sentence_case':\n return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase()\n case 'camel_case':\n return camelCase(text)\n case 'pascal_case':\n return pascalCase(text)\n case 'snake_case':\n return snakeCase(text)\n case 'kebab_case':\n return kebabCase(text)\n case 'train_case':\n return trainCase(text)\n case 'constant_case':\n return snakeCase(text).toUpperCase()\n case 'trim':\n return text.trim()\n case 'trim_start':\n return text.trimStart()\n case 'trim_end':\n return text.trimEnd()\n case 'normalize_whitespace':\n return text.replace(/\\s+/g, ' ').trim()\n case 'reverse':\n return text.split('').reverse().join('')\n case 'slug':\n return text\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n case 'strip_html':\n return text.replace(/<[^>]*>/g, '')\n case 'count_words':\n return text.trim() === '' ? 0 : text.trim().split(/\\s+/).length\n case 'count_chars':\n return text.length\n case 'count_lines':\n return text === '' ? 0 : text.split('\\n').length\n case 'repeat':\n return text.repeat(Math.max(0, Math.min(100, Math.floor(op.count))))\n case 'pad_start':\n return text.padStart(op.length, op.char ?? ' ')\n case 'pad_end':\n return text.padEnd(op.length, op.char ?? ' ')\n case 'slice':\n return text.slice(op.start, op.end)\n case 'truncate': {\n const suffix = op.suffix ?? '…'\n if (text.length <= op.length) return text\n return text.slice(0, Math.max(0, op.length - suffix.length)) + suffix\n }\n case 'replace':\n return text.replace(op.from, op.to)\n case 'replace_all':\n return text.split(op.from).join(op.to)\n case 'regex_replace': {\n const flags = (op.flags ?? 'g').replace(/[^gimsuy]/g, '')\n let re: RegExp\n try {\n re = new RegExp(op.pattern, flags)\n } catch (e) {\n throw new Error(`Invalid regex: ${isError(e) ? e.message : String(e)}`)\n }\n return text.replace(re, op.replacement)\n }\n case 'split':\n return text.split(op.delimiter)\n case 'indent': {\n const size = op.size ?? 2\n const ch = op.char ?? ' '\n const pad = ch.repeat(size)\n return text\n .split('\\n')\n .map((l) => (l === '' ? l : pad + l))\n .join('\\n')\n }\n case 'dedent': {\n const lines = text.split('\\n')\n const nonEmpty = lines.filter((l) => l.trim() !== '')\n if (nonEmpty.length === 0) return text\n const minIndent = Math.min(...nonEmpty.map((l) => l.match(/^(\\s*)/)?.[1].length ?? 0))\n return lines.map((l) => l.slice(minIndent)).join('\\n')\n }\n default:\n throw new Error(`Unknown operation: ${(op as { op: string }).op}`)\n }\n}\n\n/**\n * Apply an ordered pipeline of string transformations.\n *\n * @remarks\n * Each operation reads the previous step's output. Most operations return strings; `count_*`\n * return numbers and `split` returns an array — once a non-string flows through, subsequent\n * operations report an error rather than coercing. The result is always serialised to a string\n * (arrays become JSON; numbers/booleans are stringified).\n */\nexport const stringTransformTool = new Tool({\n name: 'string_transform',\n description:\n 'Apply one or more string transformations in sequence. Supports case conversion (camelCase, snake_case, kebab-case, etc.), trimming, truncation, replacement, splitting, indentation, and more.',\n inputSchema: validator.object({\n text: validator.string().required().allow('').description('Input string to transform'),\n operations: validator\n .array()\n .items(validator.object().unknown(true))\n .required()\n .description('Ordered list of operations to apply. Each operation has an \"op\" field.'),\n }),\n handler: async (args) => {\n const { text, operations } = args as { text: string; operations: StringOp[] }\n let current: string | number | string[] = text\n\n for (const [i, op] of operations.entries()) {\n if (typeof current !== 'string') {\n return `Error: Operation ${i + 1} (\"${op.op}\") requires a string input, but the previous operation returned ${Array.isArray(current) ? 'an array' : typeof current}.`\n }\n try {\n current = applyStringOp(current, op)\n } catch (err) {\n return `Error in operation ${i + 1} (\"${op.op}\"): ${isError(err) ? err.message : String(err)}`\n }\n }\n\n if (Array.isArray(current)) return JSON.stringify(current)\n return String(current)\n },\n})\n\n/**\n * Extract all matches of a regular expression from a string.\n *\n * @remarks\n * The `g` flag is always enabled. `group` selects which capture group to return per match (0 =\n * full match). Output is at most 500 matches; if truncated, the suffix `(truncated at 500)` is\n * appended.\n */\nexport const stringExtractTool = new Tool({\n name: 'string_extract',\n description:\n 'Extract all matches of a regex pattern from text. Returns a JSON array of matched strings. Use capture groups to pull out specific parts.',\n inputSchema: validator.object({\n text: validator.string().required().allow('').description('Input text to search'),\n pattern: validator\n .string()\n .required()\n .description('Regular expression pattern (no surrounding slashes)'),\n flags: validator\n .string()\n .default('g')\n .description('Regex flags (default: \"g\"). \"g\" is always included.'),\n group: validator\n .number()\n .default(0)\n .description('Capture group index to return (0 = full match, 1 = first group). Default: 0.'),\n }),\n handler: async (args) => {\n const {\n text,\n pattern,\n flags: rawFlags,\n group,\n } = args as {\n text: string\n pattern: string\n flags: string\n group: number\n }\n const flags = rawFlags.replace(/[^gimsuy]/g, '')\n const flagsWithG = flags.includes('g') ? flags : flags + 'g'\n\n let regex: RegExp\n try {\n regex = new RegExp(pattern, flagsWithG)\n } catch (err) {\n return `Error: Invalid regex — ${isError(err) ? err.message : String(err)}`\n }\n\n const matches: string[] = []\n let match: RegExpExecArray | null\n const MAX_MATCHES = 500\n\n while ((match = regex.exec(text)) !== null && matches.length < MAX_MATCHES) {\n const value = match[group]\n if (value !== undefined) matches.push(value)\n if (match.index === regex.lastIndex) regex.lastIndex++\n }\n\n if (matches.length === 0) return 'No matches found.'\n const truncated = matches.length === MAX_MATCHES ? ' (truncated at 500)' : ''\n return JSON.stringify(matches) + truncated\n },\n})\n"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Pre-constructed tools for transforming arrays and objects into tables and tabular text.
3
+ *
4
+ * @module @nhtio/adk/batteries/tools/structured_data
5
+ *
6
+ * @remarks
7
+ * Pre-constructed bundled tools for the `structured_data` category. Import individually, the whole
8
+ * category, or import every tool via `@nhtio/adk/batteries`.
9
+ */
10
+ import { Tool } from "../../../common";
11
+ /**
12
+ * Convert a JSON array of objects into a formatted table.
13
+ *
14
+ * @remarks
15
+ * Supports `markdown`, `csv`, and `tsv` output. Columns default to the keys of the first row;
16
+ * supply `columns` to control which keys appear and in what order.
17
+ */
18
+ export declare const formatTableTool: Tool<import("../../../common").SpooledArtifact>;
19
+ /**
20
+ * Pretty-print or minify a JSON string.
21
+ *
22
+ * @remarks
23
+ * Validates the input as JSON, then re-serialises it with the requested indentation. `indent` is
24
+ * clamped to the range [0, 8]; `0` produces minified output.
25
+ */
26
+ export declare const jsonFormatTool: Tool<import("../../../common").SpooledArtifact>;
27
+ /**
28
+ * Check whether a string matches a known format.
29
+ *
30
+ * @remarks
31
+ * Supported formats: `email`, `uuid` (v1–v5), `ipv4`, `iso_date`, `iso_datetime`, `hex_color`,
32
+ * `phone_e164`, `semver`, `integer`, `decimal`, `alphanumeric`, `slug`, `hex`, `base64`.
33
+ */
34
+ export declare const validateFormatTool: Tool<import("../../../common").SpooledArtifact>;
@@ -0,0 +1,189 @@
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/structured_data/index.ts
9
+ /**
10
+ * Pre-constructed tools for transforming arrays and objects into tables and tabular text.
11
+ *
12
+ * @module @nhtio/adk/batteries/tools/structured_data
13
+ *
14
+ * @remarks
15
+ * Pre-constructed bundled tools for the `structured_data` category. Import individually, the whole
16
+ * category, or import every tool via `@nhtio/adk/batteries`.
17
+ */
18
+ function csvEscape(value) {
19
+ const str = value === null || value === void 0 ? "" : String(value);
20
+ if (str.includes(",") || str.includes("\"") || str.includes("\n") || str.includes("\r")) return "\"" + str.replace(/"/g, "\"\"") + "\"";
21
+ return str;
22
+ }
23
+ function tsvEscape(value) {
24
+ return (value === null || value === void 0 ? "" : String(value)).replace(/\t/g, " ").replace(/\r?\n/g, " ");
25
+ }
26
+ function mdEscape(value) {
27
+ return String(value === null || value === void 0 ? "" : value).replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
28
+ }
29
+ /**
30
+ * Convert a JSON array of objects into a formatted table.
31
+ *
32
+ * @remarks
33
+ * Supports `markdown`, `csv`, and `tsv` output. Columns default to the keys of the first row;
34
+ * supply `columns` to control which keys appear and in what order.
35
+ */
36
+ var formatTableTool = new require_tool.Tool({
37
+ name: "format_table",
38
+ description: "Convert a JSON array of objects into a formatted table. Supports Markdown, CSV, and TSV output.",
39
+ inputSchema: _nhtio_validation.validator.object({
40
+ data: _nhtio_validation.validator.string().required().description("JSON array of objects as a string"),
41
+ format: _nhtio_validation.validator.string().valid("markdown", "csv", "tsv").required().description("Output format"),
42
+ columns: _nhtio_validation.validator.array().items(_nhtio_validation.validator.string()).optional().description("Column keys to include, in order. If omitted, all keys from the first row are used.")
43
+ }),
44
+ handler: async (args) => {
45
+ const { data, format, columns: explicitColumns } = args;
46
+ let rows;
47
+ try {
48
+ rows = JSON.parse(data);
49
+ } catch {
50
+ return "Error: Invalid JSON input.";
51
+ }
52
+ if (!Array.isArray(rows)) return "Error: Input must be a JSON array.";
53
+ if (rows.length === 0) return "Empty array — no data to display.";
54
+ const columns = explicitColumns ?? Object.keys(rows[0]);
55
+ if (format === "csv") {
56
+ const lines = [columns.map(csvEscape).join(",")];
57
+ for (const row of rows) {
58
+ const obj = row;
59
+ lines.push(columns.map((col) => csvEscape(obj[col])).join(","));
60
+ }
61
+ return lines.join("\n");
62
+ }
63
+ if (format === "tsv") {
64
+ const lines = [columns.map(tsvEscape).join(" ")];
65
+ for (const row of rows) {
66
+ const obj = row;
67
+ lines.push(columns.map((col) => tsvEscape(obj[col])).join(" "));
68
+ }
69
+ return lines.join("\n");
70
+ }
71
+ return [
72
+ "| " + columns.map(mdEscape).join(" | ") + " |",
73
+ "| " + columns.map(() => "---").join(" | ") + " |",
74
+ ...rows.map((row) => {
75
+ const obj = row;
76
+ return "| " + columns.map((col) => mdEscape(obj[col])).join(" | ") + " |";
77
+ })
78
+ ].join("\n");
79
+ }
80
+ });
81
+ /**
82
+ * Pretty-print or minify a JSON string.
83
+ *
84
+ * @remarks
85
+ * Validates the input as JSON, then re-serialises it with the requested indentation. `indent` is
86
+ * clamped to the range [0, 8]; `0` produces minified output.
87
+ */
88
+ var jsonFormatTool = new require_tool.Tool({
89
+ name: "json_format",
90
+ description: "Pretty-print or minify a JSON string. Validates JSON and normalises whitespace.",
91
+ inputSchema: _nhtio_validation.validator.object({
92
+ data: _nhtio_validation.validator.string().required().description("JSON string to format"),
93
+ indent: _nhtio_validation.validator.number().default(2).description("Indentation spaces (0 = minify, default: 2). Max: 8.")
94
+ }),
95
+ handler: async (args) => {
96
+ const { data, indent } = args;
97
+ try {
98
+ const parsed = JSON.parse(data);
99
+ return JSON.stringify(parsed, null, Math.max(0, Math.min(8, Math.floor(indent))));
100
+ } catch (err) {
101
+ return `Error: Invalid JSON — ${require_tool_registry.isError(err) ? err.message : String(err)}`;
102
+ }
103
+ }
104
+ });
105
+ var FORMAT_PATTERNS = {
106
+ email: {
107
+ pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
108
+ label: "email address"
109
+ },
110
+ uuid: {
111
+ pattern: /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
112
+ label: "UUID (v1–v5)"
113
+ },
114
+ ipv4: {
115
+ pattern: /^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$/,
116
+ label: "IPv4 address"
117
+ },
118
+ iso_date: {
119
+ pattern: /^\d{4}-\d{2}-\d{2}$/,
120
+ label: "ISO 8601 date (YYYY-MM-DD)"
121
+ },
122
+ iso_datetime: {
123
+ pattern: /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:\d{2})?$/,
124
+ label: "ISO 8601 datetime"
125
+ },
126
+ hex_color: {
127
+ pattern: /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/,
128
+ label: "CSS hex color"
129
+ },
130
+ phone_e164: {
131
+ pattern: /^\+[1-9]\d{1,14}$/,
132
+ label: "E.164 phone number"
133
+ },
134
+ semver: {
135
+ pattern: /^\d+\.\d+\.\d+(-[0-9A-Za-z-.]+)?(\+[0-9A-Za-z-.]+)?$/,
136
+ label: "Semantic Version (SemVer)"
137
+ },
138
+ integer: {
139
+ pattern: /^-?\d+$/,
140
+ label: "integer"
141
+ },
142
+ decimal: {
143
+ pattern: /^-?\d+(\.\d+)?$/,
144
+ label: "decimal number"
145
+ },
146
+ alphanumeric: {
147
+ pattern: /^[a-zA-Z0-9]+$/,
148
+ label: "alphanumeric string"
149
+ },
150
+ slug: {
151
+ pattern: /^[a-z0-9]+(-[a-z0-9]+)*$/,
152
+ label: "URL slug"
153
+ },
154
+ hex: {
155
+ pattern: /^(0x)?[0-9a-fA-F]+$/,
156
+ label: "hexadecimal string"
157
+ },
158
+ base64: {
159
+ pattern: /^[A-Za-z0-9+/]*={0,2}$/,
160
+ label: "base64-encoded string"
161
+ }
162
+ };
163
+ /**
164
+ * Check whether a string matches a known format.
165
+ *
166
+ * @remarks
167
+ * Supported formats: `email`, `uuid` (v1–v5), `ipv4`, `iso_date`, `iso_datetime`, `hex_color`,
168
+ * `phone_e164`, `semver`, `integer`, `decimal`, `alphanumeric`, `slug`, `hex`, `base64`.
169
+ */
170
+ var validateFormatTool = new require_tool.Tool({
171
+ name: "validate_format",
172
+ description: "Check whether a string matches a known format (email, UUID, ISO date, hex colour, phone number, semver, slug, etc.).",
173
+ inputSchema: _nhtio_validation.validator.object({
174
+ value: _nhtio_validation.validator.string().required().description("The string to validate"),
175
+ format: _nhtio_validation.validator.string().valid(...Object.keys(FORMAT_PATTERNS)).required().description(`Format to validate against. One of: ${Object.keys(FORMAT_PATTERNS).join(", ")}`)
176
+ }),
177
+ handler: async (args) => {
178
+ const { value, format } = args;
179
+ const def = FORMAT_PATTERNS[format];
180
+ if (!def) return `Error: Unknown format "${format}". Supported: ${Object.keys(FORMAT_PATTERNS).join(", ")}`;
181
+ return def.pattern.test(value) ? `Valid: "${value}" is a valid ${def.label}.` : `Invalid: "${value}" is not a valid ${def.label}.`;
182
+ }
183
+ });
184
+ //#endregion
185
+ exports.formatTableTool = formatTableTool;
186
+ exports.jsonFormatTool = jsonFormatTool;
187
+ exports.validateFormatTool = validateFormatTool;
188
+
189
+ //# sourceMappingURL=structured_data.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured_data.cjs","names":[],"sources":["../../../src/batteries/tools/structured_data/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for transforming arrays and objects into tables and tabular text.\n *\n * @module @nhtio/adk/batteries/tools/structured_data\n *\n * @remarks\n * Pre-constructed bundled tools for the `structured_data` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport { Tool } from '@nhtio/adk/common'\nimport { isError } from '@nhtio/adk/guards'\nimport { validator } from '@nhtio/validation'\n\nfunction csvEscape(value: unknown): string {\n const str = value === null || value === undefined ? '' : String(value)\n if (str.includes(',') || str.includes('\"') || str.includes('\\n') || str.includes('\\r')) {\n return '\"' + str.replace(/\"/g, '\"\"') + '\"'\n }\n return str\n}\n\nfunction tsvEscape(value: unknown): string {\n const str = value === null || value === undefined ? '' : String(value)\n return str.replace(/\\t/g, ' ').replace(/\\r?\\n/g, ' ')\n}\n\nfunction mdEscape(value: unknown): string {\n return String(value === null || value === undefined ? '' : value)\n .replace(/\\|/g, '\\\\|')\n .replace(/\\r?\\n/g, ' ')\n}\n\n/**\n * Convert a JSON array of objects into a formatted table.\n *\n * @remarks\n * Supports `markdown`, `csv`, and `tsv` output. Columns default to the keys of the first row;\n * supply `columns` to control which keys appear and in what order.\n */\nexport const formatTableTool = new Tool({\n name: 'format_table',\n description:\n 'Convert a JSON array of objects into a formatted table. Supports Markdown, CSV, and TSV output.',\n inputSchema: validator.object({\n data: validator.string().required().description('JSON array of objects as a string'),\n format: validator\n .string()\n .valid('markdown', 'csv', 'tsv')\n .required()\n .description('Output format'),\n columns: validator\n .array()\n .items(validator.string())\n .optional()\n .description(\n 'Column keys to include, in order. If omitted, all keys from the first row are used.'\n ),\n }),\n handler: async (args) => {\n const {\n data,\n format,\n columns: explicitColumns,\n } = args as {\n data: string\n format: 'markdown' | 'csv' | 'tsv'\n columns?: string[]\n }\n\n let rows: unknown[]\n try {\n rows = JSON.parse(data)\n } catch {\n return 'Error: Invalid JSON input.'\n }\n\n if (!Array.isArray(rows)) return 'Error: Input must be a JSON array.'\n if (rows.length === 0) return 'Empty array — no data to display.'\n\n const columns = explicitColumns ?? Object.keys(rows[0] as Record<string, unknown>)\n\n if (format === 'csv') {\n const lines = [columns.map(csvEscape).join(',')]\n for (const row of rows) {\n const obj = row as Record<string, unknown>\n lines.push(columns.map((col) => csvEscape(obj[col])).join(','))\n }\n return lines.join('\\n')\n }\n\n if (format === 'tsv') {\n const lines = [columns.map(tsvEscape).join('\\t')]\n for (const row of rows) {\n const obj = row as Record<string, unknown>\n lines.push(columns.map((col) => tsvEscape(obj[col])).join('\\t'))\n }\n return lines.join('\\n')\n }\n\n const header = '| ' + columns.map(mdEscape).join(' | ') + ' |'\n const separator = '| ' + columns.map(() => '---').join(' | ') + ' |'\n const dataRows = rows.map((row) => {\n const obj = row as Record<string, unknown>\n return '| ' + columns.map((col) => mdEscape(obj[col])).join(' | ') + ' |'\n })\n return [header, separator, ...dataRows].join('\\n')\n },\n})\n\n/**\n * Pretty-print or minify a JSON string.\n *\n * @remarks\n * Validates the input as JSON, then re-serialises it with the requested indentation. `indent` is\n * clamped to the range [0, 8]; `0` produces minified output.\n */\nexport const jsonFormatTool = new Tool({\n name: 'json_format',\n description: 'Pretty-print or minify a JSON string. Validates JSON and normalises whitespace.',\n inputSchema: validator.object({\n data: validator.string().required().description('JSON string to format'),\n indent: validator\n .number()\n .default(2)\n .description('Indentation spaces (0 = minify, default: 2). Max: 8.'),\n }),\n handler: async (args) => {\n const { data, indent } = args as { data: string; indent: number }\n try {\n const parsed = JSON.parse(data)\n return JSON.stringify(parsed, null, Math.max(0, Math.min(8, Math.floor(indent))))\n } catch (err) {\n return `Error: Invalid JSON — ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\nconst FORMAT_PATTERNS: Record<string, { pattern: RegExp; label: string }> = {\n email: {\n pattern: /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/,\n label: 'email address',\n },\n uuid: {\n pattern: /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,\n label: 'UUID (v1–v5)',\n },\n ipv4: {\n pattern: /^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$/,\n label: 'IPv4 address',\n },\n iso_date: {\n pattern: /^\\d{4}-\\d{2}-\\d{2}$/,\n label: 'ISO 8601 date (YYYY-MM-DD)',\n },\n iso_datetime: {\n pattern: /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:\\d{2})?$/,\n label: 'ISO 8601 datetime',\n },\n hex_color: {\n pattern: /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/,\n label: 'CSS hex color',\n },\n phone_e164: {\n pattern: /^\\+[1-9]\\d{1,14}$/,\n label: 'E.164 phone number',\n },\n semver: {\n pattern: /^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z-.]+)?(\\+[0-9A-Za-z-.]+)?$/,\n label: 'Semantic Version (SemVer)',\n },\n integer: {\n pattern: /^-?\\d+$/,\n label: 'integer',\n },\n decimal: {\n pattern: /^-?\\d+(\\.\\d+)?$/,\n label: 'decimal number',\n },\n alphanumeric: {\n pattern: /^[a-zA-Z0-9]+$/,\n label: 'alphanumeric string',\n },\n slug: {\n pattern: /^[a-z0-9]+(-[a-z0-9]+)*$/,\n label: 'URL slug',\n },\n hex: {\n pattern: /^(0x)?[0-9a-fA-F]+$/,\n label: 'hexadecimal string',\n },\n base64: {\n pattern: /^[A-Za-z0-9+/]*={0,2}$/,\n label: 'base64-encoded string',\n },\n}\n\n/**\n * Check whether a string matches a known format.\n *\n * @remarks\n * Supported formats: `email`, `uuid` (v1–v5), `ipv4`, `iso_date`, `iso_datetime`, `hex_color`,\n * `phone_e164`, `semver`, `integer`, `decimal`, `alphanumeric`, `slug`, `hex`, `base64`.\n */\nexport const validateFormatTool = new Tool({\n name: 'validate_format',\n description:\n 'Check whether a string matches a known format (email, UUID, ISO date, hex colour, phone number, semver, slug, etc.).',\n inputSchema: validator.object({\n value: validator.string().required().description('The string to validate'),\n format: validator\n .string()\n .valid(...Object.keys(FORMAT_PATTERNS))\n .required()\n .description(\n `Format to validate against. One of: ${Object.keys(FORMAT_PATTERNS).join(', ')}`\n ),\n }),\n handler: async (args) => {\n const { value, format } = args as { value: string; format: string }\n const def = FORMAT_PATTERNS[format]\n if (!def) {\n return `Error: Unknown format \"${format}\". Supported: ${Object.keys(FORMAT_PATTERNS).join(', ')}`\n }\n const valid = def.pattern.test(value)\n return valid\n ? `Valid: \"${value}\" is a valid ${def.label}.`\n : `Invalid: \"${value}\" is not a valid ${def.label}.`\n },\n})\n"],"mappings":"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"}