@xopcai/xopc 0.0.224 → 0.0.227
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/manifest.json +1 -1
- package/dist/extensions/demo-memory/src/index.js +10 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store--GBciH10.js → activity-store-BevwE16n.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-K7V4XXt7.js → agent-avatar-dicebear-BggVQrEZ.js} +1 -1
- package/dist/gateway/static/root/assets/agents-TJpjRHnr.js +68 -0
- package/dist/gateway/static/root/assets/{api-HoIz_ija.js → api-Bx_BpIt8.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-xQCmkAHh.js → app-management-settings-panel-BtKP9n2r.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BRoeA4kU.js → appearance-settings-BoH2NAUX.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-CZ4Da51l.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-CteCVsBP.js → archive-plugin-DnceUyxm.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-D7xNA2jB.js → attachment-load-Bh8_9gkr.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-BD1vK7r5.js → automations-page-ZKeAAVxD.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-2Y00PvJU.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-C3DaJa0W.js → binary-plugins-Cy9er6w-.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-lTkcHTve.js → block-editor-Cc0wWvNX.js} +3 -3
- package/dist/gateway/static/root/assets/browser-settings-page-CbJD27_j.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-1UZ0vnIy.js → browser-workflow-inputs-BS7rpLLl.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-BHuJOF4M.js → browser-workflows-page-BdBVUZXm.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-Dv8y6OuP.js +7 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-yNqTIuyd.js → capability-presets-api-D1Lqz0Tt.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-TZmjzWzt.js +3 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-krezGsKc.js → channel-recipient-api-CGuEl-l2.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-B4AtvQHk.js → channels-settings-g-68dutA.js} +1 -1
- package/dist/gateway/static/root/assets/channels-status-swr-D7KsAeWh.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-BRrL2iHA.js → chat-terminal-dock-CdX_7aQh.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-DXA0rAvQ.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-Bl-2DzBQ.js → cron-expression-BnSQc4Ek.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-CxTl6Wlz.js → date-picker-BbuG7zQ_.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-DSl0mOPa.js → dependency-picker-snZeqOmG.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-DTeCmCdb.js → desktop-pet-DJQ8JoR1.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BNebxg0V.js → desktop-pet-settings-B9txsRtv.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-Dn9XpmXY.js → directory-picker-path-field-D7WKWkNB.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-D-J-eOTb.js → extension-debug-page-D_7cOCj2.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CpST24nU.js → extension-page-Bwu47iUb.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-4nQXFnFq.js → extension-settings-page-Dwg4dSZM.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-BHWHduDi.js → gateway-config-api-jURUSte_.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-yUxMMVjK.js → gateway-config-swr-6SQXF1yR.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-BimMKmkM.js → gateway-settings-UklJOMLX.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-9mrsL84j.js → gateway-startup-retry-DqWaxyvZ.js} +1 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-Djs_nduD.js +1 -0
- package/dist/gateway/static/root/assets/{home-page-DSM6aPHF.js → home-page-i6bXCHdo.js} +1 -1
- package/dist/gateway/static/root/assets/{image-generation-api-CgFAGDi8.js → image-generation-api-Bxmt6LEr.js} +1 -1
- package/dist/gateway/static/root/assets/index-BBBE89vm.css +2 -0
- package/dist/gateway/static/root/assets/index-BsD5wygl.js +74 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-6Ar5rfX4.js → keyboard-shortcuts-settings-ByVsCH3d.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-tzM0wTL8.js → local-app-workbench-page-BCKEDMlP.js} +2 -2
- package/dist/gateway/static/root/assets/{local-apps-page-B5n-x544.js → local-apps-page-D19R-xsz.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-CPylQjH9.js → locale-store-Ci1Qi0Q-.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-CgoQlera.js → logs-page-Cy9YQK7j.js} +2 -2
- package/dist/gateway/static/root/assets/{management-settings-CXBLyU-0.js → management-settings-G0y7zmfY.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-CtmQemJi.js → markdown-split-B69d2HWt.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-CUsob4Pz.js → markdown-view-CBM-v2ph.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-Dsd-IEOW.js → media-plugins-6TWEQgN_.js} +1 -1
- package/dist/gateway/static/root/assets/messages-CtOJwGW3.js +3 -0
- package/dist/gateway/static/root/assets/{notes-api-CfKZYrBC.js → notes-api-DLsnnZCS.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-BKbOTE2n.js → notes-page-CkRJJKDm.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-B10T3hGX.js +4 -0
- package/dist/gateway/static/root/assets/{product-open-page-DqB9bsDB.js → product-open-page-HxArIvoN.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-DsqRlgsy.js +1 -0
- package/dist/gateway/static/root/assets/{projects-page-PeXUdGdO.js → projects-page-Bu2PN8OK.js} +1 -1
- package/dist/gateway/static/root/assets/{registry-api-B_5D8epF.js → registry-api-lEar5FOV.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CXACdJ2f.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DBTH_t0O.js → runtime-tools-settings-panel-Bf03UNGD.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-CqMKAwV0.js → schema-form-CIXMBgx5.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-CS2knWDT.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-ByFGk0q_.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-dPriuuYq.js → settings-form-section-DgdB26mE.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-B-Mbm8Va.js → settings-loading-skeleton-efk5W6lG.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-Dyj3w-Ml.js → settings-page-BHVf4gEP.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-C4FxY5J3.js → setup-status-panel-WK0dGNMv.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-emEdx7YL.js → share-preview-page-Cod-w2qm.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-CUqQ31gt.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-DweAPjI8.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-BNtYnrRT.js → skills-page-DwCcipqK.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-DjnbNFs5.js → skills-page.utils-3WSbtl3S.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-DDStf-jZ.js → system-settings-panel-C5VxqC_s.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-DEj-BFMP.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-BN-32Fz5.js → theme-store-Dd89g_ki.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-C2mKZ-ua.js → use-autosave-CeV8VJh2.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-f7yh7aD5.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-D7OHeQby.js → voice-api-key-field-EmJ-8aZu.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-CIiXie7F.js → work-discovery-overlay-zsk6E3Mi.js} +1 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-CBAYvm3G.js +3 -0
- package/dist/gateway/static/root/assets/workflows-page-BN0JmHrG.js +5 -0
- package/dist/gateway/static/root/index.html +11 -11
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +3 -1
- package/dist/src/agent/agent-manager.js +22 -5
- package/dist/src/agent/embedded/run-turn.js +2 -0
- package/dist/src/agent/mcp/bundle-mcp-config.d.ts +9 -1
- package/dist/src/agent/mcp/bundle-mcp-config.js +11 -15
- package/dist/src/agent/mcp/embedded-mcp.d.ts +1 -1
- package/dist/src/agent/mcp/index.d.ts +1 -0
- package/dist/src/agent/mcp/index.js +7 -1
- package/dist/src/agent/mcp/mcp-http.d.ts +4 -0
- package/dist/src/agent/mcp/mcp-http.js +25 -1
- package/dist/src/agent/mcp/mcp-transport-config.d.ts +4 -0
- package/dist/src/agent/mcp/mcp-transport-config.js +1 -0
- package/dist/src/agent/mcp/mcp-transport.d.ts +7 -1
- package/dist/src/agent/mcp/mcp-transport.js +38 -11
- package/dist/src/agent/mcp/oauth/index.d.ts +6 -0
- package/dist/src/agent/mcp/oauth/index.js +6 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-errors.d.ts +5 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-errors.js +14 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-manager.d.ts +25 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-manager.js +219 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-provider.d.ts +33 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-provider.js +103 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-session.d.ts +29 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-session.js +169 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-store.d.ts +9 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +79 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-types.d.ts +22 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-types.js +1 -0
- package/dist/src/agent/memory/builtin-provider.js +23 -4
- package/dist/src/agent/memory/compaction-promotion.d.ts +18 -0
- package/dist/src/agent/memory/compaction-promotion.js +211 -0
- package/dist/src/agent/memory/context/types.d.ts +5 -0
- package/dist/src/agent/memory/manager.d.ts +3 -0
- package/dist/src/agent/memory/manager.js +12 -2
- package/dist/src/agent/memory/trusted-recall.d.ts +7 -0
- package/dist/src/agent/memory/trusted-recall.js +53 -0
- package/dist/src/agent/memory/turn-provenance.d.ts +14 -0
- package/dist/src/agent/memory/turn-provenance.js +60 -0
- package/dist/src/agent/memory/types.d.ts +18 -3
- package/dist/src/agent/memory/understanding/service.js +1 -0
- package/dist/src/agent/memory/understanding/types.d.ts +1 -0
- package/dist/src/agent/memory/user-context-coordinator.js +57 -6
- package/dist/src/agent/service.d.ts +2 -0
- package/dist/src/agent/service.js +6 -0
- package/dist/src/agent/skills/index.d.ts +22 -2
- package/dist/src/agent/skills/index.js +74 -32
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.d.ts +2 -0
- package/dist/src/agent/skills/skill-sources.d.ts +0 -1
- package/dist/src/agent/skills/skill-sources.js +1 -11
- package/dist/src/agent/tools/memory-tool.js +5 -1
- package/dist/src/capabilities/store-connector.js +99 -10
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/cli/commands/connectors.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/config/config-mutation.d.ts +14 -0
- package/dist/src/config/config-mutation.js +33 -0
- package/dist/src/config/index.js +3 -3
- package/dist/src/config/paths.d.ts +2 -0
- package/dist/src/config/paths.js +5 -1
- package/dist/src/config/schema.d.ts +17 -0
- package/dist/src/config/schema.js +26 -2
- package/dist/src/connectors/auth-provider-registry.d.ts +1 -1
- package/dist/src/connectors/auth-provider-registry.js +23 -2
- package/dist/src/connectors/connected-source-understanding.js +1 -1
- package/dist/src/connectors/install.js +3 -3
- package/dist/src/connectors/instances.d.ts +2 -1
- package/dist/src/connectors/instances.js +15 -5
- package/dist/src/connectors/materialize.d.ts +1 -0
- package/dist/src/connectors/materialize.js +9 -1
- package/dist/src/connectors/runtime-adapter-registry.js +1 -0
- package/dist/src/connectors/types.d.ts +4 -1
- package/dist/src/extensions/connector-dependencies.d.ts +10 -0
- package/dist/src/extensions/connector-dependencies.js +65 -0
- package/dist/src/extensions/install.js +27 -0
- package/dist/src/extensions/normalize-manifest.js +1 -0
- package/dist/src/extensions/sdk/index.js +1 -1
- package/dist/src/extensions/types/manifest.d.ts +2 -0
- package/dist/src/gateway/hono/routes/capabilities.js +8 -8
- package/dist/src/gateway/hono/routes/connectors.js +104 -70
- package/dist/src/gateway/hono/routes/mcp.js +77 -5
- package/dist/src/gateway/hono/routes/project-skills.js +30 -2
- package/dist/src/gateway/hono/routes/you.js +52 -0
- package/dist/src/gateway/service.js +8 -8
- package/dist/src/knowledge/connected-knowledge-pipeline.js +26 -4
- package/dist/src/knowledge/connected-understanding-pipeline.js +12 -3
- package/dist/src/knowledge/index.d.ts +0 -1
- package/dist/src/knowledge/index.js +1 -2
- package/dist/src/projects/project-skill-service.d.ts +28 -6
- package/dist/src/projects/project-skill-service.js +76 -29
- package/dist/src/session/store.js +27 -0
- package/dist/src/storage/sqlite/index.d.ts +1 -0
- package/dist/src/storage/sqlite/index.js +2 -1
- package/dist/src/storage/sqlite/memory-records-repository.d.ts +9 -1
- package/dist/src/storage/sqlite/memory-records-repository.js +40 -6
- package/dist/src/storage/sqlite/migrations/134_memory_provenance.sql +18 -0
- package/dist/src/storage/sqlite/migrations/135_user_people.sql +59 -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/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/user-people-repository.d.ts +32 -0
- package/dist/src/storage/sqlite/user-people-repository.js +246 -0
- package/dist/src/tui/backends/embedded-backend.js +1 -1
- package/dist/src/user-context/planner.js +8 -3
- package/dist/src/user-context/relationships/indexer.d.ts +13 -0
- package/dist/src/user-context/relationships/indexer.js +185 -0
- package/dist/src/user-context/relationships/service.d.ts +22 -0
- package/dist/src/user-context/relationships/service.js +50 -0
- package/dist/src/user-context/relationships/types.d.ts +55 -0
- package/dist/src/user-context/relationships/types.js +10 -0
- package/dist/src/user-context/sources/repository.d.ts +1 -1
- package/dist/src/user-context/sources/repository.js +8 -2
- package/dist/src/work-discovery/service.js +1 -1
- package/package.json +2 -2
- package/dist/gateway/static/root/assets/agents-BsxTpXyq.js +0 -68
- package/dist/gateway/static/root/assets/apps-page-BXgpBA8w.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-wrgf-z7D.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-zhzNkeVG.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-DuCmg2Ej.js +0 -7
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-DjiP3mQQ.js +0 -3
- package/dist/gateway/static/root/assets/channels-status-swr-DMxB7slL.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-fmda2NEP.js +0 -2
- package/dist/gateway/static/root/assets/heartbeat-settings-MUJ3mEC9.js +0 -1
- package/dist/gateway/static/root/assets/index-B3zYJBhK.js +0 -74
- package/dist/gateway/static/root/assets/index-D3_xSYKd.css +0 -2
- package/dist/gateway/static/root/assets/messages-B82nsi9k.js +0 -3
- package/dist/gateway/static/root/assets/notes-workbench-BScELo01.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-DUoyty8X.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-sHho-uXP.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-DyvNgaP9.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CnYf1R7z.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-BQBVq-sN.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BFoEpQ4I.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-ZVwr8KbS.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-CHjIinCW.js +0 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-9_dAGW3_.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-DXpYJxao.js +0 -5
- package/dist/src/extensions/bundle-mcp.d.ts +0 -18
- package/dist/src/extensions/bundle-mcp.js +0 -69
- package/dist/src/knowledge/people-graph.d.ts +0 -25
- package/dist/src/knowledge/people-graph.js +0 -92
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { McpOAuthSessionSnapshot } from './mcp-oauth-types.js';
|
|
2
|
+
export declare class McpOAuthSession {
|
|
3
|
+
readonly serverId: string;
|
|
4
|
+
readonly serverUrl: URL;
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly state: string;
|
|
7
|
+
readonly createdAt: number;
|
|
8
|
+
readonly expiresAt: number;
|
|
9
|
+
private statusValue;
|
|
10
|
+
private authorizationUrlValue?;
|
|
11
|
+
private errorValue?;
|
|
12
|
+
private callbackServer?;
|
|
13
|
+
private redirectUrlValue?;
|
|
14
|
+
private settleCode?;
|
|
15
|
+
private callbackConsumed;
|
|
16
|
+
private readonly codePromise;
|
|
17
|
+
private timeout?;
|
|
18
|
+
constructor(serverId: string, serverUrl: URL, ttlMs?: number);
|
|
19
|
+
get redirectUrl(): URL;
|
|
20
|
+
start(): Promise<void>;
|
|
21
|
+
setAuthorizationUrl(url: URL): void;
|
|
22
|
+
waitForCode(): Promise<string>;
|
|
23
|
+
complete(): void;
|
|
24
|
+
fail(error: unknown): void;
|
|
25
|
+
cancel(): void;
|
|
26
|
+
snapshot(): McpOAuthSessionSnapshot;
|
|
27
|
+
close(): Promise<void>;
|
|
28
|
+
private closeServer;
|
|
29
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { randomBytes, randomUUID } from "node:crypto";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
//#region src/agent/mcp/oauth/mcp-oauth-session.ts
|
|
4
|
+
const CALLBACK_PATH = "/oauth/callback";
|
|
5
|
+
const DEFAULT_SESSION_TTL_MS = 600 * 1e3;
|
|
6
|
+
function callbackPage(title, message) {
|
|
7
|
+
return `<!doctype html><html><head><meta charset="utf-8"><title>${title}</title></head><body><h1>${title}</h1><p>${message}</p></body></html>`;
|
|
8
|
+
}
|
|
9
|
+
var McpOAuthSession = class {
|
|
10
|
+
id = `mcp_oauth_${randomUUID()}`;
|
|
11
|
+
state = randomBytes(24).toString("base64url");
|
|
12
|
+
createdAt = Date.now();
|
|
13
|
+
expiresAt;
|
|
14
|
+
statusValue = "starting";
|
|
15
|
+
authorizationUrlValue;
|
|
16
|
+
errorValue;
|
|
17
|
+
callbackServer;
|
|
18
|
+
redirectUrlValue;
|
|
19
|
+
settleCode;
|
|
20
|
+
callbackConsumed = false;
|
|
21
|
+
codePromise;
|
|
22
|
+
timeout;
|
|
23
|
+
constructor(serverId, serverUrl, ttlMs = DEFAULT_SESSION_TTL_MS) {
|
|
24
|
+
this.serverId = serverId;
|
|
25
|
+
this.serverUrl = serverUrl;
|
|
26
|
+
this.expiresAt = this.createdAt + ttlMs;
|
|
27
|
+
this.codePromise = new Promise((resolve) => {
|
|
28
|
+
this.settleCode = resolve;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
get redirectUrl() {
|
|
32
|
+
if (!this.redirectUrlValue) throw new Error("MCP OAuth callback server has not started");
|
|
33
|
+
return this.redirectUrlValue;
|
|
34
|
+
}
|
|
35
|
+
async start() {
|
|
36
|
+
if (this.callbackServer) return;
|
|
37
|
+
const server = createServer((request, response) => {
|
|
38
|
+
response.setHeader("content-type", "text/html; charset=utf-8");
|
|
39
|
+
response.setHeader("cache-control", "no-store");
|
|
40
|
+
response.setHeader("referrer-policy", "no-referrer");
|
|
41
|
+
response.setHeader("x-content-type-options", "nosniff");
|
|
42
|
+
try {
|
|
43
|
+
const callback = new URL(request.url ?? "", "http://127.0.0.1");
|
|
44
|
+
if (callback.pathname !== CALLBACK_PATH) {
|
|
45
|
+
response.statusCode = 404;
|
|
46
|
+
response.end(callbackPage("Not found", "This is not an XOPC OAuth callback."));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (callback.searchParams.get("state") !== this.state) {
|
|
50
|
+
response.statusCode = 400;
|
|
51
|
+
response.end(callbackPage("Authorization failed", "MCP OAuth state mismatch"));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (this.callbackConsumed) {
|
|
55
|
+
response.statusCode = 409;
|
|
56
|
+
response.end(callbackPage("Authorization already handled", "Return to XOPC to continue."));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const oauthError = callback.searchParams.get("error");
|
|
60
|
+
const code = callback.searchParams.get("code");
|
|
61
|
+
if (oauthError || !code) {
|
|
62
|
+
const error = /* @__PURE__ */ new Error(oauthError === "access_denied" ? "Authorization was denied" : "Authorization code is missing");
|
|
63
|
+
response.statusCode = 400;
|
|
64
|
+
response.end(callbackPage("Authorization failed", error.message));
|
|
65
|
+
this.fail(error);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
this.callbackConsumed = true;
|
|
69
|
+
this.statusValue = "exchanging_code";
|
|
70
|
+
response.statusCode = 200;
|
|
71
|
+
response.end(callbackPage("Authorization complete", "Return to XOPC to finish connecting the MCP server."));
|
|
72
|
+
this.settleCode?.({ code });
|
|
73
|
+
this.settleCode = void 0;
|
|
74
|
+
} catch {
|
|
75
|
+
const error = /* @__PURE__ */ new Error("MCP OAuth callback could not be processed");
|
|
76
|
+
response.statusCode = 500;
|
|
77
|
+
response.end(callbackPage("Authorization failed", error.message));
|
|
78
|
+
this.fail(error);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
this.callbackServer = server;
|
|
82
|
+
try {
|
|
83
|
+
this.redirectUrlValue = await new Promise((resolve, reject) => {
|
|
84
|
+
server.once("error", reject);
|
|
85
|
+
server.listen(0, "127.0.0.1", () => {
|
|
86
|
+
server.removeListener("error", reject);
|
|
87
|
+
const address = server.address();
|
|
88
|
+
if (!address || typeof address === "string") {
|
|
89
|
+
reject(/* @__PURE__ */ new Error("MCP OAuth callback server did not expose a TCP port"));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
resolve(new URL(`http://127.0.0.1:${address.port}${CALLBACK_PATH}`));
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
} catch (error) {
|
|
96
|
+
this.callbackServer = void 0;
|
|
97
|
+
server.close();
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
this.timeout = setTimeout(() => {
|
|
101
|
+
this.statusValue = "expired";
|
|
102
|
+
this.errorValue = "MCP OAuth session expired";
|
|
103
|
+
this.settleCode?.({ error: new Error(this.errorValue) });
|
|
104
|
+
this.settleCode = void 0;
|
|
105
|
+
this.closeServer();
|
|
106
|
+
}, Math.max(1, this.expiresAt - Date.now()));
|
|
107
|
+
this.timeout.unref?.();
|
|
108
|
+
}
|
|
109
|
+
setAuthorizationUrl(url) {
|
|
110
|
+
this.authorizationUrlValue = url.toString();
|
|
111
|
+
this.statusValue = "waiting_browser";
|
|
112
|
+
}
|
|
113
|
+
async waitForCode() {
|
|
114
|
+
const result = await this.codePromise;
|
|
115
|
+
if (result.error) throw result.error;
|
|
116
|
+
if (!result.code) throw new Error("MCP OAuth authorization code is unavailable");
|
|
117
|
+
return result.code;
|
|
118
|
+
}
|
|
119
|
+
complete() {
|
|
120
|
+
this.statusValue = "connected";
|
|
121
|
+
this.errorValue = void 0;
|
|
122
|
+
this.closeServer();
|
|
123
|
+
}
|
|
124
|
+
fail(error) {
|
|
125
|
+
this.statusValue = "failed";
|
|
126
|
+
this.errorValue = error instanceof Error ? error.message : String(error);
|
|
127
|
+
this.settleCode?.({ error: error instanceof Error ? error : new Error(String(error)) });
|
|
128
|
+
this.settleCode = void 0;
|
|
129
|
+
this.closeServer();
|
|
130
|
+
}
|
|
131
|
+
cancel() {
|
|
132
|
+
if ([
|
|
133
|
+
"connected",
|
|
134
|
+
"failed",
|
|
135
|
+
"expired",
|
|
136
|
+
"cancelled"
|
|
137
|
+
].includes(this.statusValue)) return;
|
|
138
|
+
this.statusValue = "cancelled";
|
|
139
|
+
this.settleCode?.({ error: /* @__PURE__ */ new Error("MCP OAuth session cancelled") });
|
|
140
|
+
this.settleCode = void 0;
|
|
141
|
+
this.closeServer();
|
|
142
|
+
}
|
|
143
|
+
snapshot() {
|
|
144
|
+
return {
|
|
145
|
+
id: this.id,
|
|
146
|
+
serverId: this.serverId,
|
|
147
|
+
serverUrl: this.serverUrl.toString(),
|
|
148
|
+
status: this.statusValue,
|
|
149
|
+
authorizationUrl: this.authorizationUrlValue,
|
|
150
|
+
error: this.errorValue,
|
|
151
|
+
createdAt: this.createdAt,
|
|
152
|
+
expiresAt: this.expiresAt
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
async close() {
|
|
156
|
+
this.cancel();
|
|
157
|
+
await this.closeServer();
|
|
158
|
+
}
|
|
159
|
+
async closeServer() {
|
|
160
|
+
if (this.timeout) clearTimeout(this.timeout);
|
|
161
|
+
this.timeout = void 0;
|
|
162
|
+
const server = this.callbackServer;
|
|
163
|
+
this.callbackServer = void 0;
|
|
164
|
+
if (!server) return;
|
|
165
|
+
await new Promise((resolve) => server.close(() => resolve()));
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
//#endregion
|
|
169
|
+
export { McpOAuthSession };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { McpOAuthRecord } from './mcp-oauth-types.js';
|
|
2
|
+
export declare function canonicalMcpServerUrl(input: string | URL): string;
|
|
3
|
+
export declare function mcpOAuthServerKey(input: string | URL): string;
|
|
4
|
+
export declare class McpOAuthStore {
|
|
5
|
+
pathFor(serverUrl: string | URL): string;
|
|
6
|
+
load(serverUrlInput: string | URL): Promise<McpOAuthRecord | undefined>;
|
|
7
|
+
update(serverUrlInput: string | URL, update: (current: McpOAuthRecord | undefined) => McpOAuthRecord | undefined): Promise<McpOAuthRecord | undefined>;
|
|
8
|
+
delete(serverUrl: string | URL): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { init_paths, resolveMcpOAuthPath } from "../../../config/paths.js";
|
|
2
|
+
import { init_write_file_atomic, writeTextAtomic } from "../../../infra/write-file-atomic.js";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { readFile, rm } from "node:fs/promises";
|
|
5
|
+
//#region src/agent/mcp/oauth/mcp-oauth-store.ts
|
|
6
|
+
init_paths();
|
|
7
|
+
init_write_file_atomic();
|
|
8
|
+
const writeTails = /* @__PURE__ */ new Map();
|
|
9
|
+
function canonicalMcpServerUrl(input) {
|
|
10
|
+
const url = input instanceof URL ? new URL(input) : new URL(input);
|
|
11
|
+
url.hash = "";
|
|
12
|
+
return url.toString();
|
|
13
|
+
}
|
|
14
|
+
function mcpOAuthServerKey(input) {
|
|
15
|
+
return createHash("sha256").update(canonicalMcpServerUrl(input)).digest("hex");
|
|
16
|
+
}
|
|
17
|
+
function isStoredRecord(value, serverUrl) {
|
|
18
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
19
|
+
const record = value;
|
|
20
|
+
if (record.version !== 1 || record.serverUrl !== serverUrl || typeof record.updatedAt !== "string") return false;
|
|
21
|
+
if (record.tokens !== void 0) {
|
|
22
|
+
const tokens = record.tokens;
|
|
23
|
+
if (typeof tokens.access_token !== "string" || typeof tokens.token_type !== "string") return false;
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
async function serializeWrite(key, operation) {
|
|
28
|
+
const previous = writeTails.get(key) ?? Promise.resolve();
|
|
29
|
+
let release;
|
|
30
|
+
const gate = new Promise((resolve) => {
|
|
31
|
+
release = resolve;
|
|
32
|
+
});
|
|
33
|
+
const tail = previous.catch(() => void 0).then(() => gate);
|
|
34
|
+
writeTails.set(key, tail);
|
|
35
|
+
await previous.catch(() => void 0);
|
|
36
|
+
try {
|
|
37
|
+
return await operation();
|
|
38
|
+
} finally {
|
|
39
|
+
release();
|
|
40
|
+
if (writeTails.get(key) === tail) writeTails.delete(key);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
var McpOAuthStore = class {
|
|
44
|
+
pathFor(serverUrl) {
|
|
45
|
+
return resolveMcpOAuthPath(mcpOAuthServerKey(serverUrl));
|
|
46
|
+
}
|
|
47
|
+
async load(serverUrlInput) {
|
|
48
|
+
const serverUrl = canonicalMcpServerUrl(serverUrlInput);
|
|
49
|
+
try {
|
|
50
|
+
const parsed = JSON.parse(await readFile(this.pathFor(serverUrl), "utf8"));
|
|
51
|
+
return isStoredRecord(parsed, serverUrl) ? parsed : void 0;
|
|
52
|
+
} catch {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async update(serverUrlInput, update) {
|
|
57
|
+
const serverUrl = canonicalMcpServerUrl(serverUrlInput);
|
|
58
|
+
return serializeWrite(mcpOAuthServerKey(serverUrl), async () => {
|
|
59
|
+
const next = update(await this.load(serverUrl));
|
|
60
|
+
if (!next) {
|
|
61
|
+
await rm(this.pathFor(serverUrl), { force: true });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const normalized = {
|
|
65
|
+
...next,
|
|
66
|
+
version: 1,
|
|
67
|
+
serverUrl,
|
|
68
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
69
|
+
};
|
|
70
|
+
await writeTextAtomic(this.pathFor(serverUrl), JSON.stringify(normalized, null, 2));
|
|
71
|
+
return normalized;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async delete(serverUrl) {
|
|
75
|
+
await this.update(serverUrl, () => void 0);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
//#endregion
|
|
79
|
+
export { McpOAuthStore, canonicalMcpServerUrl, mcpOAuthServerKey };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { OAuthDiscoveryState } from '@modelcontextprotocol/sdk/client/auth.js';
|
|
2
|
+
import type { OAuthClientInformationMixed, OAuthTokens } from '@modelcontextprotocol/sdk/shared/auth.js';
|
|
3
|
+
export type McpOAuthRecord = {
|
|
4
|
+
version: 1;
|
|
5
|
+
serverUrl: string;
|
|
6
|
+
clientInformation?: OAuthClientInformationMixed;
|
|
7
|
+
discoveryState?: OAuthDiscoveryState;
|
|
8
|
+
tokens?: OAuthTokens;
|
|
9
|
+
tokensSavedAt?: number;
|
|
10
|
+
updatedAt: string;
|
|
11
|
+
};
|
|
12
|
+
export type McpOAuthSessionStatus = 'starting' | 'waiting_browser' | 'exchanging_code' | 'connected' | 'failed' | 'expired' | 'cancelled';
|
|
13
|
+
export type McpOAuthSessionSnapshot = {
|
|
14
|
+
id: string;
|
|
15
|
+
serverId: string;
|
|
16
|
+
serverUrl: string;
|
|
17
|
+
status: McpOAuthSessionStatus;
|
|
18
|
+
authorizationUrl?: string;
|
|
19
|
+
error?: string;
|
|
20
|
+
createdAt: number;
|
|
21
|
+
expiresAt: number;
|
|
22
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { init_agent_session_key, normalizeAgentId } from "../../routing/agent-session-key.js";
|
|
2
2
|
import { appendMemorySignal, deleteMemoryRecord, getMemoryRecord, listMemoryRecords, searchMemoryRecords, upsertMemoryRecord } from "../../storage/sqlite/memory-records-repository.js";
|
|
3
3
|
import "../../storage/sqlite/index.js";
|
|
4
|
+
import { resolveMemorySessionKind } from "./turn-provenance.js";
|
|
4
5
|
//#region src/agent/memory/builtin-provider.ts
|
|
5
6
|
init_agent_session_key();
|
|
6
7
|
/**
|
|
@@ -44,7 +45,8 @@ var BuiltinMemoryProvider = class {
|
|
|
44
45
|
unscopedWorkspaceOnly: request.scope?.workspaceId == null,
|
|
45
46
|
kinds: request.kinds,
|
|
46
47
|
maxResults: request.maxResults,
|
|
47
|
-
minScore: request.minScore
|
|
48
|
+
minScore: request.minScore,
|
|
49
|
+
trustedOnly: request.trustedOnly
|
|
48
50
|
};
|
|
49
51
|
const [active, shadow] = [searchMemoryRecords(options), searchMemoryRecords({
|
|
50
52
|
...options,
|
|
@@ -90,10 +92,13 @@ var BuiltinMemoryProvider = class {
|
|
|
90
92
|
});
|
|
91
93
|
}
|
|
92
94
|
async write(request) {
|
|
95
|
+
const sourceAgentId = normalizeAgentId(request.sourceAgentId ?? "main");
|
|
96
|
+
const sourceSessionId = request.provenance?.sourceSessionId ?? request.scope?.sessionKey;
|
|
97
|
+
const originClass = request.confirmed ? "owner" : request.provenance?.originClass ?? "agent";
|
|
93
98
|
const record = upsertMemoryRecord({
|
|
94
99
|
providerId: this.id,
|
|
95
100
|
kind: request.kind,
|
|
96
|
-
sourceAgentId
|
|
101
|
+
sourceAgentId,
|
|
97
102
|
workspaceId: request.scope?.workspaceId,
|
|
98
103
|
sessionKey: request.scope?.sessionKey,
|
|
99
104
|
projectId: request.scope?.projectId,
|
|
@@ -117,7 +122,14 @@ var BuiltinMemoryProvider = class {
|
|
|
117
122
|
reviewAfter: request.reviewAfter,
|
|
118
123
|
expiresAt: request.expiresAt,
|
|
119
124
|
supersedesRecordId: request.supersedesRecordId,
|
|
120
|
-
conflictGroupId: request.conflictGroupId
|
|
125
|
+
conflictGroupId: request.conflictGroupId,
|
|
126
|
+
originClass,
|
|
127
|
+
sessionKind: request.provenance?.sessionKind ?? (sourceSessionId ? resolveMemorySessionKind(sourceSessionId) : "unknown"),
|
|
128
|
+
observedAt: request.provenance?.observedAt,
|
|
129
|
+
sourceSessionId,
|
|
130
|
+
sourceTurnId: request.provenance?.sourceTurnId,
|
|
131
|
+
supersedesKey: request.provenance?.supersedesKey,
|
|
132
|
+
derivedFromRecalledContext: request.confirmed ? false : request.provenance?.derivedFromRecalledContext
|
|
121
133
|
});
|
|
122
134
|
return {
|
|
123
135
|
success: true,
|
|
@@ -164,7 +176,14 @@ var BuiltinMemoryProvider = class {
|
|
|
164
176
|
reviewAfter: existing.reviewAfter,
|
|
165
177
|
expiresAt: existing.expiresAt,
|
|
166
178
|
supersedesRecordId: existing.supersedesRecordId,
|
|
167
|
-
conflictGroupId: existing.conflictGroupId
|
|
179
|
+
conflictGroupId: existing.conflictGroupId,
|
|
180
|
+
originClass: existing.provenance.originClass,
|
|
181
|
+
sessionKind: existing.provenance.sessionKind,
|
|
182
|
+
observedAt: existing.provenance.observedAt,
|
|
183
|
+
sourceSessionId: existing.provenance.sourceSessionId,
|
|
184
|
+
sourceTurnId: existing.provenance.sourceTurnId,
|
|
185
|
+
supersedesKey: existing.provenance.supersedesKey,
|
|
186
|
+
derivedFromRecalledContext: existing.provenance.derivedFromRecalledContext
|
|
168
187
|
})
|
|
169
188
|
};
|
|
170
189
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CompactionAudit, CompactionHandover } from '../../session/compaction-types.js';
|
|
2
|
+
import type { TranscriptSourceEntry } from '../../storage/sqlite/transcript-repository.js';
|
|
3
|
+
export interface PromoteCompactionLedgerInput {
|
|
4
|
+
sessionKey: string;
|
|
5
|
+
sessionId: string;
|
|
6
|
+
sourceAgentId: string;
|
|
7
|
+
workspaceId: string;
|
|
8
|
+
projectId?: string;
|
|
9
|
+
handover: CompactionHandover;
|
|
10
|
+
audit: CompactionAudit;
|
|
11
|
+
sourceEntries: readonly TranscriptSourceEntry[];
|
|
12
|
+
}
|
|
13
|
+
export interface PromoteCompactionLedgerResult {
|
|
14
|
+
episodicRecordIds: string[];
|
|
15
|
+
durableRecordIds: string[];
|
|
16
|
+
rejectedRecordIds: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare function promoteCompactionLedger(input: PromoteCompactionLedgerInput): PromoteCompactionLedgerResult;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { getMemoryRecord, setMemoryRecordStatus, upsertMemoryRecord } from "../../storage/sqlite/memory-records-repository.js";
|
|
2
|
+
import { resolveMemorySessionKind } from "./turn-provenance.js";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
//#region src/agent/memory/compaction-promotion.ts
|
|
5
|
+
const DURABLE_KINDS = new Set([
|
|
6
|
+
"objective",
|
|
7
|
+
"decision",
|
|
8
|
+
"pending_user_ask",
|
|
9
|
+
"todo",
|
|
10
|
+
"constraint",
|
|
11
|
+
"next_action"
|
|
12
|
+
]);
|
|
13
|
+
const RECALL_TOOL_RE = /^(?:memory_(?:search|get)|session_(?:search|recall))$/;
|
|
14
|
+
const MEMORY_KIND_BY_HANDOVER_KIND = {
|
|
15
|
+
objective: "long_term_goal",
|
|
16
|
+
decision: "derived_insight",
|
|
17
|
+
pending_user_ask: "open_question",
|
|
18
|
+
todo: "commitment",
|
|
19
|
+
constraint: "project_context",
|
|
20
|
+
file_change: "workspace_fact",
|
|
21
|
+
tool_outcome: "task_lesson",
|
|
22
|
+
failure: "task_lesson",
|
|
23
|
+
current_state: "current_state",
|
|
24
|
+
next_action: "commitment"
|
|
25
|
+
};
|
|
26
|
+
function stableId(prefix, ...parts) {
|
|
27
|
+
return `${prefix}:${createHash("sha256").update(parts.join("\0")).digest("hex").slice(0, 32)}`;
|
|
28
|
+
}
|
|
29
|
+
function rowRole(entry) {
|
|
30
|
+
const row = entry.row;
|
|
31
|
+
return typeof row.role === "string" ? row.role : void 0;
|
|
32
|
+
}
|
|
33
|
+
function rowTurnId(entry) {
|
|
34
|
+
if (!entry) return void 0;
|
|
35
|
+
const row = entry.row;
|
|
36
|
+
return typeof row.turnId === "string" && row.turnId.trim() ? row.turnId : void 0;
|
|
37
|
+
}
|
|
38
|
+
function toolNames(entry) {
|
|
39
|
+
const row = entry.row;
|
|
40
|
+
const names = [];
|
|
41
|
+
if (typeof row.toolName === "string") names.push(row.toolName);
|
|
42
|
+
if (row.role === "assistant" && Array.isArray(row.content)) for (const block of row.content) {
|
|
43
|
+
if (!block || typeof block !== "object") continue;
|
|
44
|
+
const candidate = block;
|
|
45
|
+
if (candidate.type === "toolCall" && typeof candidate.name === "string") names.push(candidate.name);
|
|
46
|
+
}
|
|
47
|
+
return names;
|
|
48
|
+
}
|
|
49
|
+
function hasAttachedSourceContext(entry) {
|
|
50
|
+
const row = entry.row;
|
|
51
|
+
if (!row.metadata || typeof row.metadata !== "object" || Array.isArray(row.metadata)) return false;
|
|
52
|
+
return Array.isArray(row.metadata.sourceContexts) && row.metadata.sourceContexts.length > 0;
|
|
53
|
+
}
|
|
54
|
+
function classifyItemProvenance(item, sourceById, entriesByTurn, entriesByRound) {
|
|
55
|
+
const directSources = item.sources.flatMap((source) => {
|
|
56
|
+
const entry = sourceById.get(source.entryId);
|
|
57
|
+
return entry ? [entry] : [];
|
|
58
|
+
});
|
|
59
|
+
const expandedSources = /* @__PURE__ */ new Map();
|
|
60
|
+
for (const entry of directSources) {
|
|
61
|
+
expandedSources.set(entry.entryId, entry);
|
|
62
|
+
const turnId = rowTurnId(entry);
|
|
63
|
+
for (const peer of turnId ? entriesByTurn.get(turnId) ?? [] : []) expandedSources.set(peer.entryId, peer);
|
|
64
|
+
for (const peer of entriesByRound.get(entry.entryId) ?? []) expandedSources.set(peer.entryId, peer);
|
|
65
|
+
}
|
|
66
|
+
const sources = [...expandedSources.values()];
|
|
67
|
+
const names = sources.flatMap(toolNames);
|
|
68
|
+
const tainted = directSources.length !== item.sources.length || sources.some((entry) => {
|
|
69
|
+
const role = rowRole(entry);
|
|
70
|
+
return role === "tool" || role === "toolResult" || role === "system" || !role || hasAttachedSourceContext(entry);
|
|
71
|
+
});
|
|
72
|
+
const observedAtMs = Math.max(0, ...directSources.map((entry) => entry.createdAt));
|
|
73
|
+
return {
|
|
74
|
+
originClass: tainted ? "untrusted" : "agent",
|
|
75
|
+
derivedFromRecalledContext: names.some((name) => RECALL_TOOL_RE.test(name)),
|
|
76
|
+
observedAt: new Date(observedAtMs || Date.now()).toISOString()
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function importanceFor(item) {
|
|
80
|
+
if (item.kind === "constraint" || item.kind === "decision") return .82;
|
|
81
|
+
if (item.kind === "objective" || item.kind === "pending_user_ask") return .75;
|
|
82
|
+
if (item.kind === "todo" || item.kind === "next_action") return .68;
|
|
83
|
+
return .5;
|
|
84
|
+
}
|
|
85
|
+
function promoteCompactionLedger(input) {
|
|
86
|
+
const sourceById = new Map(input.sourceEntries.map((entry) => [entry.entryId, entry]));
|
|
87
|
+
const entriesByTurn = /* @__PURE__ */ new Map();
|
|
88
|
+
const entriesByRound = /* @__PURE__ */ new Map();
|
|
89
|
+
let currentRound = [];
|
|
90
|
+
const flushRound = () => {
|
|
91
|
+
for (const entry of currentRound) entriesByRound.set(entry.entryId, currentRound);
|
|
92
|
+
};
|
|
93
|
+
for (const entry of input.sourceEntries) {
|
|
94
|
+
const role = rowRole(entry);
|
|
95
|
+
if (role === "user") {
|
|
96
|
+
flushRound();
|
|
97
|
+
currentRound = [];
|
|
98
|
+
}
|
|
99
|
+
if (role === "user" || role === "assistant" || role === "tool" || role === "toolResult") currentRound.push(entry);
|
|
100
|
+
const turnId = rowTurnId(entry);
|
|
101
|
+
if (!turnId) continue;
|
|
102
|
+
const entries = entriesByTurn.get(turnId) ?? [];
|
|
103
|
+
entries.push(entry);
|
|
104
|
+
entriesByTurn.set(turnId, entries);
|
|
105
|
+
}
|
|
106
|
+
flushRound();
|
|
107
|
+
const result = {
|
|
108
|
+
episodicRecordIds: [],
|
|
109
|
+
durableRecordIds: [],
|
|
110
|
+
rejectedRecordIds: []
|
|
111
|
+
};
|
|
112
|
+
const sessionKind = resolveMemorySessionKind(input.sessionKey);
|
|
113
|
+
for (const item of input.handover.items) {
|
|
114
|
+
const episodeId = stableId("compaction-episode", input.sessionId, item.id);
|
|
115
|
+
const classified = classifyItemProvenance(item, sourceById, entriesByTurn, entriesByRound);
|
|
116
|
+
const originClass = sessionKind === "automation" || sessionKind === "workflow" || sessionKind === "background" ? "system" : sessionKind === "group" ? "untrusted" : classified.originClass;
|
|
117
|
+
const active = item.status === "active";
|
|
118
|
+
upsertMemoryRecord({
|
|
119
|
+
id: episodeId,
|
|
120
|
+
providerId: "compaction-ledger",
|
|
121
|
+
kind: MEMORY_KIND_BY_HANDOVER_KIND[item.kind],
|
|
122
|
+
sourceAgentId: input.sourceAgentId,
|
|
123
|
+
workspaceId: input.workspaceId,
|
|
124
|
+
sessionKey: input.sessionKey,
|
|
125
|
+
projectId: input.projectId,
|
|
126
|
+
content: item.text,
|
|
127
|
+
canonicalKey: `compaction:${input.sessionId}:${item.id}`,
|
|
128
|
+
source: {
|
|
129
|
+
provider: "compaction-ledger",
|
|
130
|
+
sessionEntryId: item.sources[0]?.entryId
|
|
131
|
+
},
|
|
132
|
+
confidence: input.audit.status === "passed" ? .82 : .65,
|
|
133
|
+
tags: [
|
|
134
|
+
"compaction",
|
|
135
|
+
"episodic",
|
|
136
|
+
item.kind,
|
|
137
|
+
item.status
|
|
138
|
+
],
|
|
139
|
+
status: active ? "candidate" : "archived",
|
|
140
|
+
sensitivity: "normal",
|
|
141
|
+
explicitness: "inferred",
|
|
142
|
+
durability: "ephemeral",
|
|
143
|
+
importance: importanceFor(item),
|
|
144
|
+
disclosurePolicy: "referenceable",
|
|
145
|
+
evidence: item.sources.map((source) => ({
|
|
146
|
+
sessionKey: input.sessionKey,
|
|
147
|
+
turnId: rowTurnId(sourceById.get(source.entryId)),
|
|
148
|
+
relation: "derived_from",
|
|
149
|
+
sourceText: `[transcript:${source.seq}] ${item.text}`,
|
|
150
|
+
observedAt: classified.observedAt
|
|
151
|
+
})),
|
|
152
|
+
originClass,
|
|
153
|
+
sessionKind,
|
|
154
|
+
observedAt: classified.observedAt,
|
|
155
|
+
sourceSessionId: input.sessionKey,
|
|
156
|
+
supersedesKey: item.id,
|
|
157
|
+
derivedFromRecalledContext: classified.derivedFromRecalledContext
|
|
158
|
+
});
|
|
159
|
+
result.episodicRecordIds.push(episodeId);
|
|
160
|
+
const durableId = stableId("compaction-durable", input.workspaceId, input.projectId ?? "", item.kind, item.text);
|
|
161
|
+
if (!(active && input.audit.status === "passed" && sessionKind === "interactive" && originClass === "agent" && !classified.derivedFromRecalledContext && DURABLE_KINDS.has(item.kind))) {
|
|
162
|
+
if ((!active ? getMemoryRecord(durableId) : null)?.provenance.sourceSessionId === input.sessionKey) setMemoryRecordStatus(durableId, "archived");
|
|
163
|
+
result.rejectedRecordIds.push(episodeId);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
upsertMemoryRecord({
|
|
167
|
+
id: durableId,
|
|
168
|
+
providerId: "compaction-ledger",
|
|
169
|
+
kind: MEMORY_KIND_BY_HANDOVER_KIND[item.kind],
|
|
170
|
+
sourceAgentId: input.sourceAgentId,
|
|
171
|
+
workspaceId: input.workspaceId,
|
|
172
|
+
projectId: input.projectId,
|
|
173
|
+
content: item.text,
|
|
174
|
+
canonicalKey: `durable:${item.kind}:${stableId("fact", item.text)}`,
|
|
175
|
+
source: {
|
|
176
|
+
provider: "compaction-ledger",
|
|
177
|
+
sessionEntryId: item.sources[0]?.entryId
|
|
178
|
+
},
|
|
179
|
+
confidence: .82,
|
|
180
|
+
tags: [
|
|
181
|
+
"compaction",
|
|
182
|
+
"durable",
|
|
183
|
+
item.kind
|
|
184
|
+
],
|
|
185
|
+
status: "active",
|
|
186
|
+
sensitivity: "normal",
|
|
187
|
+
explicitness: "inferred",
|
|
188
|
+
durability: "durable",
|
|
189
|
+
importance: importanceFor(item),
|
|
190
|
+
disclosurePolicy: "referenceable",
|
|
191
|
+
evidence: [{
|
|
192
|
+
sessionKey: input.sessionKey,
|
|
193
|
+
turnId: item.sources[0] ? rowTurnId(sourceById.get(item.sources[0].entryId)) : void 0,
|
|
194
|
+
relation: "derived_from",
|
|
195
|
+
sourceText: item.text,
|
|
196
|
+
observedAt: classified.observedAt
|
|
197
|
+
}],
|
|
198
|
+
supersedesRecordId: episodeId,
|
|
199
|
+
originClass: "agent",
|
|
200
|
+
sessionKind,
|
|
201
|
+
observedAt: classified.observedAt,
|
|
202
|
+
sourceSessionId: input.sessionKey,
|
|
203
|
+
supersedesKey: item.id,
|
|
204
|
+
derivedFromRecalledContext: false
|
|
205
|
+
});
|
|
206
|
+
result.durableRecordIds.push(durableId);
|
|
207
|
+
}
|
|
208
|
+
return result;
|
|
209
|
+
}
|
|
210
|
+
//#endregion
|
|
211
|
+
export { promoteCompactionLedger };
|
|
@@ -26,6 +26,11 @@ export interface UserContextPlan {
|
|
|
26
26
|
purpose: string;
|
|
27
27
|
}>;
|
|
28
28
|
estimatedTokens: number;
|
|
29
|
+
/** Exact rendered context characters prepended before the user's message. */
|
|
30
|
+
contextChars: number;
|
|
31
|
+
contextItemCount: number;
|
|
32
|
+
/** Generic durable memory records selected by the trusted automatic recall lane. */
|
|
33
|
+
memoryRecordIds?: string[];
|
|
29
34
|
allocation?: {
|
|
30
35
|
profile: 'standard' | 'deep' | 'critical';
|
|
31
36
|
maxResults: number;
|
|
@@ -3,6 +3,7 @@ import type { MemoryRuntime } from '../../agent-runtime/memory-runtime.js';
|
|
|
3
3
|
import type { MemoryProvider, MemoryProviderInitOptions } from './provider.js';
|
|
4
4
|
import type { UnderstandingCandidate } from './understanding/types.js';
|
|
5
5
|
import type { MemoryDeleteRequest, MemoryListRequest, MemoryReadRequest, MemoryReadResult, MemorySearchRequest, MemorySearchResult, MemoryUpdateRequest, MemoryWriteRequest, MemoryWriteResult, MemoryRecord, MemorySignal, MemoryKind } from './types.js';
|
|
6
|
+
import type { TurnMemoryProvenance } from './turn-provenance.js';
|
|
6
7
|
export type MemorySearchStrategy = 'local-first' | 'external-first' | 'fanout' | 'local-only' | 'external-only';
|
|
7
8
|
export type MemoryWriteStrategy = 'local-first' | 'external-first' | 'write-through' | 'local-only' | 'external-only';
|
|
8
9
|
export interface MemoryRoutingOptions {
|
|
@@ -51,6 +52,8 @@ export declare class MemoryManager {
|
|
|
51
52
|
}): Promise<import('./understanding/types.js').UnderstandingReviewResult>;
|
|
52
53
|
syncProvidersForTurn(userContent: string, assistantContent: string, options?: {
|
|
53
54
|
sessionId?: string;
|
|
55
|
+
turnId?: string;
|
|
56
|
+
provenance?: TurnMemoryProvenance;
|
|
54
57
|
}): Promise<void>;
|
|
55
58
|
applyUnderstandingCandidates(candidates: UnderstandingCandidate[], context?: {
|
|
56
59
|
agentId?: string;
|
|
@@ -98,11 +98,20 @@ var MemoryManager = class {
|
|
|
98
98
|
});
|
|
99
99
|
}
|
|
100
100
|
async syncProvidersForTurn(userContent, assistantContent, options) {
|
|
101
|
+
const provenance = options?.provenance;
|
|
101
102
|
const event = {
|
|
102
103
|
type: "turn",
|
|
103
104
|
userContent,
|
|
104
105
|
assistantContent,
|
|
105
|
-
sessionId: options?.sessionId
|
|
106
|
+
sessionId: options?.sessionId,
|
|
107
|
+
turnId: options?.turnId,
|
|
108
|
+
provenance: {
|
|
109
|
+
originClass: provenance?.originClass ?? "untrusted",
|
|
110
|
+
sessionKind: provenance?.sessionKind ?? "unknown",
|
|
111
|
+
sourceSessionId: provenance?.sourceSessionId ?? options?.sessionId,
|
|
112
|
+
sourceTurnId: provenance?.sourceTurnId ?? options?.turnId,
|
|
113
|
+
derivedFromRecalledContext: provenance?.derivedFromRecalledContext ?? false
|
|
114
|
+
}
|
|
106
115
|
};
|
|
107
116
|
for (const p of this.providers) {
|
|
108
117
|
const started = Date.now();
|
|
@@ -198,7 +207,7 @@ var MemoryManager = class {
|
|
|
198
207
|
}
|
|
199
208
|
}
|
|
200
209
|
const seen = /* @__PURE__ */ new Set();
|
|
201
|
-
return results.sort((a, b) => b.score - a.score).filter((result) => this.canReadRecord(result.record, request.scope)).filter((result) => {
|
|
210
|
+
return results.sort((a, b) => b.score - a.score).filter((result) => this.canReadRecord(result.record, request.scope)).filter((result) => !request.trustedOnly || (result.record.provenance?.originClass === "owner" || result.record.provenance?.originClass === "agent") && result.record.provenance?.derivedFromRecalledContext === false).filter((result) => {
|
|
202
211
|
const key = `${result.citation.providerId}:${result.citation.recordId}`;
|
|
203
212
|
if (seen.has(key)) return false;
|
|
204
213
|
seen.add(key);
|
|
@@ -427,6 +436,7 @@ var MemoryManager = class {
|
|
|
427
436
|
if (!provider.capabilities.local && this.writePolicy.allowedProviderIds && this.writePolicy.allowedProviderIds.length > 0 && !this.writePolicy.allowedProviderIds.includes(provider.id)) return false;
|
|
428
437
|
if (operation === "write") {
|
|
429
438
|
const writeRequest = request;
|
|
439
|
+
if (writeRequest.provenance?.derivedFromRecalledContext && writeRequest.status !== "candidate" && !writeRequest.confirmed) return false;
|
|
430
440
|
if (provider.capabilities.local && this.memoryRuntime) {
|
|
431
441
|
const check = this.memoryRuntime.checkWrite({
|
|
432
442
|
target: writeRequest.writeTarget ?? writeTargetForRecord(writeRequest),
|