@xopcai/xopc 0.0.427 → 0.0.428
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/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-D_DXNHba.js → activity-store-WqnVruhY.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CjaQxFQt.js → agent-avatar-dicebear-CSiO9c2F.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-display-6Z4m31Fz.js → agent-avatar-display-D-yds6wG.js} +2 -2
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-D4ClP_DJ.js → agent-defaults-settings-panel-_UT9C7bg.js} +1 -1
- package/dist/gateway/static/root/assets/agent-plugin-dialog-DVzYXsAy.js +1 -0
- package/dist/gateway/static/root/assets/{agents-admin-api-u5c3GREg.js → agents-admin-api-Bgv4lJ9Y.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-B9slUA_1.js → agents-yTsbcxRi.js} +3 -3
- package/dist/gateway/static/root/assets/{api-C3Tp9MkF.js → api-C-9J9ghT.js} +1 -1
- package/dist/gateway/static/root/assets/{api-CRT9ZyH0.js → api-Dv6Cn-Rs.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-XqoIBF2H.js → app-management-settings-panel-BXJrrjH5.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-9ZtqCASo.js → appearance-settings-oYjAVulT.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-DUeu_7iC.js → apps-page-D95yzj-f.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-BCQnOkV8.js → archive-plugin-DBPu3xCJ.js} +1 -1
- package/dist/gateway/static/root/assets/automation-api-DAou8Kji.js +1 -0
- package/dist/gateway/static/root/assets/{automation-result-state-CMfVTv_i.js → automation-result-state-CA7LV098.js} +1 -1
- package/dist/gateway/static/root/assets/automation-task-card-w6cKxfaP.js +3 -0
- package/dist/gateway/static/root/assets/{automations-page-DMIyWsP0.js → automations-page-D4LyOLzY.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-BGyvZZj5.js +9 -0
- package/dist/gateway/static/root/assets/{binary-plugins-CIB5cbvQ.js → binary-plugins-D25P9ZxQ.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CXdlNAmZ.js → block-editor-BI105p1U.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automation-inputs-Fxo7HbK6.js → browser-automation-inputs-DhDRvWQE.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-Dn3LN5wo.js → browser-automations-page-CCPi1Bvy.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-control-api-CbbPvhHR.js → browser-control-api-BN4F-bM1.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-Cpm9fEPV.js → browser-settings-page-BZXUZpjp.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-BEvywfF9.js → capabilities-LC-yEQYo.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-page-BCzsIzvC.js → capabilities-page-DHJLl4RD.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-FJ3Vo7Wa.js +8 -0
- package/dist/gateway/static/root/assets/capabilities-u2z_KFRt.js +1 -0
- package/dist/gateway/static/root/assets/{channels-CA5z5dGY.js → channels-9Uaa-IN0.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-agents-api-D8YS5amE.js → chat-agents-api-Cffxfzi1.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-chart-block-B39npsXj.js → chat-chart-block-Bbk0b3TV.js} +1 -1
- package/dist/gateway/static/root/assets/chat-page--dKUIg5W.js +72 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-DjFnElAM.js → chat-terminal-dock-CQMuG-Bz.js} +1 -1
- package/dist/gateway/static/root/assets/{command-palette-api-Dijix7V6.js → command-palette-api-BRxfFgGA.js} +1 -1
- package/dist/gateway/static/root/assets/composer-payload-handoff-_9L2A5AZ.js +1 -0
- package/dist/gateway/static/root/assets/{computer-settings-page-MkqyKyf3.js → computer-settings-page-Bm70SIjD.js} +1 -1
- package/dist/gateway/static/root/assets/{connected-providers-grid-BSvKP2u-.js → connected-providers-grid-B7ktDgqt.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-service-page-DlIl9bLx.js → connector-service-page-BVMEg8n-.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-api-DEJU8mgn.js → connectors-api-B07yoCzk.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-hPKaJUWY.js +1 -0
- package/dist/gateway/static/root/assets/{date-picker-BIfjfOTM.js → date-picker-BvEnSGZK.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-DFNehTtd.js → desktop-pet-C1z9YDEg.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BDjsFown.js → desktop-pet-settings-CbbVb8GY.js} +1 -1
- package/dist/gateway/static/root/assets/{dev-view-store-CeZZLOc6.js → dev-view-store-38EmUIEC.js} +1 -1
- package/dist/gateway/static/root/assets/{device-pairing-wizard-DH_uJ698.js → device-pairing-wizard-Wb1EKiXA.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-DiZXY7jF.js → directory-picker-path-field-BvKDrKc4.js} +1 -1
- package/dist/gateway/static/root/assets/{discussion-annotation-sync-BXqNuZnx.js → discussion-annotation-sync-BfVzIwe2.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-myQqsol2.js → extension-debug-page-CB9Lu3Sq.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-iframe-host-DaL-OcTw.js → extension-iframe-host-BzjrVAUR.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-marketplace-api-DRBszrCR.js → extension-marketplace-api-DigziAgd.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DvlGhZLa.js → extension-page-DUa9MeaZ.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-provider-fOi6V6Cr.js → extension-provider-301x0rh-.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DOGlQpkx.js → extension-settings-page-CP9ciZUI.js} +1 -1
- package/dist/gateway/static/root/assets/{file-preview-surface-DfkXvFnc.js → file-preview-surface-BaMGmCbw.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-BOCt_zOo.js → gateway-config-swr-BD4Bf8uu.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-realtime-BL_Cf0OQ.js → gateway-realtime-CSd9VB7Z.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-Bxkv62qs.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-restart-CHf8qY7H.js → gateway-restart-CIUCTKYR.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-Di41peSM.js → gateway-settings-CCqF1uZv.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-CvkJYurV.js → gateway-startup-retry-BsU5k8oi.js} +1 -1
- package/dist/gateway/static/root/assets/{global-defaults-api-BWMbKu72.js → global-defaults-api-asOZQeM8.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-Bb_RC1O9.js +2 -0
- package/dist/gateway/static/root/assets/{image-generation-api-Ce-IY7Ug.js → image-generation-api-BbEnKsK1.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-W7_cDbxy.js → imports-page-CVnoGUyp.js} +1 -1
- package/dist/gateway/static/root/assets/index-ClPeYgQk.js +11 -0
- package/dist/gateway/static/root/assets/index-Cz-VjTNd.css +1 -0
- package/dist/gateway/static/root/assets/{install-connector-dialog-DWVl9ekV.js → install-connector-dialog-DXVOHMhS.js} +1 -1
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-Doyu0Q9e.js → keyboard-shortcuts-settings-BCl90SrD.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-B3h3P6aI.js → local-app-workbench-page-CcJc9xLJ.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-D6D2bZGW.js → local-apps-page-CdAKoWfg.js} +1 -1
- package/dist/gateway/static/root/assets/{local-session-drafts-BJ1B1dQ7.js → local-session-drafts-nRGeybku.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-Br7IfbXK.js → locale-store-B7y-RVe8.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-qiXos_12.js → logs-page-McbSQwJI.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-C0WcSdK7.js → management-settings-BIR0BwNV.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-Ck5s16p9.js → markdown-view-DFHa8rUg.js} +1 -1
- package/dist/gateway/static/root/assets/mcp-conversation-setup-page-Dwx4TuIr.js +1 -0
- package/dist/gateway/static/root/assets/{media-plugins-Ba6vUE4J.js → media-plugins-BzzLV7wW.js} +1 -1
- package/dist/gateway/static/root/assets/messages-DYDkJvXj.js +3 -0
- package/dist/gateway/static/root/assets/{model-selector-DCBmsHzj.js → model-selector-DJSVr3LM.js} +1 -1
- package/dist/gateway/static/root/assets/{models-hub-cache-Bd-fYUrV.js → models-hub-cache-BUapaPTN.js} +1 -1
- package/dist/gateway/static/root/assets/new-chat-navigation-B6NPQ4h4.js +1 -0
- package/dist/gateway/static/root/assets/{note-detail-panel-CnuxqWMd.js → note-detail-panel-CJ-dPovd.js} +3 -3
- package/dist/gateway/static/root/assets/note-image-lightbox-ClPkeHe5.js +1 -0
- package/dist/gateway/static/root/assets/{notes-api-8kp0X1x6.js → notes-api-ulup1oFS.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-XMdy-H3H.js → notes-page-BaFNplIr.js} +1 -1
- package/dist/gateway/static/root/assets/{oauth-api-DMMdeaNd.js → oauth-api-DINa08-z.js} +1 -1
- package/dist/gateway/static/root/assets/{oauth-provider-connect-CfOK8mPM.js → oauth-provider-connect-C0PVEHC2.js} +1 -1
- package/dist/gateway/static/root/assets/{page-context-capture-button-CKlKWSJ7.js → page-context-capture-button-CGfR0dsc.js} +1 -1
- package/dist/gateway/static/root/assets/{page-context-draft-LF33STHC.js → page-context-draft-DhRNxc0v.js} +1 -1
- package/dist/gateway/static/root/assets/page-header-store-CoKMiYoi.js +1 -0
- package/dist/gateway/static/root/assets/{personal-avatar-D6CzIIfo.js → personal-avatar-DiVFO2Aw.js} +1 -1
- package/dist/gateway/static/root/assets/{personal-page-CIMMSI25.js → personal-page-CiKdXLeR.js} +1 -1
- package/dist/gateway/static/root/assets/{personal-settings-panel-wKdlrfPq.js → personal-settings-panel-Ds4ntiqu.js} +1 -1
- package/dist/gateway/static/root/assets/{phone-dependencies-card-CDhk5277.js → phone-dependencies-card-B3R6L5Qu.js} +1 -1
- package/dist/gateway/static/root/assets/{phone-model-connection-DZ-ZunPz.js → phone-model-connection-ucX3Tvl8.js} +1 -1
- package/dist/gateway/static/root/assets/{phone-model-picker-DuZc5jYO.js → phone-model-picker-CU37sziM.js} +1 -1
- package/dist/gateway/static/root/assets/{phone-settings-page-0u0GQl_R.js → phone-settings-page-BSdB2pnW.js} +1 -1
- package/dist/gateway/static/root/assets/{phone-workspace-store-SN7hfddU.js → phone-workspace-store-Cmes9gQ4.js} +1 -1
- package/dist/gateway/static/root/assets/{plugin-details-dialog-Bfc-Wmrd.js → plugin-details-dialog-DblFhnuC.js} +1 -1
- package/dist/gateway/static/root/assets/{preference-select-fields-BKeHZLXZ.js → preference-select-fields-D2-QfMN5.js} +1 -1
- package/dist/gateway/static/root/assets/{product-automation-feedback-BPur0vyo.js → product-automation-feedback-BzY3z8zu.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-Bfd7R483.js → product-open-page-BKw6H0Mn.js} +1 -1
- package/dist/gateway/static/root/assets/{product-preview-content-Bnq68oVw.js → product-preview-content-CNaJb6Bj.js} +1 -1
- package/dist/gateway/static/root/assets/{product-preview-modal-BPmTeweh.js → product-preview-modal-DgwrrpqJ.js} +2 -2
- package/dist/gateway/static/root/assets/project-detail-page-FReFYUv0.js +7 -0
- package/dist/gateway/static/root/assets/{project-understanding-DLvxAoTT.js → project-understanding-CrSkrJnM.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-BGy1pw9a.js → projects-page-Cp91_KzA.js} +1 -1
- package/dist/gateway/static/root/assets/{providers-api-DOnNfkwQ.js → providers-api-CBSC3jdu.js} +1 -1
- package/dist/gateway/static/root/assets/{recording-upload-CHFJbqW1.js → recording-upload-DBHAGKZj.js} +1 -1
- package/dist/gateway/static/root/assets/{registry-api-DFDvOTg4.js → registry-api-QZEjziDq.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-BVqwnOqO.js → remote-access-hub-BdXxFQfH.js} +1 -1
- package/dist/gateway/static/root/assets/{resource-unavailable-TQcRCpAg.js → resource-unavailable-BTNhcOHF.js} +1 -1
- package/dist/gateway/static/root/assets/route-preload-DS4fVFbc.js +2 -0
- package/dist/gateway/static/root/assets/{runtime-tools-api-9o3Wfji1.js → runtime-tools-api-BDTUD8Rj.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-ccVBG-bZ.js → runtime-tools-settings-panel-CYEzIrDf.js} +1 -1
- package/dist/gateway/static/root/assets/{service-recommendation-list-CNghOavt.js → service-recommendation-list-CfeYH6lK.js} +1 -1
- package/dist/gateway/static/root/assets/{session-api-Bs3r_d2_.js → session-api-DVXLCZX2.js} +1 -1
- package/dist/gateway/static/root/assets/{session-manager-Bnq3qpqy.js → session-manager-DjRWxXJG.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-CyBj1Xw2.js → sessions-page-C8gwrFHR.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-BMHe9uwy.js +1 -0
- package/dist/gateway/static/root/assets/{settings-advanced-section-DwpPPxT0.js → settings-advanced-section-BmrbHgQa.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-mode-store-CiRpsdTJ.js → settings-mode-store-Bk_hzwPK.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-Cd8Ermnn.js → settings-page-DCQnHCNN.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-header-BZl4AMiN.js → settings-page-header-BLKI3_9N.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-onhEgq-K.js → settings-page-layout-BqBVrkC9.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-interaction-page-Cvvj6JyV.js → setup-interaction-page-B9ACeAvO.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-D4qgE7QM.js → setup-status-panel-DEefuWo3.js} +1 -1
- package/dist/gateway/static/root/assets/{share-link-dialog-DA0QuFOD.js → share-link-dialog-C2LyeNzj.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-YDpIY4dC.js → share-preview-page-BFwEr7Ws.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-api-D8Q-m46d.js → shares-api-CTFkLQxq.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-DUvjOMmA.js → shares-settings-CpK3yhtc.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-api-uKU4sRiv.js → skill-api-DpicfA6o.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-list-api-BzKzG-xG.js → skill-list-api-B8fegRLZ.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-reload-api-DkUXekcd.js → skill-reload-api-VmC8ySUy.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-ClyNSh-7.js → skills-page-BIWXS6Ki.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BN6sUX0H.js → system-settings-panel-BmoA92oX.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-L5RIelv0.js +3 -0
- package/dist/gateway/static/root/assets/{task-result-evidence-DKygspo2.js → task-result-evidence-BV-6hBVU.js} +1 -1
- package/dist/gateway/static/root/assets/{terminal-panel-store-DJVC7HqA.js → terminal-panel-store-BGdKE9hU.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-Dlnmgryi.js → theme-store-Dvv79Wb2.js} +1 -1
- package/dist/gateway/static/root/assets/{tracing-settings-page-Bs76WeoF.js → tracing-settings-page-B4uA4Pnz.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-B7nx0NQJ.js → tunnel-api-BurZtvqx.js} +1 -1
- package/dist/gateway/static/root/assets/{understanding-activity-store-C4bblRnQ.js → understanding-activity-store-C1cLL8zq.js} +1 -1
- package/dist/gateway/static/root/assets/{understanding-refresh-store-BvCj9-Ue.js → understanding-refresh-store-C3Lr_pjY.js} +1 -1
- package/dist/gateway/static/root/assets/{usage-page-anU5gslJ.js → usage-page-C91ZzLm9.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-YHxQ-UZg.js → use-autosave-zkzRuUtx.js} +1 -1
- package/dist/gateway/static/root/assets/{use-composer-attachments-DYY3Yz4a.js → use-composer-attachments-CoiQAgjo.js} +1 -1
- package/dist/gateway/static/root/assets/{use-file-preview-expanded-CYgWzDnv.js → use-file-preview-expanded-DFzy6iVy.js} +2 -2
- package/dist/gateway/static/root/assets/{use-personal-profile-D2Un8G1L.js → use-personal-profile-BB10h9ED.js} +1 -1
- package/dist/gateway/static/root/assets/{use-workspace-tree-Dkg9tUr4.js → use-workspace-tree-sF5DcONt.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-WFnD5utO.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-BUes-Jlp.js → voice-api-key-field-Bqa4PeZx.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-CrULrSKC.js → voice-config-api-LNO2xXHk.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-input-shortcut-events-DFMNIyy4.js → voice-input-shortcut-events-AzfhxBX7.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-transcribe-api-Dy4hfftb.js → voice-transcribe-api-Cb8i6dLb.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-CFF4cRFl.js → work-discovery-overlay-CdQUiV-a.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-page-BnYaVH3V.js → work-discovery-page-HcUloXxf.js} +1 -1
- package/dist/gateway/static/root/assets/{working-directory-picker-modal-GFwVefVA.js → working-directory-picker-modal-Dv1HUipe.js} +1 -1
- package/dist/gateway/static/root/assets/{workspace-api-BdB4NEOh.js → workspace-api-Am2ee4R6.js} +2 -2
- package/dist/gateway/static/root/assets/workspace-editor-agent-store-CqHcVFhS.js +1 -0
- package/dist/gateway/static/root/assets/{workspace-file-preview-dialog-NRL3YRjg.js → workspace-file-preview-dialog-z5Q00v92.js} +1 -1
- package/dist/gateway/static/root/assets/{workspace-open-location-menu-Dcij7wvJ.js → workspace-open-location-menu-4ONYaGy0.js} +1 -1
- package/dist/gateway/static/root/assets/xopc-cloud-account-card-DimGN59n.js +1 -0
- package/dist/gateway/static/root/index.html +80 -80
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/automations.js +1 -0
- package/dist/packages/gateway-contract/src/capabilities.js +6 -2
- package/dist/packages/gateway-contract/src/home.js +12 -2
- package/dist/src/agent/background-review/prompts.js +11 -6
- package/dist/src/agent/background-review/run-background-review.js +12 -3
- package/dist/src/agent/context/execution-context.js +3 -1
- package/dist/src/agent/embedded/configuration-capability-correction.js +1 -1
- package/dist/src/agent/embedded/run-turn.js +12 -1
- package/dist/src/agent/embedded/session-runner.js +4 -0
- package/dist/src/agent/mcp/connection-drafts.d.ts +2 -1
- package/dist/src/agent/mcp/connection-drafts.js +3 -2
- package/dist/src/agent/mcp/connection-setup.d.ts +15 -1
- package/dist/src/agent/mcp/connection-setup.js +219 -106
- package/dist/src/agent/mcp/continuation-guard.d.ts +3 -0
- package/dist/src/agent/mcp/continuation-guard.js +54 -0
- package/dist/src/agent/mcp/continuation-input.d.ts +4 -0
- package/dist/src/agent/mcp/continuation-input.js +13 -0
- package/dist/src/agent/mcp/conversation-setup.d.ts +121 -2
- package/dist/src/agent/mcp/conversation-setup.js +274 -39
- package/dist/src/agent/mcp/discovery.d.ts +102 -0
- package/dist/src/agent/mcp/discovery.js +219 -0
- package/dist/src/agent/mcp/native-mcp.js +8 -1
- package/dist/src/agent/mcp/setup-plan.d.ts +76 -0
- package/dist/src/agent/mcp/setup-plan.js +93 -0
- package/dist/src/agent/mcp/tool-catalog.d.ts +2 -0
- package/dist/src/agent/mcp/tool-catalog.js +7 -1
- package/dist/src/agent/mcp/transport.d.ts +20 -0
- package/dist/src/agent/mcp/transport.js +188 -0
- package/dist/src/agent/orchestration/delegation-scope.d.ts +2 -1
- package/dist/src/agent/prompt/conversational-configuration-guide.js +1 -1
- package/dist/src/agent/service/direct-turn-helpers.js +2 -1
- package/dist/src/agent/service/process-direct-streaming.js +2 -1
- package/dist/src/agent/service.js +5 -1
- package/dist/src/agent/tool-manuals/xopc-configuration.d.ts +2 -2
- package/dist/src/agent/tool-manuals/xopc-configuration.js +37 -4
- package/dist/src/agent/tools/factory.js +1 -1
- package/dist/src/agent/tools/mcp-setup-tool.js +6 -2
- package/dist/src/agent/tools/xopc-use-tool.d.ts +1 -0
- package/dist/src/agent/tools/xopc-use-tool.js +21 -0
- package/dist/src/automations/api/routes.js +13 -5
- package/dist/src/automations/capabilities/read.js +31 -3
- package/dist/src/automations/domain/types.d.ts +2 -0
- package/dist/src/automations/service/automation-service.d.ts +7 -0
- package/dist/src/automations/service/automation-service.js +9 -2
- package/dist/src/automations/storage/automation-run-repository.d.ts +11 -2
- package/dist/src/automations/storage/automation-run-repository.js +28 -24
- package/dist/src/automations/storage/index.js +2 -2
- package/dist/src/config/schema.d.ts +3 -0
- package/dist/src/config/schema.js +3 -2
- package/dist/src/extensions/agent-plugins/setup.d.ts +1 -0
- package/dist/src/extensions/agent-plugins/setup.js +1 -0
- package/dist/src/gateway/hono/routes/mcp.js +1 -1
- package/dist/src/gateway/hono/routes/tasks.js +0 -4
- package/dist/src/gateway/service/config-coordinator.d.ts +1 -1
- package/dist/src/gateway/service.js +9 -8
- package/dist/src/home-intelligence/evidence-presentation.d.ts +3 -0
- package/dist/src/home-intelligence/evidence-presentation.js +30 -0
- package/dist/src/home-intelligence/generator.d.ts +8 -0
- package/dist/src/home-intelligence/generator.js +15 -4
- package/dist/src/home-intelligence/policy.js +3 -0
- package/dist/src/memory-learning/repository.d.ts +6 -1
- package/dist/src/memory-learning/repository.js +10 -5
- package/dist/src/memory-learning/service.js +23 -1
- package/dist/src/process/mcp-stdio-supervisor.d.ts +1 -0
- package/dist/src/process/mcp-stdio-supervisor.js +14 -0
- package/dist/src/tasks/task-criterion-review-repository.js +1 -1
- package/dist/src/tui/tui.js +1 -1
- package/dist/src/user-context/extraction/registry.js +2 -2
- package/dist/src/user-model/capture/executor.d.ts +1 -0
- package/dist/src/user-model/capture/executor.js +6 -6
- package/dist/src/user-model/capture/semantic.d.ts +3 -0
- package/dist/src/user-model/capture/semantic.js +14 -4
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/agent-plugin-dialog-m1A8wF9p.js +0 -1
- package/dist/gateway/static/root/assets/automation-api-hRsGx-qe.js +0 -1
- package/dist/gateway/static/root/assets/automation-task-card-Bur78p68.js +0 -3
- package/dist/gateway/static/root/assets/automations-workspace-DEkDjxeU.js +0 -9
- package/dist/gateway/static/root/assets/capabilities-Bo2qEJhH.js +0 -1
- package/dist/gateway/static/root/assets/capabilities-settings-panel-Cr67ziwX.js +0 -8
- package/dist/gateway/static/root/assets/chat-page-D92AWJbh.js +0 -72
- package/dist/gateway/static/root/assets/composer-payload-handoff-BQXlFKf4.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-Vx8-MY0Y.js +0 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-BHBOPF_q.js +0 -1
- package/dist/gateway/static/root/assets/home-page-B3sgqrl3.js +0 -2
- package/dist/gateway/static/root/assets/index-D4B6O8B3.js +0 -11
- package/dist/gateway/static/root/assets/index-DGWBJDAM.css +0 -1
- package/dist/gateway/static/root/assets/mcp-conversation-setup-page-CENs3hGU.js +0 -1
- package/dist/gateway/static/root/assets/messages-ByFlEbsu.js +0 -3
- package/dist/gateway/static/root/assets/note-image-lightbox-BFKZ7qJr.js +0 -1
- package/dist/gateway/static/root/assets/page-header-store-Du44NIEJ.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-D9nnyvrI.js +0 -7
- package/dist/gateway/static/root/assets/route-preload-DI43HQV_.js +0 -2
- package/dist/gateway/static/root/assets/send-1f1Ntw6E.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-BI4DMz4_.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-CS9m7Ipo.js +0 -2
- package/dist/gateway/static/root/assets/user-model-page-DIgPL3tN.js +0 -2
- package/dist/gateway/static/root/assets/workspace-editor-agent-store-4cZ26iaD.js +0 -1
- package/dist/gateway/static/root/assets/xopc-cloud-account-card-DC9aG7Pl.js +0 -1
|
@@ -5,6 +5,7 @@ import { deferredToolContract, getXopcToolMetadata } from "./tool-metadata.js";
|
|
|
5
5
|
import { isCodemodeCoreRead } from "../tools/codemode-permissions.js";
|
|
6
6
|
import { createEmbeddedModelRuntime, resolveEmbeddedProviderApiKeySync } from "./model-runtime.js";
|
|
7
7
|
import { getNativePiAgentDir } from "../mcp/native-mcp.js";
|
|
8
|
+
import { createXopcMcpTransport } from "../mcp/transport.js";
|
|
8
9
|
import { createAutomationMcpSourceGuard } from "../../automations/mcp-source.js";
|
|
9
10
|
import { createXopcCodemodeExtension } from "./codemode-extension.js";
|
|
10
11
|
import { abortEmbeddedRun } from "./runs.js";
|
|
@@ -13,6 +14,7 @@ import { transformUserMessageForPersistence } from "../inbound/attachment-pipeli
|
|
|
13
14
|
import { wrapStreamFnForXopcExtensions } from "./xopc-stream-bridge.js";
|
|
14
15
|
import { xopcToolsToDefinitions } from "./xopc-tools-bridge.js";
|
|
15
16
|
import { TOOL_DISCOVERY_STATE, createXopcToolSearchExtension } from "./tool-search-extension.js";
|
|
17
|
+
import { createMcpSetupContinuationGuard } from "../mcp/continuation-guard.js";
|
|
16
18
|
import { AGENT_PROFILE_CONTEXT_STATE, createAgentProfileContextExtension } from "./agent-profile-context.js";
|
|
17
19
|
import { join } from "node:path";
|
|
18
20
|
import { createHash } from "node:crypto";
|
|
@@ -286,10 +288,12 @@ var EmbeddedSessionRunnerPool = class {
|
|
|
286
288
|
noContextFiles: true,
|
|
287
289
|
noExtensions: true,
|
|
288
290
|
extensionFactories: [
|
|
291
|
+
createMcpSetupContinuationGuard(runtimeId, tools.some((tool) => tool.name === "mcp_setup")),
|
|
289
292
|
...mcp?.automationSourceRunId ? [createAutomationMcpSourceGuard(mcp.automationSourceRunId)] : [],
|
|
290
293
|
...codemode ? [createXopcCodemodeExtension(codemode, tools, () => boundSession)] : [],
|
|
291
294
|
...discovery ? [createXopcToolSearchExtension(tools)] : [],
|
|
292
295
|
...mcp ? [createMcpExtension({
|
|
296
|
+
createTransport: createXopcMcpTransport(),
|
|
293
297
|
loadConfig: () => mcp,
|
|
294
298
|
credentials: mcp.credentials,
|
|
295
299
|
logPath: join(getNativePiAgentDir(), "mcp.log")
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Config } from '../../config/schema.js';
|
|
2
2
|
import { type McpConnectionProbe } from './connection-setup.js';
|
|
3
|
+
import type { McpTransportDiagnostics } from './transport.js';
|
|
3
4
|
export declare function mcpConfigRevision(value: unknown): string;
|
|
4
5
|
export declare class McpDraftError extends Error {
|
|
5
6
|
readonly status: 400 | 404 | 409 | 429 | 500;
|
|
@@ -30,7 +31,7 @@ export declare class McpConnectionDrafts {
|
|
|
30
31
|
serverId: string;
|
|
31
32
|
expiresAt: number;
|
|
32
33
|
}>;
|
|
33
|
-
probe(owner: string, id: string): Promise<McpConnectionProbe>;
|
|
34
|
+
probe(owner: string, id: string, diagnostics?: McpTransportDiagnostics): Promise<McpConnectionProbe>;
|
|
34
35
|
authorize(owner: string, id: string, options?: {
|
|
35
36
|
callbackRelayUrl?: string;
|
|
36
37
|
}): import("./connection-setup.js").McpAuthorization;
|
|
@@ -84,7 +84,7 @@ var McpConnectionDrafts = class {
|
|
|
84
84
|
expiresAt: draft.expiresAt
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
|
-
async probe(owner, id) {
|
|
87
|
+
async probe(owner, id, diagnostics) {
|
|
88
88
|
const draft = this.get(owner, id);
|
|
89
89
|
this.assertIdle(draft);
|
|
90
90
|
draft.authorizationId = void 0;
|
|
@@ -94,7 +94,8 @@ var McpConnectionDrafts = class {
|
|
|
94
94
|
try {
|
|
95
95
|
const result = await probeMcpConnection(draft.config, draft.workspace, draft.serverId, {
|
|
96
96
|
credentials: draft.credentials,
|
|
97
|
-
signal: draft.controller.signal
|
|
97
|
+
signal: draft.controller.signal,
|
|
98
|
+
diagnostics
|
|
98
99
|
});
|
|
99
100
|
this.get(owner, id);
|
|
100
101
|
draft.probe = result;
|
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import type { Config } from '../../config/schema.js';
|
|
2
2
|
import { type McpConnectionErrorCode } from './connection-errors.js';
|
|
3
3
|
import { type McpSessionOptions } from './tool-catalog.js';
|
|
4
|
+
import { type McpObservation } from './transport.js';
|
|
5
|
+
export type McpMetadataState = 'valid' | 'absent' | 'unreachable' | 'invalid' | 'not_checked';
|
|
6
|
+
export type McpRecovery = {
|
|
7
|
+
kind: 'choose_auth' | 'enter_secret' | 'authorize' | 'verify_documented_endpoint' | 'report_blocker' | 'wait';
|
|
8
|
+
retryAt?: number;
|
|
9
|
+
reason?: string;
|
|
10
|
+
};
|
|
4
11
|
export type McpConnectionProbe = {
|
|
5
|
-
state: 'connected' | 'oauth_required' | 'token_required' | 'error';
|
|
12
|
+
state: 'connected' | 'oauth_required' | 'token_required' | 'auth_unknown' | 'error';
|
|
6
13
|
toolCount?: number;
|
|
7
14
|
error?: string;
|
|
8
15
|
errorCode?: McpConnectionErrorCode;
|
|
16
|
+
auth?: {
|
|
17
|
+
method: 'oauth' | 'unknown' | 'credential';
|
|
18
|
+
metadata: McpMetadataState;
|
|
19
|
+
credential: 'missing' | 'present' | 'rejected' | 'unknown';
|
|
20
|
+
};
|
|
21
|
+
observation?: Omit<McpObservation, 'challenge'>;
|
|
22
|
+
recovery?: McpRecovery;
|
|
9
23
|
};
|
|
10
24
|
export declare function probeMcpConnection(config: Config, workspace: string, serverId: string, options?: McpSessionOptions): Promise<McpConnectionProbe>;
|
|
11
25
|
export type McpAuthorization = {
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { checkUrlSafety } from "../tools/url-safety.js";
|
|
3
4
|
import { isManagedConnectorServer } from "../../connectors/materialize.js";
|
|
4
5
|
import { resolveMcpSetupConfig } from "./effective-server.js";
|
|
5
6
|
import { prepareNativeMcpConfig } from "./native-mcp.js";
|
|
7
|
+
import { retryAfter } from "./transport.js";
|
|
6
8
|
import { McpAuthenticationRequiredError, discoverMcpTools, signInNativeMcp } from "./tool-catalog.js";
|
|
7
9
|
import { classifyMcpConnectionError } from "./connection-errors.js";
|
|
8
10
|
import { createHash, randomUUID } from "node:crypto";
|
|
11
|
+
import { lookup } from "node:dns";
|
|
12
|
+
import { Agent } from "undici";
|
|
9
13
|
//#region src/agent/mcp/connection-setup.ts
|
|
10
14
|
init_logger();
|
|
11
15
|
const log = createLogger("McpConnectionSetup");
|
|
@@ -14,138 +18,247 @@ function httpUrl(value) {
|
|
|
14
18
|
if (!["http:", "https:"].includes(url.protocol) || url.username || url.password) throw new Error("Use an HTTP or HTTPS MCP address without embedded credentials.");
|
|
15
19
|
return url;
|
|
16
20
|
}
|
|
17
|
-
async function metadata(url, signal) {
|
|
21
|
+
async function metadata(url, endpoint, signal, publicOnly = false) {
|
|
22
|
+
const sameOrigin = endpoint.origin === url.origin && !publicOnly;
|
|
23
|
+
if (!sameOrigin && !checkUrlSafety(url.href).safe) return { state: "invalid" };
|
|
24
|
+
const dispatcher = new Agent({ connect: { lookup(host, options, callback) {
|
|
25
|
+
lookup(host, { all: true }, (error, addresses) => {
|
|
26
|
+
if (error) {
|
|
27
|
+
callback(error, "", 4);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (!sameOrigin && addresses.some((a) => !checkUrlSafety(`http://${a.family === 6 ? `[${a.address}]` : a.address}`).safe)) {
|
|
31
|
+
callback(/* @__PURE__ */ new Error("Non-public authorization metadata destination"), "", 4);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (options.all) callback(null, addresses);
|
|
35
|
+
else if (addresses[0]) callback(null, addresses[0].address, addresses[0].family);
|
|
36
|
+
else callback(/* @__PURE__ */ new Error("No metadata address"), "", 4);
|
|
37
|
+
});
|
|
38
|
+
} } });
|
|
18
39
|
try {
|
|
19
40
|
const response = await fetch(url, {
|
|
20
41
|
signal: signal ? AbortSignal.any([signal, AbortSignal.timeout(5e3)]) : AbortSignal.timeout(5e3),
|
|
21
42
|
redirect: "error",
|
|
22
|
-
headers: { Accept: "application/json" }
|
|
43
|
+
headers: { Accept: "application/json" },
|
|
44
|
+
dispatcher
|
|
23
45
|
});
|
|
24
|
-
if (!response.ok)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
await response.body?.cancel();
|
|
48
|
+
return {
|
|
49
|
+
retryAt: response.status === 429 || response.status === 503 ? retryAfter(response.headers.get("Retry-After")) ?? Date.now() + 2e3 : void 0,
|
|
50
|
+
state: response.status === 404 || response.status === 410 ? "absent" : response.status >= 500 || response.status === 429 ? "unreachable" : "invalid"
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const reader = response.body?.getReader();
|
|
54
|
+
if (!reader) return { state: "invalid" };
|
|
55
|
+
const decoder = new TextDecoder();
|
|
56
|
+
let text = "", bytes = 0;
|
|
57
|
+
try {
|
|
58
|
+
for (;;) {
|
|
59
|
+
const chunk = await reader.read();
|
|
60
|
+
if (chunk.done) break;
|
|
61
|
+
bytes += chunk.value.byteLength;
|
|
62
|
+
if (bytes > 1e5) return { state: "invalid" };
|
|
63
|
+
text += decoder.decode(chunk.value, { stream: true });
|
|
64
|
+
}
|
|
65
|
+
text += decoder.decode();
|
|
66
|
+
} finally {
|
|
67
|
+
await reader.cancel().catch(() => {});
|
|
68
|
+
reader.releaseLock();
|
|
69
|
+
}
|
|
70
|
+
const data = JSON.parse(text);
|
|
71
|
+
return data && typeof data === "object" && !Array.isArray(data) ? {
|
|
72
|
+
state: "valid",
|
|
73
|
+
data
|
|
74
|
+
} : { state: "invalid" };
|
|
75
|
+
} catch (error) {
|
|
28
76
|
signal?.throwIfAborted();
|
|
77
|
+
return { state: error instanceof SyntaxError ? "invalid" : "unreachable" };
|
|
78
|
+
} finally {
|
|
79
|
+
await dispatcher.close();
|
|
29
80
|
}
|
|
30
81
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (!entry || !("url" in entry.config)) return false;
|
|
82
|
+
async function authentication(config, workspace, serverId, challenge, options) {
|
|
83
|
+
const entry = (await prepareNativeMcpConfig(config, workspace)).servers.find((s) => s.name === serverId);
|
|
84
|
+
if (!entry || !("url" in entry.config)) return {
|
|
85
|
+
method: "unknown",
|
|
86
|
+
metadata: "not_checked"
|
|
87
|
+
};
|
|
38
88
|
const url = httpUrl(entry.config.url);
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
capabilities: {},
|
|
56
|
-
clientInfo: {
|
|
57
|
-
name: "xopc",
|
|
58
|
-
version: "1"
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
})
|
|
62
|
-
});
|
|
63
|
-
const challenge = response.headers.get("WWW-Authenticate") ?? "";
|
|
64
|
-
await response.body?.cancel();
|
|
65
|
-
const resourceMetadata = /resource_metadata\s*=\s*"([^"\s]+)"/i.exec(challenge)?.[1];
|
|
89
|
+
const publicOnly = config.mcp?.servers?.[serverId]?.xopcPublicOnly === true;
|
|
90
|
+
const allowedIssuer = (value) => {
|
|
91
|
+
try {
|
|
92
|
+
if (typeof value !== "string") return false;
|
|
93
|
+
const issuer = httpUrl(value);
|
|
94
|
+
return issuer.protocol === "https:" && checkUrlSafety(issuer.href).safe || !publicOnly && issuer.origin === url.origin && [
|
|
95
|
+
"localhost",
|
|
96
|
+
"127.0.0.1",
|
|
97
|
+
"[::1]"
|
|
98
|
+
].includes(issuer.hostname);
|
|
99
|
+
} catch {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
challenge ??= "";
|
|
104
|
+
const reference = /resource_metadata\s*=\s*"([^"\s]+)"/i.exec(challenge)?.[1];
|
|
66
105
|
const candidates = [
|
|
67
|
-
...
|
|
106
|
+
...reference ? [httpUrl(reference)] : [],
|
|
68
107
|
new URL(`/.well-known/oauth-protected-resource${url.pathname === "/" ? "" : url.pathname}`, url),
|
|
69
108
|
new URL("/.well-known/oauth-protected-resource", url)
|
|
70
109
|
];
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
110
|
+
let state = "absent";
|
|
111
|
+
for (const candidate of [...new Map(candidates.map((c) => [c.href, c])).values()]) {
|
|
112
|
+
options?.signal?.throwIfAborted();
|
|
113
|
+
options?.diagnostics?.beforeRequest?.({
|
|
114
|
+
method: "GET",
|
|
115
|
+
stage: "authorization_metadata"
|
|
116
|
+
});
|
|
117
|
+
const result = await metadata(candidate, url, options?.signal, publicOnly);
|
|
118
|
+
if (result.retryAt) return {
|
|
119
|
+
method: "unknown",
|
|
120
|
+
metadata: result.state,
|
|
121
|
+
retryAt: result.retryAt
|
|
122
|
+
};
|
|
123
|
+
if (result.state !== "absent") state = result.state;
|
|
124
|
+
const data = result.data;
|
|
125
|
+
if (data && typeof data.resource === "string" && data.resource === url.href && Array.isArray(data.authorization_servers) && data.authorization_servers.some(allowedIssuer)) return {
|
|
126
|
+
method: "oauth",
|
|
127
|
+
metadata: "valid"
|
|
128
|
+
};
|
|
129
|
+
if (data) state = "invalid";
|
|
81
130
|
}
|
|
82
|
-
if (
|
|
83
|
-
|
|
84
|
-
|
|
131
|
+
if (/\bBearer\b/i.test(challenge)) {
|
|
132
|
+
options?.diagnostics?.beforeRequest?.({
|
|
133
|
+
method: "GET",
|
|
134
|
+
stage: "authorization_metadata"
|
|
135
|
+
});
|
|
136
|
+
const result = await metadata(new URL("/.well-known/oauth-authorization-server", url), url, options?.signal, publicOnly);
|
|
137
|
+
if (result.retryAt) return {
|
|
138
|
+
method: "unknown",
|
|
139
|
+
metadata: result.state,
|
|
140
|
+
retryAt: result.retryAt
|
|
141
|
+
};
|
|
142
|
+
const data = result.data;
|
|
143
|
+
if (data && data.issuer === url.origin && allowedIssuer(data.issuer) && typeof data.authorization_endpoint === "string" && typeof data.token_endpoint === "string" && allowedIssuer(data.authorization_endpoint) && allowedIssuer(data.token_endpoint)) return {
|
|
144
|
+
method: "oauth",
|
|
145
|
+
metadata: "valid"
|
|
146
|
+
};
|
|
147
|
+
if (result.state !== "absent") state = result.data ? "invalid" : result.state;
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
method: "unknown",
|
|
151
|
+
metadata: state
|
|
152
|
+
};
|
|
85
153
|
}
|
|
86
154
|
async function probeMcpConnection(config, workspace, serverId, options) {
|
|
87
155
|
config = resolveMcpSetupConfig(config, serverId);
|
|
156
|
+
const observations = [];
|
|
157
|
+
let cooldown = 0, requests = 0;
|
|
88
158
|
try {
|
|
89
159
|
return {
|
|
90
160
|
state: "connected",
|
|
91
|
-
toolCount: (await discoverMcpTools(config, workspace, serverId,
|
|
161
|
+
toolCount: (await discoverMcpTools(config, workspace, serverId, {
|
|
162
|
+
...options,
|
|
163
|
+
diagnostics: {
|
|
164
|
+
...options?.diagnostics,
|
|
165
|
+
probe: true,
|
|
166
|
+
beforeRequest: (request) => {
|
|
167
|
+
options?.signal?.throwIfAborted();
|
|
168
|
+
if (Date.now() < cooldown || requests >= 16) throw new Error("MCP probe request budget or cooldown reached");
|
|
169
|
+
options?.diagnostics?.beforeRequest?.(request);
|
|
170
|
+
requests++;
|
|
171
|
+
},
|
|
172
|
+
observe: (value) => {
|
|
173
|
+
observations.push(value);
|
|
174
|
+
if (value.status === 429 || value.status === 503) cooldown = value.retryAt ?? Date.now() + 2e3;
|
|
175
|
+
options?.diagnostics?.observe?.(value);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
})).length
|
|
92
179
|
};
|
|
93
180
|
} catch (error) {
|
|
94
|
-
const failed = (cause) => {
|
|
95
|
-
const errorCode = classifyMcpConnectionError(cause);
|
|
96
|
-
log.warn({
|
|
97
|
-
serverId,
|
|
98
|
-
errorCode
|
|
99
|
-
}, `MCP connection check failed: ${errorCode}`);
|
|
100
|
-
return {
|
|
101
|
-
state: "error",
|
|
102
|
-
error: cause instanceof Error ? cause.message : String(cause),
|
|
103
|
-
errorCode
|
|
104
|
-
};
|
|
105
|
-
};
|
|
106
181
|
const server = config.mcp?.servers?.[serverId];
|
|
107
|
-
const
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
Accept: "application/json, text/event-stream",
|
|
125
|
-
"Content-Type": "application/json",
|
|
126
|
-
...entry.config.headers
|
|
182
|
+
const failed = observations.filter((o) => o.status >= 400 && !(o.method === "GET" && o.status === 405 && server?.type !== "sse")).at(-1);
|
|
183
|
+
const last = failed ?? observations.at(-1);
|
|
184
|
+
const observation = last ? (({ challenge: _challenge, ...safe }) => safe)(last) : void 0;
|
|
185
|
+
const category = failed ? classifyMcpConnectionError(`HTTP ${failed.status}`) : classifyMcpConnectionError(error);
|
|
186
|
+
const hasCredentials = Boolean(server?.auth || Object.keys(server?.headers ?? {}).some((n) => n.toLowerCase() === "authorization") || JSON.stringify(server?.headers ?? {}).includes("xopcSecretRef"));
|
|
187
|
+
const denied = error instanceof McpAuthenticationRequiredError || category === "access_denied";
|
|
188
|
+
if (server?.url && denied) {
|
|
189
|
+
if (hasCredentials) {
|
|
190
|
+
const rejected = failed?.status === 401 || /\b401\b|invalid_token|unauthorized/i.test(String(error)) || /invalid_token/i.test(failed?.challenge ?? "");
|
|
191
|
+
return {
|
|
192
|
+
state: rejected ? "token_required" : "error",
|
|
193
|
+
errorCode: rejected ? void 0 : "access_denied",
|
|
194
|
+
observation,
|
|
195
|
+
auth: {
|
|
196
|
+
method: "credential",
|
|
197
|
+
metadata: "not_checked",
|
|
198
|
+
credential: rejected ? "rejected" : "unknown"
|
|
127
199
|
},
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
200
|
+
recovery: {
|
|
201
|
+
kind: "enter_secret",
|
|
202
|
+
reason: rejected ? "credential_rejected" : "credential_or_permission_refused"
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
try {
|
|
207
|
+
const auth = await authentication(config, workspace, serverId, last ? last.challenge ?? "" : void 0, options);
|
|
208
|
+
return {
|
|
209
|
+
state: auth.method === "oauth" ? "oauth_required" : "auth_unknown",
|
|
210
|
+
auth: {
|
|
211
|
+
method: auth.method,
|
|
212
|
+
metadata: auth.metadata,
|
|
213
|
+
credential: "missing"
|
|
214
|
+
},
|
|
215
|
+
observation,
|
|
216
|
+
recovery: {
|
|
217
|
+
kind: auth.retryAt ? "wait" : auth.method === "oauth" ? "authorize" : "choose_auth",
|
|
218
|
+
...auth.retryAt ? { retryAt: auth.retryAt } : {},
|
|
219
|
+
reason: auth.metadata
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
} catch {
|
|
223
|
+
options?.signal?.throwIfAborted();
|
|
224
|
+
return {
|
|
225
|
+
state: "auth_unknown",
|
|
226
|
+
auth: {
|
|
227
|
+
method: "unknown",
|
|
228
|
+
metadata: "unreachable",
|
|
229
|
+
credential: "missing"
|
|
230
|
+
},
|
|
231
|
+
observation,
|
|
232
|
+
recovery: {
|
|
233
|
+
kind: "choose_auth",
|
|
234
|
+
reason: "metadata_unreachable"
|
|
235
|
+
}
|
|
236
|
+
};
|
|
144
237
|
}
|
|
145
|
-
} catch {
|
|
146
|
-
options?.signal?.throwIfAborted();
|
|
147
238
|
}
|
|
148
|
-
|
|
239
|
+
if (category === "rate_limited" || failed?.status === 503) return {
|
|
240
|
+
state: "error",
|
|
241
|
+
errorCode: category === "rate_limited" ? category : "network",
|
|
242
|
+
observation,
|
|
243
|
+
recovery: {
|
|
244
|
+
kind: "wait",
|
|
245
|
+
retryAt: cooldown || Date.now() + 2e3
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
const errorCode = /html/i.test(observation?.contentType ?? "") ? "invalid_response" : category;
|
|
249
|
+
log.warn({
|
|
250
|
+
serverId,
|
|
251
|
+
errorCode
|
|
252
|
+
}, `MCP connection check failed: ${errorCode}`);
|
|
253
|
+
return {
|
|
254
|
+
state: "error",
|
|
255
|
+
errorCode,
|
|
256
|
+
observation,
|
|
257
|
+
recovery: {
|
|
258
|
+
kind: ["not_found", "invalid_response"].includes(errorCode) ? "verify_documented_endpoint" : "report_blocker",
|
|
259
|
+
reason: errorCode
|
|
260
|
+
}
|
|
261
|
+
};
|
|
149
262
|
}
|
|
150
263
|
}
|
|
151
264
|
const attempts = /* @__PURE__ */ new Map();
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ExtensionFactory } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
/** Connecting alone does not authorize reading private MCP resources or invoking business tools. */
|
|
3
|
+
export declare function createMcpSetupContinuationGuard(conversationId: string, discoveryAvailable?: boolean): ExtensionFactory;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { findSessionInputByRunId, init_session_input_repository } from "../../storage/sqlite/session-input-repository.js";
|
|
2
|
+
import { getSessionMetadata, init_session_read_repository } from "../../storage/sqlite/session-read-repository.js";
|
|
3
|
+
import { DurableState } from "../../storage/sqlite/durable-state.js";
|
|
4
|
+
import { getEmbeddedExecutionRunId } from "../embedded/execution-context.js";
|
|
5
|
+
//#region src/agent/mcp/continuation-guard.ts
|
|
6
|
+
init_session_input_repository();
|
|
7
|
+
init_session_read_repository();
|
|
8
|
+
/** Connecting alone does not authorize reading private MCP resources or invoking business tools. */
|
|
9
|
+
function createMcpSetupContinuationGuard(conversationId, discoveryAvailable = false) {
|
|
10
|
+
return (pi) => {
|
|
11
|
+
if (discoveryAvailable) pi.on("tool_result", (event) => {
|
|
12
|
+
if (event.isError) return;
|
|
13
|
+
const content = event.content.filter((block) => block.type === "text").map((block) => block.text).join("\n");
|
|
14
|
+
const empty = event.toolName === "codemode" && /searchTools\s*\(/.test(JSON.stringify(event.input)) && /Output:\s*\[\]\s*$/.test(content) || event.toolName === "tool_search" && /no (?:matching |relevant )?tools|0 tools/i.test(content);
|
|
15
|
+
const runId = getEmbeddedExecutionRunId();
|
|
16
|
+
const input = runId ? findSessionInputByRunId(conversationId, runId) : void 0;
|
|
17
|
+
const goal = input?.clientMessageId.startsWith("mcp-setup:") ? new DurableState("mcp.conversation-setup").get(input.clientMessageId.slice(10)) : void 0;
|
|
18
|
+
if (empty && goal?.phase === "ready") return { content: [...event.content, {
|
|
19
|
+
type: "text",
|
|
20
|
+
text: `This is a saved connection continuation. Search tools using the exact namespace mcp__${goal.serverId.replace(/-/g, "_")}, then finish the original objective. Do not restart setup.`
|
|
21
|
+
}] };
|
|
22
|
+
if (empty) return { content: [...event.content, {
|
|
23
|
+
type: "text",
|
|
24
|
+
text: "No registered tool matches this search. This is not evidence that the requested service cannot be connected. If the user clearly asked to connect a named service, call the available mcp_setup discover {serviceName,purpose} and read tool_manual topic mcp before reporting a blocker or asking for an MCP URL. Do not substitute a different saved service."
|
|
25
|
+
}] };
|
|
26
|
+
});
|
|
27
|
+
pi.on("tool_call", (event) => {
|
|
28
|
+
if (!event.toolName.startsWith("mcp__") && !["read_mcp_resource", "read_resource"].includes(event.toolName)) return;
|
|
29
|
+
const runId = getEmbeddedExecutionRunId();
|
|
30
|
+
if (!runId) return;
|
|
31
|
+
const input = findSessionInputByRunId(conversationId, runId);
|
|
32
|
+
if (!input?.clientMessageId.startsWith("mcp-setup:")) return;
|
|
33
|
+
const goal = new DurableState("mcp.conversation-setup").get(input.clientMessageId.slice(10));
|
|
34
|
+
if (!goal || goal.phase !== "ready" || goal.transcriptId !== getSessionMetadata(conversationId)?.transcriptId) return {
|
|
35
|
+
block: true,
|
|
36
|
+
reason: "MCP setup authorization changed. Return to the current conversation."
|
|
37
|
+
};
|
|
38
|
+
if (goal.objective === "connect_only") return {
|
|
39
|
+
block: true,
|
|
40
|
+
reason: "The user requested connection only. Describe discovered capabilities without reading private data or invoking business tools."
|
|
41
|
+
};
|
|
42
|
+
if (["read_mcp_resource", "read_resource"].includes(event.toolName) && event.input.server !== goal.serverId) return {
|
|
43
|
+
block: true,
|
|
44
|
+
reason: "This continuation may read resources only from the newly connected MCP server."
|
|
45
|
+
};
|
|
46
|
+
if (event.toolName.startsWith("mcp__") && !event.toolName.startsWith(`mcp__${goal.serverId.replace(/-/g, "_")}__`)) return {
|
|
47
|
+
block: true,
|
|
48
|
+
reason: `This continuation may use only the newly connected MCP server ${goal.serverId}. Discover that server's actual tools.`
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
export { createMcpSetupContinuationGuard };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { init_connection, isXopcDatabaseOpen } from "../../storage/sqlite/connection.js";
|
|
2
|
+
import { findSessionInputByRunId, init_session_input_repository } from "../../storage/sqlite/session-input-repository.js";
|
|
3
|
+
//#region src/agent/mcp/continuation-input.ts
|
|
4
|
+
init_connection();
|
|
5
|
+
init_session_input_repository();
|
|
6
|
+
/** Only host-created MCP setup inputs may become hidden continuation context. */
|
|
7
|
+
function getMcpSetupResumeInput(conversationId, runId) {
|
|
8
|
+
if (!isXopcDatabaseOpen()) return void 0;
|
|
9
|
+
const input = findSessionInputByRunId(conversationId, runId);
|
|
10
|
+
return input?.origin.type === "system" && input.origin.source === "internal" && input.clientMessageId.startsWith("mcp-setup:") ? { content: input.content } : void 0;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { getMcpSetupResumeInput };
|