@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.
- package/dist/browser-ext/_locales/en/messages.json +8 -0
- package/dist/browser-ext/_locales/zh_CN/messages.json +8 -0
- package/dist/browser-ext/dist/assets/{sidepanel-BbSQr-6P.css → sidepanel-DD6GEMvc.css} +16 -0
- package/dist/browser-ext/dist/sidepanel.html +1 -1
- package/dist/browser-ext/dist/sidepanel.js +537 -96
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-wgSB2HYK.js → activity-store-XKNYlFUI.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CZeQo09T.js → agent-avatar-dicebear-1S2TFECE.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-f0-YFMUz.js +1 -0
- package/dist/gateway/static/root/assets/{agents-BlrHMbRx.js → agents-CPqUMtCL.js} +1 -1
- package/dist/gateway/static/root/assets/{api-BKHmTb0w.js → api-BEUEE4f2.js} +1 -1
- package/dist/gateway/static/root/assets/api-CN4id43t.js +1 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-Bzw4fQP8.js → app-management-settings-panel-CgVBSqzu.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-8GZpUXva.js → appearance-settings-CoWdCokb.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-BkQQtIxH.js → apps-page-CexHOcWg.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-CQ2NaoHb.js → archive-plugin-C3ZA6LRS.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-BFi1H7yJ.js → attachment-load-CdgS6_zy.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-CDBXcii_.js → automations-page-BtHL2hpg.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-onJPfmO6.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-D07eWmOx.js → binary-plugins-CiDhtq_H.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CtVnjyYU.js → block-editor-Br00T83w.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automation-inputs-BzkJog8e.js → browser-automation-inputs-D2tILykA.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-DyrSbDdG.js → browser-automations-page-BVuEmryB.js} +1 -1
- package/dist/gateway/static/root/assets/browser-settings-page-BgVTyPFY.js +3 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-Dra8wj1S.js +8 -0
- package/dist/gateway/static/root/assets/{channels-settings-DAD9qE3J.js → channels-settings-CkxiMDJ4.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-status-swr-B2JwuTjG.js → channels-status-swr-Dtder4G_.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-B62SZdAo.js → chat-terminal-dock-JsMtzDao.js} +1 -1
- package/dist/gateway/static/root/assets/{computer-settings-page-ClSresNq.js → computer-settings-page-DHerePwo.js} +1 -1
- package/dist/gateway/static/root/assets/connector-service-page-DZFNUTiN.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-cl9ZrV4D.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-CTMi_tql.js → cron-expression-DAhdv_Xv.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-B71AJK50.js → date-picker-PacO1m3a.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-DlyGK-kA.js → dependency-picker-B-BcuG1y.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-DGkbTE8_.js → desktop-pet-CdBBhhdY.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BY8r9j66.js → desktop-pet-settings-Gy03NgMI.js} +1 -1
- package/dist/gateway/static/root/assets/{device-pairing-wizard-DzRrgd59.js → device-pairing-wizard-aV25nKag.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-L8Mm1n3A.js → extension-debug-page-BFp5eKtY.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CFc4vSNU.js → extension-page-DL3vyyH6.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-B5zWyHr3.js → extension-settings-page-BXtvdAsY.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-B6wHa6ZI.js → gateway-config-swr-xAOGtenO.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-realtime-B53R0CA4.js → gateway-realtime-BuaTsMSi.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-BG95uGVW.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-settings-D7qmTH4R.js → gateway-settings-Dcr2Ikeh.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-DRzGnEV-.js → gateway-startup-retry-BwDxKHd4.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-Glsl3X5b.js → heartbeat-settings-DOy3alvT.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-CDm3dGVy.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-Ck_pyDom.js → image-generation-api-wGMeI_yW.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-ByBX7ome.js → imports-page-zexFT5Rq.js} +1 -1
- package/dist/gateway/static/root/assets/index-D-vczw_0.css +1 -0
- package/dist/gateway/static/root/assets/index-DJo4DimT.js +79 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-C45RlO8a.js → keyboard-shortcuts-settings-CutG9zLh.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-DP0x2jpR.js → local-app-workbench-page-CwLvTwjn.js} +2 -2
- package/dist/gateway/static/root/assets/{local-apps-page-C_AQc2bI.js → local-apps-page-CJy6I7Dt.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-msTfRK8P.js → locale-store-DPZ79W1-.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-DvM8Pyok.js → logs-page-egGcPHNi.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-D1uwSutV.js → management-settings-BQhIOELc.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-BInabSKf.js → markdown-view-p2P5hP1U.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-C4mhf13f.js → media-plugins-CsBylqlN.js} +1 -1
- package/dist/gateway/static/root/assets/messages-BiYTyLJr.js +3 -0
- package/dist/gateway/static/root/assets/note-detail-panel-c2k5Uz6X.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-BLQWJMhf.js +8 -0
- package/dist/gateway/static/root/assets/{page-tabs-1go_BtX1.js → page-tabs-ChQ4jJFs.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-DmoSC0j1.js → preview-open-alternatives-9B5W7nVE.js} +1 -1
- package/dist/gateway/static/root/assets/{proactive-page-xAjKTIID.js → proactive-page-iOjI0d_e.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-gmi5LLwM.js → product-open-page-BADxWEdP.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-BcxbQn2M.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-BuSvld0O.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-BSWtko7U.js → registry-api-B_e_nZSN.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CFS8LQKW.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-ClkOoxDl.js → runtime-tools-settings-panel-D-pwiIyp.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-BuEmLiaU.js → schema-form-IWmb05DX.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DZjc__ok.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-C1SM5B93.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-Dor39QON.js → settings-form-section-B0veRBZs.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-Xj-yvIc8.js → settings-page-CxRWyWYe.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-D9Rl7Tec.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-BFWZoXdm.js → share-preview-page-CirpgkfD.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-CwCThBs0.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-DG6VGbOX.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-BdRJ2vnL.js +2 -0
- package/dist/gateway/static/root/assets/{skills-page.utils-Ii8qeXhs.js → skills-page.utils-B42mpWKV.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-Di6OSO-0.js → system-settings-panel-DXIZpAvU.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-QXo9LJly.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-1SZ-HFHX.js → theme-store-BFbj_2Tu.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-DDOlOYlj.js → tunnel-api-Db2guRdW.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-CQ8uWNnB.js → use-autosave-DDY9qoXZ.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-CzPmMkaO.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-COTzshjL.js → voice-api-key-field-BZbKQ8HT.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-DgJML_uM.js → voice-config-api-SKCeQLrH.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-_URrXbi4.js → work-discovery-overlay-BRVTTXNG.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CALs-1nd.js → workflow-run-setup-panel-D2kuwv5e.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-CQXtiYtq.js +6 -0
- package/dist/gateway/static/root/index.html +12 -12
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/notifications.js +1 -1
- package/dist/packages/gateway-contract/src/sessions.js +6 -1
- package/dist/src/agent/agent-manager.js +29 -4
- package/dist/src/agent/background-review/prompts.js +3 -1
- package/dist/src/agent/child-agent-factory.d.ts +1 -0
- package/dist/src/agent/child-agent-factory.js +18 -4
- package/dist/src/agent/coding/repository-instructions.d.ts +4 -0
- package/dist/src/agent/coding/repository-instructions.js +46 -2
- package/dist/src/agent/context/execution-context.js +4 -4
- package/dist/src/agent/data-acquisition/git.d.ts +17 -0
- package/dist/src/agent/data-acquisition/git.js +100 -0
- package/dist/src/agent/data-acquisition/render.d.ts +7 -0
- package/dist/src/agent/data-acquisition/render.js +79 -0
- package/dist/src/agent/data-acquisition/scheduler.d.ts +12 -0
- package/dist/src/agent/data-acquisition/scheduler.js +53 -0
- package/dist/src/agent/data-acquisition/schema.d.ts +75 -0
- package/dist/src/agent/data-acquisition/schema.js +206 -0
- package/dist/src/agent/data-acquisition/service.d.ts +10 -0
- package/dist/src/agent/data-acquisition/service.js +292 -0
- package/dist/src/agent/data-acquisition/types.d.ts +37 -0
- package/dist/src/agent/data-acquisition/types.js +5 -0
- package/dist/src/agent/embedded/run-turn.js +16 -4
- package/dist/src/agent/embedded/session-runner.d.ts +1 -0
- package/dist/src/agent/embedded/session-runner.js +3 -0
- package/dist/src/agent/embedded/tool-result-truncation.js +11 -0
- package/dist/src/agent/embedded/xopc-tools-bridge.js +2 -1
- package/dist/src/agent/external-tools/composio-provider.js +12 -1
- package/dist/src/agent/external-tools/gateway-tools.js +2 -1
- package/dist/src/agent/external-tools/index.js +8 -1
- package/dist/src/agent/external-tools/read-policy.d.ts +6 -0
- package/dist/src/agent/external-tools/read-policy.js +21 -0
- package/dist/src/agent/external-tools/service.d.ts +1 -0
- package/dist/src/agent/external-tools/service.js +4 -1
- package/dist/src/agent/external-tools/types.d.ts +2 -0
- package/dist/src/agent/memory/compaction-promotion.d.ts +1 -1
- package/dist/src/agent/memory/compaction-promotion.js +4 -3
- package/dist/src/agent/orchestration/agent-turn-policy.js +25 -10
- package/dist/src/agent/orchestration/delegation-scope.d.ts +9 -0
- package/dist/src/agent/orchestration/delegation-scope.js +11 -0
- package/dist/src/agent/prompt/sections/tooling.js +3 -1
- package/dist/src/agent/prompt/subagent-context.js +4 -2
- package/dist/src/agent/sandbox/fileAccess.d.ts +2 -0
- package/dist/src/agent/sandbox/fileAccess.js +31 -2
- package/dist/src/agent/tools/dataBatch.d.ts +4 -0
- package/dist/src/agent/tools/dataBatch.js +50 -0
- package/dist/src/agent/tools/delegate-tool.d.ts +6 -3
- package/dist/src/agent/tools/delegate-tool.js +65 -48
- package/dist/src/agent/tools/delegation-parent-policy.d.ts +7 -0
- package/dist/src/agent/tools/delegation-parent-policy.js +41 -0
- package/dist/src/agent/tools/delegation-policy.d.ts +16 -0
- package/dist/src/agent/tools/delegation-policy.js +93 -0
- package/dist/src/agent/tools/factory.d.ts +2 -0
- package/dist/src/agent/tools/factory.js +42 -3
- package/dist/src/agent/tools/fetch-text.d.ts +7 -0
- package/dist/src/agent/tools/fetch-text.js +86 -0
- package/dist/src/agent/tools/find.js +1 -1
- package/dist/src/agent/tools/grep.js +11 -23
- package/dist/src/agent/tools/index.d.ts +1 -0
- package/dist/src/agent/tools/index.js +2 -1
- package/dist/src/agent/tools/knowledge-memory-tool.d.ts +1 -1
- package/dist/src/agent/tools/knowledge-memory-tool.js +13 -5
- package/dist/src/agent/tools/read.js +7 -5
- package/dist/src/agent/tools/repository-search.d.ts +12 -2
- package/dist/src/agent/tools/repository-search.js +127 -74
- package/dist/src/agent/tools/user-context-tool.js +17 -7
- package/dist/src/agent/tools/web.js +19 -28
- package/dist/src/agent/workflow/subagent-runner.js +25 -3
- package/dist/src/agent/workflow/workflow-child-tools.js +13 -8
- package/dist/src/agent-config/schema.d.ts +7 -0
- package/dist/src/agent-config/schema.js +2 -0
- package/dist/src/chat-commands/builtins/understanding.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/config/schema.d.ts +6 -4
- package/dist/src/config/schema.js +2 -2
- package/dist/src/connectors/connected-source-understanding.d.ts +1 -0
- package/dist/src/connectors/connected-source-understanding.js +1 -0
- package/dist/src/connectors/learning-coordinator.js +31 -9
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/heartbeat/service.js +2 -2
- package/dist/src/gateway/hono/lib/config-payload.d.ts +4 -2
- package/dist/src/gateway/hono/routes/connectors.js +1 -1
- package/dist/src/gateway/hono/routes/context-sources.js +0 -23
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/projects.js +8 -0
- package/dist/src/gateway/hono/routes/sessions.js +141 -13
- package/dist/src/gateway/hono/routes/user-model-refresh.d.ts +5 -0
- package/dist/src/gateway/hono/routes/user-model-refresh.js +128 -0
- package/dist/src/gateway/hono/routes/user-model.js +12 -5
- package/dist/src/gateway/hono/routes/work-discovery.js +0 -30
- package/dist/src/gateway/service.js +6 -6
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/update-restart.js +1 -1
- package/dist/src/knowledge/connected-knowledge-pipeline.js +1 -1
- package/dist/src/knowledge-memory/index.js +2 -2
- package/dist/src/knowledge-memory/repository.d.ts +7 -0
- package/dist/src/knowledge-memory/repository.js +58 -8
- package/dist/src/memory-maintenance/service.js +61 -31
- package/dist/src/migrations/memory-config.d.ts +2 -0
- package/dist/src/migrations/memory-config.js +77 -0
- package/dist/src/migrations/runner.js +2 -2
- package/dist/src/notifications/planner.js +5 -5
- package/dist/src/notifications/service.d.ts +2 -2
- package/dist/src/notifications/service.js +1 -1
- package/dist/src/storage/sqlite/index.d.ts +1 -0
- package/dist/src/storage/sqlite/index.js +2 -1
- package/dist/src/storage/sqlite/migrations/184_memory_suppressions.sql +12 -0
- package/dist/src/storage/sqlite/migrations/185_understanding_refresh_batches.sql +6 -0
- package/dist/src/storage/sqlite/migrations/186_sidebar_layout.sql +16 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/sidebar-layout-repository.d.ts +12 -0
- package/dist/src/storage/sqlite/sidebar-layout-repository.js +53 -0
- package/dist/src/user-context/config.d.ts +4 -9
- package/dist/src/user-context/config.js +7 -27
- package/dist/src/user-context/memory-suppression.d.ts +7 -0
- package/dist/src/user-context/memory-suppression.js +23 -0
- package/dist/src/user-context/relationship-continuity.js +1 -1
- package/dist/src/user-context/sources/refresh-service.d.ts +48 -0
- package/dist/src/user-context/sources/refresh-service.js +221 -0
- package/dist/src/user-context/sources/repository.js +1 -1
- package/dist/src/user-model/bootstrap.js +27 -24
- package/dist/src/user-model/capture/executor.d.ts +1 -1
- package/dist/src/user-model/capture/executor.js +17 -11
- package/dist/src/user-model/capture/semantic.js +1 -1
- package/dist/src/user-model/domain.d.ts +6 -2
- package/dist/src/user-model/index.js +3 -3
- package/dist/src/user-model/profile.js +1 -1
- package/dist/src/user-model/repository.d.ts +4 -1
- package/dist/src/user-model/repository.js +96 -6
- package/dist/src/user-model/usage-policy.d.ts +2 -0
- package/dist/src/user-model/usage-policy.js +6 -2
- package/dist/src/work-discovery/project-understanding.js +2 -1
- package/dist/src/work-discovery/service.d.ts +8 -24
- package/dist/src/work-discovery/service.js +138 -180
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-BPsRb9Ck.js +0 -1
- package/dist/gateway/static/root/assets/api-DFOlahZv.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-CUpiTTiY.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-CqTxLpil.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BZ_-pnS6.js +0 -8
- package/dist/gateway/static/root/assets/connector-service-page-CPqVmNvx.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-BUQyg3CW.js +0 -2
- package/dist/gateway/static/root/assets/gateway-realtime-store-BLDgrJ30.js +0 -1
- package/dist/gateway/static/root/assets/home-page-s9hDQ8Hc.js +0 -1
- package/dist/gateway/static/root/assets/index-RBCkv8a_.js +0 -79
- package/dist/gateway/static/root/assets/index-cFU4S35z.css +0 -1
- package/dist/gateway/static/root/assets/messages-F74LVAiU.js +0 -3
- package/dist/gateway/static/root/assets/note-detail-panel-D35sErp2.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-8jCDklDn.js +0 -8
- package/dist/gateway/static/root/assets/project-detail-page-BUMQHy_N.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-DT-Mt7XR.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-Clz3byir.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-tQRwktKm.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DqWg9XS5.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BB_sMB7P.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-oDALm4b6.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DmwelnfK.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-BE9JXz4U.js +0 -2
- package/dist/gateway/static/root/assets/task-detail-page-D1AWszc7.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-C00i4ea0.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-BUiBjz6m.js +0 -6
- package/dist/src/migrations/knowledge-memory-read-policy-config.d.ts +0 -2
- 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
|
|
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")
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
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" | "
|
|
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" | "
|
|
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" | "
|
|
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
|
|
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
|
|
136
|
+
const sessionLayout = getSidebarLayout(`project:${project.id}`);
|
|
137
|
+
const allSessions = await service.sessions.listSessions({
|
|
114
138
|
projectId: project.id,
|
|
115
|
-
limit:
|
|
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:
|
|
126
|
-
sessionTotal:
|
|
127
|
-
sessionHasMore:
|
|
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
|
|
154
|
+
const inboxLayout = getSidebarLayout("inbox");
|
|
155
|
+
const allInbox = await service.sessions.listSessions({
|
|
131
156
|
unassigned: true,
|
|
132
|
-
limit:
|
|
133
|
-
offset:
|
|
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 ?? "");
|