@xopcai/xopc 0.0.176 → 0.0.178

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 (238) 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-DsFM1upC.js → activity-store-BzGX__8I.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DvdMLOga.js → agent-avatar-dicebear-BzxntcaZ.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-DC9F12Kw.js +2 -0
  6. package/dist/gateway/static/root/assets/{api-BdPLCCBm.js → api-hi6f2Xtp.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-DMLDOHul.js → app-management-settings-panel-fTY1F7ac.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-DbI9foFR.js → appearance-settings-BZ-IxQfB.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-5bKr05Fa.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-Dfdxuwvb.js → archive-plugin-ZSLLG8wB.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-Dn3RlnYD.js → attachment-load-D4YktqIF.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automation-suggestion-card-Bc0Y7A9u.js → automation-suggestion-card-B7mxFRtf.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-page-Dg6dmt5g.js +6 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-0XtB-xC0.js → binary-plugins-BIkPxfxj.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-C4fXWbEE.js → block-editor-Q3v_YQom.js} +6 -6
  16. package/dist/gateway/static/root/assets/{browser-settings-page-lC86-drr.js → browser-settings-page-BHoo6Rpq.js} +4 -4
  17. package/dist/gateway/static/root/assets/{browser-workflow-inputs-CZmzNymN.js → browser-workflow-inputs-M5lTEW1I.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflows-page-CBYM9HqG.js → browser-workflows-page-B3T1KYk4.js} +2 -2
  19. package/dist/gateway/static/root/assets/capabilities-settings-panel-BlsqN8Fu.js +7 -0
  20. package/dist/gateway/static/root/assets/{capability-presets-api-BiJxmmhW.js → capability-presets-api-DE09c0VB.js} +1 -1
  21. package/dist/gateway/static/root/assets/capability-presets-settings-panel-DJeT8_B4.js +1 -0
  22. package/dist/gateway/static/root/assets/{channel-recipient-api-BKTUZDp-.js → channel-recipient-api-CFR5FBfS.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-settings-C4VVjYEm.js +1 -0
  24. package/dist/gateway/static/root/assets/channels-status-swr-vdf8kB16.js +1 -0
  25. package/dist/gateway/static/root/assets/{connector-logo-Pr4RIKjj.js → connector-logo-B1mD-3pM.js} +1 -1
  26. package/dist/gateway/static/root/assets/connectors-page-DNcrDThX.js +2 -0
  27. package/dist/gateway/static/root/assets/desktop-pet-B1urphOZ.js +1 -0
  28. package/dist/gateway/static/root/assets/{desktop-pet-settings-CEQacUDF.js → desktop-pet-settings-DTL6J3EP.js} +1 -1
  29. package/dist/gateway/static/root/assets/{directory-picker-path-field-DWnxdZtc.js → directory-picker-path-field-BYQJ2XUS.js} +1 -1
  30. package/dist/gateway/static/root/assets/{dreaming-settings-D2e2w2Ho.js → dreaming-settings-BXcb8fwx.js} +3 -3
  31. package/dist/gateway/static/root/assets/{extension-debug-page-BLjTGbv3.js → extension-debug-page-O1Xu1r4Q.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-page-D2_UC6hy.js → extension-page-C2Jraq8l.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-settings-page-BsH6o_PX.js → extension-settings-page-DcXQDTpG.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-config-api-C-DkC6UJ.js → gateway-config-api-DmPIZrvg.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-settings-DEOGiimF.js → gateway-settings-DmObBx9b.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-startup-retry-BlSLh1TF.js → gateway-startup-retry-BZEkOdPm.js} +1 -1
  37. package/dist/gateway/static/root/assets/{goal-create-dialog-CSFcRE_N.js → goal-create-dialog-BRhmmBe9.js} +1 -1
  38. package/dist/gateway/static/root/assets/goal-detail-page-C1k7_s_O.js +4 -0
  39. package/dist/gateway/static/root/assets/{goals-config-api-CcdS9qek.js → goals-config-api-Fwu1wjEP.js} +1 -1
  40. package/dist/gateway/static/root/assets/{goals-page-BAcErdch.js → goals-page-hOu9uA3q.js} +2 -2
  41. package/dist/gateway/static/root/assets/{goals-settings-BY7crl0z.js → goals-settings-DY-JjvHz.js} +1 -1
  42. package/dist/gateway/static/root/assets/{heartbeat-settings-DtTkS0gs.js → heartbeat-settings-BtKu2NWT.js} +1 -1
  43. package/dist/gateway/static/root/assets/{image-generation-api-WGgkbwDZ.js → image-generation-api-05Gg8wsU.js} +1 -1
  44. package/dist/gateway/static/root/assets/{index-2UImfRDC.js → index-C0CGebQ1.js} +65 -65
  45. package/dist/gateway/static/root/assets/index-eqq25gvV.css +1 -0
  46. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-C5lpWQ3f.js → keyboard-shortcuts-settings-CfmDR9Sc.js} +1 -1
  47. package/dist/gateway/static/root/assets/local-app-workbench-page-EjsNT7nJ.js +2 -0
  48. package/dist/gateway/static/root/assets/{local-apps-page-b05wWvXG.js → local-apps-page-Df8BW1A_.js} +1 -1
  49. package/dist/gateway/static/root/assets/{locale-store-sToMfHX_.js → locale-store-CTwSy7yW.js} +1 -1
  50. package/dist/gateway/static/root/assets/{logs-page-cDE1jLJv.js → logs-page-Dswjlraa.js} +3 -3
  51. package/dist/gateway/static/root/assets/{markdown-split-0gPVst5y.js → markdown-split-B3FvKbaP.js} +1 -1
  52. package/dist/gateway/static/root/assets/{media-plugins-Rxyq_KTm.js → media-plugins-DsjrvvB6.js} +1 -1
  53. package/dist/gateway/static/root/assets/messages-DP6tPKk-.js +3 -0
  54. package/dist/gateway/static/root/assets/{notes-page-DRhNDl_Q.js → notes-page-tuzIwy3c.js} +1 -1
  55. package/dist/gateway/static/root/assets/notes-workbench-DSh3-hMY.js +4 -0
  56. package/dist/gateway/static/root/assets/{page-tabs-cOEOQqHh.js → page-tabs-ke9s4nYi.js} +1 -1
  57. package/dist/gateway/static/root/assets/{preview-open-alternatives-BopOLFvu.js → preview-open-alternatives-Cp1eI4S9.js} +1 -1
  58. package/dist/gateway/static/root/assets/{product-open-page-DWVPmmOq.js → product-open-page-dXQCMAtH.js} +1 -1
  59. package/dist/gateway/static/root/assets/project-detail-page-D0QPRHR_.js +1 -0
  60. package/dist/gateway/static/root/assets/projects-page-CI5Vz62F.js +1 -0
  61. package/dist/gateway/static/root/assets/remote-access-hub-S1jpzBS5.js +1 -0
  62. package/dist/gateway/static/root/assets/{save-bar-controls-BfZmKe1t.js → save-bar-controls-Bl30zjHc.js} +1 -1
  63. package/dist/gateway/static/root/assets/{schedule-field-Cpi4jCRV.js → schedule-field-DqhmXQKo.js} +1 -1
  64. package/dist/gateway/static/root/assets/{schema-form-OXFkcZQe.js → schema-form-DkUCy6vf.js} +1 -1
  65. package/dist/gateway/static/root/assets/sessions-page-CTm66k7h.js +1 -0
  66. package/dist/gateway/static/root/assets/settings-advanced-gate-CU52AUVD.js +1 -0
  67. package/dist/gateway/static/root/assets/{settings-form-section-BwqkZCHJ.js → settings-form-section-C6ZbNpdy.js} +1 -1
  68. package/dist/gateway/static/root/assets/{settings-loading-skeleton-BbqH_S3Y.js → settings-loading-skeleton-Bk58_cr7.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-page-BoxC-JSa.js → settings-page-k8iE_NdX.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-layout-Ddu2iGaW.js → settings-page-layout-DgFSya2e.js} +1 -1
  71. package/dist/gateway/static/root/assets/{setup-status-panel-z1Lwv0js.js → setup-status-panel-B_KDlyZA.js} +1 -1
  72. package/dist/gateway/static/root/assets/{share-preview-page-CVazOFjy.js → share-preview-page-CV7nL_J9.js} +1 -1
  73. package/dist/gateway/static/root/assets/shares-settings-DK6XK95e.js +1 -0
  74. package/dist/gateway/static/root/assets/skill-reload-api-Bvv_u4ii.js +1 -0
  75. package/dist/gateway/static/root/assets/skills-page-BGHvVbay.js +2 -0
  76. package/dist/gateway/static/root/assets/{skills-page.utils-DgyB1tSo.js → skills-page.utils-kahBIHg0.js} +1 -1
  77. package/dist/gateway/static/root/assets/{system-settings-panel-BoLSQL65.js → system-settings-panel-JV3-MG5F.js} +1 -1
  78. package/dist/gateway/static/root/assets/{theme-store-CBNcGOfj.js → theme-store-DFLyzoLO.js} +1 -1
  79. package/dist/gateway/static/root/assets/{time-picker-gochWrny.js → time-picker-XwpxdZFr.js} +1 -1
  80. package/dist/gateway/static/root/assets/{typed-models-lib-DvRnr7YB.js → typed-models-lib-60Aqo-UJ.js} +1 -1
  81. package/dist/gateway/static/root/assets/{use-channel-catalog-CA9BFVB7.js → use-channel-catalog-CnTkHDnw.js} +1 -1
  82. package/dist/gateway/static/root/assets/user-context-page-DBCMk-Vn.js +1 -0
  83. package/dist/gateway/static/root/assets/{voice-api-key-field-v8tgylEZ.js → voice-api-key-field-CNa8qUgS.js} +1 -1
  84. package/dist/gateway/static/root/assets/work-discovery-page-C1UIdsCl.js +1 -0
  85. package/dist/gateway/static/root/assets/work-item-detail-page-DEAQepB8.js +1 -0
  86. package/dist/gateway/static/root/assets/work-page-D5qYmCTq.js +3 -0
  87. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CC3cJn5k.js → workflow-run-setup-panel-yV_x595t.js} +2 -2
  88. package/dist/gateway/static/root/assets/workflows-page-yrK17ZZ5.js +11 -0
  89. package/dist/gateway/static/root/index.html +7 -7
  90. package/dist/package.js +1 -1
  91. package/dist/src/agent/embedded/model-runtime.js +3 -0
  92. package/dist/src/agent/embedded/run-for-session.js +18 -5
  93. package/dist/src/agent/embedded/run-turn.js +6 -3
  94. package/dist/src/agent/embedded/types.d.ts +2 -0
  95. package/dist/src/automations/service/automation-service.d.ts +3 -0
  96. package/dist/src/automations/service/automation-service.js +37 -7
  97. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  98. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  99. package/dist/src/cli/commands/update.js +1 -1
  100. package/dist/src/connectors/composio-sessions.js +1 -1
  101. package/dist/src/gateway/hono/routes/home.d.ts +18 -2
  102. package/dist/src/gateway/hono/routes/home.js +19 -0
  103. package/dist/src/gateway/hono/routes/index.js +2 -2
  104. package/dist/src/gateway/hono/routes/local-apps.js +1 -1
  105. package/dist/src/gateway/hono/routes/proactive.d.ts +4 -0
  106. package/dist/src/gateway/hono/routes/proactive.js +157 -0
  107. package/dist/src/gateway/hono/routes/projects.js +2 -2
  108. package/dist/src/gateway/hono/routes/update.js +2 -2
  109. package/dist/src/gateway/index.js +1 -1
  110. package/dist/src/gateway/run-loop.js +1 -1
  111. package/dist/src/gateway/service.d.ts +10 -1
  112. package/dist/src/gateway/service.js +36 -36
  113. package/dist/src/infra/gateway-processes.js +1 -1
  114. package/dist/src/infra/update-restart.js +1 -1
  115. package/dist/src/infra/update-runner.js +2 -2
  116. package/dist/src/infra/update-startup.js +1 -1
  117. package/dist/src/mcp/channel-bridge.js +1 -1
  118. package/dist/src/mobile/notification-service.d.ts +1 -0
  119. package/dist/src/mobile/notification-service.js +38 -18
  120. package/dist/src/mobile/notification-types.d.ts +2 -2
  121. package/dist/src/proactive/events/envelope.d.ts +2 -0
  122. package/dist/src/proactive/events/envelope.js +54 -0
  123. package/dist/src/proactive/events/publisher.d.ts +4 -0
  124. package/dist/src/proactive/events/repository.d.ts +9 -0
  125. package/dist/src/proactive/events/repository.js +62 -0
  126. package/dist/src/proactive/events/types.d.ts +44 -0
  127. package/dist/src/proactive/events/types.js +15 -0
  128. package/dist/src/proactive/execution/agent-executor.d.ts +16 -0
  129. package/dist/src/proactive/execution/agent-executor.js +104 -0
  130. package/dist/src/proactive/execution/context.d.ts +31 -0
  131. package/dist/src/proactive/execution/context.js +72 -0
  132. package/dist/src/proactive/execution/insight.d.ts +4 -0
  133. package/dist/src/proactive/execution/insight.js +74 -0
  134. package/dist/src/proactive/execution/repository.d.ts +23 -0
  135. package/dist/src/proactive/execution/repository.js +122 -0
  136. package/dist/src/proactive/execution/types.d.ts +54 -0
  137. package/dist/src/proactive/execution/types.js +1 -0
  138. package/dist/src/proactive/execution/worker.d.ts +15 -0
  139. package/dist/src/proactive/execution/worker.js +96 -0
  140. package/dist/src/proactive/inbox/repository.d.ts +24 -0
  141. package/dist/src/proactive/inbox/repository.js +117 -0
  142. package/dist/src/proactive/inbox/service.d.ts +17 -0
  143. package/dist/src/proactive/inbox/service.js +22 -0
  144. package/dist/src/proactive/inbox/types.d.ts +38 -0
  145. package/dist/src/proactive/inbox/types.js +1 -0
  146. package/dist/src/proactive/inbox/worker.d.ts +12 -0
  147. package/dist/src/proactive/inbox/worker.js +56 -0
  148. package/dist/src/proactive/index.d.ts +17 -0
  149. package/dist/src/proactive/index.js +11 -0
  150. package/dist/src/proactive/routing/batch-repository.d.ts +27 -0
  151. package/dist/src/proactive/routing/batch-repository.js +56 -0
  152. package/dist/src/proactive/routing/matcher.d.ts +5 -0
  153. package/dist/src/proactive/routing/matcher.js +56 -0
  154. package/dist/src/proactive/routing/types.d.ts +44 -0
  155. package/dist/src/proactive/routing/types.js +1 -0
  156. package/dist/src/proactive/scenarios/prompt-composer.d.ts +14 -0
  157. package/dist/src/proactive/scenarios/prompt-composer.js +24 -0
  158. package/dist/src/proactive/scenarios/repository.d.ts +23 -0
  159. package/dist/src/proactive/scenarios/repository.js +162 -0
  160. package/dist/src/proactive/scenarios/service.d.ts +15 -0
  161. package/dist/src/proactive/scenarios/service.js +26 -0
  162. package/dist/src/proactive/scenarios/types.d.ts +36 -0
  163. package/dist/src/proactive/scenarios/types.js +1 -0
  164. package/dist/src/proactive/service.d.ts +18 -0
  165. package/dist/src/proactive/service.js +61 -0
  166. package/dist/src/projects/project-service.d.ts +3 -1
  167. package/dist/src/projects/project-service.js +62 -32
  168. package/dist/src/providers/provider-auth-service.js +3 -0
  169. package/dist/src/providers/register-bundled-oauth-flows.d.ts +2 -0
  170. package/dist/src/providers/register-bundled-oauth-flows.js +16 -0
  171. package/dist/src/session/store.d.ts +2 -0
  172. package/dist/src/session/store.js +30 -0
  173. package/dist/src/storage/sqlite/migrations/068_proactive_event_spine.sql +71 -0
  174. package/dist/src/storage/sqlite/migrations/069_proactive_scenario_control.sql +69 -0
  175. package/dist/src/storage/sqlite/migrations/070_proactive_execution.sql +55 -0
  176. package/dist/src/storage/sqlite/migrations/071_proactive_inbox.sql +45 -0
  177. package/dist/src/storage/sqlite/migrations/072_proactive_judgments.sql +14 -0
  178. package/dist/src/storage/sqlite/migrations/073_enable_default_proactive_scenarios.sql +13 -0
  179. package/dist/src/storage/sqlite/migrations/074_deduplicate_blocked_work_routing.sql +5 -0
  180. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  181. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  182. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  183. package/dist/src/storage/sqlite/schema.js +1 -1
  184. package/dist/src/work-discovery/thread-service.d.ts +1 -3
  185. package/dist/src/work-discovery/thread-service.js +13 -25
  186. package/dist/src/work-items/work-item-service.d.ts +3 -1
  187. package/dist/src/work-items/work-item-service.js +67 -36
  188. package/package.json +3 -11
  189. package/dist/gateway/static/root/assets/agents-BVjlpbeZ.js +0 -2
  190. package/dist/gateway/static/root/assets/api-Bop4IQRW.js +0 -1
  191. package/dist/gateway/static/root/assets/apps-page-njqxLWYD.js +0 -1
  192. package/dist/gateway/static/root/assets/automations-page-D-eweHZJ.js +0 -6
  193. package/dist/gateway/static/root/assets/capabilities-settings-panel-6tYNfHqJ.js +0 -7
  194. package/dist/gateway/static/root/assets/capability-presets-settings-panel-Co-ymbd9.js +0 -1
  195. package/dist/gateway/static/root/assets/channels-settings-D46eVjaQ.js +0 -1
  196. package/dist/gateway/static/root/assets/channels-status-swr-BMRAO4zZ.js +0 -1
  197. package/dist/gateway/static/root/assets/connectors-page-Dw1eYbRi.js +0 -2
  198. package/dist/gateway/static/root/assets/copy-VueTIC2x.js +0 -1
  199. package/dist/gateway/static/root/assets/desktop-pet-B8cZuQUt.js +0 -1
  200. package/dist/gateway/static/root/assets/focus-detail-page-BBXUtxRB.js +0 -1
  201. package/dist/gateway/static/root/assets/goal-detail-page-VjRArfAJ.js +0 -4
  202. package/dist/gateway/static/root/assets/index-CS9sVShT.css +0 -1
  203. package/dist/gateway/static/root/assets/local-app-workbench-page-Cl0fcPL4.js +0 -2
  204. package/dist/gateway/static/root/assets/messages-CarlxqXV.js +0 -3
  205. package/dist/gateway/static/root/assets/notes-workbench-BKNBk0Uf.js +0 -4
  206. package/dist/gateway/static/root/assets/project-detail-page-BhjEXNQW.js +0 -1
  207. package/dist/gateway/static/root/assets/projects-page-B80e69PH.js +0 -1
  208. package/dist/gateway/static/root/assets/remote-access-hub-CwdVob6H.js +0 -1
  209. package/dist/gateway/static/root/assets/sessions-page-BGt3Asj6.js +0 -1
  210. package/dist/gateway/static/root/assets/settings-advanced-gate-BnTdM9Nn.js +0 -1
  211. package/dist/gateway/static/root/assets/shares-settings-C4lXuyQj.js +0 -1
  212. package/dist/gateway/static/root/assets/skill-reload-api-DSuIDkeI.js +0 -1
  213. package/dist/gateway/static/root/assets/skills-page-xgZczqVe.js +0 -2
  214. package/dist/gateway/static/root/assets/user-context-page-CEfIy4WZ.js +0 -1
  215. package/dist/gateway/static/root/assets/work-discovery-page-B-3MClaf.js +0 -1
  216. package/dist/gateway/static/root/assets/work-item-detail-page-CEsFEdax.js +0 -1
  217. package/dist/gateway/static/root/assets/work-page-CT9AHnq6.js +0 -3
  218. package/dist/gateway/static/root/assets/workflows-page-C-1-_Zp1.js +0 -11
  219. package/dist/src/focuses/candidate-repository.d.ts +0 -15
  220. package/dist/src/focuses/candidate-repository.js +0 -91
  221. package/dist/src/focuses/index.d.ts +0 -7
  222. package/dist/src/focuses/index.js +0 -7
  223. package/dist/src/focuses/insight-repository.d.ts +0 -22
  224. package/dist/src/focuses/insight-repository.js +0 -77
  225. package/dist/src/focuses/prompts.d.ts +0 -2
  226. package/dist/src/focuses/prompts.js +0 -18
  227. package/dist/src/focuses/reconciler.d.ts +0 -5
  228. package/dist/src/focuses/reconciler.js +0 -26
  229. package/dist/src/focuses/repository.d.ts +0 -61
  230. package/dist/src/focuses/repository.js +0 -214
  231. package/dist/src/focuses/run-processor.d.ts +0 -18
  232. package/dist/src/focuses/run-processor.js +0 -162
  233. package/dist/src/focuses/service.d.ts +0 -42
  234. package/dist/src/focuses/service.js +0 -241
  235. package/dist/src/focuses/types.d.ts +0 -89
  236. package/dist/src/gateway/hono/routes/focuses.d.ts +0 -3
  237. package/dist/src/gateway/hono/routes/focuses.js +0 -319
  238. /package/dist/src/{focuses/types.js → proactive/events/publisher.js} +0 -0
@@ -46,15 +46,6 @@ import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js"
46
46
  import "../knowledge/index.js";
47
47
  import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
48
48
  import { startConnectorSupervisor } from "../connectors/supervisor.js";
49
- import { FocusService } from "../focuses/service.js";
50
- import { processFocusMonitorRun } from "../focuses/run-processor.js";
51
- import { startFocusReconciler } from "../focuses/reconciler.js";
52
- import "../focuses/index.js";
53
- import { LocalAppService } from "../local-apps/service.js";
54
- import "../local-apps/index.js";
55
- import { scheduleGatewayUpdateCheck } from "../infra/update-startup.js";
56
- import { runBootstrapMigrationsSync } from "../migrations/runner.js";
57
- import { MobileNotificationService } from "../mobile/notification-service.js";
58
49
  import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
59
50
  import { reconcileDreamingAutomations } from "./dreaming-automation-reconciler.js";
60
51
  import { NotesStore } from "../notes/store.js";
@@ -80,8 +71,21 @@ import "./rate-limit/index.js";
80
71
  import { assertGatewayRuntimeConfig } from "./runtime-config.js";
81
72
  import { auditGatewayConfig } from "./security/audit.js";
82
73
  import { ModelCatalogSyncService } from "../providers/model-catalog-sync-service.js";
74
+ import { runBootstrapMigrationsSync } from "../migrations/runner.js";
75
+ import { MobileNotificationService } from "../mobile/notification-service.js";
76
+ import { LocalAppService } from "../local-apps/service.js";
77
+ import "../local-apps/index.js";
83
78
  import { createRuntimeBrowserRecipeService } from "../browser/recipes/runtime-service.js";
84
79
  import "../browser/recipes/index.js";
80
+ import { ProactiveEventService } from "../proactive/service.js";
81
+ import { ProactiveScenarioService } from "../proactive/scenarios/service.js";
82
+ import { ReadonlyProactiveAgentExecutor } from "../proactive/execution/agent-executor.js";
83
+ import { listInsights } from "../proactive/execution/repository.js";
84
+ import { ProactiveWorker } from "../proactive/execution/worker.js";
85
+ import { ProactiveInboxService } from "../proactive/inbox/service.js";
86
+ import { ProactiveInboxWorker } from "../proactive/inbox/worker.js";
87
+ import "../proactive/index.js";
88
+ import { scheduleGatewayUpdateCheck } from "../infra/update-startup.js";
85
89
  import { resolveChannelConnectDeferSet } from "./resolve-channel-connect-defer.js";
86
90
  import { restartGatewayProcessWithFreshPid } from "./respawn.js";
87
91
  import { GatewaySessionsApi } from "./service/sessions-api.js";
@@ -163,7 +167,6 @@ var GatewayService = class {
163
167
  connectedKnowledgeCoordinator = null;
164
168
  stopAutomationProductEventBridge = null;
165
169
  stopSessionTranscriptAutomationEvents = null;
166
- stopFocusReconciler = null;
167
170
  /**
168
171
  * Webchat agent invocation surface (`runAgent`, `abortAgentRun`, `steer*`,
169
172
  * `submitClarifyResponse`, clarify-bridge dispatch). Owns the
@@ -187,14 +190,27 @@ var GatewayService = class {
187
190
  marketplace;
188
191
  /** First-class project grouping surface. */
189
192
  projects;
193
+ workItems;
190
194
  /** Local user-created apps, their coder projects, previews, and installs. */
191
195
  localApps;
196
+ /** Unified durable event spine for proactive scenarios. */
197
+ proactiveScenarios = new ProactiveScenarioService();
198
+ proactive = new ProactiveEventService(() => this.proactiveScenarios.routes());
199
+ proactiveInbox = new ProactiveInboxService();
200
+ proactiveInsights = listInsights;
201
+ proactiveWorker;
202
+ proactiveInboxWorker;
192
203
  constructor(serviceConfig = {}) {
193
204
  this.serviceConfig = serviceConfig;
194
205
  this.bus = new MessageBus();
195
206
  this.configPath = serviceConfig.configPath || resolveConfigPath();
196
207
  runBootstrapMigrationsSync(this.configPath);
197
208
  this.config = loadConfig(this.configPath);
209
+ this.proactiveWorker = new ProactiveWorker(new ReadonlyProactiveAgentExecutor(() => this.config));
210
+ this.proactiveInboxWorker = new ProactiveInboxWorker({ deliver: async ({ inboxItem }) => {
211
+ this.sse.emit("proactive.inbox.created", inboxItem);
212
+ await this.createMobileNotificationService().deliverGatewayEvent("proactive.inbox.created", inboxItem);
213
+ } });
198
214
  let bootstrapConfigChanged = initializeVoiceDefaults(this.config, inferProductLanguageFromEnvironment());
199
215
  const starterResult = ensureStarterAgentsInitialized(this.config);
200
216
  if (starterResult.changed) {
@@ -248,9 +264,10 @@ var GatewayService = class {
248
264
  this.workspacePath = getWorkspacePath(this.config) || "./workspace";
249
265
  this.initializeExtensionLoader();
250
266
  this.sessionIndex = new SessionIndex({ config: this.config });
251
- this.automationService = new AutomationService();
267
+ this.automationService = new AutomationService(this.proactive);
252
268
  this.notesService = new NotesService(new NotesStore());
253
- this.projects = new ProjectService();
269
+ this.projects = new ProjectService(void 0, this.proactive);
270
+ this.workItems = new WorkItemService(void 0, this.proactive);
254
271
  this.localApps = new LocalAppService({
255
272
  projects: this.projects,
256
273
  workspaceRoot: this.workspacePath,
@@ -343,7 +360,7 @@ var GatewayService = class {
343
360
  getBrowserRecipeService: () => this.browserRecipes,
344
361
  getNotesService: () => this.notesService,
345
362
  getProjectService: () => this.projects,
346
- getWorkItemService: () => new WorkItemService(),
363
+ getWorkItemService: () => this.workItems,
347
364
  getLocalAppService: () => this.localApps,
348
365
  getWorkflowRunService: () => this.createWorkflowRunService(),
349
366
  sourceContextResolver: async (binding) => {
@@ -357,7 +374,7 @@ var GatewayService = class {
357
374
  });
358
375
  }
359
376
  if (binding.kind === "work_item") {
360
- const item = new WorkItemService().getWorkItem(binding.sourceId);
377
+ const item = this.workItems.getWorkItem(binding.sourceId);
361
378
  return item ? await buildWorkItemAgentContext(item) : null;
362
379
  }
363
380
  return null;
@@ -613,6 +630,8 @@ var GatewayService = class {
613
630
  openXopcDatabase();
614
631
  this.startTime = Date.now();
615
632
  this.running = true;
633
+ this.proactiveWorker.start();
634
+ this.proactiveInboxWorker.start();
616
635
  prepareConfiguredLocalVoiceModel(this.config);
617
636
  this.startupTrace = createGatewayStartupTrace();
618
637
  this.readiness.markStarting(this.startTime);
@@ -706,7 +725,6 @@ var GatewayService = class {
706
725
  });
707
726
  await trace.measure("automations.initialize", () => this.automationService.initialize());
708
727
  await trace.measure("dreaming.reconcile", () => this.reconcileDreamingAutomations());
709
- this.stopFocusReconciler = startFocusReconciler(new FocusService(this.automationService));
710
728
  await this.notesService.initialize();
711
729
  this.ensureHeartbeatService().start(heartbeatRunnerConfigFromConfig(this.config));
712
730
  this.connectorSupervisor = startConnectorSupervisor({
@@ -831,6 +849,8 @@ var GatewayService = class {
831
849
  setPairingBroadcastSink(null);
832
850
  log.debug("Stopping gateway service...");
833
851
  this.readiness.markStarting();
852
+ await this.proactiveWorker.stop();
853
+ await this.proactiveInboxWorker.stop();
834
854
  await stopTailscaleExposure().catch((err) => {
835
855
  log.warn({ err }, "Tailscale exposure shutdown failed");
836
856
  });
@@ -866,8 +886,6 @@ var GatewayService = class {
866
886
  this.lastChannelConnectDeferMode = "auto";
867
887
  this.lastChannelConnectDeferSource = "off";
868
888
  await this.channelManager.stop();
869
- await this.stopFocusReconciler?.();
870
- this.stopFocusReconciler = null;
871
889
  await this.automationService.stop();
872
890
  this.stopAutomationProductEventBridge?.();
873
891
  this.stopAutomationProductEventBridge = null;
@@ -1272,25 +1290,7 @@ var GatewayService = class {
1272
1290
  this.createMobileNotificationService().handleGatewayEvent(type, payload);
1273
1291
  }
1274
1292
  handleAutomationRunCompleted(run) {
1275
- try {
1276
- const focusResult = processFocusMonitorRun(run);
1277
- this.emit("automation.run.completed", {
1278
- run,
1279
- silent: focusResult.handled
1280
- });
1281
- if (focusResult.handled) this.emit("focus.run.updated", {
1282
- automationId: run.automationId,
1283
- run
1284
- });
1285
- if (focusResult.insight) this.emit("focus.insight.created", { insight: focusResult.insight });
1286
- } catch (err) {
1287
- log.warn({
1288
- err,
1289
- automationId: run.automationId,
1290
- runId: run.id
1291
- }, "Proactive result processing failed");
1292
- this.emit("automation.run.completed", { run });
1293
- }
1293
+ this.emit("automation.run.completed", { run });
1294
1294
  }
1295
1295
  startAutomationProductEventBridge() {
1296
1296
  this.stopAutomationProductEventBridge?.();
@@ -1,5 +1,5 @@
1
- import { isGatewayArgv, parseProcCmdline } from "./gateway-process-argv.js";
2
1
  import { listPortListeners } from "../gateway/ports.js";
2
+ import { isGatewayArgv, parseProcCmdline } from "./gateway-process-argv.js";
3
3
  import fs from "node:fs";
4
4
  import { spawnSync } from "node:child_process";
5
5
  //#region src/infra/gateway-processes.ts
@@ -4,8 +4,8 @@ import { init_paths, resolveConfigPath } from "../config/paths.js";
4
4
  import { init_loader, loadConfig } from "../config/loader.js";
5
5
  import { isRestartEnabled } from "../config/commands.flags.js";
6
6
  import { resolveGatewayService } from "../daemon/service.js";
7
- import { findVerifiedGatewayListenerPidsOnPortSync, signalVerifiedGatewayPidSync } from "./gateway-processes.js";
8
7
  import { authorizeGatewaySigusr1Restart, writeGatewayRestartIntentSync } from "./restart.js";
8
+ import { findVerifiedGatewayListenerPidsOnPortSync, signalVerifiedGatewayPidSync } from "./gateway-processes.js";
9
9
  import { refreshGatewayServiceAfterUpdate } from "./update-service-refresh.js";
10
10
  //#region src/infra/update-restart.ts
11
11
  init_loader();
@@ -1,11 +1,11 @@
1
1
  import { runPostUpdateExtensionSync } from "../extensions/update.js";
2
+ import "./update-channels.js";
3
+ import { compareSemver, resolveNpmChannelTag } from "./update-check.js";
2
4
  import { readPackageName, readPackageVersion } from "./package-json.js";
3
5
  import { createDefaultCommandRunner, runCommandWithTimeout } from "./run-command.js";
4
6
  import { XOPC_PACKAGE_NAME, cleanupGlobalRenameDirs, createGlobalInstallEnv, detectGlobalInstallManagerForRoot, resolveGlobalInstallSpec, resolveGlobalInstallTarget } from "./update-global.js";
5
7
  import { runGlobalPackageUpdateSteps } from "./package-update-steps.js";
6
8
  import { resolveStableNodePath } from "./stable-node-path.js";
7
- import "./update-channels.js";
8
- import { compareSemver, resolveNpmChannelTag } from "./update-check.js";
9
9
  import { trimLogTail } from "./update-log.js";
10
10
  import { maybeRestartGatewayAfterUpdate } from "./update-restart.js";
11
11
  import path from "node:path";
@@ -3,9 +3,9 @@ import { init_paths_state, resolveUpdateCheckStatePath } from "../config/paths-s
3
3
  import { createLogger } from "../utils/logger/index.js";
4
4
  import { init_logger } from "../utils/logger.js";
5
5
  import { init_write_file_atomic, writeTextAtomic } from "./write-file-atomic.js";
6
+ import { acquireUpdateLock } from "./update-lock.js";
6
7
  import { normalizeUpdateChannel } from "./update-channels.js";
7
8
  import { compareSemver, detectInstallKind, resolveNpmChannelTag, resolvePackageRoot } from "./update-check.js";
8
- import { acquireUpdateLock } from "./update-lock.js";
9
9
  import { createHash, randomUUID } from "node:crypto";
10
10
  import { readFile } from "node:fs/promises";
11
11
  //#region src/infra/update-startup.ts
@@ -1,9 +1,9 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { init_loader, loadConfig } from "../config/loader.js";
4
+ import { gatewayCredentialAuthorization } from "../gateway/credential.js";
4
5
  import { loadUndiciRuntimeDeps } from "../infra/undici-fetch.js";
5
6
  import { toConversation } from "./channel-shared.js";
6
- import { gatewayCredentialAuthorization } from "../gateway/credential.js";
7
7
  import { createGatewayHttpClientFromConfig, resolveGatewayHttpBaseUrl } from "./gateway-http-client.js";
8
8
  //#region src/mcp/channel-bridge.ts
9
9
  init_loader();
@@ -4,5 +4,6 @@ export declare function mobileNotificationEventFromGatewayEvent(type: string, pa
4
4
  export declare class MobileNotificationService {
5
5
  private readonly sent;
6
6
  handleGatewayEvent(type: string, payload: unknown): void;
7
+ deliverGatewayEvent(type: string, payload: unknown): Promise<void>;
7
8
  private deliver;
8
9
  }
@@ -9,6 +9,7 @@ function shouldDeliver(type, preferences) {
9
9
  if (type === "goal.needs_input") return preferences.needsInput;
10
10
  if (type === "goal.blocked") return preferences.failed;
11
11
  if (type === "automation.failed") return preferences.automationFailed;
12
+ if (type === "proactive.insight") return preferences.needsInput;
12
13
  return preferences.completed;
13
14
  }
14
15
  function goalEvent(payload) {
@@ -66,10 +67,33 @@ function automationEvent(payload) {
66
67
  }
67
68
  };
68
69
  }
70
+ function proactiveInsightEvent(payload) {
71
+ if (!payload || typeof payload !== "object") return null;
72
+ const item = payload;
73
+ if (typeof item.id !== "string" || typeof item.insight?.id !== "string" || typeof item.insight.title !== "string") return null;
74
+ const route = `/inbox?item=${encodeURIComponent(item.id)}`;
75
+ return {
76
+ type: "proactive.insight",
77
+ entity: {
78
+ kind: "insight",
79
+ id: item.insight.id
80
+ },
81
+ priority: item.insight.urgency === "high" || item.insight.urgency === "critical" ? "high" : "normal",
82
+ title: item.insight.title.slice(0, 120),
83
+ body: typeof item.insight.summary === "string" ? item.insight.summary.slice(0, 180) : void 0,
84
+ deepLink: route,
85
+ payload: {
86
+ route,
87
+ inboxItemId: item.id,
88
+ eventType: "proactive.insight"
89
+ }
90
+ };
91
+ }
69
92
  /** Converts gateway domain events into a portable mobile activity and push payload. */
70
93
  function mobileNotificationEventFromGatewayEvent(type, payload) {
71
94
  if (type === "goal.status.updated") return goalEvent(payload);
72
95
  if (type === "automation.run.completed") return automationEvent(payload);
96
+ if (type === "proactive.inbox.created") return proactiveInsightEvent(payload);
73
97
  return null;
74
98
  }
75
99
  async function sendExpoPush(token, event) {
@@ -105,33 +129,29 @@ async function sendExpoPush(token, event) {
105
129
  var MobileNotificationService = class {
106
130
  sent = /* @__PURE__ */ new Set();
107
131
  handleGatewayEvent(type, payload) {
132
+ this.deliverGatewayEvent(type, payload).catch((err) => {
133
+ log.warn({
134
+ err,
135
+ eventType: type
136
+ }, "Mobile notification delivery failed");
137
+ });
138
+ }
139
+ async deliverGatewayEvent(type, payload) {
108
140
  const event = mobileNotificationEventFromGatewayEvent(type, payload);
109
141
  if (!event) return;
110
142
  const dedupeKey = `${event.type}:${event.entity.kind}:${event.entity.id}:${JSON.stringify(event.payload)}`;
111
143
  if (this.sent.has(dedupeKey)) return;
112
144
  this.sent.add(dedupeKey);
113
- this.deliver(event).catch((err) => {
114
- log.warn({
115
- err,
116
- eventType: event.type,
117
- entityId: event.entity.id
118
- }, "Mobile notification delivery failed");
119
- }).finally(() => this.sent.delete(dedupeKey));
145
+ try {
146
+ await this.deliver(event);
147
+ } finally {
148
+ this.sent.delete(dedupeKey);
149
+ }
120
150
  }
121
151
  async deliver(input) {
122
152
  const event = createMobileActivityEvent(input);
123
153
  const devices = listEnabledMobileDevices().filter((device) => shouldDeliver(event.type, device.preferences));
124
- await Promise.all(devices.map(async (device) => {
125
- try {
126
- await sendExpoPush(device.pushToken, event);
127
- } catch (err) {
128
- log.warn({
129
- err,
130
- eventId: event.id,
131
- deviceId: device.id
132
- }, "Mobile push request failed");
133
- }
134
- }));
154
+ await Promise.all(devices.map((device) => sendExpoPush(device.pushToken, event)));
135
155
  }
136
156
  };
137
157
  //#endregion
@@ -1,7 +1,7 @@
1
1
  export type MobilePlatform = 'ios' | 'android';
2
2
  export type MobileNotificationPermission = 'granted' | 'denied' | 'unknown';
3
3
  export type MobileNotificationPriority = 'normal' | 'high';
4
- export type MobileNotificationEventType = 'goal.needs_input' | 'goal.blocked' | 'goal.completed' | 'automation.failed' | 'automation.completed';
4
+ export type MobileNotificationEventType = 'goal.needs_input' | 'goal.blocked' | 'goal.completed' | 'automation.failed' | 'automation.completed' | 'proactive.insight';
5
5
  export type MobileNotificationPreferences = {
6
6
  needsInput: boolean;
7
7
  failed: boolean;
@@ -24,7 +24,7 @@ export type MobileActivityEvent = {
24
24
  id: string;
25
25
  type: MobileNotificationEventType;
26
26
  entity: {
27
- kind: 'goal' | 'automation';
27
+ kind: 'goal' | 'automation' | 'insight';
28
28
  id: string;
29
29
  };
30
30
  priority: MobileNotificationPriority;
@@ -0,0 +1,2 @@
1
+ import { type EventEnvelope, type PublishEventInput } from './types.js';
2
+ export declare function normalizeEventEnvelope(input: PublishEventInput, now?: Date): EventEnvelope;
@@ -0,0 +1,54 @@
1
+ import { EVENT_ACTOR_KINDS, EVENT_SENSITIVITIES } from "./types.js";
2
+ import { randomUUID } from "node:crypto";
3
+ //#region src/proactive/events/envelope.ts
4
+ const EVENT_TYPE_PATTERN = /^[a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)+\.v[1-9][0-9]*$/;
5
+ function required(value, field) {
6
+ const normalized = value.trim();
7
+ if (!normalized) throw new Error(`${field} is required`);
8
+ if (normalized.length > 300) throw new Error(`${field} is too long`);
9
+ return normalized;
10
+ }
11
+ function timestamp(value, field) {
12
+ const time = Date.parse(value);
13
+ if (!Number.isFinite(time)) throw new Error(`${field} must be an ISO timestamp`);
14
+ return new Date(time).toISOString();
15
+ }
16
+ function normalizeEventEnvelope(input, now = /* @__PURE__ */ new Date()) {
17
+ if (!EVENT_TYPE_PATTERN.test(input.type)) throw new Error("type must use the domain.event.vN convention");
18
+ if (!Number.isInteger(input.schemaVersion) || input.schemaVersion < 1) throw new Error("schemaVersion must be a positive integer");
19
+ if (!EVENT_ACTOR_KINDS.includes(input.actor.kind)) throw new Error("actor.kind is invalid");
20
+ if (!EVENT_SENSITIVITIES.includes(input.sensitivity)) throw new Error("sensitivity is invalid");
21
+ if (!input.payload || Array.isArray(input.payload) || typeof input.payload !== "object") throw new Error("payload must be an object");
22
+ return {
23
+ id: required(input.id ?? randomUUID(), "id"),
24
+ type: input.type,
25
+ schemaVersion: input.schemaVersion,
26
+ source: {
27
+ kind: required(input.source.kind, "source.kind"),
28
+ id: required(input.source.id, "source.id"),
29
+ ...input.source.deviceId ? { deviceId: required(input.source.deviceId, "source.deviceId") } : {}
30
+ },
31
+ subject: {
32
+ kind: required(input.subject.kind, "subject.kind"),
33
+ id: required(input.subject.id, "subject.id")
34
+ },
35
+ actor: {
36
+ kind: input.actor.kind,
37
+ ...input.actor.id ? { id: required(input.actor.id, "actor.id") } : {}
38
+ },
39
+ scope: {
40
+ workspaceId: required(input.scope.workspaceId, "scope.workspaceId"),
41
+ ...input.scope.projectId ? { projectId: required(input.scope.projectId, "scope.projectId") } : {},
42
+ ...input.scope.agentId ? { agentId: required(input.scope.agentId, "scope.agentId") } : {}
43
+ },
44
+ occurredAt: timestamp(input.occurredAt, "occurredAt"),
45
+ observedAt: timestamp(input.observedAt ?? now.toISOString(), "observedAt"),
46
+ correlationId: required(input.correlationId ?? randomUUID(), "correlationId"),
47
+ ...input.causationId ? { causationId: required(input.causationId, "causationId") } : {},
48
+ dedupeKey: required(input.dedupeKey, "dedupeKey"),
49
+ sensitivity: input.sensitivity,
50
+ payload: input.payload
51
+ };
52
+ }
53
+ //#endregion
54
+ export { normalizeEventEnvelope };
@@ -0,0 +1,4 @@
1
+ import type { PublishEventInput, PublishedEvent } from './types.js';
2
+ export interface ProactiveSignalPublisher {
3
+ publish(input: PublishEventInput, observedAt?: Date): PublishedEvent;
4
+ }
@@ -0,0 +1,9 @@
1
+ import type { EventEnvelope } from './types.js';
2
+ export declare function getEventByDedupeKey(dedupeKey: string): EventEnvelope | null;
3
+ export declare function insertEvent(event: EventEnvelope): boolean;
4
+ export declare function isEventRouted(eventId: string): boolean;
5
+ export declare function markEventRouted(eventId: string, routedAt: string): void;
6
+ export declare function listEvents(input?: {
7
+ limit?: number;
8
+ type?: string;
9
+ }): EventEnvelope[];
@@ -0,0 +1,62 @@
1
+ import { getSqliteDatabase, runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
2
+ //#region src/proactive/events/repository.ts
3
+ function fromRow(row) {
4
+ return {
5
+ id: row.event_id,
6
+ type: row.type,
7
+ schemaVersion: row.schema_version,
8
+ source: {
9
+ kind: row.source_kind,
10
+ id: row.source_id,
11
+ ...row.device_id ? { deviceId: row.device_id } : {}
12
+ },
13
+ subject: {
14
+ kind: row.subject_kind,
15
+ id: row.subject_id
16
+ },
17
+ actor: {
18
+ kind: row.actor_kind,
19
+ ...row.actor_id ? { id: row.actor_id } : {}
20
+ },
21
+ scope: {
22
+ workspaceId: row.workspace_id,
23
+ ...row.project_id ? { projectId: row.project_id } : {},
24
+ ...row.agent_id ? { agentId: row.agent_id } : {}
25
+ },
26
+ occurredAt: row.occurred_at,
27
+ observedAt: row.observed_at,
28
+ correlationId: row.correlation_id,
29
+ ...row.causation_id ? { causationId: row.causation_id } : {},
30
+ dedupeKey: row.dedupe_key,
31
+ sensitivity: row.sensitivity,
32
+ payload: JSON.parse(row.payload_json)
33
+ };
34
+ }
35
+ function getEventByDedupeKey(dedupeKey) {
36
+ const row = getSqliteDatabase().prepare("SELECT * FROM proactive_events WHERE dedupe_key = ?").get(dedupeKey);
37
+ return row ? fromRow(row) : null;
38
+ }
39
+ function insertEvent(event) {
40
+ return runSqliteWriteTransaction((db) => {
41
+ return db.prepare(`INSERT OR IGNORE INTO proactive_events (
42
+ event_id, type, schema_version, source_kind, source_id, device_id,
43
+ subject_kind, subject_id, actor_kind, actor_id, workspace_id, project_id, agent_id,
44
+ occurred_at, observed_at, correlation_id, causation_id, dedupe_key, sensitivity, payload_json
45
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(event.id, event.type, event.schemaVersion, event.source.kind, event.source.id, event.source.deviceId ?? null, event.subject.kind, event.subject.id, event.actor.kind, event.actor.id ?? null, event.scope.workspaceId, event.scope.projectId ?? null, event.scope.agentId ?? null, event.occurredAt, event.observedAt, event.correlationId, event.causationId ?? null, event.dedupeKey, event.sensitivity, JSON.stringify(event.payload)).changes === 1;
46
+ });
47
+ }
48
+ function isEventRouted(eventId) {
49
+ const row = getSqliteDatabase().prepare("SELECT routed_at FROM proactive_events WHERE event_id = ?").get(eventId);
50
+ return Boolean(row?.routed_at);
51
+ }
52
+ function markEventRouted(eventId, routedAt) {
53
+ runSqliteWriteTransaction((db) => {
54
+ db.prepare("UPDATE proactive_events SET routed_at = COALESCE(routed_at, ?) WHERE event_id = ?").run(routedAt, eventId);
55
+ });
56
+ }
57
+ function listEvents(input = {}) {
58
+ const limit = Math.min(200, Math.max(1, input.limit ?? 50));
59
+ return (input.type ? getSqliteDatabase().prepare("SELECT * FROM proactive_events WHERE type = ? ORDER BY observed_at DESC LIMIT ?").all(input.type, limit) : getSqliteDatabase().prepare("SELECT * FROM proactive_events ORDER BY observed_at DESC LIMIT ?").all(limit)).map(fromRow);
60
+ }
61
+ //#endregion
62
+ export { getEventByDedupeKey, insertEvent, isEventRouted, listEvents, markEventRouted };
@@ -0,0 +1,44 @@
1
+ export declare const EVENT_SENSITIVITIES: readonly ["public", "personal", "confidential", "restricted"];
2
+ export type EventSensitivity = (typeof EVENT_SENSITIVITIES)[number];
3
+ export declare const EVENT_ACTOR_KINDS: readonly ["user", "agent", "system", "integration"];
4
+ export type EventActorKind = (typeof EVENT_ACTOR_KINDS)[number];
5
+ export interface EventEnvelope<TPayload extends Record<string, unknown> = Record<string, unknown>> {
6
+ id: string;
7
+ type: string;
8
+ schemaVersion: number;
9
+ source: {
10
+ kind: string;
11
+ id: string;
12
+ deviceId?: string;
13
+ };
14
+ subject: {
15
+ kind: string;
16
+ id: string;
17
+ };
18
+ actor: {
19
+ kind: EventActorKind;
20
+ id?: string;
21
+ };
22
+ scope: {
23
+ workspaceId: string;
24
+ projectId?: string;
25
+ agentId?: string;
26
+ };
27
+ occurredAt: string;
28
+ observedAt: string;
29
+ correlationId: string;
30
+ causationId?: string;
31
+ dedupeKey: string;
32
+ sensitivity: EventSensitivity;
33
+ payload: TPayload;
34
+ }
35
+ export type PublishEventInput<TPayload extends Record<string, unknown> = Record<string, unknown>> = Omit<EventEnvelope<TPayload>, 'id' | 'observedAt' | 'correlationId'> & {
36
+ id?: string;
37
+ observedAt?: string;
38
+ correlationId?: string;
39
+ };
40
+ export interface PublishedEvent {
41
+ event: EventEnvelope;
42
+ inserted: boolean;
43
+ batchIds: string[];
44
+ }
@@ -0,0 +1,15 @@
1
+ //#region src/proactive/events/types.ts
2
+ const EVENT_SENSITIVITIES = [
3
+ "public",
4
+ "personal",
5
+ "confidential",
6
+ "restricted"
7
+ ];
8
+ const EVENT_ACTOR_KINDS = [
9
+ "user",
10
+ "agent",
11
+ "system",
12
+ "integration"
13
+ ];
14
+ //#endregion
15
+ export { EVENT_ACTOR_KINDS, EVENT_SENSITIVITIES };
@@ -0,0 +1,16 @@
1
+ import type { Config } from '../../config/schema.js';
2
+ import type { ProactiveAgentExecutor } from './types.js';
3
+ /** Runs an isolated, read-only agent over only the context authorized by the signal batch. */
4
+ export declare class ReadonlyProactiveAgentExecutor implements ProactiveAgentExecutor {
5
+ private readonly config;
6
+ constructor(config: () => Config | undefined);
7
+ execute(input: {
8
+ systemPrompt: string;
9
+ userPrompt: string;
10
+ authorizedContext: Record<string, unknown>;
11
+ signal?: AbortSignal;
12
+ }): Promise<{
13
+ text: string;
14
+ modelRef: string;
15
+ }>;
16
+ }
@@ -0,0 +1,104 @@
1
+ import { init_sync_provider_auth, resolveProviderApiKeySync } from "../../auth/sync-provider-auth.js";
2
+ import { getApiKeySync, getDefaultModelSync, init_providers, resolveModel } from "../../providers/index.js";
3
+ import { createExtensionAwareStreamFn } from "../../providers/extension-stream-bridge.js";
4
+ import { runAgentTurnWithTimeout } from "../../agent/orchestration/run-agent-turn-with-timeout.js";
5
+ import { isAssistantTurnAborted, isAssistantTurnFailed } from "../../agent/orchestration/llm-turn-retry.js";
6
+ import { Agent } from "@earendil-works/pi-agent-core";
7
+ import { Type } from "@sinclair/typebox";
8
+ //#region src/proactive/execution/agent-executor.ts
9
+ init_sync_provider_auth();
10
+ init_providers();
11
+ const MAX_TOOL_CALLS = 6;
12
+ const AGENT_TIMEOUT_MS = 9e4;
13
+ function assistantText(messages) {
14
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
15
+ const message = messages[index];
16
+ if (message.role !== "assistant") continue;
17
+ if (Array.isArray(message.content)) return message.content.flatMap((block) => block && typeof block === "object" && block.type === "text" ? [String(block.text ?? "")] : []).join("").trim();
18
+ }
19
+ return "";
20
+ }
21
+ function inspectionTool(context) {
22
+ return {
23
+ name: "inspect_authorized_context",
24
+ label: "Inspect authorized work context",
25
+ description: "Read one authorized evidence section. This tool cannot write or trigger any action.",
26
+ parameters: Type.Object({ section: Type.String({ description: "A top-level section name from the availableSections list." }) }),
27
+ async execute(_toolCallId, args) {
28
+ const values = args;
29
+ const section = typeof values.section === "string" ? values.section : "";
30
+ if (!Object.prototype.hasOwnProperty.call(context, section)) return {
31
+ content: [{
32
+ type: "text",
33
+ text: `Unknown section. Available: ${Object.keys(context).join(", ")}`
34
+ }],
35
+ details: { found: false }
36
+ };
37
+ return {
38
+ content: [{
39
+ type: "text",
40
+ text: JSON.stringify({
41
+ section,
42
+ evidence: context[section]
43
+ }, null, 2).slice(0, 6e4)
44
+ }],
45
+ details: {
46
+ found: true,
47
+ section
48
+ }
49
+ };
50
+ }
51
+ };
52
+ }
53
+ /** Runs an isolated, read-only agent over only the context authorized by the signal batch. */
54
+ var ReadonlyProactiveAgentExecutor = class {
55
+ constructor(config) {
56
+ this.config = config;
57
+ }
58
+ async execute(input) {
59
+ const model = resolveModel(getDefaultModelSync(this.config()));
60
+ let toolCalls = 0;
61
+ const agent = new Agent({
62
+ initialState: {
63
+ systemPrompt: `${input.systemPrompt}\n\nYou are an autonomous background analysis agent. You MUST inspect relevant authorized context with the provided read-only tool before reaching a conclusion. You have no mutation, messaging, shell, network, or filesystem tools.`,
64
+ model,
65
+ thinkingLevel: "low",
66
+ tools: [inspectionTool(input.authorizedContext)],
67
+ messages: []
68
+ },
69
+ streamFn: createExtensionAwareStreamFn(),
70
+ getApiKey: (provider) => resolveProviderApiKeySync(provider) ?? getApiKeySync(provider) ?? "",
71
+ beforeToolCall: async () => {
72
+ if (toolCalls >= MAX_TOOL_CALLS) return {
73
+ block: true,
74
+ reason: `Maximum inspection calls reached (${MAX_TOOL_CALLS}).`
75
+ };
76
+ },
77
+ afterToolCall: async () => {
78
+ toolCalls += 1;
79
+ }
80
+ });
81
+ const abort = () => agent.abort();
82
+ input.signal?.addEventListener("abort", abort, { once: true });
83
+ try {
84
+ const sections = Object.keys(input.authorizedContext);
85
+ await runAgentTurnWithTimeout(agent, async () => {
86
+ await agent.prompt(`${input.userPrompt}\n\nAvailable authorized evidence sections: ${sections.join(", ") || "(none)"}.`);
87
+ await agent.waitForIdle();
88
+ }, AGENT_TIMEOUT_MS);
89
+ if (isAssistantTurnAborted(agent)) throw new Error("Proactive agent execution aborted");
90
+ if (isAssistantTurnFailed(agent)) throw new Error("Proactive agent execution failed");
91
+ const text = assistantText(agent.state.messages);
92
+ if (!text) throw new Error("Proactive agent returned empty output");
93
+ if (toolCalls === 0) throw new Error("Proactive agent did not inspect authorized evidence");
94
+ return {
95
+ text,
96
+ modelRef: `${model.provider}/${model.id}`
97
+ };
98
+ } finally {
99
+ input.signal?.removeEventListener("abort", abort);
100
+ }
101
+ }
102
+ };
103
+ //#endregion
104
+ export { ReadonlyProactiveAgentExecutor };