@xopcai/xopc 0.0.321 → 0.0.323
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/dist/assets/{auth-DKo-NMUY.js → auth-DocRzRlS.js} +95 -21
- package/dist/browser-ext/dist/background.js +1 -1
- package/dist/browser-ext/dist/sidepanel.html +1 -1
- package/dist/browser-ext/dist/sidepanel.js +18 -2
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-C69p1Gbr.js → agent-avatar-dicebear-DFzmThVi.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CAFHadiy.js +1 -0
- package/dist/gateway/static/root/assets/agent-plugin-dialog-DYFYiuig.js +1 -0
- package/dist/gateway/static/root/assets/{agents-CWR3p3t3.js → agents-BqIlB5Co.js} +1 -1
- package/dist/gateway/static/root/assets/{app-link-nL8iPwEr.js → app-link-C6gA5Nck.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-D98bt40S.js → app-management-settings-panel-BgvMRGWe.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-ChMUELAZ.js → appearance-settings-CliHU03A.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-Drt3Foi9.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-BIIiu6uP.js → archive-plugin-DnuPpm0u.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-CDJpcsCp.js → attachment-load-BiwaK0ie.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-Cb5a_WOk.js → automations-page-CJSISGQH.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-B-Eduqwz.js +7 -0
- package/dist/gateway/static/root/assets/{binary-plugins-zp55zQPu.js → binary-plugins-KDjduQZO.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-B0CTIZb-.js → block-editor-bclvgove.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automation-inputs-Bx3W4J4H.js → browser-automation-inputs-CfQ2T9t6.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-D5Lr9b8a.js → browser-automations-page-Cxq38Nnp.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-Dwgir6mu.js +3 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-H5L5vynP.js +8 -0
- package/dist/gateway/static/root/assets/capabilities-uFKh3Hd0.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-RFBRYe5S.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-1I1PdIq0.js → chat-terminal-dock-DKQC62nQ.js} +2 -2
- package/dist/gateway/static/root/assets/{computer-settings-page-BT-EfoI6.js → computer-settings-page-D1whpIqL.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-service-page-mhQ-19tj.js → connector-service-page-BAuYTgf5.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-Px-v3Q6Q.js +2 -0
- package/dist/gateway/static/root/assets/{date-picker-BqcldZoN.js → date-picker-CfCo3lqh.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-DLDLJx3D.js → dependency-picker-DOuVO2M1.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-kSFeHyrt.js → desktop-pet-D9tu6Bhu.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BjY7DqD7.js → desktop-pet-settings-CQPXub2f.js} +1 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-DxkOYSut.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-DbWJDT4X.js → extension-debug-page-CtWClPz-.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-lAC_2xWA.js → extension-page-BHh9HLCz.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-jFy1NJg9.js → extension-settings-page-BdT3v5Uh.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-B7WpH3VW.js → gateway-config-swr-1eqyz9vZ.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-CZas_Ekx.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-C8F_z865.js → gateway-startup-retry-C4rsW6vJ.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-w3_aWeNt.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-Dc7d0_7q.js → image-generation-api-B5DXMylk.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-_fMvJvzM.js → imports-page-B1JH0G5j.js} +1 -1
- package/dist/gateway/static/root/assets/index--3c0awkr.js +121 -0
- package/dist/gateway/static/root/assets/index-CNc4N4TX.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CHnZYx1U.js → keyboard-shortcuts-settings-DGrLJ8Yh.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-BYKrJpFF.js +1 -0
- package/dist/gateway/static/root/assets/local-apps-Bpja8nC6.js +1 -0
- package/dist/gateway/static/root/assets/local-apps-page-DqjStqbL.js +1 -0
- package/dist/gateway/static/root/assets/{locale-store-D9krC43K.js → locale-store-BIkcRr3t.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-COxOJsgX.js → logs-page-Dl4kM4Na.js} +2 -2
- package/dist/gateway/static/root/assets/management-settings-gCfH4cwH.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-CurpvCbB.js → markdown-view-Ck_5MADq.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-CYldyH6K.js → media-plugins-DTsZqgo6.js} +1 -1
- package/dist/gateway/static/root/assets/messages-7VAhscYe.js +3 -0
- package/dist/gateway/static/root/assets/note-detail-panel-j6sioeL1.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-CMvvHv0f.js +8 -0
- package/dist/gateway/static/root/assets/{page-context-capture-button-DZOiI84c.js → page-context-capture-button-DTI_g4tz.js} +1 -1
- package/dist/gateway/static/root/assets/{page-tabs-C-XCf9cR.js → page-tabs-CfW_Q-K5.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-CvgeoEU8.js → preview-open-alternatives-CuPN-vAn.js} +1 -1
- package/dist/gateway/static/root/assets/product-delivery-bv3z8Xkh.js +1 -0
- package/dist/gateway/static/root/assets/product-open-page-BHjxRz1E.js +1 -0
- package/dist/gateway/static/root/assets/project-detail-page-C9K_e-EV.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-Bk-es4i9.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-cK-g8BDq.js → registry-api-BAAZUGnU.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CLGJNA42.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DlUodTo-.js → runtime-tools-settings-panel-CHJBJKL1.js} +2 -2
- package/dist/gateway/static/root/assets/{scenes-page-DO8vGorm.js → scenes-page-ClLAD1pz.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-BfboLCeN.js → schema-form-FQAit5HL.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-Xj8MkXN1.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-DwALV8mi.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-BytEfCGo.js → settings-form-section-BDc6bw1q.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-Da2ql9KX.js → settings-page-DnhxBJjV.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-CBfB_7yz.js → settings-page-layout-D3KNSQ5g.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-DElF2sgq.js → setup-status-panel-F0rCQ-2a.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-B8J0Saj5.js → share-preview-page-DVQCRxwK.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-C7hf6Cov.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-xPrFejRE.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-CNQHhsiv.js → skills-page-RdDYu7Yj.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-B53tyGx5.js → skills-page.utils-mDwC9UJ-.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-0HAvlVtR.js → system-settings-panel-Bk7GrMij.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-2A966jFY.js +1 -0
- package/dist/gateway/static/root/assets/{tunnel-api-DJsxU6q_.js → tunnel-api-D3Aquraj.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-eIELzAOD.js → use-autosave-C1xQ-sHn.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-CnBxPBVe.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-BJ59ZCAn.js → voice-api-key-field-DCNECvcp.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-DBXZJWLS.js → voice-config-api-B-_niUTU.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BpSxdIgB.js → work-discovery-overlay-BrGx_JS_.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Bhlv3VUX.js → workflow-run-setup-panel-CmmC2Pdr.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-BZVpqw4T.js +6 -0
- package/dist/gateway/static/root/index.html +12 -11
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/capabilities.js +4 -110
- package/dist/packages/gateway-contract/src/chat-previews.js +73 -0
- package/dist/packages/gateway-contract/src/index.js +6 -0
- package/dist/packages/gateway-contract/src/local-apps.js +215 -0
- package/dist/packages/gateway-contract/src/product-delivery.js +62 -17
- package/dist/packages/gateway-contract/src/user-turn-document.js +60 -0
- package/dist/src/agent/agent-manager.d.ts +1 -0
- package/dist/src/agent/agent-manager.js +1 -0
- package/dist/src/agent/embedded/transcript-runtime.d.ts +3 -0
- package/dist/src/agent/embedded/transcript-runtime.js +6 -0
- package/dist/src/agent/external-tools/cliProvider.js +4 -1
- package/dist/src/agent/external-tools/composio-provider.js +9 -3
- package/dist/src/agent/external-tools/gateway-tools.js +17 -10
- package/dist/src/agent/external-tools/mcp-provider.d.ts +3 -1
- package/dist/src/agent/external-tools/mcp-provider.js +91 -6
- package/dist/src/agent/external-tools/service.d.ts +2 -1
- package/dist/src/agent/external-tools/service.js +8 -3
- package/dist/src/agent/external-tools/types.d.ts +9 -0
- package/dist/src/agent/mcp/bundle-mcp-config.js +37 -5
- package/dist/src/agent/mcp/bundle-mcp-gateway.d.ts +1 -0
- package/dist/src/agent/mcp/bundle-mcp-gateway.js +1 -0
- package/dist/src/agent/mcp/bundle-mcp-names.js +2 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +33 -1
- package/dist/src/agent/mcp/bundle-mcp-types.d.ts +4 -0
- package/dist/src/agent/mcp/index.js +1 -1
- package/dist/src/agent/mcp/mcp-stdio-transport.d.ts +1 -0
- package/dist/src/agent/mcp/mcp-stdio-transport.js +10 -0
- package/dist/src/agent/mcp/mcp-transport.js +12 -8
- package/dist/src/agent/mcp/oauth/index.js +1 -1
- package/dist/src/agent/mcp/oauth/mcp-oauth-manager.d.ts +6 -1
- package/dist/src/agent/mcp/oauth/mcp-oauth-manager.js +70 -14
- package/dist/src/agent/mcp/oauth/mcp-oauth-provider.js +1 -1
- package/dist/src/agent/mcp/oauth/mcp-oauth-session.d.ts +2 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-session.js +12 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-store.d.ts +3 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +13 -1
- package/dist/src/agent/mcp/plugin-http-fetch.d.ts +2 -0
- package/dist/src/agent/mcp/plugin-http-fetch.js +56 -0
- package/dist/src/agent/service/process-direct-streaming.js +27 -12
- package/dist/src/agent/service.js +1 -0
- package/dist/src/agent/service.types.d.ts +2 -0
- package/dist/src/agent/skills/hub-pull.js +1 -1
- package/dist/src/agent/skills/index.js +8 -1
- package/dist/src/agent/skills/skill-manager.d.ts +2 -0
- package/dist/src/agent/skills/skill-manager.js +8 -0
- package/dist/src/agent/skills/skill-sources.js +17 -0
- package/dist/src/agent/skills/types.d.ts +3 -1
- package/dist/src/agent/source-context/injector.js +10 -5
- package/dist/src/agent/source-context/types.d.ts +3 -0
- package/dist/src/agent/source-context/types.js +8 -2
- package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
- package/dist/src/agent/tool-manuals/xopc-use.js +12 -2
- package/dist/src/agent/tools/automation-tool.js +1 -1
- package/dist/src/agent/tools/factory.d.ts +1 -0
- package/dist/src/agent/tools/factory.js +2 -1
- package/dist/src/agent/tools/workflow-tool.js +1 -1
- package/dist/src/agent/tools/write.js +1 -1
- package/dist/src/agent/tools/xopc-use-tool.d.ts +4 -2
- package/dist/src/agent/tools/xopc-use-tool.js +120 -12
- package/dist/src/chat-previews/index.d.ts +2 -0
- package/dist/src/chat-previews/index.js +3 -0
- package/dist/src/chat-previews/service.d.ts +27 -0
- package/dist/src/chat-previews/service.js +106 -0
- package/dist/src/chat-previews/store.d.ts +28 -0
- package/dist/src/chat-previews/store.js +77 -0
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-agent-plugin.d.ts +8 -0
- package/dist/src/cli/commands/extension-agent-plugin.js +82 -0
- package/dist/src/cli/commands/extension-marketplace.js +44 -4
- package/dist/src/cli/commands/extension.js +35 -3
- package/dist/src/connectors/account-selection.js +1 -1
- package/dist/src/connectors/connection-candidates.d.ts +4 -1
- package/dist/src/connectors/connection-candidates.js +8 -2
- package/dist/src/connectors/connection-capabilities.d.ts +2 -2
- package/dist/src/connectors/connection-capabilities.js +3 -1
- package/dist/src/connectors/connection-recovery-service.d.ts +6 -1
- package/dist/src/connectors/connection-recovery-service.js +138 -26
- package/dist/src/connectors/plugin-mcp-recovery.d.ts +28 -0
- package/dist/src/connectors/plugin-mcp-recovery.js +90 -0
- package/dist/src/extensions/agent-plugins/auth.d.ts +39 -0
- package/dist/src/extensions/agent-plugins/auth.js +156 -0
- package/dist/src/extensions/agent-plugins/connection.d.ts +8 -0
- package/dist/src/extensions/agent-plugins/connection.js +41 -0
- package/dist/src/extensions/agent-plugins/health.d.ts +4 -0
- package/dist/src/extensions/agent-plugins/health.js +48 -0
- package/dist/src/extensions/agent-plugins/inventory.d.ts +53 -0
- package/dist/src/extensions/agent-plugins/inventory.js +34 -0
- package/dist/src/extensions/agent-plugins/mcp-adapter.d.ts +3 -0
- package/dist/src/extensions/agent-plugins/mcp-adapter.js +47 -0
- package/dist/src/extensions/agent-plugins/sources.d.ts +5 -0
- package/dist/src/extensions/agent-plugins/sources.js +72 -0
- package/dist/src/extensions/agent-plugins/store.d.ts +61 -0
- package/dist/src/extensions/agent-plugins/store.js +305 -0
- package/dist/src/extensions/agent-plugins/validation.d.ts +59 -0
- package/dist/src/extensions/agent-plugins/validation.js +211 -0
- package/dist/src/extensions/update.js +1 -1
- package/dist/src/gateway/chat-stream/mapper.js +10 -3
- package/dist/src/gateway/hono/routes/agent-plugins.d.ts +3 -0
- package/dist/src/gateway/hono/routes/agent-plugins.js +166 -0
- package/dist/src/gateway/hono/routes/agent-stream.js +14 -0
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +4 -2
- package/dist/src/gateway/hono/routes/chat-previews.d.ts +3 -0
- package/dist/src/gateway/hono/routes/chat-previews.js +41 -0
- package/dist/src/gateway/hono/routes/connection-waits.js +4 -2
- package/dist/src/gateway/hono/routes/index.js +2 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/local-apps.js +71 -39
- package/dist/src/gateway/hono/routes/mcp.js +48 -21
- package/dist/src/gateway/hono/routes/session-input-handler.d.ts +4 -0
- package/dist/src/gateway/hono/routes/session-input-handler.js +22 -0
- package/dist/src/gateway/hono/routes/side-chats.js +11 -0
- package/dist/src/gateway/service/agent-runner.js +7 -1
- package/dist/src/gateway/service/marketplace-service.d.ts +1 -0
- package/dist/src/gateway/service/marketplace-service.js +15 -1
- package/dist/src/gateway/service/session-input-coordinator.js +3 -3
- package/dist/src/gateway/service.d.ts +5 -1
- package/dist/src/gateway/service.js +14 -0
- package/dist/src/gateway/side-chat/index.d.ts +3 -1
- package/dist/src/gateway/side-chat/index.js +2 -1
- package/dist/src/gateway/side-chat/manager.d.ts +16 -0
- package/dist/src/gateway/side-chat/manager.js +40 -6
- package/dist/src/gateway/side-chat/promotion-service.d.ts +19 -0
- package/dist/src/gateway/side-chat/promotion-service.js +111 -0
- package/dist/src/gateway/side-chat/run-service.js +1 -0
- package/dist/src/gateway/side-chat/types.d.ts +1 -1
- package/dist/src/local-apps/artifact-files.d.ts +3 -0
- package/dist/src/local-apps/artifact-files.js +45 -0
- package/dist/src/local-apps/capabilities/write.js +1 -1
- package/dist/src/local-apps/fix-guidance.d.ts +3 -0
- package/dist/src/local-apps/fix-guidance.js +75 -0
- package/dist/src/local-apps/index.d.ts +2 -1
- package/dist/src/local-apps/scaffold.d.ts +5 -0
- package/dist/src/local-apps/scaffold.js +18 -5
- package/dist/src/local-apps/service.d.ts +18 -3
- package/dist/src/local-apps/service.js +106 -64
- package/dist/src/local-apps/snapshot-store.d.ts +8 -0
- package/dist/src/local-apps/snapshot-store.js +68 -0
- package/dist/src/local-apps/types.d.ts +4 -87
- package/dist/src/session/client-history.d.ts +3 -1
- package/dist/src/session/client-history.js +10 -3
- package/dist/src/session/index.d.ts +1 -1
- package/dist/src/session/manager.d.ts +4 -0
- package/dist/src/session/manager.js +6 -0
- package/dist/src/session/session-context-for-llm.d.ts +12 -1
- package/dist/src/session/session-context-for-llm.js +16 -2
- package/dist/src/session/store.d.ts +14 -0
- package/dist/src/session/store.js +17 -0
- package/dist/src/session/stored-rows-to-file-entries.js +10 -1
- package/dist/src/session/transcript-outline.js +10 -3
- package/dist/src/storage/sqlite/connection-wait-repository.js +9 -3
- package/dist/src/storage/sqlite/migrations/202_chat_previews.sql +26 -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/row-mappers.js +6 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/package.json +3 -3
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-DWLXHWXg.js +0 -1
- package/dist/gateway/static/root/assets/api-Df2D6d3C.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-BzytHIn1.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-CtSV8tp-.js +0 -7
- package/dist/gateway/static/root/assets/browser-settings-page-DrvNA-G2.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-D0S3DuAD.js +0 -1
- package/dist/gateway/static/root/assets/capabilities-settings-panel-c0k2virA.js +0 -8
- package/dist/gateway/static/root/assets/channels-settings-Bkl9fDHc.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-Dw_h-5Qh.js +0 -2
- package/dist/gateway/static/root/assets/device-pairing-wizard-C5f4FRpE.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-D7XbH6Hk.js +0 -1
- package/dist/gateway/static/root/assets/home-page-CFJypY6Y.js +0 -1
- package/dist/gateway/static/root/assets/index-B4Vwh0H-.css +0 -1
- package/dist/gateway/static/root/assets/index-BNubE2Zi.js +0 -89
- package/dist/gateway/static/root/assets/local-app-workbench-page-BLKCFXvr.js +0 -2
- package/dist/gateway/static/root/assets/local-apps-page-BNFmOkxs.js +0 -1
- package/dist/gateway/static/root/assets/management-settings-BX5NtnQ2.js +0 -1
- package/dist/gateway/static/root/assets/messages-B1sTgIrE.js +0 -3
- package/dist/gateway/static/root/assets/note-detail-panel-DZ0IWx1R.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-B9F1uue_.js +0 -8
- package/dist/gateway/static/root/assets/product-delivery-chCjIpvu.js +0 -1
- package/dist/gateway/static/root/assets/product-open-page-DEYWx__w.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-9qMDEKVd.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-D4UTOpEm.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CPmOucUB.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-zu5P0dk5.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-ClEw-i1l.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-MLolJfoV.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DTPsW9TY.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-Dc30oS9J.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-Bq6ab5WJ.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-Ci-4HAYm.js +0 -6
|
@@ -98,6 +98,7 @@ export interface AgentManagerConfig {
|
|
|
98
98
|
getProjectService?: () => ProjectService | undefined;
|
|
99
99
|
getWorkDiscovery?: () => import('../work-discovery/service.js').WorkDiscoveryService | undefined;
|
|
100
100
|
getLocalAppService?: () => import('../local-apps/index.js').LocalAppService | undefined;
|
|
101
|
+
getChatPreviewService?: () => import('../chat-previews/index.js').ChatPreviewService | undefined;
|
|
101
102
|
dispatchTaskEvents?: () => void;
|
|
102
103
|
dispatchTaskRuns?: () => void;
|
|
103
104
|
/** Gateway: starts persisted workflow runs (dedicated chat session per run). */
|
|
@@ -270,6 +270,7 @@ var AgentManager = class {
|
|
|
270
270
|
getProjectService: this.config.getProjectService,
|
|
271
271
|
getWorkDiscovery: this.config.getWorkDiscovery,
|
|
272
272
|
getLocalAppService: this.config.getLocalAppService,
|
|
273
|
+
getChatPreviewService: this.config.getChatPreviewService,
|
|
273
274
|
dispatchTaskEvents: this.config.dispatchTaskEvents,
|
|
274
275
|
dispatchTaskRuns: this.config.dispatchTaskRuns,
|
|
275
276
|
getWorkflowRunService: this.config.getWorkflowRunService,
|
|
@@ -3,6 +3,7 @@ import { SessionManager } from '@earendil-works/pi-coding-agent';
|
|
|
3
3
|
import type { Api, Model } from '@earendil-works/pi-ai';
|
|
4
4
|
import { type CompactionExecutionOptions, type CompactionResult } from '../memory/compaction.js';
|
|
5
5
|
import type { SessionStore } from '../../session/store.js';
|
|
6
|
+
import type { TranscriptSourceEntry } from '../../storage/sqlite/transcript-repository.js';
|
|
6
7
|
export interface EmbeddedTranscriptRuntime {
|
|
7
8
|
readonly runtimeId: string;
|
|
8
9
|
readonly transcriptId: string;
|
|
@@ -32,6 +33,8 @@ export declare class InMemoryTranscriptRuntime implements EmbeddedTranscriptRunt
|
|
|
32
33
|
loadMessages(): Promise<AgentMessage[]>;
|
|
33
34
|
captureBaseline(): void;
|
|
34
35
|
loadConversationMessages(): AgentMessage[];
|
|
36
|
+
loadBaselineMessages(): AgentMessage[];
|
|
37
|
+
loadConversationRows(): TranscriptSourceEntry['row'][];
|
|
35
38
|
private sourceEntries;
|
|
36
39
|
compact(_messages: AgentMessage[], model: Model<Api>, instructions?: string, force?: boolean, options?: CompactionExecutionOptions): Promise<CompactionResult>;
|
|
37
40
|
}
|
|
@@ -49,6 +49,12 @@ var InMemoryTranscriptRuntime = class {
|
|
|
49
49
|
loadConversationMessages() {
|
|
50
50
|
return this.sessionManager.getBranch().slice(this.baselineEntryCount).flatMap((entry) => entry.type === "message" ? [entry.message] : []);
|
|
51
51
|
}
|
|
52
|
+
loadBaselineMessages() {
|
|
53
|
+
return buildSessionContextForLlm(this.sourceEntries().slice(0, this.baselineEntryCount).map((entry) => entry.row));
|
|
54
|
+
}
|
|
55
|
+
loadConversationRows() {
|
|
56
|
+
return structuredClone(this.sourceEntries().slice(this.baselineEntryCount).map((entry) => entry.row));
|
|
57
|
+
}
|
|
52
58
|
sourceEntries() {
|
|
53
59
|
return this.sessionManager.getBranch().flatMap((entry, index) => {
|
|
54
60
|
const compaction = this.compactionRows.get(entry.id);
|
|
@@ -202,7 +202,10 @@ var CliToolProvider = class {
|
|
|
202
202
|
summary: `Confirm ${action.id}`,
|
|
203
203
|
needs: [{
|
|
204
204
|
key: `${item.instance.connectorId}:${connection.accountId}`,
|
|
205
|
-
|
|
205
|
+
target: {
|
|
206
|
+
type: "connector",
|
|
207
|
+
connectorId: item.instance.connectorId
|
|
208
|
+
},
|
|
206
209
|
accountId: connection.accountId,
|
|
207
210
|
connectionId: connection.id,
|
|
208
211
|
label: item.instance.displayName,
|
|
@@ -260,7 +260,7 @@ var ComposioToolProvider = class {
|
|
|
260
260
|
}).filter((connection) => connection.status === "active" && fresh.some((item) => item.id === connection.id) && canAccessConnectorAccount(connection, resolved.installation, available.agentId)));
|
|
261
261
|
const boundConnection = available.context ? connectionBinding(available.context.conversationId, resolved.installation.connectorId) : void 0;
|
|
262
262
|
const requestedAccount = typeof executionArgs[CONNECTION_ARGUMENT] === "string" ? executionArgs[CONNECTION_ARGUMENT] : boundConnection ? getConnectorConnection(boundConnection)?.accountId : void 0;
|
|
263
|
-
const bindings = available.context ? connectionBindings(available.context.conversationId).filter((need) => need.connectorId === resolved.installation.connectorId) : [];
|
|
263
|
+
const bindings = available.context ? connectionBindings(available.context.conversationId).filter((need) => need.target.type === "connector" && need.target.connectorId === resolved.installation.connectorId) : [];
|
|
264
264
|
if (bindings.length > 1 && !requestedAccount) return textResult({
|
|
265
265
|
status: "account_selection_required",
|
|
266
266
|
accounts: bindings,
|
|
@@ -277,7 +277,10 @@ var ComposioToolProvider = class {
|
|
|
277
277
|
summary: `Continue ${action.actionId} using ${toolkit}`,
|
|
278
278
|
needs: [{
|
|
279
279
|
key: `${resolved.installation.connectorId}:default`,
|
|
280
|
-
|
|
280
|
+
target: {
|
|
281
|
+
type: "connector",
|
|
282
|
+
connectorId: resolved.installation.connectorId
|
|
283
|
+
},
|
|
281
284
|
accountId: requestedAccount,
|
|
282
285
|
label: getConnectorDefinition(resolved.installation.connectorId)?.displayName ?? toolkit,
|
|
283
286
|
capabilities: [action.actionId]
|
|
@@ -388,7 +391,10 @@ var ComposioToolProvider = class {
|
|
|
388
391
|
summary: `Confirm ${action.actionId}`,
|
|
389
392
|
needs: [{
|
|
390
393
|
key: `${resolved.installation.connectorId}:${connection.accountId}`,
|
|
391
|
-
|
|
394
|
+
target: {
|
|
395
|
+
type: "connector",
|
|
396
|
+
connectorId: resolved.installation.connectorId
|
|
397
|
+
},
|
|
392
398
|
accountId: connection.accountId,
|
|
393
399
|
connectionId: connection.id,
|
|
394
400
|
label: toolkit,
|
|
@@ -2,6 +2,7 @@ import { init_connector_repository, listConnectorConnections } from "../../stora
|
|
|
2
2
|
import { connectionBindings, getActiveConnectionWait, init_connection_wait_repository, publishConnectionWait, requireSessionConnection, reviseCurrentConnectionObjective } from "../../storage/sqlite/connection-wait-repository.js";
|
|
3
3
|
import { connectorPrincipalForSession } from "../../connectors/principal.js";
|
|
4
4
|
import { connectionCandidates, resolveConnectionCandidate } from "../../connectors/connection-candidates.js";
|
|
5
|
+
import { parsePluginMcpCandidateRef, resolvePluginMcpConnectionCandidate } from "../../extensions/agent-plugins/connection.js";
|
|
5
6
|
import { ExternalToolService } from "./service.js";
|
|
6
7
|
import { EXTERNAL_TOOL_SOURCES } from "./types.js";
|
|
7
8
|
import { Type } from "@sinclair/typebox";
|
|
@@ -57,13 +58,15 @@ function createExternalToolGatewayTools(providers, getContext) {
|
|
|
57
58
|
async execute(_toolCallId, params) {
|
|
58
59
|
const selectedSources = new Set(params.sources ?? []);
|
|
59
60
|
const excludedSources = selectedSources.size ? EXTERNAL_TOOL_SOURCES.filter((source) => !selectedSources.has(source)) : [];
|
|
61
|
+
const result = await service.search(params);
|
|
62
|
+
const candidates = [...result.connectionCandidates, ...connectionCandidates(params.query)].filter((candidate, index, all) => all.findIndex((item) => item.candidateRef === candidate.candidateRef) === index);
|
|
60
63
|
return textResult({
|
|
61
|
-
...
|
|
64
|
+
...result,
|
|
65
|
+
connectionCandidates: candidates,
|
|
62
66
|
...excludedSources.length ? { searchScope: {
|
|
63
67
|
excludedSources,
|
|
64
68
|
instruction: "This search excluded these sources. Results from other apps do not establish that the requested app is unavailable. Retry without sources before declaring a capability unavailable or requesting authorization. Feishu/Lark, WeCom and WPS 365 connectors use cli."
|
|
65
69
|
} } : {},
|
|
66
|
-
connectionCandidates: connectionCandidates(params.query),
|
|
67
70
|
selectedConnections: getContext?.()?.conversationId ? connectionBindings(getContext().conversationId) : [],
|
|
68
71
|
waitingObjective: getContext?.()?.conversationId ? getActiveConnectionWait(getContext().conversationId)?.summary : void 0
|
|
69
72
|
});
|
|
@@ -147,10 +150,13 @@ function createExternalToolGatewayTools(providers, getContext) {
|
|
|
147
150
|
const principal = connectorPrincipalForSession(context.conversationId);
|
|
148
151
|
if (!principal.isLocalOwner) throw new Error("Connection recovery is available in the owner chat.");
|
|
149
152
|
const selected = connectionBindings(context.conversationId);
|
|
150
|
-
if (params.requirements.every((item) =>
|
|
151
|
-
|
|
152
|
-
connectorId
|
|
153
|
-
|
|
153
|
+
if (params.requirements.every((item) => {
|
|
154
|
+
const pluginTarget = parsePluginMcpCandidateRef(item.candidateRef);
|
|
155
|
+
return selected.some((need) => need.target.type === "connector" ? need.target.connectorId === item.candidateRef && Boolean(need.connectionId) && (!item.accountId || item.accountId === need.accountId) && (!item.accountSelector || item.accountSelector === need.accountSelector) && listConnectorConnections({
|
|
156
|
+
principalId: principal.principalId,
|
|
157
|
+
connectorId: need.target.connectorId
|
|
158
|
+
}).some((connection) => connection.id === need.connectionId && connection.status === "active") : Boolean(pluginTarget && need.target.pluginId === pluginTarget.pluginId && need.target.serverName === pluginTarget.serverName && need.connectionId === need.target.serverId));
|
|
159
|
+
})) return textResult({
|
|
154
160
|
status: "already_connected",
|
|
155
161
|
selectedConnections: selected,
|
|
156
162
|
instruction: "These accounts were already checked for this objective. Missing tool contracts are a tool availability problem. Do not request authorization again or invent a revision. Explain the unavailable capability and stop retrying the same tools."
|
|
@@ -162,16 +168,17 @@ function createExternalToolGatewayTools(providers, getContext) {
|
|
|
162
168
|
summary: params.purpose,
|
|
163
169
|
checkpoint: params.checkpoint,
|
|
164
170
|
needs: params.requirements.map((item) => {
|
|
165
|
-
const need = resolveConnectionCandidate(item.candidateRef);
|
|
166
|
-
if (item.accountId &&
|
|
171
|
+
const need = resolvePluginMcpConnectionCandidate(item.candidateRef) ?? resolveConnectionCandidate(item.candidateRef);
|
|
172
|
+
if (item.accountId && need.target.type !== "connector") throw new Error("Plugin MCP connections do not support account selection.");
|
|
173
|
+
if (item.accountId && need.target.type === "connector" && !listConnectorConnections({
|
|
167
174
|
principalId: principal.principalId,
|
|
168
|
-
connectorId: need.connectorId
|
|
175
|
+
connectorId: need.target.connectorId
|
|
169
176
|
}).some((connection) => connection.accountId === item.accountId)) throw new Error("Unknown account for this app.");
|
|
170
177
|
return {
|
|
171
178
|
...need,
|
|
172
179
|
accountId: item.accountId,
|
|
173
180
|
accountSelector: item.accountSelector,
|
|
174
|
-
key: `${need.connectorId}:${item.accountId ?? item.accountSelector ?? "default"}`
|
|
181
|
+
key: need.target.type === "connector" ? `${need.target.connectorId}:${item.accountId ?? item.accountSelector ?? "default"}` : need.key
|
|
175
182
|
};
|
|
176
183
|
})
|
|
177
184
|
});
|
|
@@ -2,7 +2,7 @@ import type { AgentToolResult } from '@earendil-works/pi-agent-core';
|
|
|
2
2
|
import type { Config } from '../../config/schema.js';
|
|
3
3
|
import type { ExtensionHookRunner } from '../../extensions/index.js';
|
|
4
4
|
import type { SessionMcpRuntime } from '../mcp/bundle-mcp-types.js';
|
|
5
|
-
import type { ExternalToolDescriptor, ExternalToolExecutionContext, ExternalToolProvider, ExternalToolSearchHit } from './types.js';
|
|
5
|
+
import type { ExternalToolDescriptor, ExternalConnectionCandidate, ExternalToolExecutionContext, ExternalToolProvider, ExternalToolSearchHit } from './types.js';
|
|
6
6
|
export interface McpToolProviderDeps {
|
|
7
7
|
workspace: string;
|
|
8
8
|
getConfig: () => Config | undefined;
|
|
@@ -21,8 +21,10 @@ export declare class McpToolProvider implements ExternalToolProvider {
|
|
|
21
21
|
readonly source: "mcp";
|
|
22
22
|
constructor(deps: McpToolProviderDeps);
|
|
23
23
|
search(_query: string): Promise<ExternalToolSearchHit[]>;
|
|
24
|
+
connectionCandidates(query: string): Promise<ExternalConnectionCandidate[]>;
|
|
24
25
|
describe(toolRef: string): Promise<ExternalToolDescriptor | undefined>;
|
|
25
26
|
execute(toolRef: string, args: Record<string, unknown>, _approvalId: string | undefined, context: ExternalToolExecutionContext): Promise<AgentToolResult<Record<string, unknown>>>;
|
|
27
|
+
private requestConnection;
|
|
26
28
|
private resolve;
|
|
27
29
|
private isAllowed;
|
|
28
30
|
private executionSignal;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import { init_connection_wait_repository, publishConnectionWait, requireSessionConnection } from "../../storage/sqlite/connection-wait-repository.js";
|
|
1
2
|
import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
|
|
3
|
+
import { connectorPrincipalForSession } from "../../connectors/principal.js";
|
|
2
4
|
import { externalToolRef, parseExternalToolRef } from "./refs.js";
|
|
5
|
+
import { pluginMcpCandidateRef } from "../../extensions/agent-plugins/connection.js";
|
|
3
6
|
import { mcpToolPolicyId } from "../mcp/bundle-mcp-policy.js";
|
|
7
|
+
import { isMcpAuthorizationError } from "../mcp/oauth/mcp-oauth-errors.js";
|
|
4
8
|
import { getOrCreateSessionMcpRuntime } from "../mcp/bundle-mcp-runtime.js";
|
|
5
9
|
//#region src/agent/external-tools/mcp-provider.ts
|
|
10
|
+
init_connection_wait_repository();
|
|
6
11
|
function policyToolId(tool) {
|
|
7
12
|
return mcpToolPolicyId(tool.safeServerName, tool.toolName);
|
|
8
13
|
}
|
|
@@ -25,6 +30,10 @@ function toAgentToolResult(params) {
|
|
|
25
30
|
}
|
|
26
31
|
};
|
|
27
32
|
}
|
|
33
|
+
function hasAuthorizationChallenge(result) {
|
|
34
|
+
const challenge = result._meta?.["mcp/www_authenticate"];
|
|
35
|
+
return typeof challenge === "string" || Array.isArray(challenge) && challenge.some((value) => typeof value === "string");
|
|
36
|
+
}
|
|
28
37
|
var McpToolProvider = class {
|
|
29
38
|
source = "mcp";
|
|
30
39
|
constructor(deps) {
|
|
@@ -41,6 +50,30 @@ var McpToolProvider = class {
|
|
|
41
50
|
}));
|
|
42
51
|
});
|
|
43
52
|
}
|
|
53
|
+
async connectionCandidates(query) {
|
|
54
|
+
return this.withRuntime(async (runtime) => {
|
|
55
|
+
const catalog = await runtime.getCatalog();
|
|
56
|
+
const normalizedQuery = query.toLocaleLowerCase();
|
|
57
|
+
return Object.values(catalog.servers).flatMap((server) => {
|
|
58
|
+
if (!server.serverName.startsWith("plugin/") || server.error?.code !== "MCP_AUTHORIZATION_REQUIRED") return [];
|
|
59
|
+
const [, encodedPluginId, encodedServerName] = server.serverName.split("/");
|
|
60
|
+
if (!encodedPluginId || !encodedServerName) return [];
|
|
61
|
+
const pluginId = decodeURIComponent(encodedPluginId);
|
|
62
|
+
const serverName = decodeURIComponent(encodedServerName);
|
|
63
|
+
const searchable = `${pluginId} ${serverName}`.toLocaleLowerCase();
|
|
64
|
+
const tokens = normalizedQuery.split(/[^\p{L}\p{N}_-]+/u).filter((token) => token.length > 1);
|
|
65
|
+
if (tokens.length && !tokens.some((token) => searchable.includes(token))) return [];
|
|
66
|
+
return [{
|
|
67
|
+
candidateRef: pluginMcpCandidateRef(pluginId, serverName),
|
|
68
|
+
source: this.source,
|
|
69
|
+
label: pluginId,
|
|
70
|
+
summary: `Connect ${pluginId}/${serverName}`,
|
|
71
|
+
capabilities: [`mcp.tools:${server.serverName}`],
|
|
72
|
+
reason: "not_connected"
|
|
73
|
+
}];
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}
|
|
44
77
|
async describe(toolRef) {
|
|
45
78
|
return this.withRuntime(async (runtime) => {
|
|
46
79
|
const tool = await this.resolve(runtime, toolRef);
|
|
@@ -71,13 +104,65 @@ var McpToolProvider = class {
|
|
|
71
104
|
if (!hook.allowed) throw new Error(hook.reason ?? "MCP tool call blocked by policy hook.");
|
|
72
105
|
executionArgs = hook.params ?? args;
|
|
73
106
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
serverName
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
107
|
+
try {
|
|
108
|
+
const result = await runtime.callTool(tool.serverName, tool.toolName, executionArgs, this.executionSignal(tool, context.signal));
|
|
109
|
+
if (tool.serverName.startsWith("plugin/") && hasAuthorizationChallenge(result)) return this.requestConnection(tool.serverName, tool.toolName);
|
|
110
|
+
return toAgentToolResult({
|
|
111
|
+
serverName: tool.serverName,
|
|
112
|
+
toolName: tool.toolName,
|
|
113
|
+
result
|
|
114
|
+
});
|
|
115
|
+
} catch (error) {
|
|
116
|
+
if (tool.serverName.startsWith("plugin/") && (isMcpAuthorizationError(error) || error?.code === 401)) return this.requestConnection(tool.serverName, tool.toolName);
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
requestConnection(serverId, toolName) {
|
|
122
|
+
const [, encodedPluginId, encodedServerName] = serverId.split("/");
|
|
123
|
+
const conversationId = this.deps.getConversationId();
|
|
124
|
+
if (!encodedPluginId || !encodedServerName || !conversationId) return {
|
|
125
|
+
content: [{
|
|
126
|
+
type: "text",
|
|
127
|
+
text: "This MCP tool requires an account connection in xopc."
|
|
128
|
+
}],
|
|
129
|
+
details: { status: "connection_required" }
|
|
130
|
+
};
|
|
131
|
+
const pluginId = decodeURIComponent(encodedPluginId);
|
|
132
|
+
const serverName = decodeURIComponent(encodedServerName);
|
|
133
|
+
const principal = connectorPrincipalForSession(conversationId);
|
|
134
|
+
if (!principal.isLocalOwner) return {
|
|
135
|
+
content: [{
|
|
136
|
+
type: "text",
|
|
137
|
+
text: "This MCP connection must be completed by the xopc owner."
|
|
138
|
+
}],
|
|
139
|
+
details: { status: "connection_required" }
|
|
140
|
+
};
|
|
141
|
+
const result = requireSessionConnection({
|
|
142
|
+
conversationId,
|
|
143
|
+
principalId: principal.principalId,
|
|
144
|
+
agentId: principal.agentId ?? this.deps.agentId ?? "main",
|
|
145
|
+
summary: `Continue ${toolName} using ${pluginId}`,
|
|
146
|
+
needs: [{
|
|
147
|
+
key: serverId,
|
|
148
|
+
target: {
|
|
149
|
+
type: "plugin-mcp",
|
|
150
|
+
pluginId,
|
|
151
|
+
serverId,
|
|
152
|
+
serverName
|
|
153
|
+
},
|
|
154
|
+
label: pluginId,
|
|
155
|
+
capabilities: [`mcp.tool:${serverId}:${toolName}`]
|
|
156
|
+
}]
|
|
80
157
|
});
|
|
158
|
+
publishConnectionWait(conversationId);
|
|
159
|
+
return {
|
|
160
|
+
content: [{
|
|
161
|
+
type: "text",
|
|
162
|
+
text: "Account connection required. The objective is preserved in xopc."
|
|
163
|
+
}],
|
|
164
|
+
details: result
|
|
165
|
+
};
|
|
81
166
|
}
|
|
82
167
|
async resolve(runtime, toolRef) {
|
|
83
168
|
const parsed = parseExternalToolRef(toolRef, this.source);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { searchFailureDetails } from './search-error.js';
|
|
2
|
-
import type { ExternalToolExecutionContext, ExternalToolProvider, ExternalToolSearchHit, ExternalToolSource, VersionedExternalToolDescriptor } from './types.js';
|
|
2
|
+
import type { ExternalToolExecutionContext, ExternalConnectionCandidate, ExternalToolProvider, ExternalToolSearchHit, ExternalToolSource, VersionedExternalToolDescriptor } from './types.js';
|
|
3
3
|
export declare class ExternalToolService {
|
|
4
4
|
private readonly providerBySource;
|
|
5
5
|
private readonly ajv;
|
|
@@ -10,6 +10,7 @@ export declare class ExternalToolService {
|
|
|
10
10
|
limit?: number;
|
|
11
11
|
}): Promise<{
|
|
12
12
|
tools: ExternalToolSearchHit[];
|
|
13
|
+
connectionCandidates: ExternalConnectionCandidate[];
|
|
13
14
|
unavailableSources: ExternalToolSource[];
|
|
14
15
|
sourceErrors?: Array<ReturnType<typeof searchFailureDetails> & {
|
|
15
16
|
source: ExternalToolSource;
|
|
@@ -52,13 +52,17 @@ var ExternalToolService = class {
|
|
|
52
52
|
const selected = params.sources?.length ? params.sources.map((source) => this.providerBySource.get(source)).filter((provider) => provider !== void 0) : [...this.providerBySource.values()];
|
|
53
53
|
const settled = await Promise.allSettled(selected.map(async (provider) => ({
|
|
54
54
|
provider,
|
|
55
|
-
hits: await provider.search(params.query)
|
|
55
|
+
hits: await provider.search(params.query),
|
|
56
|
+
candidates: await provider.connectionCandidates?.(params.query) ?? []
|
|
56
57
|
})));
|
|
57
58
|
const unavailableSources = [];
|
|
58
59
|
const sourceErrors = [];
|
|
59
60
|
const hits = [];
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
const connectionCandidates = [];
|
|
62
|
+
for (const [index, result] of settled.entries()) if (result.status === "fulfilled") {
|
|
63
|
+
hits.push(...result.value.hits);
|
|
64
|
+
connectionCandidates.push(...result.value.candidates);
|
|
65
|
+
} else {
|
|
62
66
|
const provider = selected[index];
|
|
63
67
|
if (provider) {
|
|
64
68
|
unavailableSources.push(provider.source);
|
|
@@ -87,6 +91,7 @@ var ExternalToolService = class {
|
|
|
87
91
|
title: hit.title,
|
|
88
92
|
summary: hit.summary.slice(0, 300)
|
|
89
93
|
})),
|
|
94
|
+
connectionCandidates: connectionCandidates.filter((candidate, index, all) => all.findIndex((item) => item.candidateRef === candidate.candidateRef) === index).slice(0, limit),
|
|
90
95
|
unavailableSources,
|
|
91
96
|
...sourceErrors.length ? { sourceErrors } : {}
|
|
92
97
|
};
|
|
@@ -9,6 +9,14 @@ export interface ExternalToolSearchHit {
|
|
|
9
9
|
title: string;
|
|
10
10
|
summary: string;
|
|
11
11
|
}
|
|
12
|
+
export interface ExternalConnectionCandidate {
|
|
13
|
+
candidateRef: string;
|
|
14
|
+
source: ExternalToolSource;
|
|
15
|
+
label: string;
|
|
16
|
+
summary: string;
|
|
17
|
+
capabilities: string[];
|
|
18
|
+
reason: 'not_connected' | 'reauthorize';
|
|
19
|
+
}
|
|
12
20
|
export interface ExternalToolDescriptor extends ExternalToolSearchHit {
|
|
13
21
|
description: string;
|
|
14
22
|
inputSchema: Record<string, unknown>;
|
|
@@ -32,6 +40,7 @@ export interface ExternalToolTurnContext {
|
|
|
32
40
|
export interface ExternalToolProvider {
|
|
33
41
|
readonly source: ExternalToolSource;
|
|
34
42
|
search(query: string): Promise<ExternalToolSearchHit[]>;
|
|
43
|
+
connectionCandidates?(query: string): Promise<ExternalConnectionCandidate[]>;
|
|
35
44
|
describe(toolRef: string): Promise<ExternalToolDescriptor | undefined>;
|
|
36
45
|
execute(toolRef: string, args: Record<string, unknown>, approvalId: string | undefined, context: ExternalToolExecutionContext): Promise<AgentToolResult<Record<string, unknown>>>;
|
|
37
46
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { AgentPluginStore } from "../../extensions/agent-plugins/store.js";
|
|
1
2
|
import { normalizeConfiguredMcpServers } from "../../config/mcp-config-normalize.js";
|
|
2
3
|
import { inspectExtensionConnectorDependencies } from "../../extensions/connector-dependencies.js";
|
|
4
|
+
import { materializePluginServers } from "../../extensions/agent-plugins/mcp-adapter.js";
|
|
3
5
|
//#region src/agent/mcp/bundle-mcp-config.ts
|
|
4
6
|
function listConfiguredMcpServers(params) {
|
|
5
7
|
const configuredMcp = normalizeConfiguredMcpServers(params.cfg?.mcp?.servers);
|
|
@@ -11,12 +13,42 @@ function listConfiguredMcpServers(params) {
|
|
|
11
13
|
function loadMergedBundleMcpConfig(params) {
|
|
12
14
|
const mapConfiguredServer = params.mapConfiguredServer ?? ((server) => server);
|
|
13
15
|
params.workspaceDir;
|
|
16
|
+
const configured = listConfiguredMcpServers({
|
|
17
|
+
cfg: params.cfg,
|
|
18
|
+
mapConfiguredServer
|
|
19
|
+
});
|
|
20
|
+
const diagnostics = inspectExtensionConnectorDependencies({ cfg: params.cfg });
|
|
21
|
+
for (const id of Object.keys(configured)) if (id.startsWith("plugin/")) {
|
|
22
|
+
delete configured[id];
|
|
23
|
+
diagnostics.push({
|
|
24
|
+
extensionId: "",
|
|
25
|
+
connectorId: id,
|
|
26
|
+
message: "Configured MCP cannot use the reserved plugin/ namespace"
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
const store = new AgentPluginStore();
|
|
30
|
+
const plugins = Object.create(null);
|
|
31
|
+
for (const plugin of store.active()) try {
|
|
32
|
+
const componentDiagnostics = [...plugin.diagnostics];
|
|
33
|
+
for (const [id, server] of Object.entries(materializePluginServers(plugin, store, componentDiagnostics))) plugins[id] = mapConfiguredServer(server, id);
|
|
34
|
+
diagnostics.push(...componentDiagnostics.map((d) => ({
|
|
35
|
+
extensionId: plugin.id,
|
|
36
|
+
connectorId: d.component,
|
|
37
|
+
message: d.message
|
|
38
|
+
})));
|
|
39
|
+
} catch (error) {
|
|
40
|
+
diagnostics.push({
|
|
41
|
+
extensionId: plugin.id,
|
|
42
|
+
connectorId: "mcp",
|
|
43
|
+
message: error instanceof Error ? error.message : String(error)
|
|
44
|
+
});
|
|
45
|
+
}
|
|
14
46
|
return {
|
|
15
|
-
config: { mcpServers: {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
diagnostics
|
|
47
|
+
config: { mcpServers: {
|
|
48
|
+
...configured,
|
|
49
|
+
...plugins
|
|
50
|
+
} },
|
|
51
|
+
diagnostics
|
|
20
52
|
};
|
|
21
53
|
}
|
|
22
54
|
//#endregion
|
|
@@ -29,6 +29,7 @@ export type McpGatewayCapabilitySummary = {
|
|
|
29
29
|
tools: McpGatewayToolEntry[];
|
|
30
30
|
resources: McpGatewayResourceEntry[];
|
|
31
31
|
prompts: McpGatewayPromptEntry[];
|
|
32
|
+
error?: import('./bundle-mcp-types.js').McpServerCatalog['error'];
|
|
32
33
|
};
|
|
33
34
|
export declare function listBundleMcpResourcesForGateway(params: {
|
|
34
35
|
workspaceDir: string;
|
|
@@ -80,6 +80,7 @@ async function listBundleMcpServerCapabilitiesForGateway(params) {
|
|
|
80
80
|
const prompts = mapPrompts(catalog.prompts, params.serverId);
|
|
81
81
|
return {
|
|
82
82
|
serverId: params.serverId,
|
|
83
|
+
error: catalog.servers[params.serverId]?.error,
|
|
83
84
|
toolCount: tools.length,
|
|
84
85
|
resourceCount: resources.length,
|
|
85
86
|
promptCount: prompts.length,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { init_string_coerce, normalizeLowercaseStringOrEmpty } from "../../utils/string-coerce.js";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
2
3
|
//#region src/agent/mcp/bundle-mcp-names.ts
|
|
3
4
|
init_string_coerce();
|
|
4
5
|
const TOOL_NAME_SAFE_RE = /[^A-Za-z0-9_-]/g;
|
|
@@ -9,7 +10,7 @@ function sanitizeToolFragment(raw, fallback, maxChars) {
|
|
|
9
10
|
return normalized.length > maxChars ? normalized.slice(0, maxChars) : normalized;
|
|
10
11
|
}
|
|
11
12
|
function sanitizeServerName(raw, usedNames) {
|
|
12
|
-
const base = sanitizeToolFragment(raw, "mcp", TOOL_NAME_MAX_PREFIX);
|
|
13
|
+
const base = raw.startsWith("plugin/") ? `plugin-${createHash("sha256").update(raw).digest("hex").slice(0, 20)}` : sanitizeToolFragment(raw, "mcp", TOOL_NAME_MAX_PREFIX);
|
|
13
14
|
let candidate = base;
|
|
14
15
|
let n = 2;
|
|
15
16
|
while (usedNames.has(normalizeLowercaseStringOrEmpty(candidate))) {
|
|
@@ -3,9 +3,11 @@ import { init_logger } from "../../utils/logger.js";
|
|
|
3
3
|
import { init_global_singleton, resolveGlobalSingleton } from "../../utils/global-singleton.js";
|
|
4
4
|
import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
|
|
5
5
|
import { resolveConnectorSecretReferences } from "../../connectors/secret-store.js";
|
|
6
|
+
import { recordPluginMcpHealth } from "../../extensions/agent-plugins/health.js";
|
|
6
7
|
import { redactSensitiveUrlLikeString } from "../../utils/redact-sensitive-url.js";
|
|
7
8
|
import { loadEmbeddedMcpConfig } from "./embedded-mcp.js";
|
|
8
9
|
import { isMcpConfigRecord } from "./mcp-config-shared.js";
|
|
10
|
+
import { isMcpAuthorizationError } from "./oauth/mcp-oauth-errors.js";
|
|
9
11
|
import { resolveMcpTransport } from "./mcp-transport.js";
|
|
10
12
|
import { sanitizeServerName } from "./bundle-mcp-names.js";
|
|
11
13
|
import crypto from "node:crypto";
|
|
@@ -176,7 +178,24 @@ function createSessionMcpRuntime(params) {
|
|
|
176
178
|
try {
|
|
177
179
|
for (const [serverName, rawServer] of Object.entries(loaded.mcpServers)) {
|
|
178
180
|
failIfDisposed();
|
|
179
|
-
|
|
181
|
+
let resolved;
|
|
182
|
+
try {
|
|
183
|
+
resolved = await resolveMcpTransport(serverName, await resolveConnectorSecretReferences(rawServer), params.cfg);
|
|
184
|
+
} catch (error) {
|
|
185
|
+
recordPluginMcpHealth(rawServer, "error");
|
|
186
|
+
servers[serverName] = {
|
|
187
|
+
serverName,
|
|
188
|
+
launchSummary: "",
|
|
189
|
+
toolCount: 0,
|
|
190
|
+
resourceCount: 0,
|
|
191
|
+
promptCount: 0,
|
|
192
|
+
error: {
|
|
193
|
+
code: "MCP_CONNECTION_FAILED",
|
|
194
|
+
message: redactErrorUrls(error)
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
180
199
|
if (!resolved) continue;
|
|
181
200
|
const safeServerName = sanitizeServerName(serverName, usedServerNames);
|
|
182
201
|
if (safeServerName !== serverName) log.warn({
|
|
@@ -202,6 +221,7 @@ function createSessionMcpRuntime(params) {
|
|
|
202
221
|
await connectWithTimeout(client, resolved.transport, resolved.connectionTimeoutMs);
|
|
203
222
|
failIfDisposed();
|
|
204
223
|
const listedTools = await listAllTools(client);
|
|
224
|
+
recordPluginMcpHealth(rawServer, "ready");
|
|
205
225
|
const listedResources = await listOptionalMcpCapability({
|
|
206
226
|
serverName,
|
|
207
227
|
capability: "resources",
|
|
@@ -259,6 +279,18 @@ function createSessionMcpRuntime(params) {
|
|
|
259
279
|
});
|
|
260
280
|
}
|
|
261
281
|
} catch (error) {
|
|
282
|
+
servers[serverName] = {
|
|
283
|
+
serverName,
|
|
284
|
+
launchSummary: resolved.description,
|
|
285
|
+
toolCount: 0,
|
|
286
|
+
resourceCount: 0,
|
|
287
|
+
promptCount: 0,
|
|
288
|
+
error: {
|
|
289
|
+
code: isMcpAuthorizationError(error) || error?.code === 401 ? "MCP_AUTHORIZATION_REQUIRED" : "MCP_CONNECTION_FAILED",
|
|
290
|
+
message: redactErrorUrls(error)
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
recordPluginMcpHealth(rawServer, servers[serverName].error?.code === "MCP_AUTHORIZATION_REQUIRED" ? "authorization_required" : "error");
|
|
262
294
|
if (!disposed) log.warn(`bundle-mcp: failed to start server "${serverName}" (${resolved.description}): ${redactErrorUrls(error)}`);
|
|
263
295
|
await disposeSession(session);
|
|
264
296
|
sessions.delete(serverName);
|
|
@@ -7,6 +7,10 @@ export type McpServerCatalog = {
|
|
|
7
7
|
toolCount: number;
|
|
8
8
|
resourceCount: number;
|
|
9
9
|
promptCount: number;
|
|
10
|
+
error?: {
|
|
11
|
+
code: 'MCP_AUTHORIZATION_REQUIRED' | 'MCP_CONNECTION_FAILED';
|
|
12
|
+
message: string;
|
|
13
|
+
};
|
|
10
14
|
};
|
|
11
15
|
export type McpCatalogTool = {
|
|
12
16
|
serverName: string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { mcpToolPolicyId } from "./bundle-mcp-policy.js";
|
|
2
|
+
import { McpOAuthStore, canonicalMcpServerUrl, mcpOAuthServerKey } from "./oauth/mcp-oauth-store.js";
|
|
2
3
|
import { loadMergedBundleMcpConfig } from "./bundle-mcp-config.js";
|
|
3
4
|
import { loadEmbeddedMcpConfig } from "./embedded-mcp.js";
|
|
4
5
|
import { McpAuthorizationRequiredError, isMcpAuthorizationError } from "./oauth/mcp-oauth-errors.js";
|
|
5
|
-
import { McpOAuthStore, canonicalMcpServerUrl, mcpOAuthServerKey } from "./oauth/mcp-oauth-store.js";
|
|
6
6
|
import { XopcMcpOAuthClientProvider } from "./oauth/mcp-oauth-provider.js";
|
|
7
7
|
import { __testing, createSessionMcpRuntime, disposeAllSessionMcpRuntimes, disposeSessionMcpRuntime, getOrCreateSessionMcpRuntime, getSessionMcpRuntimeManager, retireSessionMcpRuntime, retireSessionMcpRuntimeForConversationId } from "./bundle-mcp-runtime.js";
|
|
8
8
|
import "./bundle-mcp-tools.js";
|
|
@@ -6,6 +6,7 @@ export type XopcStdioServerParameters = {
|
|
|
6
6
|
env?: Record<string, string>;
|
|
7
7
|
cwd?: string;
|
|
8
8
|
stderr?: "pipe" | "overlapped" | "inherit" | "ignore";
|
|
9
|
+
pluginDataDir?: string;
|
|
9
10
|
};
|
|
10
11
|
export declare class XopcStdioClientTransport implements Transport {
|
|
11
12
|
private readonly serverParams;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { terminateProcess } from "../../process/kill-tree.js";
|
|
2
|
+
import { containedPath } from "../../extensions/agent-plugins/validation.js";
|
|
2
3
|
import { spawn } from "node:child_process";
|
|
4
|
+
import { mkdir } from "node:fs/promises";
|
|
3
5
|
import { getDefaultEnvironment } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
4
6
|
import process from "node:process";
|
|
5
7
|
import { PassThrough } from "node:stream";
|
|
@@ -24,6 +26,14 @@ var XopcStdioClientTransport = class {
|
|
|
24
26
|
}
|
|
25
27
|
async start() {
|
|
26
28
|
if (this.process) throw new Error("XopcStdioClientTransport already started; Client.connect() starts transports automatically.");
|
|
29
|
+
if (this.serverParams.pluginDataDir) {
|
|
30
|
+
const data = this.serverParams.pluginDataDir;
|
|
31
|
+
await mkdir(data, {
|
|
32
|
+
recursive: true,
|
|
33
|
+
mode: 448
|
|
34
|
+
});
|
|
35
|
+
if (this.serverParams.cwd) containedPath(this.serverParams.cwd.startsWith(data) ? data : this.serverParams.env?.PLUGIN_ROOT ?? data, this.serverParams.cwd);
|
|
36
|
+
}
|
|
27
37
|
await new Promise((resolve, reject) => {
|
|
28
38
|
const baseEnv = {
|
|
29
39
|
...getDefaultEnvironment(),
|