@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
@@ -277,4 +277,4 @@ export declare const GATEWAY_BUILTIN_TOOLS: readonly [{
277
277
  readonly zh: "使用已验证的参数执行选定的外部工具。";
278
278
  };
279
279
  }];
280
- export declare const GATEWAY_BUILTIN_TOOL_IDS: ("automation" | "workflow" | "find" | "image" | "knowledge_search" | "knowledge_get" | "knowledge_write" | "user_context_search" | "user_context_get" | "user_context_update" | "web_search" | "web_fetch" | "browser_use" | "grep" | "session_search" | "read_file" | "list_dir" | "write_file" | "apply_patch" | "exec_command" | "update_plan" | "todo" | "clarify" | "xopc_tool_execute" | "computer_use" | "tool_manual" | "web_extract" | "image_generate" | "skills_list" | "skill_view" | "skill_manage" | "skills_marketplace_search" | "session_status" | "send_message" | "send_media" | "delegate_task" | "skill_install" | "text_to_speech" | "create_share" | "xopc_tool_search" | "xopc_tool_describe" | "read_media" | "memory_maintenance" | "execute_code" | "create_desktop_pet")[];
280
+ export declare const GATEWAY_BUILTIN_TOOL_IDS: ("automation" | "workflow" | "find" | "image" | "knowledge_search" | "knowledge_get" | "knowledge_write" | "user_context_search" | "user_context_get" | "user_context_update" | "web_search" | "web_fetch" | "browser_use" | "grep" | "session_search" | "read_file" | "list_dir" | "write_file" | "apply_patch" | "exec_command" | "update_plan" | "todo" | "clarify" | "xopc_tool_execute" | "web_extract" | "image_generate" | "skills_list" | "skill_view" | "skill_manage" | "skills_marketplace_search" | "xopc_tool_search" | "xopc_tool_describe" | "send_message" | "send_media" | "read_media" | "create_share" | "session_status" | "memory_maintenance" | "computer_use" | "tool_manual" | "delegate_task" | "skill_install" | "text_to_speech" | "execute_code" | "create_desktop_pet")[];
@@ -11,7 +11,10 @@ async function reconcileHomeIntelligenceAutomation(automationService) {
11
11
  },
12
12
  safety: { mode: "auto_apply" },
13
13
  conversationMode: "new_session",
14
- notificationPolicy: "none",
14
+ delivery: {
15
+ notificationPolicy: "none",
16
+ destinations: []
17
+ },
15
18
  reliability: { disableAfterConsecutiveFailures: 3 },
16
19
  management: {
17
20
  owner: "home-intelligence",
@@ -55,7 +55,7 @@ function registerCapabilityRoutes(authenticated, deps) {
55
55
  try {
56
56
  const { instance, plan } = await persistConfigMutation({
57
57
  config,
58
- mutate: () => installStoreConnector(config, c.req.param("name"), input, optionalVersion(body)),
58
+ mutate: () => installStoreConnector(config, c.req.param("name"), input, optionalVersion(body), typeof body.reviewHash === "string" ? body.reviewHash : void 0),
59
59
  save: () => service.saveConfig(config)
60
60
  });
61
61
  return c.json({
@@ -6,9 +6,9 @@ const actionSchema = z.object({
6
6
  expectedVersion: z.number().int().positive(),
7
7
  idempotencyKey: z.string().min(1).max(200),
8
8
  action: z.enum([
9
+ "install_complete",
9
10
  "connect",
10
11
  "check",
11
- "continue",
12
12
  "skip",
13
13
  "cancel",
14
14
  "select_account",
@@ -19,7 +19,8 @@ const actionSchema = z.object({
19
19
  candidateRef: z.string().optional(),
20
20
  needKey: z.string().optional(),
21
21
  accountId: z.string().optional(),
22
- callbackUrl: z.string().max(16384).optional()
22
+ callbackUrl: z.string().max(16384).optional(),
23
+ instanceId: z.string().optional()
23
24
  }).strict();
24
25
  function registerConnectionWaitRoutes(app, { service, strictRateLimitMiddleware }) {
25
26
  app.get("/api/sessions/:conversationId/connection-wait", (c) => {
@@ -238,7 +238,12 @@ const AUTHENTICATED_LAZY_ROUTE_BUNDLES = [
238
238
  },
239
239
  {
240
240
  id: "automations",
241
- match: (path) => startsWithAny(path, ["/api/automations", "/api/automation-runs"]),
241
+ match: (path) => startsWithAny(path, [
242
+ "/api/automations",
243
+ "/api/automation-runs",
244
+ "/api/automation-events",
245
+ "/api/automation-deliveries"
246
+ ]),
242
247
  load: async () => {
243
248
  const { registerAutomationRoutes } = await import("../../../automations/api/routes.js");
244
249
  return { register: registerAutomationRoutes };
@@ -284,6 +289,14 @@ const AUTHENTICATED_LAZY_ROUTE_BUNDLES = [
284
289
  return { register: registerLogsRoutes };
285
290
  }
286
291
  },
292
+ {
293
+ id: "usage",
294
+ match: (path) => startsWithAny(path, ["/api/usage"]),
295
+ load: async () => {
296
+ const { registerUsageRoutes } = await import("./usage.js");
297
+ return { register: registerUsageRoutes };
298
+ }
299
+ },
287
300
  {
288
301
  id: "shares",
289
302
  match: (path) => startsWithAny(path, ["/api/shares", "/api/hosted-publications"]) || /^\/api\/notes\/[^/]+\/hosted-publications(?:\/.*)?$/.test(path) || /^\/api\/sessions\/[^/]+\/(?:share-preview|shares|hosted-shares)(?:\/.*)?$/.test(path),
@@ -1,10 +1,11 @@
1
1
  import { PACKAGE_VERSION, init_package_version } from "../../../package-version.js";
2
2
  import { claimConnectorWebhookDelivery, completeConnectorWebhookDelivery, releaseConnectorWebhookDelivery } from "../../../storage/sqlite/connector-repository.js";
3
3
  import { init_sqlite } from "../../../storage/sqlite/index.js";
4
+ import { resolveAutomationWebhookSecret } from "../../../automations/webhook-secrets.js";
4
5
  import { composioLogoResponse } from "../../../connectors/composio-logo.js";
5
6
  import { appendComposioTriggerEvent, applyComposioConnectionLifecycleEvent, normalizeComposioTriggerPayload, verifyComposioWebhook } from "../../../connectors/composio-triggers.js";
6
7
  import { serveStaticFile } from "../lib/static-ui.js";
7
- import { createHash } from "node:crypto";
8
+ import { createHash, timingSafeEqual } from "node:crypto";
8
9
  //#region src/gateway/hono/routes/public-gateway.ts
9
10
  init_package_version();
10
11
  init_sqlite();
@@ -19,6 +20,9 @@ const PUBLIC_UI_ROOT_ASSETS = [
19
20
  "pwa-512x512.png",
20
21
  "site.webmanifest"
21
22
  ];
23
+ function secretsEqual(actual, expected) {
24
+ return timingSafeEqual(createHash("sha256").update(actual).digest(), createHash("sha256").update(expected).digest());
25
+ }
22
26
  function registerPublicGatewayRoutes(app, service) {
23
27
  app.get("/health", (c) => {
24
28
  return c.json(service.getHealth());
@@ -84,9 +88,16 @@ function registerPublicGatewayRoutes(app, service) {
84
88
  if (inactiveConnectionId) service.setConnectorLearningPaused(inactiveConnectionId, true);
85
89
  const event = await appendComposioTriggerEvent(service.currentConfig, archivedPayload);
86
90
  if (normalized.toolkit) service.requestConnectorLearningForToolkit(normalized.toolkit);
87
- const runs = await service.automationServiceInstance.triggerEvent({
91
+ const ingested = service.ingestAutomationEvent({
92
+ id: `connector:composio:${webhookId}`,
88
93
  type: `connector.${normalized.trigger ?? normalized.type}`,
89
94
  source: normalized.toolkit ? `composio:${normalized.toolkit}` : "composio",
95
+ subject: {
96
+ kind: "connector_event",
97
+ id: webhookId
98
+ },
99
+ dedupeKey: webhookId,
100
+ trust: "connector",
90
101
  payload: {
91
102
  ...normalized.data,
92
103
  connectorId: normalized.toolkit ? `composio-${normalized.toolkit}` : "composio",
@@ -98,7 +109,7 @@ function registerPublicGatewayRoutes(app, service) {
98
109
  ok: true,
99
110
  payload: {
100
111
  eventId: event.id,
101
- automationRuns: runs.length
112
+ automationDeliveries: ingested.deliveryCount
102
113
  }
103
114
  });
104
115
  } catch (error) {
@@ -109,6 +120,85 @@ function registerPublicGatewayRoutes(app, service) {
109
120
  }, 500);
110
121
  }
111
122
  });
123
+ app.post("/api/automation-hooks/:automationId", async (c) => {
124
+ const automationId = c.req.param("automationId");
125
+ const automation = await service.automationServiceInstance.get(automationId);
126
+ if (!automation || !automation.enabled || automation.trigger.kind !== "webhook") return c.json({
127
+ ok: false,
128
+ error: "Automation webhook not found."
129
+ }, 404);
130
+ const secretId = automation.trigger.secretId?.trim();
131
+ let expectedSecret;
132
+ try {
133
+ expectedSecret = secretId ? resolveAutomationWebhookSecret(secretId) : void 0;
134
+ } catch {
135
+ return c.json({
136
+ ok: false,
137
+ error: "Automation webhook secrets are misconfigured."
138
+ }, 503);
139
+ }
140
+ if (!expectedSecret) return c.json({
141
+ ok: false,
142
+ error: "Automation webhook secret is not configured."
143
+ }, 503);
144
+ const authorization = c.req.header("authorization")?.trim() ?? "";
145
+ const suppliedSecret = authorization.startsWith("Bearer ") ? authorization.slice(7).trim() : c.req.header("x-xopc-webhook-secret")?.trim() ?? "";
146
+ if (!suppliedSecret || !secretsEqual(suppliedSecret, expectedSecret)) return c.json({
147
+ ok: false,
148
+ error: "Invalid automation webhook secret."
149
+ }, 401);
150
+ const idempotencyKey = c.req.header("idempotency-key")?.trim();
151
+ if (!idempotencyKey || idempotencyKey.length > 200) return c.json({
152
+ ok: false,
153
+ error: "A valid Idempotency-Key header is required."
154
+ }, 400);
155
+ const declaredSize = Number(c.req.header("content-length") ?? 0);
156
+ if (Number.isFinite(declaredSize) && declaredSize > 256 * 1024) return c.json({
157
+ ok: false,
158
+ error: "Webhook payload is too large."
159
+ }, 413);
160
+ const rawBody = await c.req.text();
161
+ if (Buffer.byteLength(rawBody) > 256 * 1024) return c.json({
162
+ ok: false,
163
+ error: "Webhook payload is too large."
164
+ }, 413);
165
+ let payload;
166
+ try {
167
+ const parsed = rawBody ? JSON.parse(rawBody) : {};
168
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("invalid payload");
169
+ payload = parsed;
170
+ } catch {
171
+ return c.json({
172
+ ok: false,
173
+ error: "Webhook payload must be a JSON object."
174
+ }, 400);
175
+ }
176
+ try {
177
+ const result = service.ingestAutomationEvent({
178
+ id: `webhook:${automationId}:${idempotencyKey}`,
179
+ type: "automation.webhook.received",
180
+ source: `webhook:${automationId}`,
181
+ subject: {
182
+ kind: "automation",
183
+ id: automationId
184
+ },
185
+ correlationId: c.req.header("x-correlation-id")?.trim() || void 0,
186
+ dedupeKey: idempotencyKey,
187
+ trust: "untrusted_webhook",
188
+ payload
189
+ }, { targetAutomationIds: [automationId] });
190
+ return c.json({
191
+ ok: true,
192
+ eventId: result.event.id,
193
+ duplicate: !result.created
194
+ }, result.created ? 202 : 200);
195
+ } catch {
196
+ return c.json({
197
+ ok: false,
198
+ error: "Automation webhook ingestion failed."
199
+ }, 500);
200
+ }
201
+ });
112
202
  app.get("/api", (c) => {
113
203
  return c.json({
114
204
  service: "xopc-gateway",
@@ -66,14 +66,22 @@ function registerSceneRoutes(authenticated, deps) {
66
66
  idempotencyKey: c.req.header("Idempotency-Key") ?? randomUUID()
67
67
  });
68
68
  };
69
- app.get("/source-providers", (c) => c.json({ providers: deps.scenes.followUps?.sources.list() ?? [] }));
70
- app.get("/source-providers/:provider/accounts", (c) => c.json({ accounts: deps.scenes.followUps?.sources.get(c.req.param("provider")).listAccounts?.(principal(c)) ?? [] }));
69
+ const template = (key, version) => deps.scenes.repository.getTemplate(key, version);
70
+ const adapterTarget = (key, version) => {
71
+ const manifest = template(key, version);
72
+ return manifest.execution.kind === "agent" ? void 0 : {
73
+ manifest,
74
+ adapter: deps.scenes.activationAdapters.get(manifest.execution.kind)
75
+ };
76
+ };
77
+ app.get("/source-providers", (c) => c.json({ providers: deps.scenes.sourceProviders.providers() }));
78
+ app.get("/source-providers/:provider/accounts", (c) => c.json({ accounts: deps.scenes.sourceProviders.get(c.req.param("provider")).listAccounts?.(principal(c)) ?? [] }));
71
79
  app.post("/source-providers/:provider/resolve-link", deps.strictRateLimitMiddleware, async (c) => {
72
80
  const input = z.strictObject({
73
81
  accountId: z.string().min(1).max(200),
74
82
  url: z.string().url().max(2e3)
75
83
  }).parse(await c.req.json());
76
- const source = deps.scenes.followUps?.sources.get(c.req.param("provider"));
84
+ const source = deps.scenes.sourceProviders.get(c.req.param("provider"));
77
85
  if (!source?.resolveLink) return c.json({ error: "source_resolution_unavailable" }, 422);
78
86
  const reference = await source.resolveLink(principal(c), input.accountId, input.url, AbortSignal.any([c.req.raw.signal, AbortSignal.timeout(3e4)]));
79
87
  return c.json({ source: {
@@ -81,48 +89,21 @@ function registerSceneRoutes(authenticated, deps) {
81
89
  reference
82
90
  } });
83
91
  });
84
- app.get("/task-follow-ups", (c) => c.json({ items: deps.scenes.followUps?.list(principal(c)) ?? [] }));
85
- app.get("/task-follow-ups/projects/:projectId/branches", async (c) => {
86
- if (!deps.scenes.followUps) return c.json({ error: "task_follow_up_unavailable" }, 503);
87
- return c.json(await deps.scenes.followUps.branches.list(principal(c), c.req.param("projectId")));
92
+ app.get("/resources/projects/:projectId/branches", async (c) => {
93
+ const owner = deps.scenes.activationAdapters.list().find((item) => item.listProjectBranches);
94
+ if (!owner?.listProjectBranches) return c.json({ error: "branch_inventory_unavailable" }, 503);
95
+ return c.json(await owner.listProjectBranches(principal(c), c.req.param("projectId")));
88
96
  });
89
- app.post("/task-follow-ups/branch-links", deps.strictRateLimitMiddleware, async (c) => {
97
+ app.post("/resources/branch-links", deps.strictRateLimitMiddleware, async (c) => {
90
98
  const input = z.strictObject({
91
99
  projectId: z.string().min(1).max(200),
92
100
  taskId: z.string().uuid(),
93
101
  branchRef: z.string().startsWith("refs/heads/").max(300),
94
102
  expectedSha: z.string().regex(/^[a-f0-9]{40,64}$/)
95
103
  }).parse(await c.req.json());
96
- if (!deps.scenes.followUps) return c.json({ error: "task_follow_up_unavailable" }, 503);
97
- return c.json(await deps.scenes.followUps.branches.associate(principal(c), input));
98
- });
99
- app.post("/task-follow-ups/preflight", deps.strictRateLimitMiddleware, async (c) => {
100
- if (!deps.scenes.followUps) return c.json({ error: "task_follow_up_unavailable" }, 503);
101
- return c.json(await deps.scenes.followUps.preflight(principal(c), await c.req.json()));
102
- });
103
- app.post("/task-follow-ups", deps.strictRateLimitMiddleware, async (c) => {
104
- if (!deps.scenes.followUps) return c.json({ error: "task_follow_up_unavailable" }, 503);
105
- return c.json(await deps.scenes.followUps.create(principal(c), await c.req.json()), 201);
106
- });
107
- app.get("/task-follow-ups/:id", (c) => {
108
- if (!deps.scenes.followUps) return c.json({ error: "task_follow_up_unavailable" }, 503);
109
- return c.json(deps.scenes.followUps.get(principal(c), c.req.param("id")));
110
- });
111
- app.patch("/task-follow-ups/:id", deps.strictRateLimitMiddleware, async (c) => {
112
- const input = z.union([z.strictObject({
113
- expectedRevision: z.number().int().positive(),
114
- status: z.enum([
115
- "active",
116
- "paused",
117
- "archived"
118
- ])
119
- }), z.strictObject({
120
- expectedRevision: z.number().int().positive(),
121
- configuration: z.unknown()
122
- })]).parse(await c.req.json());
123
- if (!deps.scenes.followUps) return c.json({ error: "task_follow_up_unavailable" }, 503);
124
- if ("configuration" in input) return c.json(await deps.scenes.followUps.configure(principal(c), c.req.param("id"), input.expectedRevision, input.configuration));
125
- return c.json(await deps.scenes.followUps.transition(principal(c), c.req.param("id"), input.expectedRevision, input.status));
104
+ const owner = deps.scenes.activationAdapters.list().find((item) => item.associateBranch);
105
+ if (!owner?.associateBranch) return c.json({ error: "branch_inventory_unavailable" }, 503);
106
+ return c.json(await owner.associateBranch(principal(c), input));
126
107
  });
127
108
  app.post("/browser/prepare", deps.strictRateLimitMiddleware, (c) => c.json(deps.scenes.browser.prepare()));
128
109
  app.post("/browser/subscriptions", deps.strictRateLimitMiddleware, async (c) => c.json(deps.scenes.browser.register(principal(c), await c.req.json()), 201));
@@ -160,7 +141,14 @@ function registerSceneRoutes(authenticated, deps) {
160
141
  key: c.req.param("key"),
161
142
  version: c.req.param("version")
162
143
  })));
163
- app.post("/preflight", deps.strictRateLimitMiddleware, async (c) => c.json(await read(c, "xopc.scenes.preflight", await c.req.json())));
144
+ app.post("/preflight", deps.strictRateLimitMiddleware, async (c) => {
145
+ const body = await c.req.json();
146
+ if (typeof body.templateKey === "string" && typeof body.templateVersion === "string") {
147
+ const target = adapterTarget(body.templateKey, body.templateVersion);
148
+ if (target) return c.json(await target.adapter.preflight(principal(c), target.manifest, body.configuration));
149
+ }
150
+ return c.json(await read(c, "xopc.scenes.preflight", body));
151
+ });
164
152
  app.get("/activations", async (c) => {
165
153
  return c.json(await read(c, "xopc.scenes.list", {
166
154
  ...c.req.query(),
@@ -169,14 +157,42 @@ function registerSceneRoutes(authenticated, deps) {
169
157
  });
170
158
  app.post("/activations", deps.strictRateLimitMiddleware, async (c) => {
171
159
  requestIdentity.parse(c.req.header("Idempotency-Key"));
172
- return c.json(await write(c, "xopc.scenes.start", await c.req.json()), 201);
160
+ const body = await c.req.json();
161
+ if (typeof body.templateKey === "string" && typeof body.templateVersion === "string") {
162
+ const target = adapterTarget(body.templateKey, body.templateVersion);
163
+ if (target) return c.json(await target.adapter.create(principal(c), target.manifest, body.configuration), 201);
164
+ }
165
+ return c.json(await write(c, "xopc.scenes.start", body), 201);
173
166
  });
174
167
  app.get("/activations/:id", async (c) => {
175
168
  const { activation } = ProductReadContracts["xopc.scenes.get"].output.parse(await read(c, "xopc.scenes.get", { id: c.req.param("id") }));
176
- return c.json({ activation });
169
+ const manifest = template(activation.templateKey, activation.templateVersion);
170
+ const activationAdapter = manifest.execution.kind === "agent" ? void 0 : deps.scenes.activationAdapters.get(manifest.execution.kind);
171
+ return c.json({
172
+ activation,
173
+ template: manifest,
174
+ ...activationAdapter ? { details: activationAdapter.get(principal(c), activation.id) } : {}
175
+ });
177
176
  });
178
177
  app.patch("/activations/:id", deps.strictRateLimitMiddleware, async (c) => {
179
178
  const body = await c.req.json();
179
+ const activation = deps.scenes.repository.getActivation(principal(c), c.req.param("id"));
180
+ const manifest = template(activation.templateKey, activation.templateVersion);
181
+ if (manifest.execution.kind !== "agent") {
182
+ const input = z.union([z.strictObject({
183
+ expectedRevision: z.number().int().positive(),
184
+ status: z.enum([
185
+ "active",
186
+ "paused",
187
+ "archived"
188
+ ])
189
+ }), z.strictObject({
190
+ expectedRevision: z.number().int().positive(),
191
+ configuration: z.unknown()
192
+ })]).parse(body);
193
+ const execution = deps.scenes.activationAdapters.get(manifest.execution.kind);
194
+ return c.json("configuration" in input ? await execution.configure(principal(c), activation.id, input.expectedRevision, input.configuration) : await execution.transition(principal(c), activation.id, input.expectedRevision, input.status));
195
+ }
180
196
  if (!(typeof body === "object" && body !== null && Object.hasOwn(body, "status"))) return c.json(await write(c, "xopc.scenes.configure", {
181
197
  ...body,
182
198
  id: c.req.param("id")
@@ -109,6 +109,15 @@ function registerSessionsRoutes(authenticated, deps) {
109
109
  payload: { runs: service.sessions.listActiveRuns() }
110
110
  });
111
111
  });
112
+ authenticated.get("/api/runtime/quit-impact", async (c) => {
113
+ const blocked = ensureGatewayReadyForSessions(c, service, "sessions.list");
114
+ if (blocked) return blocked;
115
+ c.header("Cache-Control", "no-store");
116
+ return c.json({
117
+ ok: true,
118
+ payload: await service.sessions.getQuitImpact()
119
+ });
120
+ });
112
121
  authenticated.get("/api/sidebar/chat-list", async (c) => {
113
122
  const blocked = ensureGatewayReadyForSessions(c, service, "sessions.list");
114
123
  if (blocked) return blocked;
@@ -564,6 +573,12 @@ function registerSessionsRoutes(authenticated, deps) {
564
573
  includeContextRows: true
565
574
  });
566
575
  if (!result) return c.json({ error: "Session not found" }, 404);
576
+ const revision = result.pagination.revision;
577
+ if (typeof revision === "number") {
578
+ const etag = `"${result.session.transcriptId ?? key}:${revision}"`;
579
+ c.header("ETag", etag);
580
+ if (c.req.header("If-None-Match") === etag) return c.body(null, 304);
581
+ }
567
582
  return c.json(result);
568
583
  });
569
584
  authenticated.get("/api/sessions/:key/timeline", async (c) => {
@@ -0,0 +1,3 @@
1
+ import { Hono } from 'hono';
2
+ import type { AuthenticatedRouteDeps } from './deps.js';
3
+ export declare function registerUsageRoutes(authenticated: Hono, _deps: AuthenticatedRouteDeps): void;
@@ -0,0 +1,61 @@
1
+ import { getAiUsageEventView, listAiUsageEvents, listAiUsageTrace, summarizeAiUsage } from "../../../storage/sqlite/ai-usage-repository.js";
2
+ import { z } from "zod";
3
+ import { Hono } from "hono";
4
+ //#region src/gateway/hono/routes/usage.ts
5
+ const MAX_RANGE_MS = 366 * 24 * 60 * 60 * 1e3;
6
+ const DEFAULT_RANGE_MS = 10080 * 60 * 1e3;
7
+ const filtersSchema = z.object({
8
+ from: z.coerce.number().int().nonnegative().optional(),
9
+ to: z.coerce.number().int().positive().optional(),
10
+ category: z.string().trim().min(1).max(80).optional(),
11
+ provider: z.string().trim().min(1).max(120).optional(),
12
+ model: z.string().trim().min(1).max(240).optional(),
13
+ agentId: z.string().trim().min(1).max(200).optional(),
14
+ conversationId: z.string().trim().min(1).max(200).optional()
15
+ });
16
+ function parseFilters(value) {
17
+ const parsed = filtersSchema.parse(value);
18
+ const to = parsed.to ?? Date.now() + 1;
19
+ const from = parsed.from ?? to - DEFAULT_RANGE_MS;
20
+ if (from >= to || to - from > MAX_RANGE_MS) throw new Error("invalid_usage_range");
21
+ return {
22
+ ...parsed,
23
+ from,
24
+ to
25
+ };
26
+ }
27
+ function parseCursor(value) {
28
+ if (!value) return void 0;
29
+ const separator = value.indexOf(":");
30
+ const startedAt = Number(value.slice(0, separator));
31
+ const id = value.slice(separator + 1);
32
+ if (separator < 1 || !Number.isSafeInteger(startedAt) || startedAt < 0 || !id) throw new Error("invalid_usage_cursor");
33
+ return {
34
+ startedAt,
35
+ id
36
+ };
37
+ }
38
+ function registerUsageRoutes(authenticated, _deps) {
39
+ const app = new Hono();
40
+ app.onError((error, c) => {
41
+ if (error instanceof z.ZodError || error.message.startsWith("invalid_usage_")) return c.json({ error: "invalid_usage_query" }, 400);
42
+ throw error;
43
+ });
44
+ app.get("/summary", (c) => c.json(summarizeAiUsage(parseFilters(c.req.query()))));
45
+ app.get("/events", (c) => {
46
+ const limit = z.coerce.number().int().min(1).max(200).optional().parse(c.req.query("limit"));
47
+ return c.json(listAiUsageEvents({
48
+ ...parseFilters(c.req.query()),
49
+ limit,
50
+ before: parseCursor(c.req.query("cursor"))
51
+ }));
52
+ });
53
+ app.get("/events/:id", (c) => {
54
+ const event = getAiUsageEventView(c.req.param("id"));
55
+ return event ? c.json({ event }) : c.json({ error: "usage_event_not_found" }, 404);
56
+ });
57
+ app.get("/traces/:traceId", (c) => c.json({ events: listAiUsageTrace(c.req.param("traceId")) }));
58
+ authenticated.route("/api/usage", app);
59
+ }
60
+ //#endregion
61
+ export { registerUsageRoutes };
@@ -101,7 +101,7 @@ async function refineTranscript(raw, config, signal) {
101
101
  maxTokens: Math.min(raw.length * 3, 4096),
102
102
  temperature: .2,
103
103
  signal: mergedSignal
104
- });
104
+ }, void 0, { operation: "voice.select" });
105
105
  let out = "";
106
106
  if (Array.isArray(result.content)) {
107
107
  for (const c of result.content) if (c && typeof c === "object" && c.type === "text") out += String(c.text || "");
@@ -42,7 +42,10 @@ async function reconcileMemoryMaintenanceAutomations(input) {
42
42
  action,
43
43
  safety: { mode: "auto_apply" },
44
44
  conversationMode: "continuous",
45
- notificationPolicy: "none",
45
+ delivery: {
46
+ notificationPolicy: "none",
47
+ destinations: []
48
+ },
46
49
  reliability: { disableAfterConsecutiveFailures: 3 },
47
50
  management: {
48
51
  owner: "memory-maintenance",
@@ -65,7 +68,7 @@ async function reconcileMemoryMaintenanceAutomations(input) {
65
68
  enabled: current.enabled,
66
69
  trigger: current.trigger
67
70
  } : next;
68
- if (current.name !== reconciled.name || current.description !== next.description || current.enabled !== reconciled.enabled || JSON.stringify(current.trigger) !== JSON.stringify(reconciled.trigger) || JSON.stringify(current.action) !== JSON.stringify(action) || current.safety?.mode !== "auto_apply" || current.notificationPolicy !== "none" || JSON.stringify(current.management) !== JSON.stringify(next.management)) {
71
+ if (current.name !== reconciled.name || current.description !== next.description || current.enabled !== reconciled.enabled || JSON.stringify(current.trigger) !== JSON.stringify(reconciled.trigger) || JSON.stringify(current.action) !== JSON.stringify(action) || current.safety?.mode !== "auto_apply" || current.delivery.notificationPolicy !== "none" || JSON.stringify(current.management) !== JSON.stringify(next.management)) {
69
72
  await input.automationService.update(schedule.automationId, reconciled);
70
73
  result.updated += 1;
71
74
  }
@@ -13,6 +13,7 @@ import { SceneMailObservationService } from "../../scenes/mailObservations.js";
13
13
  import { maintainSceneStorage } from "../../scenes/maintenance.js";
14
14
  import { SceneMetrics } from "../../scenes/metrics.js";
15
15
  import { resolveSceneModelRef } from "../../scenes/model.js";
16
+ import { SceneCapabilityRegistry } from "../../scenes/registry.js";
16
17
  import { SceneResultNotifications } from "../../scenes/resultNotifications.js";
17
18
  import { SceneRuntime } from "../../scenes/runtime.js";
18
19
  import { familyPlanTemplate, mailFollowUpTemplate } from "../../scenes/templates.js";
@@ -20,8 +21,8 @@ import { SceneUserNotesProvider } from "../../scenes/userNotes.js";
20
21
  import { createSceneBrowserDispatcher } from "./browserNotifications.js";
21
22
  import { GatewaySceneMailContext } from "./mailContext.js";
22
23
  import { SlackThreadSource } from "./slackThreadSource.js";
23
- import { TaskSourceRegistry } from "../../scenes/taskFollowUp/contracts.js";
24
- import { TaskFollowUpService } from "../../scenes/taskFollowUp/service.js";
24
+ import { SceneSourceRegistry, decisionLogTemplate, taskFollowUpTemplate } from "../../scenes/taskFollowUp/contracts.js";
25
+ import { SceneTaskExecutionService } from "../../scenes/taskFollowUp/service.js";
25
26
  //#region src/gateway/scenes/host.ts
26
27
  init_providers();
27
28
  init_scenes_schema();
@@ -47,30 +48,39 @@ var GatewaySceneHost = class {
47
48
  const repository = new SceneRepository(db);
48
49
  repository.installTemplate(mailFollowUpTemplate);
49
50
  repository.installTemplate(familyPlanTemplate);
51
+ repository.installTemplate(taskFollowUpTemplate);
52
+ repository.installTemplate(decisionLogTemplate);
50
53
  const mail = input.mail ?? new GatewaySceneMailContext(db, clock);
51
- const providers = [mail, new SceneUserNotesProvider(db, clock)];
54
+ const providers = new SceneCapabilityRegistry([mail, new SceneUserNotesProvider(db, clock)]);
52
55
  const authorize = (activation) => {
53
56
  if (activation.ownerId !== input.principal.ownerId || activation.workspaceId !== input.principal.workspaceId) return {
54
57
  accountIds: [],
55
58
  contextProviders: [],
56
59
  effectHandlers: []
57
60
  };
58
- const accountIds = mail.authorizedAccounts(activation);
61
+ const grants = providers.list().flatMap((provider) => {
62
+ const accountIds = provider.authorization?.(activation) ?? null;
63
+ return accountIds === null ? [] : [{
64
+ id: provider.id,
65
+ accountIds
66
+ }];
67
+ });
59
68
  return {
60
- accountIds,
61
- contextProviders: [...activation.scope.kind === "personal" ? ["user_notes"] : [], ...accountIds.length ? ["mail"] : []],
69
+ accountIds: [...new Set(grants.flatMap((grant) => grant.accountIds))],
70
+ contextProviders: grants.map((grant) => grant.id),
62
71
  effectHandlers: []
63
72
  };
64
73
  };
65
74
  const grant = async (activation) => authorize(activation);
66
75
  const executor = input.executor ?? new SceneAgentExecutor(() => resolveModel(resolveSceneModelRef(input.config())));
67
- const slackThread = new SlackThreadSource(db);
68
- const followUps = new TaskFollowUpService(db, {
76
+ const sourceProviders = new SceneSourceRegistry([new SlackThreadSource(db)]);
77
+ const activationAdapters = new SceneCapabilityRegistry([new SceneTaskExecutionService(db, {
69
78
  config: input.config,
70
- sources: new TaskSourceRegistry([slackThread])
71
- });
79
+ sources: sourceProviders
80
+ })]);
72
81
  this.http = {
73
- followUps,
82
+ activationAdapters,
83
+ sourceProviders,
74
84
  repository,
75
85
  mail,
76
86
  mailDiscovery: mail instanceof GatewaySceneMailContext ? mail : void 0,
@@ -99,7 +109,10 @@ var GatewaySceneHost = class {
99
109
  assertSceneStorageReady(this.db);
100
110
  this.runtime.start();
101
111
  const poll = () => {
102
- this.http.followUps?.tick().catch((err) => log.error({ err }, "Task follow-up check failed"));
112
+ for (const adapter of this.http.activationAdapters.list()) adapter.tick().catch((err) => log.error({
113
+ err,
114
+ adapter: adapter.id
115
+ }, "Scene adapter check failed"));
103
116
  try {
104
117
  if (this.clock() >= this.nextMaintenanceAt) {
105
118
  maintainSceneStorage(this.db, this.clock());
@@ -118,7 +131,7 @@ var GatewaySceneHost = class {
118
131
  tick() {
119
132
  if (this.stopped) return Promise.reject(/* @__PURE__ */ new Error("Scene host stopped"));
120
133
  if (this.active) return this.active;
121
- const work = Promise.all([this.runtime.tick(), this.http.followUps?.tick()]).then(() => {
134
+ const work = Promise.all([this.runtime.tick(), ...this.http.activationAdapters.list().map((adapter) => adapter.tick())]).then(() => {
122
135
  if (!this.stopped) this.notifications.drain();
123
136
  });
124
137
  this.active = work.finally(() => {
@@ -131,7 +144,7 @@ var GatewaySceneHost = class {
131
144
  this.stopped = true;
132
145
  if (this.timer) clearInterval(this.timer);
133
146
  this.timer = void 0;
134
- await this.http.followUps?.stop();
147
+ await Promise.all(this.http.activationAdapters.list().map((adapter) => adapter.stop()));
135
148
  await this.runtime.stop();
136
149
  await this.browserDispatcher.stop();
137
150
  await this.active?.catch(() => void 0);
@@ -2,7 +2,7 @@ import type { DatabaseSync } from 'node:sqlite';
2
2
  import { z } from 'zod';
3
3
  import { ComposioSessionsAdapter } from '../../connectors/composio-sessions.js';
4
4
  import { type ScenePrincipal } from '../../scenes/contracts.js';
5
- import type { TaskSourceAdapter, SourceSnapshot } from '../../scenes/taskFollowUp/contracts.js';
5
+ import type { SceneSourceAdapter, SourceSnapshot } from '../../scenes/taskFollowUp/contracts.js';
6
6
  export declare const slackThreadSchema: z.ZodObject<{
7
7
  accountId: z.ZodString;
8
8
  teamId: z.ZodString;
@@ -16,7 +16,7 @@ export declare function parseSlackThreadUrl(value: string): {
16
16
  threadTs: string;
17
17
  };
18
18
  /** Read-only connector adapter. Account policy is rechecked before and after every page. */
19
- export declare class SlackThreadSource implements TaskSourceAdapter {
19
+ export declare class SlackThreadSource implements SceneSourceAdapter {
20
20
  private readonly db;
21
21
  private readonly adapter;
22
22
  readonly id = "slack_thread";
@@ -22,6 +22,7 @@ function requiredGatewayScope(method, path) {
22
22
  if (method === "GET" && path === "/api/connectors/approvals") return "sessions.read";
23
23
  if (method === "POST" && path === "/api/connectors/approvals/respond") return "sessions.write";
24
24
  if (path === "/api/agent" || path.startsWith("/api/agent/")) return "agents.run";
25
+ if (path.startsWith("/api/usage")) return "gateway.admin";
25
26
  if (path.startsWith("/api/agents") || path.startsWith("/api/models")) return methodScope(method, "agents.read", "gateway.admin");
26
27
  if (path.startsWith("/api/sessions") || path.startsWith("/api/side-chats")) return methodScope(method, "sessions.read", "sessions.write");
27
28
  if (path.startsWith("/api/tasks")) return methodScope(method, "tasks.read", "tasks.write");
@@ -0,0 +1,19 @@
1
+ import type { TurnOrigin } from '@xopcai/endpoint-tools-protocol';
2
+ export type ActiveExecutionKind = 'chat' | 'side-chat' | 'task' | 'workflow' | 'automation';
3
+ export type ActiveExecutionInitiator = 'user' | 'background';
4
+ export type ActiveExecution = {
5
+ conversationId: string;
6
+ runId: string;
7
+ kind: ActiveExecutionKind;
8
+ initiator: ActiveExecutionInitiator;
9
+ phase: 'running';
10
+ startedAt: number;
11
+ };
12
+ export declare function describeActiveExecution(input: {
13
+ conversationId: string;
14
+ runId: string;
15
+ origin: TurnOrigin;
16
+ taskRunId?: string;
17
+ kind?: ActiveExecutionKind;
18
+ startedAt?: number;
19
+ }): ActiveExecution;