@raybase/core 0.0.2 → 0.3.3

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 (435) hide show
  1. package/LICENSE +21 -0
  2. package/dist/.admin-build/AdminApp.css +2 -0
  3. package/dist/.admin-build/AdminApp.js +77 -0
  4. package/dist/.admin-docs-build/AdminDocsApp.css +2 -0
  5. package/dist/.admin-docs-build/AdminDocsApp.js +45 -0
  6. package/dist/actions.d.ts +347 -0
  7. package/dist/actions.d.ts.map +1 -0
  8. package/dist/actions.js +661 -0
  9. package/dist/actions.js.map +1 -0
  10. package/dist/admin-assets/admin.7738f50720a8ed7b.css +2 -0
  11. package/dist/admin-assets/admin.8678cb61db34dc81.js +77 -0
  12. package/dist/admin-boot.d.ts +94 -0
  13. package/dist/admin-boot.d.ts.map +1 -0
  14. package/dist/admin-boot.js +139 -0
  15. package/dist/admin-boot.js.map +1 -0
  16. package/dist/admin-docs-content.d.ts +95 -0
  17. package/dist/admin-docs-content.d.ts.map +1 -0
  18. package/dist/admin-docs-content.js +463 -0
  19. package/dist/admin-docs-content.js.map +1 -0
  20. package/dist/admin-docs-ui.d.ts +11 -0
  21. package/dist/admin-docs-ui.d.ts.map +1 -0
  22. package/dist/admin-docs-ui.js +23 -0
  23. package/dist/admin-docs-ui.js.map +1 -0
  24. package/dist/admin-kit.d.ts +29 -0
  25. package/dist/admin-kit.js +1557 -0
  26. package/dist/admin-role.d.ts +8 -0
  27. package/dist/admin-role.d.ts.map +1 -0
  28. package/dist/admin-role.js +22 -0
  29. package/dist/admin-role.js.map +1 -0
  30. package/dist/admin-ui.d.ts +3 -0
  31. package/dist/admin-ui.d.ts.map +1 -0
  32. package/dist/admin-ui.js +16 -0
  33. package/dist/admin-ui.js.map +1 -0
  34. package/dist/agent-ai-chat.d.ts +127 -0
  35. package/dist/agent-ai-chat.d.ts.map +1 -0
  36. package/dist/agent-ai-chat.js +5975 -0
  37. package/dist/agent-ai-chat.js.map +1 -0
  38. package/dist/agent-chapter-archive.d.ts +214 -0
  39. package/dist/agent-chapter-archive.d.ts.map +1 -0
  40. package/dist/agent-chapter-archive.js +696 -0
  41. package/dist/agent-chapter-archive.js.map +1 -0
  42. package/dist/agent-chapter-search.d.ts +116 -0
  43. package/dist/agent-chapter-search.d.ts.map +1 -0
  44. package/dist/agent-chapter-search.js +605 -0
  45. package/dist/agent-chapter-search.js.map +1 -0
  46. package/dist/agent-chapter-tools.d.ts +45 -0
  47. package/dist/agent-chapter-tools.d.ts.map +1 -0
  48. package/dist/agent-chapter-tools.js +344 -0
  49. package/dist/agent-chapter-tools.js.map +1 -0
  50. package/dist/agent-chapters.d.ts +228 -0
  51. package/dist/agent-chapters.d.ts.map +1 -0
  52. package/dist/agent-chapters.js +737 -0
  53. package/dist/agent-chapters.js.map +1 -0
  54. package/dist/agent-data-parts.d.ts +167 -0
  55. package/dist/agent-data-parts.d.ts.map +1 -0
  56. package/dist/agent-data-parts.js +68 -0
  57. package/dist/agent-data-parts.js.map +1 -0
  58. package/dist/agent-errors.d.ts +41 -0
  59. package/dist/agent-errors.d.ts.map +1 -0
  60. package/dist/agent-errors.js +191 -0
  61. package/dist/agent-errors.js.map +1 -0
  62. package/dist/agent-follow-up-store.d.ts +273 -0
  63. package/dist/agent-follow-up-store.d.ts.map +1 -0
  64. package/dist/agent-follow-up-store.js +703 -0
  65. package/dist/agent-follow-up-store.js.map +1 -0
  66. package/dist/agent-follow-ups.d.ts +314 -0
  67. package/dist/agent-follow-ups.d.ts.map +1 -0
  68. package/dist/agent-follow-ups.js +840 -0
  69. package/dist/agent-follow-ups.js.map +1 -0
  70. package/dist/agent-memory.d.ts +323 -0
  71. package/dist/agent-memory.d.ts.map +1 -0
  72. package/dist/agent-memory.js +1270 -0
  73. package/dist/agent-memory.js.map +1 -0
  74. package/dist/agent-message-parts.d.ts +58 -0
  75. package/dist/agent-message-parts.d.ts.map +1 -0
  76. package/dist/agent-message-parts.js +163 -0
  77. package/dist/agent-message-parts.js.map +1 -0
  78. package/dist/agent-remote-mcp-credentials.d.ts +154 -0
  79. package/dist/agent-remote-mcp-credentials.d.ts.map +1 -0
  80. package/dist/agent-remote-mcp-credentials.js +287 -0
  81. package/dist/agent-remote-mcp-credentials.js.map +1 -0
  82. package/dist/agent-remote-mcp-crypto.d.ts +32 -0
  83. package/dist/agent-remote-mcp-crypto.d.ts.map +1 -0
  84. package/dist/agent-remote-mcp-crypto.js +101 -0
  85. package/dist/agent-remote-mcp-crypto.js.map +1 -0
  86. package/dist/agent-remote-mcp-install.d.ts +299 -0
  87. package/dist/agent-remote-mcp-install.d.ts.map +1 -0
  88. package/dist/agent-remote-mcp-install.js +785 -0
  89. package/dist/agent-remote-mcp-install.js.map +1 -0
  90. package/dist/agent-remote-mcp-oauth.d.ts +73 -0
  91. package/dist/agent-remote-mcp-oauth.d.ts.map +1 -0
  92. package/dist/agent-remote-mcp-oauth.js +344 -0
  93. package/dist/agent-remote-mcp-oauth.js.map +1 -0
  94. package/dist/agent-remote-mcp-transport.d.ts +46 -0
  95. package/dist/agent-remote-mcp-transport.d.ts.map +1 -0
  96. package/dist/agent-remote-mcp-transport.js +225 -0
  97. package/dist/agent-remote-mcp-transport.js.map +1 -0
  98. package/dist/agent-remote-mcp.d.ts +147 -0
  99. package/dist/agent-remote-mcp.d.ts.map +1 -0
  100. package/dist/agent-remote-mcp.js +681 -0
  101. package/dist/agent-remote-mcp.js.map +1 -0
  102. package/dist/agent-room-redaction.d.ts +66 -0
  103. package/dist/agent-room-redaction.d.ts.map +1 -0
  104. package/dist/agent-room-redaction.js +264 -0
  105. package/dist/agent-room-redaction.js.map +1 -0
  106. package/dist/agent-rooms.d.ts +209 -0
  107. package/dist/agent-rooms.d.ts.map +1 -0
  108. package/dist/agent-rooms.js +244 -0
  109. package/dist/agent-rooms.js.map +1 -0
  110. package/dist/agent-runtime.d.ts +541 -0
  111. package/dist/agent-runtime.d.ts.map +1 -0
  112. package/dist/agent-runtime.js +4260 -0
  113. package/dist/agent-runtime.js.map +1 -0
  114. package/dist/agent-skill-archive.d.ts +20 -0
  115. package/dist/agent-skill-archive.d.ts.map +1 -0
  116. package/dist/agent-skill-archive.js +316 -0
  117. package/dist/agent-skill-archive.js.map +1 -0
  118. package/dist/agent-skill-discovery.d.ts +96 -0
  119. package/dist/agent-skill-discovery.d.ts.map +1 -0
  120. package/dist/agent-skill-discovery.js +464 -0
  121. package/dist/agent-skill-discovery.js.map +1 -0
  122. package/dist/agent-skill-format.d.ts +57 -0
  123. package/dist/agent-skill-format.d.ts.map +1 -0
  124. package/dist/agent-skill-format.js +238 -0
  125. package/dist/agent-skill-format.js.map +1 -0
  126. package/dist/agent-skill-import.d.ts +64 -0
  127. package/dist/agent-skill-import.d.ts.map +1 -0
  128. package/dist/agent-skill-import.js +295 -0
  129. package/dist/agent-skill-import.js.map +1 -0
  130. package/dist/agent-skill-publish.d.ts +51 -0
  131. package/dist/agent-skill-publish.d.ts.map +1 -0
  132. package/dist/agent-skill-publish.js +136 -0
  133. package/dist/agent-skill-publish.js.map +1 -0
  134. package/dist/agent-skill-store.d.ts +252 -0
  135. package/dist/agent-skill-store.d.ts.map +1 -0
  136. package/dist/agent-skill-store.js +514 -0
  137. package/dist/agent-skill-store.js.map +1 -0
  138. package/dist/agent-skills.d.ts +85 -0
  139. package/dist/agent-skills.d.ts.map +1 -0
  140. package/dist/agent-skills.js +291 -0
  141. package/dist/agent-skills.js.map +1 -0
  142. package/dist/agent-transcript-pager.d.ts +77 -0
  143. package/dist/agent-transcript-pager.d.ts.map +1 -0
  144. package/dist/agent-transcript-pager.js +210 -0
  145. package/dist/agent-transcript-pager.js.map +1 -0
  146. package/dist/agent-user-data-parts.d.ts +20 -0
  147. package/dist/agent-user-data-parts.d.ts.map +1 -0
  148. package/dist/agent-user-data-parts.js +161 -0
  149. package/dist/agent-user-data-parts.js.map +1 -0
  150. package/dist/agent-user-transcript.d.ts +46 -0
  151. package/dist/agent-user-transcript.d.ts.map +1 -0
  152. package/dist/agent-user-transcript.js +106 -0
  153. package/dist/agent-user-transcript.js.map +1 -0
  154. package/dist/agent-voice-notes.d.ts +15 -0
  155. package/dist/agent-voice-notes.d.ts.map +1 -0
  156. package/dist/agent-voice-notes.js +17 -0
  157. package/dist/agent-voice-notes.js.map +1 -0
  158. package/dist/agent-wakes.d.ts +213 -0
  159. package/dist/agent-wakes.d.ts.map +1 -0
  160. package/dist/agent-wakes.js +534 -0
  161. package/dist/agent-wakes.js.map +1 -0
  162. package/dist/agent.d.ts +1780 -0
  163. package/dist/agent.d.ts.map +1 -0
  164. package/dist/agent.js +3123 -0
  165. package/dist/agent.js.map +1 -0
  166. package/dist/ai.d.ts +583 -0
  167. package/dist/ai.d.ts.map +1 -0
  168. package/dist/ai.js +1858 -0
  169. package/dist/ai.js.map +1 -0
  170. package/dist/app-manifest.d.ts +255 -0
  171. package/dist/app-manifest.d.ts.map +1 -0
  172. package/dist/app-manifest.js +372 -0
  173. package/dist/app-manifest.js.map +1 -0
  174. package/dist/app-users.d.ts +30 -0
  175. package/dist/app-users.d.ts.map +1 -0
  176. package/dist/app-users.js +91 -0
  177. package/dist/app-users.js.map +1 -0
  178. package/dist/audit-archive.d.ts +85 -0
  179. package/dist/audit-archive.d.ts.map +1 -0
  180. package/dist/audit-archive.js +178 -0
  181. package/dist/audit-archive.js.map +1 -0
  182. package/dist/audit.d.ts +54 -0
  183. package/dist/audit.d.ts.map +1 -0
  184. package/dist/audit.js +95 -0
  185. package/dist/audit.js.map +1 -0
  186. package/dist/auth-logger.d.ts +28 -0
  187. package/dist/auth-logger.d.ts.map +1 -0
  188. package/dist/auth-logger.js +53 -0
  189. package/dist/auth-logger.js.map +1 -0
  190. package/dist/auth-password-secret.d.ts +59 -0
  191. package/dist/auth-password-secret.d.ts.map +1 -0
  192. package/dist/auth-password-secret.js +409 -0
  193. package/dist/auth-password-secret.js.map +1 -0
  194. package/dist/auth-schema.d.ts +120 -0
  195. package/dist/auth-schema.d.ts.map +1 -0
  196. package/dist/auth-schema.js +285 -0
  197. package/dist/auth-schema.js.map +1 -0
  198. package/dist/auth.d.ts +321 -0
  199. package/dist/auth.d.ts.map +1 -0
  200. package/dist/auth.js +1562 -0
  201. package/dist/auth.js.map +1 -0
  202. package/dist/backup-archive.d.ts +257 -0
  203. package/dist/backup-archive.d.ts.map +1 -0
  204. package/dist/backup-archive.js +2068 -0
  205. package/dist/backup-archive.js.map +1 -0
  206. package/dist/backup-crypto.d.ts +313 -0
  207. package/dist/backup-crypto.d.ts.map +1 -0
  208. package/dist/backup-crypto.js +693 -0
  209. package/dist/backup-crypto.js.map +1 -0
  210. package/dist/backup-format.d.ts +200 -0
  211. package/dist/backup-format.d.ts.map +1 -0
  212. package/dist/backup-format.js +1247 -0
  213. package/dist/backup-format.js.map +1 -0
  214. package/dist/cli.d.ts +9 -0
  215. package/dist/cli.d.ts.map +1 -0
  216. package/dist/cli.js +15 -0
  217. package/dist/cli.js.map +1 -0
  218. package/dist/clock.d.ts +35 -0
  219. package/dist/clock.d.ts.map +1 -0
  220. package/dist/clock.js +83 -0
  221. package/dist/clock.js.map +1 -0
  222. package/dist/data-client.d.ts +187 -0
  223. package/dist/data-client.d.ts.map +1 -0
  224. package/dist/data-client.js +590 -0
  225. package/dist/data-client.js.map +1 -0
  226. package/dist/data-secrets.d.ts +164 -0
  227. package/dist/data-secrets.d.ts.map +1 -0
  228. package/dist/data-secrets.js +383 -0
  229. package/dist/data-secrets.js.map +1 -0
  230. package/dist/db.d.ts +453 -0
  231. package/dist/db.d.ts.map +1 -0
  232. package/dist/db.js +324 -0
  233. package/dist/db.js.map +1 -0
  234. package/dist/dev-activity.d.ts +48 -0
  235. package/dist/dev-activity.d.ts.map +1 -0
  236. package/dist/dev-activity.js +50 -0
  237. package/dist/dev-activity.js.map +1 -0
  238. package/dist/do.d.ts +429 -0
  239. package/dist/do.d.ts.map +1 -0
  240. package/dist/do.js +4526 -0
  241. package/dist/do.js.map +1 -0
  242. package/dist/email.d.ts +137 -0
  243. package/dist/email.d.ts.map +1 -0
  244. package/dist/email.js +527 -0
  245. package/dist/email.js.map +1 -0
  246. package/dist/generated/admin-assets.d.ts +16 -0
  247. package/dist/generated/admin-assets.d.ts.map +1 -0
  248. package/dist/generated/admin-assets.js +16 -0
  249. package/dist/generated/admin-assets.js.map +1 -0
  250. package/dist/generated/admin-docs-assets.d.ts +3 -0
  251. package/dist/generated/admin-docs-assets.d.ts.map +1 -0
  252. package/dist/generated/admin-docs-assets.js +3 -0
  253. package/dist/generated/admin-docs-assets.js.map +1 -0
  254. package/dist/handoff-consumer.d.ts +79 -0
  255. package/dist/handoff-consumer.d.ts.map +1 -0
  256. package/dist/handoff-consumer.js +300 -0
  257. package/dist/handoff-consumer.js.map +1 -0
  258. package/dist/handoff.d.ts +70 -0
  259. package/dist/handoff.d.ts.map +1 -0
  260. package/dist/handoff.js +228 -0
  261. package/dist/handoff.js.map +1 -0
  262. package/dist/host-auth.d.ts +47 -0
  263. package/dist/host-auth.d.ts.map +1 -0
  264. package/dist/host-auth.js +59 -0
  265. package/dist/host-auth.js.map +1 -0
  266. package/dist/host-user.d.ts +15 -0
  267. package/dist/host-user.d.ts.map +1 -0
  268. package/dist/host-user.js +23 -0
  269. package/dist/host-user.js.map +1 -0
  270. package/dist/html.d.ts +35 -0
  271. package/dist/html.d.ts.map +1 -0
  272. package/dist/html.js +634 -0
  273. package/dist/html.js.map +1 -0
  274. package/dist/http-error.d.ts +13 -0
  275. package/dist/http-error.d.ts.map +1 -0
  276. package/dist/http-error.js +15 -0
  277. package/dist/http-error.js.map +1 -0
  278. package/dist/imports.d.ts +219 -0
  279. package/dist/imports.d.ts.map +1 -0
  280. package/dist/imports.js +571 -0
  281. package/dist/imports.js.map +1 -0
  282. package/dist/index.d.ts +78 -0
  283. package/dist/index.d.ts.map +1 -0
  284. package/dist/index.js +76 -0
  285. package/dist/index.js.map +1 -0
  286. package/dist/inference-tape.d.ts +64 -0
  287. package/dist/inference-tape.d.ts.map +1 -0
  288. package/dist/inference-tape.js +278 -0
  289. package/dist/inference-tape.js.map +1 -0
  290. package/dist/internal.d.ts +15 -0
  291. package/dist/internal.d.ts.map +1 -0
  292. package/dist/internal.js +48 -0
  293. package/dist/internal.js.map +1 -0
  294. package/dist/jobs.d.ts +796 -0
  295. package/dist/jobs.d.ts.map +1 -0
  296. package/dist/jobs.js +538 -0
  297. package/dist/jobs.js.map +1 -0
  298. package/dist/json-schema.d.ts +91 -0
  299. package/dist/json-schema.d.ts.map +1 -0
  300. package/dist/json-schema.js +884 -0
  301. package/dist/json-schema.js.map +1 -0
  302. package/dist/knowledge.d.ts +33 -0
  303. package/dist/knowledge.d.ts.map +1 -0
  304. package/dist/knowledge.js +348 -0
  305. package/dist/knowledge.js.map +1 -0
  306. package/dist/local-dev-chrome.d.ts +29 -0
  307. package/dist/local-dev-chrome.d.ts.map +1 -0
  308. package/dist/local-dev-chrome.js +514 -0
  309. package/dist/local-dev-chrome.js.map +1 -0
  310. package/dist/local-dev-personas.d.ts +15 -0
  311. package/dist/local-dev-personas.d.ts.map +1 -0
  312. package/dist/local-dev-personas.js +46 -0
  313. package/dist/local-dev-personas.js.map +1 -0
  314. package/dist/mcp.d.ts +567 -0
  315. package/dist/mcp.d.ts.map +1 -0
  316. package/dist/mcp.js +2480 -0
  317. package/dist/mcp.js.map +1 -0
  318. package/dist/modules.d.ts +145 -0
  319. package/dist/modules.d.ts.map +1 -0
  320. package/dist/modules.js +164 -0
  321. package/dist/modules.js.map +1 -0
  322. package/dist/notification-client.d.ts +94 -0
  323. package/dist/notification-client.d.ts.map +1 -0
  324. package/dist/notification-client.js +127 -0
  325. package/dist/notification-client.js.map +1 -0
  326. package/dist/notifications.d.ts +447 -0
  327. package/dist/notifications.d.ts.map +1 -0
  328. package/dist/notifications.js +1625 -0
  329. package/dist/notifications.js.map +1 -0
  330. package/dist/operator-data-query.d.ts +117 -0
  331. package/dist/operator-data-query.d.ts.map +1 -0
  332. package/dist/operator-data-query.js +431 -0
  333. package/dist/operator-data-query.js.map +1 -0
  334. package/dist/operator-mcp.d.ts +63 -0
  335. package/dist/operator-mcp.d.ts.map +1 -0
  336. package/dist/operator-mcp.js +2828 -0
  337. package/dist/operator-mcp.js.map +1 -0
  338. package/dist/outbound-https.d.ts +24 -0
  339. package/dist/outbound-https.d.ts.map +1 -0
  340. package/dist/outbound-https.js +172 -0
  341. package/dist/outbound-https.js.map +1 -0
  342. package/dist/pitr.d.ts +60 -0
  343. package/dist/pitr.d.ts.map +1 -0
  344. package/dist/pitr.js +94 -0
  345. package/dist/pitr.js.map +1 -0
  346. package/dist/platform.d.ts +199 -0
  347. package/dist/platform.d.ts.map +1 -0
  348. package/dist/platform.js +196 -0
  349. package/dist/platform.js.map +1 -0
  350. package/dist/policies.d.ts +115 -0
  351. package/dist/policies.d.ts.map +1 -0
  352. package/dist/policies.js +158 -0
  353. package/dist/policies.js.map +1 -0
  354. package/dist/principal.d.ts +143 -0
  355. package/dist/principal.d.ts.map +1 -0
  356. package/dist/principal.js +174 -0
  357. package/dist/principal.js.map +1 -0
  358. package/dist/realtime.d.ts +280 -0
  359. package/dist/realtime.d.ts.map +1 -0
  360. package/dist/realtime.js +578 -0
  361. package/dist/realtime.js.map +1 -0
  362. package/dist/retrieval.d.ts +263 -0
  363. package/dist/retrieval.d.ts.map +1 -0
  364. package/dist/retrieval.js +602 -0
  365. package/dist/retrieval.js.map +1 -0
  366. package/dist/runtime-error-client.d.ts +10 -0
  367. package/dist/runtime-error-client.d.ts.map +1 -0
  368. package/dist/runtime-error-client.js +70 -0
  369. package/dist/runtime-error-client.js.map +1 -0
  370. package/dist/runtime-errors.d.ts +180 -0
  371. package/dist/runtime-errors.d.ts.map +1 -0
  372. package/dist/runtime-errors.js +572 -0
  373. package/dist/runtime-errors.js.map +1 -0
  374. package/dist/schema.d.ts +434 -0
  375. package/dist/schema.d.ts.map +1 -0
  376. package/dist/schema.js +232 -0
  377. package/dist/schema.js.map +1 -0
  378. package/dist/search.d.ts +216 -0
  379. package/dist/search.d.ts.map +1 -0
  380. package/dist/search.js +785 -0
  381. package/dist/search.js.map +1 -0
  382. package/dist/settings.d.ts +191 -0
  383. package/dist/settings.d.ts.map +1 -0
  384. package/dist/settings.js +478 -0
  385. package/dist/settings.js.map +1 -0
  386. package/dist/sql.d.ts +7 -0
  387. package/dist/sql.d.ts.map +1 -0
  388. package/dist/sql.js +30 -0
  389. package/dist/sql.js.map +1 -0
  390. package/dist/storage-client.d.ts +69 -0
  391. package/dist/storage-client.d.ts.map +1 -0
  392. package/dist/storage-client.js +469 -0
  393. package/dist/storage-client.js.map +1 -0
  394. package/dist/storage.d.ts +21 -0
  395. package/dist/storage.d.ts.map +1 -0
  396. package/dist/storage.js +82 -0
  397. package/dist/storage.js.map +1 -0
  398. package/dist/subject-domains.d.ts +15 -0
  399. package/dist/subject-domains.d.ts.map +1 -0
  400. package/dist/subject-domains.js +38 -0
  401. package/dist/subject-domains.js.map +1 -0
  402. package/dist/support.d.ts +132 -0
  403. package/dist/support.d.ts.map +1 -0
  404. package/dist/support.js +483 -0
  405. package/dist/support.js.map +1 -0
  406. package/dist/system-tables.d.ts +12 -0
  407. package/dist/system-tables.d.ts.map +1 -0
  408. package/dist/system-tables.js +225 -0
  409. package/dist/system-tables.js.map +1 -0
  410. package/dist/test.d.ts +57 -0
  411. package/dist/test.d.ts.map +1 -0
  412. package/dist/test.js +454 -0
  413. package/dist/test.js.map +1 -0
  414. package/dist/vite.d.ts +82 -0
  415. package/dist/vite.d.ts.map +1 -0
  416. package/dist/vite.js +82 -0
  417. package/dist/vite.js.map +1 -0
  418. package/dist/webpush-crypto.d.ts +39 -0
  419. package/dist/webpush-crypto.d.ts.map +1 -0
  420. package/dist/webpush-crypto.js +213 -0
  421. package/dist/webpush-crypto.js.map +1 -0
  422. package/dist/webpush-private.d.ts +11 -0
  423. package/dist/webpush-private.d.ts.map +1 -0
  424. package/dist/webpush-private.js +11 -0
  425. package/dist/webpush-private.js.map +1 -0
  426. package/dist/webpush.d.ts +86 -0
  427. package/dist/webpush.d.ts.map +1 -0
  428. package/dist/webpush.js +375 -0
  429. package/dist/webpush.js.map +1 -0
  430. package/dist/worker.d.ts +185 -0
  431. package/dist/worker.d.ts.map +1 -0
  432. package/dist/worker.js +13021 -0
  433. package/dist/worker.js.map +1 -0
  434. package/package.json +161 -8
  435. package/README.md +0 -3
@@ -0,0 +1,840 @@
1
+ import { recordAudit } from "./audit.js";
2
+ import { sha256Hex, stableJson } from "./internal.js";
3
+ import { durationMs } from "./jobs.js";
4
+ import { nowIso, q, randomId } from "./sql.js";
5
+ import { continueAgentFollowUpStore, getAgentFollowUp, parsedFollowUpJson } from "./agent-follow-up-store.js";
6
+ export { followUpDispatchRecencyMs, followUpMaxDispatchAttempts, followUpStaleRunningMs, raybaseAgentFollowUpSystemTables } from "./agent-follow-up-store.js";
7
+ export const raybaseAgentFollowUpLimits = {
8
+ maxPending: 32,
9
+ dailyCreates: 48,
10
+ apiMinDelayMs: 60_000,
11
+ toolMinDelayMs: 5 * 60_000,
12
+ maxHorizonMs: 30 * 24 * 60 * 60_000,
13
+ minIdleAfterMs: 60_000,
14
+ minFallbackEveryMs: 5 * 60_000,
15
+ maxKeyChars: 128,
16
+ maxBodyChars: 4_000,
17
+ maxContextBytes: 32_768,
18
+ maxReasonChars: 500,
19
+ maxConversationBytes: 8_192,
20
+ maxWakeEventChars: 128,
21
+ maxWakeMatchKeys: 16,
22
+ maxWakeKeyChars: 64,
23
+ maxWakeMatchBytes: 2_048,
24
+ maxWakePayloadKeys: 32,
25
+ maxWakePayloadBytes: 8_192
26
+ };
27
+ export class AgentFollowUpPolicyError extends Error {
28
+ reason;
29
+ details;
30
+ constructor(reason, message, details = {}) {
31
+ super(message);
32
+ this.reason = reason;
33
+ this.details = details;
34
+ this.name = "AgentFollowUpPolicyError";
35
+ }
36
+ }
37
+ const keyPattern = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
38
+ function positiveInteger(value, fallback, label) {
39
+ if (value === undefined)
40
+ return fallback;
41
+ if (!Number.isInteger(value) || value < 1)
42
+ throw new Error(`${label} must be a positive integer`);
43
+ return value;
44
+ }
45
+ function positiveDuration(value, fallback, label) {
46
+ if (value === undefined)
47
+ return fallback;
48
+ let parsed;
49
+ try {
50
+ parsed = durationMs(value);
51
+ }
52
+ catch (error) {
53
+ throw new Error(`${label} must be a positive duration: ${error instanceof Error ? error.message : String(error)}`);
54
+ }
55
+ if (!Number.isFinite(parsed) || parsed <= 0)
56
+ throw new Error(`${label} must be a positive duration`);
57
+ return parsed;
58
+ }
59
+ export function normalizeAgentFollowUpsConfig(agent) {
60
+ if (agent.followUps === undefined)
61
+ return null;
62
+ if (!agent.followUps || typeof agent.followUps !== "object" || Array.isArray(agent.followUps) || agent.followUps.enabled !== true) {
63
+ throw new Error(`Raybase agent ${agent.name} followUps must be configured with { enabled: true }`);
64
+ }
65
+ const limits = agent.followUps.limits ?? {};
66
+ if (!limits || typeof limits !== "object" || Array.isArray(limits)) {
67
+ throw new Error(`Raybase agent ${agent.name} followUps.limits must be an object`);
68
+ }
69
+ const minDelayMs = positiveDuration(limits.minDelay, null, `Raybase agent ${agent.name} followUps.limits.minDelay`);
70
+ const maxHorizonMs = positiveDuration(limits.maxHorizon, raybaseAgentFollowUpLimits.maxHorizonMs, `Raybase agent ${agent.name} followUps.limits.maxHorizon`);
71
+ if (minDelayMs !== null && minDelayMs > maxHorizonMs) {
72
+ throw new Error(`Raybase agent ${agent.name} followUps.limits.minDelay must not exceed maxHorizon`);
73
+ }
74
+ return {
75
+ maxPending: positiveInteger(limits.maxPending, raybaseAgentFollowUpLimits.maxPending, `Raybase agent ${agent.name} followUps.limits.maxPending`),
76
+ dailyCreates: positiveInteger(limits.dailyCreates, raybaseAgentFollowUpLimits.dailyCreates, `Raybase agent ${agent.name} followUps.limits.dailyCreates`),
77
+ minDelayMs,
78
+ maxHorizonMs
79
+ };
80
+ }
81
+ export function validateAgentFollowUpsForAgent(agent) {
82
+ normalizeAgentFollowUpsConfig(agent);
83
+ }
84
+ function validKey(value, label) {
85
+ if (typeof value !== "string" || !keyPattern.test(value.trim())) {
86
+ throw new AgentFollowUpPolicyError("invalid-request", `${label} must start with an alphanumeric character and contain at most 128 alphanumeric, dot, underscore, colon, or hyphen characters`);
87
+ }
88
+ return value.trim();
89
+ }
90
+ function textValue(value, max, label, required = false) {
91
+ if (value === undefined || value === null) {
92
+ if (required)
93
+ throw new AgentFollowUpPolicyError("invalid-request", `${label} is required`);
94
+ return null;
95
+ }
96
+ if (typeof value !== "string")
97
+ throw new AgentFollowUpPolicyError("invalid-request", `${label} must be a string`);
98
+ const normalized = value.trim();
99
+ if (!normalized && required)
100
+ throw new AgentFollowUpPolicyError("invalid-request", `${label} is required`);
101
+ if (normalized.length > max)
102
+ throw new AgentFollowUpPolicyError("invalid-request", `${label} must be at most ${max} characters`);
103
+ return normalized || null;
104
+ }
105
+ function boundedJson(value, maxBytes, label) {
106
+ if (value === undefined)
107
+ return null;
108
+ let json;
109
+ try {
110
+ json = stableJson(value);
111
+ }
112
+ catch {
113
+ throw new AgentFollowUpPolicyError("invalid-request", `${label} must be JSON serializable`);
114
+ }
115
+ if (new TextEncoder().encode(json).byteLength > maxBytes) {
116
+ throw new AgentFollowUpPolicyError("invalid-request", `${label} is too large`);
117
+ }
118
+ return json;
119
+ }
120
+ const wakeEventPattern = /^[A-Za-z][A-Za-z0-9_.:-]{0,127}$/;
121
+ /** Validates one app-chosen wake event name. */
122
+ export function normalizeAgentFollowUpWakeEvent(value, label = "Follow-up wakeOn.event") {
123
+ if (typeof value !== "string" || !wakeEventPattern.test(value.trim())) {
124
+ throw new AgentFollowUpPolicyError("invalid-request", `${label} must start with a letter and contain at most ${raybaseAgentFollowUpLimits.maxWakeEventChars} letters, digits, dots, underscores, colons, or hyphens`);
125
+ }
126
+ return value.trim();
127
+ }
128
+ function flatScalarObject(value, input) {
129
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
130
+ throw new AgentFollowUpPolicyError("invalid-request", `${input.label} must be a flat object`);
131
+ }
132
+ const entries = Object.entries(value);
133
+ if (entries.length > input.maxKeys) {
134
+ throw new AgentFollowUpPolicyError("invalid-request", `${input.label} must have at most ${input.maxKeys} keys`);
135
+ }
136
+ const normalized = {};
137
+ for (const [key, entry] of entries) {
138
+ if (!key.trim() || key.length > raybaseAgentFollowUpLimits.maxWakeKeyChars) {
139
+ throw new AgentFollowUpPolicyError("invalid-request", `${input.label} keys must be non-empty and at most ${raybaseAgentFollowUpLimits.maxWakeKeyChars} characters`);
140
+ }
141
+ if (entry === undefined || (entry === null && !input.allowNull))
142
+ continue;
143
+ if (typeof entry !== "string"
144
+ && typeof entry !== "boolean"
145
+ && entry !== null
146
+ && !(typeof entry === "number" && Number.isFinite(entry))) {
147
+ throw new AgentFollowUpPolicyError("invalid-request", `${input.label} values must be strings, finite numbers, or booleans`);
148
+ }
149
+ normalized[key] = entry;
150
+ }
151
+ if (new TextEncoder().encode(stableJson(normalized)).byteLength > input.maxBytes) {
152
+ throw new AgentFollowUpPolicyError("invalid-request", `${input.label} is too large`);
153
+ }
154
+ return normalized;
155
+ }
156
+ /**
157
+ * Normalizes the optional `wakeOn` trigger. Returns null when the follow-up
158
+ * waits only on time.
159
+ */
160
+ export function normalizeAgentFollowUpWakeOn(value) {
161
+ if (value === undefined || value === null)
162
+ return null;
163
+ if (typeof value !== "object" || Array.isArray(value)) {
164
+ throw new AgentFollowUpPolicyError("invalid-request", "Follow-up wakeOn must be an object");
165
+ }
166
+ const record = value;
167
+ const event = normalizeAgentFollowUpWakeEvent(record.event);
168
+ if (record.match === undefined || record.match === null)
169
+ return { event, match: null };
170
+ const match = flatScalarObject(record.match, {
171
+ label: "Follow-up wakeOn.match",
172
+ maxKeys: raybaseAgentFollowUpLimits.maxWakeMatchKeys,
173
+ maxBytes: raybaseAgentFollowUpLimits.maxWakeMatchBytes,
174
+ allowNull: false
175
+ });
176
+ return { event, match: Object.keys(match).length ? match : null };
177
+ }
178
+ /** Normalizes the payload an app fires with a wake. */
179
+ export function normalizeAgentFollowUpWakePayload(value) {
180
+ if (value === undefined || value === null)
181
+ return {};
182
+ return flatScalarObject(value, {
183
+ label: "Follow-up wake payload",
184
+ maxKeys: raybaseAgentFollowUpLimits.maxWakePayloadKeys,
185
+ maxBytes: raybaseAgentFollowUpLimits.maxWakePayloadBytes,
186
+ allowNull: true
187
+ });
188
+ }
189
+ /**
190
+ * Exact equality on a flat object: every `match` entry must equal the payload's
191
+ * value for that key. No expressions, no coercion, no missing keys.
192
+ */
193
+ export function agentFollowUpWakeMatches(match, payload) {
194
+ if (!match)
195
+ return true;
196
+ for (const [key, expected] of Object.entries(match)) {
197
+ if (!Object.prototype.hasOwnProperty.call(payload, key))
198
+ return false;
199
+ if (payload[key] !== expected)
200
+ return false;
201
+ }
202
+ return true;
203
+ }
204
+ function parsedWakeOn(row) {
205
+ if (!row.wakeOnEvent)
206
+ return null;
207
+ const match = parsedFollowUpJson(row.wakeOnMatchJson);
208
+ return {
209
+ event: row.wakeOnEvent,
210
+ match: match && typeof match === "object" && !Array.isArray(match) ? match : null
211
+ };
212
+ }
213
+ function parsedWakePayload(row) {
214
+ const payload = parsedFollowUpJson(row.wokePayloadJson);
215
+ return payload && typeof payload === "object" && !Array.isArray(payload)
216
+ ? payload
217
+ : null;
218
+ }
219
+ function parseContext(row) {
220
+ if (!row.contextJson)
221
+ return null;
222
+ try {
223
+ return JSON.parse(row.contextJson);
224
+ }
225
+ catch {
226
+ return null;
227
+ }
228
+ }
229
+ export function followUpSafeProjection(row) {
230
+ return {
231
+ id: row.id,
232
+ agentName: row.agentName,
233
+ key: row.key,
234
+ ownerKey: row.ownerKey,
235
+ body: row.body,
236
+ context: parseContext(row),
237
+ dueAt: row.dueAt,
238
+ mode: row.onDue === "lapse" ? "lapse" : row.fallbackEveryMs === null ? "once" : "continuing",
239
+ status: row.status,
240
+ runCount: row.runCount,
241
+ maxRuns: row.maxRuns,
242
+ fallbackEveryMs: row.fallbackEveryMs,
243
+ drifted: row.driftCount > 0,
244
+ wakeOn: parsedWakeOn(row),
245
+ wokeBy: row.wokeBy === "event" ? "event" : null,
246
+ wokeEvent: row.wokeEvent,
247
+ wokePayload: parsedWakePayload(row),
248
+ wokeAt: row.wokeAt,
249
+ createdBy: row.createdBy,
250
+ createdAt: row.createdAt
251
+ };
252
+ }
253
+ export function followUpToolProjection(row) {
254
+ const safe = followUpSafeProjection(row);
255
+ return {
256
+ followUpId: safe.id,
257
+ key: safe.key,
258
+ ownerKey: safe.ownerKey,
259
+ status: safe.status,
260
+ dueAt: safe.dueAt,
261
+ mode: safe.mode,
262
+ runCount: safe.runCount,
263
+ maxRuns: safe.maxRuns,
264
+ drifted: safe.drifted,
265
+ body: safe.body,
266
+ context: safe.context,
267
+ wakeOn: safe.wakeOn,
268
+ wokeBy: safe.wokeBy,
269
+ wokeEvent: safe.wokeEvent,
270
+ wokePayload: safe.wokePayload
271
+ };
272
+ }
273
+ export function followUpAdminProjection(row) {
274
+ let context = null;
275
+ let contextInvalid = false;
276
+ if (row.contextJson) {
277
+ try {
278
+ context = JSON.parse(row.contextJson);
279
+ }
280
+ catch {
281
+ contextInvalid = true;
282
+ }
283
+ }
284
+ return {
285
+ ...row,
286
+ context,
287
+ contextInvalid,
288
+ mode: followUpSafeProjection(row).mode,
289
+ drifted: row.driftCount > 0,
290
+ wakeOn: parsedWakeOn(row),
291
+ wokeBy: row.wokeBy === "event"
292
+ ? "event"
293
+ : row.wakeOnEvent && (row.status === "fired" || row.status === "lapsed")
294
+ ? "deadline"
295
+ : null,
296
+ wokePayload: parsedWakePayload(row)
297
+ };
298
+ }
299
+ async function normalizedConversation(agentName, followUpId, value) {
300
+ if (!value || value.mode === undefined || value.mode === "new") {
301
+ const digest = (await sha256Hex(stableJson({ agentName, followUpId }))).slice(0, 32);
302
+ return { mode: "thread", key: followUpId, conversationId: `agent_follow_up_thread:${digest}` };
303
+ }
304
+ if (value.mode === "thread") {
305
+ if (typeof value.key !== "string" || !value.key.trim()) {
306
+ throw new AgentFollowUpPolicyError("invalid-request", 'Follow-up conversation mode "thread" requires a non-empty key');
307
+ }
308
+ const key = value.key.trim();
309
+ if (key.length > 512)
310
+ throw new AgentFollowUpPolicyError("invalid-request", "Follow-up conversation thread key is too long");
311
+ const digest = (await sha256Hex(stableJson({ agentName, key }))).slice(0, 32);
312
+ return { mode: "thread", key, conversationId: `agent_follow_up_thread:${digest}`, metadata: value.metadata ?? null };
313
+ }
314
+ if (value.mode === "chat") {
315
+ if (typeof value.conversationId !== "string" || !value.conversationId.trim()) {
316
+ throw new AgentFollowUpPolicyError("invalid-request", 'Follow-up conversation mode "chat" requires a conversationId');
317
+ }
318
+ return { mode: "chat", conversationId: value.conversationId.trim() };
319
+ }
320
+ throw new AgentFollowUpPolicyError("invalid-request", "Unsupported follow-up conversation mode");
321
+ }
322
+ function requestedDueAt(options, nowMs) {
323
+ const hasAt = options.at !== undefined;
324
+ const hasIn = options.in !== undefined;
325
+ if (hasAt === hasIn)
326
+ throw new AgentFollowUpPolicyError("invalid-request", 'Provide exactly one of follow-up options "at" or "in"');
327
+ if (hasAt) {
328
+ const parsed = Date.parse(options.at);
329
+ if (!Number.isFinite(parsed))
330
+ throw new AgentFollowUpPolicyError("invalid-request", "Follow-up at must be a valid ISO timestamp");
331
+ return parsed;
332
+ }
333
+ try {
334
+ return nowMs + durationMs(options.in);
335
+ }
336
+ catch (error) {
337
+ throw new AgentFollowUpPolicyError("invalid-request", error instanceof Error ? error.message : String(error));
338
+ }
339
+ }
340
+ async function constrainedDueAt(agent, requestedMs, input) {
341
+ const nowMs = Date.parse(input.now);
342
+ const floor = nowMs + input.minDelayMs;
343
+ const ceiling = nowMs + input.maxHorizonMs;
344
+ let requested = new Date(Math.min(Math.max(requestedMs, floor), ceiling));
345
+ if (agent.followUps?.constrainDueAt) {
346
+ requested = await agent.followUps.constrainDueAt(requested, {
347
+ agentName: agent.name,
348
+ key: input.key,
349
+ ownerKey: input.ownerKey,
350
+ createdBy: input.createdBy,
351
+ source: input.source,
352
+ now: new Date(nowMs),
353
+ env: input.env
354
+ });
355
+ if (!(requested instanceof Date) || !Number.isFinite(requested.getTime())) {
356
+ throw new AgentFollowUpPolicyError("constrain-invalid", `Agent ${agent.name} followUps.constrainDueAt returned an invalid Date`);
357
+ }
358
+ }
359
+ let resultMs = Math.min(Math.max(requested.getTime(), floor), ceiling);
360
+ if (input.notLaterThan) {
361
+ const cap = Date.parse(input.notLaterThan);
362
+ if (!Number.isFinite(cap))
363
+ throw new AgentFollowUpPolicyError("invalid-request", "Follow-up notLaterThan must be a valid ISO timestamp");
364
+ if (cap < floor)
365
+ throw new AgentFollowUpPolicyError("invalid-request", "Follow-up notLaterThan is earlier than the minimum allowed due time");
366
+ resultMs = Math.min(resultMs, cap);
367
+ }
368
+ return new Date(resultMs).toISOString();
369
+ }
370
+ async function claimDailyCreateBudget(control, agentName, limit, nowMs) {
371
+ const duration = 24 * 60 * 60_000;
372
+ const windowStartMs = Math.floor(nowMs / duration) * duration;
373
+ const windowStart = new Date(windowStartMs).toISOString();
374
+ const windowEnd = new Date(windowStartMs + duration).toISOString();
375
+ const scope = "agent-follow-ups";
376
+ const row = await control.first(`SELECT "requestCount" FROM ${q("_agent_limit_windows")} WHERE "scope" = ? AND "scopeId" = ? AND "windowStart" = ? LIMIT 1`, [scope, agentName, windowStart]);
377
+ const next = Number(row?.requestCount ?? 0) + 1;
378
+ if (next > limit)
379
+ throw new AgentFollowUpPolicyError("daily-limit", `Daily follow-up creation limit reached for ${agentName}`);
380
+ if (row) {
381
+ await control.run(`UPDATE ${q("_agent_limit_windows")} SET "requestCount" = ?, "updatedAt" = ? WHERE "scope" = ? AND "scopeId" = ? AND "windowStart" = ?`, [next, nowIso(), scope, agentName, windowStart]);
382
+ }
383
+ else {
384
+ await control.run(`INSERT INTO ${q("_agent_limit_windows")} ("id", "scope", "scopeId", "windowStart", "windowEnd", "requestCount", "estimatedOutputTokens", "updatedAt")
385
+ VALUES (?, ?, ?, ?, ?, ?, 0, ?)`, [randomId("agent_limit"), scope, agentName, windowStart, windowEnd, next, nowIso()]);
386
+ }
387
+ }
388
+ export async function listAgentFollowUps(control, input) {
389
+ const limit = Math.max(1, Math.min(500, input.limit ?? 100));
390
+ if (input.status) {
391
+ return control.all(`SELECT * FROM ${q("_agent_follow_ups")} WHERE "agentName" = ? AND "status" = ? ORDER BY "dueAt" ASC, "createdAt" DESC LIMIT ?`, [input.agentName, input.status, limit]);
392
+ }
393
+ return control.all(`SELECT * FROM ${q("_agent_follow_ups")} WHERE "agentName" = ?
394
+ ORDER BY CASE "status" WHEN 'pending' THEN 0 ELSE 1 END, "dueAt" ASC, "createdAt" DESC LIMIT ?`, [input.agentName, limit]);
395
+ }
396
+ export async function createAgentFollowUp(input) {
397
+ const config = normalizeAgentFollowUpsConfig(input.agent);
398
+ if (!config)
399
+ throw new AgentFollowUpPolicyError("invalid-request", `Agent ${input.agent.name} does not enable follow-ups`);
400
+ const key = validKey(input.options.key, "Follow-up key");
401
+ const ownerKey = input.options.ownerKey === undefined ? null : validKey(input.options.ownerKey, "Follow-up ownerKey");
402
+ const body = textValue(input.options.body, raybaseAgentFollowUpLimits.maxBodyChars, "Follow-up body", true);
403
+ const contextJson = boundedJson(input.options.context, raybaseAgentFollowUpLimits.maxContextBytes, "Follow-up context");
404
+ const now = input.now ?? nowIso();
405
+ const nowMs = Date.parse(now);
406
+ const minDelayMs = config.minDelayMs ?? (input.toolInitiated ? raybaseAgentFollowUpLimits.toolMinDelayMs : raybaseAgentFollowUpLimits.apiMinDelayMs);
407
+ const wakeOn = normalizeAgentFollowUpWakeOn(input.options.wakeOn);
408
+ // A wakeOn row with no clock trigger is due at its deadline, which is then
409
+ // required: a follow-up that could wait forever is refused, exactly as an
410
+ // unbounded idleAfter is.
411
+ const deadlineIsDueAt = Boolean(wakeOn) && input.options.at === undefined && input.options.in === undefined;
412
+ if (deadlineIsDueAt && !input.options.notLaterThan) {
413
+ throw new AgentFollowUpPolicyError("invalid-request", 'A follow-up with "wakeOn" and no "at" or "in" must set "notLaterThan" as its deadline');
414
+ }
415
+ const rawDueAt = deadlineIsDueAt
416
+ ? (() => {
417
+ const parsed = Date.parse(input.options.notLaterThan);
418
+ if (!Number.isFinite(parsed))
419
+ throw new AgentFollowUpPolicyError("invalid-request", "Follow-up notLaterThan must be a valid ISO timestamp");
420
+ return parsed;
421
+ })()
422
+ : requestedDueAt(input.options, nowMs);
423
+ const idleAfterMs = input.options.idleAfter === undefined
424
+ ? null
425
+ : positiveDuration(input.options.idleAfter, null, "Follow-up idleAfter");
426
+ if (idleAfterMs !== null && (idleAfterMs < raybaseAgentFollowUpLimits.minIdleAfterMs || idleAfterMs > config.maxHorizonMs)) {
427
+ throw new AgentFollowUpPolicyError("invalid-request", "Follow-up idleAfter must be between 1 minute and maxHorizon");
428
+ }
429
+ const notLaterThan = input.options.notLaterThan ?? null;
430
+ if (notLaterThan) {
431
+ const cap = Date.parse(notLaterThan);
432
+ if (!Number.isFinite(cap) || cap > nowMs + config.maxHorizonMs || (cap <= rawDueAt && !deadlineIsDueAt)) {
433
+ throw new AgentFollowUpPolicyError("invalid-request", "Follow-up notLaterThan must be valid, after the initial dueAt, and within maxHorizon");
434
+ }
435
+ }
436
+ let onDue;
437
+ let fallbackEveryMs = null;
438
+ let maxRuns = null;
439
+ if (input.options.onDue === "lapse") {
440
+ onDue = "lapse";
441
+ }
442
+ else if (input.options.onDue && typeof input.options.onDue === "object" && "run" in input.options.onDue) {
443
+ onDue = "run";
444
+ const run = input.options.onDue.run;
445
+ if (run && typeof run === "object" && "fallbackEvery" in run) {
446
+ fallbackEveryMs = positiveDuration(run.fallbackEvery, null, "Follow-up fallbackEvery");
447
+ if (fallbackEveryMs === null || fallbackEveryMs < raybaseAgentFollowUpLimits.minFallbackEveryMs || fallbackEveryMs > config.maxHorizonMs) {
448
+ throw new AgentFollowUpPolicyError("invalid-request", "Follow-up fallbackEvery must be between 5 minutes and maxHorizon");
449
+ }
450
+ maxRuns = run.maxRuns === undefined ? null : positiveInteger(run.maxRuns, 1, "Follow-up maxRuns");
451
+ }
452
+ else if (run && typeof run === "object" && Object.keys(run).length > 0) {
453
+ throw new AgentFollowUpPolicyError("invalid-request", "Follow-up run configuration is invalid");
454
+ }
455
+ }
456
+ else {
457
+ throw new AgentFollowUpPolicyError("invalid-request", "Follow-up onDue must be lapse or run");
458
+ }
459
+ const dueAt = await constrainedDueAt(input.agent, rawDueAt, {
460
+ key,
461
+ ownerKey: ownerKey ?? undefined,
462
+ createdBy: input.createdBy,
463
+ source: "create",
464
+ now,
465
+ minDelayMs,
466
+ maxHorizonMs: config.maxHorizonMs,
467
+ notLaterThan,
468
+ env: input.env
469
+ });
470
+ const existing = await input.control.first(`SELECT * FROM ${q("_agent_follow_ups")} WHERE "agentName" = ? AND "key" = ? AND "status" = 'pending' LIMIT 1`, [input.agent.name, key]);
471
+ if (existing)
472
+ throw new AgentFollowUpPolicyError("duplicate-key", `Agent ${input.agent.name} already has a pending follow-up with key "${key}"`, { existing });
473
+ const pending = await listAgentFollowUps(input.control, { agentName: input.agent.name, status: "pending", limit: config.maxPending + 1 });
474
+ if (pending.length >= config.maxPending) {
475
+ throw new AgentFollowUpPolicyError("max-pending", `Agent ${input.agent.name} already has ${config.maxPending} pending follow-ups`, { pending });
476
+ }
477
+ if (input.toolInitiated)
478
+ await claimDailyCreateBudget(input.control, input.agent.name, config.dailyCreates, nowMs);
479
+ const id = randomId("agent_follow_up");
480
+ const conversationJson = boundedJson(await normalizedConversation(input.agent.name, id, input.options.conversation), raybaseAgentFollowUpLimits.maxConversationBytes, "Follow-up conversation");
481
+ try {
482
+ await input.control.run(`INSERT INTO ${q("_agent_follow_ups")}
483
+ ("id","agentName","key","ownerKey","body","contextJson","conversationJson","dueAt","idleAfterMs","notLaterThan",
484
+ "wakeOnEvent","wakeOnMatchJson","wokeBy","wokeEvent","wokeEventId","wokePayloadJson","wokeAt",
485
+ "onDue","fallbackEveryMs","maxRuns","status","reason","dispatchGeneration","dispatchAttempts","dispatchStartedAt","dispatchClaimToken","claimAcquiredAt","lastRunGeneration","continuedGeneration",
486
+ "runCount","lastRunAt","continuedAt","driftCount","lastDriftAt","settledAt","lapseHandledAt","lapseAttempts",
487
+ "createdBy","requestedByConversationId","requestedByRunId","triggerEventId","createdAt","updatedAt")
488
+ VALUES (?,?,?,?,?,?,?,?,?,?, ?,?,NULL,NULL,NULL,NULL,NULL, ?,?,?,'pending',NULL,0,0,NULL,NULL,NULL,NULL,NULL, 0,NULL,NULL,0,NULL,NULL,NULL,0, ?,?,?,NULL,?,?)`, [
489
+ id, input.agent.name, key, ownerKey, body, contextJson, conversationJson, dueAt, idleAfterMs, notLaterThan,
490
+ wakeOn?.event ?? null, wakeOn?.match ? stableJson(wakeOn.match) : null,
491
+ onDue, fallbackEveryMs, maxRuns,
492
+ input.createdBy, input.requestedByConversationId ?? null, input.requestedByRunId ?? null, now, now
493
+ ]);
494
+ }
495
+ catch (error) {
496
+ const raced = await input.control.first(`SELECT * FROM ${q("_agent_follow_ups")} WHERE "agentName" = ? AND "key" = ? AND "status" = 'pending' LIMIT 1`, [input.agent.name, key]);
497
+ if (raced)
498
+ throw new AgentFollowUpPolicyError("duplicate-key", `Agent ${input.agent.name} already has a pending follow-up with key "${key}"`, { existing: raced });
499
+ throw error;
500
+ }
501
+ const row = await getAgentFollowUp(input.control, id);
502
+ if (!row)
503
+ throw new Error(`Follow-up could not be loaded after creation: ${input.agent.name}/${key}`);
504
+ return {
505
+ followUpId: id,
506
+ key,
507
+ dueAt,
508
+ status: row.status,
509
+ row,
510
+ pendingCount: pending.length + 1
511
+ };
512
+ }
513
+ async function settleByKey(control, input) {
514
+ const key = validKey(input.key, "Follow-up key");
515
+ const reason = textValue(input.reason, raybaseAgentFollowUpLimits.maxReasonChars, "Follow-up reason");
516
+ const row = await control.first(`SELECT * FROM ${q("_agent_follow_ups")} WHERE "agentName" = ? AND "key" = ? AND "status" = 'pending' LIMIT 1`, [input.agentName, key]);
517
+ if (!row)
518
+ return { changed: false, row: null };
519
+ const now = input.now ?? nowIso();
520
+ await control.run(`UPDATE ${q("_agent_follow_ups")} SET "status" = ?, "reason" = ?, "settledAt" = ?, "updatedAt" = ?
521
+ WHERE "id" = ? AND "status" = 'pending'`, [input.status, reason, now, now, row.id]);
522
+ const updated = await getAgentFollowUp(control, row.id);
523
+ return { changed: updated?.status === input.status, row: updated };
524
+ }
525
+ export function resolveAgentFollowUp(control, input) {
526
+ return settleByKey(control, { ...input, status: "resolved" });
527
+ }
528
+ export function closeAgentFollowUp(control, input) {
529
+ return settleByKey(control, { ...input, status: "closed" });
530
+ }
531
+ export async function closeAgentFollowUpById(control, input) {
532
+ const row = await getAgentFollowUp(control, input.followUpId);
533
+ if (!row || row.agentName !== input.agentName || row.status !== "pending")
534
+ return { changed: false, row };
535
+ return closeAgentFollowUp(control, { agentName: input.agentName, key: row.key, reason: input.reason, now: input.now });
536
+ }
537
+ export async function closeAgentFollowUpsByOwner(control, input) {
538
+ const ownerKey = validKey(input.ownerKey, "Follow-up ownerKey");
539
+ const reason = textValue(input.reason, raybaseAgentFollowUpLimits.maxReasonChars, "Follow-up reason");
540
+ const rows = await control.all(`SELECT * FROM ${q("_agent_follow_ups")} WHERE "agentName" = ? AND "ownerKey" = ? AND "status" = 'pending'`, [input.agentName, ownerKey]);
541
+ const now = input.now ?? nowIso();
542
+ await control.run(`UPDATE ${q("_agent_follow_ups")} SET "status" = 'closed', "reason" = ?, "settledAt" = ?, "updatedAt" = ?
543
+ WHERE "agentName" = ? AND "ownerKey" = ? AND "status" = 'pending'`, [reason, now, now, input.agentName, ownerKey]);
544
+ return { closed: rows.length };
545
+ }
546
+ export async function touchAgentFollowUp(control, input) {
547
+ const key = validKey(input.key, "Follow-up key");
548
+ const row = await control.first(`SELECT * FROM ${q("_agent_follow_ups")} WHERE "agentName" = ? AND "key" = ? AND "status" = 'pending' LIMIT 1`, [input.agentName, key]);
549
+ if (!row || row.idleAfterMs === null)
550
+ return { touched: false, row };
551
+ const now = input.now ?? nowIso();
552
+ const horizon = Date.parse(row.createdAt) + (input.maxHorizonMs ?? raybaseAgentFollowUpLimits.maxHorizonMs);
553
+ const ceiling = Math.min(row.notLaterThan ? Date.parse(row.notLaterThan) : Number.POSITIVE_INFINITY, horizon);
554
+ const dueAt = new Date(Math.min(Date.parse(now) + row.idleAfterMs, ceiling)).toISOString();
555
+ await control.run(`UPDATE ${q("_agent_follow_ups")} SET "dueAt" = ?, "updatedAt" = ? WHERE "id" = ? AND "status" = 'pending'`, [dueAt, now, row.id]);
556
+ return { touched: true, row: { ...row, dueAt, updatedAt: now } };
557
+ }
558
+ /**
559
+ * Wakes every pending `wakeOn` row of one agent whose event name is `event`
560
+ * and whose `match` filter is satisfied by `payload`. A woken row becomes due
561
+ * now (never later than its own deadline) and records why it woke. A row wakes
562
+ * at most once: the CAS below refuses a second wake, a row that already ran or
563
+ * settled is no longer pending, and a non-matching payload changes nothing.
564
+ */
565
+ export async function wakeAgentFollowUps(control, input) {
566
+ const event = normalizeAgentFollowUpWakeEvent(input.event, "Follow-up wake event");
567
+ const payload = normalizeAgentFollowUpWakePayload(input.payload);
568
+ const payloadJson = stableJson(payload);
569
+ const now = input.now ?? nowIso();
570
+ const nowMs = Date.parse(now);
571
+ const wokeEventId = randomId("agent_follow_up_wake");
572
+ const candidates = await control.all(`SELECT * FROM ${q("_agent_follow_ups")}
573
+ WHERE "agentName" = ? AND "status" = 'pending' AND "wakeOnEvent" = ? AND "wokeBy" IS NULL
574
+ ORDER BY "createdAt" ASC`, [input.agentName, event]);
575
+ const woken = [];
576
+ let matched = 0;
577
+ for (const candidate of candidates) {
578
+ if (!agentFollowUpWakeMatches(parsedWakeOn(candidate)?.match ?? null, payload))
579
+ continue;
580
+ matched += 1;
581
+ const cap = candidate.notLaterThan ? Date.parse(candidate.notLaterThan) : Number.NaN;
582
+ const dueAt = new Date(Number.isFinite(cap) ? Math.min(nowMs, cap) : nowMs).toISOString();
583
+ await control.run(`UPDATE ${q("_agent_follow_ups")}
584
+ SET "dueAt" = ?, "wokeBy" = 'event', "wokeEvent" = ?, "wokeEventId" = ?, "wokePayloadJson" = ?, "wokeAt" = ?, "updatedAt" = ?
585
+ WHERE "id" = ? AND "status" = 'pending' AND "wokeBy" IS NULL AND "updatedAt" = ?`, [dueAt, event, wokeEventId, payloadJson, now, now, candidate.id, candidate.updatedAt]);
586
+ const row = await getAgentFollowUp(control, candidate.id);
587
+ if (row?.wokeEventId === wokeEventId)
588
+ woken.push(row);
589
+ }
590
+ return { event, wokeEventId, payload, woken, matched };
591
+ }
592
+ function notifyDueAtChanged(callback, targetIso) {
593
+ if (!callback)
594
+ return;
595
+ try {
596
+ void Promise.resolve(callback(targetIso)).catch((error) => {
597
+ console.warn("Failed to arm Agent follow-up alarm.", error);
598
+ });
599
+ }
600
+ catch (error) {
601
+ console.warn("Failed to arm Agent follow-up alarm.", error);
602
+ }
603
+ }
604
+ function record(value) {
605
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
606
+ }
607
+ /**
608
+ * The model's `wakeOnMatch` argument. An open record travels the strict tool
609
+ * subset as a JSON string, so accept either form; validation stays in
610
+ * `normalizeAgentFollowUpWakeOn`.
611
+ */
612
+ function toolWakeOnMatch(value) {
613
+ if (typeof value === "string") {
614
+ if (!value.trim())
615
+ return null;
616
+ try {
617
+ return toolWakeOnMatch(JSON.parse(value));
618
+ }
619
+ catch {
620
+ throw new AgentFollowUpPolicyError("invalid-request", "Follow-up wakeOn.match must be a flat object");
621
+ }
622
+ }
623
+ if (!value || typeof value !== "object" || Array.isArray(value))
624
+ return null;
625
+ const entries = Object.entries(value);
626
+ return entries.length ? value : null;
627
+ }
628
+ function auditActor(principal) {
629
+ return principal.kind === "user" && principal.user.id.startsWith("service:")
630
+ ? { kind: "service", service: principal.user.id.slice("service:".length) || "raybase-agent" }
631
+ : principal;
632
+ }
633
+ export function agentFollowUpRuntimeTools(input) {
634
+ if (!input.agent.followUps || input.principal.kind === "public")
635
+ return [];
636
+ return [
637
+ {
638
+ name: "follow_up",
639
+ displayName: "Create follow-up",
640
+ description: "Create one keyed pending expectation. This tool supports a one-time model run or a structural lapse; continuing chains are created by app code. Wait for the clock with delayMinutes/at, or wait for something the app records with wakeOnEvent (and wakeOnMatch to pin it to one record) — then notLaterThan is the deadline you come back on anyway, and is required when you give no delayMinutes or at.",
641
+ parameters: {
642
+ type: "object",
643
+ properties: {
644
+ key: { type: "string", description: "Stable dedupe key. Omit only when dedupe is unnecessary." },
645
+ ownerKey: { type: "string" },
646
+ body: { type: "string" },
647
+ context: {},
648
+ delayMinutes: { type: "number" },
649
+ at: { type: "string" },
650
+ idleAfterMinutes: { type: "number" },
651
+ notLaterThan: { type: "string" },
652
+ wakeOnEvent: {
653
+ type: "string",
654
+ description: "Wake as soon as the app records this named event, instead of only waiting for the clock. Ask the app which event names it fires."
655
+ },
656
+ wakeOnMatch: {
657
+ type: "object",
658
+ description: "Only wake when the event's payload has exactly these values, e.g. {\"questionId\": \"q_12\"}. Plain strings, numbers, or true/false.",
659
+ additionalProperties: { anyOf: [{ type: "string" }, { type: "number" }, { type: "boolean" }] }
660
+ },
661
+ onDue: { type: "string", enum: ["run", "lapse"] }
662
+ },
663
+ required: ["body", "onDue"],
664
+ additionalProperties: false
665
+ },
666
+ dataChange: { actionName: "follow_up", effects: ["agent-follow-up"] },
667
+ run: async (args) => {
668
+ const value = record(args);
669
+ try {
670
+ const result = await createAgentFollowUp({
671
+ control: input.control,
672
+ agent: input.agent,
673
+ env: input.env,
674
+ createdBy: "agent-tool",
675
+ requestedByConversationId: input.conversationId,
676
+ requestedByRunId: input.runId,
677
+ toolInitiated: true,
678
+ options: {
679
+ key: typeof value.key === "string" && value.key.trim() ? value.key : `auto:${randomId("fu")}`,
680
+ ...(typeof value.ownerKey === "string" ? { ownerKey: value.ownerKey } : {}),
681
+ body: typeof value.body === "string" ? value.body : "",
682
+ ...(value.context !== undefined ? { context: value.context } : {}),
683
+ ...(value.at !== undefined ? { at: value.at } : {}),
684
+ ...(value.delayMinutes !== undefined ? { in: `${String(value.delayMinutes)} minutes` } : {}),
685
+ ...(value.idleAfterMinutes !== undefined ? { idleAfter: `${String(value.idleAfterMinutes)} minutes` } : {}),
686
+ ...(typeof value.notLaterThan === "string" ? { notLaterThan: value.notLaterThan } : {}),
687
+ ...(typeof value.wakeOnEvent === "string" && value.wakeOnEvent.trim()
688
+ ? {
689
+ wakeOn: {
690
+ event: value.wakeOnEvent,
691
+ ...(toolWakeOnMatch(value.wakeOnMatch) ? { match: toolWakeOnMatch(value.wakeOnMatch) } : {})
692
+ }
693
+ }
694
+ : {}),
695
+ onDue: value.onDue === "lapse" ? "lapse" : { run: {} }
696
+ }
697
+ });
698
+ notifyDueAtChanged(input.onDueAtChanged, result.row.dueAt);
699
+ await recordAudit(input.control, {
700
+ actor: auditActor(input.principal),
701
+ action: "agent.follow_up.created",
702
+ target: { type: "_agent_follow_ups", id: result.row.id },
703
+ metadata: { agentName: input.agent.name, key: result.row.key, conversationId: input.conversationId, runId: input.runId }
704
+ });
705
+ return { ok: true, ...followUpToolProjection(result.row), pendingCount: result.pendingCount };
706
+ }
707
+ catch (error) {
708
+ if (error instanceof AgentFollowUpPolicyError) {
709
+ return {
710
+ ok: false,
711
+ reason: error.reason,
712
+ message: error.message,
713
+ ...(error.details.existing ? { existing: followUpToolProjection(error.details.existing) } : {}),
714
+ ...(error.details.pending ? { pending: error.details.pending.map(followUpToolProjection) } : {})
715
+ };
716
+ }
717
+ throw error;
718
+ }
719
+ }
720
+ },
721
+ {
722
+ name: "list_follow_ups",
723
+ displayName: "List follow-ups",
724
+ description: "List this agent's pending follow-ups, including their body and cross-run context.",
725
+ parameters: { type: "object", properties: {}, additionalProperties: false },
726
+ run: async () => ({
727
+ ok: true,
728
+ followUps: (await listAgentFollowUps(input.control, { agentName: input.agent.name, status: "pending" })).map(followUpToolProjection)
729
+ })
730
+ },
731
+ {
732
+ name: "close_follow_up",
733
+ displayName: "Close follow-up",
734
+ description: "End a pending follow-up because it is no longer wanted or has been superseded. Resolution attested by app code uses the separate code API.",
735
+ parameters: {
736
+ type: "object",
737
+ properties: { key: { type: "string" }, reason: { type: "string" } },
738
+ required: ["key", "reason"],
739
+ additionalProperties: false
740
+ },
741
+ dataChange: { actionName: "close_follow_up", effects: ["agent-follow-up"] },
742
+ run: async (args) => {
743
+ const value = record(args);
744
+ try {
745
+ const result = await closeAgentFollowUp(input.control, {
746
+ agentName: input.agent.name,
747
+ key: typeof value.key === "string" ? value.key : "",
748
+ reason: typeof value.reason === "string" ? value.reason : ""
749
+ });
750
+ if (result.changed && result.row) {
751
+ await recordAudit(input.control, {
752
+ actor: auditActor(input.principal),
753
+ action: "agent.follow_up.closed",
754
+ target: { type: "_agent_follow_ups", id: result.row.id },
755
+ metadata: { agentName: input.agent.name, key: result.row.key, reason: result.row.reason, conversationId: input.conversationId, runId: input.runId }
756
+ });
757
+ }
758
+ return { ok: result.changed, reason: result.changed ? undefined : "conflict", followUp: result.row ? followUpToolProjection(result.row) : null };
759
+ }
760
+ catch (error) {
761
+ if (error instanceof AgentFollowUpPolicyError)
762
+ return { ok: false, reason: error.reason, message: error.message };
763
+ throw error;
764
+ }
765
+ }
766
+ }
767
+ ];
768
+ }
769
+ export function agentFollowUpContinueTools(input) {
770
+ const baseClose = agentFollowUpRuntimeTools(input).find((tool) => tool.name === "close_follow_up");
771
+ if (!baseClose)
772
+ return [];
773
+ const continueTool = {
774
+ name: "continue_follow_up",
775
+ displayName: "Continue follow-up",
776
+ description: "Schedule the next check for the continuing follow-up that started this run, optionally replacing its body or context.",
777
+ parameters: {
778
+ type: "object",
779
+ properties: {
780
+ delayMinutes: { type: "number" },
781
+ at: { type: "string" },
782
+ body: { type: "string" },
783
+ context: {}
784
+ },
785
+ additionalProperties: false
786
+ },
787
+ dataChange: { actionName: "continue_follow_up", effects: ["agent-follow-up"] },
788
+ run: async (args) => {
789
+ const value = record(args);
790
+ const config = normalizeAgentFollowUpsConfig(input.agent);
791
+ if (!config)
792
+ return { ok: false, reason: "conflict" };
793
+ try {
794
+ const now = nowIso();
795
+ const requested = requestedDueAt({
796
+ ...(value.at !== undefined ? { at: value.at } : {}),
797
+ ...(value.delayMinutes !== undefined ? { in: `${String(value.delayMinutes)} minutes` } : {})
798
+ }, Date.parse(now));
799
+ const dueAt = await constrainedDueAt(input.agent, requested, {
800
+ key: input.followUp.key,
801
+ ownerKey: input.followUp.ownerKey ?? undefined,
802
+ createdBy: input.followUp.createdBy,
803
+ source: "continue",
804
+ now,
805
+ minDelayMs: config.minDelayMs ?? raybaseAgentFollowUpLimits.toolMinDelayMs,
806
+ maxHorizonMs: config.maxHorizonMs,
807
+ notLaterThan: input.followUp.notLaterThan,
808
+ env: input.env
809
+ });
810
+ const body = value.body === undefined ? undefined : textValue(value.body, raybaseAgentFollowUpLimits.maxBodyChars, "Follow-up body", true);
811
+ const contextJson = value.context === undefined ? undefined : boundedJson(value.context, raybaseAgentFollowUpLimits.maxContextBytes, "Follow-up context");
812
+ const row = await continueAgentFollowUpStore(input.control, {
813
+ id: input.followUp.id,
814
+ generation: input.generation,
815
+ dueAt,
816
+ body,
817
+ contextJson,
818
+ now
819
+ });
820
+ if (!row)
821
+ return { ok: false, reason: "conflict", message: "The follow-up is no longer pending for this run generation." };
822
+ notifyDueAtChanged(input.onDueAtChanged, row.dueAt);
823
+ await recordAudit(input.control, {
824
+ actor: auditActor(input.principal),
825
+ action: "agent.follow_up.continued",
826
+ target: { type: "_agent_follow_ups", id: row.id },
827
+ metadata: { agentName: row.agentName, key: row.key, generation: input.generation, dueAt }
828
+ });
829
+ return { ok: true, followUp: followUpToolProjection(row) };
830
+ }
831
+ catch (error) {
832
+ if (error instanceof AgentFollowUpPolicyError)
833
+ return { ok: false, reason: error.reason, message: error.message };
834
+ throw error;
835
+ }
836
+ }
837
+ };
838
+ return [continueTool, baseClose];
839
+ }
840
+ //# sourceMappingURL=agent-follow-ups.js.map