@xopcai/xopc 0.0.249 → 0.0.250

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 (229) 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-B759R_qf.js → activity-store-DfBjTSo9.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BUu7EnwM.js → agent-avatar-dicebear-BN6FJXkJ.js} +1 -1
  5. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-C7rZH1A2.js +1 -0
  6. package/dist/gateway/static/root/assets/{agents-DK9HjHO0.js → agents-CgGaoo4z.js} +1 -1
  7. package/dist/gateway/static/root/assets/{api-Cg0v7Lpn.js → api-zxpcJfgj.js} +1 -1
  8. package/dist/gateway/static/root/assets/{app-management-settings-panel-C9DkCW_d.js → app-management-settings-panel-D2gMshuS.js} +1 -1
  9. package/dist/gateway/static/root/assets/{appearance-settings-CFggS95Y.js → appearance-settings-wMu0jSKx.js} +1 -1
  10. package/dist/gateway/static/root/assets/{apps-page-jOvT-fzU.js → apps-page-KF1Gnv36.js} +1 -1
  11. package/dist/gateway/static/root/assets/{archive-plugin-BQrilVVv.js → archive-plugin-u6EE3JV8.js} +1 -1
  12. package/dist/gateway/static/root/assets/{attachment-load-BG0BliqV.js → attachment-load-DbJurnv-.js} +1 -1
  13. package/dist/gateway/static/root/assets/{automations-page-Bo4RiTkh.js → automations-page-Ew_e5HDn.js} +1 -1
  14. package/dist/gateway/static/root/assets/automations-workspace-Ch-ldu35.js +6 -0
  15. package/dist/gateway/static/root/assets/{binary-plugins-BCnyNU0C.js → binary-plugins-DtDFNfPM.js} +1 -1
  16. package/dist/gateway/static/root/assets/{block-editor-Db8DlVvg.js → block-editor-CnAwmabq.js} +50 -50
  17. package/dist/gateway/static/root/assets/browser-settings-page-DtVhsHJW.js +8 -0
  18. package/dist/gateway/static/root/assets/{browser-workflow-inputs-C71vfl0b.js → browser-workflow-inputs-BX1-uM9L.js} +1 -1
  19. package/dist/gateway/static/root/assets/{browser-workflows-page-vvmSYKsO.js → browser-workflows-page-CcbUOWDF.js} +2 -2
  20. package/dist/gateway/static/root/assets/capabilities-settings-panel--sXeylhe.js +7 -0
  21. package/dist/gateway/static/root/assets/channels-settings-AXSBDujZ.js +1 -0
  22. package/dist/gateway/static/root/assets/{channels-status-swr-CKyV3jY5.js → channels-status-swr-CX-yWwLD.js} +1 -1
  23. package/dist/gateway/static/root/assets/{chat-terminal-dock-B1Xd6OFB.js → chat-terminal-dock-CryTDNdD.js} +2 -2
  24. package/dist/gateway/static/root/assets/connectors-page-HBHUWohz.js +2 -0
  25. package/dist/gateway/static/root/assets/{cron-expression-D-F9vjtE.js → cron-expression-ji5aWrjG.js} +1 -1
  26. package/dist/gateway/static/root/assets/{date-picker-B2OoYvic.js → date-picker-Dro_w3eX.js} +1 -1
  27. package/dist/gateway/static/root/assets/{dependency-picker-BiGx9Sbj.js → dependency-picker-Ce19KKnX.js} +1 -1
  28. package/dist/gateway/static/root/assets/{desktop-pet-BNMRqipe.js → desktop-pet-DsSi-3uZ.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-settings-DeYbIV7A.js → desktop-pet-settings-8WQ4woJy.js} +1 -1
  30. package/dist/gateway/static/root/assets/{extension-debug-page-COyn05ub.js → extension-debug-page-CgvEBfLZ.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-page-oH43chS2.js → extension-page-DkznBbMj.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-settings-page-BMO59994.js → extension-settings-page-BOjhchK2.js} +1 -1
  33. package/dist/gateway/static/root/assets/files-BArWTfr7.js +1 -0
  34. package/dist/gateway/static/root/assets/{gateway-config-api-cimpViGk.js → gateway-config-api-OEruhhX3.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-config-swr-BGdHwT4e.js → gateway-config-swr-CMNbl0FZ.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-settings-BHJtnSic.js → gateway-settings-BgH3A0LO.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-startup-retry-CuaM3b4c.js → gateway-startup-retry-CR7Xg8As.js} +1 -1
  38. package/dist/gateway/static/root/assets/heartbeat-settings-C97naDkO.js +1 -0
  39. package/dist/gateway/static/root/assets/home-page-BBKKme4G.js +1 -0
  40. package/dist/gateway/static/root/assets/{image-generation-api-D7duj7Uj.js → image-generation-api-C5mn73ca.js} +1 -1
  41. package/dist/gateway/static/root/assets/index-BcaF-dgQ.js +72 -0
  42. package/dist/gateway/static/root/assets/{index-DGeGmj4k.css → index-DAryGvZ7.css} +1 -1
  43. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-D8Zw_lYd.js → keyboard-shortcuts-settings-BYhfzsqe.js} +1 -1
  44. package/dist/gateway/static/root/assets/{local-app-workbench-page-eBFVWmtH.js → local-app-workbench-page-DNncc2tn.js} +2 -2
  45. package/dist/gateway/static/root/assets/{local-apps-page-CvPDPRwb.js → local-apps-page-vBlknU7C.js} +1 -1
  46. package/dist/gateway/static/root/assets/{locale-store-zEL8bkwx.js → locale-store-CF4erhjB.js} +1 -1
  47. package/dist/gateway/static/root/assets/{logs-page-ClvcWlL6.js → logs-page-CizZInrT.js} +2 -2
  48. package/dist/gateway/static/root/assets/{management-settings-D8moh99U.js → management-settings-Dnx6mSNe.js} +1 -1
  49. package/dist/gateway/static/root/assets/{markdown-split-D7V3j0vE.js → markdown-split-DtBtcHWi.js} +1 -1
  50. package/dist/gateway/static/root/assets/{markdown-view-DGRN-8wP.js → markdown-view-CQvzsE24.js} +1 -1
  51. package/dist/gateway/static/root/assets/{media-plugins-BLaE5b1Y.js → media-plugins-DrMYeHe7.js} +1 -1
  52. package/dist/gateway/static/root/assets/messages-Cf5hpZE6.js +3 -0
  53. package/dist/gateway/static/root/assets/{mobile-pairing-wizard-DiVDuCxl.js → mobile-pairing-wizard-AKgGy3Kx.js} +1 -1
  54. package/dist/gateway/static/root/assets/note-detail-panel-Bw3jD9Jf.js +5 -0
  55. package/dist/gateway/static/root/assets/notes-page-Dpqq7Z-J.js +8 -0
  56. package/dist/gateway/static/root/assets/{page-tabs-BFMGjA60.js → page-tabs-CX9T71by.js} +1 -1
  57. package/dist/gateway/static/root/assets/{preview-open-alternatives-DNEWZN7H.js → preview-open-alternatives-DvEHoimN.js} +1 -1
  58. package/dist/gateway/static/root/assets/{product-open-page-Co5u7asH.js → product-open-page-COcr_NUJ.js} +1 -1
  59. package/dist/gateway/static/root/assets/project-detail-page-BuT6MCTs.js +1 -0
  60. package/dist/gateway/static/root/assets/projects-page-DXWMxOjf.js +1 -0
  61. package/dist/gateway/static/root/assets/{registry-api-Cg92zSod.js → registry-api-BsRBlji7.js} +1 -1
  62. package/dist/gateway/static/root/assets/remote-access-hub-7rBCUWzZ.js +1 -0
  63. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-C0ByNmlV.js → runtime-tools-settings-panel-CQ13P-mS.js} +1 -1
  64. package/dist/gateway/static/root/assets/{schema-form-Dq_VQpuY.js → schema-form-BUVyTpZj.js} +1 -1
  65. package/dist/gateway/static/root/assets/sessions-page-gmEOYNb4.js +1 -0
  66. package/dist/gateway/static/root/assets/settings-advanced-gate-DYYoJcl7.js +1 -0
  67. package/dist/gateway/static/root/assets/{settings-form-section-CZu6FX4k.js → settings-form-section-DVY-8_B9.js} +1 -1
  68. package/dist/gateway/static/root/assets/{settings-page-S8ekeUZd.js → settings-page-CdiVYyTl.js} +1 -1
  69. package/dist/gateway/static/root/assets/{setup-status-panel-BdVmwXMv.js → setup-status-panel-BhenBnUj.js} +1 -1
  70. package/dist/gateway/static/root/assets/{share-preview-page-D2fEidbn.js → share-preview-page-C88YLKm4.js} +1 -1
  71. package/dist/gateway/static/root/assets/shares-settings-Dq7xIj0_.js +1 -0
  72. package/dist/gateway/static/root/assets/skill-reload-api-MDI9Lz6z.js +1 -0
  73. package/dist/gateway/static/root/assets/{skills-page-AYiPlgZE.js → skills-page-DLir1nM0.js} +1 -1
  74. package/dist/gateway/static/root/assets/{skills-page.utils-DGzl-ib-.js → skills-page.utils-BMZAfS3G.js} +1 -1
  75. package/dist/gateway/static/root/assets/{system-settings-panel-5Xd5mIiR.js → system-settings-panel-BM8ivYan.js} +1 -1
  76. package/dist/gateway/static/root/assets/task-detail-page-P0_RldWv.js +1 -0
  77. package/dist/gateway/static/root/assets/{theme-store-ZVClZKQ0.js → theme-store-BOgkc_9D.js} +1 -1
  78. package/dist/gateway/static/root/assets/{tunnel-api-CdZN1Jin.js → tunnel-api-DemxChjo.js} +1 -1
  79. package/dist/gateway/static/root/assets/{use-autosave-czRI0NBc.js → use-autosave-CV3Ui5hu.js} +1 -1
  80. package/dist/gateway/static/root/assets/user-model-page-CxfnoRVn.js +2 -0
  81. package/dist/gateway/static/root/assets/{voice-api-key-field-8YEvA3cU.js → voice-api-key-field-CUoCi4Sq.js} +1 -1
  82. package/dist/gateway/static/root/assets/{voice-config-api-CopF64lY.js → voice-config-api-C-ryeIxj.js} +1 -1
  83. package/dist/gateway/static/root/assets/{work-discovery-overlay-keLtqYYJ.js → work-discovery-overlay-BhDlkCMB.js} +1 -1
  84. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Dy5WgYMO.js → workflow-run-setup-panel-D8CcPc_C.js} +2 -2
  85. package/dist/gateway/static/root/assets/workflows-page-Bxn2Dc16.js +5 -0
  86. package/dist/gateway/static/root/index.html +11 -11
  87. package/dist/package.js +1 -1
  88. package/dist/packages/gateway-contract/src/user-message-display.js +18 -0
  89. package/dist/src/agent/agent-instance-gateway.d.ts +1 -1
  90. package/dist/src/agent/agent-manager.d.ts +9 -9
  91. package/dist/src/agent/agent-manager.js +46 -28
  92. package/dist/src/agent/background-review/prompts.d.ts +1 -1
  93. package/dist/src/agent/background-review/prompts.js +11 -2
  94. package/dist/src/agent/context/audit.d.ts +3 -1
  95. package/dist/src/agent/context/audit.js +32 -6
  96. package/dist/src/agent/context/coordinator.d.ts +6 -1
  97. package/dist/src/agent/context/coordinator.js +14 -13
  98. package/dist/src/agent/context/execution-context.d.ts +6 -47
  99. package/dist/src/agent/context/execution-context.js +79 -15
  100. package/dist/src/agent/context/execution-context.types.d.ts +50 -0
  101. package/dist/src/agent/context/execution-context.types.js +1 -0
  102. package/dist/src/agent/context/execution-scope.d.ts +5 -1
  103. package/dist/src/agent/context/execution-scope.js +6 -2
  104. package/dist/src/agent/context/project-context.d.ts +3 -0
  105. package/dist/src/agent/context/project-context.js +5 -3
  106. package/dist/src/agent/external-tools/index.d.ts +1 -0
  107. package/dist/src/agent/external-tools/index.js +1 -0
  108. package/dist/src/agent/external-tools/memory-provider.d.ts +1 -0
  109. package/dist/src/agent/external-tools/memory-provider.js +1 -0
  110. package/dist/src/agent/inbound/attachment-pipeline.js +5 -1
  111. package/dist/src/agent/memory/compaction-promotion.d.ts +1 -0
  112. package/dist/src/agent/memory/compaction-promotion.js +7 -2
  113. package/dist/src/agent/memory/index.d.ts +1 -1
  114. package/dist/src/agent/memory/index.js +3 -3
  115. package/dist/src/agent/memory/memory-config.d.ts +0 -5
  116. package/dist/src/agent/memory/memory-config.js +1 -8
  117. package/dist/src/agent/orchestration/context-overflow.js +1 -0
  118. package/dist/src/agent/service/direct-turn-helpers.d.ts +2 -2
  119. package/dist/src/agent/service/direct-turn-helpers.js +2 -2
  120. package/dist/src/agent/service/process-direct-streaming.js +3 -4
  121. package/dist/src/agent/tools/factory.d.ts +1 -0
  122. package/dist/src/agent/tools/factory.js +37 -7
  123. package/dist/src/agent/tools/knowledge-memory-tool.d.ts +6 -0
  124. package/dist/src/agent/tools/knowledge-memory-tool.js +81 -26
  125. package/dist/src/agent/tools/session-search-tool.d.ts +1 -0
  126. package/dist/src/agent/tools/session-search-tool.js +7 -0
  127. package/dist/src/agent/tools/user-context-tool.d.ts +2 -0
  128. package/dist/src/agent/tools/user-context-tool.js +21 -4
  129. package/dist/src/automations/service/automation-service.d.ts +2 -1
  130. package/dist/src/automations/service/automation-service.js +6 -2
  131. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  132. package/dist/src/connectors/connection-recovery-service.d.ts +1 -0
  133. package/dist/src/connectors/connection-recovery-service.js +46 -22
  134. package/dist/src/files/file-service.js +4 -1
  135. package/dist/src/gateway/hono/routes/connectors.js +17 -3
  136. package/dist/src/gateway/hono/routes/files.js +23 -2
  137. package/dist/src/gateway/hono/routes/tasks.js +1 -1
  138. package/dist/src/gateway/security/gateway-scopes.js +2 -0
  139. package/dist/src/gateway/service/agent-runner.js +1 -1
  140. package/dist/src/gateway/service/run-gateway-agent.js +1 -1
  141. package/dist/src/gateway/service/session-input-coordinator.js +1 -1
  142. package/dist/src/gateway/service.js +8 -4
  143. package/dist/src/knowledge-memory/domain.d.ts +1 -0
  144. package/dist/src/knowledge-memory/index.js +2 -2
  145. package/dist/src/knowledge-memory/repository.d.ts +4 -1
  146. package/dist/src/knowledge-memory/repository.js +16 -2
  147. package/dist/src/notifications/planner.js +7 -3
  148. package/dist/src/proactive/actions/service.d.ts +0 -1
  149. package/dist/src/proactive/actions/service.js +1 -10
  150. package/dist/src/proactive/execution/context.d.ts +6 -8
  151. package/dist/src/proactive/execution/context.js +78 -32
  152. package/dist/src/proactive/execution/insight.d.ts +4 -1
  153. package/dist/src/proactive/execution/insight.js +5 -2
  154. package/dist/src/proactive/execution/repository.d.ts +1 -0
  155. package/dist/src/proactive/execution/repository.js +9 -1
  156. package/dist/src/proactive/execution/types.d.ts +0 -1
  157. package/dist/src/proactive/execution/worker.js +7 -5
  158. package/dist/src/proactive/inbox/repository.js +8 -2
  159. package/dist/src/proactive/inbox/service.js +2 -2
  160. package/dist/src/proactive/inbox/types.d.ts +1 -0
  161. package/dist/src/proactive/inbox/worker.d.ts +1 -0
  162. package/dist/src/proactive/inbox/worker.js +7 -0
  163. package/dist/src/proactive/index.d.ts +1 -0
  164. package/dist/src/proactive/index.js +2 -1
  165. package/dist/src/proactive/maintenance.d.ts +4 -0
  166. package/dist/src/proactive/maintenance.js +21 -0
  167. package/dist/src/proactive/scenarios/repository.d.ts +1 -1
  168. package/dist/src/proactive/scenarios/repository.js +10 -3
  169. package/dist/src/proactive/scenarios/types.d.ts +7 -0
  170. package/dist/src/proactive/service.d.ts +7 -0
  171. package/dist/src/proactive/service.js +17 -1
  172. package/dist/src/projects/project-service.d.ts +2 -1
  173. package/dist/src/projects/project-service.js +3 -2
  174. package/dist/src/session/index.js +1 -1
  175. package/dist/src/session/store.js +5 -2
  176. package/dist/src/storage/sqlite/collaboration-rule-repository.d.ts +3 -1
  177. package/dist/src/storage/sqlite/collaboration-rule-repository.js +1 -1
  178. package/dist/src/storage/sqlite/config-repository.js +1 -1
  179. package/dist/src/storage/sqlite/connection-wait-repository.js +2 -2
  180. package/dist/src/storage/sqlite/index.js +2 -2
  181. package/dist/src/storage/sqlite/migrations/151_proactive_scope_cleanup.sql +6 -0
  182. package/dist/src/storage/sqlite/migrations/152_proactive_scenario_contract.sql +140 -0
  183. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  184. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  185. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  186. package/dist/src/storage/sqlite/row-mappers.js +2 -2
  187. package/dist/src/storage/sqlite/schema.js +1 -1
  188. package/dist/src/storage/sqlite/session-input-repository.js +1 -1
  189. package/dist/src/storage/sqlite/session-instance-repository.d.ts +2 -0
  190. package/dist/src/storage/sqlite/session-instance-repository.js +6 -0
  191. package/dist/src/storage/sqlite/session-repository.d.ts +1 -1
  192. package/dist/src/storage/sqlite/session-repository.js +3 -5
  193. package/dist/src/storage/sqlite/transcript-repository.js +2 -1
  194. package/dist/src/tasks/home-query-service.js +35 -13
  195. package/dist/src/tasks/project-monitoring-service.d.ts +2 -0
  196. package/dist/src/tasks/project-monitoring-service.js +4 -1
  197. package/dist/src/tui/backends/embedded-backend.js +1 -1
  198. package/dist/src/user-context/access-policy.d.ts +11 -0
  199. package/dist/src/user-context/access-policy.js +26 -0
  200. package/dist/src/user-model/capture/executor.d.ts +10 -0
  201. package/dist/src/user-model/capture/executor.js +99 -3
  202. package/dist/src/user-model/capture/semantic.d.ts +18 -0
  203. package/dist/src/user-model/capture/semantic.js +72 -6
  204. package/dist/src/user-model/goals.d.ts +4 -0
  205. package/dist/src/user-model/goals.js +4 -2
  206. package/package.json +3 -3
  207. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-C1rXNUAG.js +0 -1
  208. package/dist/gateway/static/root/assets/automations-workspace-BKjKTlW8.js +0 -6
  209. package/dist/gateway/static/root/assets/browser-settings-page-Dzq18pO1.js +0 -8
  210. package/dist/gateway/static/root/assets/capabilities-settings-panel-DW4SBQf4.js +0 -7
  211. package/dist/gateway/static/root/assets/channels-settings-57OGuewD.js +0 -1
  212. package/dist/gateway/static/root/assets/connectors-page-CT_I3kbR.js +0 -2
  213. package/dist/gateway/static/root/assets/files-D6vf3S30.js +0 -1
  214. package/dist/gateway/static/root/assets/heartbeat-settings-DNhrZHqx.js +0 -1
  215. package/dist/gateway/static/root/assets/home-page-BiHwiBnQ.js +0 -1
  216. package/dist/gateway/static/root/assets/index-aBs0EfQB.js +0 -72
  217. package/dist/gateway/static/root/assets/messages-W5P19VTF.js +0 -11
  218. package/dist/gateway/static/root/assets/note-detail-panel-CEEvR-fV.js +0 -5
  219. package/dist/gateway/static/root/assets/notes-page-BLqgXNCx.js +0 -8
  220. package/dist/gateway/static/root/assets/project-detail-page-CIiFJ5tk.js +0 -1
  221. package/dist/gateway/static/root/assets/projects-page-B3UF-Pfm.js +0 -1
  222. package/dist/gateway/static/root/assets/remote-access-hub-BUtpkJPG.js +0 -1
  223. package/dist/gateway/static/root/assets/sessions-page-UgJmG-V4.js +0 -1
  224. package/dist/gateway/static/root/assets/settings-advanced-gate-DDCzpdkl.js +0 -1
  225. package/dist/gateway/static/root/assets/shares-settings-BdsqnCYj.js +0 -1
  226. package/dist/gateway/static/root/assets/skill-reload-api-ghzAQKna.js +0 -1
  227. package/dist/gateway/static/root/assets/task-detail-page-BQAUaCDD.js +0 -1
  228. package/dist/gateway/static/root/assets/user-model-page-W3GTm6nA.js +0 -2
  229. package/dist/gateway/static/root/assets/workflows-page-BbAV3h7n.js +0 -5
@@ -94,6 +94,13 @@ function createSessionSearchTool(deps) {
94
94
  description: "Search other chat sessions by keywords and get short summaries, or omit `query` to list recent sessions (no LLM cost). Uses the same session store as the gateway. Narrow with roleFilter if needed.",
95
95
  parameters: SessionSearchSchema,
96
96
  async execute(_toolCallId, params, signal) {
97
+ if (deps.canAccess && !deps.canAccess()) return {
98
+ content: [{
99
+ type: "text",
100
+ text: "Cross-session history is disabled for this session."
101
+ }],
102
+ details: { error: "cross_session_history_disabled" }
103
+ };
97
104
  const p = params;
98
105
  const store = deps.getSessionStore();
99
106
  const limit = Math.min(15, Math.max(1, p.limit ?? 5));
@@ -3,6 +3,8 @@ export interface UserContextToolOptions {
3
3
  agentId: string;
4
4
  workspaceId: string;
5
5
  getSessionId: () => string | undefined;
6
+ getProjectId?: () => string | undefined;
7
+ canRead: () => boolean;
6
8
  }
7
9
  export declare function createUserContextSearchTool(options: UserContextToolOptions): AgentTool;
8
10
  export declare function createUserContextGetTool(options: UserContextToolOptions): AgentTool;
@@ -13,7 +13,10 @@ const SearchSchema = Type.Object({
13
13
  const GetSchema = Type.Object({ id: Type.String() });
14
14
  function visible(options, slotId) {
15
15
  const scope = getAssertionSlot(slotId)?.scope;
16
- return scope?.type === "global" || scope?.type === "agent" && scope.id === options.agentId || scope?.type === "workspace" && scope.id === options.workspaceId || scope?.type === "session" && scope.id === options.getSessionId();
16
+ return scope?.type === "global" || scope?.type === "agent" && scope.id === options.agentId || scope?.type === "workspace" && scope.id === options.workspaceId || scope?.type === "project" && scope.id === options.getProjectId?.() || scope?.type === "session" && scope.id === options.getSessionId();
17
+ }
18
+ function referenceable(assertion) {
19
+ return assertion.status === "active" && assertion.authority !== "external_untrusted" && assertion.sensitivity !== "secret" && assertion.sensitivity !== "regulated" && assertion.disclosurePolicy !== "ask_before_reference";
17
20
  }
18
21
  function createUserContextSearchTool(options) {
19
22
  return {
@@ -22,11 +25,18 @@ function createUserContextSearchTool(options) {
22
25
  description: "Search typed user assertions such as identity, preferences, routines, and current state.",
23
26
  parameters: SearchSchema,
24
27
  async execute(_toolCallId, raw) {
28
+ if (!options.canRead()) return {
29
+ content: [{
30
+ type: "text",
31
+ text: "User context is disabled for this session."
32
+ }],
33
+ details: { error: "user_context_disabled" }
34
+ };
25
35
  const input = raw;
26
36
  const results = listUserAssertions({
27
- statuses: ["active", "needs_review"],
37
+ statuses: ["active"],
28
38
  limit: 1e3
29
- }).filter((assertion) => visible(options, assertion.slotId)).map((assertion) => ({
39
+ }).filter((assertion) => visible(options, assertion.slotId)).filter(referenceable).map((assertion) => ({
30
40
  assertion,
31
41
  score: retrievalLexicalSimilarity(input.query, `${assertion.statement} ${assertion.normalizedValue}`)
32
42
  })).filter((item) => item.score > 0).sort((left, right) => right.score - left.score).slice(0, input.maxResults ?? 12).map(({ assertion, score }) => ({
@@ -54,9 +64,16 @@ function createUserContextGetTool(options) {
54
64
  description: "Read one typed user assertion and its subject, predicate, and scope.",
55
65
  parameters: GetSchema,
56
66
  async execute(_toolCallId, raw) {
67
+ if (!options.canRead()) return {
68
+ content: [{
69
+ type: "text",
70
+ text: "User context is disabled for this session."
71
+ }],
72
+ details: { error: "user_context_disabled" }
73
+ };
57
74
  const id = raw.id;
58
75
  const assertion = getUserAssertion(id);
59
- if (!assertion || !visible(options, assertion.slotId)) return {
76
+ if (!assertion || !visible(options, assertion.slotId) || !referenceable(assertion)) return {
60
77
  content: [{
61
78
  type: "text",
62
79
  text: `User assertion not found: ${id}`
@@ -8,6 +8,7 @@ export declare class AutomationAlreadyRunningError extends Error {
8
8
  }
9
9
  export declare class AutomationService {
10
10
  private readonly signals?;
11
+ private readonly workspaceId;
11
12
  private readonly executor;
12
13
  private timer;
13
14
  private stopped;
@@ -17,7 +18,7 @@ export declare class AutomationService {
17
18
  private readonly activeRuns;
18
19
  private readonly heartbeatTimers;
19
20
  private readonly leaseOwner;
20
- constructor(signals?: ProactiveSignalPublisher);
21
+ constructor(signals?: ProactiveSignalPublisher, workspaceId?: string);
21
22
  setDeps(deps: AutomationDeps): void;
22
23
  initialize(options?: {
23
24
  maxConcurrentRuns?: number;
@@ -34,8 +34,9 @@ var AutomationService = class {
34
34
  activeRuns = /* @__PURE__ */ new Map();
35
35
  heartbeatTimers = /* @__PURE__ */ new Map();
36
36
  leaseOwner = `automation-service:${process.pid}:${randomUUID()}`;
37
- constructor(signals) {
37
+ constructor(signals, workspaceId = "default") {
38
38
  this.signals = signals;
39
+ this.workspaceId = workspaceId;
39
40
  }
40
41
  setDeps(deps) {
41
42
  this.deps = {
@@ -462,7 +463,10 @@ var AutomationService = class {
462
463
  id: run.id
463
464
  },
464
465
  actor: { kind: "system" },
465
- scope: { workspaceId: "default" },
466
+ scope: {
467
+ workspaceId: this.workspaceId,
468
+ ...automation.projectId ? { projectId: automation.projectId } : {}
469
+ },
466
470
  occurredAt: new Date(endedAtMs).toISOString(),
467
471
  dedupeKey: `automation_run:${run.id}:failed`,
468
472
  sensitivity: "personal",
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
52
52
  id: "database-schema",
53
53
  label: "Database schema",
54
54
  status: "pass",
55
- message: `SQLite schema v${status.dbVersion} (current release v150).`,
55
+ message: `SQLite schema v${status.dbVersion} (current release v152).`,
56
56
  hints: []
57
57
  };
58
58
  }
@@ -33,6 +33,7 @@ export declare class ConnectionRecoveryService {
33
33
  private get adapter();
34
34
  snapshot(sessionKey: string): ConnectionWaitSnapshot;
35
35
  private view;
36
+ private ensureInstallation;
36
37
  private checkCapabilities;
37
38
  preflight(input: SessionInput): Promise<boolean>;
38
39
  act(sessionKey: string, action: ConnectionAction): Promise<{
@@ -1,17 +1,19 @@
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 { cancelConnectionObjective, getActiveConnectionWait, getConnectionWait, listConnectionWaitsToCheck, publishConnectionWait, queueConnectionResolution, updateConnectionWait } from "../storage/sqlite/connection-wait-repository.js";
5
- import { readCurrentSessionId } from "../storage/sqlite/session-repository.js";
4
+ import { readCurrentSessionId } from "../storage/sqlite/session-instance-repository.js";
6
5
  import { getSessionInputState } from "../storage/sqlite/session-input-repository.js";
6
+ import { cancelConnectionObjective, getActiveConnectionWait, getConnectionWait, listConnectionWaitsToCheck, publishConnectionWait, queueConnectionResolution, updateConnectionWait } from "../storage/sqlite/connection-wait-repository.js";
7
+ import "../storage/sqlite/session-repository.js";
7
8
  import { getConnectorInstallation, listConnectorConnections, upsertConnectorInstallation } from "../storage/sqlite/connector-repository.js";
9
+ import { getConnectorAccount } from "../storage/sqlite/connector-account-repository.js";
8
10
  import { ComposioSessionsAdapter } from "./composio-sessions.js";
9
11
  import { getConfiguredComposioAuthConfigs, isComposioActionAllowedByCatalog, scopeForComposioAction } from "./composio.js";
10
12
  import { getConnectorDefinition } from "./catalog.js";
11
13
  import { capabilityActions, isToolInputSchema, missingConnectionCapabilities } from "./connection-capabilities.js";
12
14
  import { connectorPrincipalForSession } from "./principal.js";
13
15
  import { resolveConnectionCandidate } from "./connection-candidates.js";
14
- import { getConnectorInstance } from "./instances.js";
16
+ import { listConnectorInstances } from "./instances.js";
15
17
  import { installConnector } from "./install.js";
16
18
  import { persistConfigMutation } from "../config/config-mutation.js";
17
19
  import { randomUUID } from "node:crypto";
@@ -79,7 +81,7 @@ var ConnectionRecoveryService = class {
79
81
  }
80
82
  view(wait, verifiedIds) {
81
83
  const needs = wait.needs.map((need) => {
82
- const instance = getConnectorInstance(this.deps.getConfig(), need.connectorId);
84
+ const instance = listConnectorInstances(this.deps.getConfig()).find((instance) => instance.connectorId === need.connectorId);
83
85
  const installation = getConnectorInstallation(`${need.connectorId}-${wait.principalId}`);
84
86
  const scopeBlocked = Math.max(1, ...need.capabilities.filter((capability) => /^[A-Z]+_/.test(capability)).map((capability) => SCOPE_ORDER[scopeForComposioAction(capability).scope])) > SCOPE_ORDER[installation?.maxScope ?? "read"];
85
87
  const blocked = scopeBlocked || instance?.enabled === false || installation?.enabled === false || Boolean(installation?.allowedAgentIds.length && !installation.allowedAgentIds.includes(wait.agentId));
@@ -87,9 +89,17 @@ var ConnectionRecoveryService = class {
87
89
  principalId: wait.principalId,
88
90
  connectorId: need.connectorId
89
91
  });
90
- const active = all.filter((connection) => connection.status === "active" && (!verifiedIds || verifiedIds.has(connection.id)) && (!need.accountId || connection.accountId === need.accountId) && (!installation?.selectedConnectionIds.length || installation.selectedConnectionIds.includes(connection.id)));
92
+ const eligible = all.filter((connection) => connection.status === "active" && (!verifiedIds || verifiedIds.has(connection.id)) && (!need.accountId || connection.accountId === need.accountId) && (!installation?.selectedConnectionIds.length || installation.selectedConnectionIds.includes(connection.id)));
93
+ const byAccount = /* @__PURE__ */ new Map();
94
+ for (const connection of eligible) {
95
+ const key = connection.accountId ?? connection.id;
96
+ const previous = byAccount.get(key);
97
+ const preferredId = need.connectionId ?? eligible.find((item) => item.providerConnectionId === need.attempt?.connectionId)?.id ?? (connection.accountId ? getConnectorAccount(connection.accountId)?.currentConnectionId : void 0);
98
+ if (!previous || connection.id === preferredId || previous.id !== preferredId && connection.updatedAt > previous.updatedAt) byAccount.set(key, connection);
99
+ }
100
+ const active = [...byAccount.values()];
91
101
  const selected = !verifiedIds && need.unavailable ? void 0 : need.attempt ? active.find((connection) => connection.providerConnectionId === need.attempt?.connectionId) : need.connectionId ? active.find((connection) => connection.id === need.connectionId) : active.length === 1 && !need.accountSelector ? active[0] : void 0;
92
- const phase = blocked || selected && need.capabilityError ? "blocked" : selected && instance ? "ready" : active.length > 1 || need.accountSelector && active.length > 0 && !need.connectionId ? "choose_account" : need.attempt && need.attempt.expiresAt > Date.now() ? "authorizing" : need.unavailable || all.some((connection) => [
102
+ const phase = blocked || selected && need.capabilityError ? "blocked" : selected ? "ready" : active.length > 1 || need.accountSelector && active.length > 0 && !need.connectionId ? "choose_account" : need.attempt && need.attempt.expiresAt > Date.now() ? "authorizing" : need.unavailable || all.some((connection) => [
93
103
  "expired",
94
104
  "revoked",
95
105
  "failed"
@@ -121,6 +131,28 @@ var ConnectionRecoveryService = class {
121
131
  phase: wait.status === "queued" ? "queued" : ready ? review ? "review_scope" : "ready" : "needs_connection"
122
132
  };
123
133
  }
134
+ async ensureInstallation(wait, connectorId) {
135
+ const config = this.deps.getConfig();
136
+ const instance = listConnectorInstances(config).find((item) => item.connectorId === connectorId);
137
+ const installationId = `${connectorId}-${wait.principalId}`;
138
+ const installation = getConnectorInstallation(installationId);
139
+ if (instance?.enabled === false || installation?.enabled === false || installation?.allowedAgentIds.length && !installation.allowedAgentIds.includes(wait.agentId)) throw new Error("Connector policy blocks this connection.");
140
+ if (!instance) await persistConfigMutation({
141
+ config,
142
+ mutate: () => installConnector(config, connectorId, {}),
143
+ save: () => this.deps.saveConfig(config)
144
+ });
145
+ if (!installation) upsertConnectorInstallation({
146
+ id: installationId,
147
+ connectorId,
148
+ principalId: wait.principalId,
149
+ enabled: true,
150
+ allowedAgentIds: [],
151
+ maxScope: "read",
152
+ confirmationPolicy: "writes",
153
+ selectedConnectionIds: []
154
+ });
155
+ }
124
156
  async checkCapabilities(wait, verified) {
125
157
  const views = this.view({
126
158
  ...wait,
@@ -135,6 +167,7 @@ var ConnectionRecoveryService = class {
135
167
  capabilityError: void 0
136
168
  };
137
169
  try {
170
+ if (!listConnectorInstances(this.deps.getConfig()).some((instance) => instance.connectorId === need.connectorId && instance.enabled)) throw new Error("Connector setup is unavailable");
138
171
  const definition = getConnectorDefinition(need.connectorId);
139
172
  if (definition?.runtime.type !== "composio" || definition.runtime.role !== "toolkit") throw new Error("Unsupported connector");
140
173
  const toolkit = definition.runtime.toolkit;
@@ -261,22 +294,8 @@ var ConnectionRecoveryService = class {
261
294
  }, wait.version);
262
295
  publishConnectionWait(sessionKey);
263
296
  const config = this.deps.getConfig();
264
- if (!getConnectorInstance(config, need.connectorId)) await persistConfigMutation({
265
- config,
266
- mutate: () => installConnector(config, need.connectorId, {}),
267
- save: () => this.deps.saveConfig(config)
268
- });
297
+ await this.ensureInstallation(wait, need.connectorId);
269
298
  const installationId = `${need.connectorId}-${wait.principalId}`;
270
- if (!getConnectorInstallation(installationId)) upsertConnectorInstallation({
271
- id: installationId,
272
- connectorId: need.connectorId,
273
- principalId: wait.principalId,
274
- enabled: true,
275
- allowedAgentIds: [],
276
- maxScope: "read",
277
- confirmationPolicy: "writes",
278
- selectedConnectionIds: []
279
- });
280
299
  const auth = await this.adapter.authorize({
281
300
  principalId: wait.principalId,
282
301
  toolkit: definition.runtime.toolkit,
@@ -335,9 +354,14 @@ var ConnectionRecoveryService = class {
335
354
  ...item,
336
355
  connectionId: connection.id,
337
356
  accountId: connection.accountId,
338
- unavailable: false
357
+ unavailable: false,
358
+ attempt: void 0
339
359
  } : item);
340
360
  }
361
+ for (const selected of this.view({
362
+ ...wait,
363
+ needs
364
+ }, verified).needs) if (selected.phase === "ready" || selected.capabilityError && selected.connectionId) await this.ensureInstallation(wait, selected.connectorId);
341
365
  needs = await this.checkCapabilities({
342
366
  ...wait,
343
367
  needs
@@ -91,7 +91,10 @@ function capabilities(name, directory, writable) {
91
91
  const extension = name.includes(".") ? name.split(".").pop().toLowerCase() : "";
92
92
  const result = ["download", "share"];
93
93
  if (MIME_TYPES[extension] || TEXT_EXTENSIONS.has(extension)) result.unshift("preview");
94
- if (writable && TEXT_EXTENSIONS.has(extension)) result.push("edit");
94
+ if (writable) {
95
+ if (TEXT_EXTENSIONS.has(extension)) result.push("edit");
96
+ result.push("delete");
97
+ }
95
98
  return result;
96
99
  }
97
100
  function fileSpaceId(root) {
@@ -1,3 +1,4 @@
1
+ import { hasGatewayScope } from "../../security/gateway-scopes.js";
1
2
  import { listConnectorLearningJobs } from "../../../storage/sqlite/connector-learning-repository.js";
2
3
  import { decideConnectorApproval, getConnectorApproval, listConnectorApprovals, listConnectorConnections } from "../../../storage/sqlite/connector-repository.js";
3
4
  import { getConnectorAccount } from "../../../storage/sqlite/connector-account-repository.js";
@@ -25,6 +26,7 @@ import { previewConnectorDefinition, testConnectorInstance } from "../../../conn
25
26
  import { listUnderstandingSourceGrants, revokeUnderstandingSourceGrant } from "../../../user-context/sources/repository.js";
26
27
  import { setConnectorEnabled } from "../../../connectors/lifecycle.js";
27
28
  import { projectComposioConnectionStatus } from "../../../connectors/runtime-status.js";
29
+ import { getGatewayPrincipal } from "../../security/gateway-principal.js";
28
30
  import { markContextSourceAssertionsForReview } from "./context-sources.js";
29
31
  //#region src/gateway/hono/routes/connectors.ts
30
32
  init_agent_scope();
@@ -467,9 +469,15 @@ function registerConnectorRoutes(authenticated, deps) {
467
469
  ok: false,
468
470
  error: "Invalid approval status."
469
471
  }, 400);
472
+ const principalId = c.req.query("principalId")?.trim() || "local-owner";
473
+ const sessionKey = c.req.query("sessionKey")?.trim() || void 0;
474
+ if (!hasGatewayScope(getGatewayPrincipal(c).scopes, "gateway.admin") && (!sessionKey || principalId !== "local-owner")) return c.json({
475
+ ok: false,
476
+ error: "A local-owner session is required to read confirmations."
477
+ }, 403);
470
478
  const approvals = listConnectorApprovals({
471
- principalId: c.req.query("principalId")?.trim() || "local-owner",
472
- sessionKey: c.req.query("sessionKey")?.trim() || void 0,
479
+ principalId,
480
+ sessionKey,
473
481
  status,
474
482
  limit: Number(c.req.query("limit") ?? "100")
475
483
  });
@@ -582,10 +590,16 @@ function registerConnectorRoutes(authenticated, deps) {
582
590
  ok: false,
583
591
  error: "Approval id and an approved or denied decision are required."
584
592
  }, 400);
585
- if (!getConnectorApproval(id)) return c.json({
593
+ const current = getConnectorApproval(id);
594
+ if (!current) return c.json({
586
595
  ok: false,
587
596
  error: "Connector approval not found."
588
597
  }, 404);
598
+ const sessionKey = typeof record.sessionKey === "string" ? record.sessionKey.trim() : "";
599
+ if (!hasGatewayScope(getGatewayPrincipal(c).scopes, "gateway.admin") && (!sessionKey || current.sessionKey !== sessionKey || current.principalId !== "local-owner")) return c.json({
600
+ ok: false,
601
+ error: "Confirmation does not belong to the requested local-owner session."
602
+ }, 403);
589
603
  const approval = decideConnectorApproval(id, decision);
590
604
  if (!approval || approval.status !== decision) return c.json({
591
605
  ok: false,
@@ -1,9 +1,9 @@
1
- import { FileServiceError, fileResourceFromPath, resolveFilePath } from "../../../files/file-service.js";
1
+ import { FileServiceError, fileResourceFromPath, parseFileResourceId, resolveFilePath } from "../../../files/file-service.js";
2
2
  import { getGatewayFileSpaceService } from "../../file-space-service.js";
3
3
  import { fuzzySearchWorkspaceFiles, fuzzySubsequenceScore } from "../../workspace-file-search.js";
4
4
  import { registerFileReferenceRoutes } from "./file-references.js";
5
5
  import { basename, join } from "node:path";
6
- import { readFile, writeFile } from "node:fs/promises";
6
+ import { readFile, unlink, writeFile } from "node:fs/promises";
7
7
  //#region src/gateway/hono/routes/files.ts
8
8
  const mutationLocks = /* @__PURE__ */ new Map();
9
9
  async function withMutationLock(key, action) {
@@ -185,6 +185,27 @@ function registerFilesRoutes(authenticated, deps) {
185
185
  return errorResponse(c, error);
186
186
  }
187
187
  });
188
+ authenticated.delete("/api/files/:id", async (c) => {
189
+ try {
190
+ const id = c.req.param("id");
191
+ const initial = await files.resource(id);
192
+ if (!initial.space.writable) throw new FileServiceError(403, "File space is read-only");
193
+ if (initial.resource.kind !== "file") throw new FileServiceError(400, "Resource is not a file");
194
+ await withMutationLock(initial.absolutePath, async () => {
195
+ const current = await files.resource(id);
196
+ if (current.absolutePath !== initial.absolutePath) throw new FileServiceError(409, "File has changed");
197
+ if (current.resource.kind !== "file") throw new FileServiceError(400, "Resource is not a file");
198
+ const { relativePath } = parseFileResourceId(id);
199
+ await unlink(await resolveFilePath(current.space.root, relativePath, false)).catch((error) => {
200
+ if (error.code === "ENOENT") throw new FileServiceError(404, "File not found");
201
+ throw error;
202
+ });
203
+ });
204
+ return c.json({ ok: true });
205
+ } catch (error) {
206
+ return errorResponse(c, error);
207
+ }
208
+ });
188
209
  authenticated.post("/api/files/spaces/:id/upload", async (c) => {
189
210
  try {
190
211
  const space = await files.get(c.req.param("id"));
@@ -25,7 +25,7 @@ function registerTaskRoutes(authenticated, deps) {
25
25
  const taskRateLimit = deps.taskRateLimitMiddleware ?? deps.strictRateLimitMiddleware;
26
26
  const application = new TaskApplicationService();
27
27
  const operatingViews = new ProjectOperatingViewService(deps.service.projects);
28
- const monitoring = new ProjectMonitoringService();
28
+ const monitoring = new ProjectMonitoringService(deps.service.currentWorkspacePath);
29
29
  const metrics = new TaskValueMetricsService();
30
30
  const tasks = new TaskRepository();
31
31
  const runs = new TaskRunRepository();
@@ -48,6 +48,8 @@ function requiredGatewayScope(method, path) {
48
48
  if (path === "/api/device-auth/refresh" || path === "/api/devices/me") return "device.self";
49
49
  if (path.startsWith("/api/devices/me/push")) return "notifications.self";
50
50
  if (path.startsWith("/api/endpoint-tools")) return "device.self";
51
+ if (method === "GET" && path === "/api/connectors/approvals") return "sessions.read";
52
+ if (method === "POST" && path === "/api/connectors/approvals/respond") return "sessions.write";
51
53
  if (path === "/api/agent" || path.startsWith("/api/agent/")) return "agents.run";
52
54
  if (path.startsWith("/api/agents") || path.startsWith("/api/models")) return methodScope(method, "agents.read", "gateway.admin");
53
55
  if (path.startsWith("/api/sessions") || path.startsWith("/api/side-chats")) return methodScope(method, "sessions.read", "sessions.write");
@@ -1,7 +1,7 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
- import { onConnectionWaitChanged } from "../../storage/sqlite/connection-wait-repository.js";
4
3
  import { listActiveSessionInputRuns } from "../../storage/sqlite/session-input-repository.js";
4
+ import { onConnectionWaitChanged } from "../../storage/sqlite/connection-wait-repository.js";
5
5
  import "../../storage/sqlite/index.js";
6
6
  import { ClarifyBridge } from "../clarify-bridge.js";
7
7
  import { runGatewayAgent } from "./run-gateway-agent.js";
@@ -1,8 +1,8 @@
1
1
  import { inboundCorrelationMetadataFromAsyncLogContext, updateAsyncLogContext } from "../../utils/logger/context.js";
2
2
  import { createLogger } from "../../utils/logger/index.js";
3
3
  import { init_logger } from "../../utils/logger.js";
4
- import { getConnectionResumeInput, isConnectionSuspended } from "../../storage/sqlite/connection-wait-repository.js";
5
4
  import { updateInteractionStateFromMessage } from "../../storage/sqlite/interaction-state-repository.js";
5
+ import { getConnectionResumeInput, isConnectionSuspended } from "../../storage/sqlite/connection-wait-repository.js";
6
6
  import "../../storage/sqlite/index.js";
7
7
  import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
8
8
  import { resolveExecutionContext } from "../../tasks/execution-context.js";
@@ -1,8 +1,8 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
- import { cancelConnectionObjective, consumeConnectionResume, invalidateConnectionResumeIntent, publishConnectionWait } from "../../storage/sqlite/connection-wait-repository.js";
4
3
  import { SessionInstanceChangedError, cancelQueuedSessionInput, claimNextSessionInput, findSessionInput, finishSessionInputRun, getSessionInputById, getSessionInputState, insertSessionInput, mutateQueuedSessionInput, recoverSessionInputState, setSessionInputStatus } from "../../storage/sqlite/session-input-repository.js";
5
4
  import { replaceLatestSessionTurnAndQueueInput, validateLatestSessionTurnTarget } from "../../storage/sqlite/session-turn-replace-repository.js";
5
+ import { cancelConnectionObjective, consumeConnectionResume, invalidateConnectionResumeIntent, publishConnectionWait } from "../../storage/sqlite/connection-wait-repository.js";
6
6
  import "../../storage/sqlite/index.js";
7
7
  import { summarizeSourceContext } from "../../agent/source-context/types.js";
8
8
  import { deleteMediaUrisNoLongerReferenced } from "../../media/session-references.js";
@@ -6,8 +6,8 @@ import { getRuntimeLogStats } from "../utils/logger/stats.js";
6
6
  import { createLogger } from "../utils/logger/index.js";
7
7
  import { init_logger } from "../utils/logger.js";
8
8
  import { closeXopcDatabase, openXopcDatabase } from "../storage/sqlite/connection.js";
9
- import { notifyUserContextChange } from "../user-context/changes.js";
10
9
  import { insertSessionInput } from "../storage/sqlite/session-input-repository.js";
10
+ import { notifyUserContextChange } from "../user-context/changes.js";
11
11
  import { getSessionConfig } from "../storage/sqlite/config-repository.js";
12
12
  import "../storage/sqlite/index.js";
13
13
  import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
@@ -366,9 +366,9 @@ var GatewayService = class {
366
366
  this.workspacePath = getWorkspacePath(this.config) || "./workspace";
367
367
  this.initializeExtensionLoader();
368
368
  this.sessionIndex = new SessionIndex({ config: this.config });
369
- this.automationService = new AutomationService(this.proactive);
369
+ this.automationService = new AutomationService(this.proactive, this.workspacePath);
370
370
  this.notesService = new NotesService(new NotesStore());
371
- this.projects = new ProjectService(void 0, this.proactive);
371
+ this.projects = new ProjectService(void 0, this.proactive, this.workspacePath);
372
372
  const emitDiscussion = (capture) => {
373
373
  this.emit("discussion.updated", capture);
374
374
  };
@@ -1096,7 +1096,11 @@ var GatewayService = class {
1096
1096
  log.debug("Gateway service started");
1097
1097
  }
1098
1098
  ensureDefaultProactiveScenarioSubscriptions() {
1099
- for (const scenarioKey of ["meeting_preparation", "discussion_follow_up"]) {
1099
+ for (const scenarioKey of [
1100
+ "automation_failure_impact",
1101
+ "meeting_preparation",
1102
+ "discussion_follow_up"
1103
+ ]) {
1100
1104
  if (this.proactiveScenarios.subscriptions(scenarioKey).some((subscription) => subscription.workspaceId === this.currentWorkspacePath)) continue;
1101
1105
  this.proactiveScenarios.subscribe({
1102
1106
  scenarioKey,
@@ -3,6 +3,7 @@ export type KnowledgeKind = 'project_fact' | 'workspace_fact' | 'decision' | 'ta
3
3
  export type KnowledgeStatus = 'candidate' | 'active' | 'needs_review' | 'stale' | 'archived' | 'rejected';
4
4
  export type KnowledgeOriginClass = 'owner' | 'agent' | 'system' | 'untrusted';
5
5
  export type KnowledgeRecordClass = 'memory' | 'source_index';
6
+ export type KnowledgeSource = 'session' | 'workspace' | 'project' | 'connector';
6
7
  export interface KnowledgeItem {
7
8
  id: string;
8
9
  principalId: string;
@@ -1,2 +1,2 @@
1
- import { getKnowledgeItem, listKnowledgeItems, searchKnowledgeItems, setKnowledgeStatus, writeKnowledgeItem } from "./repository.js";
2
- export { getKnowledgeItem, listKnowledgeItems, searchKnowledgeItems, setKnowledgeStatus, writeKnowledgeItem };
1
+ import { getKnowledgeItem, knowledgeSourceAllowed, listKnowledgeItems, searchKnowledgeItems, setKnowledgeStatus, writeKnowledgeItem } from "./repository.js";
2
+ export { getKnowledgeItem, knowledgeSourceAllowed, listKnowledgeItems, searchKnowledgeItems, setKnowledgeStatus, writeKnowledgeItem };
@@ -1,5 +1,5 @@
1
1
  import { type UserModelScope } from '../user-model/domain.js';
2
- import type { KnowledgeItem, KnowledgeKind, KnowledgeOriginClass, KnowledgeRecordClass, KnowledgeStatus, KnowledgeVisibilityContext } from './domain.js';
2
+ import type { KnowledgeItem, KnowledgeKind, KnowledgeOriginClass, KnowledgeRecordClass, KnowledgeSource, KnowledgeStatus, KnowledgeVisibilityContext } from './domain.js';
3
3
  export interface WriteKnowledgeInput {
4
4
  principalId?: string;
5
5
  kind: KnowledgeKind;
@@ -41,5 +41,8 @@ export declare function searchKnowledgeItems(input: {
41
41
  principalId?: string;
42
42
  asOf?: number;
43
43
  recordClass?: KnowledgeRecordClass;
44
+ trustedOnly?: boolean;
45
+ sources?: readonly KnowledgeSource[];
44
46
  limit?: number;
45
47
  }): KnowledgeItem[];
48
+ export declare function knowledgeSourceAllowed(item: KnowledgeItem, sources: readonly KnowledgeSource[]): boolean;
@@ -138,6 +138,14 @@ function searchKnowledgeItems(input) {
138
138
  const asOf = input.asOf ?? Date.now();
139
139
  const limit = Math.max(1, Math.min(100, input.limit ?? 12));
140
140
  const visible = visibilityClause(input.context);
141
+ const sourceParts = [];
142
+ const sourceValues = [];
143
+ if (input.sources?.includes("connector")) sourceParts.push("k.record_class = 'source_index'");
144
+ const memoryScopes = input.sources?.filter((source) => source !== "connector") ?? [];
145
+ if (memoryScopes.length) {
146
+ sourceParts.push(`(k.record_class = 'memory' AND k.scope_type IN (${memoryScopes.map(() => "?").join(", ")}))`);
147
+ sourceValues.push(...memoryScopes);
148
+ }
141
149
  const fts = buildFts5SearchQuery(input.query);
142
150
  if (!fts) return [];
143
151
  return getSqliteDatabase().prepare(`SELECT k.*, bm25(knowledge_items_fts) AS rank
@@ -147,8 +155,14 @@ function searchKnowledgeItems(input) {
147
155
  AND (k.valid_to IS NULL OR k.valid_to >= ?)
148
156
  AND (k.expires_at IS NULL OR k.expires_at >= ?)
149
157
  ${input.recordClass ? "AND k.record_class = ?" : ""}
158
+ ${input.trustedOnly ? "AND k.origin_class != 'untrusted'" : ""}
159
+ ${input.sources ? `AND (${sourceParts.length ? sourceParts.join(" OR ") : "0"})` : ""}
150
160
  AND ${visible.sql}
151
- ORDER BY rank ASC, k.importance DESC, k.updated_at DESC LIMIT ?`).all(fts, principalId, asOf, asOf, asOf, ...input.recordClass ? [input.recordClass] : [], ...visible.values, limit).map(fromRow);
161
+ ORDER BY rank ASC, k.importance DESC, k.updated_at DESC LIMIT ?`).all(fts, principalId, asOf, asOf, asOf, ...input.recordClass ? [input.recordClass] : [], ...sourceValues, ...visible.values, limit).map(fromRow);
162
+ }
163
+ function knowledgeSourceAllowed(item, sources) {
164
+ if (item.recordClass === "source_index") return sources.includes("connector");
165
+ return item.scope.type === "session" ? sources.includes("session") : item.scope.type === "workspace" ? sources.includes("workspace") : item.scope.type === "project" ? sources.includes("project") : false;
152
166
  }
153
167
  //#endregion
154
- export { getKnowledgeItem, listKnowledgeItems, searchKnowledgeItems, setKnowledgeStatus, writeKnowledgeItem };
168
+ export { getKnowledgeItem, knowledgeSourceAllowed, listKnowledgeItems, searchKnowledgeItems, setKnowledgeStatus, writeKnowledgeItem };
@@ -122,7 +122,11 @@ function automationPlan(payload) {
122
122
  function proactivePlan(payload) {
123
123
  if (!payload || typeof payload !== "object") return null;
124
124
  const item = payload;
125
- if (typeof item.id !== "string" || typeof item.insight?.id !== "string" || typeof item.insight.title !== "string") return null;
125
+ if (typeof item.id !== "string" || typeof item.insightId !== "string" || typeof item.insight.title !== "string") return null;
126
+ const requiresDecision = item.insight.attentionKind === "decision";
127
+ const highUrgency = item.insight.urgency === "high" || item.insight.urgency === "critical";
128
+ if (item.insight.attentionKind === "receipt") return null;
129
+ if (!requiresDecision && !highUrgency) return null;
126
130
  const title = item.insight.title.trim().slice(0, 120);
127
131
  const summary = typeof item.insight.summary === "string" ? item.insight.summary.trim().slice(0, 180) : "";
128
132
  return {
@@ -133,7 +137,7 @@ function proactivePlan(payload) {
133
137
  kind: "insight",
134
138
  inboxItemId: item.id
135
139
  },
136
- priority: item.insight.urgency === "high" || item.insight.urgency === "critical" ? "high" : "normal",
140
+ priority: requiresDecision || highUrgency ? "high" : "normal",
137
141
  title: {
138
142
  en: title,
139
143
  zh: title
@@ -144,7 +148,7 @@ function proactivePlan(payload) {
144
148
  } } : {},
145
149
  payload: {
146
150
  inboxItemId: item.id,
147
- insightId: item.insight.id
151
+ insightId: item.insightId
148
152
  }
149
153
  }
150
154
  };
@@ -1,2 +1 @@
1
1
  export declare function executePendingProactiveActions(now?: Date): number;
2
- export declare function resolveProactiveActionDecision(inboxItemId: string, choice: string, now?: Date): void;
@@ -67,14 +67,5 @@ function executePendingProactiveActions(now = /* @__PURE__ */ new Date()) {
67
67
  executed += 1;
68
68
  }
69
69
  }
70
- function resolveProactiveActionDecision(inboxItemId, choice, now = /* @__PURE__ */ new Date()) {
71
- const row = getSqliteDatabase().prepare(`SELECT x.insight_id, x.action_status
72
- FROM proactive_inbox_items i JOIN proactive_insights x ON x.insight_id = i.insight_id
73
- WHERE i.inbox_item_id = ?`).get(inboxItemId);
74
- if (!row || row.action_status !== "approval_required") return;
75
- getSqliteDatabase().prepare(`UPDATE proactive_insights SET action_status = ?, action_updated_at = ?
76
- WHERE insight_id = ? AND action_status = 'approval_required'`).run(choice === "approve" ? "pending" : "rejected", now.toISOString(), row.insight_id);
77
- if (choice === "approve") executePendingProactiveActions(now);
78
- }
79
70
  //#endregion
80
- export { executePendingProactiveActions, resolveProactiveActionDecision };
71
+ export { executePendingProactiveActions };
@@ -1,44 +1,42 @@
1
1
  import type { ContextProvider, ResolvedContext } from './types.js';
2
+ import type { ScenarioDefinition } from '../scenarios/types.js';
2
3
  type ContextInput = Parameters<ContextProvider['collect']>[0];
3
4
  export declare class EventBatchContextProvider implements ContextProvider {
4
5
  readonly id = "event_batch";
5
- supports(): boolean;
6
6
  collect(input: ContextInput): Promise<ResolvedContext>;
7
7
  }
8
8
  export declare class ConnectedSourceContextProvider implements ContextProvider {
9
9
  readonly id = "connected_source";
10
- supports(): boolean;
11
10
  collect(input: ContextInput): Promise<ResolvedContext>;
12
11
  }
13
12
  export declare class InternalObjectContextProvider implements ContextProvider {
14
13
  readonly id = "internal_objects";
15
- supports(): boolean;
16
14
  collect(input: ContextInput): Promise<ResolvedContext>;
17
15
  }
18
16
  export declare class UserModelContextProvider implements ContextProvider {
19
17
  readonly id = "user_model";
20
- supports(): boolean;
21
18
  collect(input: ContextInput): Promise<ResolvedContext>;
22
19
  }
23
20
  export declare class MeetingWorkspaceContextProvider implements ContextProvider {
24
21
  readonly id = "meeting_workspace";
25
- supports(scenarioKey: string): boolean;
26
22
  collect(input: ContextInput): Promise<ResolvedContext>;
27
23
  }
28
24
  export declare class ProjectStateContextProvider implements ContextProvider {
29
25
  readonly id = "project_state";
30
- supports(scenarioKey: string): boolean;
31
26
  collect(input: ContextInput): Promise<ResolvedContext>;
32
27
  }
33
28
  export declare class AutomationStateContextProvider implements ContextProvider {
34
29
  readonly id = "automation_state";
35
- supports(scenarioKey: string): boolean;
30
+ collect(input: ContextInput): Promise<ResolvedContext>;
31
+ }
32
+ export declare class DiscussionContextProvider implements ContextProvider {
33
+ readonly id = "discussion";
36
34
  collect(input: ContextInput): Promise<ResolvedContext>;
37
35
  }
38
36
  export declare class ContextProviderRegistry {
39
37
  private readonly providers;
40
38
  constructor(providers?: ContextProvider[]);
41
- collect(scenarioKey: string, input: {
39
+ collect(scenario: ScenarioDefinition, input: {
42
40
  batchId: string;
43
41
  eventIds: string[];
44
42
  subscriptionId: string;