@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,51 @@
1
+ /**
2
+ * Pre-constructed tools for parsing natural-language dates and business-calendar calculations.
3
+ *
4
+ * @module @nhtio/adk/batteries/tools/datetime_extended
5
+ *
6
+ * @remarks
7
+ * Pre-constructed bundled tools for the `datetime_extended` category. Import individually, the whole
8
+ * category, or import every tool via `@nhtio/adk/batteries`.
9
+ */
10
+ import { Tool } from "../../../common";
11
+ /**
12
+ * Find the Nth occurrence of a weekday in a given month.
13
+ *
14
+ * @remarks
15
+ * Examples: "2nd Friday of March 2026", "last Monday of January 2025". Accepts 1st–5th and
16
+ * `last`. Returns an error if the month does not contain that many occurrences of the weekday.
17
+ */
18
+ export declare const dateNthWeekdayTool: Tool<import("../../../common").SpooledArtifact>;
19
+ /**
20
+ * Get calendar metadata for a date.
21
+ *
22
+ * @remarks
23
+ * Reports ISO week number, day of year, calendar quarter, fiscal quarter/year (configurable via
24
+ * `fiscal_year_start_month`), week of month, and whether the date is a weekend. Accepts ISO
25
+ * dates, natural-language ("next Tuesday"), and `now`.
26
+ */
27
+ export declare const dateCalendarInfoTool: Tool<import("../../../common").SpooledArtifact>;
28
+ /**
29
+ * Parse a date/time expression from natural language or common formats.
30
+ *
31
+ * @remarks
32
+ * Examples: `"next Monday"`, `"March 5th"`, `"in 2 weeks"`, `"yesterday"`. Uses chrono-node for
33
+ * relative parsing. `reference_date` overrides the "now" anchor.
34
+ */
35
+ export declare const dateParseTool: Tool<import("../../../common").SpooledArtifact>;
36
+ /**
37
+ * Get the start or end of a time period containing a given date.
38
+ *
39
+ * @remarks
40
+ * Periods: `day`, `week`, `isoweek` (Monday-start), `month`, `quarter`, `year`. Quarter and year
41
+ * honour `fiscal_year_start_month` for fiscal calendars (default: 1 = calendar year).
42
+ */
43
+ export declare const datePeriodTool: Tool<import("../../../common").SpooledArtifact>;
44
+ /**
45
+ * Count business days between two dates, or compute the date N business days away.
46
+ *
47
+ * @remarks
48
+ * Monday–Friday only; no holiday calendar awareness. Provide either `to` (count between) or
49
+ * `add_days` (compute target date). Negative `add_days` walks backwards.
50
+ */
51
+ export declare const dateBusinessDaysTool: Tool<import("../../../common").SpooledArtifact>;
@@ -0,0 +1,309 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_chunk = require("../../chunk-KmRHZBOW.js");
3
+ require("../../common-Od8edUXU.js");
4
+ const require_tool = require("../../tool-COSeH8I6.js");
5
+ let _nhtio_validation = require("@nhtio/validation");
6
+ let luxon = require("luxon");
7
+ let chrono_node = require("chrono-node");
8
+ chrono_node = require_chunk.__toESM(chrono_node);
9
+ //#region src/batteries/tools/datetime_extended/index.ts
10
+ /**
11
+ * Pre-constructed tools for parsing natural-language dates and business-calendar calculations.
12
+ *
13
+ * @module @nhtio/adk/batteries/tools/datetime_extended
14
+ *
15
+ * @remarks
16
+ * Pre-constructed bundled tools for the `datetime_extended` category. Import individually, the whole
17
+ * category, or import every tool via `@nhtio/adk/batteries`.
18
+ */
19
+ function resolveZone(timezone) {
20
+ if (!timezone) return { zone: "UTC" };
21
+ if (!luxon.IANAZone.isValidZone(timezone)) return {
22
+ zone: "",
23
+ error: `Invalid timezone "${timezone}".`
24
+ };
25
+ return { zone: timezone };
26
+ }
27
+ function countBusinessDays(from, to) {
28
+ const forward = to >= from;
29
+ const start = forward ? from.startOf("day") : to.startOf("day");
30
+ const end = forward ? to.startOf("day") : from.startOf("day");
31
+ const totalDays = Math.round(end.diff(start, "days").days);
32
+ const fullWeeks = Math.floor(totalDays / 7);
33
+ let bdays = fullWeeks * 5;
34
+ let cursor = start.plus({ days: fullWeeks * 7 });
35
+ while (cursor < end) {
36
+ cursor = cursor.plus({ days: 1 });
37
+ if (cursor.weekday <= 5) bdays++;
38
+ }
39
+ return forward ? bdays : -bdays;
40
+ }
41
+ /**
42
+ * Find the Nth occurrence of a weekday in a given month.
43
+ *
44
+ * @remarks
45
+ * Examples: "2nd Friday of March 2026", "last Monday of January 2025". Accepts 1st–5th and
46
+ * `last`. Returns an error if the month does not contain that many occurrences of the weekday.
47
+ */
48
+ var dateNthWeekdayTool = new require_tool.Tool({
49
+ name: "date_nth_weekday",
50
+ description: "Find the Nth occurrence of a weekday in a given month (e.g., \"2nd Friday of March 2026\", \"last Monday of next month\"). Supports 1st–5th and \"last\".",
51
+ inputSchema: _nhtio_validation.validator.object({
52
+ nth: _nhtio_validation.validator.string().required().description("Which occurrence: \"1st\", \"2nd\", \"3rd\", \"4th\", \"5th\", or \"last\"."),
53
+ weekday: _nhtio_validation.validator.string().valid("monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday").required().description("Day of the week."),
54
+ month: _nhtio_validation.validator.number().required().description("Month number (1–12)."),
55
+ year: _nhtio_validation.validator.number().optional().description("Year (defaults to current year)."),
56
+ timezone: _nhtio_validation.validator.string().optional().description("IANA timezone (optional, defaults UTC).")
57
+ }),
58
+ handler: async (args) => {
59
+ const { nth, weekday, month: rawMonth, year: rawYear, timezone } = args;
60
+ const { zone, error: zoneError } = resolveZone(timezone);
61
+ if (zoneError) return `Error: ${zoneError}`;
62
+ const targetWeekday = {
63
+ monday: 1,
64
+ tuesday: 2,
65
+ wednesday: 3,
66
+ thursday: 4,
67
+ friday: 5,
68
+ saturday: 6,
69
+ sunday: 7
70
+ }[weekday.toLowerCase()];
71
+ const month = Math.floor(rawMonth);
72
+ if (month < 1 || month > 12) return `Error: Month must be 1–12, got ${rawMonth}.`;
73
+ const year = Math.floor(rawYear ?? luxon.DateTime.now().setZone(zone).year);
74
+ const nthRaw = nth.toLowerCase().replace(/\s/g, "");
75
+ const firstOfMonth = luxon.DateTime.fromObject({
76
+ year,
77
+ month,
78
+ day: 1
79
+ }, { zone });
80
+ if (!firstOfMonth.isValid) return `Error: Invalid date for ${year}-${month}.`;
81
+ const occurrences = [];
82
+ let cursor = firstOfMonth;
83
+ while (cursor.weekday !== targetWeekday) cursor = cursor.plus({ days: 1 });
84
+ while (cursor.month === month) {
85
+ occurrences.push(cursor);
86
+ cursor = cursor.plus({ weeks: 1 });
87
+ }
88
+ let result;
89
+ if (nthRaw === "last") result = occurrences[occurrences.length - 1];
90
+ else {
91
+ const n = {
92
+ "1st": 1,
93
+ "1": 1,
94
+ "first": 1,
95
+ "2nd": 2,
96
+ "2": 2,
97
+ "second": 2,
98
+ "3rd": 3,
99
+ "3": 3,
100
+ "third": 3,
101
+ "4th": 4,
102
+ "4": 4,
103
+ "fourth": 4,
104
+ "5th": 5,
105
+ "5": 5,
106
+ "fifth": 5
107
+ }[nthRaw];
108
+ if (!n) return `Error: Invalid nth value "${nth}". Use 1st–5th or "last".`;
109
+ if (n > occurrences.length) return `Error: There is no ${nth} ${weekday} in ${firstOfMonth.toFormat("LLLL yyyy")} (only ${occurrences.length} occurrence${occurrences.length !== 1 ? "s" : ""}).`;
110
+ result = occurrences[n - 1];
111
+ }
112
+ if (!result) return "Error: Could not compute the date.";
113
+ return `${nth} ${weekday} of ${result.toFormat("LLLL yyyy")}: ${result.toISODate()}\nFormatted: ${result.toFormat("cccc, LLLL d, yyyy")}`;
114
+ }
115
+ });
116
+ /**
117
+ * Get calendar metadata for a date.
118
+ *
119
+ * @remarks
120
+ * Reports ISO week number, day of year, calendar quarter, fiscal quarter/year (configurable via
121
+ * `fiscal_year_start_month`), week of month, and whether the date is a weekend. Accepts ISO
122
+ * dates, natural-language ("next Tuesday"), and `now`.
123
+ */
124
+ var dateCalendarInfoTool = new require_tool.Tool({
125
+ name: "date_calendar_info",
126
+ description: "Get calendar metadata for a date: ISO week number, day of year, calendar quarter, fiscal quarter/year, week of month, and whether it is a weekend or weekday.",
127
+ inputSchema: _nhtio_validation.validator.object({
128
+ date: _nhtio_validation.validator.string().required().description("ISO 8601 date, natural language date, or \"now\"."),
129
+ timezone: _nhtio_validation.validator.string().optional().description("IANA timezone (optional, defaults UTC)."),
130
+ fiscal_year_start_month: _nhtio_validation.validator.number().default(1).description("Month when fiscal year starts (1–12, default: 1 = calendar year).")
131
+ }),
132
+ handler: async (args) => {
133
+ const { date: dateStr, timezone, fiscal_year_start_month: rawFyStart } = args;
134
+ const { zone, error: zoneError } = resolveZone(timezone);
135
+ if (zoneError) return `Error: ${zoneError}`;
136
+ let dt;
137
+ if (dateStr.toLowerCase() === "now") dt = luxon.DateTime.now().setZone(zone);
138
+ else {
139
+ dt = luxon.DateTime.fromISO(dateStr, { zone });
140
+ if (!dt.isValid) {
141
+ const parsed = chrono_node.parseDate(dateStr, /* @__PURE__ */ new Date());
142
+ if (!parsed) return `Error: Could not parse date "${dateStr}".`;
143
+ dt = luxon.DateTime.fromJSDate(parsed).setZone(zone);
144
+ }
145
+ }
146
+ const fyStart = Math.max(1, Math.min(12, Math.floor(rawFyStart)));
147
+ const calendarQuarter = Math.ceil(dt.month / 3);
148
+ const monthInFY = (dt.month - fyStart + 12) % 12;
149
+ const fiscalQuarter = Math.floor(monthInFY / 3) + 1;
150
+ const fiscalYear = dt.month >= fyStart ? dt.year : dt.year - 1;
151
+ const firstOfMonth = dt.startOf("month");
152
+ const weekOfMonth = Math.ceil((dt.day + firstOfMonth.weekday - 1) / 7);
153
+ const dayOfYear = Math.floor(dt.diff(dt.startOf("year"), "days").days) + 1;
154
+ const isWeekend = dt.weekday >= 6;
155
+ return [
156
+ `Date: ${dt.toISODate()} (${dt.toFormat("cccc, LLLL d, yyyy")})`,
157
+ "",
158
+ `ISO week number: ${dt.weekNumber} (ISO year: ${dt.weekYear})`,
159
+ `Day of year: ${dayOfYear} / ${dt.daysInYear}`,
160
+ `Day of week: ${dt.weekday} (${dt.toFormat("cccc")})`,
161
+ `Week of month: ${weekOfMonth}`,
162
+ `Weekend: ${isWeekend ? "Yes" : "No"}`,
163
+ "",
164
+ `Calendar quarter: Q${calendarQuarter}`,
165
+ `Fiscal quarter: FQ${fiscalQuarter} (FY${fiscalYear}${fyStart !== 1 ? `, starts month ${fyStart}` : ""})`
166
+ ].join("\n");
167
+ }
168
+ });
169
+ /**
170
+ * Parse a date/time expression from natural language or common formats.
171
+ *
172
+ * @remarks
173
+ * Examples: `"next Monday"`, `"March 5th"`, `"in 2 weeks"`, `"yesterday"`. Uses chrono-node for
174
+ * relative parsing. `reference_date` overrides the "now" anchor.
175
+ */
176
+ var dateParseTool = new require_tool.Tool({
177
+ name: "date_parse",
178
+ description: "Parse a date/time string from natural language or common formats (\"next Monday\", \"March 5th\", \"in 2 weeks\", \"yesterday\"). Returns an ISO 8601 date.",
179
+ inputSchema: _nhtio_validation.validator.object({
180
+ text: _nhtio_validation.validator.string().required().description("Date/time expression to parse (natural language or structured)"),
181
+ reference_date: _nhtio_validation.validator.string().optional().description("ISO date to treat as \"now\" for relative expressions (default: current time)"),
182
+ timezone: _nhtio_validation.validator.string().optional().description("IANA timezone for the result (optional, defaults UTC)")
183
+ }),
184
+ handler: async (args) => {
185
+ const { text, reference_date: referenceDate, timezone } = args;
186
+ const { zone, error: zoneError } = resolveZone(timezone);
187
+ if (zoneError) return `Error: ${zoneError}`;
188
+ let refDate = /* @__PURE__ */ new Date();
189
+ if (referenceDate) {
190
+ refDate = new Date(referenceDate);
191
+ if (Number.isNaN(refDate.getTime())) return `Error: Invalid reference_date "${referenceDate}".`;
192
+ }
193
+ const parsed = chrono_node.parseDate(text, refDate);
194
+ if (!parsed) return `Error: Could not parse a date from "${text}".`;
195
+ const dt = luxon.DateTime.fromJSDate(parsed).setZone(zone);
196
+ return `ISO: ${dt.toISO()}\nFormatted: ${dt.toFormat("cccc, LLLL d, yyyy h:mm a ZZZZ")}`;
197
+ }
198
+ });
199
+ /**
200
+ * Get the start or end of a time period containing a given date.
201
+ *
202
+ * @remarks
203
+ * Periods: `day`, `week`, `isoweek` (Monday-start), `month`, `quarter`, `year`. Quarter and year
204
+ * honour `fiscal_year_start_month` for fiscal calendars (default: 1 = calendar year).
205
+ */
206
+ var datePeriodTool = new require_tool.Tool({
207
+ name: "date_period",
208
+ description: "Get the start or end of a time period (day, week, month, quarter, year) containing a given date. Supports fiscal year offsets.",
209
+ inputSchema: _nhtio_validation.validator.object({
210
+ date: _nhtio_validation.validator.string().required().description("ISO 8601 date or \"now\""),
211
+ period: _nhtio_validation.validator.string().valid("day", "week", "isoweek", "month", "quarter", "year").required().description("Time period (isoweek = Monday-start week)"),
212
+ boundary: _nhtio_validation.validator.string().valid("start", "end").required().description("\"start\" for the first moment, \"end\" for the last moment of the period"),
213
+ timezone: _nhtio_validation.validator.string().optional().description("IANA timezone (optional, defaults UTC)"),
214
+ fiscal_year_start_month: _nhtio_validation.validator.number().default(1).description("For quarter/year: month number when the fiscal year starts (1–12, default: 1 = calendar year)")
215
+ }),
216
+ handler: async (args) => {
217
+ const { date: dateStr, period, boundary, timezone, fiscal_year_start_month: rawFyStart } = args;
218
+ const { zone, error: zoneError } = resolveZone(timezone);
219
+ if (zoneError) return `Error: ${zoneError}`;
220
+ const dt = dateStr.toLowerCase() === "now" ? luxon.DateTime.now().setZone(zone) : luxon.DateTime.fromISO(dateStr, { zone });
221
+ if (!dt.isValid) return `Error: Invalid date "${dateStr}".`;
222
+ const fyStart = Math.max(1, Math.min(12, Math.floor(rawFyStart)));
223
+ let result;
224
+ switch (period) {
225
+ case "day":
226
+ result = boundary === "start" ? dt.startOf("day") : dt.endOf("day");
227
+ break;
228
+ case "week":
229
+ result = boundary === "start" ? dt.startOf("week") : dt.endOf("week");
230
+ break;
231
+ case "isoweek":
232
+ result = boundary === "start" ? dt.startOf("week").set({ weekday: 1 }) : dt.startOf("week").set({ weekday: 7 }).endOf("day");
233
+ break;
234
+ case "month":
235
+ result = boundary === "start" ? dt.startOf("month") : dt.endOf("month");
236
+ break;
237
+ case "quarter": {
238
+ const monthInFY = (dt.month - fyStart + 12) % 12;
239
+ const qStartMonth = (Math.floor(monthInFY / 3) * 3 + fyStart - 1) % 12 + 1;
240
+ const qStart = dt.set({
241
+ month: qStartMonth,
242
+ day: 1
243
+ }).startOf("day");
244
+ const adjusted = qStart > dt ? qStart.minus({ months: 3 }) : qStart;
245
+ result = boundary === "start" ? adjusted : adjusted.plus({ months: 3 }).minus({ days: 1 }).endOf("day");
246
+ break;
247
+ }
248
+ case "year":
249
+ if (fyStart === 1) result = boundary === "start" ? dt.startOf("year") : dt.endOf("year");
250
+ else {
251
+ const fyStartThis = dt.set({
252
+ month: fyStart,
253
+ day: 1
254
+ }).startOf("day");
255
+ const fyBase = dt >= fyStartThis ? fyStartThis : fyStartThis.minus({ years: 1 });
256
+ result = boundary === "start" ? fyBase : fyBase.plus({ years: 1 }).minus({ days: 1 }).endOf("day");
257
+ }
258
+ break;
259
+ }
260
+ return `${boundary === "start" ? "Start" : "End"} of ${period} containing ${dateStr}: ${result.toISO()}\nFormatted: ${result.toFormat("cccc, LLLL d, yyyy h:mm:ss a ZZZZ")}`;
261
+ }
262
+ });
263
+ /**
264
+ * Count business days between two dates, or compute the date N business days away.
265
+ *
266
+ * @remarks
267
+ * Monday–Friday only; no holiday calendar awareness. Provide either `to` (count between) or
268
+ * `add_days` (compute target date). Negative `add_days` walks backwards.
269
+ */
270
+ var dateBusinessDaysTool = new require_tool.Tool({
271
+ name: "date_business_days",
272
+ description: "Count business days (Mon–Fri, no holiday awareness) between two dates, or calculate the date that is N business days from a start date.",
273
+ inputSchema: _nhtio_validation.validator.object({
274
+ from: _nhtio_validation.validator.string().required().description("Start date (ISO 8601 or \"now\")"),
275
+ to: _nhtio_validation.validator.string().optional().description("End date (ISO 8601 or \"now\") — for counting business days between two dates"),
276
+ add_days: _nhtio_validation.validator.number().optional().description("Instead of \"to\": number of business days to add (negative to subtract)"),
277
+ timezone: _nhtio_validation.validator.string().optional().description("IANA timezone (optional, defaults UTC)")
278
+ }),
279
+ handler: async (args) => {
280
+ const { from: fromStr, to: toStr, add_days: addDays, timezone } = args;
281
+ const { zone, error: zoneError } = resolveZone(timezone);
282
+ if (zoneError) return `Error: ${zoneError}`;
283
+ const fromDt = (fromStr.toLowerCase() === "now" ? luxon.DateTime.now() : luxon.DateTime.fromISO(fromStr)).setZone(zone);
284
+ if (!fromDt.isValid) return `Error: Invalid from date "${fromStr}".`;
285
+ if (addDays !== void 0) {
286
+ const n = Math.floor(addDays);
287
+ let cursor = fromDt.startOf("day");
288
+ let remaining = Math.abs(n);
289
+ const dir = n >= 0 ? 1 : -1;
290
+ while (remaining > 0) {
291
+ cursor = cursor.plus({ days: dir });
292
+ if (cursor.weekday <= 5) remaining--;
293
+ }
294
+ return `${n >= 0 ? "+" : ""}${n} business day${Math.abs(n) !== 1 ? "s" : ""} from ${fromStr}: ${cursor.toISODate()}\nFormatted: ${cursor.toFormat("cccc, LLLL d, yyyy")}`;
295
+ }
296
+ if (!toStr) return "Error: Provide either \"to\" date or \"add_days\".";
297
+ const toDt = (toStr.toLowerCase() === "now" ? luxon.DateTime.now() : luxon.DateTime.fromISO(toStr)).setZone(zone);
298
+ if (!toDt.isValid) return `Error: Invalid to date "${toStr}".`;
299
+ return `Business days from ${fromStr} to ${toStr}: ${countBusinessDays(fromDt, toDt)}`;
300
+ }
301
+ });
302
+ //#endregion
303
+ exports.dateBusinessDaysTool = dateBusinessDaysTool;
304
+ exports.dateCalendarInfoTool = dateCalendarInfoTool;
305
+ exports.dateNthWeekdayTool = dateNthWeekdayTool;
306
+ exports.dateParseTool = dateParseTool;
307
+ exports.datePeriodTool = datePeriodTool;
308
+
309
+ //# sourceMappingURL=datetime_extended.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datetime_extended.cjs","names":[],"sources":["../../../src/batteries/tools/datetime_extended/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for parsing natural-language dates and business-calendar calculations.\n *\n * @module @nhtio/adk/batteries/tools/datetime_extended\n *\n * @remarks\n * Pre-constructed bundled tools for the `datetime_extended` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport * as chrono from 'chrono-node'\nimport { Tool } from '@nhtio/adk/common'\nimport { DateTime, IANAZone } from 'luxon'\nimport { validator } from '@nhtio/validation'\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 countBusinessDays(from: DateTime, to: DateTime): number {\n const forward = to >= from\n const start = forward ? from.startOf('day') : to.startOf('day')\n const end = forward ? to.startOf('day') : from.startOf('day')\n\n const totalDays = Math.round(end.diff(start, 'days').days)\n const fullWeeks = Math.floor(totalDays / 7)\n let bdays = fullWeeks * 5\n\n let cursor = start.plus({ days: fullWeeks * 7 })\n while (cursor < end) {\n cursor = cursor.plus({ days: 1 })\n if (cursor.weekday <= 5) bdays++\n }\n\n return forward ? bdays : -bdays\n}\n\n/**\n * Find the Nth occurrence of a weekday in a given month.\n *\n * @remarks\n * Examples: \"2nd Friday of March 2026\", \"last Monday of January 2025\". Accepts 1st–5th and\n * `last`. Returns an error if the month does not contain that many occurrences of the weekday.\n */\nexport const dateNthWeekdayTool = new Tool({\n name: 'date_nth_weekday',\n description:\n 'Find the Nth occurrence of a weekday in a given month (e.g., \"2nd Friday of March 2026\", \"last Monday of next month\"). Supports 1st–5th and \"last\".',\n inputSchema: validator.object({\n nth: validator\n .string()\n .required()\n .description('Which occurrence: \"1st\", \"2nd\", \"3rd\", \"4th\", \"5th\", or \"last\".'),\n weekday: validator\n .string()\n .valid('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday')\n .required()\n .description('Day of the week.'),\n month: validator.number().required().description('Month number (1–12).'),\n year: validator.number().optional().description('Year (defaults to current year).'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC).'),\n }),\n handler: async (args) => {\n const {\n nth,\n weekday,\n month: rawMonth,\n year: rawYear,\n timezone,\n } = args as {\n nth: string\n weekday: string\n month: number\n year?: number\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const weekdayNames: Record<string, number> = {\n monday: 1,\n tuesday: 2,\n wednesday: 3,\n thursday: 4,\n friday: 5,\n saturday: 6,\n sunday: 7,\n }\n\n const targetWeekday = weekdayNames[weekday.toLowerCase()]\n const month = Math.floor(rawMonth)\n if (month < 1 || month > 12) return `Error: Month must be 1–12, got ${rawMonth}.`\n\n const year = Math.floor(rawYear ?? DateTime.now().setZone(zone).year)\n const nthRaw = nth.toLowerCase().replace(/\\s/g, '')\n\n const firstOfMonth = DateTime.fromObject({ year, month, day: 1 }, { zone })\n if (!firstOfMonth.isValid) return `Error: Invalid date for ${year}-${month}.`\n\n const occurrences: DateTime[] = []\n let cursor = firstOfMonth\n while (cursor.weekday !== targetWeekday) {\n cursor = cursor.plus({ days: 1 })\n }\n while (cursor.month === month) {\n occurrences.push(cursor)\n cursor = cursor.plus({ weeks: 1 })\n }\n\n let result: DateTime | undefined\n\n if (nthRaw === 'last') {\n result = occurrences[occurrences.length - 1]\n } else {\n const nthMap: Record<string, number> = {\n '1st': 1,\n '1': 1,\n 'first': 1,\n '2nd': 2,\n '2': 2,\n 'second': 2,\n '3rd': 3,\n '3': 3,\n 'third': 3,\n '4th': 4,\n '4': 4,\n 'fourth': 4,\n '5th': 5,\n '5': 5,\n 'fifth': 5,\n }\n const n = nthMap[nthRaw]\n if (!n) return `Error: Invalid nth value \"${nth}\". Use 1st–5th or \"last\".`\n if (n > occurrences.length) {\n return `Error: There is no ${nth} ${weekday} in ${firstOfMonth.toFormat('LLLL yyyy')} (only ${occurrences.length} occurrence${occurrences.length !== 1 ? 's' : ''}).`\n }\n result = occurrences[n - 1]\n }\n\n if (!result) return 'Error: Could not compute the date.'\n\n return `${nth} ${weekday} of ${result.toFormat('LLLL yyyy')}: ${result.toISODate()}\\nFormatted: ${result.toFormat('cccc, LLLL d, yyyy')}`\n },\n})\n\n/**\n * Get calendar metadata for a date.\n *\n * @remarks\n * Reports ISO week number, day of year, calendar quarter, fiscal quarter/year (configurable via\n * `fiscal_year_start_month`), week of month, and whether the date is a weekend. Accepts ISO\n * dates, natural-language (\"next Tuesday\"), and `now`.\n */\nexport const dateCalendarInfoTool = new Tool({\n name: 'date_calendar_info',\n description:\n 'Get calendar metadata for a date: ISO week number, day of year, calendar quarter, fiscal quarter/year, week of month, and whether it is a weekend or weekday.',\n inputSchema: validator.object({\n date: validator\n .string()\n .required()\n .description('ISO 8601 date, natural language date, or \"now\".'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC).'),\n fiscal_year_start_month: validator\n .number()\n .default(1)\n .description('Month when fiscal year starts (1–12, default: 1 = calendar year).'),\n }),\n handler: async (args) => {\n const {\n date: dateStr,\n timezone,\n fiscal_year_start_month: rawFyStart,\n } = args as {\n date: string\n timezone?: string\n fiscal_year_start_month: number\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n let dt: DateTime\n\n if (dateStr.toLowerCase() === 'now') {\n dt = DateTime.now().setZone(zone)\n } else {\n dt = DateTime.fromISO(dateStr, { zone })\n if (!dt.isValid) {\n const parsed = chrono.parseDate(dateStr, new Date())\n if (!parsed) return `Error: Could not parse date \"${dateStr}\".`\n dt = DateTime.fromJSDate(parsed).setZone(zone)\n }\n }\n\n const fyStart = Math.max(1, Math.min(12, Math.floor(rawFyStart)))\n\n const calendarQuarter = Math.ceil(dt.month / 3)\n\n const monthInFY = (dt.month - fyStart + 12) % 12\n const fiscalQuarter = Math.floor(monthInFY / 3) + 1\n const fiscalYear = dt.month >= fyStart ? dt.year : dt.year - 1\n\n const firstOfMonth = dt.startOf('month')\n const weekOfMonth = Math.ceil((dt.day + firstOfMonth.weekday - 1) / 7)\n\n const dayOfYear = Math.floor(dt.diff(dt.startOf('year'), 'days').days) + 1\n\n const isWeekend = dt.weekday >= 6\n\n const lines = [\n `Date: ${dt.toISODate()} (${dt.toFormat('cccc, LLLL d, yyyy')})`,\n '',\n `ISO week number: ${dt.weekNumber} (ISO year: ${dt.weekYear})`,\n `Day of year: ${dayOfYear} / ${dt.daysInYear}`,\n `Day of week: ${dt.weekday} (${dt.toFormat('cccc')})`,\n `Week of month: ${weekOfMonth}`,\n `Weekend: ${isWeekend ? 'Yes' : 'No'}`,\n '',\n `Calendar quarter: Q${calendarQuarter}`,\n `Fiscal quarter: FQ${fiscalQuarter} (FY${fiscalYear}${fyStart !== 1 ? `, starts month ${fyStart}` : ''})`,\n ]\n\n return lines.join('\\n')\n },\n})\n\n/**\n * Parse a date/time expression from natural language or common formats.\n *\n * @remarks\n * Examples: `\"next Monday\"`, `\"March 5th\"`, `\"in 2 weeks\"`, `\"yesterday\"`. Uses chrono-node for\n * relative parsing. `reference_date` overrides the \"now\" anchor.\n */\nexport const dateParseTool = new Tool({\n name: 'date_parse',\n description:\n 'Parse a date/time string from natural language or common formats (\"next Monday\", \"March 5th\", \"in 2 weeks\", \"yesterday\"). Returns an ISO 8601 date.',\n inputSchema: validator.object({\n text: validator\n .string()\n .required()\n .description('Date/time expression to parse (natural language or structured)'),\n reference_date: validator\n .string()\n .optional()\n .description('ISO date to treat as \"now\" for relative expressions (default: current time)'),\n timezone: validator\n .string()\n .optional()\n .description('IANA timezone for the result (optional, defaults UTC)'),\n }),\n handler: async (args) => {\n const {\n text,\n reference_date: referenceDate,\n timezone,\n } = args as {\n text: string\n reference_date?: string\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n let refDate = new Date()\n if (referenceDate) {\n refDate = new Date(referenceDate)\n if (Number.isNaN(refDate.getTime()))\n return `Error: Invalid reference_date \"${referenceDate}\".`\n }\n\n const parsed = chrono.parseDate(text, refDate)\n if (!parsed) return `Error: Could not parse a date from \"${text}\".`\n\n const dt = DateTime.fromJSDate(parsed).setZone(zone)\n return `ISO: ${dt.toISO()}\\nFormatted: ${dt.toFormat('cccc, LLLL d, yyyy h:mm a ZZZZ')}`\n },\n})\n\n/**\n * Get the start or end of a time period containing a given date.\n *\n * @remarks\n * Periods: `day`, `week`, `isoweek` (Monday-start), `month`, `quarter`, `year`. Quarter and year\n * honour `fiscal_year_start_month` for fiscal calendars (default: 1 = calendar year).\n */\nexport const datePeriodTool = new Tool({\n name: 'date_period',\n description:\n 'Get the start or end of a time period (day, week, month, quarter, year) containing a given date. Supports fiscal year offsets.',\n inputSchema: validator.object({\n date: validator.string().required().description('ISO 8601 date or \"now\"'),\n period: validator\n .string()\n .valid('day', 'week', 'isoweek', 'month', 'quarter', 'year')\n .required()\n .description('Time period (isoweek = Monday-start week)'),\n boundary: validator\n .string()\n .valid('start', 'end')\n .required()\n .description('\"start\" for the first moment, \"end\" for the last moment of the period'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC)'),\n fiscal_year_start_month: validator\n .number()\n .default(1)\n .description(\n 'For quarter/year: month number when the fiscal year starts (1–12, default: 1 = calendar year)'\n ),\n }),\n handler: async (args) => {\n const {\n date: dateStr,\n period,\n boundary,\n timezone,\n fiscal_year_start_month: rawFyStart,\n } = args as {\n date: string\n period: 'day' | 'week' | 'isoweek' | 'month' | 'quarter' | 'year'\n boundary: 'start' | 'end'\n timezone?: string\n fiscal_year_start_month: number\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const dt =\n dateStr.toLowerCase() === 'now'\n ? DateTime.now().setZone(zone)\n : DateTime.fromISO(dateStr, { zone })\n if (!dt.isValid) return `Error: Invalid date \"${dateStr}\".`\n\n const fyStart = Math.max(1, Math.min(12, Math.floor(rawFyStart)))\n\n let result: DateTime\n\n switch (period) {\n case 'day':\n result = boundary === 'start' ? dt.startOf('day') : dt.endOf('day')\n break\n case 'week':\n result = boundary === 'start' ? dt.startOf('week') : dt.endOf('week')\n break\n case 'isoweek':\n result =\n boundary === 'start'\n ? dt.startOf('week').set({ weekday: 1 })\n : dt.startOf('week').set({ weekday: 7 }).endOf('day')\n break\n case 'month':\n result = boundary === 'start' ? dt.startOf('month') : dt.endOf('month')\n break\n case 'quarter': {\n const monthInFY = (dt.month - fyStart + 12) % 12\n const qIndex = Math.floor(monthInFY / 3)\n const qStartMonth = ((qIndex * 3 + fyStart - 1) % 12) + 1\n const qStart = dt.set({ month: qStartMonth, day: 1 }).startOf('day')\n const adjusted = qStart > dt ? qStart.minus({ months: 3 }) : qStart\n result =\n boundary === 'start'\n ? adjusted\n : adjusted.plus({ months: 3 }).minus({ days: 1 }).endOf('day')\n break\n }\n case 'year':\n if (fyStart === 1) {\n result = boundary === 'start' ? dt.startOf('year') : dt.endOf('year')\n } else {\n const fyStartThis = dt.set({ month: fyStart, day: 1 }).startOf('day')\n const fyBase = dt >= fyStartThis ? fyStartThis : fyStartThis.minus({ years: 1 })\n result =\n boundary === 'start'\n ? fyBase\n : fyBase.plus({ years: 1 }).minus({ days: 1 }).endOf('day')\n }\n break\n }\n\n return `${boundary === 'start' ? 'Start' : 'End'} of ${period} containing ${dateStr}: ${result.toISO()}\\nFormatted: ${result.toFormat('cccc, LLLL d, yyyy h:mm:ss a ZZZZ')}`\n },\n})\n\n/**\n * Count business days between two dates, or compute the date N business days away.\n *\n * @remarks\n * Monday–Friday only; no holiday calendar awareness. Provide either `to` (count between) or\n * `add_days` (compute target date). Negative `add_days` walks backwards.\n */\nexport const dateBusinessDaysTool = new Tool({\n name: 'date_business_days',\n description:\n 'Count business days (Mon–Fri, no holiday awareness) between two dates, or calculate the date that is N business days from a start date.',\n inputSchema: validator.object({\n from: validator.string().required().description('Start date (ISO 8601 or \"now\")'),\n to: validator\n .string()\n .optional()\n .description('End date (ISO 8601 or \"now\") — for counting business days between two dates'),\n add_days: validator\n .number()\n .optional()\n .description('Instead of \"to\": number of business days to add (negative to subtract)'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC)'),\n }),\n handler: async (args) => {\n const {\n from: fromStr,\n to: toStr,\n add_days: addDays,\n timezone,\n } = args as {\n from: string\n to?: string\n add_days?: number\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const fromDt = (\n fromStr.toLowerCase() === 'now' ? DateTime.now() : DateTime.fromISO(fromStr)\n ).setZone(zone)\n if (!fromDt.isValid) return `Error: Invalid from date \"${fromStr}\".`\n\n if (addDays !== undefined) {\n const n = Math.floor(addDays)\n let cursor = fromDt.startOf('day')\n let remaining = Math.abs(n)\n const dir = n >= 0 ? 1 : -1\n while (remaining > 0) {\n cursor = cursor.plus({ days: dir })\n if (cursor.weekday <= 5) remaining--\n }\n return `${n >= 0 ? '+' : ''}${n} business day${Math.abs(n) !== 1 ? 's' : ''} from ${fromStr}: ${cursor.toISODate()}\\nFormatted: ${cursor.toFormat('cccc, LLLL d, yyyy')}`\n }\n\n if (!toStr) return 'Error: Provide either \"to\" date or \"add_days\".'\n\n const toDt = (toStr.toLowerCase() === 'now' ? DateTime.now() : DateTime.fromISO(toStr)).setZone(\n zone\n )\n if (!toDt.isValid) return `Error: Invalid to date \"${toStr}\".`\n\n const count = countBusinessDays(fromDt, toDt)\n return `Business days from ${fromStr} to ${toStr}: ${count}`\n },\n})\n"],"mappings":"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"}