@xopcai/xopc 0.0.269 → 0.0.272

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 (293) hide show
  1. package/dist/browser-ext/dist/assets/{auth-cwEj8rFb.js → auth-C1QI-uMG.js} +65 -14
  2. package/dist/browser-ext/dist/background.js +23 -2
  3. package/dist/browser-ext/dist/pairing-handoff.js +51 -0
  4. package/dist/browser-ext/dist/sidepanel.html +1 -1
  5. package/dist/browser-ext/dist/sidepanel.js +39 -27
  6. package/dist/browser-ext/manifest.json +12 -1
  7. package/dist/extensions/telegram/xopc.extension.json +1 -1
  8. package/dist/gateway/static/root/assets/{activity-store-DcwCSY6s.js → activity-store-DffqjeqQ.js} +1 -1
  9. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-D0NBOWC4.js → agent-avatar-dicebear-Cwj4HCYY.js} +1 -1
  10. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-6CLfLxVc.js +1 -0
  11. package/dist/gateway/static/root/assets/agents-B6mu64fY.js +1 -0
  12. package/dist/gateway/static/root/assets/{api-eaPO-mdr.js → api-CGLdye4i.js} +1 -1
  13. package/dist/gateway/static/root/assets/{app-management-settings-panel-E3xm2teY.js → app-management-settings-panel-BLujSbaw.js} +1 -1
  14. package/dist/gateway/static/root/assets/{appearance-settings-CiZOjgls.js → appearance-settings-BXMcueb8.js} +1 -1
  15. package/dist/gateway/static/root/assets/apps-page-BEgy4hY3.js +1 -0
  16. package/dist/gateway/static/root/assets/{archive-plugin-D09yo_Hc.js → archive-plugin-D4bUampf.js} +1 -1
  17. package/dist/gateway/static/root/assets/{attachment-load-CNYb8Qru.js → attachment-load-CBGNA2Ys.js} +1 -1
  18. package/dist/gateway/static/root/assets/{automations-page-DsrfW5ii.js → automations-page-dQyolNmy.js} +1 -1
  19. package/dist/gateway/static/root/assets/automations-workspace-DxRFrmrV.js +6 -0
  20. package/dist/gateway/static/root/assets/{binary-plugins-OWlaGqlY.js → binary-plugins-bbvp81h2.js} +1 -1
  21. package/dist/gateway/static/root/assets/{block-editor-CVND3M6r.js → block-editor-C8e6Wri4.js} +3 -3
  22. package/dist/gateway/static/root/assets/{browser-automation-inputs-D7IzVK_J.js → browser-automation-inputs-oJWJtQa6.js} +1 -1
  23. package/dist/gateway/static/root/assets/{browser-automations-page-CQ6cCpIv.js → browser-automations-page-CAcJQSjN.js} +2 -2
  24. package/dist/gateway/static/root/assets/browser-settings-page-TLAlqcPo.js +8 -0
  25. package/dist/gateway/static/root/assets/capabilities-settings-panel-z-K_jrZz.js +8 -0
  26. package/dist/gateway/static/root/assets/channels-settings-Dzrk33aB.js +1 -0
  27. package/dist/gateway/static/root/assets/{channels-status-swr-D4JrgJKa.js → channels-status-swr-CfOPNnVr.js} +1 -1
  28. package/dist/gateway/static/root/assets/{chat-terminal-dock-BUjnhT7C.js → chat-terminal-dock-9ZOl92kh.js} +2 -2
  29. package/dist/gateway/static/root/assets/clock-3-DnrAnuyZ.js +1 -0
  30. package/dist/gateway/static/root/assets/connectors-page-B1dIoRNi.js +2 -0
  31. package/dist/gateway/static/root/assets/cron-expression-C26e13YU.js +2 -0
  32. package/dist/gateway/static/root/assets/date-picker-Dj6FRLF9.js +1 -0
  33. package/dist/gateway/static/root/assets/{dependency-picker-Z6Nf0Wjq.js → dependency-picker-D1q89tVc.js} +1 -1
  34. package/dist/gateway/static/root/assets/{desktop-pet-C0F5Iqnc.js → desktop-pet-DfqZBvhp.js} +1 -1
  35. package/dist/gateway/static/root/assets/{desktop-pet-settings-Bj_W6HL1.js → desktop-pet-settings-HCEh2MOm.js} +1 -1
  36. package/dist/gateway/static/root/assets/device-pairing-wizard-CPth92s6.js +1 -0
  37. package/dist/gateway/static/root/assets/{extension-debug-page-Ba09EnAn.js → extension-debug-page-C8cAWVoK.js} +1 -1
  38. package/dist/gateway/static/root/assets/{extension-page-C88aGXJs.js → extension-page-5N87Vaym.js} +1 -1
  39. package/dist/gateway/static/root/assets/extension-settings-page-D85SAUFP.js +1 -0
  40. package/dist/gateway/static/root/assets/{gateway-config-swr-bjzk_4hn.js → gateway-config-swr-BjsDnB_n.js} +1 -1
  41. package/dist/gateway/static/root/assets/gateway-settings-Dqx8PmcT.js +1 -0
  42. package/dist/gateway/static/root/assets/{gateway-startup-retry-DrbIzFyB.js → gateway-startup-retry-BIf0eLWX.js} +1 -1
  43. package/dist/gateway/static/root/assets/git-branch-Dh9uxTot.js +1 -0
  44. package/dist/gateway/static/root/assets/heartbeat-settings-BpDWGE1a.js +1 -0
  45. package/dist/gateway/static/root/assets/home-page-DJaqpC8-.js +1 -0
  46. package/dist/gateway/static/root/assets/{image-generation-api-CBWU9Ner.js → image-generation-api-1m8xTVS_.js} +1 -1
  47. package/dist/gateway/static/root/assets/index-C6PmD0cK.js +74 -0
  48. package/dist/gateway/static/root/assets/index-DKy1Qn1_.css +2 -0
  49. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-B8Z7kKQY.js → keyboard-shortcuts-settings-Byy8mCSq.js} +1 -1
  50. package/dist/gateway/static/root/assets/local-app-workbench-page-l2AEiG2C.js +2 -0
  51. package/dist/gateway/static/root/assets/{local-apps-page-CLSfzkRp.js → local-apps-page-BPo0wBgM.js} +1 -1
  52. package/dist/gateway/static/root/assets/locale-store-CRNble2Z.js +1 -0
  53. package/dist/gateway/static/root/assets/logs-page-X5FdLlXK.js +2 -0
  54. package/dist/gateway/static/root/assets/management-settings-DT6NoIjm.js +1 -0
  55. package/dist/gateway/static/root/assets/{markdown-view-DIcfrLmG.js → markdown-view-AglreSOj.js} +1 -1
  56. package/dist/gateway/static/root/assets/{media-plugins-CSv6-xTA.js → media-plugins-Bzka9qXu.js} +1 -1
  57. package/dist/gateway/static/root/assets/message-circle-Badhj-4D.js +1 -0
  58. package/dist/gateway/static/root/assets/message-square-fVE7Ghj1.js +1 -0
  59. package/dist/gateway/static/root/assets/{messages-BRjoarIr.js → messages-DH_HCgmw.js} +3 -3
  60. package/dist/gateway/static/root/assets/note-detail-panel-BUJPoaGZ.js +5 -0
  61. package/dist/gateway/static/root/assets/notes-page-BwFpWRuo.js +8 -0
  62. package/dist/gateway/static/root/assets/{page-tabs-BfV-PQa5.js → page-tabs-Ys0p65Lt.js} +1 -1
  63. package/dist/gateway/static/root/assets/popover-select-Dz_Qis2R.js +1 -0
  64. package/dist/gateway/static/root/assets/{preview-open-alternatives-DQS7NFpg.js → preview-open-alternatives-iknB5xEp.js} +1 -1
  65. package/dist/gateway/static/root/assets/proactive-card-BPZDgNNR.js +1 -0
  66. package/dist/gateway/static/root/assets/proactive-page-CxdZR-p2.js +1 -0
  67. package/dist/gateway/static/root/assets/{product-open-page-BIhjZLKg.js → product-open-page-W1o3f-kz.js} +1 -1
  68. package/dist/gateway/static/root/assets/project-detail-page-BU1RKAcy.js +1 -0
  69. package/dist/gateway/static/root/assets/projects-page-z0X0tL8G.js +1 -0
  70. package/dist/gateway/static/root/assets/{registry-api-CwveUfe8.js → registry-api-DmYFpjsH.js} +1 -1
  71. package/dist/gateway/static/root/assets/remote-access-hub-NNTut2I8.js +1 -0
  72. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DMQ0wpNg.js → runtime-tools-settings-panel-DP1XyYO8.js} +1 -1
  73. package/dist/gateway/static/root/assets/{schema-form-C91g2PRU.js → schema-form-BMYKdzsH.js} +1 -1
  74. package/dist/gateway/static/root/assets/sessions-page-B6SsHlz5.js +1 -0
  75. package/dist/gateway/static/root/assets/settings-advanced-gate-BQu8bAcN.js +1 -0
  76. package/dist/gateway/static/root/assets/{settings-form-section-Cem6L49Y.js → settings-form-section-2LGjz7bu.js} +1 -1
  77. package/dist/gateway/static/root/assets/{settings-page-afDUxqlV.js → settings-page-7DjpC9_C.js} +1 -1
  78. package/dist/gateway/static/root/assets/setup-status-panel-Dj9jFWJt.js +1 -0
  79. package/dist/gateway/static/root/assets/{share-preview-page-CVEVHksg.js → share-preview-page-BxYdSi8c.js} +1 -1
  80. package/dist/gateway/static/root/assets/shares-settings-CMqE0KuK.js +1 -0
  81. package/dist/gateway/static/root/assets/skill-reload-api-BXqSJymN.js +1 -0
  82. package/dist/gateway/static/root/assets/{skills-page-CNrq1W6C.js → skills-page-DNEScMZH.js} +1 -1
  83. package/dist/gateway/static/root/assets/skills-page.utils-q88l65YU.js +1 -0
  84. package/dist/gateway/static/root/assets/{system-settings-panel-BLE8PxWE.js → system-settings-panel-8NIssGKj.js} +1 -1
  85. package/dist/gateway/static/root/assets/task-detail-page-L6dp9v2y.js +1 -0
  86. package/dist/gateway/static/root/assets/{theme-store-BejLVjIT.js → theme-store-BXZG3S25.js} +1 -1
  87. package/dist/gateway/static/root/assets/tunnel-api-CWsRPM84.js +1 -0
  88. package/dist/gateway/static/root/assets/{use-autosave-DmgEA8Qb.js → use-autosave-BwQuoTQU.js} +1 -1
  89. package/dist/gateway/static/root/assets/user-model-page-D4BucMrZ.js +2 -0
  90. package/dist/gateway/static/root/assets/{voice-api-key-field-sZ0J83SF.js → voice-api-key-field-Bd03Ic0s.js} +1 -1
  91. package/dist/gateway/static/root/assets/{voice-config-api-BEbz3avx.js → voice-config-api-gggUp3u9.js} +1 -1
  92. package/dist/gateway/static/root/assets/{work-discovery-overlay-BXnAlbmO.js → work-discovery-overlay-DF8PR_pK.js} +1 -1
  93. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BkwFey0a.js → workflow-run-setup-panel-BiAAWlir.js} +2 -2
  94. package/dist/gateway/static/root/assets/workflows-page-DryKUMfA.js +6 -0
  95. package/dist/gateway/static/root/index.html +15 -11
  96. package/dist/package.js +1 -1
  97. package/dist/packages/gateway-contract/src/device-pairing.js +2 -1
  98. package/dist/packages/gateway-contract/src/notifications.js +2 -2
  99. package/dist/packages/gateway-contract/src/proactive.js +22 -6
  100. package/dist/packages/gateway-contract/src/session-identity.js +37 -0
  101. package/dist/src/agent/memory/compaction-chunks.d.ts +18 -0
  102. package/dist/src/agent/memory/compaction-chunks.js +53 -0
  103. package/dist/src/agent/memory/compaction-request.d.ts +12 -0
  104. package/dist/src/agent/memory/compaction-request.js +72 -0
  105. package/dist/src/agent/memory/compaction.d.ts +3 -0
  106. package/dist/src/agent/memory/compaction.js +166 -118
  107. package/dist/src/agent/service.js +1 -0
  108. package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
  109. package/dist/src/agent/tool-manuals/xopc-use.js +19 -1
  110. package/dist/src/agent/tools/factory.js +1 -0
  111. package/dist/src/agent/tools/xopc-use-tool.d.ts +3 -2
  112. package/dist/src/agent/tools/xopc-use-tool.js +48 -4
  113. package/dist/src/browser/automations/schema.d.ts +1 -1
  114. package/dist/src/browser/automations/service.d.ts +1 -1
  115. package/dist/src/browser/native-messaging-host.js +3 -1
  116. package/dist/src/cli/commands/connectors.js +1 -1
  117. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  118. package/dist/src/cli/commands/tunnel.js +5 -0
  119. package/dist/src/connectors/connected-source-ingestion.js +1 -1
  120. package/dist/src/connectors/connected-source-normalizers.js +3 -0
  121. package/dist/src/connectors/connection-recovery-service.js +1 -1
  122. package/dist/src/connectors/health.js +1 -1
  123. package/dist/src/gateway/heartbeat/service.js +1 -1
  124. package/dist/src/gateway/hono/app.js +1 -0
  125. package/dist/src/gateway/hono/middleware/auth.d.ts +1 -2
  126. package/dist/src/gateway/hono/middleware/auth.js +49 -31
  127. package/dist/src/gateway/hono/middleware/strict-rate-limit.js +11 -15
  128. package/dist/src/gateway/hono/routes/browser-session.d.ts +3 -0
  129. package/dist/src/gateway/hono/routes/browser-session.js +43 -0
  130. package/dist/src/gateway/hono/routes/capabilities.js +1 -1
  131. package/dist/src/gateway/hono/routes/connectors.js +1 -1
  132. package/dist/src/gateway/hono/routes/devices.js +61 -96
  133. package/dist/src/gateway/hono/routes/exposure.js +3 -7
  134. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  135. package/dist/src/gateway/hono/routes/mcp.js +1 -1
  136. package/dist/src/gateway/hono/routes/models.js +60 -1
  137. package/dist/src/gateway/hono/routes/notes.js +3 -7
  138. package/dist/src/gateway/hono/routes/proactive-control.js +31 -24
  139. package/dist/src/gateway/hono/routes/sessions.js +11 -0
  140. package/dist/src/gateway/hono/routes/shares.js +8 -20
  141. package/dist/src/gateway/hono/routes/site-shares.js +4 -8
  142. package/dist/src/gateway/hono/routes/tunnel.js +13 -13
  143. package/dist/src/gateway/image-generation-setup.d.ts +17 -0
  144. package/dist/src/gateway/image-generation-setup.js +30 -21
  145. package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
  146. package/dist/src/gateway/rate-limit/buckets.js +10 -0
  147. package/dist/src/gateway/runtime-config.js +2 -0
  148. package/dist/src/gateway/security/browser-session.d.ts +5 -0
  149. package/dist/src/gateway/security/browser-session.js +45 -0
  150. package/dist/src/gateway/security/gateway-principal.d.ts +1 -0
  151. package/dist/src/gateway/service.d.ts +1 -0
  152. package/dist/src/gateway/service.js +21 -11
  153. package/dist/src/heartbeat/index.js +1 -1
  154. package/dist/src/infra/rate-limit/keyed-store.d.ts +3 -0
  155. package/dist/src/infra/rate-limit/keyed-store.js +9 -2
  156. package/dist/src/notifications/web-push.js +1 -1
  157. package/dist/src/proactive/actions/service.js +4 -2
  158. package/dist/src/proactive/execution/authorization.d.ts +2 -0
  159. package/dist/src/proactive/execution/authorization.js +39 -1
  160. package/dist/src/proactive/execution/context.d.ts +4 -0
  161. package/dist/src/proactive/execution/context.js +51 -5
  162. package/dist/src/proactive/execution/insight.js +3 -1
  163. package/dist/src/proactive/execution/repository.js +15 -5
  164. package/dist/src/proactive/execution/types.d.ts +2 -0
  165. package/dist/src/proactive/execution/worker.js +7 -2
  166. package/dist/src/proactive/experience.d.ts +69 -0
  167. package/dist/src/proactive/experience.js +90 -0
  168. package/dist/src/proactive/follow-ups.d.ts +123 -0
  169. package/dist/src/proactive/follow-ups.js +169 -0
  170. package/dist/src/proactive/inbox/cards.js +35 -6
  171. package/dist/src/proactive/inbox/delivery.js +4 -2
  172. package/dist/src/proactive/inbox/digest.js +2 -2
  173. package/dist/src/proactive/inbox/lifecycle.js +4 -1
  174. package/dist/src/proactive/inbox/notification-policy.js +4 -2
  175. package/dist/src/proactive/inbox/repository.js +17 -11
  176. package/dist/src/proactive/inbox/types.d.ts +2 -0
  177. package/dist/src/proactive/inbox/worker.js +1 -1
  178. package/dist/src/proactive/index.js +2 -2
  179. package/dist/src/proactive/mail-thread.d.ts +13 -0
  180. package/dist/src/proactive/mail-thread.js +54 -0
  181. package/dist/src/proactive/policy/service.d.ts +3 -5
  182. package/dist/src/proactive/policy/service.js +3 -5
  183. package/dist/src/proactive/scenarios/control.d.ts +4 -7
  184. package/dist/src/proactive/scenarios/control.js +3 -4
  185. package/dist/src/proactive/scenarios/preview.js +1 -1
  186. package/dist/src/proactive/scenarios/prompt-composer.js +2 -0
  187. package/dist/src/proactive/service.js +1 -1
  188. package/dist/src/proactive/temporal/worker.d.ts +1 -0
  189. package/dist/src/proactive/temporal/worker.js +18 -4
  190. package/dist/src/realtime/runtime.d.ts +2 -1
  191. package/dist/src/realtime/runtime.js +9 -3
  192. package/dist/src/realtime/tickets.d.ts +1 -0
  193. package/dist/src/realtime/tickets.js +3 -0
  194. package/dist/src/session/store.d.ts +2 -0
  195. package/dist/src/session/store.js +17 -2
  196. package/dist/src/session/types.d.ts +2 -1
  197. package/dist/src/storage/sqlite/browser-session-repository.d.ts +17 -0
  198. package/dist/src/storage/sqlite/browser-session-repository.js +54 -0
  199. package/dist/src/storage/sqlite/device-pairing-approval.js +2 -1
  200. package/dist/src/storage/sqlite/device-pairing-repository.d.ts +4 -10
  201. package/dist/src/storage/sqlite/device-pairing-repository.js +10 -62
  202. package/dist/src/storage/sqlite/index.d.ts +1 -1
  203. package/dist/src/storage/sqlite/index.js +2 -2
  204. package/dist/src/storage/sqlite/migrations/162_proactive_product.sql +7 -0
  205. package/dist/src/storage/sqlite/migrations/163_proactive_follow_ups.sql +29 -0
  206. package/dist/src/storage/sqlite/migrations/164_browser_sessions.sql +8 -0
  207. package/dist/src/storage/sqlite/migrations/165_device_pairing_target.sql +40 -0
  208. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  209. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  210. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  211. package/dist/src/storage/sqlite/schema.js +1 -1
  212. package/dist/src/storage/sqlite/session-identity-sql.d.ts +2 -0
  213. package/dist/src/storage/sqlite/session-identity-sql.js +18 -0
  214. package/dist/src/storage/sqlite/session-repository.js +26 -22
  215. package/dist/src/tasks/home-query-service.js +1 -1
  216. package/dist/src/tasks/index.js +4 -4
  217. package/dist/src/tui/tui-startup-resources.js +1 -1
  218. package/dist/src/tunnel/auth-policy.d.ts +3 -0
  219. package/dist/src/tunnel/auth-policy.js +8 -0
  220. package/dist/src/tunnel/broker-client.d.ts +5 -15
  221. package/dist/src/tunnel/broker-client.js +37 -49
  222. package/dist/src/tunnel/frpc-binary.d.ts +8 -6
  223. package/dist/src/tunnel/frpc-binary.js +76 -88
  224. package/dist/src/tunnel/frpc-config.d.ts +2 -1
  225. package/dist/src/tunnel/frpc-config.js +29 -12
  226. package/dist/src/tunnel/frpc-release.d.ts +27 -0
  227. package/dist/src/tunnel/frpc-release.js +30 -0
  228. package/dist/src/tunnel/gateway-lifecycle.js +8 -2
  229. package/dist/src/tunnel/index.js +2 -1
  230. package/dist/src/tunnel/registration-proof.d.ts +19 -0
  231. package/dist/src/tunnel/registration-proof.js +37 -0
  232. package/dist/src/tunnel/tunnel-persist.js +3 -1
  233. package/dist/src/tunnel/tunnel-service.d.ts +1 -0
  234. package/dist/src/tunnel/tunnel-service.js +35 -8
  235. package/dist/src/tunnel/tunnel-state.js +11 -5
  236. package/dist/src/tunnel/tunnel-types.d.ts +2 -0
  237. package/dist/src/tunnel/well-known.js +5 -1
  238. package/dist/src/user-context/config.js +2 -2
  239. package/dist/src/utils/logger/redact.js +4 -0
  240. package/dist/src/voice/dashscope/streaming-stt-session.js +1 -0
  241. package/dist/src/voice/dashscope/streaming-tts-stream.d.ts +1 -0
  242. package/dist/src/voice/dashscope/streaming-tts-stream.js +8 -0
  243. package/dist/src/voice/realtime/agentBroker.js +1 -1
  244. package/dist/src/voice/realtime/agentEngine.js +1 -1
  245. package/dist/src/voice/realtime/pcm-output-gain.d.ts +2 -0
  246. package/dist/src/voice/realtime/pcm-output-gain.js +16 -0
  247. package/dist/src/voice/realtime/runtime.d.ts +1 -0
  248. package/dist/src/voice/realtime/runtime.js +21 -3
  249. package/dist/src/voice/realtime/runtime.types.d.ts +1 -0
  250. package/dist/src/workflows/service/workflow-run-service.js +3 -1
  251. package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -0
  252. package/dist/src/workflows/service/workflow-session-bridge.js +1 -0
  253. package/package.json +4 -4
  254. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-qKCezlBg.js +0 -1
  255. package/dist/gateway/static/root/assets/agents-BMhnZKhP.js +0 -1
  256. package/dist/gateway/static/root/assets/apps-page-DduJDWGY.js +0 -1
  257. package/dist/gateway/static/root/assets/automations-workspace-X7hNHCjW.js +0 -6
  258. package/dist/gateway/static/root/assets/browser-settings-page-BZ7nK_pN.js +0 -8
  259. package/dist/gateway/static/root/assets/capabilities-settings-panel-BfKvJO1C.js +0 -7
  260. package/dist/gateway/static/root/assets/channels-settings-D1UDxJuA.js +0 -1
  261. package/dist/gateway/static/root/assets/connectors-page-C2nuqs_O.js +0 -2
  262. package/dist/gateway/static/root/assets/cron-expression-DlyRIyUn.js +0 -2
  263. package/dist/gateway/static/root/assets/date-picker-CU-ij_yE.js +0 -1
  264. package/dist/gateway/static/root/assets/extension-settings-page-CMyt0A32.js +0 -1
  265. package/dist/gateway/static/root/assets/gateway-settings-ogv8ZbvG.js +0 -1
  266. package/dist/gateway/static/root/assets/heartbeat-settings-BnrMRKaZ.js +0 -1
  267. package/dist/gateway/static/root/assets/home-page-CbcJCREd.js +0 -1
  268. package/dist/gateway/static/root/assets/index-7PZ6jmhy.css +0 -2
  269. package/dist/gateway/static/root/assets/index-CfyyA9-g.js +0 -74
  270. package/dist/gateway/static/root/assets/local-app-workbench-page-D5XVZnK1.js +0 -2
  271. package/dist/gateway/static/root/assets/locale-store-BQ2HKTWb.js +0 -1
  272. package/dist/gateway/static/root/assets/logs-page-CWDU1AGN.js +0 -2
  273. package/dist/gateway/static/root/assets/management-settings-CuFNgQUy.js +0 -1
  274. package/dist/gateway/static/root/assets/mobile-pairing-wizard-C7d_ztgp.js +0 -1
  275. package/dist/gateway/static/root/assets/note-detail-panel-D5JuBLyt.js +0 -5
  276. package/dist/gateway/static/root/assets/notes-page-C5-ccCi4.js +0 -8
  277. package/dist/gateway/static/root/assets/popover-select-CKBYnT3c.js +0 -1
  278. package/dist/gateway/static/root/assets/proactive-page-fHjPigmx.js +0 -1
  279. package/dist/gateway/static/root/assets/project-detail-page-6v_khvEt.js +0 -1
  280. package/dist/gateway/static/root/assets/projects-page-CCy1aK4V.js +0 -1
  281. package/dist/gateway/static/root/assets/remote-access-hub-pkqKRnch.js +0 -1
  282. package/dist/gateway/static/root/assets/sessions-page-Cr4E4cap.js +0 -1
  283. package/dist/gateway/static/root/assets/settings-advanced-gate-D1JRDRyL.js +0 -1
  284. package/dist/gateway/static/root/assets/setup-status-panel-Cc_iP_vv.js +0 -1
  285. package/dist/gateway/static/root/assets/shares-settings-BrMECMAB.js +0 -1
  286. package/dist/gateway/static/root/assets/skill-reload-api-DuqIDYjc.js +0 -1
  287. package/dist/gateway/static/root/assets/skills-page.utils-D1wGfm22.js +0 -1
  288. package/dist/gateway/static/root/assets/task-detail-page-m0oXUKl2.js +0 -1
  289. package/dist/gateway/static/root/assets/tunnel-api-Dur80zSQ.js +0 -1
  290. package/dist/gateway/static/root/assets/user-model-page-Dl10D_5q.js +0 -2
  291. package/dist/gateway/static/root/assets/workflows-page-CswgoIFU.js +0 -6
  292. package/dist/src/proactive/actions/workflow.d.ts +0 -15
  293. package/dist/src/proactive/actions/workflow.js +0 -88
@@ -3,10 +3,10 @@ import { resolveSiteShareConfig } from "../../../share/site-share-config.js";
3
3
  import { getSiteShareStore } from "../../../share/site-share-store.js";
4
4
  import { resolveSiteShareUrl } from "../../../share/share-url.js";
5
5
  import { resolveReverseProxyPublicUrl } from "../../public-url.js";
6
- import { extractToken } from "../../auth.js";
6
+ import { getGatewayPrincipal } from "../../security/gateway-principal.js";
7
7
  import { createHash } from "node:crypto";
8
8
  //#region src/gateway/hono/routes/site-shares.ts
9
- function hashGatewayToken(token) {
9
+ function hashPrincipal(token) {
10
10
  return createHash("sha256").update(token, "utf8").digest("hex").slice(0, 12);
11
11
  }
12
12
  function buildShareUrls(record, publicHostSuffix, service) {
@@ -42,11 +42,7 @@ function registerSiteShareRoutes(authenticated, deps) {
42
42
  return resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg));
43
43
  }
44
44
  authenticated.post("/api/site-shares", async (c) => {
45
- const gatewayToken = extractToken({ authorization: c.req.header("authorization") ?? void 0 });
46
- if (!gatewayToken) return c.json({
47
- ok: false,
48
- error: { message: "Token required" }
49
- }, 401);
45
+ const principalId = getGatewayPrincipal(c).principalId;
50
46
  let body;
51
47
  try {
52
48
  body = await c.req.json();
@@ -96,7 +92,7 @@ function registerSiteShareRoutes(authenticated, deps) {
96
92
  sessionKey,
97
93
  agentId,
98
94
  workspaceRoot,
99
- gatewayTokenHash: hashGatewayToken(gatewayToken)
95
+ gatewayTokenHash: hashPrincipal(principalId)
100
96
  });
101
97
  const urls = buildShareUrls(record, store.getConfig().publicHostSuffix, service);
102
98
  return c.json({
@@ -2,10 +2,11 @@ import { init_public_url, validatePublicUrl } from "../../../config/public-url.j
2
2
  import { TUNNEL_REGISTRATION_SECRET_REQUIRED_CODE, TunnelRegistrationSecretError, getTunnelRegistrationSecretMeta, readTunnelRegistrationSecretFromConfigOnly, resolveTunnelBrokerUrl } from "../../../tunnel/env.js";
3
3
  import { logTunnelAudit } from "../../../tunnel/tunnel-audit.js";
4
4
  import { getTunnelService, hashGatewayToken } from "../../../tunnel/tunnel-service.js";
5
- import { extractToken } from "../../auth.js";
5
+ import { requireTunnelGatewayToken } from "../../../tunnel/auth-policy.js";
6
6
  import { TUNNEL_CONSENT_REQUIRED_CODE, TunnelConsentError, assertTunnelMayStart, getTunnelConsentState } from "../../../tunnel/consent.js";
7
7
  import { configureTunnelFromGatewayConfig } from "../../../tunnel/gateway-lifecycle.js";
8
8
  import { applyTunnelConsentToConfig, mergeTunnelConfigPatch, setTunnelEnabledInConfig } from "../../../tunnel/tunnel-config.js";
9
+ import { getGatewayPrincipal } from "../../security/gateway-principal.js";
9
10
  import { consumeTunnelMutationLimit } from "../../../tunnel/tunnel-rate-limit.js";
10
11
  import "../../../tunnel/index.js";
11
12
  import { provisionTunnelRegistrationKey } from "../../../tunnel/xopc-cloud-registration.js";
@@ -36,14 +37,9 @@ function enrichTunnelStatus(config, status) {
36
37
  registrationSecret
37
38
  };
38
39
  }
39
- function requireGatewayToken(c) {
40
- return extractToken({ authorization: c.req.header("authorization") ?? void 0 }) ?? null;
41
- }
42
40
  function createTunnelMutationRateLimitMiddleware() {
43
41
  return async (c, next) => {
44
- const token = requireGatewayToken(c);
45
- if (!token) return c.json({ error: "Gateway token required" }, 401);
46
- const result = consumeTunnelMutationLimit(token);
42
+ const result = consumeTunnelMutationLimit(getGatewayPrincipal(c).principalId);
47
43
  if (!result.allowed) {
48
44
  c.header("Retry-After", String(Math.ceil(result.retryAfterMs / 1e3)));
49
45
  return c.json({
@@ -66,7 +62,6 @@ function registerTunnelRoutes(authenticated, deps) {
66
62
  * the UI can render targeted hints (TLS / DNS / wrong service / blocked path).
67
63
  */
68
64
  authenticated.post("/api/tunnel/probe-public", tunnelMutationLimit, async (c) => {
69
- if (!requireGatewayToken(c)) return c.json({ error: "Gateway token required" }, 401);
70
65
  let body;
71
66
  try {
72
67
  body = await c.req.json();
@@ -142,8 +137,6 @@ function registerTunnelRoutes(authenticated, deps) {
142
137
  return c.json(enrichTunnelStatus(config, tunnel.getStatus()));
143
138
  });
144
139
  authenticated.post("/api/tunnel/consent", tunnelMutationLimit, async (c) => {
145
- const token = requireGatewayToken(c);
146
- if (!token) return c.json({ error: "Gateway token required" }, 401);
147
140
  const config = deps.service.currentConfig;
148
141
  applyTunnelConsentToConfig(config);
149
142
  const result = await deps.service.saveConfig(config);
@@ -154,7 +147,7 @@ function registerTunnelRoutes(authenticated, deps) {
154
147
  const consent = getTunnelConsentState(config);
155
148
  logTunnelAudit("tunnel.consent", {
156
149
  consentVersion: consent.currentVersion,
157
- gatewayTokenHash: hashGatewayToken(token).slice(0, 12)
150
+ principalId: getGatewayPrincipal(c).principalId
158
151
  }, "Remote access security consent recorded");
159
152
  return c.json({
160
153
  ok: true,
@@ -190,10 +183,17 @@ function registerTunnelRoutes(authenticated, deps) {
190
183
  }
191
184
  });
192
185
  authenticated.post("/api/tunnel/start", tunnelMutationLimit, async (c) => {
186
+ let token;
187
+ try {
188
+ token = requireTunnelGatewayToken(deps.service.getResolvedAuth());
189
+ } catch (error) {
190
+ return c.json({
191
+ error: error.message,
192
+ code: "TUNNEL_AUTH_REQUIRED"
193
+ }, 403);
194
+ }
193
195
  await configureTunnelFromService(deps, { force: true });
194
196
  const config = deps.service.currentConfig;
195
- const token = requireGatewayToken(c);
196
- if (!token) return c.json({ error: "Gateway token required" }, 401);
197
197
  try {
198
198
  assertTunnelMayStart(config);
199
199
  } catch (err) {
@@ -19,6 +19,23 @@ export declare function getAgentImageGenerationConfig(config: Config, agentIdRaw
19
19
  timeoutMs?: number;
20
20
  };
21
21
  };
22
+ export declare function getDefaultImageGenerationConfig(config: Config): {
23
+ model: {
24
+ primary: string;
25
+ fallbacks: string[];
26
+ autoProviderFallback: boolean;
27
+ timeoutMs?: number;
28
+ };
29
+ };
30
+ export declare function prepareDefaultImageGenerationSetup(config: Config, input: ImageGenerationSetupInput): {
31
+ ok: true;
32
+ config: Config;
33
+ providerId: string;
34
+ modelId: string;
35
+ } | {
36
+ ok: false;
37
+ error: string;
38
+ };
22
39
  export declare function prepareImageGenerationSetup(config: Config, agentIdRaw: string, input: ImageGenerationSetupInput): {
23
40
  ok: true;
24
41
  config: Config;
@@ -59,12 +59,10 @@ function getAgentImageGenerationConfig(config, agentIdRaw) {
59
59
  model: resolveEffectiveAgentConfigForAgent(config, agentId).config.models.imageGeneration ?? null
60
60
  };
61
61
  }
62
- function prepareImageGenerationSetup(config, agentIdRaw, input) {
63
- const agentId = normalizeAgentId(agentIdRaw);
64
- if (!config.agents.list.some((entry) => entry.enabled !== false && normalizeAgentId(entry.id) === agentId)) return {
65
- ok: false,
66
- error: `Agent not found: ${agentId}`
67
- };
62
+ function getDefaultImageGenerationConfig(config) {
63
+ return { model: config.agents.defaults.models.imageGeneration ?? null };
64
+ }
65
+ function prepareImageGenerationConfig(config, input, applyModel) {
68
66
  const providerId = input.providerId.trim();
69
67
  const provider = getImageGenerationProvider(providerId);
70
68
  if (!provider) return {
@@ -82,11 +80,6 @@ function prepareImageGenerationSetup(config, agentIdRaw, input) {
82
80
  error: parsedProviderConfig.error
83
81
  };
84
82
  const next = structuredClone(config);
85
- const index = next.agents.list.findIndex((entry) => entry.enabled !== false && normalizeAgentId(entry.id) === agentId);
86
- if (index < 0) return {
87
- ok: false,
88
- error: `Agent not found: ${agentId}`
89
- };
90
83
  next.providers = {
91
84
  ...next.providers ?? {},
92
85
  [providerId]: {
@@ -94,15 +87,11 @@ function prepareImageGenerationSetup(config, agentIdRaw, input) {
94
87
  ...parsedProviderConfig.value
95
88
  }
96
89
  };
97
- const entry = next.agents.list[index];
98
- entry.models = {
99
- ...entry.models ?? {},
100
- imageGeneration: {
101
- primary: `${providerId}/${modelId}`,
102
- fallbacks: [],
103
- autoProviderFallback: false
104
- }
105
- };
90
+ applyModel(next, {
91
+ primary: `${providerId}/${modelId}`,
92
+ fallbacks: [],
93
+ autoProviderFallback: false
94
+ });
106
95
  const parsed = ConfigSchema.safeParse(next);
107
96
  if (!parsed.success) return {
108
97
  ok: false,
@@ -115,6 +104,26 @@ function prepareImageGenerationSetup(config, agentIdRaw, input) {
115
104
  modelId
116
105
  };
117
106
  }
107
+ function prepareDefaultImageGenerationSetup(config, input) {
108
+ return prepareImageGenerationConfig(config, input, (next, model) => {
109
+ next.agents.defaults.models.imageGeneration = model;
110
+ });
111
+ }
112
+ function prepareImageGenerationSetup(config, agentIdRaw, input) {
113
+ const agentId = normalizeAgentId(agentIdRaw);
114
+ if (!config.agents.list.some((entry) => entry.enabled !== false && normalizeAgentId(entry.id) === agentId)) return {
115
+ ok: false,
116
+ error: `Agent not found: ${agentId}`
117
+ };
118
+ return prepareImageGenerationConfig(config, input, (next, model) => {
119
+ const index = next.agents.list.findIndex((entry) => entry.enabled !== false && normalizeAgentId(entry.id) === agentId);
120
+ const entry = next.agents.list[index];
121
+ entry.models = {
122
+ ...entry.models ?? {},
123
+ imageGeneration: model
124
+ };
125
+ });
126
+ }
118
127
  async function verifyImageGenerationCredential(input) {
119
128
  const apiKey = input.apiKey.trim();
120
129
  if (!apiKey) return {
@@ -165,4 +174,4 @@ async function verifyImageGenerationCredential(input) {
165
174
  }
166
175
  }
167
176
  //#endregion
168
- export { getAgentImageGenerationConfig, getImageGenerationCatalog, prepareImageGenerationSetup, verifyImageGenerationCredential };
177
+ export { getAgentImageGenerationConfig, getDefaultImageGenerationConfig, getImageGenerationCatalog, prepareDefaultImageGenerationSetup, prepareImageGenerationSetup, verifyImageGenerationCredential };
@@ -34,6 +34,7 @@ export declare function authPolicyConfig(cfg: ResolvedAuthRateLimitConfig): Auth
34
34
  declare class BucketRegistry {
35
35
  private authFailureLimiter?;
36
36
  private authFailureSignature?;
37
+ private identityChallengeLimiter?;
37
38
  private strictApiLimiter?;
38
39
  private chatApiLimiter?;
39
40
  private mediaApiLimiter?;
@@ -50,6 +51,8 @@ declare class BucketRegistry {
50
51
  * config read.
51
52
  */
52
53
  authFailure(cfg: ResolvedAuthRateLimitConfig): FailureLimiter;
54
+ /** Global pre-authentication signing budget; independent of authenticated traffic. */
55
+ identityChallenge(): RateLimiter;
53
56
  /** Authenticated admin / mutation endpoints — 150 req / 60 s per client IP. */
54
57
  strictApi(): RateLimiter;
55
58
  /** Interactive chat actions — 180 req / 60 s per client IP. */
@@ -46,6 +46,7 @@ function authPolicyConfig(cfg) {
46
46
  var BucketRegistry = class {
47
47
  authFailureLimiter;
48
48
  authFailureSignature;
49
+ identityChallengeLimiter;
49
50
  strictApiLimiter;
50
51
  chatApiLimiter;
51
52
  mediaApiLimiter;
@@ -75,6 +76,13 @@ var BucketRegistry = class {
75
76
  }
76
77
  return this.authFailureLimiter;
77
78
  }
79
+ /** Global pre-authentication signing budget; independent of authenticated traffic. */
80
+ identityChallenge() {
81
+ return this.identityChallengeLimiter ??= new RateLimiter({
82
+ maxRequests: 300,
83
+ windowMs: 6e4
84
+ });
85
+ }
78
86
  /** Authenticated admin / mutation endpoints — 150 req / 60 s per client IP. */
79
87
  strictApi() {
80
88
  if (!this.strictApiLimiter) this.strictApiLimiter = new RateLimiter({
@@ -158,6 +166,7 @@ var BucketRegistry = class {
158
166
  }
159
167
  destroyAll() {
160
168
  this.authFailureLimiter?.destroy();
169
+ this.identityChallengeLimiter?.destroy();
161
170
  this.strictApiLimiter?.destroy();
162
171
  this.chatApiLimiter?.destroy();
163
172
  this.mediaApiLimiter?.destroy();
@@ -169,6 +178,7 @@ var BucketRegistry = class {
169
178
  this.sharePublicShortLimiter?.destroy();
170
179
  this.sharePublicLongLimiter?.destroy();
171
180
  this.authFailureLimiter = void 0;
181
+ this.identityChallengeLimiter = void 0;
172
182
  this.strictApiLimiter = void 0;
173
183
  this.chatApiLimiter = void 0;
174
184
  this.mediaApiLimiter = void 0;
@@ -1,6 +1,7 @@
1
1
  import { isAllInterfacesHost, isLoopbackHost, resolveGatewayCorsOrigins } from "./host.js";
2
2
  import { resolveGatewayListenPlan } from "./listen.js";
3
3
  import { assertTailscaleExposureCompatible } from "./tailscale-lifecycle.js";
4
+ import { requireTunnelGatewayToken } from "../tunnel/auth-policy.js";
4
5
  import { isAuthRateLimitGloballyDisabled, isGatewayStrictSecurityEnabled } from "./rate-limit/env-flags.js";
5
6
  import "./rate-limit/index.js";
6
7
  //#region src/gateway/runtime-config.ts
@@ -15,6 +16,7 @@ function hasSharedSecret(auth) {
15
16
  * Throws when bind/auth/origin combinations are unsafe for network exposure.
16
17
  */
17
18
  function assertGatewayRuntimeConfig(params) {
19
+ if (params.cfg.tunnel?.enabled) requireTunnelGatewayToken(params.auth);
18
20
  const { bindMode, bindHost, customBindHost } = resolveGatewayListenPlan({
19
21
  cfg: params.cfg,
20
22
  bindOverride: params.bindOverride
@@ -0,0 +1,5 @@
1
+ import type { Context } from 'hono';
2
+ export declare function readBrowserSessionCookie(c: Context): string | undefined;
3
+ export declare function browserCookieRequestAllowed(c: Context): boolean;
4
+ export declare function writeBrowserSessionCookie(c: Context, token: string, expiresAt: number): void;
5
+ export declare function clearBrowserSessionCookie(c: Context): void;
@@ -0,0 +1,45 @@
1
+ import { isLoopbackHost } from "../host.js";
2
+ import { deleteCookie, getCookie, setCookie } from "hono/cookie";
3
+ //#region src/gateway/security/browser-session.ts
4
+ function origin(c) {
5
+ return new URL(`http://${c.req.header("host") ?? new URL(c.req.url).host}`);
6
+ }
7
+ function secure(c) {
8
+ return !isLoopbackHost(origin(c).hostname.replace(/^\[|\]$/g, ""));
9
+ }
10
+ function name(c) {
11
+ return secure(c) ? "__Host-xopc-session" : "xopc-local-session";
12
+ }
13
+ function readBrowserSessionCookie(c) {
14
+ return getCookie(c, name(c));
15
+ }
16
+ function browserCookieRequestAllowed(c) {
17
+ const requestOrigin = c.req.header("origin");
18
+ if (requestOrigin) try {
19
+ const parsed = new URL(requestOrigin);
20
+ const localOrigin = isLoopbackHost(parsed.hostname.replace(/^\[|\]$/g, ""));
21
+ return (parsed.host === origin(c).host || !secure(c) && localOrigin) && (parsed.protocol === "https:" || !secure(c) && parsed.protocol === "http:");
22
+ } catch {
23
+ return false;
24
+ }
25
+ return ["GET", "HEAD"].includes(c.req.method) && c.req.header("sec-fetch-site") !== "cross-site";
26
+ }
27
+ function writeBrowserSessionCookie(c, token, expiresAt) {
28
+ setCookie(c, name(c), token, {
29
+ httpOnly: true,
30
+ secure: secure(c),
31
+ sameSite: "Strict",
32
+ path: "/",
33
+ expires: new Date(expiresAt)
34
+ });
35
+ }
36
+ function clearBrowserSessionCookie(c) {
37
+ deleteCookie(c, name(c), {
38
+ httpOnly: true,
39
+ secure: secure(c),
40
+ sameSite: "Strict",
41
+ path: "/"
42
+ });
43
+ }
44
+ //#endregion
45
+ export { browserCookieRequestAllowed, clearBrowserSessionCookie, readBrowserSessionCookie, writeBrowserSessionCookie };
@@ -5,6 +5,7 @@ export type GatewayPrincipal = {
5
5
  principalId: string;
6
6
  deviceId?: string;
7
7
  accessSessionId?: string;
8
+ browserSessionId?: string;
8
9
  scopes: readonly GatewayScope[];
9
10
  };
10
11
  export declare function setGatewayPrincipal(c: Context, principal: GatewayPrincipal): void;
@@ -48,6 +48,7 @@ export declare class GatewayService {
48
48
  private readonly modelCatalogSync;
49
49
  private auth;
50
50
  readonly endpointTools: EndpointToolRuntime;
51
+ private isRealtimePrincipalActive;
51
52
  readonly realtime: RealtimeRuntime;
52
53
  readonly voiceRealtime: VoiceRealtimeRuntime;
53
54
  getConfig(): Config;
@@ -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";
@@ -122,6 +122,7 @@ import { GatewaySessionsApi } from "./service/sessions-api.js";
122
122
  import { GatewayMarketplaceService } from "./service/marketplace-service.js";
123
123
  import { GatewayConfigCoordinator } from "./service/config-coordinator.js";
124
124
  import { GatewayAgentRunner } from "./service/agent-runner.js";
125
+ import { isBrowserSessionActive } from "../storage/sqlite/browser-session-repository.js";
125
126
  import { RealtimeRuntime } from "../realtime/runtime.js";
126
127
  import { VoiceRealtimeRuntime } from "../voice/realtime/runtime.js";
127
128
  import { DurableVoiceAgentBroker } from "../voice/realtime/agentBroker.js";
@@ -165,8 +166,17 @@ var GatewayService = class {
165
166
  });
166
167
  auth;
167
168
  endpointTools = new EndpointToolRuntime();
168
- realtime = new RealtimeRuntime(this.endpointTools);
169
+ isRealtimePrincipalActive = (principalId) => {
170
+ if (!principalId.startsWith("browser:")) return true;
171
+ try {
172
+ return isBrowserSessionActive(principalId.slice(8), this.auth);
173
+ } catch {
174
+ return false;
175
+ }
176
+ };
177
+ realtime = new RealtimeRuntime(this.endpointTools, this.isRealtimePrincipalActive);
169
178
  voiceRealtime = new VoiceRealtimeRuntime({
179
+ isPrincipalActive: this.isRealtimePrincipalActive,
170
180
  getConversationContext: async (sessionKey, expectedSessionId) => {
171
181
  if ((await this.sessionIndex.getSessionMetadata(sessionKey))?.sessionId !== expectedSessionId) throw new Error("Conversation changed before voice connection");
172
182
  const messages = await this.sessionIndex.loadMessages(sessionKey);
@@ -1,6 +1,6 @@
1
1
  import { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, shouldSilence, stripHeartbeatToken } from "./tokens.js";
2
+ import { appendCronEventLines } from "./event-prompt.js";
2
3
  import { isWithinActiveHours } from "./active-hours.js";
3
4
  import { isHeartbeatContentEmpty } from "./content-check.js";
4
- import { appendCronEventLines } from "./event-prompt.js";
5
5
  import { createHeartbeatWake } from "./wake.js";
6
6
  export { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, appendCronEventLines, createHeartbeatWake, isHeartbeatContentEmpty, isWithinActiveHours, shouldSilence, stripHeartbeatToken };
@@ -11,6 +11,7 @@ export type Clock = () => number;
11
11
  export type KeyedStoreOptions = {
12
12
  /** Drop entries whose `lastTouchedMs` is older than this. */
13
13
  staleAfterMs: number;
14
+ maxEntries?: number;
14
15
  /** How often the sweep runs. Defaults to `staleAfterMs / 4` (capped at 10min). */
15
16
  cleanupIntervalMs?: number;
16
17
  /** Injected clock for deterministic tests. */
@@ -20,6 +21,8 @@ export declare class KeyedStore<V extends {
20
21
  lastTouchedMs: number;
21
22
  }> {
22
23
  private readonly map;
24
+ private readonly maxEntries;
25
+ private overflow?;
23
26
  private readonly clock;
24
27
  private readonly staleAfterMs;
25
28
  private cleanupTimer?;
@@ -1,10 +1,13 @@
1
1
  //#region src/infra/rate-limit/keyed-store.ts
2
2
  var KeyedStore = class {
3
3
  map = /* @__PURE__ */ new Map();
4
+ maxEntries;
5
+ overflow;
4
6
  clock;
5
7
  staleAfterMs;
6
8
  cleanupTimer;
7
9
  constructor(opts) {
10
+ this.maxEntries = Math.max(1, opts.maxEntries ?? 1e4);
8
11
  this.clock = opts.clock ?? Date.now;
9
12
  this.staleAfterMs = Math.max(1e3, opts.staleAfterMs);
10
13
  const interval = Math.min(600 * 1e3, Math.max(1e3, opts.cleanupIntervalMs ?? Math.floor(this.staleAfterMs / 4)));
@@ -12,10 +15,11 @@ var KeyedStore = class {
12
15
  this.cleanupTimer.unref?.();
13
16
  }
14
17
  get(key) {
15
- return this.map.get(key);
18
+ return this.map.get(key) ?? (this.map.size >= this.maxEntries ? this.overflow : void 0);
16
19
  }
17
20
  set(key, value) {
18
- this.map.set(key, value);
21
+ if (this.map.has(key) || this.map.size < this.maxEntries) this.map.set(key, value);
22
+ else this.overflow ??= value;
19
23
  }
20
24
  delete(key) {
21
25
  this.map.delete(key);
@@ -25,6 +29,7 @@ var KeyedStore = class {
25
29
  }
26
30
  clear() {
27
31
  this.map.clear();
32
+ this.overflow = void 0;
28
33
  }
29
34
  destroy() {
30
35
  if (this.cleanupTimer) {
@@ -32,9 +37,11 @@ var KeyedStore = class {
32
37
  this.cleanupTimer = void 0;
33
38
  }
34
39
  this.map.clear();
40
+ this.overflow = void 0;
35
41
  }
36
42
  sweep() {
37
43
  const now = this.clock();
44
+ if (this.overflow && now - this.overflow.lastTouchedMs > this.staleAfterMs) this.overflow = void 0;
38
45
  for (const [k, v] of this.map.entries()) if (now - v.lastTouchedMs > this.staleAfterMs) this.map.delete(k);
39
46
  }
40
47
  };
@@ -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[]);