@xopcai/xopc 0.0.332 → 0.0.333

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 (329) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-C2wg3xC_.js → agent-avatar-dicebear-DiI2O7lC.js} +1 -1
  4. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CVp3J969.js +1 -0
  5. package/dist/gateway/static/root/assets/{agent-plugin-dialog-BeNnu1Ts.js → agent-plugin-dialog-CacyndrS.js} +1 -1
  6. package/dist/gateway/static/root/assets/agents-DXYZSuUV.js +70 -0
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-etFSkfzl.js → app-management-settings-panel-BcszTlqr.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-DKmU2VAP.js → appearance-settings-B1XPe8qz.js} +1 -1
  9. package/dist/gateway/static/root/assets/{apps-page-DVNySL58.js → apps-page-ZqANbUZv.js} +1 -1
  10. package/dist/gateway/static/root/assets/{archive-plugin-D0z_Fr2G.js → archive-plugin-MjUsJcNb.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-DNCDbeOX.js → attachment-load-DHa-BI9a.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-page-B7_C-p66.js → automations-page-Dsjivdxs.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-workspace-B37vs5tk.js +7 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-BYn2hScX.js → binary-plugins-DQYcuBHP.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-ChWW8Z9L.js → block-editor-Bx0uXbJP.js} +3 -3
  16. package/dist/gateway/static/root/assets/{browser-automation-inputs-C5s1yHOu.js → browser-automation-inputs-1ZIPGDeq.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-automations-page-BV00BXRb.js → browser-automations-page-CCjYipHc.js} +2 -2
  18. package/dist/gateway/static/root/assets/browser-settings-page-CSv4rvmx.js +3 -0
  19. package/dist/gateway/static/root/assets/capabilities-BnO9LV7U.js +1 -0
  20. package/dist/gateway/static/root/assets/{capabilities-page-v0WkhV5o.js → capabilities-page-BfvDvIY1.js} +2 -2
  21. package/dist/gateway/static/root/assets/capabilities-settings-panel-CoW7-ESq.js +8 -0
  22. package/dist/gateway/static/root/assets/{capability-header-actions-vmx35sbu.js → capability-header-actions-D_hbWRRF.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-BhMaRh1x.js +1 -0
  24. package/dist/gateway/static/root/assets/{chat-terminal-dock-C41mXCAi.js → chat-terminal-dock-Fnum_IEm.js} +1 -1
  25. package/dist/gateway/static/root/assets/{computer-settings-page-BJkqok2G.js → computer-settings-page-DI1zfCTA.js} +1 -1
  26. package/dist/gateway/static/root/assets/{connector-service-page-BKCZMmwm.js → connector-service-page-CiGDAubm.js} +1 -1
  27. package/dist/gateway/static/root/assets/connectors-page-Ono0Pha1.js +2 -0
  28. package/dist/gateway/static/root/assets/{date-picker-CrOV4Ynd.js → date-picker-D-JhzZyW.js} +1 -1
  29. package/dist/gateway/static/root/assets/{dependency-picker-CqADAHZp.js → dependency-picker-DpD3xaEB.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-Bab-iWED.js → desktop-pet-CCoDxKqh.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-settings-BqgzLOdi.js → desktop-pet-settings-GxndKfCx.js} +1 -1
  32. package/dist/gateway/static/root/assets/{device-pairing-wizard-DFg7FDPf.js → device-pairing-wizard-B71w3ptm.js} +1 -1
  33. package/dist/gateway/static/root/assets/{directory-picker-path-field-hqJ9sFCR.js → directory-picker-path-field-CUzjJvjs.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-debug-page-DX3PFhRE.js → extension-debug-page-BtDY8ntX.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-page-DkREdHLs.js → extension-page-D9_XF-XC.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-settings-page-wF-HNTM-.js → extension-settings-page-CjhUFAaC.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-config-swr-cR-tz7-Q.js → gateway-config-swr-CgIjCxM8.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-settings-Du-Dos9O.js → gateway-settings-BWaCnwT1.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-startup-retry-6jLRcQsu.js → gateway-startup-retry-i-1lTrwY.js} +1 -1
  40. package/dist/gateway/static/root/assets/home-page-BTjGLngn.js +1 -0
  41. package/dist/gateway/static/root/assets/{image-generation-api-CSSkwsyC.js → image-generation-api-gilc-u7M.js} +1 -1
  42. package/dist/gateway/static/root/assets/{imports-page-B80Cv043.js → imports-page-BEtq5BRU.js} +1 -1
  43. package/dist/gateway/static/root/assets/index-DHL16aYZ.js +121 -0
  44. package/dist/gateway/static/root/assets/index-N1e6PDwx.css +1 -0
  45. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BgoFaTwv.js → keyboard-shortcuts-settings-JUYY_18v.js} +1 -1
  46. package/dist/gateway/static/root/assets/local-app-workbench-page-uI7mtoVz.js +1 -0
  47. package/dist/gateway/static/root/assets/{local-apps-page-HO6OQlQT.js → local-apps-page-BlYESNqz.js} +1 -1
  48. package/dist/gateway/static/root/assets/{locale-store-wNXWkWu5.js → locale-store-BY30D6tg.js} +1 -1
  49. package/dist/gateway/static/root/assets/{logs-page-CjzR9Rpj.js → logs-page-BbLQreeN.js} +2 -2
  50. package/dist/gateway/static/root/assets/management-settings-c4krhYU7.js +1 -0
  51. package/dist/gateway/static/root/assets/{markdown-view-DlT9KqwF.js → markdown-view-BEeXMfDw.js} +1 -1
  52. package/dist/gateway/static/root/assets/{media-plugins-Dlj6TD3M.js → media-plugins-DEFN1I73.js} +1 -1
  53. package/dist/gateway/static/root/assets/messages-_6IXbP2u.js +3 -0
  54. package/dist/gateway/static/root/assets/note-detail-panel--09xGxyE.js +5 -0
  55. package/dist/gateway/static/root/assets/notes-page-DsxcVBXF.js +8 -0
  56. package/dist/gateway/static/root/assets/{page-context-capture-button-BArPtqp5.js → page-context-capture-button-D43aVpCj.js} +1 -1
  57. package/dist/gateway/static/root/assets/{page-tabs-vqI30Yrg.js → page-tabs-BhYBCqls.js} +1 -1
  58. package/dist/gateway/static/root/assets/{preview-open-alternatives-B-mwPBJW.js → preview-open-alternatives-CP8agNlc.js} +1 -1
  59. package/dist/gateway/static/root/assets/{product-open-page-D--sj_uN.js → product-open-page-CU7fRhfT.js} +1 -1
  60. package/dist/gateway/static/root/assets/project-detail-page-U-EdDfAW.js +1 -0
  61. package/dist/gateway/static/root/assets/{projects-page-DBsBwAQ6.js → projects-page-DUOKZLt7.js} +1 -1
  62. package/dist/gateway/static/root/assets/{registry-api-BIpltJ47.js → registry-api-BvVx0G1o.js} +1 -1
  63. package/dist/gateway/static/root/assets/{remote-access-hub-BurdDY0m.js → remote-access-hub-fVPQe5YS.js} +1 -1
  64. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CAnb0PNY.js → runtime-tools-settings-panel-Czvzsuj_.js} +2 -2
  65. package/dist/gateway/static/root/assets/scenes-page-C0-WHOY3.js +2 -0
  66. package/dist/gateway/static/root/assets/{schema-form-BKj6wIMb.js → schema-form-B9Ni5O93.js} +1 -1
  67. package/dist/gateway/static/root/assets/sessions-page-DdXvW09N.js +1 -0
  68. package/dist/gateway/static/root/assets/settings-advanced-gate-BtF83fBY.js +1 -0
  69. package/dist/gateway/static/root/assets/{settings-form-section-78ycUHfv.js → settings-form-section-jquf1P7n.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-BOdxIVzo.js → settings-page-DPomsvba.js} +1 -1
  71. package/dist/gateway/static/root/assets/{setup-status-panel-CbKHBjrU.js → setup-status-panel-BvVlqpHf.js} +1 -1
  72. package/dist/gateway/static/root/assets/{share-preview-page-DyLfktib.js → share-preview-page-b9DI0N1J.js} +1 -1
  73. package/dist/gateway/static/root/assets/shares-settings-R_qwc4DN.js +1 -0
  74. package/dist/gateway/static/root/assets/{skill-api-CiBGQ0Jg.js → skill-api-Bu7-3w-L.js} +1 -1
  75. package/dist/gateway/static/root/assets/skill-reload-api-CNJAQ_e-.js +1 -0
  76. package/dist/gateway/static/root/assets/{skills-page-C35VKjhb.js → skills-page-D7XPEQu_.js} +1 -1
  77. package/dist/gateway/static/root/assets/{system-settings-panel-CyJUeREH.js → system-settings-panel-BwFR0Uci.js} +1 -1
  78. package/dist/gateway/static/root/assets/task-detail-page-PFjGW2g1.js +1 -0
  79. package/dist/gateway/static/root/assets/{tunnel-api-Day9zhKi.js → tunnel-api-PfucxMP3.js} +1 -1
  80. package/dist/gateway/static/root/assets/usage-page-t_zdQHcy.js +1 -0
  81. package/dist/gateway/static/root/assets/{use-autosave-Bj9hC6ML.js → use-autosave-DLyy2wHz.js} +1 -1
  82. package/dist/gateway/static/root/assets/user-model-page-OyfPVfB9.js +2 -0
  83. package/dist/gateway/static/root/assets/{voice-api-key-field-fWRD6B8r.js → voice-api-key-field-CQDY5EBK.js} +1 -1
  84. package/dist/gateway/static/root/assets/{voice-config-api-ujEySjyc.js → voice-config-api-Bwy3Al3J.js} +1 -1
  85. package/dist/gateway/static/root/assets/{work-discovery-overlay-CnxdvIk8.js → work-discovery-overlay-CJzqJ47I.js} +1 -1
  86. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DlWNN1VA.js → workflow-run-setup-panel-sCOk-esV.js} +2 -2
  87. package/dist/gateway/static/root/assets/workflows-page-DYBGjN7C.js +6 -0
  88. package/dist/gateway/static/root/index.html +9 -9
  89. package/dist/package.js +1 -1
  90. package/dist/packages/gateway-contract/src/automations.js +44 -14
  91. package/dist/packages/gateway-contract/src/capabilities.js +106 -8
  92. package/dist/packages/gateway-contract/src/index.js +2 -0
  93. package/dist/packages/gateway-contract/src/scenes.js +7 -6
  94. package/dist/packages/gateway-contract/src/sessions.js +2 -1
  95. package/dist/packages/gateway-contract/src/usage.js +6 -0
  96. package/dist/src/agent/agent-manager.js +9 -3
  97. package/dist/src/agent/background-review/run-background-review.js +6 -1
  98. package/dist/src/agent/embedded/run-turn.js +7 -1
  99. package/dist/src/agent/external-tools/gateway-tools.d.ts +2 -1
  100. package/dist/src/agent/external-tools/gateway-tools.js +44 -11
  101. package/dist/src/agent/external-tools/index.js +1 -1
  102. package/dist/src/agent/image/understanding/pi-ai-provider.js +1 -1
  103. package/dist/src/agent/memory/compaction.js +4 -0
  104. package/dist/src/agent/service/btw-query.js +8 -2
  105. package/dist/src/agent/service.js +1 -1
  106. package/dist/src/agent/skills/filesystem-watcher.js +1 -1
  107. package/dist/src/agent/skills/hub-pull.js +2 -2
  108. package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +1 -1
  109. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +1 -1
  110. package/dist/src/agent/tasks/task-judge-service.js +4 -0
  111. package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
  112. package/dist/src/agent/tool-manuals/xopc-use.js +5 -4
  113. package/dist/src/agent/tools/automation-tool.d.ts +4 -1
  114. package/dist/src/agent/tools/automation-tool.js +42 -4
  115. package/dist/src/agent/tools/session-search-tool.js +1 -1
  116. package/dist/src/agent/tools/web-extract.js +1 -1
  117. package/dist/src/agent/tools/xopc-use-tool.js +49 -8
  118. package/dist/src/ai-assist/text-assist.js +5 -1
  119. package/dist/src/automations/api/routes.js +65 -0
  120. package/dist/src/automations/capabilities/read.js +24 -0
  121. package/dist/src/automations/capabilities/write.d.ts +52 -14
  122. package/dist/src/automations/capabilities/write.js +52 -3
  123. package/dist/src/automations/delivery/delivery-router.d.ts +50 -0
  124. package/dist/src/automations/delivery/delivery-router.js +318 -0
  125. package/dist/src/automations/delivery/index.d.ts +1 -0
  126. package/dist/src/automations/delivery/index.js +2 -0
  127. package/dist/src/automations/domain/defaults.d.ts +0 -1
  128. package/dist/src/automations/domain/defaults.js +1 -1
  129. package/dist/src/automations/domain/index.js +2 -2
  130. package/dist/src/automations/domain/types.d.ts +158 -7
  131. package/dist/src/automations/domain/validation.d.ts +104 -22
  132. package/dist/src/automations/domain/validation.js +66 -13
  133. package/dist/src/automations/draft/automation-draft-prompt.js +3 -4
  134. package/dist/src/automations/draft/automation-draft-service.js +6 -0
  135. package/dist/src/automations/draft/automation-draft-validator.d.ts +22 -3
  136. package/dist/src/automations/draft/automation-draft-validator.js +4 -4
  137. package/dist/src/automations/events/event-catalog.d.ts +14 -0
  138. package/dist/src/automations/events/event-catalog.js +117 -0
  139. package/dist/src/automations/events/event-dispatcher.d.ts +27 -0
  140. package/dist/src/automations/events/event-dispatcher.js +140 -0
  141. package/dist/src/automations/events/event-repository.d.ts +59 -0
  142. package/dist/src/automations/events/event-repository.js +361 -0
  143. package/dist/src/automations/events/index.d.ts +3 -0
  144. package/dist/src/automations/events/index.js +4 -0
  145. package/dist/src/automations/index.d.ts +3 -1
  146. package/dist/src/automations/index.js +9 -3
  147. package/dist/src/automations/service/action-executor.d.ts +20 -1
  148. package/dist/src/automations/service/action-executor.js +80 -40
  149. package/dist/src/automations/service/automation-service.d.ts +21 -4
  150. package/dist/src/automations/service/automation-service.js +150 -100
  151. package/dist/src/automations/storage/automation-repository.js +4 -5
  152. package/dist/src/automations/storage/automation-run-repository.d.ts +1 -0
  153. package/dist/src/automations/storage/automation-run-repository.js +26 -1
  154. package/dist/src/automations/storage/index.js +2 -2
  155. package/dist/src/automations/webhook-secrets.d.ts +1 -0
  156. package/dist/src/automations/webhook-secrets.js +16 -0
  157. package/dist/src/capabilities/store-connector.d.ts +17 -1
  158. package/dist/src/capabilities/store-connector.js +69 -3
  159. package/dist/src/cli/commands/connectors.js +4 -3
  160. package/dist/src/cli/commands/doctor/checks/automation-integrity.d.ts +2 -0
  161. package/dist/src/cli/commands/doctor/checks/automation-integrity.js +55 -0
  162. package/dist/src/cli/commands/doctor/checks/database-relations.d.ts +2 -0
  163. package/dist/src/cli/commands/doctor/checks/database-relations.js +81 -0
  164. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  165. package/dist/src/cli/commands/doctor/flow.js +5 -1
  166. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  167. package/dist/src/cli/commands/skills.js +1 -1
  168. package/dist/src/connectors/approval-resume.js +1 -1
  169. package/dist/src/connectors/cli/store.js +1 -1
  170. package/dist/src/connectors/composio-backends.js +14 -4
  171. package/dist/src/connectors/composio-managed-events.d.ts +5 -2
  172. package/dist/src/connectors/composio-managed-events.js +4 -1
  173. package/dist/src/connectors/connection-recovery-service.d.ts +2 -1
  174. package/dist/src/connectors/connection-recovery-service.js +89 -4
  175. package/dist/src/discussions/analyzer.js +4 -4
  176. package/dist/src/extensions/update.js +1 -1
  177. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  178. package/dist/src/gateway/home-intelligence-automation-reconciler.js +4 -1
  179. package/dist/src/gateway/hono/routes/capabilities.js +1 -1
  180. package/dist/src/gateway/hono/routes/connection-waits.js +3 -2
  181. package/dist/src/gateway/hono/routes/lazy-bundles.js +14 -1
  182. package/dist/src/gateway/hono/routes/public-gateway.js +93 -3
  183. package/dist/src/gateway/hono/routes/scenes.js +57 -41
  184. package/dist/src/gateway/hono/routes/sessions.js +15 -0
  185. package/dist/src/gateway/hono/routes/usage.d.ts +3 -0
  186. package/dist/src/gateway/hono/routes/usage.js +61 -0
  187. package/dist/src/gateway/hono/routes/voice.js +1 -1
  188. package/dist/src/gateway/memory-maintenance-automation-reconciler.js +5 -2
  189. package/dist/src/gateway/scenes/host.js +27 -14
  190. package/dist/src/gateway/scenes/slackThreadSource.d.ts +2 -2
  191. package/dist/src/gateway/security/gateway-scopes.js +1 -0
  192. package/dist/src/gateway/service/active-execution.d.ts +19 -0
  193. package/dist/src/gateway/service/active-execution.js +16 -0
  194. package/dist/src/gateway/service/agent-runner.d.ts +4 -0
  195. package/dist/src/gateway/service/agent-runner.js +19 -1
  196. package/dist/src/gateway/service/marketplace-service.js +2 -2
  197. package/dist/src/gateway/service/run-gateway-agent.d.ts +2 -0
  198. package/dist/src/gateway/service/run-gateway-agent.js +9 -1
  199. package/dist/src/gateway/service/sessions-api.d.ts +13 -0
  200. package/dist/src/gateway/service/sessions-api.js +23 -0
  201. package/dist/src/gateway/service.d.ts +6 -3
  202. package/dist/src/gateway/service.js +82 -85
  203. package/dist/src/gateway/side-chat/run-service.js +10 -7
  204. package/dist/src/home-intelligence/generator.js +4 -1
  205. package/dist/src/home-intelligence/host.js +1 -1
  206. package/dist/src/infra/domain-outbox-dispatcher.d.ts +0 -3
  207. package/dist/src/infra/domain-outbox-dispatcher.js +15 -7
  208. package/dist/src/local-apps/service.js +1 -1
  209. package/dist/src/notes/service.js +2 -3
  210. package/dist/src/projects/project-service.js +1 -2
  211. package/dist/src/projects/project-skill-service.js +2 -2
  212. package/dist/src/providers/model-call.d.ts +3 -2
  213. package/dist/src/providers/model-call.js +30 -5
  214. package/dist/src/scenes/activationAdapter.d.ts +19 -0
  215. package/dist/src/scenes/activationAdapter.js +1 -0
  216. package/dist/src/scenes/agentExecutor.js +3 -10
  217. package/dist/src/scenes/contracts.d.ts +3 -9
  218. package/dist/src/scenes/contracts.js +1 -0
  219. package/dist/src/scenes/execution.d.ts +9 -3
  220. package/dist/src/scenes/execution.js +12 -11
  221. package/dist/src/scenes/httpServices.d.ts +5 -2
  222. package/dist/src/scenes/mailContext.d.ts +4 -0
  223. package/dist/src/scenes/mailContext.js +9 -0
  224. package/dist/src/scenes/maintenance.js +1 -5
  225. package/dist/src/scenes/metrics.d.ts +0 -6
  226. package/dist/src/scenes/metrics.js +0 -11
  227. package/dist/src/scenes/registry.d.ts +11 -0
  228. package/dist/src/scenes/registry.js +28 -0
  229. package/dist/src/scenes/repository.d.ts +6 -3
  230. package/dist/src/scenes/repository.js +43 -5
  231. package/dist/src/scenes/service.d.ts +2 -1
  232. package/dist/src/scenes/service.js +9 -7
  233. package/dist/src/scenes/taskFollowUp/contracts.d.ts +37 -7
  234. package/dist/src/scenes/taskFollowUp/contracts.js +36 -17
  235. package/dist/src/scenes/taskFollowUp/service.d.ts +35 -7
  236. package/dist/src/scenes/taskFollowUp/service.js +86 -28
  237. package/dist/src/scenes/templates.d.ts +2 -2
  238. package/dist/src/scenes/userNotes.d.ts +3 -0
  239. package/dist/src/scenes/userNotes.js +6 -0
  240. package/dist/src/session/client-history.d.ts +3 -0
  241. package/dist/src/session/client-history.js +10 -5
  242. package/dist/src/session/manager.d.ts +1 -0
  243. package/dist/src/session/resolve-session.js +4 -3
  244. package/dist/src/session/session-title.js +1 -1
  245. package/dist/src/session/store.d.ts +1 -0
  246. package/dist/src/session/store.js +3 -2
  247. package/dist/src/storage/sqlite/ai-usage-repository.d.ts +137 -0
  248. package/dist/src/storage/sqlite/ai-usage-repository.js +175 -0
  249. package/dist/src/storage/sqlite/connector-account-repository.js +7 -5
  250. package/dist/src/storage/sqlite/connector-repository.js +36 -34
  251. package/dist/src/storage/sqlite/index.d.ts +2 -2
  252. package/dist/src/storage/sqlite/index.js +3 -3
  253. package/dist/src/storage/sqlite/migrations/209_automation_event_hub.sql +48 -0
  254. package/dist/src/storage/sqlite/migrations/210_remove_legacy_automation_timeout.sql +14 -0
  255. package/dist/src/storage/sqlite/migrations/211_automation_result_deliveries.sql +16 -0
  256. package/dist/src/storage/sqlite/migrations/212_automation_delivery_policy.sql +30 -0
  257. package/dist/src/storage/sqlite/migrations/213_automation_reliability_contract.sql +188 -0
  258. package/dist/src/storage/sqlite/migrations/214_ai_usage_ledger.sql +41 -0
  259. package/dist/src/storage/sqlite/migrations/215_scene_execution_adapters.sql +6 -0
  260. package/dist/src/storage/sqlite/migrations/216_remove_scene_model_usage.sql +1 -0
  261. package/dist/src/storage/sqlite/migrations/217_remove_legacy_memory_tables.sql +4 -0
  262. package/dist/src/storage/sqlite/migrations/218_core_relation_indexes.sql +26 -0
  263. package/dist/src/storage/sqlite/migrations/219_json_contracts.sql +123 -0
  264. package/dist/src/storage/sqlite/migrations/220_normalize_timestamps.sql +339 -0
  265. package/dist/src/storage/sqlite/migrations/221_ai_usage_retention_index.sql +2 -0
  266. package/dist/src/storage/sqlite/migrations/222_session_config_authority.sql +13 -0
  267. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  268. package/dist/src/storage/sqlite/migrations/runner.js +4 -4
  269. package/dist/src/storage/sqlite/row-mappers.d.ts +3 -7
  270. package/dist/src/storage/sqlite/row-mappers.js +6 -6
  271. package/dist/src/storage/sqlite/scenes-schema.d.ts +1 -1
  272. package/dist/src/storage/sqlite/scenes-schema.js +0 -1
  273. package/dist/src/storage/sqlite/schema.js +1 -1
  274. package/dist/src/storage/sqlite/schema.sql +0 -52
  275. package/dist/src/storage/sqlite/schemas/scenes.sql +0 -7
  276. package/dist/src/storage/sqlite/session-input-repository.d.ts +8 -0
  277. package/dist/src/storage/sqlite/session-input-repository.js +18 -1
  278. package/dist/src/storage/sqlite/session-read-repository.d.ts +1 -1
  279. package/dist/src/storage/sqlite/session-read-repository.js +0 -1
  280. package/dist/src/storage/sqlite/session-repository.d.ts +0 -4
  281. package/dist/src/storage/sqlite/session-repository.js +8 -18
  282. package/dist/src/storage/sqlite/timestamps.d.ts +4 -0
  283. package/dist/src/storage/sqlite/timestamps.js +20 -0
  284. package/dist/src/storage/sqlite/transcript-repository.d.ts +1 -0
  285. package/dist/src/storage/sqlite/transcript-repository.js +23 -15
  286. package/dist/src/storage/sqlite/user-trust-repository.js +4 -2
  287. package/dist/src/tasks/capabilities/write.d.ts +1 -1
  288. package/dist/src/tasks/home-query-service.js +3 -3
  289. package/dist/src/tasks/task-contract-planner.js +1 -1
  290. package/dist/src/usage/cost.d.ts +4 -0
  291. package/dist/src/usage/cost.js +28 -0
  292. package/dist/src/usage/recorder.d.ts +13 -0
  293. package/dist/src/usage/recorder.js +117 -0
  294. package/dist/src/usage/scenario-registry.d.ts +8 -0
  295. package/dist/src/usage/scenario-registry.js +117 -0
  296. package/dist/src/usage/types.d.ts +55 -0
  297. package/dist/src/usage/types.js +1 -0
  298. package/dist/src/voice/tts/summarize.js +1 -1
  299. package/dist/src/work-discovery/analyzer.js +2 -2
  300. package/dist/src/work-discovery/investigator.js +1 -1
  301. package/dist/src/workflows/service/workflow-run-service.js +15 -2
  302. package/package.json +3 -3
  303. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-Se1Z72VG.js +0 -1
  304. package/dist/gateway/static/root/assets/agents-udIitwV8.js +0 -70
  305. package/dist/gateway/static/root/assets/automations-workspace-BMgJvdcv.js +0 -7
  306. package/dist/gateway/static/root/assets/browser-settings-page-xwTmuZjS.js +0 -3
  307. package/dist/gateway/static/root/assets/capabilities-CHA-sTAZ.js +0 -1
  308. package/dist/gateway/static/root/assets/capabilities-settings-panel-DefBGjhV.js +0 -8
  309. package/dist/gateway/static/root/assets/channels-Eo4ONF5X.js +0 -1
  310. package/dist/gateway/static/root/assets/connectors-page-DZYgogQw.js +0 -2
  311. package/dist/gateway/static/root/assets/home-page-D7YoMHq4.js +0 -1
  312. package/dist/gateway/static/root/assets/index-BEw0xrde.css +0 -1
  313. package/dist/gateway/static/root/assets/index-DalslRUx.js +0 -121
  314. package/dist/gateway/static/root/assets/local-app-workbench-page-BKL5UZAj.js +0 -1
  315. package/dist/gateway/static/root/assets/management-settings-Dk_gTJb9.js +0 -1
  316. package/dist/gateway/static/root/assets/messages-fmf0dnr4.js +0 -3
  317. package/dist/gateway/static/root/assets/note-detail-panel-BebJPjjk.js +0 -5
  318. package/dist/gateway/static/root/assets/notes-page-CmS_hvz8.js +0 -8
  319. package/dist/gateway/static/root/assets/project-detail-page-BFUdtWXF.js +0 -1
  320. package/dist/gateway/static/root/assets/scenes-page-Cj8xtr5t.js +0 -2
  321. package/dist/gateway/static/root/assets/sessions-page-BCsjgkCs.js +0 -1
  322. package/dist/gateway/static/root/assets/settings-advanced-gate-BLL7csOJ.js +0 -1
  323. package/dist/gateway/static/root/assets/shares-settings-BzvSNouj.js +0 -1
  324. package/dist/gateway/static/root/assets/skill-reload-api-BHnru0F5.js +0 -1
  325. package/dist/gateway/static/root/assets/task-detail-page-Bd1_Fguk.js +0 -1
  326. package/dist/gateway/static/root/assets/user-model-page-DuYzuR1T.js +0 -2
  327. package/dist/gateway/static/root/assets/workflows-page-B45YDiEw.js +0 -6
  328. package/dist/src/automations/product-events.d.ts +0 -5
  329. package/dist/src/automations/product-events.js +0 -19
@@ -1,4 +1,4 @@
1
- import { AutomationCancelOutputSchema, AutomationDeleteInputSchema, AutomationDeleteOutputSchema, AutomationMutationOutputSchema, AutomationReadAllInputSchema, AutomationReadAllOutputSchema, AutomationReadOutputSchema, AutomationRunMutationOutputSchema, AutomationSetEnabledInputSchema, CapabilityResourceInputSchema } from "../../../packages/gateway-contract/src/capabilities.js";
1
+ import { AutomationCancelOutputSchema, AutomationDeleteInputSchema, AutomationDeleteOutputSchema, AutomationMutationOutputSchema, AutomationReadAllInputSchema, AutomationReadAllOutputSchema, AutomationReadOutputSchema, AutomationRecoveryOutputSchema, AutomationReplayEventInputSchema, AutomationRetryDeliveryInputSchema, AutomationRunMutationOutputSchema, AutomationSetEnabledInputSchema, CapabilityResourceInputSchema } from "../../../packages/gateway-contract/src/capabilities.js";
2
2
  import { init_src } from "../../../packages/gateway-contract/src/index.js";
3
3
  import { CapabilityError } from "../../capabilities/runtime/errors.js";
4
4
  import { defineAtomicCapability } from "../../capabilities/runtime/dispatcher.js";
@@ -6,6 +6,8 @@ import { CreateAutomationSchema, UpdateAutomationSchema } from "../domain/valida
6
6
  import { getAutomation } from "../storage/automation-repository.js";
7
7
  import { getAutomationRun, markAllAutomationRunsRead, markAutomationRunRead } from "../storage/automation-run-repository.js";
8
8
  import "../storage/index.js";
9
+ import { getAutomationEventForRun } from "../events/event-repository.js";
10
+ import "../events/index.js";
9
11
  import { AutomationAlreadyExistsError, AutomationAlreadyRunningError } from "../service/automation-service.js";
10
12
  import { z } from "zod";
11
13
  //#region src/automations/capabilities/write.ts
@@ -44,6 +46,36 @@ function registerAutomationWriteCapabilities(dispatcher, service, projects) {
44
46
  const requireProject = (id) => {
45
47
  if (id && !projects?.get(id)) throw new CapabilityError("NOT_FOUND", "Project not found");
46
48
  };
49
+ dispatcher.register(defineAtomicCapability({
50
+ ...policy,
51
+ id: "xopc.automations.replay_event",
52
+ description: "Replay dead-letter projection and run-delivery work for one immutable event.",
53
+ input: AutomationReplayEventInputSchema,
54
+ output: AutomationRecoveryOutputSchema,
55
+ execute({ id }) {
56
+ if (!service.replayEventAtomically(id)) throw new CapabilityError("NOT_FOUND", "Dead-letter event work not found");
57
+ return {
58
+ ok: true,
59
+ accepted: true
60
+ };
61
+ },
62
+ afterCommit: () => service.dispatchRecoveryWork()
63
+ }));
64
+ dispatcher.register(defineAtomicCapability({
65
+ ...policy,
66
+ id: "xopc.automations.retry_delivery",
67
+ description: "Retry one dead-letter result destination using its stable delivery identity.",
68
+ input: AutomationRetryDeliveryInputSchema,
69
+ output: AutomationRecoveryOutputSchema,
70
+ execute({ runId, destinationKey }) {
71
+ if (!service.retryResultDeliveryAtomically(runId, destinationKey)) throw new CapabilityError("NOT_FOUND", "Dead-letter result delivery not found");
72
+ return {
73
+ ok: true,
74
+ accepted: true
75
+ };
76
+ },
77
+ afterCommit: () => service.dispatchRecoveryWork()
78
+ }));
47
79
  dispatcher.register(defineAtomicCapability({
48
80
  ...policy,
49
81
  id: "xopc.automations.cancel",
@@ -91,13 +123,30 @@ function registerAutomationWriteCapabilities(dispatcher, service, projects) {
91
123
  description: command === "run" ? "Queue a manual run with the currently accepted execution configuration." : "Queue a rerun with current configuration and the original trigger event.",
92
124
  input: CapabilityResourceInputSchema,
93
125
  output: AutomationRunMutationOutputSchema,
94
- execute({ id }) {
126
+ execute({ id }, context) {
95
127
  const automationId = command === "run" ? id : getAutomationRun(id)?.automationId;
96
128
  const automation = automationId ? getAutomation(automationId) : null;
97
129
  if (!automation) throw new CapabilityError("NOT_FOUND", "Automation or source run not found");
98
130
  assertManagedOperation(automation, "run");
99
131
  try {
100
- const run = command === "run" ? service.queueRunAtomically(id) : service.queueRerunAtomically(id);
132
+ const request = {
133
+ id: `${command}:${context.operationId}`,
134
+ type: command === "run" ? "automation.manual.requested" : "automation.rerun.requested",
135
+ source: "user",
136
+ trust: "user",
137
+ subject: {
138
+ kind: "automation",
139
+ id: automation.id
140
+ },
141
+ correlationId: context.operationId,
142
+ dedupeKey: context.idempotencyKey,
143
+ payload: command === "run" ? { automationId: automation.id } : {
144
+ automationId: automation.id,
145
+ previousRunId: id
146
+ }
147
+ };
148
+ const executionEvent = command === "rerun" ? getAutomationEventForRun(id) ?? request : request;
149
+ const run = service.queueTriggerAtomically(automation.id, request, executionEvent);
101
150
  return {
102
151
  ok: true,
103
152
  automation: { ...automation },
@@ -0,0 +1,50 @@
1
+ import type { Automation, AutomationArtifact, AutomationResultDeliveryRecord, AutomationResultEnvelope, AutomationRun, AutomationRunDeliveryContext } from '../domain/types.js';
2
+ type AutomationDeliveryHandler = (input: {
3
+ deliveryId: string;
4
+ attempt: number;
5
+ run: AutomationRun;
6
+ result: AutomationResultEnvelope;
7
+ config: Record<string, unknown>;
8
+ signal: AbortSignal;
9
+ }) => void | Promise<void>;
10
+ export declare function listAutomationResultDeliveries(input?: {
11
+ runId?: string;
12
+ status?: AutomationResultDeliveryRecord['status'];
13
+ limit?: number;
14
+ }): AutomationResultDeliveryRecord[];
15
+ export declare function retryAutomationResultDelivery(runId: string, destinationKey: string): boolean;
16
+ export declare function getAutomationResultDeliveryMetrics(): {
17
+ pending: number;
18
+ deadLetters: number;
19
+ activeLeases: number;
20
+ };
21
+ export declare class AutomationDeliveryRouter {
22
+ private readonly options;
23
+ private active?;
24
+ private timer?;
25
+ private readonly handlers;
26
+ private readonly owner;
27
+ private readonly abortController;
28
+ constructor(options?: {
29
+ deliverGatewayEvent?: (run: AutomationRun, context: AutomationRunDeliveryContext) => void | Promise<void>;
30
+ onDeadLetter?: (input: {
31
+ phase: 'result_delivery';
32
+ runId: string;
33
+ destinationKey: string;
34
+ error: string;
35
+ }) => void;
36
+ fetch?: typeof fetch;
37
+ });
38
+ register(kind: string, handler: AutomationDeliveryHandler): void;
39
+ validateArtifacts(artifacts: AutomationArtifact[]): void;
40
+ enqueue(run: AutomationRun, automation: Automation, suppliedArtifacts?: AutomationArtifact[]): void;
41
+ start(): void;
42
+ stop(): Promise<void>;
43
+ dispatch(): Promise<number>;
44
+ private claim;
45
+ private runDispatch;
46
+ private release;
47
+ private fail;
48
+ private postWebhook;
49
+ }
50
+ export {};
@@ -0,0 +1,318 @@
1
+ import { createLogger } from "../../utils/logger/index.js";
2
+ import { init_logger } from "../../utils/logger.js";
3
+ import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
4
+ import { getAutomationRun } from "../storage/automation-run-repository.js";
5
+ import "../storage/index.js";
6
+ import { getAutomationEventForRun } from "../events/event-repository.js";
7
+ import { assertUrlSafe } from "../../agent/tools/url-safety.js";
8
+ import "../events/index.js";
9
+ import { resolveAutomationWebhookSecret } from "../webhook-secrets.js";
10
+ import { createHmac, randomUUID } from "node:crypto";
11
+ //#region src/automations/delivery/delivery-router.ts
12
+ init_transaction();
13
+ init_logger();
14
+ const log = createLogger("AutomationDeliveryRouter");
15
+ const MAX_ATTEMPTS = 5;
16
+ const LEASE_MS = 45e3;
17
+ const MAX_INLINE_ARTIFACT_BYTES = 64 * 1024;
18
+ function listAutomationResultDeliveries(input = {}) {
19
+ const clauses = [];
20
+ const params = [];
21
+ if (input.runId) {
22
+ clauses.push("run_id = ?");
23
+ params.push(input.runId);
24
+ }
25
+ if (input.status) {
26
+ clauses.push("status = ?");
27
+ params.push(input.status);
28
+ }
29
+ params.push(Math.max(1, Math.min(200, Math.floor(input.limit ?? 50))));
30
+ return getSqliteDatabase().prepare(`SELECT delivery_id, run_id, destination_key, kind, status, config_json,
31
+ attempts, next_attempt_at_ms, last_error, created_at_ms, updated_at_ms
32
+ FROM automation_result_deliveries ${clauses.length ? `WHERE ${clauses.join(" AND ")}` : ""}
33
+ ORDER BY created_at_ms DESC, run_id DESC, destination_key LIMIT ?`).all(...params).map((row) => ({
34
+ runId: row.run_id,
35
+ destinationKey: row.destination_key,
36
+ kind: row.kind,
37
+ status: row.status,
38
+ attempts: row.attempts,
39
+ nextAttemptAtMs: row.next_attempt_at_ms,
40
+ ...row.last_error ? { lastError: row.last_error } : {},
41
+ createdAtMs: row.created_at_ms,
42
+ updatedAtMs: row.updated_at_ms
43
+ }));
44
+ }
45
+ function retryAutomationResultDelivery(runId, destinationKey) {
46
+ const now = Date.now();
47
+ return getSqliteDatabase().prepare(`UPDATE automation_result_deliveries
48
+ SET status = 'retrying', attempts = 0, next_attempt_at_ms = ?, last_error = NULL,
49
+ lease_owner = NULL, lease_until_ms = NULL, updated_at_ms = ?
50
+ WHERE run_id = ? AND destination_key = ? AND status = 'dead_letter'`).run(now, now, runId, destinationKey).changes === 1;
51
+ }
52
+ function getAutomationResultDeliveryMetrics() {
53
+ const now = Date.now();
54
+ const row = getSqliteDatabase().prepare(`SELECT
55
+ SUM(CASE WHEN status IN ('pending', 'retrying', 'delivering') THEN 1 ELSE 0 END) AS pending,
56
+ SUM(CASE WHEN status = 'dead_letter' THEN 1 ELSE 0 END) AS dead_letters,
57
+ SUM(CASE WHEN status = 'delivering' AND lease_until_ms > ? THEN 1 ELSE 0 END) AS active_leases
58
+ FROM automation_result_deliveries`).get(now);
59
+ return {
60
+ pending: row.pending ?? 0,
61
+ deadLetters: row.dead_letters ?? 0,
62
+ activeLeases: row.active_leases ?? 0
63
+ };
64
+ }
65
+ function assertArtifacts(artifacts) {
66
+ for (const artifact of artifacts) {
67
+ if (artifact.kind === "file") {
68
+ let uri;
69
+ try {
70
+ uri = new URL(artifact.uri);
71
+ } catch {
72
+ throw new Error(`Automation file artifact must use an authorized URI: ${artifact.id}`);
73
+ }
74
+ if (uri.protocol !== "xopc:" && uri.protocol !== "https:") throw new Error(`Automation file artifact URI is not allowed: ${artifact.id}`);
75
+ continue;
76
+ }
77
+ if (artifact.kind === "reference") continue;
78
+ if (Buffer.byteLength(JSON.stringify(artifact)) > MAX_INLINE_ARTIFACT_BYTES) throw new Error(`Automation artifact exceeds ${MAX_INLINE_ARTIFACT_BYTES} bytes: ${artifact.id}`);
79
+ }
80
+ }
81
+ function toResult(run, artifacts) {
82
+ if (run.endedAtMs === void 0 || ![
83
+ "succeeded",
84
+ "failed",
85
+ "cancelled",
86
+ "timeout"
87
+ ].includes(run.status)) throw new Error("Cannot deliver an unfinished automation run");
88
+ assertArtifacts(artifacts);
89
+ const event = getAutomationEventForRun(run.id);
90
+ return {
91
+ schemaVersion: 1,
92
+ resultId: `result:${run.id}`,
93
+ runId: run.id,
94
+ automationId: run.automationId,
95
+ status: run.status,
96
+ ...run.summary ? { summary: run.summary } : {},
97
+ ...run.error ? { error: {
98
+ code: `AUTOMATION_${run.status.toUpperCase()}`,
99
+ message: run.error,
100
+ retryable: false
101
+ } } : {},
102
+ artifacts,
103
+ correlationId: event?.correlationId ?? run.id,
104
+ rootEventId: event?.rootEventId ?? run.id,
105
+ createdAtMs: run.createdAtMs,
106
+ completedAtMs: run.endedAtMs
107
+ };
108
+ }
109
+ var AutomationDeliveryRouter = class {
110
+ active;
111
+ timer;
112
+ handlers = /* @__PURE__ */ new Map();
113
+ owner = `automation-delivery:${process.pid}:${randomUUID()}`;
114
+ abortController = new AbortController();
115
+ constructor(options = {}) {
116
+ this.options = options;
117
+ this.register("gateway_event", ({ run, config }) => this.options.deliverGatewayEvent?.(run, {
118
+ notificationPolicy: config.notificationPolicy,
119
+ requiresAttention: config.requiresAttention === true,
120
+ ...typeof config.projectId === "string" ? { projectId: config.projectId } : {}
121
+ }));
122
+ this.register("webhook", (input) => this.postWebhook(input));
123
+ }
124
+ register(kind, handler) {
125
+ if (this.handlers.has(kind)) throw new Error(`Automation delivery handler already registered: ${kind}`);
126
+ this.handlers.set(kind, handler);
127
+ }
128
+ validateArtifacts(artifacts) {
129
+ assertArtifacts(artifacts);
130
+ }
131
+ enqueue(run, automation, suppliedArtifacts = []) {
132
+ const now = Date.now();
133
+ const result = toResult(run, suppliedArtifacts.length > 0 ? suppliedArtifacts : run.summary ? [{
134
+ id: `summary:${run.id}`,
135
+ kind: "text",
136
+ text: run.summary,
137
+ mediaType: "text/plain"
138
+ }] : []);
139
+ runSqliteWriteTransaction((db) => {
140
+ db.prepare(`INSERT INTO automation_results (run_id, result_id, result_json, created_at_ms)
141
+ VALUES (?, ?, ?, ?)`).run(run.id, result.resultId, JSON.stringify(result), now);
142
+ const insert = db.prepare(`INSERT INTO automation_result_deliveries (
143
+ delivery_id, run_id, destination_key, kind, status, config_json, attempts,
144
+ next_attempt_at_ms, created_at_ms, updated_at_ms
145
+ ) VALUES (?, ?, ?, ?, 'pending', ?, 0, ?, ?, ?)`);
146
+ for (const destination of automation.delivery.destinations) {
147
+ const config = destination.kind === "gateway_event" ? {
148
+ ...destination,
149
+ notificationPolicy: automation.delivery.notificationPolicy,
150
+ requiresAttention: run.status !== "succeeded" || (automation.safety?.mode ?? "auto_apply") !== "auto_apply",
151
+ ...automation.projectId ? { projectId: automation.projectId } : {}
152
+ } : destination;
153
+ insert.run(randomUUID(), run.id, destination.key, destination.kind, JSON.stringify(config), now, now, now);
154
+ }
155
+ });
156
+ }
157
+ start() {
158
+ if (this.timer) return;
159
+ this.dispatch();
160
+ this.timer = setInterval(() => void this.dispatch(), 1e3);
161
+ this.timer.unref?.();
162
+ }
163
+ async stop() {
164
+ if (this.timer) clearInterval(this.timer);
165
+ this.timer = void 0;
166
+ this.abortController.abort(/* @__PURE__ */ new Error("Automation delivery router stopped"));
167
+ await this.active?.catch(() => void 0);
168
+ }
169
+ dispatch() {
170
+ this.active ??= this.runDispatch().finally(() => {
171
+ this.active = void 0;
172
+ });
173
+ return this.active;
174
+ }
175
+ claim(limit) {
176
+ const now = Date.now();
177
+ return runSqliteWriteTransaction((db) => {
178
+ const expiredCandidates = db.prepare(`SELECT delivery_id, run_id, destination_key
179
+ FROM automation_result_deliveries
180
+ WHERE status = 'delivering' AND lease_until_ms <= ? AND attempts >= ?`).all(now, MAX_ATTEMPTS);
181
+ const expire = db.prepare(`UPDATE automation_result_deliveries
182
+ SET status = 'dead_letter', last_error = 'Delivery lease expired after maximum attempts',
183
+ lease_owner = NULL, lease_until_ms = NULL, updated_at_ms = ?
184
+ WHERE delivery_id = ? AND status = 'delivering' AND lease_until_ms <= ? AND attempts >= ?`);
185
+ const expired = [];
186
+ for (const candidate of expiredCandidates) if (expire.run(now, candidate.delivery_id, now, MAX_ATTEMPTS).changes === 1) expired.push({
187
+ runId: candidate.run_id,
188
+ destinationKey: candidate.destination_key,
189
+ error: "Delivery lease expired after maximum attempts"
190
+ });
191
+ const candidates = db.prepare(`SELECT delivery_id, run_id, destination_key, kind, config_json, attempts
192
+ FROM automation_result_deliveries
193
+ WHERE attempts < ? AND (
194
+ (status IN ('pending', 'retrying') AND next_attempt_at_ms <= ?)
195
+ OR (status = 'delivering' AND lease_until_ms <= ?)
196
+ )
197
+ ORDER BY created_at_ms, run_id, destination_key LIMIT ?`).all(MAX_ATTEMPTS, now, now, limit);
198
+ const claimed = [];
199
+ const statement = db.prepare(`UPDATE automation_result_deliveries
200
+ SET status = 'delivering', attempts = attempts + 1, lease_owner = ?, lease_until_ms = ?, updated_at_ms = ?
201
+ WHERE delivery_id = ? AND attempts = ? AND (
202
+ (status IN ('pending', 'retrying') AND next_attempt_at_ms <= ?)
203
+ OR (status = 'delivering' AND lease_until_ms <= ?)
204
+ )`);
205
+ for (const candidate of candidates) if (statement.run(this.owner, now + LEASE_MS, now, candidate.delivery_id, candidate.attempts, now, now).changes === 1) claimed.push(candidate);
206
+ return {
207
+ rows: claimed,
208
+ expired
209
+ };
210
+ });
211
+ }
212
+ async runDispatch() {
213
+ const { rows, expired } = this.claim(100);
214
+ for (const item of expired) {
215
+ this.options.onDeadLetter?.({
216
+ phase: "result_delivery",
217
+ ...item
218
+ });
219
+ log.warn(item, "Automation result delivery moved to dead letter after lease expiry");
220
+ }
221
+ let delivered = 0;
222
+ for (const [index, row] of rows.entries()) {
223
+ if (this.abortController.signal.aborted) {
224
+ for (const remaining of rows.slice(index)) this.release(remaining);
225
+ break;
226
+ }
227
+ const run = getAutomationRun(row.run_id);
228
+ const resultRow = getSqliteDatabase().prepare("SELECT result_json FROM automation_results WHERE run_id = ?").get(row.run_id);
229
+ if (!run || !resultRow) {
230
+ this.fail(row, /* @__PURE__ */ new Error("Automation result is unavailable"), true);
231
+ continue;
232
+ }
233
+ try {
234
+ const handler = this.handlers.get(row.kind);
235
+ if (!handler) throw new Error(`Automation delivery handler is unavailable: ${row.kind}`);
236
+ await handler({
237
+ deliveryId: row.delivery_id,
238
+ attempt: row.attempts + 1,
239
+ run,
240
+ result: JSON.parse(resultRow.result_json),
241
+ config: JSON.parse(row.config_json),
242
+ signal: this.abortController.signal
243
+ });
244
+ if (getSqliteDatabase().prepare(`UPDATE automation_result_deliveries
245
+ SET status = 'delivered', last_error = NULL, lease_owner = NULL, lease_until_ms = NULL, updated_at_ms = ?
246
+ WHERE delivery_id = ? AND status = 'delivering' AND lease_owner = ?`).run(Date.now(), row.delivery_id, this.owner).changes === 1) delivered += 1;
247
+ } catch (error) {
248
+ if (this.abortController.signal.aborted) this.release(row);
249
+ else this.fail(row, error, false);
250
+ }
251
+ }
252
+ return delivered;
253
+ }
254
+ release(row) {
255
+ getSqliteDatabase().prepare(`UPDATE automation_result_deliveries
256
+ SET status = 'retrying', attempts = MAX(0, attempts - 1), next_attempt_at_ms = ?,
257
+ lease_owner = NULL, lease_until_ms = NULL, updated_at_ms = ?
258
+ WHERE delivery_id = ? AND status = 'delivering' AND lease_owner = ?`).run(Date.now(), Date.now(), row.delivery_id, this.owner);
259
+ }
260
+ fail(row, error, permanent) {
261
+ const attempts = row.attempts + 1;
262
+ const terminal = permanent || attempts >= MAX_ATTEMPTS;
263
+ const delayMs = Math.min(10 * 6e4, 1e3 * 5 ** Math.max(0, attempts - 1));
264
+ if (getSqliteDatabase().prepare(`UPDATE automation_result_deliveries
265
+ SET status = ?, next_attempt_at_ms = ?, last_error = ?, lease_owner = NULL,
266
+ lease_until_ms = NULL, updated_at_ms = ?
267
+ WHERE delivery_id = ? AND status = 'delivering' AND lease_owner = ?`).run(terminal ? "dead_letter" : "retrying", Date.now() + delayMs, error instanceof Error ? error.message : String(error), Date.now(), row.delivery_id, this.owner).changes !== 1) return;
268
+ if (terminal) this.options.onDeadLetter?.({
269
+ phase: "result_delivery",
270
+ runId: row.run_id,
271
+ destinationKey: row.destination_key,
272
+ error: error instanceof Error ? error.message : String(error)
273
+ });
274
+ log.warn({
275
+ err: error,
276
+ runId: row.run_id,
277
+ deliveryKind: row.kind,
278
+ attempt: attempts
279
+ }, terminal ? "Automation result delivery moved to dead letter" : "Automation result delivery will retry");
280
+ }
281
+ async postWebhook(input) {
282
+ const endpoint = String(input.config.endpoint ?? "");
283
+ const secretId = String(input.config.secretId ?? "");
284
+ assertUrlSafe(endpoint);
285
+ const secret = resolveAutomationWebhookSecret(secretId);
286
+ if (!secret) throw new Error(`Automation webhook secret is unavailable: ${secretId}`);
287
+ const timestamp = String(Date.now());
288
+ const body = JSON.stringify(input.result);
289
+ const signature = createHmac("sha256", secret).update(`${timestamp}.${body}`).digest("hex");
290
+ const controller = new AbortController();
291
+ const onAbort = () => controller.abort(input.signal.reason);
292
+ input.signal.addEventListener("abort", onAbort, { once: true });
293
+ if (input.signal.aborted) onAbort();
294
+ const timer = setTimeout(() => controller.abort(/* @__PURE__ */ new Error("Automation delivery timed out")), 3e4);
295
+ try {
296
+ const response = await (this.options.fetch ?? fetch)(endpoint, {
297
+ method: "POST",
298
+ redirect: "manual",
299
+ headers: {
300
+ "content-type": "application/json",
301
+ "idempotency-key": `${input.result.runId}:${String(input.config.key)}`,
302
+ "x-xopc-delivery-id": input.deliveryId,
303
+ "x-xopc-delivery-attempt": String(input.attempt),
304
+ "x-xopc-timestamp": timestamp,
305
+ "x-xopc-signature": `sha256=${signature}`
306
+ },
307
+ body,
308
+ signal: controller.signal
309
+ });
310
+ if (!response.ok) throw new Error(`Automation delivery failed with HTTP ${response.status}`);
311
+ } finally {
312
+ clearTimeout(timer);
313
+ input.signal.removeEventListener("abort", onAbort);
314
+ }
315
+ }
316
+ };
317
+ //#endregion
318
+ export { AutomationDeliveryRouter, getAutomationResultDeliveryMetrics, listAutomationResultDeliveries, retryAutomationResultDelivery };
@@ -0,0 +1 @@
1
+ export * from './delivery-router.js';
@@ -0,0 +1,2 @@
1
+ import { AutomationDeliveryRouter, getAutomationResultDeliveryMetrics, listAutomationResultDeliveries, retryAutomationResultDelivery } from "./delivery-router.js";
2
+ export { AutomationDeliveryRouter, getAutomationResultDeliveryMetrics, listAutomationResultDeliveries, retryAutomationResultDelivery };
@@ -4,5 +4,4 @@ export declare const DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS: number;
4
4
  export declare function defaultAutomationTimeoutSeconds(action: AutomationAction): number;
5
5
  export declare function resolveAutomationTimeoutSeconds(action: AutomationAction, reliability?: {
6
6
  executionTimeoutSeconds?: number;
7
- timeoutSeconds?: number;
8
7
  }): number;
@@ -5,7 +5,7 @@ function defaultAutomationTimeoutSeconds(action) {
5
5
  return action.kind === "system" ? 60 : action.kind === "browser_automation" ? 600 : DEFAULT_AUTOMATION_TIMEOUT_SECONDS;
6
6
  }
7
7
  function resolveAutomationTimeoutSeconds(action, reliability) {
8
- return reliability?.executionTimeoutSeconds ?? ("timeoutSeconds" in action ? action.timeoutSeconds : void 0) ?? reliability?.timeoutSeconds ?? defaultAutomationTimeoutSeconds(action);
8
+ return reliability?.executionTimeoutSeconds ?? ("timeoutSeconds" in action ? action.timeoutSeconds : void 0) ?? defaultAutomationTimeoutSeconds(action);
9
9
  }
10
10
  //#endregion
11
11
  export { DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds };
@@ -1,4 +1,4 @@
1
- import { AutomationActionSchema, AutomationManagementSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./validation.js";
1
+ import { AutomationActionSchema, AutomationDeliveryPolicySchema, AutomationManagementSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./validation.js";
2
2
  import { computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, timerDelayUntil } from "./schedule.js";
3
3
  import { DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds } from "./defaults.js";
4
- export { AutomationActionSchema, AutomationManagementSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds, timerDelayUntil };
4
+ export { AutomationActionSchema, AutomationDeliveryPolicySchema, AutomationManagementSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds, timerDelayUntil };