agentfootprint 9.128.1 → 9.131.0

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 (603) hide show
  1. package/CAPABILITIES.md +13 -1
  2. package/dist/adapters/llm/AnthropicProvider.js +10 -111
  3. package/dist/adapters/llm/AnthropicProvider.js.map +1 -1
  4. package/dist/adapters/llm/BedrockProvider.js +11 -4
  5. package/dist/adapters/llm/BedrockProvider.js.map +1 -1
  6. package/dist/adapters/llm/InvokeModelGatewayProvider.js +167 -35
  7. package/dist/adapters/llm/InvokeModelGatewayProvider.js.map +1 -1
  8. package/dist/adapters/llm/OpenAIProvider.js +5 -0
  9. package/dist/adapters/llm/OpenAIProvider.js.map +1 -1
  10. package/dist/adapters/llm/anthropicMessagesWire.js +20 -6
  11. package/dist/adapters/llm/anthropicMessagesWire.js.map +1 -1
  12. package/dist/adapters/llm/retryAfter.js +61 -0
  13. package/dist/adapters/llm/retryAfter.js.map +1 -0
  14. package/dist/adapters/types.js.map +1 -1
  15. package/dist/artifacts/datasetResult.js +2 -2
  16. package/dist/artifacts/datasetResult.js.map +1 -1
  17. package/dist/artifacts/index.js +10 -8
  18. package/dist/artifacts/index.js.map +1 -1
  19. package/dist/artifacts/minting.js +2 -2
  20. package/dist/artifacts/minting.js.map +1 -1
  21. package/dist/core/Agent.js +229 -5
  22. package/dist/core/Agent.js.map +1 -1
  23. package/dist/core/agent/AgentBuilder.js +75 -1
  24. package/dist/core/agent/AgentBuilder.js.map +1 -1
  25. package/dist/core/agent/arguments/ask.js +356 -14
  26. package/dist/core/agent/arguments/ask.js.map +1 -1
  27. package/dist/core/agent/arguments/declare.js +260 -45
  28. package/dist/core/agent/arguments/declare.js.map +1 -1
  29. package/dist/core/agent/arguments/dispatch.js +25 -1
  30. package/dist/core/agent/arguments/dispatch.js.map +1 -1
  31. package/dist/core/agent/arguments/resolve.js +239 -6
  32. package/dist/core/agent/arguments/resolve.js.map +1 -1
  33. package/dist/core/agent/arguments/rows.js +37 -2
  34. package/dist/core/agent/arguments/rows.js.map +1 -1
  35. package/dist/core/agent/arguments/serve.js +332 -4
  36. package/dist/core/agent/arguments/serve.js.map +1 -1
  37. package/dist/core/agent/arguments/subflow.js +46 -7
  38. package/dist/core/agent/arguments/subflow.js.map +1 -1
  39. package/dist/core/agent/assessment/assess.js +45 -6
  40. package/dist/core/agent/assessment/assess.js.map +1 -1
  41. package/dist/core/agent/assessment/compose.js +3 -0
  42. package/dist/core/agent/assessment/compose.js.map +1 -1
  43. package/dist/core/agent/assessment/reasons.js +18 -0
  44. package/dist/core/agent/assessment/reasons.js.map +1 -1
  45. package/dist/core/agent/buildAgentChart.js +31 -1
  46. package/dist/core/agent/buildAgentChart.js.map +1 -1
  47. package/dist/core/agent/buildDynamicAgentChart.js +9 -0
  48. package/dist/core/agent/buildDynamicAgentChart.js.map +1 -1
  49. package/dist/core/agent/coverage/answer.js +24 -7
  50. package/dist/core/agent/coverage/answer.js.map +1 -1
  51. package/dist/core/agent/coverage/period.js +110 -69
  52. package/dist/core/agent/coverage/period.js.map +1 -1
  53. package/dist/core/agent/coverage/timeLimitFacts.js +70 -0
  54. package/dist/core/agent/coverage/timeLimitFacts.js.map +1 -0
  55. package/dist/core/agent/coverage/timeLimits.js +72 -0
  56. package/dist/core/agent/coverage/timeLimits.js.map +1 -0
  57. package/dist/core/agent/evidence/evidenceIndex.js +48 -7
  58. package/dist/core/agent/evidence/evidenceIndex.js.map +1 -1
  59. package/dist/core/agent/evidence/gate.js +9 -4
  60. package/dist/core/agent/evidence/gate.js.map +1 -1
  61. package/dist/core/agent/evidence/normalize.js +1 -105
  62. package/dist/core/agent/evidence/normalize.js.map +1 -1
  63. package/dist/core/agent/findings/ledger.js +14 -0
  64. package/dist/core/agent/findings/ledger.js.map +1 -1
  65. package/dist/core/agent/findings/types.js.map +1 -1
  66. package/dist/core/agent/honesty/mounts.js +105 -4
  67. package/dist/core/agent/honesty/mounts.js.map +1 -1
  68. package/dist/core/agent/results/subflow.js +43 -11
  69. package/dist/core/agent/results/subflow.js.map +1 -1
  70. package/dist/core/agent/stages/argumentAsk.js +85 -6
  71. package/dist/core/agent/stages/argumentAsk.js.map +1 -1
  72. package/dist/core/agent/stages/callLLM.js +16 -0
  73. package/dist/core/agent/stages/callLLM.js.map +1 -1
  74. package/dist/core/agent/stages/prepareFinal.js +61 -8
  75. package/dist/core/agent/stages/prepareFinal.js.map +1 -1
  76. package/dist/core/agent/stages/route.js +64 -6
  77. package/dist/core/agent/stages/route.js.map +1 -1
  78. package/dist/core/agent/stages/seed.js +29 -6
  79. package/dist/core/agent/stages/seed.js.map +1 -1
  80. package/dist/core/agent/stages/timeLayer.js +201 -0
  81. package/dist/core/agent/stages/timeLayer.js.map +1 -0
  82. package/dist/core/agent/stages/timeLineage.js +61 -0
  83. package/dist/core/agent/stages/timeLineage.js.map +1 -0
  84. package/dist/core/agent/stages/toolCalls.js +70 -0
  85. package/dist/core/agent/stages/toolCalls.js.map +1 -1
  86. package/dist/core/inputRequest.js +132 -5
  87. package/dist/core/inputRequest.js.map +1 -1
  88. package/dist/core/messageFrom.js +5 -2
  89. package/dist/core/messageFrom.js.map +1 -1
  90. package/dist/core/runCheckpoint.js +17 -2
  91. package/dist/core/runCheckpoint.js.map +1 -1
  92. package/dist/core/slots/buildToolsSlot.js +30 -2
  93. package/dist/core/slots/buildToolsSlot.js.map +1 -1
  94. package/dist/core/time/ask.js +239 -0
  95. package/dist/core/time/ask.js.map +1 -0
  96. package/dist/core/time/axis.js +469 -0
  97. package/dist/core/time/axis.js.map +1 -0
  98. package/dist/core/time/bind.js +235 -0
  99. package/dist/core/time/bind.js.map +1 -0
  100. package/dist/core/time/check.js +261 -0
  101. package/dist/core/time/check.js.map +1 -0
  102. package/dist/core/time/checkRecord.js +97 -0
  103. package/dist/core/time/checkRecord.js.map +1 -0
  104. package/dist/core/time/clock.js +260 -0
  105. package/dist/core/time/clock.js.map +1 -0
  106. package/dist/core/time/convert.js +634 -0
  107. package/dist/core/time/convert.js.map +1 -0
  108. package/dist/core/time/drift.js +96 -0
  109. package/dist/core/time/drift.js.map +1 -0
  110. package/dist/core/time/duration.js +125 -0
  111. package/dist/core/time/duration.js.map +1 -0
  112. package/dist/core/time/forms.js +273 -0
  113. package/dist/core/time/forms.js.map +1 -0
  114. package/dist/core/time/instant.js +141 -0
  115. package/dist/core/time/instant.js.map +1 -0
  116. package/dist/core/time/periodForm.js +392 -0
  117. package/dist/core/time/periodForm.js.map +1 -0
  118. package/dist/core/time/present.js +312 -0
  119. package/dist/core/time/present.js.map +1 -0
  120. package/dist/core/time/range.js +267 -0
  121. package/dist/core/time/range.js.map +1 -0
  122. package/dist/core/time/reader.js +209 -0
  123. package/dist/core/time/reader.js.map +1 -0
  124. package/dist/core/time/readers/english.js +576 -0
  125. package/dist/core/time/readers/english.js.map +1 -0
  126. package/dist/core/time/readingAsk.js +94 -0
  127. package/dist/core/time/readingAsk.js.map +1 -0
  128. package/dist/core/time/resolve.js +694 -0
  129. package/dist/core/time/resolve.js.map +1 -0
  130. package/dist/core/time/resolveRecord.js +164 -0
  131. package/dist/core/time/resolveRecord.js.map +1 -0
  132. package/dist/core/time/rows.js +412 -0
  133. package/dist/core/time/rows.js.map +1 -0
  134. package/dist/core/time/rowsBuild.js +193 -0
  135. package/dist/core/time/rowsBuild.js.map +1 -0
  136. package/dist/core/time/textForms.js +133 -0
  137. package/dist/core/time/textForms.js.map +1 -0
  138. package/dist/core/time/windows.js +172 -0
  139. package/dist/core/time/windows.js.map +1 -0
  140. package/dist/core/time/wire.js +86 -0
  141. package/dist/core/time/wire.js.map +1 -0
  142. package/dist/core/time/zone.js +253 -0
  143. package/dist/core/time/zone.js.map +1 -0
  144. package/dist/core/tools.js.map +1 -1
  145. package/dist/esm/adapters/llm/AnthropicProvider.js +8 -109
  146. package/dist/esm/adapters/llm/AnthropicProvider.js.map +1 -1
  147. package/dist/esm/adapters/llm/BedrockProvider.js +11 -4
  148. package/dist/esm/adapters/llm/BedrockProvider.js.map +1 -1
  149. package/dist/esm/adapters/llm/InvokeModelGatewayProvider.d.ts +38 -4
  150. package/dist/esm/adapters/llm/InvokeModelGatewayProvider.js +167 -35
  151. package/dist/esm/adapters/llm/InvokeModelGatewayProvider.js.map +1 -1
  152. package/dist/esm/adapters/llm/OpenAIProvider.js +5 -0
  153. package/dist/esm/adapters/llm/OpenAIProvider.js.map +1 -1
  154. package/dist/esm/adapters/llm/anthropicMessagesWire.d.ts +6 -1
  155. package/dist/esm/adapters/llm/anthropicMessagesWire.js +20 -6
  156. package/dist/esm/adapters/llm/anthropicMessagesWire.js.map +1 -1
  157. package/dist/esm/adapters/llm/retryAfter.d.ts +27 -0
  158. package/dist/esm/adapters/llm/retryAfter.js +56 -0
  159. package/dist/esm/adapters/llm/retryAfter.js.map +1 -0
  160. package/dist/esm/adapters/types.d.ts +9 -0
  161. package/dist/esm/adapters/types.js.map +1 -1
  162. package/dist/esm/artifacts/datasetResult.js +1 -1
  163. package/dist/esm/artifacts/datasetResult.js.map +1 -1
  164. package/dist/esm/artifacts/index.d.ts +1 -1
  165. package/dist/esm/artifacts/index.js +3 -2
  166. package/dist/esm/artifacts/index.js.map +1 -1
  167. package/dist/esm/artifacts/minting.js +1 -1
  168. package/dist/esm/artifacts/minting.js.map +1 -1
  169. package/dist/esm/artifacts/types.d.ts +2 -2
  170. package/dist/esm/core/Agent.d.ts +64 -0
  171. package/dist/esm/core/Agent.js +230 -6
  172. package/dist/esm/core/Agent.js.map +1 -1
  173. package/dist/esm/core/agent/AgentBuilder.d.ts +60 -0
  174. package/dist/esm/core/agent/AgentBuilder.js +75 -1
  175. package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
  176. package/dist/esm/core/agent/arguments/ask.d.ts +88 -5
  177. package/dist/esm/core/agent/arguments/ask.js +349 -8
  178. package/dist/esm/core/agent/arguments/ask.js.map +1 -1
  179. package/dist/esm/core/agent/arguments/checks.d.ts +1 -1
  180. package/dist/esm/core/agent/arguments/declare.d.ts +76 -15
  181. package/dist/esm/core/agent/arguments/declare.js +255 -44
  182. package/dist/esm/core/agent/arguments/declare.js.map +1 -1
  183. package/dist/esm/core/agent/arguments/dispatch.js +25 -1
  184. package/dist/esm/core/agent/arguments/dispatch.js.map +1 -1
  185. package/dist/esm/core/agent/arguments/resolve.d.ts +77 -7
  186. package/dist/esm/core/agent/arguments/resolve.js +239 -8
  187. package/dist/esm/core/agent/arguments/resolve.js.map +1 -1
  188. package/dist/esm/core/agent/arguments/rows.d.ts +31 -2
  189. package/dist/esm/core/agent/arguments/rows.js +35 -1
  190. package/dist/esm/core/agent/arguments/rows.js.map +1 -1
  191. package/dist/esm/core/agent/arguments/serve.d.ts +133 -4
  192. package/dist/esm/core/agent/arguments/serve.js +328 -4
  193. package/dist/esm/core/agent/arguments/serve.js.map +1 -1
  194. package/dist/esm/core/agent/arguments/subflow.d.ts +28 -0
  195. package/dist/esm/core/agent/arguments/subflow.js +47 -8
  196. package/dist/esm/core/agent/arguments/subflow.js.map +1 -1
  197. package/dist/esm/core/agent/assessment/assess.js +45 -6
  198. package/dist/esm/core/agent/assessment/assess.js.map +1 -1
  199. package/dist/esm/core/agent/assessment/compose.js +3 -0
  200. package/dist/esm/core/agent/assessment/compose.js.map +1 -1
  201. package/dist/esm/core/agent/assessment/reasons.js +18 -0
  202. package/dist/esm/core/agent/assessment/reasons.js.map +1 -1
  203. package/dist/esm/core/agent/assessment/types.d.ts +15 -1
  204. package/dist/esm/core/agent/buildAgentChart.d.ts +41 -0
  205. package/dist/esm/core/agent/buildAgentChart.js +28 -0
  206. package/dist/esm/core/agent/buildAgentChart.js.map +1 -1
  207. package/dist/esm/core/agent/buildDynamicAgentChart.d.ts +1 -1
  208. package/dist/esm/core/agent/buildDynamicAgentChart.js +9 -0
  209. package/dist/esm/core/agent/buildDynamicAgentChart.js.map +1 -1
  210. package/dist/esm/core/agent/coverage/answer.d.ts +20 -1
  211. package/dist/esm/core/agent/coverage/answer.js +23 -6
  212. package/dist/esm/core/agent/coverage/answer.js.map +1 -1
  213. package/dist/esm/core/agent/coverage/period.d.ts +49 -3
  214. package/dist/esm/core/agent/coverage/period.js +107 -68
  215. package/dist/esm/core/agent/coverage/period.js.map +1 -1
  216. package/dist/esm/core/agent/coverage/timeLimitFacts.d.ts +56 -0
  217. package/dist/esm/core/agent/coverage/timeLimitFacts.js +65 -0
  218. package/dist/esm/core/agent/coverage/timeLimitFacts.js.map +1 -0
  219. package/dist/esm/core/agent/coverage/timeLimits.d.ts +46 -0
  220. package/dist/esm/core/agent/coverage/timeLimits.js +67 -0
  221. package/dist/esm/core/agent/coverage/timeLimits.js.map +1 -0
  222. package/dist/esm/core/agent/evidence/evidenceIndex.d.ts +25 -2
  223. package/dist/esm/core/agent/evidence/evidenceIndex.js +47 -7
  224. package/dist/esm/core/agent/evidence/evidenceIndex.js.map +1 -1
  225. package/dist/esm/core/agent/evidence/gate.d.ts +7 -0
  226. package/dist/esm/core/agent/evidence/gate.js +9 -4
  227. package/dist/esm/core/agent/evidence/gate.js.map +1 -1
  228. package/dist/esm/core/agent/evidence/normalize.d.ts +0 -34
  229. package/dist/esm/core/agent/evidence/normalize.js +0 -103
  230. package/dist/esm/core/agent/evidence/normalize.js.map +1 -1
  231. package/dist/esm/core/agent/evidence/types.d.ts +12 -1
  232. package/dist/esm/core/agent/findings/ledger.js +14 -0
  233. package/dist/esm/core/agent/findings/ledger.js.map +1 -1
  234. package/dist/esm/core/agent/findings/types.d.ts +2 -1
  235. package/dist/esm/core/agent/findings/types.js.map +1 -1
  236. package/dist/esm/core/agent/honesty/mounts.d.ts +25 -0
  237. package/dist/esm/core/agent/honesty/mounts.js +104 -4
  238. package/dist/esm/core/agent/honesty/mounts.js.map +1 -1
  239. package/dist/esm/core/agent/results/subflow.d.ts +34 -2
  240. package/dist/esm/core/agent/results/subflow.js +43 -11
  241. package/dist/esm/core/agent/results/subflow.js.map +1 -1
  242. package/dist/esm/core/agent/stages/argumentAsk.d.ts +19 -0
  243. package/dist/esm/core/agent/stages/argumentAsk.js +85 -6
  244. package/dist/esm/core/agent/stages/argumentAsk.js.map +1 -1
  245. package/dist/esm/core/agent/stages/callLLM.d.ts +6 -0
  246. package/dist/esm/core/agent/stages/callLLM.js +16 -0
  247. package/dist/esm/core/agent/stages/callLLM.js.map +1 -1
  248. package/dist/esm/core/agent/stages/prepareFinal.d.ts +13 -1
  249. package/dist/esm/core/agent/stages/prepareFinal.js +59 -7
  250. package/dist/esm/core/agent/stages/prepareFinal.js.map +1 -1
  251. package/dist/esm/core/agent/stages/route.d.ts +29 -1
  252. package/dist/esm/core/agent/stages/route.js +64 -7
  253. package/dist/esm/core/agent/stages/route.js.map +1 -1
  254. package/dist/esm/core/agent/stages/seed.d.ts +23 -0
  255. package/dist/esm/core/agent/stages/seed.js +29 -6
  256. package/dist/esm/core/agent/stages/seed.js.map +1 -1
  257. package/dist/esm/core/agent/stages/timeLayer.d.ts +94 -0
  258. package/dist/esm/core/agent/stages/timeLayer.js +193 -0
  259. package/dist/esm/core/agent/stages/timeLayer.js.map +1 -0
  260. package/dist/esm/core/agent/stages/timeLineage.d.ts +31 -0
  261. package/dist/esm/core/agent/stages/timeLineage.js +57 -0
  262. package/dist/esm/core/agent/stages/timeLineage.js.map +1 -0
  263. package/dist/esm/core/agent/stages/toolCalls.d.ts +32 -0
  264. package/dist/esm/core/agent/stages/toolCalls.js +70 -0
  265. package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
  266. package/dist/esm/core/agent/types.d.ts +37 -0
  267. package/dist/esm/core/inputRequest.d.ts +50 -6
  268. package/dist/esm/core/inputRequest.js +132 -5
  269. package/dist/esm/core/inputRequest.js.map +1 -1
  270. package/dist/esm/core/messageFrom.d.ts +5 -2
  271. package/dist/esm/core/messageFrom.js +5 -2
  272. package/dist/esm/core/messageFrom.js.map +1 -1
  273. package/dist/esm/core/runCheckpoint.js +17 -2
  274. package/dist/esm/core/runCheckpoint.js.map +1 -1
  275. package/dist/esm/core/slots/buildToolsSlot.d.ts +29 -0
  276. package/dist/esm/core/slots/buildToolsSlot.js +30 -2
  277. package/dist/esm/core/slots/buildToolsSlot.js.map +1 -1
  278. package/dist/esm/core/time/ask.d.ts +126 -0
  279. package/dist/esm/core/time/ask.js +230 -0
  280. package/dist/esm/core/time/ask.js.map +1 -0
  281. package/dist/esm/core/time/axis.d.ts +224 -0
  282. package/dist/esm/core/time/axis.js +462 -0
  283. package/dist/esm/core/time/axis.js.map +1 -0
  284. package/dist/esm/core/time/bind.d.ts +143 -0
  285. package/dist/esm/core/time/bind.js +227 -0
  286. package/dist/esm/core/time/bind.js.map +1 -0
  287. package/dist/esm/core/time/check.d.ts +113 -0
  288. package/dist/esm/core/time/check.js +252 -0
  289. package/dist/esm/core/time/check.js.map +1 -0
  290. package/dist/esm/core/time/checkRecord.d.ts +74 -0
  291. package/dist/esm/core/time/checkRecord.js +90 -0
  292. package/dist/esm/core/time/checkRecord.js.map +1 -0
  293. package/dist/esm/core/time/clock.d.ts +183 -0
  294. package/dist/esm/core/time/clock.js +252 -0
  295. package/dist/esm/core/time/clock.js.map +1 -0
  296. package/dist/esm/core/time/convert.d.ts +178 -0
  297. package/dist/esm/core/time/convert.js +609 -0
  298. package/dist/esm/core/time/convert.js.map +1 -0
  299. package/dist/esm/core/time/drift.d.ts +85 -0
  300. package/dist/esm/core/time/drift.js +91 -0
  301. package/dist/esm/core/time/drift.js.map +1 -0
  302. package/dist/esm/core/time/duration.d.ts +71 -0
  303. package/dist/esm/core/time/duration.js +117 -0
  304. package/dist/esm/core/time/duration.js.map +1 -0
  305. package/dist/esm/core/time/forms.d.ts +84 -0
  306. package/dist/esm/core/time/forms.js +268 -0
  307. package/dist/esm/core/time/forms.js.map +1 -0
  308. package/dist/esm/core/time/instant.d.ts +75 -0
  309. package/dist/esm/core/time/instant.js +131 -0
  310. package/dist/esm/core/time/instant.js.map +1 -0
  311. package/dist/esm/core/time/periodForm.d.ts +184 -0
  312. package/dist/esm/core/time/periodForm.js +376 -0
  313. package/dist/esm/core/time/periodForm.js.map +1 -0
  314. package/dist/esm/core/time/present.d.ts +107 -0
  315. package/dist/esm/core/time/present.js +305 -0
  316. package/dist/esm/core/time/present.js.map +1 -0
  317. package/dist/esm/core/time/range.d.ts +127 -0
  318. package/dist/esm/core/time/range.js +249 -0
  319. package/dist/esm/core/time/range.js.map +1 -0
  320. package/dist/esm/core/time/reader.d.ts +162 -0
  321. package/dist/esm/core/time/reader.js +203 -0
  322. package/dist/esm/core/time/reader.js.map +1 -0
  323. package/dist/esm/core/time/readers/english.d.ts +99 -0
  324. package/dist/esm/core/time/readers/english.js +572 -0
  325. package/dist/esm/core/time/readers/english.js.map +1 -0
  326. package/dist/esm/core/time/readingAsk.d.ts +45 -0
  327. package/dist/esm/core/time/readingAsk.js +90 -0
  328. package/dist/esm/core/time/readingAsk.js.map +1 -0
  329. package/dist/esm/core/time/resolve.d.ts +103 -0
  330. package/dist/esm/core/time/resolve.js +684 -0
  331. package/dist/esm/core/time/resolve.js.map +1 -0
  332. package/dist/esm/core/time/resolveRecord.d.ts +160 -0
  333. package/dist/esm/core/time/resolveRecord.js +158 -0
  334. package/dist/esm/core/time/resolveRecord.js.map +1 -0
  335. package/dist/esm/core/time/rows.d.ts +297 -0
  336. package/dist/esm/core/time/rows.js +397 -0
  337. package/dist/esm/core/time/rows.js.map +1 -0
  338. package/dist/esm/core/time/rowsBuild.d.ts +82 -0
  339. package/dist/esm/core/time/rowsBuild.js +185 -0
  340. package/dist/esm/core/time/rowsBuild.js.map +1 -0
  341. package/dist/esm/core/time/textForms.d.ts +53 -0
  342. package/dist/esm/core/time/textForms.js +126 -0
  343. package/dist/esm/core/time/textForms.js.map +1 -0
  344. package/dist/esm/core/time/windows.d.ts +113 -0
  345. package/dist/esm/core/time/windows.js +166 -0
  346. package/dist/esm/core/time/windows.js.map +1 -0
  347. package/dist/esm/core/time/wire.d.ts +63 -0
  348. package/dist/esm/core/time/wire.js +81 -0
  349. package/dist/esm/core/time/wire.js.map +1 -0
  350. package/dist/esm/core/time/zone.d.ts +115 -0
  351. package/dist/esm/core/time/zone.js +242 -0
  352. package/dist/esm/core/time/zone.js.map +1 -0
  353. package/dist/esm/core/tools.d.ts +26 -4
  354. package/dist/esm/core/tools.js.map +1 -1
  355. package/dist/esm/events/payloads.d.ts +16 -2
  356. package/dist/esm/index.d.ts +13 -1
  357. package/dist/esm/index.js +6 -1
  358. package/dist/esm/index.js.map +1 -1
  359. package/dist/esm/lib/answer-account/facts/howSure.js +7 -0
  360. package/dist/esm/lib/answer-account/facts/howSure.js.map +1 -1
  361. package/dist/esm/lib/answer-account/templates.d.ts +3 -0
  362. package/dist/esm/lib/answer-account/templates.js +4 -0
  363. package/dist/esm/lib/answer-account/templates.js.map +1 -1
  364. package/dist/esm/lib/mcp/elicitation.d.ts +84 -0
  365. package/dist/esm/lib/mcp/elicitation.js +181 -0
  366. package/dist/esm/lib/mcp/elicitation.js.map +1 -0
  367. package/dist/esm/lib/mcp/mcpClient.js +9 -3
  368. package/dist/esm/lib/mcp/mcpClient.js.map +1 -1
  369. package/dist/esm/lib/mcp/mcpServe.js +6 -2
  370. package/dist/esm/lib/mcp/mcpServe.js.map +1 -1
  371. package/dist/esm/lib/mcp/mockMcpClient.d.ts +9 -1
  372. package/dist/esm/lib/mcp/mockMcpClient.js +5 -3
  373. package/dist/esm/lib/mcp/mockMcpClient.js.map +1 -1
  374. package/dist/esm/lib/mcp/toolExtras.d.ts +21 -2
  375. package/dist/esm/lib/mcp/toolExtras.js +22 -0
  376. package/dist/esm/lib/mcp/toolExtras.js.map +1 -1
  377. package/dist/esm/lib/mcp/types.d.ts +8 -0
  378. package/dist/esm/lib/time-travel/receipt.d.ts +1 -1
  379. package/dist/esm/lib/time-travel/servedView.d.ts +1 -1
  380. package/dist/esm/lib/time-travel/servedView.js +9 -0
  381. package/dist/esm/lib/time-travel/servedView.js.map +1 -1
  382. package/dist/esm/locales/index.d.ts +6 -0
  383. package/dist/esm/locales/index.js +6 -0
  384. package/dist/esm/locales/index.js.map +1 -1
  385. package/dist/esm/locales/timeAsk.d.ts +29 -0
  386. package/dist/esm/locales/timeAsk.js +44 -0
  387. package/dist/esm/locales/timeAsk.js.map +1 -0
  388. package/dist/esm/recorders/core/resilienceHooks.js +1 -0
  389. package/dist/esm/recorders/core/resilienceHooks.js.map +1 -1
  390. package/dist/esm/resilience/statedWait.d.ts +22 -0
  391. package/dist/esm/resilience/statedWait.js +35 -0
  392. package/dist/esm/resilience/statedWait.js.map +1 -0
  393. package/dist/esm/resilience/withRetry.d.ts +13 -2
  394. package/dist/esm/resilience/withRetry.js +16 -1
  395. package/dist/esm/resilience/withRetry.js.map +1 -1
  396. package/dist/index.js +11 -1
  397. package/dist/index.js.map +1 -1
  398. package/dist/lib/answer-account/facts/howSure.js +7 -0
  399. package/dist/lib/answer-account/facts/howSure.js.map +1 -1
  400. package/dist/lib/answer-account/templates.js +4 -0
  401. package/dist/lib/answer-account/templates.js.map +1 -1
  402. package/dist/lib/mcp/elicitation.js +186 -0
  403. package/dist/lib/mcp/elicitation.js.map +1 -0
  404. package/dist/lib/mcp/mcpClient.js +8 -2
  405. package/dist/lib/mcp/mcpClient.js.map +1 -1
  406. package/dist/lib/mcp/mcpServe.js +5 -1
  407. package/dist/lib/mcp/mcpServe.js.map +1 -1
  408. package/dist/lib/mcp/mockMcpClient.js +4 -2
  409. package/dist/lib/mcp/mockMcpClient.js.map +1 -1
  410. package/dist/lib/mcp/toolExtras.js +25 -1
  411. package/dist/lib/mcp/toolExtras.js.map +1 -1
  412. package/dist/lib/time-travel/servedView.js +9 -0
  413. package/dist/lib/time-travel/servedView.js.map +1 -1
  414. package/dist/locales/index.js +8 -1
  415. package/dist/locales/index.js.map +1 -1
  416. package/dist/locales/timeAsk.js +47 -0
  417. package/dist/locales/timeAsk.js.map +1 -0
  418. package/dist/recorders/core/resilienceHooks.js +1 -0
  419. package/dist/recorders/core/resilienceHooks.js.map +1 -1
  420. package/dist/resilience/statedWait.js +39 -0
  421. package/dist/resilience/statedWait.js.map +1 -0
  422. package/dist/resilience/withRetry.js +16 -1
  423. package/dist/resilience/withRetry.js.map +1 -1
  424. package/dist/types/adapters/llm/AnthropicProvider.d.ts.map +1 -1
  425. package/dist/types/adapters/llm/BedrockProvider.d.ts.map +1 -1
  426. package/dist/types/adapters/llm/InvokeModelGatewayProvider.d.ts +38 -4
  427. package/dist/types/adapters/llm/InvokeModelGatewayProvider.d.ts.map +1 -1
  428. package/dist/types/adapters/llm/OpenAIProvider.d.ts.map +1 -1
  429. package/dist/types/adapters/llm/anthropicMessagesWire.d.ts +6 -1
  430. package/dist/types/adapters/llm/anthropicMessagesWire.d.ts.map +1 -1
  431. package/dist/types/adapters/llm/retryAfter.d.ts +28 -0
  432. package/dist/types/adapters/llm/retryAfter.d.ts.map +1 -0
  433. package/dist/types/adapters/types.d.ts +9 -0
  434. package/dist/types/adapters/types.d.ts.map +1 -1
  435. package/dist/types/artifacts/index.d.ts +1 -1
  436. package/dist/types/artifacts/index.d.ts.map +1 -1
  437. package/dist/types/artifacts/types.d.ts +2 -2
  438. package/dist/types/artifacts/types.d.ts.map +1 -1
  439. package/dist/types/core/Agent.d.ts +64 -0
  440. package/dist/types/core/Agent.d.ts.map +1 -1
  441. package/dist/types/core/agent/AgentBuilder.d.ts +60 -0
  442. package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
  443. package/dist/types/core/agent/arguments/ask.d.ts +88 -5
  444. package/dist/types/core/agent/arguments/ask.d.ts.map +1 -1
  445. package/dist/types/core/agent/arguments/checks.d.ts +1 -1
  446. package/dist/types/core/agent/arguments/checks.d.ts.map +1 -1
  447. package/dist/types/core/agent/arguments/declare.d.ts +76 -15
  448. package/dist/types/core/agent/arguments/declare.d.ts.map +1 -1
  449. package/dist/types/core/agent/arguments/dispatch.d.ts.map +1 -1
  450. package/dist/types/core/agent/arguments/resolve.d.ts +77 -7
  451. package/dist/types/core/agent/arguments/resolve.d.ts.map +1 -1
  452. package/dist/types/core/agent/arguments/rows.d.ts +31 -2
  453. package/dist/types/core/agent/arguments/rows.d.ts.map +1 -1
  454. package/dist/types/core/agent/arguments/serve.d.ts +133 -4
  455. package/dist/types/core/agent/arguments/serve.d.ts.map +1 -1
  456. package/dist/types/core/agent/arguments/subflow.d.ts +28 -0
  457. package/dist/types/core/agent/arguments/subflow.d.ts.map +1 -1
  458. package/dist/types/core/agent/assessment/assess.d.ts.map +1 -1
  459. package/dist/types/core/agent/assessment/compose.d.ts.map +1 -1
  460. package/dist/types/core/agent/assessment/reasons.d.ts.map +1 -1
  461. package/dist/types/core/agent/assessment/types.d.ts +15 -1
  462. package/dist/types/core/agent/assessment/types.d.ts.map +1 -1
  463. package/dist/types/core/agent/buildAgentChart.d.ts +41 -0
  464. package/dist/types/core/agent/buildAgentChart.d.ts.map +1 -1
  465. package/dist/types/core/agent/buildDynamicAgentChart.d.ts +1 -1
  466. package/dist/types/core/agent/buildDynamicAgentChart.d.ts.map +1 -1
  467. package/dist/types/core/agent/coverage/answer.d.ts +20 -1
  468. package/dist/types/core/agent/coverage/answer.d.ts.map +1 -1
  469. package/dist/types/core/agent/coverage/period.d.ts +49 -3
  470. package/dist/types/core/agent/coverage/period.d.ts.map +1 -1
  471. package/dist/types/core/agent/coverage/timeLimitFacts.d.ts +57 -0
  472. package/dist/types/core/agent/coverage/timeLimitFacts.d.ts.map +1 -0
  473. package/dist/types/core/agent/coverage/timeLimits.d.ts +47 -0
  474. package/dist/types/core/agent/coverage/timeLimits.d.ts.map +1 -0
  475. package/dist/types/core/agent/evidence/evidenceIndex.d.ts +25 -2
  476. package/dist/types/core/agent/evidence/evidenceIndex.d.ts.map +1 -1
  477. package/dist/types/core/agent/evidence/gate.d.ts +7 -0
  478. package/dist/types/core/agent/evidence/gate.d.ts.map +1 -1
  479. package/dist/types/core/agent/evidence/normalize.d.ts +0 -34
  480. package/dist/types/core/agent/evidence/normalize.d.ts.map +1 -1
  481. package/dist/types/core/agent/evidence/types.d.ts +12 -1
  482. package/dist/types/core/agent/evidence/types.d.ts.map +1 -1
  483. package/dist/types/core/agent/findings/ledger.d.ts.map +1 -1
  484. package/dist/types/core/agent/findings/types.d.ts +2 -1
  485. package/dist/types/core/agent/findings/types.d.ts.map +1 -1
  486. package/dist/types/core/agent/honesty/mounts.d.ts +25 -0
  487. package/dist/types/core/agent/honesty/mounts.d.ts.map +1 -1
  488. package/dist/types/core/agent/results/subflow.d.ts +34 -2
  489. package/dist/types/core/agent/results/subflow.d.ts.map +1 -1
  490. package/dist/types/core/agent/stages/argumentAsk.d.ts +19 -0
  491. package/dist/types/core/agent/stages/argumentAsk.d.ts.map +1 -1
  492. package/dist/types/core/agent/stages/callLLM.d.ts +6 -0
  493. package/dist/types/core/agent/stages/callLLM.d.ts.map +1 -1
  494. package/dist/types/core/agent/stages/prepareFinal.d.ts +13 -1
  495. package/dist/types/core/agent/stages/prepareFinal.d.ts.map +1 -1
  496. package/dist/types/core/agent/stages/route.d.ts +29 -1
  497. package/dist/types/core/agent/stages/route.d.ts.map +1 -1
  498. package/dist/types/core/agent/stages/seed.d.ts +23 -0
  499. package/dist/types/core/agent/stages/seed.d.ts.map +1 -1
  500. package/dist/types/core/agent/stages/timeLayer.d.ts +95 -0
  501. package/dist/types/core/agent/stages/timeLayer.d.ts.map +1 -0
  502. package/dist/types/core/agent/stages/timeLineage.d.ts +32 -0
  503. package/dist/types/core/agent/stages/timeLineage.d.ts.map +1 -0
  504. package/dist/types/core/agent/stages/toolCalls.d.ts +32 -0
  505. package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
  506. package/dist/types/core/agent/types.d.ts +37 -0
  507. package/dist/types/core/agent/types.d.ts.map +1 -1
  508. package/dist/types/core/inputRequest.d.ts +50 -6
  509. package/dist/types/core/inputRequest.d.ts.map +1 -1
  510. package/dist/types/core/messageFrom.d.ts +5 -2
  511. package/dist/types/core/messageFrom.d.ts.map +1 -1
  512. package/dist/types/core/runCheckpoint.d.ts.map +1 -1
  513. package/dist/types/core/slots/buildToolsSlot.d.ts +29 -0
  514. package/dist/types/core/slots/buildToolsSlot.d.ts.map +1 -1
  515. package/dist/types/core/time/ask.d.ts +127 -0
  516. package/dist/types/core/time/ask.d.ts.map +1 -0
  517. package/dist/types/core/time/axis.d.ts +225 -0
  518. package/dist/types/core/time/axis.d.ts.map +1 -0
  519. package/dist/types/core/time/bind.d.ts +144 -0
  520. package/dist/types/core/time/bind.d.ts.map +1 -0
  521. package/dist/types/core/time/check.d.ts +114 -0
  522. package/dist/types/core/time/check.d.ts.map +1 -0
  523. package/dist/types/core/time/checkRecord.d.ts +75 -0
  524. package/dist/types/core/time/checkRecord.d.ts.map +1 -0
  525. package/dist/types/core/time/clock.d.ts +184 -0
  526. package/dist/types/core/time/clock.d.ts.map +1 -0
  527. package/dist/types/core/time/convert.d.ts +179 -0
  528. package/dist/types/core/time/convert.d.ts.map +1 -0
  529. package/dist/types/core/time/drift.d.ts +86 -0
  530. package/dist/types/core/time/drift.d.ts.map +1 -0
  531. package/dist/types/core/time/duration.d.ts +72 -0
  532. package/dist/types/core/time/duration.d.ts.map +1 -0
  533. package/dist/types/core/time/forms.d.ts +85 -0
  534. package/dist/types/core/time/forms.d.ts.map +1 -0
  535. package/dist/types/core/time/instant.d.ts +76 -0
  536. package/dist/types/core/time/instant.d.ts.map +1 -0
  537. package/dist/types/core/time/periodForm.d.ts +185 -0
  538. package/dist/types/core/time/periodForm.d.ts.map +1 -0
  539. package/dist/types/core/time/present.d.ts +108 -0
  540. package/dist/types/core/time/present.d.ts.map +1 -0
  541. package/dist/types/core/time/range.d.ts +128 -0
  542. package/dist/types/core/time/range.d.ts.map +1 -0
  543. package/dist/types/core/time/reader.d.ts +163 -0
  544. package/dist/types/core/time/reader.d.ts.map +1 -0
  545. package/dist/types/core/time/readers/english.d.ts +100 -0
  546. package/dist/types/core/time/readers/english.d.ts.map +1 -0
  547. package/dist/types/core/time/readingAsk.d.ts +46 -0
  548. package/dist/types/core/time/readingAsk.d.ts.map +1 -0
  549. package/dist/types/core/time/resolve.d.ts +104 -0
  550. package/dist/types/core/time/resolve.d.ts.map +1 -0
  551. package/dist/types/core/time/resolveRecord.d.ts +161 -0
  552. package/dist/types/core/time/resolveRecord.d.ts.map +1 -0
  553. package/dist/types/core/time/rows.d.ts +298 -0
  554. package/dist/types/core/time/rows.d.ts.map +1 -0
  555. package/dist/types/core/time/rowsBuild.d.ts +83 -0
  556. package/dist/types/core/time/rowsBuild.d.ts.map +1 -0
  557. package/dist/types/core/time/textForms.d.ts +54 -0
  558. package/dist/types/core/time/textForms.d.ts.map +1 -0
  559. package/dist/types/core/time/windows.d.ts +114 -0
  560. package/dist/types/core/time/windows.d.ts.map +1 -0
  561. package/dist/types/core/time/wire.d.ts +64 -0
  562. package/dist/types/core/time/wire.d.ts.map +1 -0
  563. package/dist/types/core/time/zone.d.ts +116 -0
  564. package/dist/types/core/time/zone.d.ts.map +1 -0
  565. package/dist/types/core/tools.d.ts +26 -4
  566. package/dist/types/core/tools.d.ts.map +1 -1
  567. package/dist/types/events/payloads.d.ts +16 -2
  568. package/dist/types/events/payloads.d.ts.map +1 -1
  569. package/dist/types/index.d.ts +13 -1
  570. package/dist/types/index.d.ts.map +1 -1
  571. package/dist/types/lib/answer-account/facts/howSure.d.ts.map +1 -1
  572. package/dist/types/lib/answer-account/templates.d.ts +3 -0
  573. package/dist/types/lib/answer-account/templates.d.ts.map +1 -1
  574. package/dist/types/lib/mcp/elicitation.d.ts +85 -0
  575. package/dist/types/lib/mcp/elicitation.d.ts.map +1 -0
  576. package/dist/types/lib/mcp/mcpServe.d.ts.map +1 -1
  577. package/dist/types/lib/mcp/mockMcpClient.d.ts +9 -1
  578. package/dist/types/lib/mcp/mockMcpClient.d.ts.map +1 -1
  579. package/dist/types/lib/mcp/toolExtras.d.ts +21 -2
  580. package/dist/types/lib/mcp/toolExtras.d.ts.map +1 -1
  581. package/dist/types/lib/mcp/types.d.ts +8 -0
  582. package/dist/types/lib/mcp/types.d.ts.map +1 -1
  583. package/dist/types/lib/time-travel/receipt.d.ts +1 -1
  584. package/dist/types/lib/time-travel/receipt.d.ts.map +1 -1
  585. package/dist/types/lib/time-travel/servedView.d.ts +1 -1
  586. package/dist/types/lib/time-travel/servedView.d.ts.map +1 -1
  587. package/dist/types/locales/index.d.ts +6 -0
  588. package/dist/types/locales/index.d.ts.map +1 -1
  589. package/dist/types/locales/timeAsk.d.ts +30 -0
  590. package/dist/types/locales/timeAsk.d.ts.map +1 -0
  591. package/dist/types/recorders/core/resilienceHooks.d.ts.map +1 -1
  592. package/dist/types/resilience/statedWait.d.ts +23 -0
  593. package/dist/types/resilience/statedWait.d.ts.map +1 -0
  594. package/dist/types/resilience/withRetry.d.ts +13 -2
  595. package/dist/types/resilience/withRetry.d.ts.map +1 -1
  596. package/package.json +1 -1
  597. package/dist/artifacts/timeAxis.js +0 -218
  598. package/dist/artifacts/timeAxis.js.map +0 -1
  599. package/dist/esm/artifacts/timeAxis.d.ts +0 -114
  600. package/dist/esm/artifacts/timeAxis.js +0 -212
  601. package/dist/esm/artifacts/timeAxis.js.map +0 -1
  602. package/dist/types/artifacts/timeAxis.d.ts +0 -115
  603. package/dist/types/artifacts/timeAxis.d.ts.map +0 -1
@@ -0,0 +1,99 @@
1
+ /**
2
+ * core/time/readers/english — the library's careful English reader (time
3
+ * design § 5.3): a tokenizer over a small, closed set of phrases, and
4
+ * "unreadable" for every other time phrase it recognises.
5
+ *
6
+ * Pattern: Strategy behind the `TimeReader` port (`../reader.ts`). It
7
+ * TOKENIZES only: it returns the parts it sees and the verbatim
8
+ * quote. It never resolves an instant, never applies a date order,
9
+ * never maps a zone abbreviation and never refuses a future date —
10
+ * all of that is `resolve.ts`'s, the policy's or the ask's.
11
+ * Role: core/ leaf (the time layer). Imports only the port's types. Armed
12
+ * by the app: `.time({ reader: englishTimeReader() })` — there is no
13
+ * default reader.
14
+ * Emits: N/A.
15
+ *
16
+ * ## What it reads (the v1 rows of § 5.3)
17
+ *
18
+ * | Phrase | Example | Parts |
19
+ * |--------|---------|-------|
20
+ * | an ISO date or instant | `2026-10-09`, `2026-10-09T08:00-07:00` | `date: fixed`, `wall`, `zoneToken` |
21
+ * | a numeric date | `10/09/26`, `10/9` | `date: numeric` — the ORDER is not decided here |
22
+ * | a clock time | `8 AM`, `8:40`, `20:40`, `8:40 p.m.` | `wall` (a bare `8` is a time only as a range's first side: `8 to 9 AM`) |
23
+ * | a range between two of the above | `8 AM to 8:40 AM`, `08:00–08:40`, `between 8 and 9 AM` | `rangeOf` (a day or zone said once for both sides is the whole mention's) |
24
+ * | a zone after a time or date | `America/Los_Angeles`, `UTC-07:00`, `PST` | `zoneToken`, as written (an abbreviation is ASKED — v1 ships no map) |
25
+ * | a day word | today, yesterday, tomorrow | `relative: { unit: 'day', offset }` |
26
+ * | a relative span from now | last 40 minutes, past 2 hours, the last hour, the past week | `relative: { unit, count }` — a look-back in minutes, hours, days or weeks |
27
+ *
28
+ * ## What it says "unreadable" for — never a partial reading
29
+ *
30
+ * Parts of the day (`yesterday morning`, `tonight`, `noon`), calendar spans
31
+ * (`last week`, `this month`), week days and named months (`Friday`,
32
+ * `Oct 9`), `N hours ago`, spans in words (`last two hours`), in a unit it
33
+ * does not read (`last 30 seconds`, `last 3 months`) or said with `previous`
34
+ * (`previous 7 days` — often relative to another window), a look-ahead (`next 2 hours`), an
35
+ * ordinal day (`the 9th`), `8 o'clock`, and any v1 phrase a modifier changes
36
+ * (`since 8 AM`, `before yesterday`, `around 8:40`, `earlier today`,
37
+ * `8 AM to now`, `past 8 PM`, `8 AM-ish`, `from 3 PM yesterday` with no `to`) and
38
+ * a meridiem the number contradicts (`13:00 PM`). Such a phrase is ONE mention
39
+ * with `problem: 'unreadable'`, quoting the whole phrase: reading `yesterday`
40
+ * out of `yesterday morning` would silently widen what the person said.
41
+ *
42
+ * ## It only PROPOSES — the person confirms (the owner's decision "Always confirm")
43
+ *
44
+ * Nothing this reader reads is ever filed as the person's words. Seven review
45
+ * rounds each found the next English spelling a word list, an allow-list or a
46
+ * position rule missed (a zone named in words, a look-back tied to an event,
47
+ * an open end, a half-read range), so the owner decided (2026-09-30, time
48
+ * design TQ29): every reading of a chat message is a PROPOSAL, offered
49
+ * through the time ask pre-filled and editable, with its window AND its zone
50
+ * ("I read “last 2 hours” as … in America/Los_Angeles — is that right?").
51
+ * Only what the person picks or types in that form is theirs. The library
52
+ * owns the law (`../rowsBuild.ts` · `timeReadingRows`), so this reader returns
53
+ * parts and quotes only — no confirm flag, no leftover list, no allow-list.
54
+ * A form may later skip the click only when a registered benchmark shows it
55
+ * is always read right (TQ29's growth rule).
56
+ *
57
+ * A numeric date the tokens could split two ways stays ONE parse — `10/09/26`
58
+ * is three numbers; which is the month is the policy's or the person's.
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * const reader = englishTimeReader();
63
+ * reader.read('errors on 10/09/26 8 AM to 8:40 AM PST', { locale: 'en-US' });
64
+ * // { mentions: [{ quote: '10/09/26 8 AM to 8:40 AM PST', parses: [{
65
+ * // date: { kind: 'numeric', fields: [10, 9, 26], yearDigits: 2 }, zoneToken: 'PST',
66
+ * // rangeOf: [{ wall: { h: 8, meridiem: 'am' } }, { wall: { h: 8, m: 40, meridiem: 'am' } }] }] }] }
67
+ * reader.read('errors in the last 2 hours', { locale: 'en-US' });
68
+ * // { mentions: [{ quote: 'last 2 hours', parses: [{ relative: { unit: 'hour', count: 2 } }] }] }
69
+ * reader.read('what failed yesterday morning?', { locale: 'en-US' });
70
+ * // { mentions: [{ quote: 'yesterday morning', parses: [], problem: 'unreadable' }] }
71
+ * ```
72
+ */
73
+ import { type TimeReader } from '../reader.js';
74
+ /** The reader's recorded identity — on every `time-reading` row with its version. */
75
+ export declare const ENGLISH_TIME_READER_ID = "agentfootprint/english";
76
+ /** Raised whenever what the reader returns for some text changes. */
77
+ export declare const ENGLISH_TIME_READER_VERSION = "1.0.0";
78
+ /** Options for {@link englishTimeReader}. */
79
+ export interface EnglishTimeReaderOptions {
80
+ /**
81
+ * The language tag the time ask's labels are rendered in (`present.ts`),
82
+ * e.g. `'en-GB'`. Default `'en-US'`. It never decides a date order — that is
83
+ * the policy's (`dateOrder`) or the person's.
84
+ */
85
+ readonly locale?: string;
86
+ }
87
+ /**
88
+ * The library's careful English reader: a `kind: 'rule'` tokenizer over the
89
+ * v1 phrases of the time design's § 5.3, "unreadable" for every other time
90
+ * phrase it recognises. No dependency; deterministic over the text.
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * Agent.create({ provider, model })
95
+ * .time({ zone: 'America/Los_Angeles', reader: englishTimeReader() })
96
+ * .build();
97
+ * ```
98
+ */
99
+ export declare function englishTimeReader(options?: EnglishTimeReaderOptions): TimeReader;
@@ -0,0 +1,572 @@
1
+ /**
2
+ * core/time/readers/english — the library's careful English reader (time
3
+ * design § 5.3): a tokenizer over a small, closed set of phrases, and
4
+ * "unreadable" for every other time phrase it recognises.
5
+ *
6
+ * Pattern: Strategy behind the `TimeReader` port (`../reader.ts`). It
7
+ * TOKENIZES only: it returns the parts it sees and the verbatim
8
+ * quote. It never resolves an instant, never applies a date order,
9
+ * never maps a zone abbreviation and never refuses a future date —
10
+ * all of that is `resolve.ts`'s, the policy's or the ask's.
11
+ * Role: core/ leaf (the time layer). Imports only the port's types. Armed
12
+ * by the app: `.time({ reader: englishTimeReader() })` — there is no
13
+ * default reader.
14
+ * Emits: N/A.
15
+ *
16
+ * ## What it reads (the v1 rows of § 5.3)
17
+ *
18
+ * | Phrase | Example | Parts |
19
+ * |--------|---------|-------|
20
+ * | an ISO date or instant | `2026-10-09`, `2026-10-09T08:00-07:00` | `date: fixed`, `wall`, `zoneToken` |
21
+ * | a numeric date | `10/09/26`, `10/9` | `date: numeric` — the ORDER is not decided here |
22
+ * | a clock time | `8 AM`, `8:40`, `20:40`, `8:40 p.m.` | `wall` (a bare `8` is a time only as a range's first side: `8 to 9 AM`) |
23
+ * | a range between two of the above | `8 AM to 8:40 AM`, `08:00–08:40`, `between 8 and 9 AM` | `rangeOf` (a day or zone said once for both sides is the whole mention's) |
24
+ * | a zone after a time or date | `America/Los_Angeles`, `UTC-07:00`, `PST` | `zoneToken`, as written (an abbreviation is ASKED — v1 ships no map) |
25
+ * | a day word | today, yesterday, tomorrow | `relative: { unit: 'day', offset }` |
26
+ * | a relative span from now | last 40 minutes, past 2 hours, the last hour, the past week | `relative: { unit, count }` — a look-back in minutes, hours, days or weeks |
27
+ *
28
+ * ## What it says "unreadable" for — never a partial reading
29
+ *
30
+ * Parts of the day (`yesterday morning`, `tonight`, `noon`), calendar spans
31
+ * (`last week`, `this month`), week days and named months (`Friday`,
32
+ * `Oct 9`), `N hours ago`, spans in words (`last two hours`), in a unit it
33
+ * does not read (`last 30 seconds`, `last 3 months`) or said with `previous`
34
+ * (`previous 7 days` — often relative to another window), a look-ahead (`next 2 hours`), an
35
+ * ordinal day (`the 9th`), `8 o'clock`, and any v1 phrase a modifier changes
36
+ * (`since 8 AM`, `before yesterday`, `around 8:40`, `earlier today`,
37
+ * `8 AM to now`, `past 8 PM`, `8 AM-ish`, `from 3 PM yesterday` with no `to`) and
38
+ * a meridiem the number contradicts (`13:00 PM`). Such a phrase is ONE mention
39
+ * with `problem: 'unreadable'`, quoting the whole phrase: reading `yesterday`
40
+ * out of `yesterday morning` would silently widen what the person said.
41
+ *
42
+ * ## It only PROPOSES — the person confirms (the owner's decision "Always confirm")
43
+ *
44
+ * Nothing this reader reads is ever filed as the person's words. Seven review
45
+ * rounds each found the next English spelling a word list, an allow-list or a
46
+ * position rule missed (a zone named in words, a look-back tied to an event,
47
+ * an open end, a half-read range), so the owner decided (2026-09-30, time
48
+ * design TQ29): every reading of a chat message is a PROPOSAL, offered
49
+ * through the time ask pre-filled and editable, with its window AND its zone
50
+ * ("I read “last 2 hours” as … in America/Los_Angeles — is that right?").
51
+ * Only what the person picks or types in that form is theirs. The library
52
+ * owns the law (`../rowsBuild.ts` · `timeReadingRows`), so this reader returns
53
+ * parts and quotes only — no confirm flag, no leftover list, no allow-list.
54
+ * A form may later skip the click only when a registered benchmark shows it
55
+ * is always read right (TQ29's growth rule).
56
+ *
57
+ * A numeric date the tokens could split two ways stays ONE parse — `10/09/26`
58
+ * is three numbers; which is the month is the policy's or the person's.
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * const reader = englishTimeReader();
63
+ * reader.read('errors on 10/09/26 8 AM to 8:40 AM PST', { locale: 'en-US' });
64
+ * // { mentions: [{ quote: '10/09/26 8 AM to 8:40 AM PST', parses: [{
65
+ * // date: { kind: 'numeric', fields: [10, 9, 26], yearDigits: 2 }, zoneToken: 'PST',
66
+ * // rangeOf: [{ wall: { h: 8, meridiem: 'am' } }, { wall: { h: 8, m: 40, meridiem: 'am' } }] }] }] }
67
+ * reader.read('errors in the last 2 hours', { locale: 'en-US' });
68
+ * // { mentions: [{ quote: 'last 2 hours', parses: [{ relative: { unit: 'hour', count: 2 } }] }] }
69
+ * reader.read('what failed yesterday morning?', { locale: 'en-US' });
70
+ * // { mentions: [{ quote: 'yesterday morning', parses: [], problem: 'unreadable' }] }
71
+ * ```
72
+ */
73
+ import { isTimeParts, MAX_MENTIONS, } from '../reader.js';
74
+ // ─── The words (data) ────────────────────────────────────────────────────
75
+ /** The reader's recorded identity — on every `time-reading` row with its version. */
76
+ export const ENGLISH_TIME_READER_ID = 'agentfootprint/english';
77
+ /** Raised whenever what the reader returns for some text changes. */
78
+ export const ENGLISH_TIME_READER_VERSION = '1.0.0';
79
+ const DAY_WORDS = { today: 0, yesterday: -1, tomorrow: 1 };
80
+ /** The units a look-back is read in: minutes, hours, days, weeks. */
81
+ const SPAN_UNITS = {
82
+ minute: 'minute',
83
+ min: 'minute',
84
+ hour: 'hour',
85
+ hr: 'hour',
86
+ day: 'day',
87
+ week: 'week',
88
+ };
89
+ /** Zone abbreviations the reader TOKENIZES after a time or a date — never maps (§ 5.3). */
90
+ const ZONE_ABBREVIATIONS = [
91
+ 'UTC', 'GMT', 'PST', 'PDT', 'PT', 'MST', 'MDT', 'MT', 'CST', 'CDT', 'CT', 'EST', 'EDT', 'ET',
92
+ 'AKST', 'AKDT', 'HST', 'AST', 'ADT', 'NST', 'NDT', 'BST', 'IST', 'CET', 'CEST', 'EET', 'EEST',
93
+ 'WET', 'WEST', 'MSK', 'JST', 'KST', 'HKT', 'SGT', 'AEST', 'AEDT', 'ACST', 'ACDT', 'AWST',
94
+ 'NZST', 'NZDT', 'SAST',
95
+ ]; // prettier-ignore
96
+ const IANA_AREAS = 'Africa|America|Antarctica|Arctic|Asia|Atlantic|Australia|Europe|Indian|Pacific|Etc';
97
+ const UNIT_WORDS = 'seconds?|secs?|minutes?|mins?|hours?|hrs?|days?|weeks?|months?|years?|quarters?';
98
+ const NUMBER_WORDS = 'an?|one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|fifteen|twenty|thirty|' +
99
+ 'forty|fifty|sixty|ninety|few|several|couple(?:\\s+of)?';
100
+ const MONTHS = 'jan(?:uary)?|feb(?:ruary)?|mar(?:ch)?|apr(?:il)?|may|june?|july?|aug(?:ust)?|' +
101
+ 'sep(?:t(?:ember)?)?|oct(?:ober)?|nov(?:ember)?|dec(?:ember)?';
102
+ /**
103
+ * Time phrases v1 does not read (§ 5.3's "later" rows and everything past
104
+ * them). Each forms an `unreadable` mention on its own, and taints any v1
105
+ * phrase it touches.
106
+ */
107
+ const NOT_READ = [
108
+ /\b(?:(?:this|last|early|late|mid)\s+)?(?:morning|afternoon|evening|night|tonight|overnight|noon|midday|midnight|lunchtime|dawn|dusk)s?\b/gi,
109
+ /\b(?:last|this|next|past|previous|coming|current)\s+(?:week|month|year|quarter|weekend|hour|minute|second|day|night|decade|fortnight|shift)\b/gi,
110
+ /\bweekends?\b/gi,
111
+ /\b(?:monday|tuesday|wednesday|thursday|friday|saturday|sunday)s?\b/gi,
112
+ new RegExp(`\\b(?:${MONTHS})\\.?\\s+\\d{1,2}(?:st|nd|rd|th)?\\b(?:,?\\s+\\d{4}\\b)?`, 'gi'),
113
+ new RegExp(`\\b\\d{1,2}(?:st|nd|rd|th)?\\s+(?:of\\s+)?(?:${MONTHS})\\b\\.?(?:,?\\s+\\d{4}\\b)?`, 'gi'),
114
+ /\b(?:january|february|july|september|october|november|december)\b/gi,
115
+ new RegExp(`\\b(?:\\d+|${NUMBER_WORDS})\\s+(?:${UNIT_WORDS})\\s+ago\\b`, 'gi'),
116
+ new RegExp(`\\b(?:last|past|previous|next|coming|upcoming|following)\\s+` +
117
+ `(?:(?:${NUMBER_WORDS}|\\d+)\\s+)?(?:${UNIT_WORDS})\\b`, 'gi'),
118
+ /\b(?:the\s+)?day\s+(?:before\s+yesterday|after\s+tomorrow)\b/gi,
119
+ /\bon\s+the\s+\d{1,2}(?:st|nd|rd|th)\b/gi,
120
+ /\bthe\s+\d{1,2}(?:st|nd|rd|th)\s+of\b/gi,
121
+ /\b\d{1,2}\s*o['’]?\s?clock\b/gi,
122
+ // A meridiem on a number that is no 12-hour time (`13:00 PM`, `0 AM`): the words contradict.
123
+ /(?<![\w:.+/])\d{1,2}(?::\d{2}){0,2}\s?(?:am|pm|a\.m\.|p\.m\.)(?![a-z])/gi,
124
+ ];
125
+ // ─── The range grammar (one owner) ──────────────────────────────────────
126
+ //
127
+ // The connectors a v1 range is READ with — the grammar's own list: the joins
128
+ // (`joins`), the bare hour's lookahead (`BARE_HOUR`) and `… to now`
129
+ // (`MODIFIER_AFTER`) all build from it. What the reader did not read is not
130
+ // its question any more: every reading is a proposal the person confirms
131
+ // (the owner's decision "Always confirm", time design TQ29).
132
+ const RANGE_WORDS = 'to|until|till|through|thru';
133
+ /** A range connector the grammar reads: a word, or a hyphen, en dash or em dash. */
134
+ const RANGE_CONNECTOR = `(?:(?:${RANGE_WORDS})(?![a-z])|[–—-])`;
135
+ /** A word right before a phrase that changes what it means: the phrase is not read. */
136
+ const MODIFIER_BEFORE = new RegExp('(?:^|[^\\w])(since|before|after|by|around|circa|approx(?:imately)?|until|till|earlier|later|' +
137
+ 'early|late|within|past|beyond|prior\\s+to|up\\s+to|no\\s+(?:later|earlier|sooner)\\s+than|' +
138
+ 'as\\s+of|(?:starting|beginning)(?:\\s+(?:at|from|on))?|~)\\s*$', 'i');
139
+ /** `from` with no `to`: a time after it is where a window STARTS (`from 3 PM yesterday`), not an hour. */
140
+ const FROM_BEFORE = /(?:^|[^\w])(from)\s*$/i;
141
+ /** …and right after it. */
142
+ const MODIFIER_AFTER = new RegExp('^(?:\\s*-?\\s*ish\\b|\\s*(?:ago\\b|onwards?\\b|or\\s+so\\b|(?:or|and)\\s+(?:later|earlier|after|before)\\b|' +
143
+ `at\\s+the\\s+(?:latest|earliest)\\b|${RANGE_CONNECTOR}\\s*now\\b))`, 'i');
144
+ /** Text not preceded by something that would make these digits part of a larger token. */
145
+ const NOT_AFTER = '(?<![\\w:./-])';
146
+ /**
147
+ * The same for a clock time — which may follow a range's hyphen (`8:00-8:40`)
148
+ * or `..` (`2026-09-26 08:00..08:40`), never an offset's sign or one dot.
149
+ */
150
+ const TIME_NOT_AFTER = '(?<![\\w:+/])(?<!(?:^|[^.])\\.)';
151
+ const ISO = new RegExp(
152
+ // An ISO interval's second end follows its first's `/` (`…08:00Z/2026-…`) or `..`; a path's `/` does not count.
153
+ `(?<![\\w:-])(?<!(?:^|[^.])\\.)(?<![^\\dZ]/)(?<!^/)(\\d{4})-(\\d{2})-(\\d{2})` +
154
+ '(?:[Tt ](\\d{2}):(\\d{2})(?::(\\d{2}))?(Z|[+-]\\d{2}(?::?\\d{2})?)?)?' +
155
+ '(?![\\w:]|[.-]\\d)', 'g');
156
+ const NUMERIC = new RegExp(
157
+ // A hyphen may join two dates (`10/01/26-10/09/26`).
158
+ `(?<![\\w:./])(\\d{1,4})/(\\d{1,2})(?:/(\\d{4}|\\d{2}))?(?![\\w/:]|\\.\\d)`, 'g');
159
+ const WALL_MERIDIEM = new RegExp(`${TIME_NOT_AFTER}(\\d{1,2})(?::(\\d{2})(?::(\\d{2}))?)?\\s?(am|pm|a\\.m\\.|p\\.m\\.)(?![a-z])`, 'gi');
160
+ const WALL_COLON = new RegExp(
161
+ // A meridiem after it is `WALL_MERIDIEM`'s — or, when that refuses it (`13:00 PM`), unreadable.
162
+ `${TIME_NOT_AFTER}(\\d{1,2}):(\\d{2})(?::(\\d{2}))?(?![\\d:])(?!\\s?(?:am|pm|a\\.m\\.|p\\.m\\.)(?![a-z]))`, 'gi');
163
+ /** A bare hour — a time only as a range's first side whose second side carries a meridiem. */
164
+ const BARE_HOUR = new RegExp(`${NOT_AFTER}(\\d{1,2})(?=\\s*(?:${RANGE_CONNECTOR}|and)\\s*` +
165
+ '\\d{1,2}(?::\\d{2})?\\s?(?:am|pm|a\\.m\\.|p\\.m\\.)(?![a-z]))', 'gi');
166
+ const DAY_WORD = /\b(today|yesterday|tomorrow)\b/gi;
167
+ const SPAN = /\b(?:last|past)\s+(\d{1,6})\s*(minutes?|mins?|hours?|hrs?|days?|weeks?)\b/gi;
168
+ /** `the last hour`, `the past week` — a look-back of one unit; without `the`, `last week` is a calendar week (not read). */
169
+ const ONE_SPAN = /\bthe\s+(?:last|past)\s+(hour|day|week)\b/gi;
170
+ /** A zone right after a phrase: optional `(`, or `in`, then the token (and a closing `)`). */
171
+ const ZONE_AFTER = new RegExp('^(\\s*\\(?\\s*|\\s+in\\s+)' +
172
+ `(?:(${IANA_AREAS})/[A-Za-z0-9_+-]+(?:/[A-Za-z0-9_+-]+)?` +
173
+ '|(?:UTC|GMT)\\s?([+-]\\d{1,2}(?::?\\d{2})?)' +
174
+ `|(${ZONE_ABBREVIATIONS.join('|')}))(?![A-Za-z0-9_/])(\\s*\\))?`);
175
+ const num = (text) => text === undefined ? undefined : Number(text);
176
+ function wallOf(h, m, s, meridiem) {
177
+ if (!Number.isInteger(h) || h > 23)
178
+ return undefined;
179
+ if (m !== undefined && m > 59)
180
+ return undefined;
181
+ if (s !== undefined && s > 59)
182
+ return undefined;
183
+ if (meridiem !== undefined && (h < 1 || h > 12))
184
+ return undefined;
185
+ return {
186
+ h,
187
+ ...(m !== undefined && { m }),
188
+ ...(s !== undefined && { s }),
189
+ ...(meridiem !== undefined && { meridiem }),
190
+ };
191
+ }
192
+ function* matches(re, text) {
193
+ re.lastIndex = 0;
194
+ for (let m = re.exec(text); m !== null; m = re.exec(text)) {
195
+ yield m;
196
+ if (m[0].length === 0)
197
+ re.lastIndex++;
198
+ }
199
+ }
200
+ function isoAtoms(text) {
201
+ const out = [];
202
+ for (const m of matches(ISO, text)) {
203
+ const [, y, mo, d, h, mi, s, zone] = m;
204
+ const date = { kind: 'fixed', year: Number(y), month: Number(mo), day: Number(d) };
205
+ const wall = h === undefined ? undefined : wallOf(Number(h), Number(mi), num(s));
206
+ if (h !== undefined && wall === undefined)
207
+ continue;
208
+ out.push({
209
+ start: m.index,
210
+ end: m.index + m[0].length,
211
+ kind: 'instant',
212
+ date,
213
+ ...(wall !== undefined && { wall }),
214
+ ...(zone !== undefined && { zoneToken: zone }),
215
+ });
216
+ }
217
+ return out;
218
+ }
219
+ function numericAtoms(text) {
220
+ const out = [];
221
+ for (const m of matches(NUMERIC, text)) {
222
+ const [, a, b, c] = m;
223
+ if (a.length === 3 || (a.length === 4 && c === undefined))
224
+ continue;
225
+ const fields = [Number(a), Number(b), ...(c !== undefined ? [Number(c)] : [])];
226
+ const yearDigits = c === undefined ? undefined : a.length === 4 ? 4 : c.length;
227
+ out.push({
228
+ start: m.index,
229
+ end: m.index + m[0].length,
230
+ kind: 'date',
231
+ date: { kind: 'numeric', fields, ...(yearDigits !== undefined && { yearDigits }) },
232
+ });
233
+ }
234
+ return out;
235
+ }
236
+ function wallAtoms(text) {
237
+ const out = [];
238
+ for (const m of matches(WALL_MERIDIEM, text)) {
239
+ const meridiem = m[4].toLowerCase().startsWith('a') ? 'am' : 'pm';
240
+ const wall = wallOf(Number(m[1]), num(m[2]), num(m[3]), meridiem);
241
+ if (wall !== undefined) {
242
+ out.push({ start: m.index, end: m.index + m[0].length, kind: 'wall', wall });
243
+ }
244
+ }
245
+ for (const m of matches(WALL_COLON, text)) {
246
+ const wall = wallOf(Number(m[1]), Number(m[2]), num(m[3]));
247
+ if (wall !== undefined) {
248
+ out.push({ start: m.index, end: m.index + m[0].length, kind: 'wall', wall });
249
+ }
250
+ }
251
+ for (const m of matches(BARE_HOUR, text)) {
252
+ const wall = wallOf(Number(m[1]));
253
+ if (wall !== undefined) {
254
+ out.push({ start: m.index, end: m.index + m[0].length, kind: 'bare', wall });
255
+ }
256
+ }
257
+ return out;
258
+ }
259
+ function wordAtoms(text) {
260
+ const out = [];
261
+ for (const m of matches(DAY_WORD, text)) {
262
+ const offset = DAY_WORDS[m[1].toLowerCase()];
263
+ out.push({
264
+ start: m.index,
265
+ end: m.index + m[0].length,
266
+ kind: 'day',
267
+ relative: { unit: 'day', offset },
268
+ });
269
+ }
270
+ for (const m of matches(SPAN, text)) {
271
+ const count = Number(m[1]);
272
+ const unit = SPAN_UNITS[m[2].toLowerCase().replace(/s$/, '')];
273
+ if (unit === undefined || count < 1 || count > 100_000)
274
+ continue;
275
+ out.push({
276
+ start: m.index,
277
+ end: m.index + m[0].length,
278
+ kind: 'span',
279
+ relative: { unit, count },
280
+ });
281
+ }
282
+ for (const m of matches(ONE_SPAN, text)) {
283
+ const unit = SPAN_UNITS[m[1].toLowerCase()];
284
+ out.push({
285
+ start: m.index,
286
+ end: m.index + m[0].length,
287
+ kind: 'span',
288
+ relative: { unit, count: 1 },
289
+ });
290
+ }
291
+ return out;
292
+ }
293
+ /** The v1 phrases, overlaps settled: the earlier, then the longer, wins. */
294
+ function atomsOf(text) {
295
+ const all = [...isoAtoms(text), ...numericAtoms(text), ...wallAtoms(text), ...wordAtoms(text)];
296
+ all.sort((a, b) => a.start - b.start || b.end - b.start - (a.end - a.start));
297
+ const kept = [];
298
+ for (const atom of all) {
299
+ const last = kept[kept.length - 1];
300
+ if (last !== undefined && atom.start < last.end)
301
+ continue;
302
+ kept.push({ ...atom });
303
+ }
304
+ for (const atom of kept)
305
+ attachZone(text, atom);
306
+ // A zone written after a phrase may cover a phrase found on its own (`UTC-07:00` holds `07:00`).
307
+ const out = [];
308
+ for (const atom of kept) {
309
+ const last = out[out.length - 1];
310
+ if (last === undefined || atom.start >= last.end)
311
+ out.push(atom);
312
+ }
313
+ return out;
314
+ }
315
+ /** A zone written right after a date or a time joins that phrase, as written. */
316
+ function attachZone(text, atom) {
317
+ if (atom.kind === 'day' || atom.kind === 'span' || atom.kind === 'bare')
318
+ return;
319
+ if (atom.zoneToken !== undefined)
320
+ return;
321
+ const m = ZONE_AFTER.exec(text.slice(atom.end));
322
+ if (m === null)
323
+ return;
324
+ const lead = m[1];
325
+ const opened = lead.includes('(');
326
+ const closed = m[5] !== undefined;
327
+ if (opened !== closed)
328
+ return;
329
+ // The IANA name, else the offset after `UTC` / `GMT`, else the abbreviation — each verbatim.
330
+ const whole = m[0].slice(lead.length).replace(/\s*\)$/, '');
331
+ const token = m[2] !== undefined ? whole : m[3] !== undefined ? m[3] : m[4];
332
+ atom.zoneToken = token;
333
+ atom.end += m[0].length;
334
+ }
335
+ function notReadSpans(text, atoms) {
336
+ const out = [];
337
+ for (const re of NOT_READ) {
338
+ for (const m of matches(re, text)) {
339
+ const span = { start: m.index, end: m.index + m[0].length };
340
+ // A span a v1 phrase covers whole is that phrase (`last 40 minutes`), not a later row.
341
+ if (atoms.some((a) => a.start <= span.start && span.end <= a.end))
342
+ continue;
343
+ out.push(span);
344
+ }
345
+ }
346
+ return out;
347
+ }
348
+ // ─── Mentions ────────────────────────────────────────────────────────────
349
+ /** A gap token that is one of the grammar's range connectors. */
350
+ const CONNECTOR = new RegExp(`^${RANGE_CONNECTOR}$`, 'i');
351
+ const GLUE = /^(?:,|at|on|in|of|the|@|from|between)$/i;
352
+ /** The words and marks between two phrases. */
353
+ const gapTokens = (gap) => gap.match(/\.\.|[–—\-/,@()]|[A-Za-z]+|\d+|\S/g) ?? [];
354
+ /** Whether the text between two phrases only joins them — and whether it says "range". */
355
+ function joins(gap, between, left, right) {
356
+ if (gap.replace(/[\s\w,@()./–—-]/g, '') !== '')
357
+ return undefined;
358
+ const tokens = gapTokens(gap);
359
+ let range = false;
360
+ for (const t of tokens) {
361
+ const instants = left.atom?.kind === 'instant' && right.atom?.kind === 'instant';
362
+ if (CONNECTOR.test(t) || t === '..' || (instants && t === '/')) {
363
+ if (range)
364
+ return undefined;
365
+ range = true;
366
+ }
367
+ else if (t.toLowerCase() === 'and' && between) {
368
+ if (range)
369
+ return undefined;
370
+ range = true;
371
+ }
372
+ else if (!GLUE.test(t)) {
373
+ return undefined;
374
+ }
375
+ }
376
+ return range ? 'range' : 'glue';
377
+ }
378
+ function groupsOf(text, atoms, notRead) {
379
+ const items = [
380
+ ...atoms.map((atom) => ({ start: atom.start, end: atom.end, atom })),
381
+ ...notRead.map((s) => ({ start: s.start, end: s.end })),
382
+ ].sort((a, b) => a.start - b.start || b.end - a.end);
383
+ const groups = [];
384
+ for (const item of items) {
385
+ const group = groups[groups.length - 1];
386
+ const last = group?.items[group.items.length - 1];
387
+ if (group !== undefined && last !== undefined) {
388
+ if (item.start < group.end) {
389
+ group.items.push(item);
390
+ group.end = Math.max(group.end, item.end);
391
+ group.unreadable = true;
392
+ continue;
393
+ }
394
+ const between = /\bbetween\s+$/i.test(text.slice(0, group.start));
395
+ const joined = joins(text.slice(group.end, item.start), between, last, item);
396
+ if (joined !== undefined) {
397
+ if (joined === 'range') {
398
+ if (group.rangeAt !== undefined)
399
+ group.unreadable = true;
400
+ group.rangeAt = group.items.length;
401
+ }
402
+ group.items.push(item);
403
+ group.end = item.end;
404
+ if (item.atom === undefined)
405
+ group.unreadable = true;
406
+ continue;
407
+ }
408
+ }
409
+ groups.push({
410
+ start: item.start,
411
+ end: item.end,
412
+ items: [item],
413
+ unreadable: item.atom === undefined,
414
+ });
415
+ }
416
+ for (const group of groups)
417
+ widenForModifiers(text, group);
418
+ return mergeOverlaps(groups).filter((g) => g.unreadable || g.items.some((i) => i.atom?.kind !== 'bare'));
419
+ }
420
+ /** Groups a widening made overlap are one phrase (`8 and 9 AM` held the bare `8` on its own). */
421
+ function mergeOverlaps(groups) {
422
+ const out = [];
423
+ for (const group of [...groups].sort((a, b) => a.start - b.start)) {
424
+ const last = out[out.length - 1];
425
+ if (last !== undefined && group.start < last.end) {
426
+ last.items.push(...group.items);
427
+ last.end = Math.max(last.end, group.end);
428
+ last.unreadable = true;
429
+ continue;
430
+ }
431
+ out.push(group);
432
+ }
433
+ return out;
434
+ }
435
+ /** A modifier before or after a v1 phrase changes it: the whole phrase is not read. */
436
+ function widenForModifiers(text, group) {
437
+ const head = text.slice(0, group.start);
438
+ const clock = group.items.some((i) => i.atom?.wall !== undefined);
439
+ const before = MODIFIER_BEFORE.exec(head) ??
440
+ (group.rangeAt === undefined && clock ? FROM_BEFORE.exec(head) : null);
441
+ if (before !== null) {
442
+ group.start = before.index + before[0].lastIndexOf(before[1]);
443
+ group.unreadable = true;
444
+ }
445
+ const after = MODIFIER_AFTER.exec(text.slice(group.end));
446
+ if (after !== null) {
447
+ group.end += after[0].length;
448
+ group.unreadable = true;
449
+ }
450
+ }
451
+ /** One side's parts from its phrases — `undefined` when two phrases say the same part. */
452
+ function sideOf(atoms) {
453
+ const side = {};
454
+ for (const a of atoms) {
455
+ if (a.date !== undefined || a.kind === 'day') {
456
+ if (side.date !== undefined || side.relative !== undefined)
457
+ return undefined;
458
+ if (a.date !== undefined)
459
+ side.date = a.date;
460
+ if (a.kind === 'day')
461
+ side.relative = a.relative;
462
+ side.dayFirst = side.wall === undefined;
463
+ }
464
+ if (a.kind === 'span') {
465
+ if (side.relative !== undefined)
466
+ return undefined;
467
+ side.relative = a.relative;
468
+ side.span = true;
469
+ }
470
+ if (a.wall !== undefined) {
471
+ if (side.wall !== undefined)
472
+ return undefined;
473
+ side.wall = a.wall;
474
+ if (a.kind === 'bare')
475
+ side.bare = true;
476
+ }
477
+ if (a.zoneToken !== undefined) {
478
+ if (side.zoneToken !== undefined)
479
+ return undefined;
480
+ side.zoneToken = a.zoneToken;
481
+ }
482
+ }
483
+ if (side.span === true && (side.date !== undefined || side.wall !== undefined))
484
+ return undefined;
485
+ return side;
486
+ }
487
+ const partsOfSide = (side) => ({
488
+ ...(side.date !== undefined && { date: side.date }),
489
+ ...(side.wall !== undefined && { wall: side.wall }),
490
+ ...(side.zoneToken !== undefined && { zoneToken: side.zoneToken }),
491
+ ...(side.relative !== undefined && { relative: side.relative }),
492
+ });
493
+ /** The parts a group says, or `undefined` when they are not a v1 phrase. */
494
+ function partsOf(group) {
495
+ const atoms = group.items.map((i) => i.atom);
496
+ if (group.rangeAt === undefined) {
497
+ const side = sideOf(atoms);
498
+ if (side === undefined || side.bare === true)
499
+ return undefined;
500
+ const parts = partsOfSide(side);
501
+ return isTimeParts(parts) ? parts : undefined;
502
+ }
503
+ const left = sideOf(atoms.slice(0, group.rangeAt));
504
+ const right = sideOf(atoms.slice(group.rangeAt));
505
+ if (left === undefined || right === undefined)
506
+ return undefined;
507
+ if (left.span === true || right.span === true || right.bare === true)
508
+ return undefined;
509
+ if (left.bare === true && right.wall?.meridiem === undefined)
510
+ return undefined;
511
+ const outer = {};
512
+ // A day said before the first side's time, and not again, is the whole mention's…
513
+ const leftDay = left.date !== undefined || left.relative !== undefined;
514
+ const rightDay = right.date !== undefined || right.relative !== undefined;
515
+ if (leftDay && !rightDay && left.dayFirst === true && left.wall !== undefined) {
516
+ if (left.date !== undefined)
517
+ outer.date = left.date;
518
+ if (left.relative !== undefined)
519
+ outer.relative = left.relative;
520
+ delete left.date;
521
+ delete left.relative;
522
+ }
523
+ // …and so is a zone said after the second side, and not on the first.
524
+ if (right.zoneToken !== undefined && left.zoneToken === undefined) {
525
+ outer.zoneToken = right.zoneToken;
526
+ delete right.zoneToken;
527
+ }
528
+ const l = partsOfSide(left);
529
+ const r = partsOfSide(right);
530
+ if (Object.keys(l).length === 0 || Object.keys(r).length === 0)
531
+ return undefined;
532
+ const parts = { ...outer, rangeOf: [l, r] };
533
+ return isTimeParts(parts) ? parts : undefined;
534
+ }
535
+ /** The text's mentions, in the order written — at most `MAX_MENTIONS`, the port's bound. */
536
+ function mentionsOf(text) {
537
+ const atoms = atomsOf(text);
538
+ const groups = groupsOf(text, atoms, notReadSpans(text, atoms));
539
+ const mentions = [];
540
+ for (const group of groups) {
541
+ const quote = text.slice(group.start, group.end);
542
+ if (quote.trim() === '')
543
+ continue;
544
+ const parts = group.unreadable ? undefined : partsOf(group);
545
+ mentions.push(parts === undefined
546
+ ? { quote, parses: [], problem: 'unreadable' }
547
+ : { quote, parses: [parts] });
548
+ }
549
+ return mentions.slice(0, MAX_MENTIONS);
550
+ }
551
+ /**
552
+ * The library's careful English reader: a `kind: 'rule'` tokenizer over the
553
+ * v1 phrases of the time design's § 5.3, "unreadable" for every other time
554
+ * phrase it recognises. No dependency; deterministic over the text.
555
+ *
556
+ * @example
557
+ * ```ts
558
+ * Agent.create({ provider, model })
559
+ * .time({ zone: 'America/Los_Angeles', reader: englishTimeReader() })
560
+ * .build();
561
+ * ```
562
+ */
563
+ export function englishTimeReader(options = {}) {
564
+ return Object.freeze({
565
+ id: ENGLISH_TIME_READER_ID,
566
+ version: ENGLISH_TIME_READER_VERSION,
567
+ locale: options.locale ?? 'en-US',
568
+ kind: 'rule',
569
+ read: (text) => ({ mentions: mentionsOf(text) }),
570
+ });
571
+ }
572
+ //# sourceMappingURL=english.js.map