@xopcai/xopc 0.0.307 → 0.0.309

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 (261) hide show
  1. package/dist/browser-ext/_locales/en/messages.json +8 -0
  2. package/dist/browser-ext/_locales/zh_CN/messages.json +8 -0
  3. package/dist/browser-ext/dist/assets/{sidepanel-BbSQr-6P.css → sidepanel-DD6GEMvc.css} +16 -0
  4. package/dist/browser-ext/dist/sidepanel.html +1 -1
  5. package/dist/browser-ext/dist/sidepanel.js +537 -96
  6. package/dist/browser-ext/manifest.json +1 -1
  7. package/dist/extensions/telegram/xopc.extension.json +1 -1
  8. package/dist/gateway/static/root/assets/{activity-store-wgSB2HYK.js → activity-store-XKNYlFUI.js} +1 -1
  9. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CZeQo09T.js → agent-avatar-dicebear-1S2TFECE.js} +1 -1
  10. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-f0-YFMUz.js +1 -0
  11. package/dist/gateway/static/root/assets/{agents-BlrHMbRx.js → agents-CPqUMtCL.js} +1 -1
  12. package/dist/gateway/static/root/assets/{api-BKHmTb0w.js → api-BEUEE4f2.js} +1 -1
  13. package/dist/gateway/static/root/assets/api-CN4id43t.js +1 -0
  14. package/dist/gateway/static/root/assets/{app-management-settings-panel-Bzw4fQP8.js → app-management-settings-panel-CgVBSqzu.js} +1 -1
  15. package/dist/gateway/static/root/assets/{appearance-settings-8GZpUXva.js → appearance-settings-CoWdCokb.js} +1 -1
  16. package/dist/gateway/static/root/assets/{apps-page-BkQQtIxH.js → apps-page-CexHOcWg.js} +1 -1
  17. package/dist/gateway/static/root/assets/{archive-plugin-CQ2NaoHb.js → archive-plugin-C3ZA6LRS.js} +1 -1
  18. package/dist/gateway/static/root/assets/{attachment-load-BFi1H7yJ.js → attachment-load-CdgS6_zy.js} +1 -1
  19. package/dist/gateway/static/root/assets/{automations-page-CDBXcii_.js → automations-page-BtHL2hpg.js} +1 -1
  20. package/dist/gateway/static/root/assets/automations-workspace-onJPfmO6.js +6 -0
  21. package/dist/gateway/static/root/assets/{binary-plugins-D07eWmOx.js → binary-plugins-CiDhtq_H.js} +1 -1
  22. package/dist/gateway/static/root/assets/{block-editor-CtVnjyYU.js → block-editor-Br00T83w.js} +3 -3
  23. package/dist/gateway/static/root/assets/{browser-automation-inputs-BzkJog8e.js → browser-automation-inputs-D2tILykA.js} +1 -1
  24. package/dist/gateway/static/root/assets/{browser-automations-page-DyrSbDdG.js → browser-automations-page-BVuEmryB.js} +1 -1
  25. package/dist/gateway/static/root/assets/browser-settings-page-BgVTyPFY.js +3 -0
  26. package/dist/gateway/static/root/assets/capabilities-settings-panel-Dra8wj1S.js +8 -0
  27. package/dist/gateway/static/root/assets/{channels-settings-DAD9qE3J.js → channels-settings-CkxiMDJ4.js} +1 -1
  28. package/dist/gateway/static/root/assets/{channels-status-swr-B2JwuTjG.js → channels-status-swr-Dtder4G_.js} +1 -1
  29. package/dist/gateway/static/root/assets/{chat-terminal-dock-B62SZdAo.js → chat-terminal-dock-JsMtzDao.js} +1 -1
  30. package/dist/gateway/static/root/assets/{computer-settings-page-ClSresNq.js → computer-settings-page-DHerePwo.js} +1 -1
  31. package/dist/gateway/static/root/assets/connector-service-page-DZFNUTiN.js +1 -0
  32. package/dist/gateway/static/root/assets/connectors-page-cl9ZrV4D.js +2 -0
  33. package/dist/gateway/static/root/assets/{cron-expression-CTMi_tql.js → cron-expression-DAhdv_Xv.js} +1 -1
  34. package/dist/gateway/static/root/assets/{date-picker-B71AJK50.js → date-picker-PacO1m3a.js} +1 -1
  35. package/dist/gateway/static/root/assets/{dependency-picker-DlyGK-kA.js → dependency-picker-B-BcuG1y.js} +1 -1
  36. package/dist/gateway/static/root/assets/{desktop-pet-DGkbTE8_.js → desktop-pet-CdBBhhdY.js} +1 -1
  37. package/dist/gateway/static/root/assets/{desktop-pet-settings-BY8r9j66.js → desktop-pet-settings-Gy03NgMI.js} +1 -1
  38. package/dist/gateway/static/root/assets/{device-pairing-wizard-DzRrgd59.js → device-pairing-wizard-aV25nKag.js} +1 -1
  39. package/dist/gateway/static/root/assets/{extension-debug-page-L8Mm1n3A.js → extension-debug-page-BFp5eKtY.js} +1 -1
  40. package/dist/gateway/static/root/assets/{extension-page-CFc4vSNU.js → extension-page-DL3vyyH6.js} +1 -1
  41. package/dist/gateway/static/root/assets/{extension-settings-page-B5zWyHr3.js → extension-settings-page-BXtvdAsY.js} +1 -1
  42. package/dist/gateway/static/root/assets/{gateway-config-swr-B6wHa6ZI.js → gateway-config-swr-xAOGtenO.js} +1 -1
  43. package/dist/gateway/static/root/assets/{gateway-realtime-B53R0CA4.js → gateway-realtime-BuaTsMSi.js} +1 -1
  44. package/dist/gateway/static/root/assets/gateway-realtime-store-BG95uGVW.js +1 -0
  45. package/dist/gateway/static/root/assets/{gateway-settings-D7qmTH4R.js → gateway-settings-Dcr2Ikeh.js} +1 -1
  46. package/dist/gateway/static/root/assets/{gateway-startup-retry-DRzGnEV-.js → gateway-startup-retry-BwDxKHd4.js} +1 -1
  47. package/dist/gateway/static/root/assets/{heartbeat-settings-Glsl3X5b.js → heartbeat-settings-DOy3alvT.js} +1 -1
  48. package/dist/gateway/static/root/assets/home-page-CDm3dGVy.js +1 -0
  49. package/dist/gateway/static/root/assets/{image-generation-api-Ck_pyDom.js → image-generation-api-wGMeI_yW.js} +1 -1
  50. package/dist/gateway/static/root/assets/{imports-page-ByBX7ome.js → imports-page-zexFT5Rq.js} +1 -1
  51. package/dist/gateway/static/root/assets/index-D-vczw_0.css +1 -0
  52. package/dist/gateway/static/root/assets/index-DJo4DimT.js +79 -0
  53. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-C45RlO8a.js → keyboard-shortcuts-settings-CutG9zLh.js} +1 -1
  54. package/dist/gateway/static/root/assets/{local-app-workbench-page-DP0x2jpR.js → local-app-workbench-page-CwLvTwjn.js} +2 -2
  55. package/dist/gateway/static/root/assets/{local-apps-page-C_AQc2bI.js → local-apps-page-CJy6I7Dt.js} +1 -1
  56. package/dist/gateway/static/root/assets/{locale-store-msTfRK8P.js → locale-store-DPZ79W1-.js} +1 -1
  57. package/dist/gateway/static/root/assets/{logs-page-DvM8Pyok.js → logs-page-egGcPHNi.js} +1 -1
  58. package/dist/gateway/static/root/assets/{management-settings-D1uwSutV.js → management-settings-BQhIOELc.js} +1 -1
  59. package/dist/gateway/static/root/assets/{markdown-view-BInabSKf.js → markdown-view-p2P5hP1U.js} +1 -1
  60. package/dist/gateway/static/root/assets/{media-plugins-C4mhf13f.js → media-plugins-CsBylqlN.js} +1 -1
  61. package/dist/gateway/static/root/assets/messages-BiYTyLJr.js +3 -0
  62. package/dist/gateway/static/root/assets/note-detail-panel-c2k5Uz6X.js +5 -0
  63. package/dist/gateway/static/root/assets/notes-page-BLQWJMhf.js +8 -0
  64. package/dist/gateway/static/root/assets/{page-tabs-1go_BtX1.js → page-tabs-ChQ4jJFs.js} +1 -1
  65. package/dist/gateway/static/root/assets/{preview-open-alternatives-DmoSC0j1.js → preview-open-alternatives-9B5W7nVE.js} +1 -1
  66. package/dist/gateway/static/root/assets/{proactive-page-xAjKTIID.js → proactive-page-iOjI0d_e.js} +1 -1
  67. package/dist/gateway/static/root/assets/{product-open-page-gmi5LLwM.js → product-open-page-BADxWEdP.js} +1 -1
  68. package/dist/gateway/static/root/assets/project-detail-page-BcxbQn2M.js +1 -0
  69. package/dist/gateway/static/root/assets/projects-page-BuSvld0O.js +1 -0
  70. package/dist/gateway/static/root/assets/{registry-api-BSWtko7U.js → registry-api-B_e_nZSN.js} +1 -1
  71. package/dist/gateway/static/root/assets/remote-access-hub-CFS8LQKW.js +1 -0
  72. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-ClkOoxDl.js → runtime-tools-settings-panel-D-pwiIyp.js} +1 -1
  73. package/dist/gateway/static/root/assets/{schema-form-BuEmLiaU.js → schema-form-IWmb05DX.js} +1 -1
  74. package/dist/gateway/static/root/assets/sessions-page-DZjc__ok.js +1 -0
  75. package/dist/gateway/static/root/assets/settings-advanced-gate-C1SM5B93.js +1 -0
  76. package/dist/gateway/static/root/assets/{settings-form-section-Dor39QON.js → settings-form-section-B0veRBZs.js} +1 -1
  77. package/dist/gateway/static/root/assets/{settings-page-Xj-yvIc8.js → settings-page-CxRWyWYe.js} +1 -1
  78. package/dist/gateway/static/root/assets/setup-status-panel-D9Rl7Tec.js +1 -0
  79. package/dist/gateway/static/root/assets/{share-preview-page-BFWZoXdm.js → share-preview-page-CirpgkfD.js} +1 -1
  80. package/dist/gateway/static/root/assets/shares-settings-CwCThBs0.js +1 -0
  81. package/dist/gateway/static/root/assets/skill-reload-api-DG6VGbOX.js +1 -0
  82. package/dist/gateway/static/root/assets/skills-page-BdRJ2vnL.js +2 -0
  83. package/dist/gateway/static/root/assets/{skills-page.utils-Ii8qeXhs.js → skills-page.utils-B42mpWKV.js} +1 -1
  84. package/dist/gateway/static/root/assets/{system-settings-panel-Di6OSO-0.js → system-settings-panel-DXIZpAvU.js} +1 -1
  85. package/dist/gateway/static/root/assets/task-detail-page-QXo9LJly.js +1 -0
  86. package/dist/gateway/static/root/assets/{theme-store-1SZ-HFHX.js → theme-store-BFbj_2Tu.js} +1 -1
  87. package/dist/gateway/static/root/assets/{tunnel-api-DDOlOYlj.js → tunnel-api-Db2guRdW.js} +1 -1
  88. package/dist/gateway/static/root/assets/{use-autosave-CQ8uWNnB.js → use-autosave-DDY9qoXZ.js} +1 -1
  89. package/dist/gateway/static/root/assets/user-model-page-CzPmMkaO.js +2 -0
  90. package/dist/gateway/static/root/assets/{voice-api-key-field-COTzshjL.js → voice-api-key-field-BZbKQ8HT.js} +1 -1
  91. package/dist/gateway/static/root/assets/{voice-config-api-DgJML_uM.js → voice-config-api-SKCeQLrH.js} +1 -1
  92. package/dist/gateway/static/root/assets/{work-discovery-overlay-_URrXbi4.js → work-discovery-overlay-BRVTTXNG.js} +1 -1
  93. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CALs-1nd.js → workflow-run-setup-panel-D2kuwv5e.js} +2 -2
  94. package/dist/gateway/static/root/assets/workflows-page-CQXtiYtq.js +6 -0
  95. package/dist/gateway/static/root/index.html +12 -12
  96. package/dist/package.js +1 -1
  97. package/dist/packages/gateway-contract/src/notifications.js +1 -1
  98. package/dist/packages/gateway-contract/src/sessions.js +6 -1
  99. package/dist/src/agent/agent-manager.js +29 -4
  100. package/dist/src/agent/background-review/prompts.js +3 -1
  101. package/dist/src/agent/child-agent-factory.d.ts +1 -0
  102. package/dist/src/agent/child-agent-factory.js +18 -4
  103. package/dist/src/agent/coding/repository-instructions.d.ts +4 -0
  104. package/dist/src/agent/coding/repository-instructions.js +46 -2
  105. package/dist/src/agent/context/execution-context.js +4 -4
  106. package/dist/src/agent/data-acquisition/git.d.ts +17 -0
  107. package/dist/src/agent/data-acquisition/git.js +100 -0
  108. package/dist/src/agent/data-acquisition/render.d.ts +7 -0
  109. package/dist/src/agent/data-acquisition/render.js +79 -0
  110. package/dist/src/agent/data-acquisition/scheduler.d.ts +12 -0
  111. package/dist/src/agent/data-acquisition/scheduler.js +53 -0
  112. package/dist/src/agent/data-acquisition/schema.d.ts +75 -0
  113. package/dist/src/agent/data-acquisition/schema.js +206 -0
  114. package/dist/src/agent/data-acquisition/service.d.ts +10 -0
  115. package/dist/src/agent/data-acquisition/service.js +292 -0
  116. package/dist/src/agent/data-acquisition/types.d.ts +37 -0
  117. package/dist/src/agent/data-acquisition/types.js +5 -0
  118. package/dist/src/agent/embedded/run-turn.js +16 -4
  119. package/dist/src/agent/embedded/session-runner.d.ts +1 -0
  120. package/dist/src/agent/embedded/session-runner.js +3 -0
  121. package/dist/src/agent/embedded/tool-result-truncation.js +11 -0
  122. package/dist/src/agent/embedded/xopc-tools-bridge.js +2 -1
  123. package/dist/src/agent/external-tools/composio-provider.js +12 -1
  124. package/dist/src/agent/external-tools/gateway-tools.js +2 -1
  125. package/dist/src/agent/external-tools/index.js +8 -1
  126. package/dist/src/agent/external-tools/read-policy.d.ts +6 -0
  127. package/dist/src/agent/external-tools/read-policy.js +21 -0
  128. package/dist/src/agent/external-tools/service.d.ts +1 -0
  129. package/dist/src/agent/external-tools/service.js +4 -1
  130. package/dist/src/agent/external-tools/types.d.ts +2 -0
  131. package/dist/src/agent/memory/compaction-promotion.d.ts +1 -1
  132. package/dist/src/agent/memory/compaction-promotion.js +4 -3
  133. package/dist/src/agent/orchestration/agent-turn-policy.js +25 -10
  134. package/dist/src/agent/orchestration/delegation-scope.d.ts +9 -0
  135. package/dist/src/agent/orchestration/delegation-scope.js +11 -0
  136. package/dist/src/agent/prompt/sections/tooling.js +3 -1
  137. package/dist/src/agent/prompt/subagent-context.js +4 -2
  138. package/dist/src/agent/sandbox/fileAccess.d.ts +2 -0
  139. package/dist/src/agent/sandbox/fileAccess.js +31 -2
  140. package/dist/src/agent/tools/dataBatch.d.ts +4 -0
  141. package/dist/src/agent/tools/dataBatch.js +50 -0
  142. package/dist/src/agent/tools/delegate-tool.d.ts +6 -3
  143. package/dist/src/agent/tools/delegate-tool.js +65 -48
  144. package/dist/src/agent/tools/delegation-parent-policy.d.ts +7 -0
  145. package/dist/src/agent/tools/delegation-parent-policy.js +41 -0
  146. package/dist/src/agent/tools/delegation-policy.d.ts +16 -0
  147. package/dist/src/agent/tools/delegation-policy.js +93 -0
  148. package/dist/src/agent/tools/factory.d.ts +2 -0
  149. package/dist/src/agent/tools/factory.js +42 -3
  150. package/dist/src/agent/tools/fetch-text.d.ts +7 -0
  151. package/dist/src/agent/tools/fetch-text.js +86 -0
  152. package/dist/src/agent/tools/find.js +1 -1
  153. package/dist/src/agent/tools/grep.js +11 -23
  154. package/dist/src/agent/tools/index.d.ts +1 -0
  155. package/dist/src/agent/tools/index.js +2 -1
  156. package/dist/src/agent/tools/knowledge-memory-tool.d.ts +1 -1
  157. package/dist/src/agent/tools/knowledge-memory-tool.js +13 -5
  158. package/dist/src/agent/tools/read.js +7 -5
  159. package/dist/src/agent/tools/repository-search.d.ts +12 -2
  160. package/dist/src/agent/tools/repository-search.js +127 -74
  161. package/dist/src/agent/tools/user-context-tool.js +17 -7
  162. package/dist/src/agent/tools/web.js +19 -28
  163. package/dist/src/agent/workflow/subagent-runner.js +25 -3
  164. package/dist/src/agent/workflow/workflow-child-tools.js +13 -8
  165. package/dist/src/agent-config/schema.d.ts +7 -0
  166. package/dist/src/agent-config/schema.js +2 -0
  167. package/dist/src/chat-commands/builtins/understanding.js +1 -1
  168. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  169. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  170. package/dist/src/config/schema.d.ts +6 -4
  171. package/dist/src/config/schema.js +2 -2
  172. package/dist/src/connectors/connected-source-understanding.d.ts +1 -0
  173. package/dist/src/connectors/connected-source-understanding.js +1 -0
  174. package/dist/src/connectors/learning-coordinator.js +31 -9
  175. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  176. package/dist/src/gateway/heartbeat/service.js +2 -2
  177. package/dist/src/gateway/hono/lib/config-payload.d.ts +4 -2
  178. package/dist/src/gateway/hono/routes/connectors.js +1 -1
  179. package/dist/src/gateway/hono/routes/context-sources.js +0 -23
  180. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  181. package/dist/src/gateway/hono/routes/projects.js +8 -0
  182. package/dist/src/gateway/hono/routes/sessions.js +141 -13
  183. package/dist/src/gateway/hono/routes/user-model-refresh.d.ts +5 -0
  184. package/dist/src/gateway/hono/routes/user-model-refresh.js +128 -0
  185. package/dist/src/gateway/hono/routes/user-model.js +12 -5
  186. package/dist/src/gateway/hono/routes/work-discovery.js +0 -30
  187. package/dist/src/gateway/service.js +6 -6
  188. package/dist/src/heartbeat/index.js +1 -1
  189. package/dist/src/infra/update-restart.js +1 -1
  190. package/dist/src/knowledge/connected-knowledge-pipeline.js +1 -1
  191. package/dist/src/knowledge-memory/index.js +2 -2
  192. package/dist/src/knowledge-memory/repository.d.ts +7 -0
  193. package/dist/src/knowledge-memory/repository.js +58 -8
  194. package/dist/src/memory-maintenance/service.js +61 -31
  195. package/dist/src/migrations/memory-config.d.ts +2 -0
  196. package/dist/src/migrations/memory-config.js +77 -0
  197. package/dist/src/migrations/runner.js +2 -2
  198. package/dist/src/notifications/planner.js +5 -5
  199. package/dist/src/notifications/service.d.ts +2 -2
  200. package/dist/src/notifications/service.js +1 -1
  201. package/dist/src/storage/sqlite/index.d.ts +1 -0
  202. package/dist/src/storage/sqlite/index.js +2 -1
  203. package/dist/src/storage/sqlite/migrations/184_memory_suppressions.sql +12 -0
  204. package/dist/src/storage/sqlite/migrations/185_understanding_refresh_batches.sql +6 -0
  205. package/dist/src/storage/sqlite/migrations/186_sidebar_layout.sql +16 -0
  206. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  207. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  208. package/dist/src/storage/sqlite/schema.js +1 -1
  209. package/dist/src/storage/sqlite/sidebar-layout-repository.d.ts +12 -0
  210. package/dist/src/storage/sqlite/sidebar-layout-repository.js +53 -0
  211. package/dist/src/user-context/config.d.ts +4 -9
  212. package/dist/src/user-context/config.js +7 -27
  213. package/dist/src/user-context/memory-suppression.d.ts +7 -0
  214. package/dist/src/user-context/memory-suppression.js +23 -0
  215. package/dist/src/user-context/relationship-continuity.js +1 -1
  216. package/dist/src/user-context/sources/refresh-service.d.ts +48 -0
  217. package/dist/src/user-context/sources/refresh-service.js +221 -0
  218. package/dist/src/user-context/sources/repository.js +1 -1
  219. package/dist/src/user-model/bootstrap.js +27 -24
  220. package/dist/src/user-model/capture/executor.d.ts +1 -1
  221. package/dist/src/user-model/capture/executor.js +17 -11
  222. package/dist/src/user-model/capture/semantic.js +1 -1
  223. package/dist/src/user-model/domain.d.ts +6 -2
  224. package/dist/src/user-model/index.js +3 -3
  225. package/dist/src/user-model/profile.js +1 -1
  226. package/dist/src/user-model/repository.d.ts +4 -1
  227. package/dist/src/user-model/repository.js +96 -6
  228. package/dist/src/user-model/usage-policy.d.ts +2 -0
  229. package/dist/src/user-model/usage-policy.js +6 -2
  230. package/dist/src/work-discovery/project-understanding.js +2 -1
  231. package/dist/src/work-discovery/service.d.ts +8 -24
  232. package/dist/src/work-discovery/service.js +138 -180
  233. package/package.json +1 -1
  234. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-BPsRb9Ck.js +0 -1
  235. package/dist/gateway/static/root/assets/api-DFOlahZv.js +0 -1
  236. package/dist/gateway/static/root/assets/automations-workspace-CUpiTTiY.js +0 -6
  237. package/dist/gateway/static/root/assets/browser-settings-page-CqTxLpil.js +0 -3
  238. package/dist/gateway/static/root/assets/capabilities-settings-panel-BZ_-pnS6.js +0 -8
  239. package/dist/gateway/static/root/assets/connector-service-page-CPqVmNvx.js +0 -1
  240. package/dist/gateway/static/root/assets/connectors-page-BUQyg3CW.js +0 -2
  241. package/dist/gateway/static/root/assets/gateway-realtime-store-BLDgrJ30.js +0 -1
  242. package/dist/gateway/static/root/assets/home-page-s9hDQ8Hc.js +0 -1
  243. package/dist/gateway/static/root/assets/index-RBCkv8a_.js +0 -79
  244. package/dist/gateway/static/root/assets/index-cFU4S35z.css +0 -1
  245. package/dist/gateway/static/root/assets/messages-F74LVAiU.js +0 -3
  246. package/dist/gateway/static/root/assets/note-detail-panel-D35sErp2.js +0 -5
  247. package/dist/gateway/static/root/assets/notes-page-8jCDklDn.js +0 -8
  248. package/dist/gateway/static/root/assets/project-detail-page-BUMQHy_N.js +0 -1
  249. package/dist/gateway/static/root/assets/projects-page-DT-Mt7XR.js +0 -1
  250. package/dist/gateway/static/root/assets/remote-access-hub-Clz3byir.js +0 -1
  251. package/dist/gateway/static/root/assets/sessions-page-tQRwktKm.js +0 -1
  252. package/dist/gateway/static/root/assets/settings-advanced-gate-DqWg9XS5.js +0 -1
  253. package/dist/gateway/static/root/assets/setup-status-panel-BB_sMB7P.js +0 -1
  254. package/dist/gateway/static/root/assets/shares-settings-oDALm4b6.js +0 -1
  255. package/dist/gateway/static/root/assets/skill-reload-api-DmwelnfK.js +0 -1
  256. package/dist/gateway/static/root/assets/skills-page-BE9JXz4U.js +0 -2
  257. package/dist/gateway/static/root/assets/task-detail-page-D1AWszc7.js +0 -1
  258. package/dist/gateway/static/root/assets/user-model-page-C00i4ea0.js +0 -2
  259. package/dist/gateway/static/root/assets/workflows-page-BUiBjz6m.js +0 -6
  260. package/dist/src/migrations/knowledge-memory-read-policy-config.d.ts +0 -2
  261. package/dist/src/migrations/knowledge-memory-read-policy-config.js +0 -48
@@ -95,6 +95,7 @@ async function deriveConnectedSourceUnderstanding(input) {
95
95
  config: input.config,
96
96
  items
97
97
  });
98
+ input.assertAuthorized?.();
98
99
  const byRef = new Map(items.map((item) => [item.evidenceRef, item]));
99
100
  let created = 0;
100
101
  for (const candidate of analysis.profileCandidates.filter(isPortraitCandidate)) {
@@ -15,7 +15,7 @@ import "../knowledge/index.js";
15
15
  import { ingestComposioConnectedSource } from "./connected-source-ingestion.js";
16
16
  import { deriveConnectedSourceUnderstanding } from "./connected-source-understanding.js";
17
17
  import { listConnectedContentCandidates, readConnectedContent } from "./content-enrichment.js";
18
- import { createUnderstandingSourceRun, getUnderstandingSourceGrant, listUnderstandingSourceRuns, updateUnderstandingSourceGrantCheckpoint, updateUnderstandingSourceRun, upsertUnderstandingSourceGrant } from "../user-context/sources/repository.js";
18
+ import { createUnderstandingSourceRun, getUnderstandingSourceGrant, listUnderstandingSourceGrants, listUnderstandingSourceRuns, updateUnderstandingSourceGrantCheckpoint, updateUnderstandingSourceRun, upsertUnderstandingSourceGrant } from "../user-context/sources/repository.js";
19
19
  //#region src/connectors/learning-coordinator.ts
20
20
  init_logger();
21
21
  const log = createLogger("ConnectorLearning");
@@ -33,7 +33,9 @@ function connectorSourceCategory(toolkit) {
33
33
  return "files";
34
34
  }
35
35
  function ensureUnderstandingSourceRun(job, toolkit, displayName) {
36
- const grant = upsertUnderstandingSourceGrant({
36
+ const existing = listUnderstandingSourceGrants({ includeRevoked: true }).find((grant) => grant.sourceKey === `connector-account:${job.accountId}`);
37
+ if (existing?.status === "revoked") throw new Error("Source authorization was revoked.");
38
+ const grant = existing ?? upsertUnderstandingSourceGrant({
37
39
  sourceKey: `connector-account:${job.accountId}`,
38
40
  adapterId: `connector:${job.connectorId}`,
39
41
  category: connectorSourceCategory(toolkit),
@@ -75,6 +77,14 @@ function startConnectorLearningCoordinator(options) {
75
77
  if (!connection) return null;
76
78
  if (!connection.accountId) throw new Error(`Connector account is missing for connection ${connection.id}.`);
77
79
  if (!getConnectorAccount(connection.accountId)?.enabled) return null;
80
+ if (listUnderstandingSourceGrants({ includeRevoked: true }).some((grant) => grant.sourceKey === `connector-account:${connection.accountId}` && grant.status === "revoked")) return null;
81
+ if (request.reason === "manual") {
82
+ const active = listConnectorLearningJobs({
83
+ accountId: connection.accountId,
84
+ limit: 100
85
+ }).find((job) => job.status === "running" || job.status === "queued" && (!job.nextRunAt || Date.parse(job.nextRunAt) <= Date.now()));
86
+ if (active) return active;
87
+ }
78
88
  const syncPolicy = getConnectorSyncPolicyForConnection(connection.id);
79
89
  if (request.reason !== "manual" && syncPolicy?.scanEnabled !== true) return null;
80
90
  const definition = getConnectorDefinition(connection.connectorId);
@@ -213,13 +223,21 @@ function startConnectorLearningCoordinator(options) {
213
223
  knowledgeCount: 0,
214
224
  status: "completed"
215
225
  };
226
+ const sourceGrantPolicy = getUnderstandingSourceGrant(sourceRun.grantId)?.processingPolicy;
216
227
  try {
217
228
  semantic = await deriveConnectedSourceUnderstanding({
218
229
  config: options.getConfig(),
219
230
  agentId: job.agentId,
220
231
  sourceInstanceId: job.sourceInstanceId,
221
232
  sourceRunId: sourceRun.id,
222
- processingPolicy: getUnderstandingSourceGrant(sourceRun.grantId)?.processingPolicy ?? "local_only"
233
+ processingPolicy: getUnderstandingSourceGrant(sourceRun.grantId)?.processingPolicy ?? "local_only",
234
+ assertAuthorized: () => {
235
+ const grant = getUnderstandingSourceGrant(sourceRun.grantId);
236
+ if (grant?.status !== "active" || !getConnectorAccount(job.accountId)?.enabled || grant.processingPolicy !== sourceGrantPolicy || !learningEnabled(options.getConfig()) || listConnectorLearningJobs({
237
+ accountId: job.accountId,
238
+ limit: 100
239
+ }).find((item) => item.id === job.id)?.status !== "running") throw new Error("Source authorization changed during analysis.");
240
+ }
223
241
  });
224
242
  } catch (error) {
225
243
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -297,7 +315,7 @@ function startConnectorLearningCoordinator(options) {
297
315
  await execute(job);
298
316
  } catch (err) {
299
317
  const errorMessage = err instanceof Error ? err.message : String(err);
300
- const exhausted = job.attemptCount >= 5;
318
+ const exhausted = job.attemptCount >= 5 || job.idempotencyKey.startsWith("understanding-refresh:");
301
319
  publish(updateConnectorLearningJob(job.id, {
302
320
  status: exhausted ? "paused" : "failed",
303
321
  error: learningFailureCode(err),
@@ -305,11 +323,15 @@ function startConnectorLearningCoordinator(options) {
305
323
  finished: true
306
324
  }));
307
325
  const definition = getConnectorDefinition(job.connectorId);
308
- if (definition?.runtime.type === "composio" && definition.runtime.role === "toolkit") updateUnderstandingSourceRun(ensureUnderstandingSourceRun(job, definition.runtime.toolkit, definition.displayName).id, {
309
- status: "failed",
310
- errorMessage: learningFailureCode(err),
311
- completed: true
312
- });
326
+ if (definition?.runtime.type === "composio" && definition.runtime.role === "toolkit") {
327
+ const grant = listUnderstandingSourceGrants({ includeRevoked: true }).find((item) => item.sourceKey === `connector-account:${job.accountId}`);
328
+ const sourceRun = grant && listUnderstandingSourceRuns(grant.id, 100).find((item) => item.metadata.connectorLearningJobId === job.id);
329
+ if (sourceRun) updateUnderstandingSourceRun(sourceRun.id, {
330
+ status: "failed",
331
+ errorMessage: learningFailureCode(err),
332
+ completed: true
333
+ });
334
+ }
313
335
  log.warn({
314
336
  err,
315
337
  jobId: job.id,
@@ -277,4 +277,4 @@ export declare const GATEWAY_BUILTIN_TOOLS: readonly [{
277
277
  readonly zh: "使用已验证的参数执行选定的外部工具。";
278
278
  };
279
279
  }];
280
- export declare const GATEWAY_BUILTIN_TOOL_IDS: ("automation" | "workflow" | "find" | "image" | "knowledge_search" | "knowledge_get" | "knowledge_write" | "user_context_search" | "user_context_get" | "user_context_update" | "web_search" | "web_fetch" | "browser_use" | "grep" | "session_search" | "read_file" | "list_dir" | "write_file" | "apply_patch" | "exec_command" | "update_plan" | "todo" | "clarify" | "web_extract" | "image_generate" | "skills_list" | "skill_view" | "skill_manage" | "skills_marketplace_search" | "xopc_tool_search" | "xopc_tool_describe" | "xopc_tool_execute" | "send_message" | "send_media" | "read_media" | "create_share" | "session_status" | "memory_maintenance" | "computer_use" | "tool_manual" | "delegate_task" | "skill_install" | "text_to_speech" | "execute_code" | "create_desktop_pet")[];
280
+ export declare const GATEWAY_BUILTIN_TOOL_IDS: ("automation" | "workflow" | "find" | "image" | "knowledge_search" | "knowledge_get" | "knowledge_write" | "user_context_search" | "user_context_get" | "user_context_update" | "web_search" | "web_fetch" | "browser_use" | "grep" | "session_search" | "read_file" | "list_dir" | "write_file" | "apply_patch" | "exec_command" | "update_plan" | "todo" | "clarify" | "xopc_tool_execute" | "web_extract" | "image_generate" | "skills_list" | "skill_view" | "skill_manage" | "skills_marketplace_search" | "xopc_tool_search" | "xopc_tool_describe" | "send_message" | "send_media" | "read_media" | "create_share" | "session_status" | "memory_maintenance" | "computer_use" | "tool_manual" | "delegate_task" | "skill_install" | "text_to_speech" | "execute_code" | "create_desktop_pet")[];
@@ -4,11 +4,11 @@ import { init_agent_scope, resolveDefaultAgentId } from "../../agent/agent-scope
4
4
  import { createConversation, init_conversation_repository, resolveRoutedConversation } from "../../storage/sqlite/conversation-repository.js";
5
5
  import { shouldSilence, stripHeartbeatToken } from "../../heartbeat/tokens.js";
6
6
  import { proactiveChecksAllowed, proactivePreferences } from "../../proactive/policy/service.js";
7
+ import { beginHeartbeatCheck, completeHeartbeatCheck, deliverHeartbeatChecks, recentHeartbeatChecks, recoverHeartbeatChecks } from "./check-store.js";
8
+ import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
7
9
  import { isWithinActiveHours } from "../../heartbeat/active-hours.js";
8
10
  import { isHeartbeatContentEmpty } from "../../heartbeat/content-check.js";
9
- import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
10
11
  import { createHeartbeatWake } from "../../heartbeat/wake.js";
11
- import { beginHeartbeatCheck, completeHeartbeatCheck, deliverHeartbeatChecks, recentHeartbeatChecks, recoverHeartbeatChecks } from "./check-store.js";
12
12
  import { resolveHeartbeatMdPath } from "../workspace-heartbeat-path.js";
13
13
  import { readFile } from "fs/promises";
14
14
  //#region src/gateway/heartbeat/service.ts
@@ -49,6 +49,7 @@ export declare function buildSafeWebConfigPayload(service: GatewayService, optio
49
49
  };
50
50
  tools: Record<string, {
51
51
  mode: "allow" | "deny" | "ask";
52
+ readOnly?: boolean;
52
53
  maxCallsPerTurn?: number;
53
54
  timeoutMs?: number;
54
55
  }>;
@@ -99,6 +100,7 @@ export declare function buildSafeWebConfigPayload(service: GatewayService, optio
99
100
  };
100
101
  tools: Record<string, {
101
102
  mode: "allow" | "deny" | "ask";
103
+ readOnly?: boolean;
102
104
  maxCallsPerTurn?: number;
103
105
  timeoutMs?: number;
104
106
  }>;
@@ -222,7 +224,7 @@ export declare function buildSafeWebConfigPayload(service: GatewayService, optio
222
224
  };
223
225
  userModel: {
224
226
  enabled: boolean;
225
- writePolicy: "allow" | "confirm" | "deny";
227
+ writePolicy: "allow" | "deny";
226
228
  sensitiveWritePolicy: "allow" | "confirm" | "deny";
227
229
  processingPolicy: "local_only" | "remote_allowed";
228
230
  extraction: {
@@ -244,7 +246,7 @@ export declare function buildSafeWebConfigPayload(service: GatewayService, optio
244
246
  };
245
247
  knowledgeMemory: {
246
248
  enabled: boolean;
247
- writePolicy: "allow" | "confirm" | "deny";
249
+ writePolicy: "allow" | "deny";
248
250
  readScopes: ("project" | "session" | "agent" | "workspace" | "global")[];
249
251
  contentSources: ("memory" | "connector" | "local_import")[];
250
252
  searchStrategy: "local-first" | "external-first" | "fanout" | "local-only" | "external-only";
@@ -19,6 +19,7 @@ import { createConnectorSetupSecretRequest, submitConnectorSetupSecret } from ".
19
19
  import { recordConnectorHealthUsage } from "../../../connectors/usage.js";
20
20
  import { getConnectorInstance, getInstalledConnectorDefinition, listConnectorInstances } from "../../../connectors/instances.js";
21
21
  import { installConnector, installConnectorDefinition, uninstallConnector, updateConnectorConfig } from "../../../connectors/install.js";
22
+ import { ConfigPersistenceError, persistConfigMutation } from "../../../config/config-mutation.js";
22
23
  import { resumeApprovedConnectorAction } from "../../../connectors/approval-resume.js";
23
24
  import { getMcpOAuthManager } from "../../../agent/mcp/oauth/mcp-oauth-manager.js";
24
25
  import { startConnectorAuthorization } from "../../../connectors/auth-provider-registry.js";
@@ -26,7 +27,6 @@ import { composioLogoResponse } from "../../../connectors/composio-logo.js";
26
27
  import { inspectManagedComposioStatus } from "../../../connectors/composio-managed-client.js";
27
28
  import { appendComposioTriggerEvent, listComposioTriggerEvents } from "../../../connectors/composio-triggers.js";
28
29
  import { ingestLocalFolderSource } from "../../../connectors/connected-source-ingestion.js";
29
- import { ConfigPersistenceError, persistConfigMutation } from "../../../config/config-mutation.js";
30
30
  import { previewConnectorDefinition, testConnectorInstance } from "../../../connectors/health.js";
31
31
  import { listUnderstandingSourceGrants, revokeUnderstandingSourceGrant } from "../../../user-context/sources/repository.js";
32
32
  import { setConnectorEnabled } from "../../../connectors/lifecycle.js";
@@ -8,7 +8,6 @@ import "../../../user-model/index.js";
8
8
  import { listConnectedContentCandidates, readConnectedContent } from "../../../connectors/content-enrichment.js";
9
9
  import { getUnderstandingSourceGrant, listUnderstandingSourceGrants, listUnderstandingSourceRuns, revokeUnderstandingSourceGrant, updateUnderstandingSourceGrantPolicies } from "../../../user-context/sources/repository.js";
10
10
  import { listUnderstandingSourceDefinitions } from "../../../user-context/sources/catalog.js";
11
- import { randomUUID } from "node:crypto";
12
11
  //#region src/gateway/hono/routes/context-sources.ts
13
12
  init_agent_scope();
14
13
  init_transaction();
@@ -103,28 +102,6 @@ function registerContextSourceRoutes(authenticated, deps) {
103
102
  return c.json({ error: error instanceof Error ? error.message : String(error) }, 400);
104
103
  }
105
104
  });
106
- authenticated.post("/api/context-sources/grants/:grantId/refresh", limited, async (c) => {
107
- const grant = getUnderstandingSourceGrant(c.req.param("grantId"));
108
- if (!grant || grant.status !== "active") return c.json({ error: "Active context source not found" }, 404);
109
- try {
110
- if (grant.adapterId === "local-work-folders") {
111
- const result = await service.refreshDirectorySourceIfChanged({
112
- id: grant.id,
113
- idempotencyKey: randomUUID()
114
- });
115
- return c.json({ result }, result.changed ? 202 : 200);
116
- }
117
- const accountId = typeof grant.config.accountId === "string" ? grant.config.accountId : "";
118
- const connectionId = accountId ? getConnectorAccount(accountId)?.currentConnectionId : void 0;
119
- const job = connectionId ? deps.service.requestConnectorLearning(connectionId, {
120
- mode: "incremental",
121
- reason: "manual"
122
- }) : null;
123
- return job ? c.json({ job }, 202) : c.json({ error: "Context source cannot be refreshed here" }, 409);
124
- } catch (error) {
125
- return c.json({ error: error instanceof Error ? error.message : String(error) }, 400);
126
- }
127
- });
128
105
  authenticated.get("/api/context-sources/work-folders", (c) => c.json({ sources: service.listDirectorySources() }));
129
106
  authenticated.post("/api/context-sources/work-folders", limited, async (c) => {
130
107
  const input = await c.req.json().catch(() => null);
@@ -329,6 +329,14 @@ const AUTHENTICATED_LAZY_ROUTE_BUNDLES = [
329
329
  return { register: registerVoiceRoutes };
330
330
  }
331
331
  },
332
+ {
333
+ id: "user-model-refresh",
334
+ match: (pathname) => pathname === "/api/user-model/refresh" || pathname.startsWith("/api/user-model/refresh/"),
335
+ load: async () => {
336
+ const { registerUserModelRefreshRoutes } = await import("./user-model-refresh.js");
337
+ return { register: registerUserModelRefreshRoutes };
338
+ }
339
+ },
332
340
  {
333
341
  id: "user-model",
334
342
  match: (path) => startsWithAny(path, [
@@ -405,6 +405,10 @@ function registerProjectsRoutes(authenticated, deps) {
405
405
  originClass: "system",
406
406
  replaceExisting: true
407
407
  });
408
+ if (!record.item) return c.json({
409
+ ok: false,
410
+ error: "This memory was deleted and automatic recreation is disabled."
411
+ }, 409);
408
412
  return c.json({
409
413
  ok: true,
410
414
  knowledge: record.item
@@ -804,6 +808,10 @@ function registerProjectsRoutes(authenticated, deps) {
804
808
  originClass: "agent",
805
809
  replaceExisting: true
806
810
  });
811
+ if (!record.item) return c.json({
812
+ ok: false,
813
+ error: "This memory was deleted and automatic recreation is disabled."
814
+ }, 409);
807
815
  return c.json({
808
816
  ok: true,
809
817
  knowledge: record.item
@@ -2,7 +2,9 @@ import { deleteBrowserTabBinding } from "../../../storage/sqlite/browser-tab-bin
2
2
  import { conversationIdSchema } from "../../../../packages/gateway-contract/src/conversation-identity.js";
3
3
  import { SessionDiscoveryQuerySchema } from "../../../../packages/gateway-contract/src/session-identity.js";
4
4
  import { init_src } from "../../../../packages/gateway-contract/src/index.js";
5
+ import "../../../session/types.js";
5
6
  import { deleteSessionRecord, init_session_repository } from "../../../storage/sqlite/session-repository.js";
7
+ import { SidebarLayoutConflictError, getSidebarLayout, replaceSidebarLayout, sortBySidebarLayout } from "../../../storage/sqlite/sidebar-layout-repository.js";
6
8
  import { ConversationAlreadyExistsError, createConversation, init_conversation_repository } from "../../../storage/sqlite/conversation-repository.js";
7
9
  import { resolveProjectAgentId } from "../../../projects/project-agent.js";
8
10
  import "../../../projects/index.js";
@@ -48,6 +50,21 @@ function parseOffset(value) {
48
50
  const parsed = value ? Number.parseInt(value, 10) : 0;
49
51
  return Number.isFinite(parsed) ? Math.max(0, parsed) : 0;
50
52
  }
53
+ function listAllSidebarProjects(service, options = {}) {
54
+ const items = [];
55
+ let offset = 0;
56
+ while (true) {
57
+ const page = service.projects.listWithSidebarSessions({
58
+ status: "active",
59
+ limit: 50,
60
+ offset,
61
+ ...options
62
+ });
63
+ items.push(...page.items);
64
+ if (!page.hasMore || page.items.length === 0) return items;
65
+ offset += page.items.length;
66
+ }
67
+ }
51
68
  function isHistoryCursor(value) {
52
69
  if (!/^(0|[1-9]\d*)$/.test(value)) return false;
53
70
  return Number.isSafeInteger(Number(value));
@@ -101,18 +118,25 @@ function registerSessionsRoutes(authenticated, deps) {
101
118
  const staleDays = parsePositiveInt(c.req.query("staleDays"), DEFAULT_SIDEBAR_STALE_DAYS, 3650);
102
119
  const updatedAfter = Date.now() - staleDays * 24 * 60 * 60 * 1e3;
103
120
  const includeConversationId = c.req.query("includeConversationId")?.trim() || void 0;
104
- const projects = service.projects.listWithSidebarSessions({
105
- status: "active",
106
- limit: projectLimit,
107
- offset: projectOffset,
121
+ const allProjectItems = listAllSidebarProjects(service, {
108
122
  updatedAfter,
109
123
  includePinned: true,
110
124
  includeConversationId
111
125
  });
126
+ const projectLayout = getSidebarLayout("projects");
127
+ const orderedProjects = sortBySidebarLayout(allProjectItems, projectLayout, (project) => project.id);
128
+ const projects = {
129
+ items: orderedProjects.slice(projectOffset, projectOffset + projectLimit),
130
+ total: orderedProjects.length,
131
+ limit: projectLimit,
132
+ offset: projectOffset,
133
+ hasMore: projectOffset + projectLimit < orderedProjects.length
134
+ };
112
135
  const projectItems = await Promise.all(projects.items.map(async (project) => {
113
- const sessions = await service.sessions.listSessions({
136
+ const sessionLayout = getSidebarLayout(`project:${project.id}`);
137
+ const allSessions = await service.sessions.listSessions({
114
138
  projectId: project.id,
115
- limit: sessionPreviewLimit,
139
+ limit: 5e3,
116
140
  offset: 0,
117
141
  updatedAfter,
118
142
  includePinned: true,
@@ -122,21 +146,47 @@ function registerSessionsRoutes(authenticated, deps) {
122
146
  });
123
147
  return {
124
148
  project,
125
- sessions: sessions.items,
126
- sessionTotal: sessions.total,
127
- sessionHasMore: sessions.hasMore
149
+ sessions: sortBySidebarLayout(allSessions.items, sessionLayout, (session) => session.key).slice(0, sessionPreviewLimit),
150
+ sessionTotal: allSessions.total,
151
+ sessionHasMore: sessionPreviewLimit < allSessions.total
128
152
  };
129
153
  }));
130
- const inbox = await service.sessions.listSessions({
154
+ const inboxLayout = getSidebarLayout("inbox");
155
+ const allInbox = await service.sessions.listSessions({
131
156
  unassigned: true,
132
- limit: inboxLimit,
133
- offset: inboxOffset,
157
+ limit: 5e3,
158
+ offset: 0,
134
159
  updatedAfter,
135
160
  includePinned: true,
136
161
  includeConversationId,
137
162
  sortBy: "updatedAt",
138
163
  sortOrder: "desc"
139
164
  });
165
+ const orderedInbox = sortBySidebarLayout(allInbox.items, inboxLayout, (session) => session.key);
166
+ const inbox = {
167
+ ...allInbox,
168
+ items: orderedInbox.slice(inboxOffset, inboxOffset + inboxLimit),
169
+ limit: inboxLimit,
170
+ offset: inboxOffset,
171
+ hasMore: inboxOffset + inboxLimit < allInbox.total
172
+ };
173
+ const pinnedLayout = getSidebarLayout("pinned");
174
+ const pinned = sortBySidebarLayout((await service.sessions.listSessions({
175
+ status: "pinned",
176
+ limit: 5e3,
177
+ offset: 0,
178
+ sortBy: "updatedAt",
179
+ sortOrder: "desc"
180
+ })).items, pinnedLayout, (session) => session.key);
181
+ const layouts = Object.fromEntries([
182
+ projectLayout,
183
+ inboxLayout,
184
+ pinnedLayout,
185
+ ...projects.items.map((project) => getSidebarLayout(`project:${project.id}`))
186
+ ].map((layout) => [layout.containerId, {
187
+ itemIds: layout.itemIds,
188
+ revision: layout.revision
189
+ }]));
140
190
  return c.json({
141
191
  ok: true,
142
192
  projects: {
@@ -146,9 +196,87 @@ function registerSessionsRoutes(authenticated, deps) {
146
196
  offset: projects.offset,
147
197
  hasMore: projects.hasMore
148
198
  },
149
- inbox
199
+ inbox,
200
+ pinned,
201
+ layouts
150
202
  });
151
203
  });
204
+ authenticated.put("/api/sidebar/layouts/:containerId", async (c) => {
205
+ const blocked = ensureGatewayReadyForSessions(c, service, "sessions.list");
206
+ if (blocked) return blocked;
207
+ const containerId = decodeURIComponent(c.req.param("containerId"));
208
+ if (containerId !== "projects" && containerId !== "pinned" && containerId !== "inbox" && !containerId.startsWith("project:")) return c.json({
209
+ ok: false,
210
+ error: "Invalid sidebar container"
211
+ }, 400);
212
+ const body = await c.req.json().catch(() => ({}));
213
+ if (!Array.isArray(body.itemIds) || body.itemIds.length > 5e3 || body.itemIds.some((id) => typeof id !== "string" || !id.trim())) return c.json({
214
+ ok: false,
215
+ error: "itemIds must be an array of non-empty strings"
216
+ }, 400);
217
+ if (!Number.isInteger(body.expectedRevision) || body.expectedRevision < 0) return c.json({
218
+ ok: false,
219
+ error: "expectedRevision must be a non-negative integer"
220
+ }, 400);
221
+ const itemIds = [...new Set(body.itemIds)];
222
+ if (itemIds.length !== body.itemIds.length) return c.json({
223
+ ok: false,
224
+ error: "itemIds must be unique"
225
+ }, 400);
226
+ let completeItemIds = itemIds;
227
+ if (containerId === "projects") {
228
+ if (itemIds.some((id) => !service.projects.get(id))) return c.json({
229
+ ok: false,
230
+ error: "Project not found"
231
+ }, 404);
232
+ const allIds = listAllSidebarProjects(service).map((project) => project.id);
233
+ completeItemIds = [...itemIds, ...allIds.filter((id) => !itemIds.includes(id))];
234
+ } else {
235
+ const projectId = containerId.startsWith("project:") ? containerId.slice(8) : void 0;
236
+ if (projectId && !service.projects.get(projectId)) return c.json({
237
+ ok: false,
238
+ error: "Project not found"
239
+ }, 404);
240
+ if ((await Promise.all(itemIds.map((id) => service.sessions.getSession(id)))).some((session) => {
241
+ if (!session || session.status === "archived") return true;
242
+ if (containerId === "pinned") return session.status !== "pinned";
243
+ if (session.status === "pinned") return true;
244
+ if (containerId === "inbox") return Boolean(session.projectId);
245
+ return session.projectId !== projectId;
246
+ })) return c.json({
247
+ ok: false,
248
+ error: "Sidebar item does not belong to the container"
249
+ }, 409);
250
+ const eligibleIds = (await service.sessions.listSessions({
251
+ ...containerId === "pinned" ? { status: "pinned" } : containerId === "inbox" ? {
252
+ unassigned: true,
253
+ excludeArchived: true
254
+ } : {
255
+ projectId,
256
+ excludeArchived: true
257
+ },
258
+ limit: 5e3,
259
+ offset: 0,
260
+ sortBy: "updatedAt",
261
+ sortOrder: "desc"
262
+ })).items.filter((session) => containerId === "pinned" || session.status !== "pinned").map((session) => session.key);
263
+ completeItemIds = [...itemIds, ...eligibleIds.filter((id) => !itemIds.includes(id))];
264
+ }
265
+ try {
266
+ const layout = replaceSidebarLayout(containerId, completeItemIds, body.expectedRevision);
267
+ return c.json({
268
+ ok: true,
269
+ layout
270
+ });
271
+ } catch (error) {
272
+ if (error instanceof SidebarLayoutConflictError) return c.json({
273
+ ok: false,
274
+ error: error.message,
275
+ layout: error.current
276
+ }, 409);
277
+ throw error;
278
+ }
279
+ });
152
280
  authenticated.post("/api/sessions", async (c) => {
153
281
  const body = await c.req.json().catch(() => ({}));
154
282
  if (body.conversationId !== void 0 && !conversationIdSchema.safeParse(body.conversationId).success) return c.json({
@@ -0,0 +1,5 @@
1
+ import type { Hono } from 'hono';
2
+ import { UnderstandingRefreshService } from '../../../user-context/sources/refresh-service.js';
3
+ import type { AuthenticatedRouteDeps } from './deps.js';
4
+ export declare function createUnderstandingRefreshService(deps: AuthenticatedRouteDeps): UnderstandingRefreshService;
5
+ export declare function registerUserModelRefreshRoutes(app: Hono, deps: AuthenticatedRouteDeps, refresh?: UnderstandingRefreshService): void;
@@ -0,0 +1,128 @@
1
+ import { listConnectorLearningJobs } from "../../../storage/sqlite/connector-learning-repository.js";
2
+ import { getConnectorAccount } from "../../../storage/sqlite/connector-account-repository.js";
3
+ import "../../../storage/sqlite/index.js";
4
+ import { listUnderstandingSourceRuns } from "../../../user-context/sources/repository.js";
5
+ import { isLocalUnderstandingSourceId } from "../../../user-context/sources/local-source-contract.js";
6
+ import { getWorkDiscoveryRun } from "../../../work-discovery/repository.js";
7
+ import { normalizeUnderstandingSourceItems } from "../../../work-discovery/service.js";
8
+ import { UnderstandingRefreshService } from "../../../user-context/sources/refresh-service.js";
9
+ import { randomUUID } from "node:crypto";
10
+ //#region src/gateway/hono/routes/user-model-refresh.ts
11
+ function createUnderstandingRefreshService(deps) {
12
+ const service = deps.service;
13
+ return new UnderstandingRefreshService({
14
+ enabled: () => service.currentConfig.userContext.enabled && service.currentConfig.userContext.userModel.enabled,
15
+ emit: (type, payload) => service.emit(type, payload),
16
+ async start(grant, runId) {
17
+ if (grant.adapterId === "local-work-folders") return {
18
+ discoveryRunId: (await service.workDiscovery.rescanDirectorySource({
19
+ id: grant.id,
20
+ idempotencyKey: runId
21
+ })).id,
22
+ phase: "reading"
23
+ };
24
+ if (isLocalUnderstandingSourceId(grant.adapterId)) return { phase: "waiting_desktop" };
25
+ if (grant.adapterId.startsWith("connector:")) {
26
+ const account = typeof grant.config.accountId === "string" ? getConnectorAccount(grant.config.accountId) : void 0;
27
+ if (!account?.enabled || !account.currentConnectionId) throw new Error("Reconnect this source before updating.");
28
+ const job = service.requestConnectorLearning(account.currentConnectionId, {
29
+ mode: "incremental",
30
+ reason: "manual",
31
+ idempotencyKey: `understanding-refresh:${randomUUID()}`
32
+ });
33
+ if (!job) throw new Error("This source cannot currently be updated.");
34
+ return {
35
+ connectorLearningJobId: job.id,
36
+ accountId: account.id,
37
+ phase: "reading"
38
+ };
39
+ }
40
+ throw new Error("This source does not support understanding updates.");
41
+ },
42
+ progress(run) {
43
+ if (typeof run.metadata.discoveryRunId === "string") {
44
+ const discovery = getWorkDiscoveryRun(run.metadata.discoveryRunId);
45
+ if (!discovery) return {
46
+ status: "failed",
47
+ phase: "completed",
48
+ error: "Work folder update is no longer available."
49
+ };
50
+ return {
51
+ status: discovery.status === "completed" ? "completed" : discovery.status === "failed" || discovery.status === "canceled" ? "failed" : "running",
52
+ phase: discovery.status === "analyzing" ? "analyzing" : discovery.status === "queued" || discovery.status === "probing" ? "reading" : "completed",
53
+ error: discovery.errorMessage
54
+ };
55
+ }
56
+ if (typeof run.metadata.connectorLearningJobId === "string") {
57
+ const job = listConnectorLearningJobs({
58
+ accountId: String(run.metadata.accountId),
59
+ limit: 100
60
+ }).find((item) => item.id === run.metadata.connectorLearningJobId);
61
+ if (!job) return {
62
+ status: "failed",
63
+ phase: "completed",
64
+ error: "Connector update is no longer available."
65
+ };
66
+ const sourceRun = listUnderstandingSourceRuns(run.grantId, 100).find((item) => item.id !== run.id && item.metadata.connectorLearningJobId === job.id);
67
+ if (job.status === "completed") return {
68
+ status: sourceRun?.status === "partial" ? "partial" : "completed",
69
+ phase: "completed",
70
+ added: job.candidatesCreated,
71
+ itemsSeen: job.itemsDiscovered,
72
+ error: sourceRun?.status === "partial" ? "Some source information could not be analyzed. Retry this source." : void 0
73
+ };
74
+ if (job.status === "paused" || job.status === "failed") return {
75
+ status: "failed",
76
+ phase: "completed",
77
+ error: job.error ?? "Connector update failed."
78
+ };
79
+ return {
80
+ status: "running",
81
+ phase: job.phase === "deriving" ? "analyzing" : "reading",
82
+ itemsSeen: job.itemsDiscovered
83
+ };
84
+ }
85
+ },
86
+ async analyzeDesktop(grant, items, signal) {
87
+ const status = (await service.workDiscovery.importUnderstandingSources(items, grant.processingPolicy, signal, void 0, void 0, { grantId: grant.id })).sourceStatuses.find((item) => item.sourceId === grant.adapterId);
88
+ if (status?.status !== "completed") throw new Error(status?.error ?? "Source analysis did not complete.");
89
+ return {};
90
+ }
91
+ });
92
+ }
93
+ function registerUserModelRefreshRoutes(app, deps, refresh = createUnderstandingRefreshService(deps)) {
94
+ app.post("/api/user-model/refresh", deps.strictRateLimitMiddleware, async (c) => {
95
+ const input = await c.req.json().catch(() => null);
96
+ if (!input || typeof input !== "object" || Array.isArray(input) || input.sourceIds !== void 0 && (!Array.isArray(input.sourceIds) || !input.sourceIds.length || input.sourceIds.length > 100 || input.sourceIds.some((id) => typeof id !== "string" || !id))) return c.json({ error: "Provide sourceIds or an empty object to update all authorized sources." }, 400);
97
+ try {
98
+ return c.json({ batch: refresh.start(input.sourceIds) }, 202);
99
+ } catch (err) {
100
+ return c.json({ error: err instanceof Error ? err.message : String(err) }, 400);
101
+ }
102
+ });
103
+ app.get("/api/user-model/refresh", (c) => c.json({
104
+ batch: refresh.latest(),
105
+ sources: refresh.sources()
106
+ }));
107
+ app.get("/api/user-model/refresh/:id", (c) => {
108
+ const batch = refresh.get(c.req.param("id"));
109
+ return batch ? c.json({ batch }) : c.json({ error: "Update not found." }, 404);
110
+ });
111
+ app.post("/api/user-model/refresh/sources/:runId/collection", deps.strictRateLimitMiddleware, async (c) => {
112
+ const raw = await c.req.json().catch(() => null);
113
+ if (!raw || !Array.isArray(raw.items) || raw.items.length > 1200 || raw.error !== void 0 && typeof raw.error !== "string") return c.json({ error: "Invalid collection." }, 400);
114
+ const items = normalizeUnderstandingSourceItems(raw.items);
115
+ if (raw.items.length && !items.length) return c.json({ error: "No valid source items." }, 400);
116
+ try {
117
+ refresh.submitDesktop(c.req.param("runId"), {
118
+ items,
119
+ error: raw.error
120
+ });
121
+ return c.json({ ok: true }, 202);
122
+ } catch (err) {
123
+ return c.json({ error: err instanceof Error ? err.message : String(err) }, 409);
124
+ }
125
+ });
126
+ }
127
+ //#endregion
128
+ export { createUnderstandingRefreshService, registerUserModelRefreshRoutes };
@@ -1,10 +1,11 @@
1
1
  import { createCollaborationRule, getCollaborationRule, listCollaborationRules, setCollaborationRuleStatus } from "../../../storage/sqlite/collaboration-rule-repository.js";
2
- import { KnowledgeReviewConflictError, getKnowledgeItem, listKnowledgeItems, reviewKnowledgeItem, searchKnowledgeItems } from "../../../knowledge-memory/repository.js";
2
+ import { KnowledgeReviewConflictError, deleteKnowledgeItem, getKnowledgeItem, listKnowledgeItems, reviewKnowledgeItem, searchKnowledgeItems } from "../../../knowledge-memory/repository.js";
3
3
  import "../../../knowledge-memory/index.js";
4
4
  import { createPriorityWindow, createUserGoal, listPriorityWindows, listUserGoals, setUserGoalStatus } from "../../../user-model/goals.js";
5
- import { getAssertionSlot, getUserAssertion, listUserAssertionSources, listUserAssertions, reconcileAssertion, setAssertionStatus } from "../../../user-model/repository.js";
5
+ import { deleteUserAssertion, getAssertionSlot, getUserAssertion, listUserAssertionSources, listUserAssertions, reconcileAssertion, setAssertionStatus } from "../../../user-model/repository.js";
6
6
  import { applyUserProfilePatch, getUserProfileSnapshot } from "../../../user-model/profile.js";
7
7
  import { bootstrapUserModel } from "../../../user-model/bootstrap.js";
8
+ import { canUseAssertion } from "../../../user-model/usage-policy.js";
8
9
  import "../../../user-model/index.js";
9
10
  import { listMemoryMaintenanceRuns } from "../../../memory-maintenance/service.js";
10
11
  import "../../../memory-maintenance/index.js";
@@ -117,7 +118,8 @@ function assertionView(assertion, sources = listUserAssertionSources([assertion.
117
118
  predicate: slot.predicate,
118
119
  subject: slot.subject,
119
120
  scope: slot.scope,
120
- sources
121
+ sources,
122
+ usable: canUseAssertion(assertion)
121
123
  };
122
124
  }
123
125
  function registerUserModelRoutes(authenticated, deps) {
@@ -259,11 +261,14 @@ function registerUserModelRoutes(authenticated, deps) {
259
261
  createdBy: "user",
260
262
  ...typeof input.correctionOfAssertionId === "string" ? { correctionOfAssertionId: input.correctionOfAssertionId } : {}
261
263
  };
262
- return c.json(reconcileAssertion(candidate), 201);
264
+ return c.json(reconcileAssertion(candidate, Date.now(), { restoreDeleted: true }), 201);
263
265
  } catch (error) {
264
266
  return c.json({ error: errorMessage(error) }, 400);
265
267
  }
266
268
  });
269
+ authenticated.delete("/api/user-model/assertions/:id", write, (c) => {
270
+ return deleteUserAssertion(c.req.param("id")) ? c.json({ ok: true }) : c.json({ error: "Assertion not found" }, 404);
271
+ });
267
272
  authenticated.patch("/api/user-model/assertions/:id/status", write, async (c) => {
268
273
  const input = await body(c);
269
274
  const status = input?.status;
@@ -307,7 +312,6 @@ function registerUserModelRoutes(authenticated, deps) {
307
312
  ...current.validFrom === void 0 ? {} : { validFrom: current.validFrom },
308
313
  ...current.validTo === void 0 ? {} : { validTo: current.validTo },
309
314
  observedAt: Date.now(),
310
- ...current.reviewAt === void 0 ? {} : { reviewAt: current.reviewAt },
311
315
  createdBy: "user",
312
316
  correctionOfAssertionId: current.id
313
317
  }));
@@ -405,6 +409,9 @@ function registerUserModelRoutes(authenticated, deps) {
405
409
  const item = getKnowledgeItem(c.req.param("id"));
406
410
  return item ? c.json({ item }) : c.json({ error: "Knowledge item not found" }, 404);
407
411
  });
412
+ authenticated.delete("/api/knowledge-memory/:id", write, (c) => {
413
+ return deleteKnowledgeItem(c.req.param("id")) ? c.json({ ok: true }) : c.json({ error: "Knowledge item not found" }, 404);
414
+ });
408
415
  authenticated.post("/api/knowledge-memory/:id/review", write, async (c) => {
409
416
  const input = await body(c);
410
417
  const action = String(input?.action ?? "");