@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,171 @@
1
+ import "../../common-DeZaonK1.mjs";
2
+ import { t as Tool } from "../../tool-D2WB1EA1.mjs";
3
+ import { validator } from "@nhtio/validation";
4
+ import { DateTime, Duration, IANAZone } from "luxon";
5
+ //#region src/batteries/tools/datetime_math/index.ts
6
+ /**
7
+ * Pre-constructed tools for ISO datetime arithmetic, differences, and timezone-aware formatting.
8
+ *
9
+ * @module @nhtio/adk/batteries/tools/datetime_math
10
+ *
11
+ * @remarks
12
+ * Pre-constructed bundled tools for the `datetime_math` category. Import individually, the whole
13
+ * category, or import every tool via `@nhtio/adk/batteries`.
14
+ */
15
+ function resolveZone(timezone) {
16
+ if (!timezone) return { zone: "UTC" };
17
+ if (!IANAZone.isValidZone(timezone)) return {
18
+ zone: "",
19
+ error: `Invalid timezone "${timezone}".`
20
+ };
21
+ return { zone: timezone };
22
+ }
23
+ function parseDate(input, zone) {
24
+ if (input.toLowerCase() === "now") return DateTime.now().setZone(zone);
25
+ const dt = DateTime.fromISO(input, { zone });
26
+ if (!dt.isValid) return { error: `Invalid date "${input}". Use ISO 8601 format (e.g. "2025-06-15" or "2025-06-15T14:30:00") or "now".` };
27
+ return dt;
28
+ }
29
+ /**
30
+ * Add or subtract a duration from a date/time.
31
+ *
32
+ * @remarks
33
+ * All duration components (years/months/weeks/days/hours/minutes/seconds) are optional and
34
+ * combined into a single Duration. Output formatting includes a time component when the input
35
+ * itself has one or when any sub-day component is non-zero.
36
+ */
37
+ var dateAddTool = new Tool({
38
+ name: "date_add",
39
+ description: "Add or subtract a duration from a date/time. Useful for \"what date is 90 days from now?\" or \"when was 6 months before X?\"",
40
+ inputSchema: validator.object({
41
+ date: validator.string().required().description("ISO 8601 date/datetime string or \"now\""),
42
+ direction: validator.string().valid("add", "subtract").required().description("\"add\" to move forward in time, \"subtract\" to move backward"),
43
+ years: validator.number().default(0).description("Years component (optional)"),
44
+ months: validator.number().default(0).description("Months component (optional)"),
45
+ weeks: validator.number().default(0).description("Weeks component (optional)"),
46
+ days: validator.number().default(0).description("Days component (optional)"),
47
+ hours: validator.number().default(0).description("Hours component (optional)"),
48
+ minutes: validator.number().default(0).description("Minutes component (optional)"),
49
+ seconds: validator.number().default(0).description("Seconds component (optional)"),
50
+ timezone: validator.string().optional().description("IANA timezone for interpreting the date (optional, defaults UTC)")
51
+ }),
52
+ handler: async (args) => {
53
+ const { date, direction, years, months, weeks, days, hours, minutes, seconds, timezone } = args;
54
+ const { zone, error: zoneError } = resolveZone(timezone);
55
+ if (zoneError) return `Error: ${zoneError}`;
56
+ const parsed = parseDate(date, zone);
57
+ if ("error" in parsed) return `Error: ${parsed.error}`;
58
+ const durObj = {
59
+ years,
60
+ months,
61
+ weeks,
62
+ days,
63
+ hours,
64
+ minutes,
65
+ seconds
66
+ };
67
+ const dur = Duration.fromObject(durObj);
68
+ const result = direction === "subtract" ? parsed.minus(dur) : parsed.plus(dur);
69
+ const inputHasTime = date.includes("T") || date.toLowerCase() === "now";
70
+ const durationHasTime = durObj.hours !== 0 || durObj.minutes !== 0 || durObj.seconds !== 0;
71
+ const formatted = inputHasTime || durationHasTime ? result.toFormat("cccc, LLLL d, yyyy 'at' h:mm:ss a ZZZZ") : result.toFormat("cccc, LLLL d, yyyy");
72
+ const durParts = Object.entries(durObj).filter(([, v]) => v !== 0).map(([k, v]) => `${v} ${k}`).join(", ");
73
+ return `${direction === "subtract" ? "Subtracting" : "Adding"} ${durParts || "0"} ${direction === "subtract" ? "from" : "to"} ${date}: ${formatted}`;
74
+ }
75
+ });
76
+ /**
77
+ * Calculate the difference between two dates/times in a chosen unit.
78
+ *
79
+ * @remarks
80
+ * Result is signed — positive when `to` is after `from`, negative otherwise — but rendered as
81
+ * `|value| <unit> after/before` for readability. Uses luxon's `diff().as(unit)` which respects
82
+ * calendar arithmetic for months/years.
83
+ */
84
+ var dateDiffTool = new Tool({
85
+ name: "date_diff",
86
+ description: "Calculate the difference between two dates/times in a specified unit. Useful for \"how many days until X?\" or \"how long ago was Y?\"",
87
+ inputSchema: validator.object({
88
+ from: validator.string().required().description("Start date (ISO 8601 or \"now\")"),
89
+ to: validator.string().required().description("End date (ISO 8601 or \"now\")"),
90
+ unit: validator.string().valid("years", "months", "weeks", "days", "hours", "minutes", "seconds").required().description("Unit to express the difference in"),
91
+ timezone: validator.string().optional().description("IANA timezone for interpreting dates (optional, defaults UTC)")
92
+ }),
93
+ handler: async (args) => {
94
+ const { from, to, unit, timezone } = args;
95
+ const { zone, error: zoneError } = resolveZone(timezone);
96
+ if (zoneError) return `Error: ${zoneError}`;
97
+ const fromParsed = parseDate(from, zone);
98
+ if ("error" in fromParsed) return `Error: ${fromParsed.error}`;
99
+ const toParsed = parseDate(to, zone);
100
+ if ("error" in toParsed) return `Error: ${toParsed.error}`;
101
+ const value = toParsed.diff(fromParsed, unit).as(unit);
102
+ const rounded = Number.parseFloat(value.toFixed(4));
103
+ return `${to} is ${Math.abs(rounded)} ${unit} ${value >= 0 ? "after" : "before"} ${from}`;
104
+ }
105
+ });
106
+ /**
107
+ * Convert total seconds into a human-readable duration string.
108
+ *
109
+ * @remarks
110
+ * Examples: `3725` → `1 hour, 2 minutes and 5 seconds`. Negative inputs are prefixed with `-`.
111
+ * Zero seconds returns the literal `0 seconds`.
112
+ */
113
+ var durationFormatTool = new Tool({
114
+ name: "duration_format",
115
+ description: "Convert a total number of seconds into a human-readable duration breakdown (e.g. \"2 hours, 15 minutes and 30 seconds\").",
116
+ inputSchema: validator.object({ seconds: validator.number().required().description("Total number of seconds (may be negative)") }),
117
+ handler: async (args) => {
118
+ const { seconds: totalSeconds } = args;
119
+ const sign = totalSeconds < 0 ? "-" : "";
120
+ const absSeconds = Math.abs(totalSeconds);
121
+ const obj = Duration.fromObject({ seconds: absSeconds }).shiftTo("years", "months", "weeks", "days", "hours", "minutes", "seconds").toObject();
122
+ const units = [
123
+ [
124
+ "years",
125
+ "year",
126
+ "years"
127
+ ],
128
+ [
129
+ "months",
130
+ "month",
131
+ "months"
132
+ ],
133
+ [
134
+ "weeks",
135
+ "week",
136
+ "weeks"
137
+ ],
138
+ [
139
+ "days",
140
+ "day",
141
+ "days"
142
+ ],
143
+ [
144
+ "hours",
145
+ "hour",
146
+ "hours"
147
+ ],
148
+ [
149
+ "minutes",
150
+ "minute",
151
+ "minutes"
152
+ ],
153
+ [
154
+ "seconds",
155
+ "second",
156
+ "seconds"
157
+ ]
158
+ ];
159
+ const parts = [];
160
+ for (const [key, singular, plural] of units) {
161
+ const v = Math.floor(obj[key] ?? 0);
162
+ if (v > 0) parts.push(`${v} ${v === 1 ? singular : plural}`);
163
+ }
164
+ if (parts.length === 0) return "0 seconds";
165
+ return `${sign}${parts.length === 1 ? parts[0] : parts.slice(0, -1).join(", ") + " and " + parts[parts.length - 1]}`;
166
+ }
167
+ });
168
+ //#endregion
169
+ export { dateAddTool, dateDiffTool, durationFormatTool };
170
+
171
+ //# sourceMappingURL=datetime_math.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datetime_math.mjs","names":[],"sources":["../../../src/batteries/tools/datetime_math/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for ISO datetime arithmetic, differences, and timezone-aware formatting.\n *\n * @module @nhtio/adk/batteries/tools/datetime_math\n *\n * @remarks\n * Pre-constructed bundled tools for the `datetime_math` 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 { DateTime, Duration, IANAZone } from 'luxon'\n\nfunction resolveZone(timezone: string | undefined): { zone: string; error?: string } {\n if (!timezone) return { zone: 'UTC' }\n if (!IANAZone.isValidZone(timezone)) return { zone: '', error: `Invalid timezone \"${timezone}\".` }\n return { zone: timezone }\n}\n\nfunction parseDate(input: string, zone: string): DateTime | { error: string } {\n if (input.toLowerCase() === 'now') return DateTime.now().setZone(zone)\n const dt = DateTime.fromISO(input, { zone })\n if (!dt.isValid)\n return {\n error: `Invalid date \"${input}\". Use ISO 8601 format (e.g. \"2025-06-15\" or \"2025-06-15T14:30:00\") or \"now\".`,\n }\n return dt\n}\n\n/**\n * Add or subtract a duration from a date/time.\n *\n * @remarks\n * All duration components (years/months/weeks/days/hours/minutes/seconds) are optional and\n * combined into a single Duration. Output formatting includes a time component when the input\n * itself has one or when any sub-day component is non-zero.\n */\nexport const dateAddTool = new Tool({\n name: 'date_add',\n description:\n 'Add or subtract a duration from a date/time. Useful for \"what date is 90 days from now?\" or \"when was 6 months before X?\"',\n inputSchema: validator.object({\n date: validator.string().required().description('ISO 8601 date/datetime string or \"now\"'),\n direction: validator\n .string()\n .valid('add', 'subtract')\n .required()\n .description('\"add\" to move forward in time, \"subtract\" to move backward'),\n years: validator.number().default(0).description('Years component (optional)'),\n months: validator.number().default(0).description('Months component (optional)'),\n weeks: validator.number().default(0).description('Weeks component (optional)'),\n days: validator.number().default(0).description('Days component (optional)'),\n hours: validator.number().default(0).description('Hours component (optional)'),\n minutes: validator.number().default(0).description('Minutes component (optional)'),\n seconds: validator.number().default(0).description('Seconds component (optional)'),\n timezone: validator\n .string()\n .optional()\n .description('IANA timezone for interpreting the date (optional, defaults UTC)'),\n }),\n handler: async (args) => {\n const { date, direction, years, months, weeks, days, hours, minutes, seconds, timezone } =\n args as {\n date: string\n direction: 'add' | 'subtract'\n years: number\n months: number\n weeks: number\n days: number\n hours: number\n minutes: number\n seconds: number\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const parsed = parseDate(date, zone)\n if ('error' in parsed) return `Error: ${parsed.error}`\n\n const durObj = { years, months, weeks, days, hours, minutes, seconds }\n const dur = Duration.fromObject(durObj)\n const result = direction === 'subtract' ? parsed.minus(dur) : parsed.plus(dur)\n\n const inputHasTime = date.includes('T') || date.toLowerCase() === 'now'\n const durationHasTime = durObj.hours !== 0 || durObj.minutes !== 0 || durObj.seconds !== 0\n const showTime = inputHasTime || durationHasTime\n\n const formatted = showTime\n ? result.toFormat(\"cccc, LLLL d, yyyy 'at' h:mm:ss a ZZZZ\")\n : result.toFormat('cccc, LLLL d, yyyy')\n\n const durParts = Object.entries(durObj)\n .filter(([, v]) => v !== 0)\n .map(([k, v]) => `${v} ${k}`)\n .join(', ')\n\n const verb = direction === 'subtract' ? 'Subtracting' : 'Adding'\n const prep = direction === 'subtract' ? 'from' : 'to'\n return `${verb} ${durParts || '0'} ${prep} ${date}: ${formatted}`\n },\n})\n\n/**\n * Calculate the difference between two dates/times in a chosen unit.\n *\n * @remarks\n * Result is signed — positive when `to` is after `from`, negative otherwise — but rendered as\n * `|value| <unit> after/before` for readability. Uses luxon's `diff().as(unit)` which respects\n * calendar arithmetic for months/years.\n */\nexport const dateDiffTool = new Tool({\n name: 'date_diff',\n description:\n 'Calculate the difference between two dates/times in a specified unit. Useful for \"how many days until X?\" or \"how long ago was Y?\"',\n inputSchema: validator.object({\n from: validator.string().required().description('Start date (ISO 8601 or \"now\")'),\n to: validator.string().required().description('End date (ISO 8601 or \"now\")'),\n unit: validator\n .string()\n .valid('years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds')\n .required()\n .description('Unit to express the difference in'),\n timezone: validator\n .string()\n .optional()\n .description('IANA timezone for interpreting dates (optional, defaults UTC)'),\n }),\n handler: async (args) => {\n const { from, to, unit, timezone } = args as {\n from: string\n to: string\n unit: 'years' | 'months' | 'weeks' | 'days' | 'hours' | 'minutes' | 'seconds'\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const fromParsed = parseDate(from, zone)\n if ('error' in fromParsed) return `Error: ${fromParsed.error}`\n\n const toParsed = parseDate(to, zone)\n if ('error' in toParsed) return `Error: ${toParsed.error}`\n\n const diff = toParsed.diff(fromParsed, unit)\n const value = diff.as(unit)\n const rounded = Number.parseFloat(value.toFixed(4))\n const abs = Math.abs(rounded)\n const direction = value >= 0 ? 'after' : 'before'\n\n return `${to} is ${abs} ${unit} ${direction} ${from}`\n },\n})\n\n/**\n * Convert total seconds into a human-readable duration string.\n *\n * @remarks\n * Examples: `3725` → `1 hour, 2 minutes and 5 seconds`. Negative inputs are prefixed with `-`.\n * Zero seconds returns the literal `0 seconds`.\n */\nexport const durationFormatTool = new Tool({\n name: 'duration_format',\n description:\n 'Convert a total number of seconds into a human-readable duration breakdown (e.g. \"2 hours, 15 minutes and 30 seconds\").',\n inputSchema: validator.object({\n seconds: validator.number().required().description('Total number of seconds (may be negative)'),\n }),\n handler: async (args) => {\n const { seconds: totalSeconds } = args as { seconds: number }\n const sign = totalSeconds < 0 ? '-' : ''\n const absSeconds = Math.abs(totalSeconds)\n\n const dur = Duration.fromObject({ seconds: absSeconds }).shiftTo(\n 'years',\n 'months',\n 'weeks',\n 'days',\n 'hours',\n 'minutes',\n 'seconds'\n )\n const obj = dur.toObject()\n\n const units: Array<[keyof typeof obj, string, string]> = [\n ['years', 'year', 'years'],\n ['months', 'month', 'months'],\n ['weeks', 'week', 'weeks'],\n ['days', 'day', 'days'],\n ['hours', 'hour', 'hours'],\n ['minutes', 'minute', 'minutes'],\n ['seconds', 'second', 'seconds'],\n ]\n\n const parts: string[] = []\n for (const [key, singular, plural] of units) {\n const v = Math.floor(obj[key] ?? 0)\n if (v > 0) parts.push(`${v} ${v === 1 ? singular : plural}`)\n }\n\n if (parts.length === 0) return '0 seconds'\n const formatted =\n parts.length === 1\n ? parts[0]\n : parts.slice(0, -1).join(', ') + ' and ' + parts[parts.length - 1]\n return `${sign}${formatted}`\n },\n})\n"],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Pre-constructed tools for common text encodings and decoding operations.
3
+ *
4
+ * @module @nhtio/adk/batteries/tools/encoding
5
+ *
6
+ * @remarks
7
+ * Pre-constructed bundled tools for the `encoding` category. Import individually, the whole
8
+ * category, or import every tool via `@nhtio/adk/batteries`.
9
+ */
10
+ import { Tool } from "../../../common";
11
+ /**
12
+ * Encode or decode text using common schemes: base64, url (percent-encoding), html_entities.
13
+ *
14
+ * @remarks
15
+ * `base64` uses the portable `globalThis.btoa`/`atob` pair so the tool works in browsers, Node,
16
+ * and edge runtimes. Encoding/decoding errors are returned as `Error:` strings rather than
17
+ * thrown so the model can react in-line.
18
+ */
19
+ export declare const encodeTextTool: Tool<import("../../../common").SpooledArtifact>;
20
+ /**
21
+ * Escape or unescape special characters for a target context.
22
+ *
23
+ * @remarks
24
+ * Supports `json_string`, `regex`, `csv_field`, `sql_like`, and `markdown` targets. Returns
25
+ * an error string for unknown targets rather than throwing.
26
+ */
27
+ export declare const textEscapeTool: Tool<import("../../../common").SpooledArtifact>;
28
+ /**
29
+ * Normalize Unicode text or extract code points.
30
+ *
31
+ * @remarks
32
+ * Operations: NFC, NFD, NFKC, NFKD Unicode normalization forms (via `String.prototype.normalize`),
33
+ * `strip_accents` (NFD-decompose, remove combining diacritics, re-compose to NFC), or
34
+ * `code_points` (one `U+HHHH (char)` per line).
35
+ */
36
+ export declare const unicodeNormalizeTool: Tool<import("../../../common").SpooledArtifact>;
@@ -0,0 +1,156 @@
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/encoding/index.ts
9
+ /**
10
+ * Pre-constructed tools for common text encodings and decoding operations.
11
+ *
12
+ * @module @nhtio/adk/batteries/tools/encoding
13
+ *
14
+ * @remarks
15
+ * Pre-constructed bundled tools for the `encoding` category. Import individually, the whole
16
+ * category, or import every tool via `@nhtio/adk/batteries`.
17
+ */
18
+ var utf8ToBase64 = (text) => {
19
+ const bytes = new TextEncoder().encode(text);
20
+ let binary = "";
21
+ for (const byte of bytes) binary += String.fromCharCode(byte);
22
+ return globalThis.btoa(binary);
23
+ };
24
+ var base64ToUtf8 = (b64) => {
25
+ const binary = globalThis.atob(b64);
26
+ const bytes = new Uint8Array(binary.length);
27
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
28
+ return new TextDecoder().decode(bytes);
29
+ };
30
+ /**
31
+ * Encode or decode text using common schemes: base64, url (percent-encoding), html_entities.
32
+ *
33
+ * @remarks
34
+ * `base64` uses the portable `globalThis.btoa`/`atob` pair so the tool works in browsers, Node,
35
+ * and edge runtimes. Encoding/decoding errors are returned as `Error:` strings rather than
36
+ * thrown so the model can react in-line.
37
+ */
38
+ var encodeTextTool = new require_tool.Tool({
39
+ name: "encode_text",
40
+ description: "Encode or decode text using common schemes: base64, url (percent-encoding), html_entities. Specify direction: encode or decode.",
41
+ inputSchema: _nhtio_validation.validator.object({
42
+ text: _nhtio_validation.validator.string().required().description("Text to encode or decode"),
43
+ scheme: _nhtio_validation.validator.string().valid("base64", "url", "html_entities").required().description("Encoding scheme"),
44
+ direction: _nhtio_validation.validator.string().valid("encode", "decode").default("encode").description("Whether to encode or decode (default: encode)")
45
+ }),
46
+ handler: async (args) => {
47
+ const { text, scheme, direction } = args;
48
+ try {
49
+ if (scheme === "base64") {
50
+ if (direction === "encode") return utf8ToBase64(text);
51
+ return base64ToUtf8(text);
52
+ }
53
+ if (scheme === "url") {
54
+ if (direction === "encode") return encodeURIComponent(text);
55
+ return decodeURIComponent(text);
56
+ }
57
+ if (scheme === "html_entities") {
58
+ if (direction === "encode") return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
59
+ return text.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, "\"").replace(/&#39;/g, "'").replace(/&#(\d+);/g, (_, code) => String.fromCharCode(Number.parseInt(code, 10))).replace(/&#x([0-9a-fA-F]+);/g, (_, hex) => String.fromCharCode(Number.parseInt(hex, 16)));
60
+ }
61
+ return `Error: Unknown scheme "${scheme}".`;
62
+ } catch (err) {
63
+ return `Error: ${require_tool_registry.isError(err) ? err.message : String(err)}`;
64
+ }
65
+ }
66
+ });
67
+ /**
68
+ * Escape or unescape special characters for a target context.
69
+ *
70
+ * @remarks
71
+ * Supports `json_string`, `regex`, `csv_field`, `sql_like`, and `markdown` targets. Returns
72
+ * an error string for unknown targets rather than throwing.
73
+ */
74
+ var textEscapeTool = new require_tool.Tool({
75
+ name: "text_escape",
76
+ description: "Escape or unescape special characters for a target context: json_string, regex, csv_field, sql_like, markdown.",
77
+ inputSchema: _nhtio_validation.validator.object({
78
+ text: _nhtio_validation.validator.string().required().description("Text to escape or unescape"),
79
+ target: _nhtio_validation.validator.string().valid("json_string", "regex", "csv_field", "sql_like", "markdown").required().description("Target context for escaping"),
80
+ direction: _nhtio_validation.validator.string().valid("escape", "unescape").default("escape").description("Whether to escape or unescape (default: escape)")
81
+ }),
82
+ handler: async (args) => {
83
+ const { text, target, direction } = args;
84
+ try {
85
+ if (target === "json_string") {
86
+ if (direction === "escape") return JSON.stringify(text).slice(1, -1);
87
+ return JSON.parse(`"${text}"`);
88
+ }
89
+ if (target === "regex") {
90
+ if (direction === "escape") return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
91
+ return text.replace(/\\([.*+?^${}()|[\]\\])/g, "$1");
92
+ }
93
+ if (target === "csv_field") {
94
+ if (direction === "escape") {
95
+ if (/[,"\n\r]/.test(text)) return `"${text.replace(/"/g, "\"\"")}"`;
96
+ return text;
97
+ }
98
+ if (text.startsWith("\"") && text.endsWith("\"")) return text.slice(1, -1).replace(/""/g, "\"");
99
+ return text;
100
+ }
101
+ if (target === "sql_like") {
102
+ if (direction === "escape") return text.replace(/[%_\\]/g, "\\$&");
103
+ return text.replace(/\\([%_\\])/g, "$1");
104
+ }
105
+ if (target === "markdown") {
106
+ const mdChars = /[\\`*_{}[\]()#+\-.!|]/g;
107
+ if (direction === "escape") return text.replace(mdChars, "\\$&");
108
+ return text.replace(/\\([\\`*_{}[\]()#+\-.!|])/g, "$1");
109
+ }
110
+ return `Error: Unknown target "${target}".`;
111
+ } catch (err) {
112
+ return `Error: ${require_tool_registry.isError(err) ? err.message : String(err)}`;
113
+ }
114
+ }
115
+ });
116
+ /**
117
+ * Normalize Unicode text or extract code points.
118
+ *
119
+ * @remarks
120
+ * Operations: NFC, NFD, NFKC, NFKD Unicode normalization forms (via `String.prototype.normalize`),
121
+ * `strip_accents` (NFD-decompose, remove combining diacritics, re-compose to NFC), or
122
+ * `code_points` (one `U+HHHH (char)` per line).
123
+ */
124
+ var unicodeNormalizeTool = new require_tool.Tool({
125
+ name: "unicode_normalize",
126
+ description: "Normalize Unicode text (NFC, NFD, NFKC, NFKD), strip accents/diacritics, or get Unicode code points for each character.",
127
+ inputSchema: _nhtio_validation.validator.object({
128
+ text: _nhtio_validation.validator.string().required().description("Text to process"),
129
+ operation: _nhtio_validation.validator.string().valid("nfc", "nfd", "nfkc", "nfkd", "strip_accents", "code_points").required().description("Operation: NFC/NFD/NFKC/NFKD normalization, strip_accents (remove diacritics), or code_points (list hex values)")
130
+ }),
131
+ handler: async (args) => {
132
+ const { text, operation } = args;
133
+ try {
134
+ if (operation === "strip_accents") return text.normalize("NFD").replace(/[̀-ͯ]/g, "").normalize("NFC");
135
+ if (operation === "code_points") return [...text].map((ch) => {
136
+ return `U+${ch.codePointAt(0).toString(16).toUpperCase().padStart(4, "0")} (${ch})`;
137
+ }).join("\n");
138
+ const form = {
139
+ nfc: "NFC",
140
+ nfd: "NFD",
141
+ nfkc: "NFKC",
142
+ nfkd: "NFKD"
143
+ }[operation];
144
+ if (!form) return `Error: Unknown operation "${operation}".`;
145
+ return text.normalize(form);
146
+ } catch (err) {
147
+ return `Error: ${require_tool_registry.isError(err) ? err.message : String(err)}`;
148
+ }
149
+ }
150
+ });
151
+ //#endregion
152
+ exports.encodeTextTool = encodeTextTool;
153
+ exports.textEscapeTool = textEscapeTool;
154
+ exports.unicodeNormalizeTool = unicodeNormalizeTool;
155
+
156
+ //# sourceMappingURL=encoding.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoding.cjs","names":[],"sources":["../../../src/batteries/tools/encoding/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for common text encodings and decoding operations.\n *\n * @module @nhtio/adk/batteries/tools/encoding\n *\n * @remarks\n * Pre-constructed bundled tools for the `encoding` 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\nconst utf8ToBase64 = (text: string): string => {\n const bytes = new TextEncoder().encode(text)\n let binary = ''\n for (const byte of bytes) binary += String.fromCharCode(byte)\n return globalThis.btoa(binary)\n}\n\nconst base64ToUtf8 = (b64: string): string => {\n const binary = globalThis.atob(b64)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n return new TextDecoder().decode(bytes)\n}\n\n/**\n * Encode or decode text using common schemes: base64, url (percent-encoding), html_entities.\n *\n * @remarks\n * `base64` uses the portable `globalThis.btoa`/`atob` pair so the tool works in browsers, Node,\n * and edge runtimes. Encoding/decoding errors are returned as `Error:` strings rather than\n * thrown so the model can react in-line.\n */\nexport const encodeTextTool = new Tool({\n name: 'encode_text',\n description:\n 'Encode or decode text using common schemes: base64, url (percent-encoding), html_entities. Specify direction: encode or decode.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to encode or decode'),\n scheme: validator\n .string()\n .valid('base64', 'url', 'html_entities')\n .required()\n .description('Encoding scheme'),\n direction: validator\n .string()\n .valid('encode', 'decode')\n .default('encode')\n .description('Whether to encode or decode (default: encode)'),\n }),\n handler: async (args) => {\n const { text, scheme, direction } = args as {\n text: string\n scheme: string\n direction: string\n }\n\n try {\n if (scheme === 'base64') {\n if (direction === 'encode') return utf8ToBase64(text)\n return base64ToUtf8(text)\n }\n\n if (scheme === 'url') {\n if (direction === 'encode') return encodeURIComponent(text)\n return decodeURIComponent(text)\n }\n\n if (scheme === 'html_entities') {\n if (direction === 'encode') {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;')\n }\n return text\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/&#(\\d+);/g, (_, code: string) => String.fromCharCode(Number.parseInt(code, 10)))\n .replace(/&#x([0-9a-fA-F]+);/g, (_, hex: string) =>\n String.fromCharCode(Number.parseInt(hex, 16))\n )\n }\n\n return `Error: Unknown scheme \"${scheme}\".`\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Escape or unescape special characters for a target context.\n *\n * @remarks\n * Supports `json_string`, `regex`, `csv_field`, `sql_like`, and `markdown` targets. Returns\n * an error string for unknown targets rather than throwing.\n */\nexport const textEscapeTool = new Tool({\n name: 'text_escape',\n description:\n 'Escape or unescape special characters for a target context: json_string, regex, csv_field, sql_like, markdown.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to escape or unescape'),\n target: validator\n .string()\n .valid('json_string', 'regex', 'csv_field', 'sql_like', 'markdown')\n .required()\n .description('Target context for escaping'),\n direction: validator\n .string()\n .valid('escape', 'unescape')\n .default('escape')\n .description('Whether to escape or unescape (default: escape)'),\n }),\n handler: async (args) => {\n const { text, target, direction } = args as {\n text: string\n target: string\n direction: string\n }\n\n try {\n if (target === 'json_string') {\n if (direction === 'escape') return JSON.stringify(text).slice(1, -1)\n return JSON.parse(`\"${text}\"`) as string\n }\n\n if (target === 'regex') {\n if (direction === 'escape') return text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n return text.replace(/\\\\([.*+?^${}()|[\\]\\\\])/g, '$1')\n }\n\n if (target === 'csv_field') {\n if (direction === 'escape') {\n if (/[,\"\\n\\r]/.test(text)) return `\"${text.replace(/\"/g, '\"\"')}\"`\n return text\n }\n if (text.startsWith('\"') && text.endsWith('\"')) {\n return text.slice(1, -1).replace(/\"\"/g, '\"')\n }\n return text\n }\n\n if (target === 'sql_like') {\n if (direction === 'escape') return text.replace(/[%_\\\\]/g, '\\\\$&')\n return text.replace(/\\\\([%_\\\\])/g, '$1')\n }\n\n if (target === 'markdown') {\n const mdChars = /[\\\\`*_{}[\\]()#+\\-.!|]/g\n if (direction === 'escape') return text.replace(mdChars, '\\\\$&')\n return text.replace(/\\\\([\\\\`*_{}[\\]()#+\\-.!|])/g, '$1')\n }\n\n return `Error: Unknown target \"${target}\".`\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Normalize Unicode text or extract code points.\n *\n * @remarks\n * Operations: NFC, NFD, NFKC, NFKD Unicode normalization forms (via `String.prototype.normalize`),\n * `strip_accents` (NFD-decompose, remove combining diacritics, re-compose to NFC), or\n * `code_points` (one `U+HHHH (char)` per line).\n */\nexport const unicodeNormalizeTool = new Tool({\n name: 'unicode_normalize',\n description:\n 'Normalize Unicode text (NFC, NFD, NFKC, NFKD), strip accents/diacritics, or get Unicode code points for each character.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to process'),\n operation: validator\n .string()\n .valid('nfc', 'nfd', 'nfkc', 'nfkd', 'strip_accents', 'code_points')\n .required()\n .description(\n 'Operation: NFC/NFD/NFKC/NFKD normalization, strip_accents (remove diacritics), or code_points (list hex values)'\n ),\n }),\n handler: async (args) => {\n const { text, operation } = args as { text: string; operation: string }\n\n try {\n if (operation === 'strip_accents') {\n return text.normalize('NFD').replace(/[̀-ͯ]/g, '').normalize('NFC')\n }\n\n if (operation === 'code_points') {\n return [...text]\n .map((ch) => {\n const cp = ch.codePointAt(0)!\n const hex = cp.toString(16).toUpperCase().padStart(4, '0')\n return `U+${hex} (${ch})`\n })\n .join('\\n')\n }\n\n const formMap: Record<string, string> = { nfc: 'NFC', nfd: 'NFD', nfkc: 'NFKC', nfkd: 'NFKD' }\n const form = formMap[operation]\n if (!form) return `Error: Unknown operation \"${operation}\".`\n return text.normalize(form)\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n"],"mappings":"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"}
@@ -0,0 +1,152 @@
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
+ //#region src/batteries/tools/encoding/index.ts
7
+ /**
8
+ * Pre-constructed tools for common text encodings and decoding operations.
9
+ *
10
+ * @module @nhtio/adk/batteries/tools/encoding
11
+ *
12
+ * @remarks
13
+ * Pre-constructed bundled tools for the `encoding` category. Import individually, the whole
14
+ * category, or import every tool via `@nhtio/adk/batteries`.
15
+ */
16
+ var utf8ToBase64 = (text) => {
17
+ const bytes = new TextEncoder().encode(text);
18
+ let binary = "";
19
+ for (const byte of bytes) binary += String.fromCharCode(byte);
20
+ return globalThis.btoa(binary);
21
+ };
22
+ var base64ToUtf8 = (b64) => {
23
+ const binary = globalThis.atob(b64);
24
+ const bytes = new Uint8Array(binary.length);
25
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
26
+ return new TextDecoder().decode(bytes);
27
+ };
28
+ /**
29
+ * Encode or decode text using common schemes: base64, url (percent-encoding), html_entities.
30
+ *
31
+ * @remarks
32
+ * `base64` uses the portable `globalThis.btoa`/`atob` pair so the tool works in browsers, Node,
33
+ * and edge runtimes. Encoding/decoding errors are returned as `Error:` strings rather than
34
+ * thrown so the model can react in-line.
35
+ */
36
+ var encodeTextTool = new Tool({
37
+ name: "encode_text",
38
+ description: "Encode or decode text using common schemes: base64, url (percent-encoding), html_entities. Specify direction: encode or decode.",
39
+ inputSchema: validator.object({
40
+ text: validator.string().required().description("Text to encode or decode"),
41
+ scheme: validator.string().valid("base64", "url", "html_entities").required().description("Encoding scheme"),
42
+ direction: validator.string().valid("encode", "decode").default("encode").description("Whether to encode or decode (default: encode)")
43
+ }),
44
+ handler: async (args) => {
45
+ const { text, scheme, direction } = args;
46
+ try {
47
+ if (scheme === "base64") {
48
+ if (direction === "encode") return utf8ToBase64(text);
49
+ return base64ToUtf8(text);
50
+ }
51
+ if (scheme === "url") {
52
+ if (direction === "encode") return encodeURIComponent(text);
53
+ return decodeURIComponent(text);
54
+ }
55
+ if (scheme === "html_entities") {
56
+ if (direction === "encode") return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
57
+ return text.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, "\"").replace(/&#39;/g, "'").replace(/&#(\d+);/g, (_, code) => String.fromCharCode(Number.parseInt(code, 10))).replace(/&#x([0-9a-fA-F]+);/g, (_, hex) => String.fromCharCode(Number.parseInt(hex, 16)));
58
+ }
59
+ return `Error: Unknown scheme "${scheme}".`;
60
+ } catch (err) {
61
+ return `Error: ${isError(err) ? err.message : String(err)}`;
62
+ }
63
+ }
64
+ });
65
+ /**
66
+ * Escape or unescape special characters for a target context.
67
+ *
68
+ * @remarks
69
+ * Supports `json_string`, `regex`, `csv_field`, `sql_like`, and `markdown` targets. Returns
70
+ * an error string for unknown targets rather than throwing.
71
+ */
72
+ var textEscapeTool = new Tool({
73
+ name: "text_escape",
74
+ description: "Escape or unescape special characters for a target context: json_string, regex, csv_field, sql_like, markdown.",
75
+ inputSchema: validator.object({
76
+ text: validator.string().required().description("Text to escape or unescape"),
77
+ target: validator.string().valid("json_string", "regex", "csv_field", "sql_like", "markdown").required().description("Target context for escaping"),
78
+ direction: validator.string().valid("escape", "unescape").default("escape").description("Whether to escape or unescape (default: escape)")
79
+ }),
80
+ handler: async (args) => {
81
+ const { text, target, direction } = args;
82
+ try {
83
+ if (target === "json_string") {
84
+ if (direction === "escape") return JSON.stringify(text).slice(1, -1);
85
+ return JSON.parse(`"${text}"`);
86
+ }
87
+ if (target === "regex") {
88
+ if (direction === "escape") return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
89
+ return text.replace(/\\([.*+?^${}()|[\]\\])/g, "$1");
90
+ }
91
+ if (target === "csv_field") {
92
+ if (direction === "escape") {
93
+ if (/[,"\n\r]/.test(text)) return `"${text.replace(/"/g, "\"\"")}"`;
94
+ return text;
95
+ }
96
+ if (text.startsWith("\"") && text.endsWith("\"")) return text.slice(1, -1).replace(/""/g, "\"");
97
+ return text;
98
+ }
99
+ if (target === "sql_like") {
100
+ if (direction === "escape") return text.replace(/[%_\\]/g, "\\$&");
101
+ return text.replace(/\\([%_\\])/g, "$1");
102
+ }
103
+ if (target === "markdown") {
104
+ const mdChars = /[\\`*_{}[\]()#+\-.!|]/g;
105
+ if (direction === "escape") return text.replace(mdChars, "\\$&");
106
+ return text.replace(/\\([\\`*_{}[\]()#+\-.!|])/g, "$1");
107
+ }
108
+ return `Error: Unknown target "${target}".`;
109
+ } catch (err) {
110
+ return `Error: ${isError(err) ? err.message : String(err)}`;
111
+ }
112
+ }
113
+ });
114
+ /**
115
+ * Normalize Unicode text or extract code points.
116
+ *
117
+ * @remarks
118
+ * Operations: NFC, NFD, NFKC, NFKD Unicode normalization forms (via `String.prototype.normalize`),
119
+ * `strip_accents` (NFD-decompose, remove combining diacritics, re-compose to NFC), or
120
+ * `code_points` (one `U+HHHH (char)` per line).
121
+ */
122
+ var unicodeNormalizeTool = new Tool({
123
+ name: "unicode_normalize",
124
+ description: "Normalize Unicode text (NFC, NFD, NFKC, NFKD), strip accents/diacritics, or get Unicode code points for each character.",
125
+ inputSchema: validator.object({
126
+ text: validator.string().required().description("Text to process"),
127
+ operation: validator.string().valid("nfc", "nfd", "nfkc", "nfkd", "strip_accents", "code_points").required().description("Operation: NFC/NFD/NFKC/NFKD normalization, strip_accents (remove diacritics), or code_points (list hex values)")
128
+ }),
129
+ handler: async (args) => {
130
+ const { text, operation } = args;
131
+ try {
132
+ if (operation === "strip_accents") return text.normalize("NFD").replace(/[̀-ͯ]/g, "").normalize("NFC");
133
+ if (operation === "code_points") return [...text].map((ch) => {
134
+ return `U+${ch.codePointAt(0).toString(16).toUpperCase().padStart(4, "0")} (${ch})`;
135
+ }).join("\n");
136
+ const form = {
137
+ nfc: "NFC",
138
+ nfd: "NFD",
139
+ nfkc: "NFKC",
140
+ nfkd: "NFKD"
141
+ }[operation];
142
+ if (!form) return `Error: Unknown operation "${operation}".`;
143
+ return text.normalize(form);
144
+ } catch (err) {
145
+ return `Error: ${isError(err) ? err.message : String(err)}`;
146
+ }
147
+ }
148
+ });
149
+ //#endregion
150
+ export { encodeTextTool, textEscapeTool, unicodeNormalizeTool };
151
+
152
+ //# sourceMappingURL=encoding.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoding.mjs","names":[],"sources":["../../../src/batteries/tools/encoding/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for common text encodings and decoding operations.\n *\n * @module @nhtio/adk/batteries/tools/encoding\n *\n * @remarks\n * Pre-constructed bundled tools for the `encoding` 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\nconst utf8ToBase64 = (text: string): string => {\n const bytes = new TextEncoder().encode(text)\n let binary = ''\n for (const byte of bytes) binary += String.fromCharCode(byte)\n return globalThis.btoa(binary)\n}\n\nconst base64ToUtf8 = (b64: string): string => {\n const binary = globalThis.atob(b64)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n return new TextDecoder().decode(bytes)\n}\n\n/**\n * Encode or decode text using common schemes: base64, url (percent-encoding), html_entities.\n *\n * @remarks\n * `base64` uses the portable `globalThis.btoa`/`atob` pair so the tool works in browsers, Node,\n * and edge runtimes. Encoding/decoding errors are returned as `Error:` strings rather than\n * thrown so the model can react in-line.\n */\nexport const encodeTextTool = new Tool({\n name: 'encode_text',\n description:\n 'Encode or decode text using common schemes: base64, url (percent-encoding), html_entities. Specify direction: encode or decode.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to encode or decode'),\n scheme: validator\n .string()\n .valid('base64', 'url', 'html_entities')\n .required()\n .description('Encoding scheme'),\n direction: validator\n .string()\n .valid('encode', 'decode')\n .default('encode')\n .description('Whether to encode or decode (default: encode)'),\n }),\n handler: async (args) => {\n const { text, scheme, direction } = args as {\n text: string\n scheme: string\n direction: string\n }\n\n try {\n if (scheme === 'base64') {\n if (direction === 'encode') return utf8ToBase64(text)\n return base64ToUtf8(text)\n }\n\n if (scheme === 'url') {\n if (direction === 'encode') return encodeURIComponent(text)\n return decodeURIComponent(text)\n }\n\n if (scheme === 'html_entities') {\n if (direction === 'encode') {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;')\n }\n return text\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/&#(\\d+);/g, (_, code: string) => String.fromCharCode(Number.parseInt(code, 10)))\n .replace(/&#x([0-9a-fA-F]+);/g, (_, hex: string) =>\n String.fromCharCode(Number.parseInt(hex, 16))\n )\n }\n\n return `Error: Unknown scheme \"${scheme}\".`\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Escape or unescape special characters for a target context.\n *\n * @remarks\n * Supports `json_string`, `regex`, `csv_field`, `sql_like`, and `markdown` targets. Returns\n * an error string for unknown targets rather than throwing.\n */\nexport const textEscapeTool = new Tool({\n name: 'text_escape',\n description:\n 'Escape or unescape special characters for a target context: json_string, regex, csv_field, sql_like, markdown.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to escape or unescape'),\n target: validator\n .string()\n .valid('json_string', 'regex', 'csv_field', 'sql_like', 'markdown')\n .required()\n .description('Target context for escaping'),\n direction: validator\n .string()\n .valid('escape', 'unescape')\n .default('escape')\n .description('Whether to escape or unescape (default: escape)'),\n }),\n handler: async (args) => {\n const { text, target, direction } = args as {\n text: string\n target: string\n direction: string\n }\n\n try {\n if (target === 'json_string') {\n if (direction === 'escape') return JSON.stringify(text).slice(1, -1)\n return JSON.parse(`\"${text}\"`) as string\n }\n\n if (target === 'regex') {\n if (direction === 'escape') return text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n return text.replace(/\\\\([.*+?^${}()|[\\]\\\\])/g, '$1')\n }\n\n if (target === 'csv_field') {\n if (direction === 'escape') {\n if (/[,\"\\n\\r]/.test(text)) return `\"${text.replace(/\"/g, '\"\"')}\"`\n return text\n }\n if (text.startsWith('\"') && text.endsWith('\"')) {\n return text.slice(1, -1).replace(/\"\"/g, '\"')\n }\n return text\n }\n\n if (target === 'sql_like') {\n if (direction === 'escape') return text.replace(/[%_\\\\]/g, '\\\\$&')\n return text.replace(/\\\\([%_\\\\])/g, '$1')\n }\n\n if (target === 'markdown') {\n const mdChars = /[\\\\`*_{}[\\]()#+\\-.!|]/g\n if (direction === 'escape') return text.replace(mdChars, '\\\\$&')\n return text.replace(/\\\\([\\\\`*_{}[\\]()#+\\-.!|])/g, '$1')\n }\n\n return `Error: Unknown target \"${target}\".`\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Normalize Unicode text or extract code points.\n *\n * @remarks\n * Operations: NFC, NFD, NFKC, NFKD Unicode normalization forms (via `String.prototype.normalize`),\n * `strip_accents` (NFD-decompose, remove combining diacritics, re-compose to NFC), or\n * `code_points` (one `U+HHHH (char)` per line).\n */\nexport const unicodeNormalizeTool = new Tool({\n name: 'unicode_normalize',\n description:\n 'Normalize Unicode text (NFC, NFD, NFKC, NFKD), strip accents/diacritics, or get Unicode code points for each character.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to process'),\n operation: validator\n .string()\n .valid('nfc', 'nfd', 'nfkc', 'nfkd', 'strip_accents', 'code_points')\n .required()\n .description(\n 'Operation: NFC/NFD/NFKC/NFKD normalization, strip_accents (remove diacritics), or code_points (list hex values)'\n ),\n }),\n handler: async (args) => {\n const { text, operation } = args as { text: string; operation: string }\n\n try {\n if (operation === 'strip_accents') {\n return text.normalize('NFD').replace(/[̀-ͯ]/g, '').normalize('NFC')\n }\n\n if (operation === 'code_points') {\n return [...text]\n .map((ch) => {\n const cp = ch.codePointAt(0)!\n const hex = cp.toString(16).toUpperCase().padStart(4, '0')\n return `U+${hex} (${ch})`\n })\n .join('\\n')\n }\n\n const formMap: Record<string, string> = { nfc: 'NFC', nfd: 'NFD', nfkc: 'NFKC', nfkd: 'NFKD' }\n const form = formMap[operation]\n if (!form) return `Error: Unknown operation \"${operation}\".`\n return text.normalize(form)\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n"],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Pre-constructed tools for locale-aware number, list, table, and text formatting.
3
+ *
4
+ * @module @nhtio/adk/batteries/tools/formatting
5
+ *
6
+ * @remarks
7
+ * Pre-constructed bundled tools for the `formatting` category. Import individually, the whole
8
+ * category, or import every tool via `@nhtio/adk/batteries`.
9
+ */
10
+ import { Tool } from "../../../common";
11
+ /**
12
+ * Format a number using locale-aware styles.
13
+ *
14
+ * @remarks
15
+ * Supported styles: `decimal`, `currency`, `percent`, `compact` (e.g. `1.2K`), `scientific`
16
+ * (e.g. `1.2e+3`), and `ordinal` (`1st`, `2nd`, `3rd`). Uses `Intl.NumberFormat` and
17
+ * `Intl.PluralRules` from the JS standard library. Returns an error string for non-finite values
18
+ * or invalid currency-without-currency-code.
19
+ */
20
+ export declare const formatNumberTool: Tool<import("../../../common").SpooledArtifact>;
21
+ /**
22
+ * Format an array of items as a list.
23
+ *
24
+ * @remarks
25
+ * Supported styles: `bullet` (`• item`), `numbered` (`1. item`), `inline_and`
26
+ * (`a, b, and c`), `inline_or` (`a, b, or c`), `newline` (one per line).
27
+ */
28
+ export declare const formatListTool: Tool<import("../../../common").SpooledArtifact>;