@xopcai/xopc 0.0.178 → 0.0.180

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 (450) 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/{activity-store-BzGX__8I.js → activity-store-DFKtQDgE.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BzxntcaZ.js → agent-avatar-dicebear-CcTvB_4W.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-DgGj9bu6.js +2 -0
  6. package/dist/gateway/static/root/assets/{api-hi6f2Xtp.js → api-CUClAvuL.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-fTY1F7ac.js → app-management-settings-panel-Ib-cWKHM.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-BZ-IxQfB.js → appearance-settings-CRSN8WuA.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-B5xahuT-.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-ZSLLG8wB.js → archive-plugin-BBF9zspN.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-D4YktqIF.js → attachment-load-D3QQfA7w.js} +1 -1
  12. package/dist/gateway/static/root/assets/automations-page-BUYrvMmD.js +6 -0
  13. package/dist/gateway/static/root/assets/{binary-plugins-BIkPxfxj.js → binary-plugins-D78XOjJ3.js} +1 -1
  14. package/dist/gateway/static/root/assets/{block-editor-Q3v_YQom.js → block-editor-D_VVXlYX.js} +46 -46
  15. package/dist/gateway/static/root/assets/browser-settings-page-Cjw07q9h.js +8 -0
  16. package/dist/gateway/static/root/assets/{browser-workflow-inputs-M5lTEW1I.js → browser-workflow-inputs-_gu08MA4.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-workflows-page-B3T1KYk4.js → browser-workflows-page-58DBMXgG.js} +2 -2
  18. package/dist/gateway/static/root/assets/capabilities-settings-panel-D_dfVxHY.js +7 -0
  19. package/dist/gateway/static/root/assets/{capability-presets-api-DE09c0VB.js → capability-presets-api-DhCn9rPv.js} +1 -1
  20. package/dist/gateway/static/root/assets/capability-presets-settings-panel-LWWIYUT7.js +1 -0
  21. package/dist/gateway/static/root/assets/{channel-recipient-api-CFR5FBfS.js → channel-recipient-api-DYtoNV5A.js} +1 -1
  22. package/dist/gateway/static/root/assets/channels-settings-Cyj5OunL.js +1 -0
  23. package/dist/gateway/static/root/assets/channels-status-swr-TEFnV0IG.js +1 -0
  24. package/dist/gateway/static/root/assets/{connector-logo-B1mD-3pM.js → connector-logo-CxIXnifA.js} +1 -1
  25. package/dist/gateway/static/root/assets/connectors-page-0TobCpBB.js +2 -0
  26. package/dist/gateway/static/root/assets/desktop-pet-CwVSLL6N.js +1 -0
  27. package/dist/gateway/static/root/assets/desktop-pet-settings-BOIp4q0Z.js +1 -0
  28. package/dist/gateway/static/root/assets/{directory-picker-path-field-BYQJ2XUS.js → directory-picker-path-field-C8_lsW6S.js} +1 -1
  29. package/dist/gateway/static/root/assets/{dreaming-settings-BXcb8fwx.js → dreaming-settings-Da9FeWQl.js} +3 -3
  30. package/dist/gateway/static/root/assets/{extension-debug-page-O1Xu1r4Q.js → extension-debug-page-CMNnSJP6.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-page-C2Jraq8l.js → extension-page-t0pJqLvM.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-settings-page-DcXQDTpG.js → extension-settings-page-aiR-tKnW.js} +1 -1
  33. package/dist/gateway/static/root/assets/{gateway-config-api-DmPIZrvg.js → gateway-config-api-CkyQBD6r.js} +1 -1
  34. package/dist/gateway/static/root/assets/gateway-settings-BIZfAgfB.js +1 -0
  35. package/dist/gateway/static/root/assets/{gateway-startup-retry-BZEkOdPm.js → gateway-startup-retry-CSU7UvzG.js} +1 -1
  36. package/dist/gateway/static/root/assets/goals-settings-Dx9uTyWF.js +1 -0
  37. package/dist/gateway/static/root/assets/{heartbeat-settings-BtKu2NWT.js → heartbeat-settings-Cnr5ORXL.js} +1 -1
  38. package/dist/gateway/static/root/assets/{image-generation-api-05Gg8wsU.js → image-generation-api-BR6Kb77X.js} +1 -1
  39. package/dist/gateway/static/root/assets/index-B0Tdge_q.css +1 -0
  40. package/dist/gateway/static/root/assets/index-BA56bQ68.js +224 -0
  41. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CfmDR9Sc.js → keyboard-shortcuts-settings-D76uYKeQ.js} +1 -1
  42. package/dist/gateway/static/root/assets/local-app-workbench-page-DSUNtLHg.js +2 -0
  43. package/dist/gateway/static/root/assets/{local-apps-page-Df8BW1A_.js → local-apps-page-BsLnojTh.js} +1 -1
  44. package/dist/gateway/static/root/assets/{locale-store-CTwSy7yW.js → locale-store-BNC8HUCI.js} +1 -1
  45. package/dist/gateway/static/root/assets/logs-page-yI8kpQtO.js +7 -0
  46. package/dist/gateway/static/root/assets/{markdown-split-B3FvKbaP.js → markdown-split-D6smTQWD.js} +1 -1
  47. package/dist/gateway/static/root/assets/{media-plugins-DsjrvvB6.js → media-plugins-D1TmMF0A.js} +1 -1
  48. package/dist/gateway/static/root/assets/messages-H_iJjnEM.js +3 -0
  49. package/dist/gateway/static/root/assets/{notes-page-tuzIwy3c.js → notes-page-Vt-diFf0.js} +1 -1
  50. package/dist/gateway/static/root/assets/notes-workbench-BD297EZt.js +4 -0
  51. package/dist/gateway/static/root/assets/outcome-detail-page-C5i_ZR9a.js +1 -0
  52. package/dist/gateway/static/root/assets/{page-tabs-ke9s4nYi.js → page-tabs-BnSzIjH0.js} +1 -1
  53. package/dist/gateway/static/root/assets/{preview-open-alternatives-Cp1eI4S9.js → preview-open-alternatives-CF12Eqi4.js} +1 -1
  54. package/dist/gateway/static/root/assets/product-delivery-BVG-eWQO.js +1 -0
  55. package/dist/gateway/static/root/assets/{product-open-page-dXQCMAtH.js → product-open-page-Du0TE_CU.js} +1 -1
  56. package/dist/gateway/static/root/assets/project-detail-page-D1HGz7Dy.js +1 -0
  57. package/dist/gateway/static/root/assets/projects-page-CqP2TnW-.js +1 -0
  58. package/dist/gateway/static/root/assets/remote-access-hub-BXdVJLS3.js +1 -0
  59. package/dist/gateway/static/root/assets/{save-bar-controls-Bl30zjHc.js → save-bar-controls-B53UNtDM.js} +1 -1
  60. package/dist/gateway/static/root/assets/{schedule-field-DqhmXQKo.js → schedule-field-C3dIMN5q.js} +1 -1
  61. package/dist/gateway/static/root/assets/{schema-form-DkUCy6vf.js → schema-form-BKvpxqof.js} +1 -1
  62. package/dist/gateway/static/root/assets/{schemas-DgQq6Z5S.js → schemas-C6onAggk.js} +2 -2
  63. package/dist/gateway/static/root/assets/sessions-page-CPAwDdl5.js +1 -0
  64. package/dist/gateway/static/root/assets/settings-advanced-gate-C-jGsoft.js +1 -0
  65. package/dist/gateway/static/root/assets/{settings-form-section-C6ZbNpdy.js → settings-form-section-kt6GIS32.js} +1 -1
  66. package/dist/gateway/static/root/assets/{settings-loading-skeleton-Bk58_cr7.js → settings-loading-skeleton-85eUPcKz.js} +1 -1
  67. package/dist/gateway/static/root/assets/{settings-page-k8iE_NdX.js → settings-page-Di5x6Xrc.js} +1 -1
  68. package/dist/gateway/static/root/assets/{settings-page-layout-DgFSya2e.js → settings-page-layout-CkkCee_x.js} +1 -1
  69. package/dist/gateway/static/root/assets/{setup-status-panel-B_KDlyZA.js → setup-status-panel-uxEE6gAB.js} +1 -1
  70. package/dist/gateway/static/root/assets/{share-preview-page-CV7nL_J9.js → share-preview-page-BtLEstaI.js} +1 -1
  71. package/dist/gateway/static/root/assets/shares-settings-2mcsMWgn.js +1 -0
  72. package/dist/gateway/static/root/assets/skill-reload-api-ocDwsrEt.js +1 -0
  73. package/dist/gateway/static/root/assets/skills-page-9_jfsFU5.js +2 -0
  74. package/dist/gateway/static/root/assets/{skills-page.utils-kahBIHg0.js → skills-page.utils-C2SHvq8V.js} +1 -1
  75. package/dist/gateway/static/root/assets/{system-settings-panel-JV3-MG5F.js → system-settings-panel-CIJ66cUy.js} +1 -1
  76. package/dist/gateway/static/root/assets/{theme-store-DFLyzoLO.js → theme-store-ClDa_Bci.js} +1 -1
  77. package/dist/gateway/static/root/assets/time-picker-D0zAsHOo.js +1 -0
  78. package/dist/gateway/static/root/assets/{typed-models-lib-60Aqo-UJ.js → typed-models-lib-GsmwmB40.js} +1 -1
  79. package/dist/gateway/static/root/assets/{use-channel-catalog-CnTkHDnw.js → use-channel-catalog-BQz3K7xj.js} +1 -1
  80. package/dist/gateway/static/root/assets/user-context-page-Bn4BLg4W.js +1 -0
  81. package/dist/gateway/static/root/assets/{voice-api-key-field-CNa8qUgS.js → voice-api-key-field-Blaxsbb3.js} +1 -1
  82. package/dist/gateway/static/root/assets/work-copy-Cwyan9Sn.js +1 -0
  83. package/dist/gateway/static/root/assets/work-discovery-page-iJ9RBSpu.js +1 -0
  84. package/dist/gateway/static/root/assets/work-item-detail-page-CqTH7PQX.js +1 -0
  85. package/dist/gateway/static/root/assets/work-page-H3m99ccS.js +3 -0
  86. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-yV_x595t.js → workflow-run-setup-panel-CTG4RpRE.js} +2 -2
  87. package/dist/gateway/static/root/assets/workflows-page-BxZSKMfv.js +11 -0
  88. package/dist/gateway/static/root/index.html +9 -10
  89. package/dist/package.js +1 -1
  90. package/dist/packages/gateway-contract/src/outcomes.js +137 -0
  91. package/dist/packages/gateway-contract/src/product-delivery.js +1 -0
  92. package/dist/packages/gateway-contract/src/work-intake.js +85 -0
  93. package/dist/src/activity/service.d.ts +1 -0
  94. package/dist/src/activity/service.js +4 -1
  95. package/dist/src/agent/agent-manager.d.ts +4 -1
  96. package/dist/src/agent/agent-manager.js +21 -7
  97. package/dist/src/agent/bootstrap/filter-bootstrap-files.js +1 -1
  98. package/dist/src/agent/code-intelligence/binary.js +1 -1
  99. package/dist/src/agent/context/execution-scope.d.ts +1 -1
  100. package/dist/src/agent/context/execution-scope.js +6 -4
  101. package/dist/src/agent/embedded/model-runtime.js +1 -1
  102. package/dist/src/agent/embedded/run-for-session.d.ts +2 -0
  103. package/dist/src/agent/embedded/run-for-session.js +3 -1
  104. package/dist/src/agent/goals/post-turn.js +7 -6
  105. package/dist/src/agent/image/tool-model-config.js +1 -1
  106. package/dist/src/agent/inbound/turn-dispatcher.d.ts +6 -1
  107. package/dist/src/agent/inbound/turn-dispatcher.js +5 -2
  108. package/dist/src/agent/ipc/inbox.js +1 -1
  109. package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +2 -0
  110. package/dist/src/agent/lifecycle/timeout-wrapper.js +39 -9
  111. package/dist/src/agent/mcp/bundle-mcp-materialize.js +2 -2
  112. package/dist/src/agent/mcp/bundle-mcp-runtime.js +6 -1
  113. package/dist/src/agent/mcp/bundle-mcp-types.d.ts +1 -1
  114. package/dist/src/agent/mcp/mcp-stdio-transport.js +1 -1
  115. package/dist/src/agent/mcp/mcp-transport-config.d.ts +2 -0
  116. package/dist/src/agent/mcp/mcp-transport-config.js +10 -3
  117. package/dist/src/agent/mcp/mcp-transport.d.ts +1 -0
  118. package/dist/src/agent/mcp/mcp-transport.js +5 -2
  119. package/dist/src/agent/memory/dreaming/config.js +1 -1
  120. package/dist/src/agent/memory/user-context-coordinator.d.ts +1 -0
  121. package/dist/src/agent/memory/user-context-coordinator.js +17 -1
  122. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +1 -1
  123. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +6 -2
  124. package/dist/src/agent/outcomes/{task-evaluation.d.ts → execution-evaluation.d.ts} +3 -3
  125. package/dist/src/agent/outcomes/{task-evaluation.js → execution-evaluation.js} +5 -5
  126. package/dist/src/agent/outcomes/execution-verifier.d.ts +29 -0
  127. package/dist/src/agent/outcomes/{task-verifier.js → execution-verifier.js} +4 -4
  128. package/dist/src/agent/service/direct-turn-helpers.d.ts +1 -0
  129. package/dist/src/agent/service/direct-turn-helpers.js +1 -0
  130. package/dist/src/agent/service/process-direct-one-shot.d.ts +3 -0
  131. package/dist/src/agent/service/process-direct-one-shot.js +4 -1
  132. package/dist/src/agent/service/process-direct-streaming.js +3 -1
  133. package/dist/src/agent/service.d.ts +1 -0
  134. package/dist/src/agent/service.js +5 -2
  135. package/dist/src/agent/session/session-inspector.js +1 -1
  136. package/dist/src/agent/skills/config.js +6 -0
  137. package/dist/src/agent/skills/filesystem-watcher.d.ts +4 -0
  138. package/dist/src/agent/skills/filesystem-watcher.js +16 -7
  139. package/dist/src/agent/skills/hub-lock.js +1 -1
  140. package/dist/src/agent/skills/index.d.ts +10 -7
  141. package/dist/src/agent/skills/index.js +56 -47
  142. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  143. package/dist/src/agent/skills/skill-manager.d.ts +5 -2
  144. package/dist/src/agent/skills/skill-manager.js +10 -5
  145. package/dist/src/agent/skills/skill-sources.d.ts +18 -0
  146. package/dist/src/agent/skills/skill-sources.js +143 -0
  147. package/dist/src/agent/skills/types.d.ts +25 -2
  148. package/dist/src/agent/tools/delegate-tool.js +2 -1
  149. package/dist/src/agent/tools/executor.d.ts +2 -0
  150. package/dist/src/agent/tools/executor.js +18 -11
  151. package/dist/src/agent/tools/factory.js +18 -1
  152. package/dist/src/agent/tools/goal-tool.js +5 -3
  153. package/dist/src/agent/tools/index.d.ts +1 -0
  154. package/dist/src/agent/tools/index.js +2 -1
  155. package/dist/src/agent/tools/managed-job-tool.d.ts +2 -0
  156. package/dist/src/agent/tools/managed-job-tool.js +160 -0
  157. package/dist/src/agent/tools/todo-tool.d.ts +5 -0
  158. package/dist/src/agent/tools/todo-tool.js +16 -4
  159. package/dist/src/agent/tools/update-plan-tool.d.ts +1 -0
  160. package/dist/src/agent/tools/update-plan-tool.js +6 -0
  161. package/dist/src/agent/workspace-runtime/registry.d.ts +3 -0
  162. package/dist/src/agent/workspace-runtime/registry.js +3 -1
  163. package/dist/src/agent-runtime/index.js +1 -1
  164. package/dist/src/agent-runtime/runtime-profile.js +1 -1
  165. package/dist/src/auth/credentials.d.ts +9 -1
  166. package/dist/src/auth/credentials.js +112 -56
  167. package/dist/src/auth/model-credential-store.js +7 -22
  168. package/dist/src/auth/oauth-provider-lock.d.ts +5 -0
  169. package/dist/src/auth/oauth-provider-lock.js +91 -0
  170. package/dist/src/auth/profiles/store.js +1 -1
  171. package/dist/src/auth/sync-provider-auth.js +2 -2
  172. package/dist/src/automations/domain/defaults.d.ts +8 -1
  173. package/dist/src/automations/domain/defaults.js +9 -2
  174. package/dist/src/automations/domain/index.js +2 -2
  175. package/dist/src/automations/domain/types.d.ts +33 -7
  176. package/dist/src/automations/domain/validation.d.ts +8 -0
  177. package/dist/src/automations/domain/validation.js +2 -0
  178. package/dist/src/automations/draft/automation-draft-validator.d.ts +2 -1
  179. package/dist/src/automations/index.js +2 -2
  180. package/dist/src/automations/service/action-executor.d.ts +2 -2
  181. package/dist/src/automations/service/action-executor.js +144 -34
  182. package/dist/src/automations/service/automation-service.d.ts +4 -0
  183. package/dist/src/automations/service/automation-service.js +197 -18
  184. package/dist/src/automations/storage/automation-run-repository.d.ts +1 -0
  185. package/dist/src/automations/storage/automation-run-repository.js +37 -7
  186. package/dist/src/automations/storage/index.js +2 -2
  187. package/dist/src/browser/providers/browser-ext-install.js +1 -1
  188. package/dist/src/browser/providers/cloakbrowser.js +2 -2
  189. package/dist/src/channels/attachments/voice-stt-webchat.d.ts +0 -3
  190. package/dist/src/channels/attachments/voice-stt-webchat.js +1 -24
  191. package/dist/src/chat-commands/builtins/goal.js +5 -4
  192. package/dist/src/cli/commands/agents.js +1 -1
  193. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  194. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  195. package/dist/src/cli/commands/goal.js +6 -5
  196. package/dist/src/cli/commands/models.js +1 -1
  197. package/dist/src/cli/commands/tunnel.js +3 -3
  198. package/dist/src/cli/utils/oauth-login.js +1 -7
  199. package/dist/src/config/agent-profile.js +1 -1
  200. package/dist/src/config/index.js +4 -4
  201. package/dist/src/config/loader.js +1 -1
  202. package/dist/src/config/models-json.js +1 -1
  203. package/dist/src/config/schema.d.ts +3 -0
  204. package/dist/src/config/schema.js +2 -1
  205. package/dist/src/connectors/learning-coordinator.js +7 -1
  206. package/dist/src/connectors/source-change-publisher.d.ts +17 -0
  207. package/dist/src/connectors/source-change-publisher.js +148 -0
  208. package/dist/src/discussions/analyzer.d.ts +35 -0
  209. package/dist/src/discussions/analyzer.js +127 -0
  210. package/dist/src/discussions/index.d.ts +7 -0
  211. package/dist/src/discussions/index.js +7 -0
  212. package/dist/src/discussions/live-worker.d.ts +33 -0
  213. package/dist/src/discussions/live-worker.js +148 -0
  214. package/dist/src/discussions/pipeline.d.ts +33 -0
  215. package/dist/src/discussions/pipeline.js +205 -0
  216. package/dist/src/discussions/project-inference.d.ts +13 -0
  217. package/dist/src/discussions/project-inference.js +19 -0
  218. package/dist/src/discussions/repository.d.ts +29 -0
  219. package/dist/src/discussions/repository.js +255 -0
  220. package/dist/src/discussions/service.d.ts +51 -0
  221. package/dist/src/discussions/service.js +335 -0
  222. package/dist/src/discussions/transcript.d.ts +3 -0
  223. package/dist/src/discussions/transcript.js +15 -0
  224. package/dist/src/discussions/types.d.ts +116 -0
  225. package/dist/src/discussions/types.js +10 -0
  226. package/dist/src/discussions/worker.d.ts +18 -0
  227. package/dist/src/discussions/worker.js +74 -0
  228. package/dist/src/extensions/activation-context.js +2 -1
  229. package/dist/src/extensions/lockfile.js +1 -1
  230. package/dist/src/extensions/sdk/testing.js +1 -1
  231. package/dist/src/gateway/agents-admin.js +3 -3
  232. package/dist/src/gateway/chat-stream/mapper.js +53 -3
  233. package/dist/src/gateway/chat-stream/protocol.d.ts +17 -1
  234. package/dist/src/gateway/file-path-classifier.js +1 -1
  235. package/dist/src/gateway/hono/app.js +8 -3
  236. package/dist/src/gateway/hono/lib/config-payload.js +2 -2
  237. package/dist/src/gateway/hono/middleware/auth.js +2 -2
  238. package/dist/src/gateway/hono/middleware/logger.js +1 -1
  239. package/dist/src/gateway/hono/middleware/strict-rate-limit.js +1 -1
  240. package/dist/src/gateway/hono/oauth-async.js +1 -7
  241. package/dist/src/gateway/hono/oauth.js +1 -7
  242. package/dist/src/gateway/hono/routes/agents.js +1 -1
  243. package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -2
  244. package/dist/src/gateway/hono/routes/connectors.js +79 -0
  245. package/dist/src/gateway/hono/routes/discussions.d.ts +3 -0
  246. package/dist/src/gateway/hono/routes/discussions.js +177 -0
  247. package/dist/src/gateway/hono/routes/execution-receipts.d.ts +3 -0
  248. package/dist/src/gateway/hono/routes/execution-receipts.js +163 -0
  249. package/dist/src/gateway/hono/routes/exposure.js +1 -1
  250. package/dist/src/gateway/hono/routes/goals.js +3 -288
  251. package/dist/src/gateway/hono/routes/home.d.ts +2 -102
  252. package/dist/src/gateway/hono/routes/home.js +8 -424
  253. package/dist/src/gateway/hono/routes/index.js +6 -2
  254. package/dist/src/gateway/hono/routes/memory.js +7 -7
  255. package/dist/src/gateway/hono/routes/models.js +1 -1
  256. package/dist/src/gateway/hono/routes/notes.js +30 -0
  257. package/dist/src/gateway/hono/routes/projects.js +8 -152
  258. package/dist/src/gateway/hono/routes/shares.js +1 -1
  259. package/dist/src/gateway/hono/routes/status.js +2 -2
  260. package/dist/src/gateway/hono/routes/tunnel.js +3 -3
  261. package/dist/src/gateway/hono/routes/voice.js +1 -1
  262. package/dist/src/gateway/hono/routes/work.d.ts +3 -0
  263. package/dist/src/gateway/hono/routes/work.js +207 -0
  264. package/dist/src/gateway/hono/routes/you.js +13 -15
  265. package/dist/src/gateway/index.js +2 -2
  266. package/dist/src/gateway/runtime-config.js +2 -2
  267. package/dist/src/gateway/security/audit.js +2 -2
  268. package/dist/src/gateway/security/index.js +1 -1
  269. package/dist/src/gateway/service/config-coordinator.js +2 -2
  270. package/dist/src/gateway/service/run-gateway-agent.js +46 -51
  271. package/dist/src/gateway/service.d.ts +8 -1
  272. package/dist/src/gateway/service.js +142 -15
  273. package/dist/src/goals/goal-queue-store.d.ts +1 -0
  274. package/dist/src/goals/goal-queue-store.js +5 -1
  275. package/dist/src/goals/goal-queue-types.d.ts +11 -1
  276. package/dist/src/goals/goal-runner.js +10 -6
  277. package/dist/src/goals/goal-service.d.ts +2 -15
  278. package/dist/src/goals/goal-service.js +9 -42
  279. package/dist/src/goals/goal-store.d.ts +1 -18
  280. package/dist/src/goals/goal-store.js +25 -231
  281. package/dist/src/goals/goal-workflow-judge.js +1 -1
  282. package/dist/src/goals/index.d.ts +0 -4
  283. package/dist/src/goals/index.js +1 -3
  284. package/dist/src/goals/types.d.ts +4 -66
  285. package/dist/src/notes/agent-context.js +1 -1
  286. package/dist/src/notes/service.d.ts +1 -0
  287. package/dist/src/notes/service.js +10 -1
  288. package/dist/src/notes/types.d.ts +1 -0
  289. package/dist/src/proactive/events/product-event-bridge.d.ts +7 -0
  290. package/dist/src/proactive/events/product-event-bridge.js +84 -0
  291. package/dist/src/proactive/execution/context.d.ts +27 -11
  292. package/dist/src/proactive/execution/context.js +259 -25
  293. package/dist/src/proactive/execution/repository.js +18 -5
  294. package/dist/src/proactive/execution/types.d.ts +7 -1
  295. package/dist/src/proactive/execution/worker.js +7 -6
  296. package/dist/src/proactive/inbox/repository.js +8 -2
  297. package/dist/src/proactive/index.d.ts +4 -2
  298. package/dist/src/proactive/index.js +5 -3
  299. package/dist/src/proactive/temporal/worker.d.ts +16 -0
  300. package/dist/src/proactive/temporal/worker.js +110 -0
  301. package/dist/src/projects/project-loop.js +3 -3
  302. package/dist/src/providers/auth-runtime/oauth.js +12 -0
  303. package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
  304. package/dist/src/providers/index.js +2 -2
  305. package/dist/src/providers/model-registry.js +1 -1
  306. package/dist/src/providers/register-runtime-providers.js +1 -1
  307. package/dist/src/share/share-zip.js +1 -1
  308. package/dist/src/share/site-proxy.js +1 -1
  309. package/dist/src/storage/sqlite/activity-repository.d.ts +1 -0
  310. package/dist/src/storage/sqlite/activity-repository.js +4 -1
  311. package/dist/src/storage/sqlite/connector-sync-policy-repository.d.ts +20 -0
  312. package/dist/src/storage/sqlite/connector-sync-policy-repository.js +50 -0
  313. package/dist/src/storage/sqlite/execution-receipt-repository.d.ts +146 -0
  314. package/dist/src/storage/sqlite/execution-receipt-repository.js +235 -0
  315. package/dist/src/storage/sqlite/index.d.ts +4 -2
  316. package/dist/src/storage/sqlite/index.js +6 -4
  317. package/dist/src/storage/sqlite/knowledge-repository.d.ts +3 -0
  318. package/dist/src/storage/sqlite/knowledge-repository.js +9 -1
  319. package/dist/src/storage/sqlite/memory-records-repository.js +1 -1
  320. package/dist/src/storage/sqlite/migrations/075_connector_sync_policies.sql +13 -0
  321. package/dist/src/storage/sqlite/migrations/076_meeting_preparation_scenario.sql +29 -0
  322. package/dist/src/storage/sqlite/migrations/077_proactive_insight_fingerprints.sql +4 -0
  323. package/dist/src/storage/sqlite/migrations/078_discussion_captures.sql +64 -0
  324. package/dist/src/storage/sqlite/migrations/079_discussion_follow_up_scenario.sql +29 -0
  325. package/dist/src/storage/sqlite/migrations/080_task_outcome_context.sql +15 -0
  326. package/dist/src/storage/sqlite/migrations/081_project_monitoring_policies.sql +10 -0
  327. package/dist/src/storage/sqlite/migrations/082_one_click_live_discussions.sql +100 -0
  328. package/dist/src/storage/sqlite/migrations/083_session_task_plans.sql +9 -0
  329. package/dist/src/storage/sqlite/migrations/084_work_intake_lifecycle.sql +26 -0
  330. package/dist/src/storage/sqlite/migrations/085_task_outcome_projection.sql +19 -0
  331. package/dist/src/storage/sqlite/migrations/086_outcome_aggregates.sql +168 -0
  332. package/dist/src/storage/sqlite/migrations/087_context_snapshots.sql +21 -0
  333. package/dist/src/storage/sqlite/migrations/088_automation_execution_deadlines.sql +5 -0
  334. package/dist/src/storage/sqlite/migrations/089_automation_run_leases.sql +8 -0
  335. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  336. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  337. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  338. package/dist/src/storage/sqlite/notes-repository.js +9 -0
  339. package/dist/src/storage/sqlite/schema.js +1 -1
  340. package/dist/src/storage/sqlite/schema.sql +89 -44
  341. package/dist/src/storage/sqlite/session-repository.js +1 -1
  342. package/dist/src/storage/sqlite/session-task-plan-repository.d.ts +20 -0
  343. package/dist/src/storage/sqlite/session-task-plan-repository.js +77 -0
  344. package/dist/src/tui/backends/embedded-backend.d.ts +2 -0
  345. package/dist/src/tui/backends/embedded-backend.js +12 -8
  346. package/dist/src/tui/tui-backend.d.ts +2 -0
  347. package/dist/src/tui/tui-oauth-login.js +1 -7
  348. package/dist/src/tui/tui-picker-overlay.js +1 -0
  349. package/dist/src/tui/tui-picker-services.d.ts +1 -0
  350. package/dist/src/tui/tui-skills-autocomplete.d.ts +6 -2
  351. package/dist/src/tui/tui-skills-autocomplete.js +10 -6
  352. package/dist/src/tui/tui-startup-resources.d.ts +3 -1
  353. package/dist/src/tui/tui-startup-resources.js +4 -3
  354. package/dist/src/tui/tui.js +4 -1
  355. package/dist/src/tunnel/frpc-binary.js +1 -1
  356. package/dist/src/tunnel/frpc-extract.js +1 -1
  357. package/dist/src/tunnel/index.js +2 -2
  358. package/dist/src/user-context/context-compiler.d.ts +31 -0
  359. package/dist/src/user-context/context-compiler.js +51 -0
  360. package/dist/src/voice/local/model-files.js +1 -1
  361. package/dist/src/voice/stt/config.d.ts +4 -0
  362. package/dist/src/voice/stt/config.js +26 -0
  363. package/dist/src/voice/stt/index.d.ts +1 -0
  364. package/dist/src/voice/stt/index.js +2 -1
  365. package/dist/src/voice/stt/list-providers.js +1 -1
  366. package/dist/src/work/attention-governor.d.ts +20 -0
  367. package/dist/src/work/attention-governor.js +46 -0
  368. package/dist/src/work/execution-context.d.ts +16 -0
  369. package/dist/src/work/execution-context.js +66 -0
  370. package/dist/src/work/home-query-service.d.ts +147 -0
  371. package/dist/src/work/home-query-service.js +389 -0
  372. package/dist/src/work/index.d.ts +14 -0
  373. package/dist/src/work/index.js +15 -0
  374. package/dist/src/work/outcome-contract-definition.d.ts +8 -0
  375. package/dist/src/work/outcome-contract-definition.js +15 -0
  376. package/dist/src/work/outcome-execution-service.d.ts +27 -0
  377. package/dist/src/work/outcome-execution-service.js +60 -0
  378. package/dist/src/work/outcome-projection-service.d.ts +7 -0
  379. package/dist/src/work/outcome-projection-service.js +51 -0
  380. package/dist/src/work/outcome-receipt-service.d.ts +13 -0
  381. package/dist/src/work/outcome-receipt-service.js +55 -0
  382. package/dist/src/work/outcome-repository.d.ts +50 -0
  383. package/dist/src/work/outcome-repository.js +112 -0
  384. package/dist/src/work/outcome-run-coordinator.d.ts +25 -0
  385. package/dist/src/work/outcome-run-coordinator.js +117 -0
  386. package/dist/src/work/project-monitoring-service.d.ts +21 -0
  387. package/dist/src/work/project-monitoring-service.js +76 -0
  388. package/dist/src/work/project-operating-view-service.d.ts +10 -0
  389. package/dist/src/work/project-operating-view-service.js +46 -0
  390. package/dist/src/work/work-intake-repository.d.ts +49 -0
  391. package/dist/src/work/work-intake-repository.js +97 -0
  392. package/dist/src/work/work-intake-service.d.ts +26 -0
  393. package/dist/src/work/work-intake-service.js +171 -0
  394. package/dist/src/work/work-value-metrics-service.d.ts +4 -0
  395. package/dist/src/work/work-value-metrics-service.js +88 -0
  396. package/dist/src/work-items/work-item-service.d.ts +0 -2
  397. package/dist/src/work-items/work-item-service.js +0 -28
  398. package/dist/src/workflows/service/workflow-run-service.js +2 -2
  399. package/dist/src/workflows/service/workflow-run-service.types.d.ts +3 -1
  400. package/dist/src/workflows/service/workflow-session-bridge.js +2 -2
  401. package/package.json +1 -1
  402. package/dist/gateway/static/root/assets/agents-DC9F12Kw.js +0 -2
  403. package/dist/gateway/static/root/assets/apps-page-5bKr05Fa.js +0 -1
  404. package/dist/gateway/static/root/assets/automation-suggestion-card-B7mxFRtf.js +0 -1
  405. package/dist/gateway/static/root/assets/automations-page-Dg6dmt5g.js +0 -6
  406. package/dist/gateway/static/root/assets/browser-settings-page-BHoo6Rpq.js +0 -8
  407. package/dist/gateway/static/root/assets/capabilities-settings-panel-BlsqN8Fu.js +0 -7
  408. package/dist/gateway/static/root/assets/capability-presets-settings-panel-DJeT8_B4.js +0 -1
  409. package/dist/gateway/static/root/assets/channels-settings-C4VVjYEm.js +0 -1
  410. package/dist/gateway/static/root/assets/channels-status-swr-vdf8kB16.js +0 -1
  411. package/dist/gateway/static/root/assets/circle-alert-BEjgurr2.js +0 -1
  412. package/dist/gateway/static/root/assets/connectors-page-DNcrDThX.js +0 -2
  413. package/dist/gateway/static/root/assets/desktop-pet-B1urphOZ.js +0 -1
  414. package/dist/gateway/static/root/assets/desktop-pet-settings-DTL6J3EP.js +0 -1
  415. package/dist/gateway/static/root/assets/gateway-settings-DmObBx9b.js +0 -1
  416. package/dist/gateway/static/root/assets/goal-create-dialog-BRhmmBe9.js +0 -1
  417. package/dist/gateway/static/root/assets/goal-detail-page-C1k7_s_O.js +0 -4
  418. package/dist/gateway/static/root/assets/goals-config-api-Fwu1wjEP.js +0 -1
  419. package/dist/gateway/static/root/assets/goals-page-hOu9uA3q.js +0 -2
  420. package/dist/gateway/static/root/assets/goals-settings-DY-JjvHz.js +0 -1
  421. package/dist/gateway/static/root/assets/index-C0CGebQ1.js +0 -212
  422. package/dist/gateway/static/root/assets/index-eqq25gvV.css +0 -1
  423. package/dist/gateway/static/root/assets/local-app-workbench-page-EjsNT7nJ.js +0 -2
  424. package/dist/gateway/static/root/assets/logs-page-Dswjlraa.js +0 -7
  425. package/dist/gateway/static/root/assets/messages-DP6tPKk-.js +0 -3
  426. package/dist/gateway/static/root/assets/notes-workbench-DSh3-hMY.js +0 -4
  427. package/dist/gateway/static/root/assets/product-delivery-BTRT9kCS.js +0 -1
  428. package/dist/gateway/static/root/assets/project-detail-page-D0QPRHR_.js +0 -1
  429. package/dist/gateway/static/root/assets/projects-page-CI5Vz62F.js +0 -1
  430. package/dist/gateway/static/root/assets/remote-access-hub-S1jpzBS5.js +0 -1
  431. package/dist/gateway/static/root/assets/sessions-page-CTm66k7h.js +0 -1
  432. package/dist/gateway/static/root/assets/settings-advanced-gate-CU52AUVD.js +0 -1
  433. package/dist/gateway/static/root/assets/shares-settings-DK6XK95e.js +0 -1
  434. package/dist/gateway/static/root/assets/skill-reload-api-Bvv_u4ii.js +0 -1
  435. package/dist/gateway/static/root/assets/skills-page-BGHvVbay.js +0 -2
  436. package/dist/gateway/static/root/assets/time-picker-XwpxdZFr.js +0 -1
  437. package/dist/gateway/static/root/assets/user-context-page-DBCMk-Vn.js +0 -1
  438. package/dist/gateway/static/root/assets/work-discovery-page-C1UIdsCl.js +0 -1
  439. package/dist/gateway/static/root/assets/work-item-detail-page-DEAQepB8.js +0 -1
  440. package/dist/gateway/static/root/assets/work-page-D5qYmCTq.js +0 -3
  441. package/dist/gateway/static/root/assets/workflows-page-yrK17ZZ5.js +0 -11
  442. package/dist/src/agent/outcomes/task-verifier.d.ts +0 -29
  443. package/dist/src/gateway/hono/routes/task-outcomes.d.ts +0 -3
  444. package/dist/src/gateway/hono/routes/task-outcomes.js +0 -109
  445. package/dist/src/goals/goal-contract-draft.d.ts +0 -15
  446. package/dist/src/goals/goal-contract-draft.js +0 -112
  447. package/dist/src/goals/goal-evidence-review.d.ts +0 -15
  448. package/dist/src/goals/goal-evidence-review.js +0 -89
  449. package/dist/src/storage/sqlite/task-outcome-repository.d.ts +0 -90
  450. package/dist/src/storage/sqlite/task-outcome-repository.js +0 -138
@@ -2,35 +2,71 @@ import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { init_agent_scope, normalizeAgentId } from "../../agent/agent-scope.js";
4
4
  import { buildSessionKey, init_session_key } from "../../routing/session-key.js";
5
- import "../domain/defaults.js";
5
+ import { resolveAutomationTimeoutSeconds } from "../domain/defaults.js";
6
6
  import crypto from "node:crypto";
7
7
  //#region src/automations/service/action-executor.ts
8
8
  init_agent_scope();
9
9
  init_session_key();
10
10
  init_logger();
11
11
  const log = createLogger("Automation:ActionExecutor");
12
- function withTimeout(promise, timeoutMs, signal) {
13
- return new Promise((resolve, reject) => {
14
- if (signal.aborted) {
15
- reject(/* @__PURE__ */ new Error("Automation run was cancelled"));
16
- return;
12
+ const CANCELLATION_GRACE_MS = 1e4;
13
+ var AutomationExecutionStoppedError = class extends Error {
14
+ constructor(status, cancellationConfirmed, deadlineAtMs, timeoutMs) {
15
+ super(status === "timeout" ? `Automation timed out after ${timeoutMs}ms` : "Automation run was cancelled");
16
+ this.status = status;
17
+ this.cancellationConfirmed = cancellationConfirmed;
18
+ this.deadlineAtMs = deadlineAtMs;
19
+ this.name = "AutomationExecutionStoppedError";
20
+ }
21
+ };
22
+ async function waitForCancellation(promise) {
23
+ let timer;
24
+ try {
25
+ return await Promise.race([promise.then(() => true, () => true), new Promise((resolve) => {
26
+ timer = setTimeout(() => resolve(false), CANCELLATION_GRACE_MS);
27
+ })]);
28
+ } finally {
29
+ if (timer) clearTimeout(timer);
30
+ }
31
+ }
32
+ async function executeWithDeadline(operation, timeoutMs, parentSignal, deadlineAtMs) {
33
+ const controller = new AbortController();
34
+ let stoppedAs;
35
+ const stop = (status, reason) => {
36
+ if (controller.signal.aborted) return;
37
+ stoppedAs = status;
38
+ controller.abort(reason);
39
+ };
40
+ const onParentAbort = () => stop("cancelled", parentSignal.reason);
41
+ parentSignal.addEventListener("abort", onParentAbort, { once: true });
42
+ if (parentSignal.aborted) onParentAbort();
43
+ const timer = setTimeout(() => stop("timeout", /* @__PURE__ */ new Error(`Automation timed out after ${timeoutMs}ms`)), Math.max(0, deadlineAtMs - Date.now()));
44
+ const operationPromise = operation(controller.signal);
45
+ const rejectForAbort = () => {
46
+ throw controller.signal.reason ?? /* @__PURE__ */ new Error("Automation run was cancelled");
47
+ };
48
+ let removeDeadlineAbortListener;
49
+ const abortPromise = new Promise((_, reject) => {
50
+ const rejectPromise = () => reject(controller.signal.reason ?? /* @__PURE__ */ new Error("Automation run was cancelled"));
51
+ if (controller.signal.aborted) rejectPromise();
52
+ else {
53
+ controller.signal.addEventListener("abort", rejectPromise, { once: true });
54
+ removeDeadlineAbortListener = () => controller.signal.removeEventListener("abort", rejectPromise);
17
55
  }
18
- const timer = setTimeout(() => reject(/* @__PURE__ */ new Error(`Automation timed out after ${timeoutMs}ms`)), timeoutMs);
19
- const onAbort = () => {
20
- clearTimeout(timer);
21
- reject(/* @__PURE__ */ new Error("Automation run was cancelled"));
22
- };
23
- signal.addEventListener("abort", onAbort, { once: true });
24
- promise.then((value) => {
25
- clearTimeout(timer);
26
- signal.removeEventListener("abort", onAbort);
27
- resolve(value);
28
- }, (err) => {
29
- clearTimeout(timer);
30
- signal.removeEventListener("abort", onAbort);
31
- reject(err);
32
- });
33
56
  });
57
+ try {
58
+ const result = await Promise.race([operationPromise, abortPromise]);
59
+ if (stoppedAs) rejectForAbort();
60
+ return result;
61
+ } catch (err) {
62
+ if (!stoppedAs) throw err;
63
+ const cancellationConfirmed = await waitForCancellation(operationPromise);
64
+ throw new AutomationExecutionStoppedError(stoppedAs, cancellationConfirmed, deadlineAtMs, timeoutMs);
65
+ } finally {
66
+ clearTimeout(timer);
67
+ parentSignal.removeEventListener("abort", onParentAbort);
68
+ removeDeadlineAbortListener?.();
69
+ }
34
70
  }
35
71
  var AutomationActionExecutor = class {
36
72
  deps = {};
@@ -40,26 +76,41 @@ var AutomationActionExecutor = class {
40
76
  ...deps
41
77
  };
42
78
  }
43
- async execute(automation, run, signal) {
44
- const timeoutMs = (automation.action.timeoutSeconds ?? automation.reliability?.timeoutSeconds ?? 0) > 0 ? (automation.action.timeoutSeconds ?? automation.reliability?.timeoutSeconds) * 1e3 : 300 * 1e3;
45
- return withTimeout(this.executeWithoutTimeout(automation, run, signal), timeoutMs, signal).catch((err) => {
79
+ async execute(automation, run, signal, hooks = {}) {
80
+ const configuredTimeoutMs = resolveAutomationTimeoutSeconds(automation.action, automation.reliability) * 1e3;
81
+ const deadlineAtMs = run.deadlineAtMs ?? Date.now() + configuredTimeoutMs;
82
+ const timeoutMs = Math.max(1, deadlineAtMs - Date.now());
83
+ await hooks.onRunPatch?.({ deadlineAtMs });
84
+ return executeWithDeadline((deadlineSignal) => this.executeWithoutTimeout(automation, run, deadlineSignal, hooks, deadlineAtMs), timeoutMs, signal, deadlineAtMs).catch((err) => {
46
85
  const message = err instanceof Error ? err.message : String(err);
86
+ if (err instanceof AutomationExecutionStoppedError) return {
87
+ status: err.status,
88
+ error: message,
89
+ deadlineAtMs: err.deadlineAtMs,
90
+ termination: {
91
+ reason: err.status === "timeout" ? "deadline_exceeded" : "user_cancelled",
92
+ component: "automation",
93
+ cancellationConfirmed: err.cancellationConfirmed
94
+ }
95
+ };
47
96
  return {
48
97
  status: message.toLowerCase().includes("cancelled") ? "cancelled" : message.toLowerCase().includes("timed out") ? "timeout" : "failed",
49
- error: message
98
+ error: message,
99
+ deadlineAtMs
50
100
  };
51
101
  });
52
102
  }
53
- async executeWithoutTimeout(automation, run, signal) {
103
+ async executeWithoutTimeout(automation, run, signal, hooks, deadlineAtMs) {
54
104
  if (signal.aborted) return {
55
105
  status: "cancelled",
56
106
  error: "Automation run was cancelled"
57
107
  };
58
- if (automation.action.kind === "workflow") return this.executeWorkflow(automation, automation.action, run);
59
- if (automation.action.kind === "browser_recipe") return this.executeBrowserRecipe(automation, automation.action, signal);
60
- return this.executeAgent(automation, automation.action);
108
+ if (automation.action.kind === "workflow") return this.executeWorkflow(automation, automation.action, run, signal, hooks);
109
+ if (automation.action.kind === "browser_recipe") return this.executeBrowserRecipe(automation, automation.action, signal, hooks);
110
+ return this.executeAgent(automation, automation.action, run, signal, hooks, deadlineAtMs);
61
111
  }
62
- async executeBrowserRecipe(automation, action, signal) {
112
+ async executeBrowserRecipe(automation, action, signal, hooks) {
113
+ await hooks.onRunPatch?.({ currentPhase: "action" });
63
114
  const safetyMode = automation.safety?.mode ?? "auto_apply";
64
115
  if (safetyMode !== "auto_apply") return {
65
116
  status: "succeeded",
@@ -80,7 +131,7 @@ var AutomationActionExecutor = class {
80
131
  error: run.error ?? `Browser automation ${action.recipeId} ${run.status}`
81
132
  };
82
133
  }
83
- async executeAgent(automation, action) {
134
+ async executeAgent(automation, action, run, signal, hooks, deadlineAtMs) {
84
135
  const agentService = this.deps.agentService;
85
136
  if (!agentService?.turnDispatcher?.processDirect) return {
86
137
  status: "failed",
@@ -94,6 +145,10 @@ var AutomationActionExecutor = class {
94
145
  peerId: `${automation.id}-${crypto.randomUUID().slice(0, 8)}`
95
146
  });
96
147
  const effectiveWorkingDirectory = action.workingDirectory ?? (automation.projectId ? this.deps.getProjectWorkspaceRoot?.(automation.projectId) : void 0);
148
+ await hooks.onRunPatch?.({
149
+ sessionKey,
150
+ currentPhase: "action"
151
+ });
97
152
  await agentService.sessionConfig?.applyAutomationWorkingDirectory?.(sessionKey, effectiveWorkingDirectory);
98
153
  if (agentService.sessionConfig?.applyAutomationModelOverride) {
99
154
  if (!await agentService.sessionConfig.applyAutomationModelOverride(sessionKey, action.model) && action.model) log.warn({
@@ -102,7 +157,11 @@ var AutomationActionExecutor = class {
102
157
  model: action.model
103
158
  }, "Automation model override invalid; using agent default");
104
159
  }
105
- const response = await agentService.turnDispatcher.processDirect(buildSafetyInstruction(automation, action.instruction), sessionKey);
160
+ const response = await agentService.turnDispatcher.processDirect(buildSafetyInstruction(automation, action.instruction), sessionKey, void 0, void 0, {
161
+ signal,
162
+ runId: run.id,
163
+ deadlineAtMs
164
+ });
106
165
  const model = agentService.getModelForSession?.(sessionKey);
107
166
  return {
108
167
  status: "succeeded",
@@ -111,7 +170,7 @@ var AutomationActionExecutor = class {
111
170
  model
112
171
  };
113
172
  }
114
- async executeWorkflow(automation, action, run) {
173
+ async executeWorkflow(automation, action, run, signal, hooks) {
115
174
  const safetyMode = automation.safety?.mode ?? "auto_apply";
116
175
  if (safetyMode === "suggest_only") return {
117
176
  status: "succeeded",
@@ -148,14 +207,65 @@ var AutomationActionExecutor = class {
148
207
  status: "failed",
149
208
  error: result.message
150
209
  };
151
- return {
210
+ await hooks.onRunPatch?.({
211
+ sessionKey: result.sessionKey,
212
+ workflowRunId: result.runId,
213
+ currentPhase: "action"
214
+ });
215
+ if (!workflowRunService.readWorkflowRunView) return {
152
216
  status: "succeeded",
153
217
  summary: `Started workflow run ${result.runId}`,
154
218
  sessionKey: result.sessionKey,
155
219
  workflowRunId: result.runId
156
220
  };
221
+ while (!signal.aborted) {
222
+ const view = await workflowRunService.readWorkflowRunView(agentId, result.runId);
223
+ if (!view) return {
224
+ status: "failed",
225
+ error: `Workflow run ${result.runId} disappeared`
226
+ };
227
+ const workflowStatus = view.run.status;
228
+ if (workflowStatus === "succeeded") return {
229
+ status: "succeeded",
230
+ summary: `Workflow run ${result.runId} completed`,
231
+ sessionKey: result.sessionKey,
232
+ workflowRunId: result.runId
233
+ };
234
+ if (workflowStatus === "failed" || workflowStatus === "cancelled" || workflowStatus === "timeout") return {
235
+ status: workflowStatus,
236
+ error: view.run.error?.message ?? `Workflow run ${result.runId} ${workflowStatus}`,
237
+ sessionKey: result.sessionKey,
238
+ workflowRunId: result.runId
239
+ };
240
+ await waitForSignalOrDelay(signal, 500);
241
+ }
242
+ await workflowRunService.cancelWorkflowRun?.({
243
+ agentId,
244
+ runId: result.runId,
245
+ reason: "Parent automation was cancelled or reached its deadline"
246
+ });
247
+ return {
248
+ status: "cancelled",
249
+ error: "Parent automation stopped while the workflow was running",
250
+ sessionKey: result.sessionKey,
251
+ workflowRunId: result.runId
252
+ };
157
253
  }
158
254
  };
255
+ function waitForSignalOrDelay(signal, delayMs) {
256
+ return new Promise((resolve) => {
257
+ const timer = setTimeout(() => {
258
+ signal.removeEventListener("abort", onAbort);
259
+ resolve();
260
+ }, delayMs);
261
+ const onAbort = () => {
262
+ clearTimeout(timer);
263
+ resolve();
264
+ };
265
+ if (signal.aborted) onAbort();
266
+ else signal.addEventListener("abort", onAbort, { once: true });
267
+ });
268
+ }
159
269
  function buildSafetyInstruction(automation, instruction) {
160
270
  const mode = automation.safety?.mode ?? "auto_apply";
161
271
  if (mode === "suggest_only") return [
@@ -15,6 +15,8 @@ export declare class AutomationService {
15
15
  private deps;
16
16
  private maxConcurrentRuns;
17
17
  private readonly activeRuns;
18
+ private readonly heartbeatTimers;
19
+ private readonly leaseOwner;
18
20
  constructor(signals?: ProactiveSignalPublisher);
19
21
  setDeps(deps: AutomationDeps): void;
20
22
  initialize(options?: {
@@ -54,6 +56,8 @@ export declare class AutomationService {
54
56
  private onTimer;
55
57
  private startRun;
56
58
  private executeRun;
59
+ private recoverInterruptedRuns;
60
+ private waitForRetry;
57
61
  private appendRunEvent;
58
62
  private finishAutomationRun;
59
63
  private postAfterRunWebhook;
@@ -5,7 +5,7 @@ import { computeNextAutomationRunAtMs, timerDelayUntil } from "../domain/schedul
5
5
  import { AutomationSchema, CreateAutomationSchema, UpdateAutomationSchema } from "../domain/validation.js";
6
6
  import { AutomationActionExecutor } from "./action-executor.js";
7
7
  import { deleteAutomation, getAutomation, listAutomations, saveAutomation, saveAutomations } from "../storage/automation-repository.js";
8
- import { appendAutomationRunEvent, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, saveAutomationRun } from "../storage/automation-run-repository.js";
8
+ import { appendAutomationRunEvent, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, saveAutomationRun, touchAutomationRunLease } from "../storage/automation-run-repository.js";
9
9
  import "../storage/index.js";
10
10
  import { randomUUID } from "node:crypto";
11
11
  //#region src/automations/service/automation-service.ts
@@ -13,6 +13,9 @@ init_logger();
13
13
  const log = createLogger("AutomationService");
14
14
  const DEFAULT_MAX_CONCURRENT_RUNS = 5;
15
15
  const MISSED_RUN_STAGGER_MS = 5e3;
16
+ const RUN_HEARTBEAT_INTERVAL_MS = 1e4;
17
+ const RUN_LEASE_DURATION_MS = 3e4;
18
+ const RETRY_BASE_DELAY_MS = 1e3;
16
19
  var AutomationAlreadyRunningError = class extends Error {
17
20
  constructor(automationId, runningRunId) {
18
21
  super(`Automation is already running: ${automationId}`);
@@ -29,6 +32,8 @@ var AutomationService = class {
29
32
  deps = {};
30
33
  maxConcurrentRuns = DEFAULT_MAX_CONCURRENT_RUNS;
31
34
  activeRuns = /* @__PURE__ */ new Map();
35
+ heartbeatTimers = /* @__PURE__ */ new Map();
36
+ leaseOwner = `automation-service:${process.pid}:${randomUUID()}`;
32
37
  constructor(signals) {
33
38
  this.signals = signals;
34
39
  }
@@ -42,6 +47,7 @@ var AutomationService = class {
42
47
  async initialize(options) {
43
48
  this.maxConcurrentRuns = Math.max(1, Math.floor(options?.maxConcurrentRuns ?? DEFAULT_MAX_CONCURRENT_RUNS));
44
49
  this.stopped = false;
50
+ await this.recoverInterruptedRuns();
45
51
  await this.recomputeNextRuns({ catchUp: true });
46
52
  this.armTimer();
47
53
  log.info("Automation service initialized");
@@ -53,6 +59,8 @@ var AutomationService = class {
53
59
  this.timer = null;
54
60
  }
55
61
  for (const controller of this.activeRuns.values()) controller.abort();
62
+ for (const timer of this.heartbeatTimers.values()) clearInterval(timer);
63
+ this.heartbeatTimers.clear();
56
64
  log.info("Automation service stopped");
57
65
  }
58
66
  async create(input) {
@@ -160,7 +168,19 @@ var AutomationService = class {
160
168
  async cancelRun(runId) {
161
169
  const controller = this.activeRuns.get(runId);
162
170
  if (!controller) return false;
163
- controller.abort();
171
+ const now = Date.now();
172
+ const current = getAutomationRun(runId);
173
+ if (current && current.status === "running") {
174
+ const cancelling = {
175
+ ...current,
176
+ status: "cancelling",
177
+ currentPhase: "cancelling",
178
+ cancelRequestedAtMs: now
179
+ };
180
+ saveAutomationRun(cancelling);
181
+ this.appendRunEvent(cancelling, "run.cancel_requested", "Automation cancellation requested", { reason: "user_cancelled" });
182
+ }
183
+ controller.abort(/* @__PURE__ */ new Error("Automation run was cancelled by the user"));
164
184
  return true;
165
185
  }
166
186
  async getMetrics() {
@@ -187,7 +207,7 @@ var AutomationService = class {
187
207
  ...automation,
188
208
  state: { ...automation.state }
189
209
  };
190
- if (next.state.runningRunId) {
210
+ if (next.state.runningRunId && !this.activeRuns.has(next.state.runningRunId)) {
191
211
  next.state.lastRunStatus = "failed";
192
212
  next.state.lastError = "Interrupted by gateway restart";
193
213
  next.state.consecutiveFailures = (next.state.consecutiveFailures ?? 0) + 1;
@@ -237,8 +257,10 @@ var AutomationService = class {
237
257
  triggerSnapshot: automation.trigger,
238
258
  actionSnapshot: automation.action,
239
259
  manual: opts.manual,
240
- createdAtMs: now
260
+ createdAtMs: now,
261
+ attemptNumber: 1
241
262
  };
263
+ run.rootRunId = run.id;
242
264
  saveAutomationRun(run);
243
265
  this.appendRunEvent(run, "run.queued", opts.event ? `Event ${opts.event.type} queued automation` : opts.manual ? "Manual run queued" : "Scheduled run queued", {
244
266
  trigger: automation.trigger,
@@ -270,21 +292,69 @@ var AutomationService = class {
270
292
  let run = {
271
293
  ...initialRun,
272
294
  status: "running",
273
- startedAtMs
295
+ startedAtMs,
296
+ currentPhase: "action",
297
+ heartbeatAtMs: startedAtMs,
298
+ leaseOwner: this.leaseOwner,
299
+ leaseExpiresAtMs: startedAtMs + RUN_LEASE_DURATION_MS
274
300
  };
275
301
  saveAutomationRun(run);
276
302
  this.appendRunEvent(run, "run.started", "Automation run started");
303
+ const heartbeat = setInterval(() => {
304
+ const now = Date.now();
305
+ touchAutomationRunLease(run.id, this.leaseOwner, now, now + RUN_LEASE_DURATION_MS);
306
+ }, RUN_HEARTBEAT_INTERVAL_MS);
307
+ heartbeat.unref?.();
308
+ this.heartbeatTimers.set(run.id, heartbeat);
277
309
  let status = "failed";
278
310
  let error;
279
311
  let activePhase = "action";
280
312
  try {
281
- this.appendRunEvent(run, "action.started", `Running ${automation.action.kind} action`, {
282
- actionKind: automation.action.kind,
283
- safety: automation.safety ?? { mode: "auto_apply" }
284
- });
285
- const outcome = await this.executor.execute(automation, run, controller.signal);
313
+ const maxAttempts = Math.max(1, (automation.reliability?.retryCount ?? 0) + 1);
314
+ let outcome;
315
+ for (let attempt = 1;; attempt += 1) {
316
+ run = {
317
+ ...run,
318
+ attemptNumber: attempt
319
+ };
320
+ saveAutomationRun(run);
321
+ this.appendRunEvent(run, "action.started", `Running ${automation.action.kind} action`, {
322
+ actionKind: automation.action.kind,
323
+ safety: automation.safety ?? { mode: "auto_apply" },
324
+ attempt,
325
+ maxAttempts
326
+ });
327
+ outcome = await this.executor.execute(automation, run, controller.signal, { onRunPatch: (patch) => {
328
+ const previousDeadline = run.deadlineAtMs;
329
+ run = {
330
+ ...run,
331
+ ...patch
332
+ };
333
+ saveAutomationRun(run);
334
+ if (patch.deadlineAtMs !== void 0 && patch.deadlineAtMs !== previousDeadline) this.appendRunEvent(run, "run.deadline_resolved", "Automation deadline resolved", {
335
+ deadlineAtMs: patch.deadlineAtMs,
336
+ timeoutMs: patch.deadlineAtMs - startedAtMs
337
+ });
338
+ } });
339
+ if (!(outcome.status === "failed") || attempt >= maxAttempts || controller.signal.aborted) break;
340
+ const delayMs = Math.min(RETRY_BASE_DELAY_MS * 2 ** (attempt - 1), 3e4);
341
+ this.appendRunEvent(run, "action.retry_scheduled", "Automation action retry scheduled", {
342
+ attempt,
343
+ nextAttempt: attempt + 1,
344
+ maxAttempts,
345
+ delayMs,
346
+ status: outcome.status,
347
+ error: outcome.error
348
+ });
349
+ await this.waitForRetry(delayMs, controller.signal);
350
+ }
286
351
  status = outcome.status;
287
352
  error = outcome.error;
353
+ const persistedRun = getAutomationRun(run.id);
354
+ if (persistedRun) run = {
355
+ ...run,
356
+ ...persistedRun
357
+ };
288
358
  this.appendRunEvent(run, status === "succeeded" ? "action.completed" : "action.failed", status === "succeeded" ? `${automation.action.kind} action completed` : `${automation.action.kind} action ${status}`, {
289
359
  summary: outcome.summary,
290
360
  error: outcome.error,
@@ -299,23 +369,52 @@ var AutomationService = class {
299
369
  error,
300
370
  sessionKey: outcome.sessionKey,
301
371
  workflowRunId: outcome.workflowRunId,
302
- model: outcome.model
372
+ model: outcome.model,
373
+ deadlineAtMs: outcome.deadlineAtMs ?? run.deadlineAtMs,
374
+ termination: outcome.termination ?? (status === "succeeded" ? {
375
+ reason: "completed",
376
+ cancellationConfirmed: true
377
+ } : status === "failed" ? {
378
+ reason: "failed",
379
+ cancellationConfirmed: true
380
+ } : run.termination)
303
381
  };
304
- if ((automation.safety?.mode ?? "auto_apply") !== "auto_apply" && automation.afterRun?.kind === "webhook") this.appendRunEvent(run, "after_run.completed", "After-run webhook skipped by safety mode", { safety: automation.safety ?? { mode: "auto_apply" } });
382
+ if (outcome.termination) {
383
+ const now = Date.now();
384
+ run = {
385
+ ...run,
386
+ currentPhase: "cancelling",
387
+ cancelRequestedAtMs: run.cancelRequestedAtMs ?? now,
388
+ cancelConfirmedAtMs: outcome.termination.cancellationConfirmed ? now : void 0
389
+ };
390
+ this.appendRunEvent(run, outcome.termination.cancellationConfirmed ? "run.cancel_confirmed" : "run.cancellation_unconfirmed", outcome.termination.cancellationConfirmed ? "Automation cancellation confirmed" : "Automation cancellation was not confirmed within the cleanup grace period", { termination: outcome.termination });
391
+ }
392
+ if (status === "timeout" || status === "cancelled") {} else if ((automation.safety?.mode ?? "auto_apply") !== "auto_apply" && automation.afterRun?.kind === "webhook") this.appendRunEvent(run, "after_run.completed", "After-run webhook skipped by safety mode", { safety: automation.safety ?? { mode: "auto_apply" } });
305
393
  else if (automation.afterRun?.kind === "webhook") {
306
394
  activePhase = "after_run";
395
+ run = {
396
+ ...run,
397
+ currentPhase: "after_run"
398
+ };
399
+ saveAutomationRun(run);
307
400
  this.appendRunEvent(run, "after_run.started", "Calling after-run webhook", { url: automation.afterRun.url });
308
- await this.postAfterRunWebhook(automation.afterRun.url, run);
401
+ await this.postAfterRunWebhook(automation.afterRun.url, run, controller.signal);
309
402
  this.appendRunEvent(run, "after_run.completed", "After-run webhook completed");
310
403
  }
311
404
  } catch (err) {
312
405
  error = err instanceof Error ? err.message : String(err);
313
- status = controller.signal.aborted ? "cancelled" : "failed";
406
+ const deadlineExceeded = run.deadlineAtMs !== void 0 && Date.now() >= run.deadlineAtMs;
407
+ status = controller.signal.aborted ? "cancelled" : deadlineExceeded ? "timeout" : "failed";
314
408
  this.appendRunEvent(run, activePhase === "after_run" ? "after_run.failed" : "action.failed", `Automation run ${status}`, { error });
315
409
  run = {
316
410
  ...run,
317
411
  status,
318
- error
412
+ error,
413
+ termination: {
414
+ reason: status === "cancelled" ? "user_cancelled" : status === "timeout" ? "deadline_exceeded" : "failed",
415
+ component: activePhase === "after_run" ? "automation" : run.termination?.component,
416
+ cancellationConfirmed: status !== "cancelled" || controller.signal.aborted
417
+ }
319
418
  };
320
419
  } finally {
321
420
  const endedAtMs = Date.now();
@@ -323,9 +422,19 @@ var AutomationService = class {
323
422
  ...run,
324
423
  status,
325
424
  endedAtMs,
326
- durationMs: endedAtMs - startedAtMs
425
+ durationMs: endedAtMs - startedAtMs,
426
+ currentPhase: "completed"
327
427
  };
328
428
  this.activeRuns.delete(initialRun.id);
429
+ const heartbeatTimer = this.heartbeatTimers.get(initialRun.id);
430
+ if (heartbeatTimer) clearInterval(heartbeatTimer);
431
+ this.heartbeatTimers.delete(initialRun.id);
432
+ run = {
433
+ ...run,
434
+ heartbeatAtMs: endedAtMs,
435
+ leaseOwner: void 0,
436
+ leaseExpiresAtMs: void 0
437
+ };
329
438
  runSqliteWriteTransaction(() => {
330
439
  saveAutomationRun(run);
331
440
  this.appendRunEvent(run, "run.completed", `Automation run ${status}`, {
@@ -370,6 +479,73 @@ var AutomationService = class {
370
479
  }
371
480
  }
372
481
  }
482
+ async recoverInterruptedRuns() {
483
+ const recoverable = listAutomationRuns({ limit: 500 }).filter((run) => run.status === "queued" || run.status === "running" || run.status === "cancelling");
484
+ for (const run of recoverable) {
485
+ const automation = getAutomation(run.automationId);
486
+ if (run.status === "queued" && automation) {
487
+ const claimed = {
488
+ ...automation,
489
+ state: {
490
+ ...automation.state,
491
+ runningRunId: run.id
492
+ }
493
+ };
494
+ saveAutomation(claimed);
495
+ this.appendRunEvent(run, "run.recovered", "Queued automation run recovered after restart", { previousLeaseOwner: run.leaseOwner });
496
+ this.executeRun(claimed, run).catch((err) => {
497
+ log.error({
498
+ err,
499
+ runId: run.id
500
+ }, "Recovered automation run failed");
501
+ });
502
+ continue;
503
+ }
504
+ const now = Date.now();
505
+ const status = run.status === "cancelling" ? "cancelled" : "failed";
506
+ const error = run.status === "cancelling" ? "Cancellation interrupted by gateway restart" : "Automation execution interrupted by gateway restart";
507
+ const recovered = {
508
+ ...run,
509
+ status,
510
+ error,
511
+ endedAtMs: now,
512
+ durationMs: run.startedAtMs ? now - run.startedAtMs : void 0,
513
+ currentPhase: "completed",
514
+ heartbeatAtMs: now,
515
+ leaseOwner: void 0,
516
+ leaseExpiresAtMs: void 0,
517
+ termination: {
518
+ reason: status === "cancelled" ? "user_cancelled" : "failed",
519
+ component: "automation",
520
+ cancellationConfirmed: false
521
+ }
522
+ };
523
+ saveAutomationRun(recovered);
524
+ this.appendRunEvent(recovered, "run.recovered", error, {
525
+ previousLeaseOwner: run.leaseOwner,
526
+ previousLeaseExpiresAtMs: run.leaseExpiresAtMs
527
+ });
528
+ this.appendRunEvent(recovered, "run.completed", `Automation run ${status}`, {
529
+ status,
530
+ error
531
+ });
532
+ if (automation) this.finishAutomationRun(automation.id, status, error, now);
533
+ }
534
+ }
535
+ waitForRetry(delayMs, signal) {
536
+ return new Promise((resolve, reject) => {
537
+ const timer = setTimeout(() => {
538
+ signal.removeEventListener("abort", onAbort);
539
+ resolve();
540
+ }, delayMs);
541
+ const onAbort = () => {
542
+ clearTimeout(timer);
543
+ reject(signal.reason ?? /* @__PURE__ */ new Error("Automation run was cancelled"));
544
+ };
545
+ if (signal.aborted) onAbort();
546
+ else signal.addEventListener("abort", onAbort, { once: true });
547
+ });
548
+ }
373
549
  appendRunEvent(run, type, message, data) {
374
550
  appendAutomationRunEvent({
375
551
  id: randomUUID(),
@@ -404,11 +580,14 @@ var AutomationService = class {
404
580
  saveAutomation(next);
405
581
  this.armTimer();
406
582
  }
407
- async postAfterRunWebhook(url, run) {
583
+ async postAfterRunWebhook(url, run, signal) {
584
+ const remainingMs = run.deadlineAtMs === void 0 ? 3e4 : Math.max(1, run.deadlineAtMs - Date.now());
585
+ const requestSignal = AbortSignal.any([signal, AbortSignal.timeout(remainingMs)]);
408
586
  const response = await fetch(url, {
409
587
  method: "POST",
410
588
  headers: { "content-type": "application/json" },
411
- body: JSON.stringify({ run })
589
+ body: JSON.stringify({ run }),
590
+ signal: requestSignal
412
591
  });
413
592
  if (!response.ok) {
414
593
  const text = await response.text().catch(() => "");
@@ -1,6 +1,7 @@
1
1
  import type { AutomationProductEventRun, AutomationRun, AutomationRunEvent } from '../domain/types.js';
2
2
  export declare function appendAutomationRunEvent(event: AutomationRunEvent): void;
3
3
  export declare function saveAutomationRun(run: AutomationRun): void;
4
+ export declare function touchAutomationRunLease(runId: string, leaseOwner: string, heartbeatAtMs: number, leaseExpiresAtMs: number): void;
4
5
  export declare function listAutomationRunEvents(runId: string): AutomationRunEvent[];
5
6
  export declare function getAutomationRun(runId: string): AutomationRun | null;
6
7
  export declare function listAutomationRuns(options?: {