@xopcai/xopc 0.0.269 → 0.0.270

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 (204) 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-DcwCSY6s.js → activity-store-D_0FmdRj.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-D0NBOWC4.js → agent-avatar-dicebear-IZvEXak_.js} +1 -1
  5. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CE3ygr3l.js +1 -0
  6. package/dist/gateway/static/root/assets/agents-DzG2qw-c.js +1 -0
  7. package/dist/gateway/static/root/assets/{api-eaPO-mdr.js → api-O3TTQ4qN.js} +1 -1
  8. package/dist/gateway/static/root/assets/{app-management-settings-panel-E3xm2teY.js → app-management-settings-panel-Cqqsbzri.js} +1 -1
  9. package/dist/gateway/static/root/assets/{appearance-settings-CiZOjgls.js → appearance-settings-DaJyf32s.js} +1 -1
  10. package/dist/gateway/static/root/assets/apps-page-B4lX6yoT.js +1 -0
  11. package/dist/gateway/static/root/assets/{archive-plugin-D09yo_Hc.js → archive-plugin-kDPnDTJI.js} +1 -1
  12. package/dist/gateway/static/root/assets/{attachment-load-CNYb8Qru.js → attachment-load-CJ3VceKS.js} +1 -1
  13. package/dist/gateway/static/root/assets/{automations-page-DsrfW5ii.js → automations-page-JwMtU8XB.js} +1 -1
  14. package/dist/gateway/static/root/assets/automations-workspace-BiNBewg0.js +6 -0
  15. package/dist/gateway/static/root/assets/{binary-plugins-OWlaGqlY.js → binary-plugins-DzyZXLBX.js} +1 -1
  16. package/dist/gateway/static/root/assets/{block-editor-CVND3M6r.js → block-editor-kTt3gYIJ.js} +3 -3
  17. package/dist/gateway/static/root/assets/{browser-automation-inputs-D7IzVK_J.js → browser-automation-inputs-BKohPYR4.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-automations-page-CQ6cCpIv.js → browser-automations-page-ktQfFPk-.js} +2 -2
  19. package/dist/gateway/static/root/assets/browser-settings-page-Dgdt5uVL.js +8 -0
  20. package/dist/gateway/static/root/assets/capabilities-settings-panel-BpDW-R9f.js +7 -0
  21. package/dist/gateway/static/root/assets/channels-settings-DU4EQnR0.js +1 -0
  22. package/dist/gateway/static/root/assets/{channels-status-swr-D4JrgJKa.js → channels-status-swr-DrqzYmDr.js} +1 -1
  23. package/dist/gateway/static/root/assets/{chat-terminal-dock-BUjnhT7C.js → chat-terminal-dock-CIFGGLGa.js} +2 -2
  24. package/dist/gateway/static/root/assets/connectors-page-CfJqy284.js +2 -0
  25. package/dist/gateway/static/root/assets/{cron-expression-DlyRIyUn.js → cron-expression-BNwbnrEb.js} +1 -1
  26. package/dist/gateway/static/root/assets/{date-picker-CU-ij_yE.js → date-picker-DKyirU4K.js} +1 -1
  27. package/dist/gateway/static/root/assets/{dependency-picker-Z6Nf0Wjq.js → dependency-picker-D3vNIjRI.js} +1 -1
  28. package/dist/gateway/static/root/assets/{desktop-pet-C0F5Iqnc.js → desktop-pet-fQwRb_3p.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-settings-Bj_W6HL1.js → desktop-pet-settings-DfOJ-GvT.js} +1 -1
  30. package/dist/gateway/static/root/assets/{extension-debug-page-Ba09EnAn.js → extension-debug-page-Cn53jB5-.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-page-C88aGXJs.js → extension-page-IDpLCxpC.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-settings-page-CMyt0A32.js → extension-settings-page-B1dds2bP.js} +1 -1
  33. package/dist/gateway/static/root/assets/{gateway-config-swr-bjzk_4hn.js → gateway-config-swr-B7dcmP7Q.js} +1 -1
  34. package/dist/gateway/static/root/assets/gateway-settings-pp9jN0wl.js +1 -0
  35. package/dist/gateway/static/root/assets/{gateway-startup-retry-DrbIzFyB.js → gateway-startup-retry-JGhGMhVZ.js} +1 -1
  36. package/dist/gateway/static/root/assets/{heartbeat-settings-BnrMRKaZ.js → heartbeat-settings-B8_zTyev.js} +1 -1
  37. package/dist/gateway/static/root/assets/home-page-g1KdAdLb.js +1 -0
  38. package/dist/gateway/static/root/assets/{image-generation-api-CBWU9Ner.js → image-generation-api-BJLX7Qrh.js} +1 -1
  39. package/dist/gateway/static/root/assets/index-1zRt56Zt.css +2 -0
  40. package/dist/gateway/static/root/assets/{index-CfyyA9-g.js → index-OMnem2nr.js} +47 -47
  41. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-B8Z7kKQY.js → keyboard-shortcuts-settings-CBvMTFFx.js} +1 -1
  42. package/dist/gateway/static/root/assets/local-app-workbench-page-bj75v2ZE.js +2 -0
  43. package/dist/gateway/static/root/assets/{local-apps-page-CLSfzkRp.js → local-apps-page-APCMNDvU.js} +1 -1
  44. package/dist/gateway/static/root/assets/{locale-store-BQ2HKTWb.js → locale-store-BThkG0W5.js} +1 -1
  45. package/dist/gateway/static/root/assets/{logs-page-CWDU1AGN.js → logs-page-BX7n39zV.js} +2 -2
  46. package/dist/gateway/static/root/assets/{management-settings-CuFNgQUy.js → management-settings-CM62j8ZX.js} +1 -1
  47. package/dist/gateway/static/root/assets/{markdown-view-DIcfrLmG.js → markdown-view-BwjpJVPs.js} +1 -1
  48. package/dist/gateway/static/root/assets/{media-plugins-CSv6-xTA.js → media-plugins-C10byeaa.js} +1 -1
  49. package/dist/gateway/static/root/assets/{messages-BRjoarIr.js → messages-D0V_bgRP.js} +2 -2
  50. package/dist/gateway/static/root/assets/{mobile-pairing-wizard-C7d_ztgp.js → mobile-pairing-wizard-BCWfwVx3.js} +1 -1
  51. package/dist/gateway/static/root/assets/note-detail-panel-koOqb0gX.js +5 -0
  52. package/dist/gateway/static/root/assets/notes-page-BH54rY3B.js +8 -0
  53. package/dist/gateway/static/root/assets/{page-tabs-BfV-PQa5.js → page-tabs-qQ36zncF.js} +1 -1
  54. package/dist/gateway/static/root/assets/{preview-open-alternatives-DQS7NFpg.js → preview-open-alternatives-BiAJvvCo.js} +1 -1
  55. package/dist/gateway/static/root/assets/proactive-card-CcNBqHoH.js +1 -0
  56. package/dist/gateway/static/root/assets/proactive-page-C3K61jve.js +1 -0
  57. package/dist/gateway/static/root/assets/{product-open-page-BIhjZLKg.js → product-open-page-CunnDP4w.js} +1 -1
  58. package/dist/gateway/static/root/assets/project-detail-page-SL2g8MZY.js +1 -0
  59. package/dist/gateway/static/root/assets/projects-page-BtxazT5J.js +1 -0
  60. package/dist/gateway/static/root/assets/{registry-api-CwveUfe8.js → registry-api-0JSegbNl.js} +1 -1
  61. package/dist/gateway/static/root/assets/remote-access-hub-BSb7b67A.js +1 -0
  62. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DMQ0wpNg.js → runtime-tools-settings-panel-bu_mwBTr.js} +2 -2
  63. package/dist/gateway/static/root/assets/{schema-form-C91g2PRU.js → schema-form-BE0sgZyz.js} +1 -1
  64. package/dist/gateway/static/root/assets/sessions-page-ljcS2KVz.js +1 -0
  65. package/dist/gateway/static/root/assets/settings-advanced-gate-CR9Y9LQm.js +1 -0
  66. package/dist/gateway/static/root/assets/{settings-form-section-Cem6L49Y.js → settings-form-section-CBo517lV.js} +1 -1
  67. package/dist/gateway/static/root/assets/{settings-page-afDUxqlV.js → settings-page-DBPimx93.js} +1 -1
  68. package/dist/gateway/static/root/assets/{setup-status-panel-Cc_iP_vv.js → setup-status-panel-J3AnooPW.js} +1 -1
  69. package/dist/gateway/static/root/assets/{share-preview-page-CVEVHksg.js → share-preview-page-DdV75VTe.js} +1 -1
  70. package/dist/gateway/static/root/assets/shares-settings-AAm4Iwcp.js +1 -0
  71. package/dist/gateway/static/root/assets/skill-reload-api-pRCjP5sm.js +1 -0
  72. package/dist/gateway/static/root/assets/{skills-page-CNrq1W6C.js → skills-page-Cn_-nvRo.js} +1 -1
  73. package/dist/gateway/static/root/assets/{skills-page.utils-D1wGfm22.js → skills-page.utils-CfVAc_lu.js} +1 -1
  74. package/dist/gateway/static/root/assets/{system-settings-panel-BLE8PxWE.js → system-settings-panel-B-pzalp-.js} +1 -1
  75. package/dist/gateway/static/root/assets/task-detail-page-CmrLy3PO.js +1 -0
  76. package/dist/gateway/static/root/assets/{theme-store-BejLVjIT.js → theme-store-1wryLgBQ.js} +1 -1
  77. package/dist/gateway/static/root/assets/{tunnel-api-Dur80zSQ.js → tunnel-api-Cgpnm2fL.js} +1 -1
  78. package/dist/gateway/static/root/assets/{use-autosave-DmgEA8Qb.js → use-autosave-N_lm4FdD.js} +1 -1
  79. package/dist/gateway/static/root/assets/user-model-page-u3QLDX6L.js +2 -0
  80. package/dist/gateway/static/root/assets/{voice-api-key-field-sZ0J83SF.js → voice-api-key-field-DMsyVfri.js} +1 -1
  81. package/dist/gateway/static/root/assets/{voice-config-api-BEbz3avx.js → voice-config-api-QWVmiAp3.js} +1 -1
  82. package/dist/gateway/static/root/assets/{work-discovery-overlay-BXnAlbmO.js → work-discovery-overlay-BC0vAxp1.js} +1 -1
  83. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BkwFey0a.js → workflow-run-setup-panel-Cz9jQIlP.js} +2 -2
  84. package/dist/gateway/static/root/assets/workflows-page-DA6OOK6X.js +6 -0
  85. package/dist/gateway/static/root/index.html +10 -10
  86. package/dist/package.js +1 -1
  87. package/dist/packages/gateway-contract/src/notifications.js +2 -2
  88. package/dist/packages/gateway-contract/src/proactive.js +22 -6
  89. package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
  90. package/dist/src/agent/tool-manuals/xopc-use.js +19 -1
  91. package/dist/src/agent/tools/factory.js +1 -0
  92. package/dist/src/agent/tools/xopc-use-tool.d.ts +3 -2
  93. package/dist/src/agent/tools/xopc-use-tool.js +48 -4
  94. package/dist/src/browser/automations/schema.d.ts +1 -1
  95. package/dist/src/browser/automations/service.d.ts +1 -1
  96. package/dist/src/cli/bin.js +2 -2
  97. package/dist/src/cli/commands/agent.js +2 -2
  98. package/dist/src/cli/commands/auth.js +1 -1
  99. package/dist/src/cli/commands/connectors.js +1 -1
  100. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  101. package/dist/src/cli/commands/extension-dev.js +1 -1
  102. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  103. package/dist/src/cli/commands/extension.js +1 -1
  104. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  105. package/dist/src/cli/commands/gateway-ssh-tunnel.js +1 -1
  106. package/dist/src/cli/commands/models.js +2 -2
  107. package/dist/src/cli/commands/onboard.js +1 -1
  108. package/dist/src/cli/commands/platform.js +1 -1
  109. package/dist/src/cli/commands/profile.js +1 -1
  110. package/dist/src/cli/commands/tunnel.js +1 -1
  111. package/dist/src/cli/commands/update.js +1 -1
  112. package/dist/src/cli/extension-cli-register.js +1 -1
  113. package/dist/src/config/index.js +1 -1
  114. package/dist/src/connectors/connected-source-ingestion.js +1 -1
  115. package/dist/src/connectors/connected-source-normalizers.js +3 -0
  116. package/dist/src/connectors/connection-recovery-service.js +1 -1
  117. package/dist/src/connectors/health.js +1 -1
  118. package/dist/src/gateway/hono/routes/capabilities.js +1 -1
  119. package/dist/src/gateway/hono/routes/connectors.js +1 -1
  120. package/dist/src/gateway/hono/routes/mcp.js +1 -1
  121. package/dist/src/gateway/hono/routes/proactive-control.js +31 -24
  122. package/dist/src/gateway/run-loop.js +1 -1
  123. package/dist/src/gateway/server.js +1 -1
  124. package/dist/src/gateway/service.js +10 -10
  125. package/dist/src/notifications/web-push.js +1 -1
  126. package/dist/src/proactive/actions/service.js +4 -2
  127. package/dist/src/proactive/execution/authorization.d.ts +2 -0
  128. package/dist/src/proactive/execution/authorization.js +39 -1
  129. package/dist/src/proactive/execution/context.d.ts +4 -0
  130. package/dist/src/proactive/execution/context.js +51 -5
  131. package/dist/src/proactive/execution/insight.js +3 -1
  132. package/dist/src/proactive/execution/repository.js +15 -5
  133. package/dist/src/proactive/execution/types.d.ts +2 -0
  134. package/dist/src/proactive/execution/worker.js +7 -2
  135. package/dist/src/proactive/experience.d.ts +69 -0
  136. package/dist/src/proactive/experience.js +90 -0
  137. package/dist/src/proactive/follow-ups.d.ts +123 -0
  138. package/dist/src/proactive/follow-ups.js +169 -0
  139. package/dist/src/proactive/inbox/cards.js +35 -6
  140. package/dist/src/proactive/inbox/delivery.js +4 -2
  141. package/dist/src/proactive/inbox/digest.js +2 -2
  142. package/dist/src/proactive/inbox/lifecycle.js +4 -1
  143. package/dist/src/proactive/inbox/notification-policy.js +4 -2
  144. package/dist/src/proactive/inbox/repository.js +17 -11
  145. package/dist/src/proactive/inbox/types.d.ts +2 -0
  146. package/dist/src/proactive/inbox/worker.js +1 -1
  147. package/dist/src/proactive/index.js +2 -2
  148. package/dist/src/proactive/mail-thread.d.ts +13 -0
  149. package/dist/src/proactive/mail-thread.js +54 -0
  150. package/dist/src/proactive/policy/service.d.ts +2 -4
  151. package/dist/src/proactive/policy/service.js +3 -5
  152. package/dist/src/proactive/scenarios/control.d.ts +4 -7
  153. package/dist/src/proactive/scenarios/control.js +3 -4
  154. package/dist/src/proactive/scenarios/preview.js +1 -1
  155. package/dist/src/proactive/scenarios/prompt-composer.js +2 -0
  156. package/dist/src/proactive/service.js +1 -1
  157. package/dist/src/proactive/temporal/worker.d.ts +1 -0
  158. package/dist/src/proactive/temporal/worker.js +18 -4
  159. package/dist/src/storage/sqlite/migrations/162_proactive_product.sql +7 -0
  160. package/dist/src/storage/sqlite/migrations/163_proactive_follow_ups.sql +29 -0
  161. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  162. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  163. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  164. package/dist/src/storage/sqlite/schema.js +1 -1
  165. package/dist/src/tasks/home-query-service.js +1 -1
  166. package/dist/src/tasks/index.js +4 -4
  167. package/dist/src/tui/tui-startup-resources.js +1 -1
  168. package/dist/src/voice/dashscope/streaming-stt-session.js +1 -0
  169. package/dist/src/voice/dashscope/streaming-tts-stream.d.ts +1 -0
  170. package/dist/src/voice/dashscope/streaming-tts-stream.js +8 -0
  171. package/dist/src/voice/realtime/agentBroker.js +1 -1
  172. package/dist/src/voice/realtime/agentEngine.js +1 -1
  173. package/dist/src/voice/realtime/pcm-output-gain.d.ts +2 -0
  174. package/dist/src/voice/realtime/pcm-output-gain.js +16 -0
  175. package/dist/src/voice/realtime/runtime.js +4 -2
  176. package/dist/src/workflows/service/workflow-run-service.js +1 -1
  177. package/package.json +2 -2
  178. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-qKCezlBg.js +0 -1
  179. package/dist/gateway/static/root/assets/agents-BMhnZKhP.js +0 -1
  180. package/dist/gateway/static/root/assets/apps-page-DduJDWGY.js +0 -1
  181. package/dist/gateway/static/root/assets/automations-workspace-X7hNHCjW.js +0 -6
  182. package/dist/gateway/static/root/assets/browser-settings-page-BZ7nK_pN.js +0 -8
  183. package/dist/gateway/static/root/assets/capabilities-settings-panel-BfKvJO1C.js +0 -7
  184. package/dist/gateway/static/root/assets/channels-settings-D1UDxJuA.js +0 -1
  185. package/dist/gateway/static/root/assets/connectors-page-C2nuqs_O.js +0 -2
  186. package/dist/gateway/static/root/assets/gateway-settings-ogv8ZbvG.js +0 -1
  187. package/dist/gateway/static/root/assets/home-page-CbcJCREd.js +0 -1
  188. package/dist/gateway/static/root/assets/index-7PZ6jmhy.css +0 -2
  189. package/dist/gateway/static/root/assets/local-app-workbench-page-D5XVZnK1.js +0 -2
  190. package/dist/gateway/static/root/assets/note-detail-panel-D5JuBLyt.js +0 -5
  191. package/dist/gateway/static/root/assets/notes-page-C5-ccCi4.js +0 -8
  192. package/dist/gateway/static/root/assets/proactive-page-fHjPigmx.js +0 -1
  193. package/dist/gateway/static/root/assets/project-detail-page-6v_khvEt.js +0 -1
  194. package/dist/gateway/static/root/assets/projects-page-CCy1aK4V.js +0 -1
  195. package/dist/gateway/static/root/assets/remote-access-hub-pkqKRnch.js +0 -1
  196. package/dist/gateway/static/root/assets/sessions-page-Cr4E4cap.js +0 -1
  197. package/dist/gateway/static/root/assets/settings-advanced-gate-D1JRDRyL.js +0 -1
  198. package/dist/gateway/static/root/assets/shares-settings-BrMECMAB.js +0 -1
  199. package/dist/gateway/static/root/assets/skill-reload-api-DuqIDYjc.js +0 -1
  200. package/dist/gateway/static/root/assets/task-detail-page-m0oXUKl2.js +0 -1
  201. package/dist/gateway/static/root/assets/user-model-page-Dl10D_5q.js +0 -2
  202. package/dist/gateway/static/root/assets/workflows-page-CswgoIFU.js +0 -6
  203. package/dist/src/proactive/actions/workflow.d.ts +0 -15
  204. package/dist/src/proactive/actions/workflow.js +0 -88
@@ -1,26 +1,51 @@
1
1
  import { getSqliteDatabase } from "../../../storage/sqlite/transaction.js";
2
- import { getDefaultAgentId, init_resolve_route } from "../../../routing/resolve-route.js";
3
- import { resolveProjectAgentId } from "../../../projects/project-agent.js";
4
- import "../../../projects/index.js";
5
2
  import { ProactiveConflict, proactivePreferences, updateProactivePreferences } from "../../../proactive/policy/service.js";
6
- import { recordProactivePresence } from "../../../proactive/policy/presence.js";
7
3
  import { controlledSubscriptions, createControlledSubscription, requireSubscription, templateCatalog, updateControlledSubscription } from "../../../proactive/scenarios/control.js";
4
+ import { listMailFollowUps, mailFollowUpSources, startMailFollowUp, updateMailFollowUp } from "../../../proactive/follow-ups.js";
8
5
  import { cardChanges, getCard, listCards, performCardAction } from "../../../proactive/inbox/cards.js";
6
+ import { checkDelegation, delegationOverview, startDelegation } from "../../../proactive/experience.js";
7
+ import { recordProactivePresence } from "../../../proactive/policy/presence.js";
9
8
  import { digestCards } from "../../../proactive/inbox/digest.js";
10
9
  import { acknowledgeBrowserProbe, listBrowserProbes, prepareBrowserPush, registerBrowserPush, testBrowserPush, unregisterBrowserPush } from "../../../notifications/web-push.js";
11
10
  import { ReadonlyProactiveAgentExecutor } from "../../../proactive/execution/agent-executor.js";
12
11
  import { proactiveMetrics } from "../../../proactive/metrics.js";
13
- import { prepareCardWorkflow, workflowForCard } from "../../../proactive/actions/workflow.js";
14
12
  import { previewSubscription } from "../../../proactive/scenarios/preview.js";
15
13
  import { ZodError } from "zod";
16
14
  //#region src/gateway/hono/routes/proactive-control.ts
17
- init_resolve_route();
18
15
  function registerProactiveControlRoutes(app, deps) {
19
16
  app.onError((error, c) => c.json({
20
17
  ok: false,
21
18
  error: error instanceof ZodError ? "Invalid request" : error.message
22
19
  }, error instanceof ProactiveConflict ? 409 : 400));
23
20
  const workspace = () => deps.service.currentWorkspacePath;
21
+ app.get("/api/proactive/follow-ups/sources", (c) => c.json({
22
+ ok: true,
23
+ sources: mailFollowUpSources(workspace())
24
+ }));
25
+ app.get("/api/proactive/follow-ups", (c) => c.json({
26
+ ok: true,
27
+ followUps: listMailFollowUps(workspace())
28
+ }));
29
+ app.post("/api/proactive/follow-ups", deps.strictRateLimitMiddleware, async (c) => c.json({
30
+ ok: true,
31
+ followUp: startMailFollowUp(workspace(), await c.req.json())
32
+ }, 201));
33
+ app.patch("/api/proactive/follow-ups/:id", deps.strictRateLimitMiddleware, async (c) => c.json({
34
+ ok: true,
35
+ followUp: updateMailFollowUp(workspace(), c.req.param("id"), await c.req.json())
36
+ }));
37
+ app.get("/api/proactive/overview", (c) => c.json({
38
+ ok: true,
39
+ ...delegationOverview(workspace())
40
+ }));
41
+ app.post("/api/proactive/delegations", deps.strictRateLimitMiddleware, async (c) => c.json({
42
+ ok: true,
43
+ subscription: startDelegation(workspace(), await c.req.json())
44
+ }, 201));
45
+ app.post("/api/proactive/subscriptions/:id/check", deps.strictRateLimitMiddleware, (c) => c.json({
46
+ ok: true,
47
+ ...checkDelegation(workspace(), c.req.param("id"))
48
+ }, 202));
24
49
  for (const path of ["/api/proactive/*", "/api/inbox/judgments/*"]) app.use(path, async (c, next) => {
25
50
  try {
26
51
  const id = c.req.path.match(/^\/api\/inbox\/judgments\/([^/]+)/)?.[1];
@@ -57,24 +82,6 @@ function registerProactiveControlRoutes(app, deps) {
57
82
  unregisterBrowserPush(workspace(), c.req.param("id"));
58
83
  return c.json({ ok: true });
59
84
  });
60
- app.get("/api/inbox/judgments/:itemId/workflow", async (c) => c.json({
61
- ok: true,
62
- workflow: await workflowForCard(c.req.param("itemId"), workspace(), deps.service.createWorkflowRunService())
63
- }));
64
- app.post("/api/inbox/judgments/:itemId/prepare", deps.strictRateLimitMiddleware, async (c) => {
65
- const card = getCard(c.req.param("itemId"), workspace());
66
- const sub = requireSubscription(card.subscriptionId, workspace());
67
- const config = deps.service.currentConfig;
68
- const agentId = sub.scopeKind === "project" ? resolveProjectAgentId({
69
- config,
70
- projects: deps.service.projects,
71
- projectId: sub.scopeId
72
- }) : getDefaultAgentId(config);
73
- return c.json({
74
- ok: true,
75
- workflow: await prepareCardWorkflow(workspace(), card.id, await c.req.json(), agentId, deps.service.createWorkflowRunService())
76
- }, 202);
77
- });
78
85
  app.post("/api/proactive/presence", deps.strictRateLimitMiddleware, async (c) => {
79
86
  recordProactivePresence(workspace(), await c.req.json());
80
87
  return c.json({ ok: true });
@@ -1,6 +1,6 @@
1
1
  import { loadConfig } from "../config/loader.js";
2
- import "../config/index.js";
3
2
  import { isRestartEnabled } from "../config/commands.flags.js";
3
+ import "../config/index.js";
4
4
  import { runBootstrapMigrationsSync } from "../migrations/runner.js";
5
5
  import { restartGatewayProcessWithFreshPid } from "./respawn.js";
6
6
  import { acquireGatewayLock } from "./lock.js";
@@ -1,6 +1,6 @@
1
1
  import { resolveGatewayBindHost, resolveGatewayListenHosts } from "../config/gateway-bind.js";
2
- import { ensureXopcCliOnPath } from "../infra/path-env.js";
3
2
  import { resolveGatewayListenPlan } from "./listen.js";
3
+ import { ensureXopcCliOnPath } from "../infra/path-env.js";
4
4
  import { GatewayService } from "./service.js";
5
5
  import { handleSiteShareUpgrade } from "../share/site-share-router.js";
6
6
  import { createHonoApp } from "./hono/app.js";
@@ -31,11 +31,13 @@ import { resolveProjectAgentId } from "../projects/project-agent.js";
31
31
  import "../projects/index.js";
32
32
  import { resolveEffectiveGatewayPort } from "./host.js";
33
33
  import { onSessionTranscriptUpdate } from "../session/transcript-events.js";
34
+ import { ProactiveScenarioService } from "../proactive/scenarios/service.js";
35
+ import { ProactiveEventService } from "../proactive/service.js";
36
+ import { TaskApplicationService } from "../tasks/task-application-service.js";
37
+ import { ProactiveInboxService } from "../proactive/inbox/service.js";
34
38
  import { AutomationService } from "../automations/service/automation-service.js";
35
39
  import { onAutomationProductEvent, publishAutomationProductEvent } from "../automations/product-events.js";
36
40
  import "../automations/index.js";
37
- import { TaskApplicationService } from "../tasks/task-application-service.js";
38
- import { ProactiveScenarioService } from "../proactive/scenarios/service.js";
39
41
  import { TaskOutboxDispatcher } from "../tasks/task-outbox-dispatcher.js";
40
42
  import { TaskRunDispatcher } from "../tasks/task-run-dispatcher.js";
41
43
  import { TaskSignalService } from "../tasks/task-signal-service.js";
@@ -54,12 +56,6 @@ import { registerClarificationChannelRuntime } from "./clarify-runtime.js";
54
56
  import { ChannelManager } from "../channels/manager.js";
55
57
  import { getWorkspacePath } from "../config/workspace-path-helpers.js";
56
58
  import "../config/index.js";
57
- import { DiscussionService } from "../discussions/service.js";
58
- import { DiscussionOrganizer } from "../discussions/organizer.js";
59
- import { DiscussionLiveWorker } from "../discussions/live-worker.js";
60
- import { DiscussionOrganizerWorker } from "../discussions/organizer-worker.js";
61
- import { DiscussionSealer } from "../discussions/sealer.js";
62
- import "../discussions/index.js";
63
59
  import { ManagedComposioEventPoller } from "../connectors/composio-managed-events.js";
64
60
  import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
65
61
  import "../knowledge/index.js";
@@ -67,12 +63,17 @@ import { ConnectionRecoveryService } from "../connectors/connection-recovery-ser
67
63
  import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
68
64
  import { ConnectedSourceChangePublisher } from "../connectors/source-change-publisher.js";
69
65
  import { startConnectorSupervisor } from "../connectors/supervisor.js";
66
+ import { DiscussionService } from "../discussions/service.js";
67
+ import { DiscussionOrganizer } from "../discussions/organizer.js";
68
+ import { DiscussionLiveWorker } from "../discussions/live-worker.js";
69
+ import { DiscussionOrganizerWorker } from "../discussions/organizer-worker.js";
70
+ import { DiscussionSealer } from "../discussions/sealer.js";
71
+ import "../discussions/index.js";
70
72
  import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
71
73
  import "../endpoint-tools/index.js";
72
74
  import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
73
75
  import { prepareAutomationAgentSession } from "./automation-agent-session.js";
74
76
  import { stopTailscaleExposure } from "./tailscale-lifecycle.js";
75
- import { ProactiveInboxService } from "../proactive/inbox/service.js";
76
77
  import { deliverProactiveCard } from "../proactive/inbox/delivery.js";
77
78
  import { buildVoiceMemoryContext } from "../voice/realtime/memory-context.js";
78
79
  import { buildVoicePersonaContext } from "../voice/realtime/persona-context.js";
@@ -108,7 +109,6 @@ import "../local-apps/index.js";
108
109
  import { createRuntimeBrowserAutomationService } from "../browser/automations/runtime-service.js";
109
110
  import "../browser/automations/index.js";
110
111
  import { mapProductEventToProactive } from "../proactive/events/product-event-bridge.js";
111
- import { ProactiveEventService } from "../proactive/service.js";
112
112
  import { ReadonlyProactiveAgentExecutor } from "../proactive/execution/agent-executor.js";
113
113
  import { listInsights } from "../proactive/execution/repository.js";
114
114
  import { ProactiveWorker } from "../proactive/execution/worker.js";
@@ -152,7 +152,7 @@ async function testBrowserPush(workspaceId, subscriptionId, send = webPush.sendN
152
152
  id,
153
153
  title: "xopc 推送测试 / Push test",
154
154
  body: "点击此通知确认打开 / Tap to confirm opening",
155
- route: `/proactive?probe=${encodeURIComponent(id)}`
155
+ route: `/assistant-work?probe=${encodeURIComponent(id)}`
156
156
  }), {
157
157
  vapidDetails: {
158
158
  subject: "https://xopc.ai",
@@ -1,8 +1,8 @@
1
1
  import { getSqliteDatabase, runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
2
- import { TaskApplicationService } from "../../tasks/task-application-service.js";
2
+ import { insightSourcesAuthorized, insightSourcesChanged } from "../execution/authorization.js";
3
3
  import { effectiveProactivePolicy } from "../policy/service.js";
4
- import { insightSourcesAuthorized } from "../execution/authorization.js";
5
4
  import { insightCorrelation } from "../inbox/lifecycle.js";
5
+ import { TaskApplicationService } from "../../tasks/task-application-service.js";
6
6
  //#region src/proactive/actions/service.ts
7
7
  function projectIdFromAggregationKey(value) {
8
8
  if (!value.startsWith("project:") || value.length === 8) throw new Error("Proactive action has no project scope");
@@ -13,6 +13,7 @@ function executeClaimedAction(row, now = /* @__PURE__ */ new Date()) {
13
13
  try {
14
14
  if (getSqliteDatabase().prepare("SELECT 1 FROM proactive_inbox_items WHERE insight_id = ? AND withdrawn_at IS NOT NULL").get(row.insight_id)) throw new Error("Card was withdrawn");
15
15
  if (!insightSourcesAuthorized(row.insight_id)) throw new Error("Source permission is no longer available");
16
+ if (insightSourcesChanged(row.insight_id)) throw new Error("Source changed; review updated work before acting");
16
17
  if (!effectiveProactivePolicy(row.subscription_id).enabled) throw new Error("Proactive subscription paused");
17
18
  const permission = getSqliteDatabase().prepare(`SELECT mode, allowed_actions_json FROM project_monitoring_policies WHERE project_id = ?`).get(projectIdFromAggregationKey(row.aggregation_key));
18
19
  if (!getSqliteDatabase().prepare(`SELECT 1 FROM proactive_decisions d JOIN proactive_inbox_items i USING(inbox_item_id) WHERE i.insight_id = ? AND d.choice = 'approve'`).get(row.insight_id) && !(permission?.mode === "auto_low_risk" && JSON.parse(permission.allowed_actions_json).includes(action.id))) throw new Error("Action permission is no longer available");
@@ -48,6 +49,7 @@ function executeClaimedAction(row, now = /* @__PURE__ */ new Date()) {
48
49
  getSqliteDatabase().prepare(`UPDATE proactive_insights
49
50
  SET action_status = 'completed', action_result_json = ?, action_error = NULL, action_updated_at = ?
50
51
  WHERE insight_id = ? AND action_status = 'executing'`).run(JSON.stringify({ taskId: result.model.task.id }), now.toISOString(), row.insight_id);
52
+ getSqliteDatabase().prepare("UPDATE proactive_inbox_items SET status = 'read', resolution = NULL, updated_at = ? WHERE insight_id = ?").run(now.toISOString(), row.insight_id);
51
53
  } catch (error) {
52
54
  getSqliteDatabase().prepare(`UPDATE proactive_insights
53
55
  SET action_status = 'failed', action_error = ?, action_updated_at = ?
@@ -1,3 +1,5 @@
1
1
  /** Recheck connector consent for stored cards and actions, not just model input. */
2
2
  export declare function insightSourcesAuthorized(insightId: string): boolean;
3
+ /** Compare versions, not generated prose, before showing or executing prepared work. */
4
+ export declare function insightSourcesChanged(insightId: string): boolean;
3
5
  export declare function authorizedConnectedSource(itemId: string, workspaceId: string, scenarioKey: string, agentId?: string | null): import("../../knowledge/types.js").KnowledgeSourceItem;
@@ -1,14 +1,52 @@
1
1
  import { getSqliteDatabase } from "../../storage/sqlite/transaction.js";
2
2
  import { getKnowledgeSourceItem } from "../../storage/sqlite/knowledge-repository.js";
3
3
  import { getConnectorSyncPolicyForConnection } from "../../storage/sqlite/connector-sync-policy-repository.js";
4
+ import { readMailThread } from "../mail-thread.js";
4
5
  //#region src/proactive/execution/authorization.ts
5
6
  /** Recheck connector consent for stored cards and actions, not just model input. */
6
7
  function insightSourcesAuthorized(insightId) {
8
+ const snapshot = getSqliteDatabase().prepare(`SELECT s.workspace_id, x.scenario_key, c.evidence_ids_json
9
+ FROM proactive_insights x JOIN proactive_scenario_subscriptions s USING(subscription_id)
10
+ JOIN proactive_runs r USING(run_id) LEFT JOIN proactive_context_snapshots c ON c.snapshot_id = r.context_snapshot_id
11
+ WHERE x.insight_id = ?`).get(insightId);
12
+ if (snapshot?.evidence_ids_json) {
13
+ if (JSON.parse(snapshot.evidence_ids_json).some((id) => id.startsWith("source-item:") && !authorizedConnectedSource(id.slice(12), snapshot.workspace_id, snapshot.scenario_key))) return false;
14
+ }
7
15
  return getSqliteDatabase().prepare(`SELECT e.subject_id, e.workspace_id, x.scenario_key
8
16
  FROM proactive_insights x JOIN proactive_runs r USING(run_id)
9
17
  JOIN proactive_batch_events be ON be.batch_id = r.batch_id JOIN proactive_events e USING(event_id)
10
18
  WHERE x.insight_id = ? AND e.type LIKE 'connected_source.%'`).all(insightId).every((row) => Boolean(authorizedConnectedSource(row.subject_id, row.workspace_id, row.scenario_key)));
11
19
  }
20
+ /** Compare versions, not generated prose, before showing or executing prepared work. */
21
+ function insightSourcesChanged(insightId) {
22
+ const db = getSqliteDatabase();
23
+ const row = db.prepare(`SELECT c.content_json FROM proactive_insights x JOIN proactive_runs r USING(run_id)
24
+ JOIN proactive_context_snapshots c ON c.snapshot_id = r.context_snapshot_id WHERE x.insight_id = ?`).get(insightId);
25
+ if (!row) return false;
26
+ const snapshot = JSON.parse(row.content_json);
27
+ if (snapshot.follow_up?.followUpId) {
28
+ const follow = db.prepare("SELECT source_item_id, revision, status, due_at FROM proactive_follow_ups WHERE id = ?").get(snapshot.follow_up.followUpId);
29
+ if (!follow || follow.status !== "watching" || follow.revision !== snapshot.follow_up.revision || Date.parse(follow.due_at) <= Date.now() !== snapshot.follow_up.deadlinePassed || readMailThread(follow.source_item_id)?.fingerprint !== snapshot.follow_up.fingerprint) return true;
30
+ }
31
+ for (const source of [...snapshot.connected_source?.items ?? [], ...snapshot.follow_up?.items ?? []]) {
32
+ const current = getKnowledgeSourceItem(source.sourceItemId);
33
+ if (!current || current.deletedAt || current.contentHash !== source.contentHash || current.occurredAt !== source.occurredAt) return true;
34
+ }
35
+ const project = snapshot.project_state?.project;
36
+ if (project) {
37
+ const current = db.prepare("SELECT updated_at FROM projects WHERE project_id = ?").get(project.project_id);
38
+ if (!current || current.updated_at !== project.updated_at) return true;
39
+ }
40
+ for (const task of [...snapshot.project_state?.activeTasks ?? [], ...snapshot.meeting_workspace?.activeTasks ?? []]) {
41
+ const current = db.prepare("SELECT updated_at FROM tasks WHERE task_id = ?").get(task.task_id);
42
+ if (!current || current.updated_at !== task.updated_at) return true;
43
+ }
44
+ for (const note of snapshot.meeting_workspace?.recentNotes ?? []) {
45
+ const current = db.prepare("SELECT updated_at FROM notes WHERE note_id = ?").get(note.note_id);
46
+ if (!current || current.updated_at !== note.updated_at) return true;
47
+ }
48
+ return false;
49
+ }
12
50
  function authorizedConnectedSource(itemId, workspaceId, scenarioKey, agentId) {
13
51
  const item = getKnowledgeSourceItem(itemId);
14
52
  if (!item || item.deletedAt || item.metadata.workspaceId !== workspaceId || item.sensitivity === "secret" || item.sensitivity === "regulated") return null;
@@ -20,4 +58,4 @@ function authorizedConnectedSource(itemId, workspaceId, scenarioKey, agentId) {
20
58
  return policy?.scanEnabled && policy.proactiveEnabled && (!policy.allowedScenarioKeys.length || policy.allowedScenarioKeys.includes(scenarioKey)) ? item : null;
21
59
  }
22
60
  //#endregion
23
- export { authorizedConnectedSource, insightSourcesAuthorized };
61
+ export { authorizedConnectedSource, insightSourcesAuthorized, insightSourcesChanged };
@@ -33,6 +33,10 @@ export declare class DiscussionContextProvider implements ContextProvider {
33
33
  readonly id = "discussion";
34
34
  collect(input: ContextInput): Promise<ResolvedContext>;
35
35
  }
36
+ export declare class MailFollowUpContextProvider implements ContextProvider {
37
+ readonly id = "follow_up";
38
+ collect(input: ContextInput): Promise<ResolvedContext>;
39
+ }
36
40
  export declare class ContextProviderRegistry {
37
41
  private readonly providers;
38
42
  constructor(providers?: ContextProvider[]);
@@ -1,8 +1,9 @@
1
1
  import { getSqliteDatabase } from "../../storage/sqlite/transaction.js";
2
2
  import { getAssertionSlot, listUserAssertions } from "../../user-model/repository.js";
3
3
  import "../../user-model/index.js";
4
- import { getDiscussionCapture, getLatestDiscussionOrganization } from "../../discussions/repository.js";
5
4
  import { authorizedConnectedSource } from "./authorization.js";
5
+ import { authorizedMailThread, requireMailFollowUp } from "../follow-ups.js";
6
+ import { getDiscussionCapture, getLatestDiscussionOrganization } from "../../discussions/repository.js";
6
7
  import { wrapExternalContent } from "../../gateway/security/external-content.js";
7
8
  //#region src/proactive/execution/context.ts
8
9
  const MAX_EVENT_COUNT = 50;
@@ -27,7 +28,12 @@ function emptyContext() {
27
28
  };
28
29
  }
29
30
  function authorizedConnectedSourceItem(event, scenarioKey) {
30
- return authorizedConnectedSource(event.subject_id, event.workspace_id, scenarioKey, event.agent_id);
31
+ const item = authorizedConnectedSource(event.subject_id, event.workspace_id, scenarioKey, event.agent_id);
32
+ if (item && event.type === "connected_source.calendar_window.v1") {
33
+ const payload = JSON.parse(event.payload_json);
34
+ if (payload.meetingStartsAt !== item.occurredAt || payload.contentHash && payload.contentHash !== item.contentHash) return null;
35
+ }
36
+ return item;
31
37
  }
32
38
  var EventBatchContextProvider = class {
33
39
  id = "event_batch";
@@ -53,11 +59,13 @@ var ConnectedSourceContextProvider = class {
53
59
  async collect(input) {
54
60
  const items = [];
55
61
  const snapshotItems = [];
62
+ const seen = /* @__PURE__ */ new Set();
56
63
  const evidenceIds = [];
57
64
  for (const event of eventRows(input.eventIds)) {
58
65
  if (!event.type.startsWith("connected_source.") || event.type.includes("_deleted.")) continue;
59
66
  const item = authorizedConnectedSourceItem(event, input.scenarioKey);
60
- if (!item) continue;
67
+ if (!item || seen.has(item.id)) continue;
68
+ seen.add(item.id);
61
69
  const evidenceId = `source-item:${item.id}`;
62
70
  const common = {
63
71
  evidenceId,
@@ -325,6 +333,43 @@ var DiscussionContextProvider = class {
325
333
  };
326
334
  }
327
335
  };
336
+ var MailFollowUpContextProvider = class {
337
+ id = "follow_up";
338
+ async collect(input) {
339
+ const event = eventRows(input.eventIds).findLast((row) => row.subject_kind === "mail_follow_up");
340
+ if (!event) return emptyContext();
341
+ const follow = requireMailFollowUp(event.workspace_id, event.subject_id);
342
+ const thread = authorizedMailThread(follow);
343
+ if (!thread || follow.status !== "watching") return emptyContext();
344
+ const common = {
345
+ followUpId: follow.id,
346
+ revision: follow.revision,
347
+ fingerprint: thread.fingerprint,
348
+ dueAt: follow.due_at,
349
+ deadlinePassed: Date.parse(follow.due_at) <= Date.now()
350
+ };
351
+ return {
352
+ content: {
353
+ ...common,
354
+ instructions: follow.instructions,
355
+ items: thread.items.map((item) => ({
356
+ evidenceId: `source-item:${item.id}`,
357
+ occurredAt: item.occurredAt,
358
+ content: wrapExternalContent(item.normalizedText?.slice(0, 4e3) ?? "", { source: "email" })
359
+ }))
360
+ },
361
+ snapshotContent: {
362
+ ...common,
363
+ items: thread.items.map((item) => ({
364
+ sourceItemId: item.id,
365
+ contentHash: item.contentHash,
366
+ occurredAt: item.occurredAt
367
+ }))
368
+ },
369
+ evidenceIds: thread.items.map((item) => `source-item:${item.id}`)
370
+ };
371
+ }
372
+ };
328
373
  var ContextProviderRegistry = class {
329
374
  constructor(providers = [
330
375
  new EventBatchContextProvider(),
@@ -334,7 +379,8 @@ var ContextProviderRegistry = class {
334
379
  new MeetingWorkspaceContextProvider(),
335
380
  new ProjectStateContextProvider(),
336
381
  new AutomationStateContextProvider(),
337
- new DiscussionContextProvider()
382
+ new DiscussionContextProvider(),
383
+ new MailFollowUpContextProvider()
338
384
  ]) {
339
385
  this.providers = providers;
340
386
  }
@@ -357,4 +403,4 @@ var ContextProviderRegistry = class {
357
403
  }
358
404
  };
359
405
  //#endregion
360
- export { AutomationStateContextProvider, ConnectedSourceContextProvider, ContextProviderRegistry, DiscussionContextProvider, EventBatchContextProvider, InternalObjectContextProvider, MeetingWorkspaceContextProvider, ProjectStateContextProvider, UserModelContextProvider };
406
+ export { AutomationStateContextProvider, ConnectedSourceContextProvider, ContextProviderRegistry, DiscussionContextProvider, EventBatchContextProvider, InternalObjectContextProvider, MailFollowUpContextProvider, MeetingWorkspaceContextProvider, ProjectStateContextProvider, UserModelContextProvider };
@@ -1,3 +1,4 @@
1
+ import { ProactiveArtifactSchema } from "../../../packages/gateway-contract/src/proactive.js";
1
2
  import { stripCodeFences } from "../../providers/model-response.js";
2
3
  //#region src/proactive/execution/insight.ts
3
4
  const URGENCY = new Set([
@@ -65,6 +66,7 @@ function parseInsightCandidate(raw, allowedEvidenceIds) {
65
66
  const proposedAction = parseProposedAction(row.proposedAction);
66
67
  if (proposedAction && (!decision || decision.options.length !== 2 || decision.options[0]?.id !== "approve" || decision.options[1]?.id !== "reject")) throw new Error("Insight proposedAction requires approve and reject decision options");
67
68
  return {
69
+ ...row.artifact != null ? { artifact: ProactiveArtifactSchema.parse(row.artifact) } : {},
68
70
  title: boundedText(row.title, "title", 160),
69
71
  summary: boundedText(row.summary, "summary", 1200),
70
72
  whyNow: boundedText(row.whyNow, "whyNow", 800),
@@ -91,7 +93,7 @@ function isValuableInsight(candidate, policy = {
91
93
  minConfidence: .65,
92
94
  minScore: .6
93
95
  }) {
94
- return candidate.confidence >= policy.minConfidence && candidate.urgency !== "low" && scoreInsight(candidate) >= policy.minScore;
96
+ return candidate.confidence >= policy.minConfidence && (candidate.urgency !== "low" || Boolean(candidate.artifact)) && scoreInsight(candidate) >= policy.minScore;
95
97
  }
96
98
  function parseAnalysisResult(raw, allowedEvidenceIds) {
97
99
  let value;
@@ -107,11 +107,19 @@ function finishRun(input, now = /* @__PURE__ */ new Date()) {
107
107
  JOIN proactive_events e ON e.event_id = be.event_id
108
108
  WHERE be.batch_id = ?
109
109
  ORDER BY e.subject_kind, e.subject_id`).all(input.run.batchId).map((row) => `${str(row, "subject_kind")}:${str(row, "subject_id")}`);
110
- const fingerprint = input.candidate ? createHash("sha256").update([...subjectScope, ...[
111
- input.candidate.title,
112
- input.candidate.summary,
113
- input.candidate.recommendation
114
- ].map((value) => value.trim().toLowerCase().replace(/\s+/g, " "))].join("\n")).digest("hex") : void 0;
110
+ const snapshot = db.prepare(`SELECT c.content_json FROM proactive_runs r JOIN proactive_context_snapshots c
111
+ ON c.snapshot_id = r.context_snapshot_id WHERE r.run_id = ?`).get(input.run.id);
112
+ const sourceVersions = snapshot ? JSON.parse(snapshot.content_json) : {};
113
+ const fingerprint = input.candidate ? createHash("sha256").update([
114
+ ...subjectScope,
115
+ JSON.stringify(input.candidate.artifact ?? null),
116
+ JSON.stringify(sourceVersions.connected_source ?? sourceVersions.project_state ?? sourceVersions.follow_up ?? null),
117
+ ...[
118
+ input.candidate.title,
119
+ input.candidate.summary,
120
+ input.candidate.recommendation
121
+ ].map((value) => value.trim().toLowerCase().replace(/\s+/g, " "))
122
+ ].join("\n")).digest("hex") : void 0;
115
123
  const duplicate = fingerprint ? db.prepare(`SELECT 1 FROM proactive_insights
116
124
  WHERE subscription_id = ? AND scenario_key = ? AND content_fingerprint = ? AND created_at >= ? LIMIT 1`).get(input.run.subscriptionId, input.run.scenarioKey, fingerprint, (/* @__PURE__ */ new Date(now.getTime() - (input.cooldownSeconds ?? 10080 * 60) * 1e3)).toISOString()) : void 0;
117
125
  const valuable = Boolean(input.candidate) && !duplicate;
@@ -141,6 +149,7 @@ function finishRun(input, now = /* @__PURE__ */ new Date()) {
141
149
  why_now, impact, recommendation, work_done, decision_json, proposed_action_json, urgency, confidence, value_score,
142
150
  evidence_ids_json, content_fingerprint, created_at)
143
151
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(insight.id, insight.runId, insight.subscriptionId, insight.scenarioKey, insight.title, insight.summary, insight.whyNow, insight.impact, insight.recommendation, insight.workDone, insight.decision ? JSON.stringify(insight.decision) : null, insight.proposedAction ? JSON.stringify(insight.proposedAction) : null, insight.urgency, insight.confidence, insight.valueScore, JSON.stringify(insight.evidenceIds), fingerprint, insight.createdAt);
152
+ if (insight.artifact) db.prepare("UPDATE proactive_insights SET artifact_json = ? WHERE insight_id = ?").run(JSON.stringify(insight.artifact), insight.id);
144
153
  return insight;
145
154
  });
146
155
  }
@@ -165,6 +174,7 @@ function listInsights(limit = 50) {
165
174
  impact: str(row, "impact"),
166
175
  recommendation: str(row, "recommendation"),
167
176
  workDone: str(row, "work_done"),
177
+ ...row.artifact_json ? { artifact: JSON.parse(str(row, "artifact_json")) } : {},
168
178
  ...row.decision_json ? { decision: JSON.parse(str(row, "decision_json")) } : {},
169
179
  ...row.proposed_action_json ? { proposedAction: JSON.parse(str(row, "proposed_action_json")) } : {},
170
180
  urgency: str(row, "urgency"),
@@ -1,3 +1,4 @@
1
+ import type { ProactiveArtifact } from '@xopcai/gateway-contract';
1
2
  export interface ContextSnapshot {
2
3
  id: string;
3
4
  batchId: string;
@@ -6,6 +7,7 @@ export interface ContextSnapshot {
6
7
  createdAt: string;
7
8
  }
8
9
  export interface InsightCandidate {
10
+ artifact?: ProactiveArtifact;
9
11
  title: string;
10
12
  summary: string;
11
13
  whyNow: string;
@@ -1,6 +1,7 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { getSqliteDatabase } from "../../storage/sqlite/transaction.js";
4
+ import { authorizedConnectedSource } from "./authorization.js";
4
5
  import { effectiveProactivePolicy } from "../policy/service.js";
5
6
  import { getPromptRevision, getScenario } from "../scenarios/repository.js";
6
7
  import { composeScenarioPrompt } from "../scenarios/prompt-composer.js";
@@ -9,6 +10,7 @@ import { ContextProviderRegistry } from "./context.js";
9
10
  import { attachSnapshot, claimNextRun, eventIdsForBatch, failRun, finishRun, saveSnapshot } from "./repository.js";
10
11
  import { isValuableInsight, parseAnalysisResult, scoreInsight } from "./insight.js";
11
12
  import { randomUUID } from "node:crypto";
13
+ import { isDeepStrictEqual } from "node:util";
12
14
  //#region src/proactive/execution/worker.ts
13
15
  init_logger();
14
16
  const log = createLogger("ProactiveWorker");
@@ -86,11 +88,14 @@ var ProactiveWorker = class {
86
88
  subscriptionId: run.subscriptionId
87
89
  });
88
90
  const revoked = context.evidenceIds.some((id) => !latestContext.evidenceIds.includes(id));
89
- const result = revoked ? {
91
+ const changed = !isDeepStrictEqual(context.snapshotContent ?? context.content, latestContext.snapshotContent ?? latestContext.content);
92
+ const unavailable = context.evidenceIds.some((id) => id.startsWith("source-item:") && !authorizedConnectedSource(id.slice(12), effectiveProactivePolicy(run.subscriptionId).workspaceId, run.scenarioKey));
93
+ const result = revoked || changed ? {
90
94
  result: "no_insight",
91
- reason: "source_unavailable"
95
+ reason: unavailable ? "source_unavailable" : "source_changed"
92
96
  } : parseAnalysisResult(output.text, new Set(latestContext.evidenceIds));
93
97
  const candidate = result.result === "insight" ? result.candidate : void 0;
98
+ if (run.scenarioKey === "communication_follow_up" && (candidate?.decision || candidate?.proposedAction)) throw new Error("Communication preparation must return a draft or update; actions require the conversation confirmation flow");
94
99
  const valueScore = candidate ? scoreInsight(candidate) : 0;
95
100
  const enabled = effectiveProactivePolicy(run.subscriptionId).enabled;
96
101
  const valuable = enabled && candidate && isValuableInsight(candidate, scenario.valuePolicy);
@@ -0,0 +1,69 @@
1
+ export declare function startDelegation(workspace: string, value: unknown): {
2
+ effectiveLevel: "off" | "active" | "quiet" | "balanced";
3
+ schedule: Record<string, import("node:sqlite").SQLOutputValue>;
4
+ revision: number;
5
+ level: "off" | "active" | "quiet" | "balanced";
6
+ delivery: "digest" | "inbox" | "important";
7
+ completedAt: string;
8
+ scanIntervalMinutes: number;
9
+ userInstructions: string;
10
+ id: string;
11
+ scenarioKey: string;
12
+ workspaceId: string;
13
+ scopeKind: "workspace" | "project";
14
+ scopeId: string;
15
+ enabled: boolean;
16
+ activePromptRevisionId?: string;
17
+ createdAt: string;
18
+ updatedAt: string;
19
+ };
20
+ /** Queue work in the existing worker; HTTP and conversation requests do not own model runs. */
21
+ export declare function checkDelegation(workspace: string, id: string): {
22
+ status: "queued";
23
+ };
24
+ export declare function delegationOverview(workspace: string): {
25
+ followUps: {
26
+ id: string;
27
+ subscriptionId: string;
28
+ instructions: string;
29
+ dueAt: string;
30
+ status: "completed" | "paused" | "watching";
31
+ revision: number;
32
+ lastCheckedAt: string;
33
+ sessionKey: string;
34
+ sourceAvailable: boolean;
35
+ enabled: boolean;
36
+ subject: string;
37
+ latestMessageAt: string;
38
+ latestDirection: string;
39
+ lastSyncedAt: string;
40
+ syncFailed: boolean;
41
+ }[];
42
+ needsDecision: import("@xopcai/gateway-contract/src/proactive.js").ProactiveCard[];
43
+ prepared: import("@xopcai/gateway-contract/src/proactive.js").ProactiveCard[];
44
+ updates: import("@xopcai/gateway-contract/src/proactive.js").ProactiveCard[];
45
+ delegations: {
46
+ effectiveEnabled: boolean;
47
+ project: Record<string, import("node:sqlite").SQLOutputValue>;
48
+ latestRun: Record<string, import("node:sqlite").SQLOutputValue>;
49
+ pending: boolean;
50
+ effectiveLevel: "off" | "active" | "quiet" | "balanced";
51
+ schedule: Record<string, import("node:sqlite").SQLOutputValue>;
52
+ revision: number;
53
+ level: "off" | "active" | "quiet" | "balanced";
54
+ delivery: "digest" | "inbox" | "important";
55
+ completedAt: string;
56
+ scanIntervalMinutes: number;
57
+ userInstructions: string;
58
+ id: string;
59
+ scenarioKey: string;
60
+ workspaceId: string;
61
+ scopeKind: "workspace" | "project";
62
+ scopeId: string;
63
+ enabled: boolean;
64
+ activePromptRevisionId?: string;
65
+ createdAt: string;
66
+ updatedAt: string;
67
+ }[];
68
+ };
69
+ export declare function completeDeliveredProjects(now?: Date): void;