@xopcai/xopc 0.0.331 → 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 (388) 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-B0BtF24E.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-DbvLXQO2.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-fwzTRJfP.js → app-management-settings-panel-BcszTlqr.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-v_GGe8UZ.js → appearance-settings-B1XPe8qz.js} +1 -1
  9. package/dist/gateway/static/root/assets/{apps-page-C9ZMEuuA.js → apps-page-ZqANbUZv.js} +1 -1
  10. package/dist/gateway/static/root/assets/{archive-plugin-B6EgADeH.js → archive-plugin-MjUsJcNb.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-B4H_IFeX.js → attachment-load-DHa-BI9a.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-page-UlVCvg4r.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-BxTSx30f.js → binary-plugins-DQYcuBHP.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-CVzdrpjl.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-CBVD8k6O.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-BAT7Vvb8.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-EETjXmkG.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-DCqm9j9W.js → chat-terminal-dock-Fnum_IEm.js} +1 -1
  25. package/dist/gateway/static/root/assets/{computer-settings-page-CxFWdovV.js → computer-settings-page-DI1zfCTA.js} +1 -1
  26. package/dist/gateway/static/root/assets/{connector-service-page-wxsEhmlU.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-h_OS6uBR.js → date-picker-D-JhzZyW.js} +1 -1
  29. package/dist/gateway/static/root/assets/{dependency-picker-DNgSSH3z.js → dependency-picker-DpD3xaEB.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-CflvPnB-.js → desktop-pet-CCoDxKqh.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-settings-CXy0X5Js.js → desktop-pet-settings-GxndKfCx.js} +1 -1
  32. package/dist/gateway/static/root/assets/{device-pairing-wizard-BDMiJcsK.js → device-pairing-wizard-B71w3ptm.js} +1 -1
  33. package/dist/gateway/static/root/assets/{directory-picker-path-field-BqkOh13m.js → directory-picker-path-field-CUzjJvjs.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-debug-page-VT4s-9pK.js → extension-debug-page-BtDY8ntX.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-page-CBSeGhGA.js → extension-page-D9_XF-XC.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-settings-page-DRB6uOo8.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-lF-FpnZy.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-DGkOijwE.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-iU6c2zg1.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-C0BWC8D2.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-Dpoi-r-_.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-C8E_F2F_.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-qqWG_gs_.js → page-context-capture-button-D43aVpCj.js} +1 -1
  57. package/dist/gateway/static/root/assets/{page-tabs-b3lheKy4.js → page-tabs-BhYBCqls.js} +1 -1
  58. package/dist/gateway/static/root/assets/{preview-open-alternatives-0Q4rTfGX.js → preview-open-alternatives-CP8agNlc.js} +1 -1
  59. package/dist/gateway/static/root/assets/{product-open-page-jnJZCrKQ.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-r96k_2wB.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-B1d8pB_y.js → remote-access-hub-fVPQe5YS.js} +1 -1
  64. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-Do_iF13W.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-Cfft26Je.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-iI0MTyuU.js → settings-form-section-jquf1P7n.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-C2Ka9oJm.js → settings-page-DPomsvba.js} +1 -1
  71. package/dist/gateway/static/root/assets/{setup-status-panel-nnmS_p5h.js → setup-status-panel-BvVlqpHf.js} +1 -1
  72. package/dist/gateway/static/root/assets/{share-preview-page-D0Knvtlp.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-BuZKcy9b.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-DcxWxIrR.js → skills-page-D7XPEQu_.js} +1 -1
  77. package/dist/gateway/static/root/assets/{system-settings-panel-CMG0ZAsd.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-DGYA6GyO.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-CDemMoSX.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-CXArY4t5.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-Dk5KsKOm.js → work-discovery-overlay-CJzqJ47I.js} +1 -1
  86. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DNpdaI-2.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 +59 -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 +13 -7
  97. package/dist/src/agent/background-review/run-background-review.js +7 -2
  98. package/dist/src/agent/bootstrap/filter-bootstrap-files.js +1 -1
  99. package/dist/src/agent/embedded/run-turn.js +7 -1
  100. package/dist/src/agent/external-tools/endpoint-provider.js +2 -2
  101. package/dist/src/agent/external-tools/gateway-tools.d.ts +2 -1
  102. package/dist/src/agent/external-tools/gateway-tools.js +44 -11
  103. package/dist/src/agent/external-tools/index.js +1 -1
  104. package/dist/src/agent/image/tool-model-config.js +1 -1
  105. package/dist/src/agent/image/understanding/pi-ai-provider.js +1 -1
  106. package/dist/src/agent/memory/compaction.js +4 -0
  107. package/dist/src/agent/orchestration/agent-orchestrator.js +0 -21
  108. package/dist/src/agent/service/btw-query.js +8 -2
  109. package/dist/src/agent/service.js +3 -3
  110. package/dist/src/agent/skills/filesystem-watcher.js +1 -1
  111. package/dist/src/agent/skills/hub-pull.js +2 -2
  112. package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +1 -1
  113. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +1 -1
  114. package/dist/src/agent/tasks/task-judge-service.js +4 -0
  115. package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
  116. package/dist/src/agent/tool-manuals/xopc-use.js +5 -4
  117. package/dist/src/agent/tools/automation-tool.d.ts +4 -1
  118. package/dist/src/agent/tools/automation-tool.js +42 -4
  119. package/dist/src/agent/tools/session-search-tool.js +1 -1
  120. package/dist/src/agent/tools/web-extract.js +1 -1
  121. package/dist/src/agent/tools/xopc-use-tool.js +50 -9
  122. package/dist/src/agent-catalog/capabilities.js +2 -2
  123. package/dist/src/ai-assist/text-assist.js +5 -1
  124. package/dist/src/auth/credentials.js +1 -1
  125. package/dist/src/auth/oauth-provider-lock.js +1 -1
  126. package/dist/src/auth/sync-provider-auth.js +1 -1
  127. package/dist/src/automations/api/routes.js +65 -0
  128. package/dist/src/automations/capabilities/drafts.js +1 -1
  129. package/dist/src/automations/capabilities/read.js +24 -0
  130. package/dist/src/automations/capabilities/write.d.ts +69 -14
  131. package/dist/src/automations/capabilities/write.js +78 -5
  132. package/dist/src/automations/delivery/delivery-router.d.ts +50 -0
  133. package/dist/src/automations/delivery/delivery-router.js +318 -0
  134. package/dist/src/automations/delivery/index.d.ts +1 -0
  135. package/dist/src/automations/delivery/index.js +2 -0
  136. package/dist/src/automations/domain/defaults.d.ts +0 -1
  137. package/dist/src/automations/domain/defaults.js +2 -2
  138. package/dist/src/automations/domain/index.js +2 -2
  139. package/dist/src/automations/domain/types.d.ts +180 -7
  140. package/dist/src/automations/domain/validation.d.ts +172 -22
  141. package/dist/src/automations/domain/validation.js +82 -13
  142. package/dist/src/automations/draft/automation-draft-prompt.js +3 -4
  143. package/dist/src/automations/draft/automation-draft-service.js +6 -0
  144. package/dist/src/automations/draft/automation-draft-validator.d.ts +31 -3
  145. package/dist/src/automations/draft/automation-draft-validator.js +5 -4
  146. package/dist/src/automations/events/event-catalog.d.ts +14 -0
  147. package/dist/src/automations/events/event-catalog.js +117 -0
  148. package/dist/src/automations/events/event-dispatcher.d.ts +27 -0
  149. package/dist/src/automations/events/event-dispatcher.js +140 -0
  150. package/dist/src/automations/events/event-repository.d.ts +59 -0
  151. package/dist/src/automations/events/event-repository.js +361 -0
  152. package/dist/src/automations/events/index.d.ts +3 -0
  153. package/dist/src/automations/events/index.js +4 -0
  154. package/dist/src/automations/index.d.ts +3 -1
  155. package/dist/src/automations/index.js +9 -3
  156. package/dist/src/automations/service/action-executor.d.ts +20 -1
  157. package/dist/src/automations/service/action-executor.js +80 -24
  158. package/dist/src/automations/service/automation-service.d.ts +21 -4
  159. package/dist/src/automations/service/automation-service.js +150 -100
  160. package/dist/src/automations/storage/automation-repository.js +7 -7
  161. package/dist/src/automations/storage/automation-run-repository.d.ts +1 -0
  162. package/dist/src/automations/storage/automation-run-repository.js +26 -1
  163. package/dist/src/automations/storage/index.js +2 -2
  164. package/dist/src/automations/webhook-secrets.d.ts +1 -0
  165. package/dist/src/automations/webhook-secrets.js +16 -0
  166. package/dist/src/bootstrap/application-state.js +1 -1
  167. package/dist/src/capabilities/runtime/dispatcher.js +1 -1
  168. package/dist/src/capabilities/runtime/product.js +1 -1
  169. package/dist/src/capabilities/store-connector.d.ts +17 -1
  170. package/dist/src/capabilities/store-connector.js +69 -3
  171. package/dist/src/chat-commands/agent-edit.js +1 -1
  172. package/dist/src/chat-commands/builtins/config.js +1 -1
  173. package/dist/src/cli/commands/agent.js +1 -1
  174. package/dist/src/cli/commands/agents.js +1 -1
  175. package/dist/src/cli/commands/connectors.js +4 -3
  176. package/dist/src/cli/commands/doctor/checks/automation-integrity.d.ts +2 -0
  177. package/dist/src/cli/commands/doctor/checks/automation-integrity.js +55 -0
  178. package/dist/src/cli/commands/doctor/checks/database-relations.d.ts +2 -0
  179. package/dist/src/cli/commands/doctor/checks/database-relations.js +81 -0
  180. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  181. package/dist/src/cli/commands/doctor/flow.js +5 -1
  182. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  183. package/dist/src/cli/commands/models.js +1 -1
  184. package/dist/src/cli/commands/onboard/model.js +2 -2
  185. package/dist/src/cli/commands/skills.js +1 -1
  186. package/dist/src/cli/utils/init-workspace-core.js +1 -1
  187. package/dist/src/config/index.js +4 -4
  188. package/dist/src/config/loader.js +2 -2
  189. package/dist/src/config/models-json.js +1 -1
  190. package/dist/src/config/schema.d.ts +4 -0
  191. package/dist/src/config/schema.js +5 -1
  192. package/dist/src/connectors/approval-resume.js +1 -1
  193. package/dist/src/connectors/cli/store.js +1 -1
  194. package/dist/src/connectors/composio-backends.js +14 -4
  195. package/dist/src/connectors/composio-managed-events.d.ts +5 -2
  196. package/dist/src/connectors/composio-managed-events.js +4 -1
  197. package/dist/src/connectors/connection-recovery-service.d.ts +2 -1
  198. package/dist/src/connectors/connection-recovery-service.js +89 -4
  199. package/dist/src/discussions/analyzer.js +4 -4
  200. package/dist/src/extensions/agent-plugins/validation.js +1 -1
  201. package/dist/src/extensions/update.js +1 -1
  202. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  203. package/dist/src/gateway/agents-admin.js +2 -2
  204. package/dist/src/gateway/file-path-classifier.js +1 -1
  205. package/dist/src/gateway/home-intelligence-automation-reconciler.d.ts +3 -0
  206. package/dist/src/gateway/home-intelligence-automation-reconciler.js +52 -0
  207. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  208. package/dist/src/gateway/hono/routes/capabilities.js +1 -1
  209. package/dist/src/gateway/hono/routes/config-patch/misc.js +18 -4
  210. package/dist/src/gateway/hono/routes/connection-waits.js +3 -2
  211. package/dist/src/gateway/hono/routes/home.js +0 -1
  212. package/dist/src/gateway/hono/routes/lazy-bundles.js +14 -1
  213. package/dist/src/gateway/hono/routes/notes.js +2 -2
  214. package/dist/src/gateway/hono/routes/projects.js +2 -2
  215. package/dist/src/gateway/hono/routes/public-gateway.js +93 -3
  216. package/dist/src/gateway/hono/routes/scenes.js +57 -41
  217. package/dist/src/gateway/hono/routes/session-input-handler.js +1 -1
  218. package/dist/src/gateway/hono/routes/sessions.js +15 -0
  219. package/dist/src/gateway/hono/routes/tasks.js +1 -1
  220. package/dist/src/gateway/hono/routes/update.js +6 -1
  221. package/dist/src/gateway/hono/routes/usage.d.ts +3 -0
  222. package/dist/src/gateway/hono/routes/usage.js +61 -0
  223. package/dist/src/gateway/hono/routes/voice.js +1 -1
  224. package/dist/src/gateway/image-generation-setup.js +2 -2
  225. package/dist/src/gateway/lock.js +1 -1
  226. package/dist/src/gateway/memory-maintenance-automation-reconciler.js +21 -15
  227. package/dist/src/gateway/scenes/host.js +27 -14
  228. package/dist/src/gateway/scenes/slackThreadSource.d.ts +2 -2
  229. package/dist/src/gateway/security/gateway-scopes.js +1 -0
  230. package/dist/src/gateway/service/active-execution.d.ts +19 -0
  231. package/dist/src/gateway/service/active-execution.js +16 -0
  232. package/dist/src/gateway/service/agent-runner.d.ts +4 -0
  233. package/dist/src/gateway/service/agent-runner.js +19 -1
  234. package/dist/src/gateway/service/marketplace-service.js +2 -2
  235. package/dist/src/gateway/service/run-gateway-agent.d.ts +2 -0
  236. package/dist/src/gateway/service/run-gateway-agent.js +9 -1
  237. package/dist/src/gateway/service/sessions-api.d.ts +13 -0
  238. package/dist/src/gateway/service/sessions-api.js +23 -0
  239. package/dist/src/gateway/service.d.ts +7 -3
  240. package/dist/src/gateway/service.js +108 -89
  241. package/dist/src/gateway/side-chat/run-service.js +10 -7
  242. package/dist/src/gateway/xopc-cloud-capability-setup.js +1 -1
  243. package/dist/src/home-intelligence/generator.js +4 -1
  244. package/dist/src/home-intelligence/host.d.ts +1 -1
  245. package/dist/src/home-intelligence/host.js +2 -10
  246. package/dist/src/home-intelligence/notification.js +1 -1
  247. package/dist/src/home-intelligence/repository.d.ts +1 -1
  248. package/dist/src/infra/domain-outbox-dispatcher.d.ts +0 -3
  249. package/dist/src/infra/domain-outbox-dispatcher.js +15 -7
  250. package/dist/src/infra/update-check.d.ts +8 -4
  251. package/dist/src/infra/update-check.js +43 -41
  252. package/dist/src/infra/update-startup.d.ts +7 -1
  253. package/dist/src/infra/update-startup.js +15 -6
  254. package/dist/src/local-apps/service.js +2 -2
  255. package/dist/src/memory-maintenance/index.js +2 -2
  256. package/dist/src/memory-maintenance/schedule.d.ts +0 -3
  257. package/dist/src/memory-maintenance/schedule.js +1 -8
  258. package/dist/src/notes/service.js +2 -3
  259. package/dist/src/projects/project-service.js +1 -2
  260. package/dist/src/projects/project-skill-service.js +2 -2
  261. package/dist/src/providers/model-call.d.ts +3 -2
  262. package/dist/src/providers/model-call.js +30 -5
  263. package/dist/src/providers/model-catalog-persistence.js +1 -1
  264. package/dist/src/scenes/activationAdapter.d.ts +19 -0
  265. package/dist/src/scenes/activationAdapter.js +1 -0
  266. package/dist/src/scenes/agentExecutor.js +3 -10
  267. package/dist/src/scenes/contracts.d.ts +3 -9
  268. package/dist/src/scenes/contracts.js +1 -0
  269. package/dist/src/scenes/execution.d.ts +9 -3
  270. package/dist/src/scenes/execution.js +12 -11
  271. package/dist/src/scenes/httpServices.d.ts +5 -2
  272. package/dist/src/scenes/mailContext.d.ts +4 -0
  273. package/dist/src/scenes/mailContext.js +9 -0
  274. package/dist/src/scenes/maintenance.js +1 -5
  275. package/dist/src/scenes/metrics.d.ts +0 -6
  276. package/dist/src/scenes/metrics.js +0 -11
  277. package/dist/src/scenes/registry.d.ts +11 -0
  278. package/dist/src/scenes/registry.js +28 -0
  279. package/dist/src/scenes/repository.d.ts +6 -3
  280. package/dist/src/scenes/repository.js +43 -5
  281. package/dist/src/scenes/service.d.ts +2 -1
  282. package/dist/src/scenes/service.js +9 -7
  283. package/dist/src/scenes/taskFollowUp/contracts.d.ts +37 -7
  284. package/dist/src/scenes/taskFollowUp/contracts.js +36 -17
  285. package/dist/src/scenes/taskFollowUp/service.d.ts +35 -7
  286. package/dist/src/scenes/taskFollowUp/service.js +86 -28
  287. package/dist/src/scenes/templates.d.ts +2 -2
  288. package/dist/src/scenes/userNotes.d.ts +3 -0
  289. package/dist/src/scenes/userNotes.js +6 -0
  290. package/dist/src/session/client-history.d.ts +3 -0
  291. package/dist/src/session/client-history.js +10 -5
  292. package/dist/src/session/manager.d.ts +1 -0
  293. package/dist/src/session/resolve-session.js +4 -3
  294. package/dist/src/session/session-title.js +1 -1
  295. package/dist/src/session/store.d.ts +1 -0
  296. package/dist/src/session/store.js +3 -2
  297. package/dist/src/storage/sqlite/ai-usage-repository.d.ts +137 -0
  298. package/dist/src/storage/sqlite/ai-usage-repository.js +175 -0
  299. package/dist/src/storage/sqlite/connector-account-repository.js +7 -5
  300. package/dist/src/storage/sqlite/connector-repository.js +36 -34
  301. package/dist/src/storage/sqlite/index.d.ts +2 -2
  302. package/dist/src/storage/sqlite/index.js +3 -3
  303. package/dist/src/storage/sqlite/migrations/208_automation_management.sql +2 -0
  304. package/dist/src/storage/sqlite/migrations/209_automation_event_hub.sql +48 -0
  305. package/dist/src/storage/sqlite/migrations/210_remove_legacy_automation_timeout.sql +14 -0
  306. package/dist/src/storage/sqlite/migrations/211_automation_result_deliveries.sql +16 -0
  307. package/dist/src/storage/sqlite/migrations/212_automation_delivery_policy.sql +30 -0
  308. package/dist/src/storage/sqlite/migrations/213_automation_reliability_contract.sql +188 -0
  309. package/dist/src/storage/sqlite/migrations/214_ai_usage_ledger.sql +41 -0
  310. package/dist/src/storage/sqlite/migrations/215_scene_execution_adapters.sql +6 -0
  311. package/dist/src/storage/sqlite/migrations/216_remove_scene_model_usage.sql +1 -0
  312. package/dist/src/storage/sqlite/migrations/217_remove_legacy_memory_tables.sql +4 -0
  313. package/dist/src/storage/sqlite/migrations/218_core_relation_indexes.sql +26 -0
  314. package/dist/src/storage/sqlite/migrations/219_json_contracts.sql +123 -0
  315. package/dist/src/storage/sqlite/migrations/220_normalize_timestamps.sql +339 -0
  316. package/dist/src/storage/sqlite/migrations/221_ai_usage_retention_index.sql +2 -0
  317. package/dist/src/storage/sqlite/migrations/222_session_config_authority.sql +13 -0
  318. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  319. package/dist/src/storage/sqlite/migrations/runner.js +4 -4
  320. package/dist/src/storage/sqlite/row-mappers.d.ts +3 -7
  321. package/dist/src/storage/sqlite/row-mappers.js +6 -6
  322. package/dist/src/storage/sqlite/scenes-schema.d.ts +1 -1
  323. package/dist/src/storage/sqlite/scenes-schema.js +0 -1
  324. package/dist/src/storage/sqlite/schema.js +1 -1
  325. package/dist/src/storage/sqlite/schema.sql +0 -52
  326. package/dist/src/storage/sqlite/schemas/scenes.sql +0 -7
  327. package/dist/src/storage/sqlite/session-input-repository.d.ts +8 -0
  328. package/dist/src/storage/sqlite/session-input-repository.js +18 -1
  329. package/dist/src/storage/sqlite/session-read-repository.d.ts +1 -1
  330. package/dist/src/storage/sqlite/session-read-repository.js +0 -1
  331. package/dist/src/storage/sqlite/session-repository.d.ts +0 -4
  332. package/dist/src/storage/sqlite/session-repository.js +8 -18
  333. package/dist/src/storage/sqlite/timestamps.d.ts +4 -0
  334. package/dist/src/storage/sqlite/timestamps.js +20 -0
  335. package/dist/src/storage/sqlite/transcript-repository.d.ts +1 -0
  336. package/dist/src/storage/sqlite/transcript-repository.js +23 -15
  337. package/dist/src/storage/sqlite/user-trust-repository.js +4 -2
  338. package/dist/src/tasks/capabilities/read.js +2 -2
  339. package/dist/src/tasks/capabilities/write.d.ts +1 -1
  340. package/dist/src/tasks/home-query-service.js +4 -3
  341. package/dist/src/tasks/task-contract-planner.js +1 -1
  342. package/dist/src/tui/backends/embedded-backend.js +2 -2
  343. package/dist/src/tui/tui-commands.js +1 -1
  344. package/dist/src/tui/tui-startup-resources.js +1 -1
  345. package/dist/src/tui/tui.js +1 -1
  346. package/dist/src/usage/cost.d.ts +4 -0
  347. package/dist/src/usage/cost.js +28 -0
  348. package/dist/src/usage/recorder.d.ts +13 -0
  349. package/dist/src/usage/recorder.js +117 -0
  350. package/dist/src/usage/scenario-registry.d.ts +8 -0
  351. package/dist/src/usage/scenario-registry.js +117 -0
  352. package/dist/src/usage/types.d.ts +55 -0
  353. package/dist/src/usage/types.js +1 -0
  354. package/dist/src/user-context/config.d.ts +9 -0
  355. package/dist/src/user-context/config.js +13 -4
  356. package/dist/src/voice/realtime/persona-context.js +1 -1
  357. package/dist/src/voice/tts/summarize.js +1 -1
  358. package/dist/src/work-discovery/analyzer.js +2 -2
  359. package/dist/src/work-discovery/investigator.js +1 -1
  360. package/dist/src/workflows/service/workflow-run-service.js +15 -2
  361. package/package.json +6 -6
  362. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-DgP5DEJF.js +0 -1
  363. package/dist/gateway/static/root/assets/agents-Bh4XNLyk.js +0 -70
  364. package/dist/gateway/static/root/assets/automations-workspace-C7VS-yb7.js +0 -7
  365. package/dist/gateway/static/root/assets/browser-settings-page-CC43CC43.js +0 -3
  366. package/dist/gateway/static/root/assets/capabilities-sAZT4brT.js +0 -1
  367. package/dist/gateway/static/root/assets/capabilities-settings-panel-DPETQOfF.js +0 -8
  368. package/dist/gateway/static/root/assets/channels-CwA619os.js +0 -1
  369. package/dist/gateway/static/root/assets/connectors-page-l7goF6QS.js +0 -2
  370. package/dist/gateway/static/root/assets/home-page-DSaXXoLm.js +0 -1
  371. package/dist/gateway/static/root/assets/index-BEw0xrde.css +0 -1
  372. package/dist/gateway/static/root/assets/index-D99vN3es.js +0 -121
  373. package/dist/gateway/static/root/assets/local-app-workbench-page-rH33N8I9.js +0 -1
  374. package/dist/gateway/static/root/assets/management-settings-RFDLaquR.js +0 -1
  375. package/dist/gateway/static/root/assets/messages-fmf0dnr4.js +0 -3
  376. package/dist/gateway/static/root/assets/note-detail-panel-DI7CIjmM.js +0 -5
  377. package/dist/gateway/static/root/assets/notes-page-BkqnU-Jh.js +0 -8
  378. package/dist/gateway/static/root/assets/project-detail-page-BvvcTH2F.js +0 -1
  379. package/dist/gateway/static/root/assets/scenes-page-DK316w9a.js +0 -2
  380. package/dist/gateway/static/root/assets/sessions-page-EIk8iJTK.js +0 -1
  381. package/dist/gateway/static/root/assets/settings-advanced-gate-DcOsdz78.js +0 -1
  382. package/dist/gateway/static/root/assets/shares-settings-BcaxGQLC.js +0 -1
  383. package/dist/gateway/static/root/assets/skill-reload-api-Cb_CUL-U.js +0 -1
  384. package/dist/gateway/static/root/assets/task-detail-page-Cvr1qUTW.js +0 -1
  385. package/dist/gateway/static/root/assets/user-model-page-VXfz3rE7.js +0 -2
  386. package/dist/gateway/static/root/assets/workflows-page-DDNDLdId.js +0 -6
  387. package/dist/src/automations/product-events.d.ts +0 -5
  388. package/dist/src/automations/product-events.js +0 -19
@@ -121,6 +121,14 @@ export declare const AutomationCreateCapabilityInputSchema: z.ZodObject<{
121
121
  outputDestinations: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
122
122
  }, z.core.$strip>;
123
123
  }, z.core.$strip>], "type">;
124
+ }, z.core.$strict>, z.ZodObject<{
125
+ kind: z.ZodLiteral<"system">;
126
+ capability: z.ZodEnum<{
127
+ "home.advisor.refresh": "home.advisor.refresh";
128
+ "memory.temporal_sweep": "memory.temporal_sweep";
129
+ "memory.daily_reconciliation": "memory.daily_reconciliation";
130
+ "memory.weekly_knowledge": "memory.weekly_knowledge";
131
+ }>;
124
132
  }, z.core.$strict>], "kind">;
125
133
  id: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string, string>>;
126
134
  trigger: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -160,15 +168,34 @@ export declare const AutomationCreateCapabilityInputSchema: z.ZodObject<{
160
168
  new_session: "new_session";
161
169
  continuous: "continuous";
162
170
  }>>;
163
- notificationPolicy: z.ZodDefault<z.ZodEnum<{
164
- attention: "attention";
165
- all: "all";
166
- none: "none";
167
- }>>;
168
- completionWebhookUrl: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string, string>>;
171
+ delivery: z.ZodDefault<z.ZodObject<{
172
+ notificationPolicy: z.ZodDefault<z.ZodEnum<{
173
+ attention: "attention";
174
+ all: "all";
175
+ none: "none";
176
+ }>>;
177
+ destinations: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
178
+ key: z.ZodString;
179
+ kind: z.ZodLiteral<"gateway_event">;
180
+ }, z.core.$strict>, z.ZodObject<{
181
+ key: z.ZodString;
182
+ kind: z.ZodLiteral<"webhook">;
183
+ endpoint: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
184
+ secretId: z.ZodString;
185
+ }, z.core.$strict>, z.ZodObject<{
186
+ key: z.ZodString;
187
+ kind: z.ZodLiteral<"file">;
188
+ targetId: z.ZodString;
189
+ pathTemplate: z.ZodString;
190
+ }, z.core.$strict>, z.ZodObject<{
191
+ key: z.ZodString;
192
+ kind: z.ZodLiteral<"card">;
193
+ channelId: z.ZodString;
194
+ templateId: z.ZodString;
195
+ }, z.core.$strict>], "kind">>>;
196
+ }, z.core.$strict>>;
169
197
  reliability: z.ZodOptional<z.ZodObject<{
170
198
  executionTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
171
- timeoutSeconds: z.ZodOptional<z.ZodNumber>;
172
199
  retryCount: z.ZodOptional<z.ZodNumber>;
173
200
  maxConcurrentRuns: z.ZodOptional<z.ZodNumber>;
174
201
  disableAfterConsecutiveFailures: z.ZodOptional<z.ZodNumber>;
@@ -293,6 +320,14 @@ export declare const AutomationUpdatePatchSchema: z.ZodObject<{
293
320
  outputDestinations: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
294
321
  }, z.core.$strip>;
295
322
  }, z.core.$strip>], "type">;
323
+ }, z.core.$strict>, z.ZodObject<{
324
+ kind: z.ZodLiteral<"system">;
325
+ capability: z.ZodEnum<{
326
+ "home.advisor.refresh": "home.advisor.refresh";
327
+ "memory.temporal_sweep": "memory.temporal_sweep";
328
+ "memory.daily_reconciliation": "memory.daily_reconciliation";
329
+ "memory.weekly_knowledge": "memory.weekly_knowledge";
330
+ }>;
296
331
  }, z.core.$strict>], "kind">>;
297
332
  trigger: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
298
333
  kind: z.ZodLiteral<"manual">;
@@ -327,10 +362,8 @@ export declare const AutomationUpdatePatchSchema: z.ZodObject<{
327
362
  auto_apply: "auto_apply";
328
363
  }>;
329
364
  }, z.core.$strict>>>;
330
- completionWebhookUrl: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string, string>>>;
331
365
  reliability: z.ZodOptional<z.ZodOptional<z.ZodObject<{
332
366
  executionTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
333
- timeoutSeconds: z.ZodOptional<z.ZodNumber>;
334
367
  retryCount: z.ZodOptional<z.ZodNumber>;
335
368
  maxConcurrentRuns: z.ZodOptional<z.ZodNumber>;
336
369
  disableAfterConsecutiveFailures: z.ZodOptional<z.ZodNumber>;
@@ -339,11 +372,33 @@ export declare const AutomationUpdatePatchSchema: z.ZodObject<{
339
372
  new_session: "new_session";
340
373
  continuous: "continuous";
341
374
  }>>;
342
- notificationPolicy: z.ZodOptional<z.ZodEnum<{
343
- attention: "attention";
344
- all: "all";
345
- none: "none";
346
- }>>;
375
+ delivery: z.ZodOptional<z.ZodOptional<z.ZodObject<{
376
+ notificationPolicy: z.ZodDefault<z.ZodEnum<{
377
+ attention: "attention";
378
+ all: "all";
379
+ none: "none";
380
+ }>>;
381
+ destinations: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
382
+ key: z.ZodString;
383
+ kind: z.ZodLiteral<"gateway_event">;
384
+ }, z.core.$strict>, z.ZodObject<{
385
+ key: z.ZodString;
386
+ kind: z.ZodLiteral<"webhook">;
387
+ endpoint: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
388
+ secretId: z.ZodString;
389
+ }, z.core.$strict>, z.ZodObject<{
390
+ key: z.ZodString;
391
+ kind: z.ZodLiteral<"file">;
392
+ targetId: z.ZodString;
393
+ pathTemplate: z.ZodString;
394
+ }, z.core.$strict>, z.ZodObject<{
395
+ key: z.ZodString;
396
+ kind: z.ZodLiteral<"card">;
397
+ channelId: z.ZodString;
398
+ templateId: z.ZodString;
399
+ }, z.core.$strict>], "kind">>>;
400
+ }, z.core.$strict>>>;
347
401
  state: z.ZodOptional<z.ZodNever>;
402
+ management: z.ZodOptional<z.ZodNever>;
348
403
  }, z.core.$strict>;
349
404
  export declare function registerAutomationWriteCapabilities(dispatcher: CapabilityDispatcher, service: AutomationService, projects?: ProjectService): void;
@@ -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,12 +6,34 @@ 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
12
14
  init_src();
13
- const AutomationCreateCapabilityInputSchema = CreateAutomationSchema.omit({ state: true });
14
- const AutomationUpdatePatchSchema = UpdateAutomationSchema.safeExtend({ state: z.never().optional() });
15
+ const AutomationCreateCapabilityInputSchema = CreateAutomationSchema.omit({
16
+ state: true,
17
+ management: true
18
+ }).refine((input) => input.action.kind !== "system", { message: "System actions can only be created by the runtime" });
19
+ const AutomationUpdatePatchSchema = UpdateAutomationSchema.safeExtend({
20
+ state: z.never().optional(),
21
+ management: z.never().optional()
22
+ });
23
+ function assertManagedOperation(automation, operation, patch) {
24
+ const management = automation.management;
25
+ if (!management) return;
26
+ if (operation === "run") {
27
+ if (!management.runnable) throw new CapabilityError("FORBIDDEN", "This managed automation cannot be run manually");
28
+ return;
29
+ }
30
+ if (operation === "delete") {
31
+ if (!management.deletable) throw new CapabilityError("FORBIDDEN", "This managed automation cannot be deleted");
32
+ return;
33
+ }
34
+ const forbidden = Object.entries(patch ?? {}).filter(([key, value]) => JSON.stringify(automation[key]) !== JSON.stringify(value)).map(([key]) => key).filter((field) => !management.editable.includes(field));
35
+ if (forbidden.length > 0) throw new CapabilityError("FORBIDDEN", `Managed fields cannot be changed: ${forbidden.join(", ")}`);
36
+ }
15
37
  function registerAutomationWriteCapabilities(dispatcher, service, projects) {
16
38
  const policy = {
17
39
  majorVersion: 1,
@@ -24,6 +46,36 @@ function registerAutomationWriteCapabilities(dispatcher, service, projects) {
24
46
  const requireProject = (id) => {
25
47
  if (id && !projects?.get(id)) throw new CapabilityError("NOT_FOUND", "Project not found");
26
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
+ }));
27
79
  dispatcher.register(defineAtomicCapability({
28
80
  ...policy,
29
81
  id: "xopc.automations.cancel",
@@ -71,12 +123,30 @@ function registerAutomationWriteCapabilities(dispatcher, service, projects) {
71
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.",
72
124
  input: CapabilityResourceInputSchema,
73
125
  output: AutomationRunMutationOutputSchema,
74
- execute({ id }) {
126
+ execute({ id }, context) {
75
127
  const automationId = command === "run" ? id : getAutomationRun(id)?.automationId;
76
128
  const automation = automationId ? getAutomation(automationId) : null;
77
129
  if (!automation) throw new CapabilityError("NOT_FOUND", "Automation or source run not found");
130
+ assertManagedOperation(automation, "run");
78
131
  try {
79
- 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);
80
150
  return {
81
151
  ok: true,
82
152
  automation: { ...automation },
@@ -98,6 +168,7 @@ function registerAutomationWriteCapabilities(dispatcher, service, projects) {
98
168
  execute({ id, expectedRevision }) {
99
169
  const current = getAutomation(id);
100
170
  if (current && current.updatedAtMs !== expectedRevision) throw new CapabilityError("REVISION_CONFLICT", "Automation changed");
171
+ if (current) assertManagedOperation(current, "delete");
101
172
  const result = service.removeAtomically(id);
102
173
  return {
103
174
  ok: true,
@@ -138,6 +209,7 @@ function registerAutomationWriteCapabilities(dispatcher, service, projects) {
138
209
  const current = getAutomation(id);
139
210
  if (!current) throw new CapabilityError("NOT_FOUND", "Automation not found");
140
211
  if (current.updatedAtMs !== expectedRevision) throw new CapabilityError("REVISION_CONFLICT", "Automation changed");
212
+ assertManagedOperation(current, "update", patch);
141
213
  requireProject(patch.projectId);
142
214
  return {
143
215
  ok: true,
@@ -158,6 +230,7 @@ function registerAutomationWriteCapabilities(dispatcher, service, projects) {
158
230
  const current = getAutomation(id);
159
231
  if (!current) throw new CapabilityError("NOT_FOUND", "Automation not found");
160
232
  if (current.updatedAtMs !== expectedRevision) throw new CapabilityError("REVISION_CONFLICT", "Automation changed");
233
+ assertManagedOperation(current, "update", { enabled });
161
234
  const automation = service.updateAtomically(id, { enabled });
162
235
  if (!automation) throw new CapabilityError("NOT_FOUND", "Automation not found");
163
236
  return {
@@ -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;
@@ -2,10 +2,10 @@
2
2
  const DEFAULT_AUTOMATION_TIMEOUT_SECONDS = 1800;
3
3
  const DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS = 600;
4
4
  function defaultAutomationTimeoutSeconds(action) {
5
- return action.kind === "browser_automation" ? 600 : DEFAULT_AUTOMATION_TIMEOUT_SECONDS;
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, 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, 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 };