@xopcai/xopc 0.0.113 → 0.0.115
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/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/feishu/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/src/adapters/streaming-adapter.js +1 -1
- package/dist/extensions/telegram/src/inbound-processor.js +1 -1
- package/dist/extensions/telegram/src/plugin.js +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/src/update-offset-store.js +1 -1
- package/dist/extensions/telegram/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/api/api.js +2 -2
- package/dist/extensions/weixin/src/auth/accounts.js +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CBlklyNr.js → agent-avatar-dicebear-DVnBfANm.js} +1 -1
- package/dist/gateway/static/root/assets/agent-browser-settings-page-DPXc4hz8.js +6 -0
- package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-CTJ0YnRQ.js +1 -0
- package/dist/gateway/static/root/assets/agents-zJXQfJ_W.js +71 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-28E_WfMe.js → app-management-settings-panel-DzGbdr04.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-Do1z0XgJ.js → appearance-settings-BQpPSTHD.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-CPjfyzSD.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-BAFlsov_.js → archive-plugin-CXu-Csep.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-V3qGPC3x.js → attachment-load-BAjgOoGY.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-DT8NvA6W.js → binary-plugins-BSBgB2hO.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CdLMEcHd.js → block-editor-BpXw9TTR.js} +3 -3
- package/dist/gateway/static/root/assets/channels-settings-BbPUpzWB.js +1 -0
- package/dist/gateway/static/root/assets/{config-api-Bf5mjpu7.js → config-api-NOoPiIYz.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-settings-CAXYMOdp.js +2 -0
- package/dist/gateway/static/root/assets/{cron-api--pAB_rps.js → cron-api-C9BOqAXd.js} +1 -1
- package/dist/gateway/static/root/assets/cron-page-DuUbBeKI.js +3 -0
- package/dist/gateway/static/root/assets/{dreaming-settings-6UZE1FSK.js → dreaming-settings-DQ4DtiK1.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BGhE7msg.js → extension-debug-page-D9kgUHCc.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CvpI45WG.js → extension-page-CGyhXqzR.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DAmR5FUe.js → extension-settings-page-DL8Xquqd.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-NZmjSXLl.js → fetch-D0VXA932.js} +1 -1
- package/dist/gateway/static/root/assets/{format-interval-label-qhth3BMV.js → format-interval-label-Be8SmgUw.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-CaXBt-9R.js → gateway-config-api-C-xjn__h.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-DphpbLBc.js → gateway-settings-BMPwIjKI.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-Be1omjh3.js → gateway-startup-retry-DERUH61L.js} +1 -1
- package/dist/gateway/static/root/assets/goal-detail-page-BJsyjJnF.js +1 -0
- package/dist/gateway/static/root/assets/goals-config-api-BPmqWk90.js +1 -0
- package/dist/gateway/static/root/assets/goals-page-BerDgIhw.js +2 -0
- package/dist/gateway/static/root/assets/goals-settings-ByTjeAto.js +1 -0
- package/dist/gateway/static/root/assets/{heartbeat-config-api-BzO6G4fD.js → heartbeat-config-api-Bfdzr8oV.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-DCST9-du.js → heartbeat-settings-TbHgcjTn.js} +1 -1
- package/dist/gateway/static/root/assets/index-AkTrf6Pb.js +122 -0
- package/dist/gateway/static/root/assets/index-fh5sXTj9.css +1 -0
- package/dist/gateway/static/root/assets/{interval-presets-DJmshV8n.js → interval-presets-utKbuCRY.js} +1 -1
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-9AUUlQ5Q.js → keyboard-shortcuts-settings-CjqS6c6V.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-DGXuPf5B.js +2 -0
- package/dist/gateway/static/root/assets/{markdown-split-CYYELqAr.js → markdown-split-DW8C47iB.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-BEcMR2M8.js → media-plugins-D6HwDhDT.js} +1 -1
- package/dist/gateway/static/root/assets/messages-upgxw6Ub.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-panel-Bot16nn7.js +2 -0
- package/dist/gateway/static/root/assets/note-detail-page-Brlyou8M.js +2 -0
- package/dist/gateway/static/root/assets/{note-image-lightbox-DNAoPcmm.js → note-image-lightbox-pJM35Pz5.js} +1 -1
- package/dist/gateway/static/root/assets/notes-page-DvZ4pwc-.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-BPLz0AIv.js → preview-open-alternatives-CVwHuyN6.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-BZEDmxbZ.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-CrWwWRVK.js → save-bar-controls-Ba-UEk7x.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-CF2sadvN.js → schedule-field-CNN9595U.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-Di5cKjYE.js → schema-form-DnNMmtD5.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DdGGlsfn.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-DlkEkPf9.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-Chh282jW.js → settings-collapsible-section-CmOz80i5.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-Dq-83cQd.js → settings-form-section-BmK7JJOV.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-DFPTrsPF.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-CYCCfgh4.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-0FXYnSUA.js → share-preview-page-Dp2qGrHC.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-Bff1pGd0.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-CJGKpBur.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-C6ocduTD.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-W1pTcojB.js → system-settings-panel-5jrIEr5b.js} +1 -1
- package/dist/gateway/static/root/assets/{use-agent-defaults-form-BVRvkK7m.js → use-agent-defaults-form-BuiXLIs5.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-CgJibfMM.js → use-channel-catalog-CHlO8J9G.js} +1 -1
- package/dist/gateway/static/root/assets/{use-settings-tab-guard-Bw_qkRQE.js → use-settings-tab-guard-CW5JORnl.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-DDoQyghO.js +1 -0
- package/dist/gateway/static/root/assets/{voice-player-store-C7lziaAx.js → voice-player-store-DDDWYHvg.js} +1 -1
- package/dist/gateway/static/root/assets/workflow-page.utils-CKjeEGqx.js +1 -0
- package/dist/gateway/static/root/assets/workflows-page-B604ehHG.js +18 -0
- package/dist/gateway/static/root/index.html +5 -5
- package/dist/gateway/static/root/logo.svg +4 -3
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +8 -0
- package/dist/src/agent/agent-manager.js +63 -28
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/agent-scope.js +1 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/bootstrap/project-agents-context.d.ts +2 -0
- package/dist/src/agent/bootstrap/project-agents-context.js +32 -0
- package/dist/src/agent/bootstrap/project-agents-context.js.map +1 -0
- package/dist/src/agent/context/workspace-seed.js +2 -2
- package/dist/src/agent/context/workspace-state.js +1 -1
- package/dist/src/agent/context/workspace.js +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js +8 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
- package/dist/src/agent/goals/checklist-judge.d.ts +1 -0
- package/dist/src/agent/goals/checklist-judge.js +3 -2
- package/dist/src/agent/goals/checklist-judge.js.map +1 -1
- package/dist/src/agent/goals/evaluate-turn.d.ts +1 -1
- package/dist/src/agent/goals/evaluate-turn.js +1 -0
- package/dist/src/agent/goals/evaluate-turn.js.map +1 -1
- package/dist/src/agent/goals/goal-locale.js +2 -2
- package/dist/src/agent/goals/persistent-goal-service.js +2 -4
- package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
- package/dist/src/agent/goals/post-turn.d.ts +6 -1
- package/dist/src/agent/goals/post-turn.js +15 -6
- package/dist/src/agent/goals/post-turn.js.map +1 -1
- package/dist/src/agent/image/load-image-media.js +2 -2
- package/dist/src/agent/inbound/inbound-loop.js +5 -1
- package/dist/src/agent/inbound/inbound-loop.js.map +1 -1
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +2 -2
- package/dist/src/agent/inbound/turn-dispatcher.js +2 -2
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
- package/dist/src/agent/ipc/inbox.js +3 -3
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.d.ts +27 -0
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +50 -2
- package/dist/src/agent/mcp/bundle-mcp-materialize.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +79 -4
- package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-types.d.ts +19 -0
- package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
- package/dist/src/agent/mcp/mcp-transport.js +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/memory-flush.js +1 -1
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/prompt/memory/index.js +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +2 -2
- package/dist/src/agent/service/btw-query.js +11 -3
- package/dist/src/agent/service/btw-query.js.map +1 -1
- package/dist/src/agent/service/parse-outbound-session-key.js +13 -8
- package/dist/src/agent/service/parse-outbound-session-key.js.map +1 -1
- package/dist/src/agent/service/process-direct-one-shot.d.ts +2 -2
- package/dist/src/agent/service/process-direct-one-shot.js +1 -1
- package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.d.ts +2 -2
- package/dist/src/agent/service/process-direct-streaming.js +1 -1
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service.d.ts +1 -1
- package/dist/src/agent/service.js +13 -9
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/service.types.d.ts +5 -0
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/config.js +2 -2
- package/dist/src/agent/skills/filesystem-watcher.js +5 -4
- package/dist/src/agent/skills/filesystem-watcher.js.map +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +2 -2
- package/dist/src/agent/skills/index.js +4 -3
- package/dist/src/agent/skills/index.js.map +1 -1
- package/dist/src/agent/skills/installer.js +2 -2
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +3 -2
- package/dist/src/agent/skills/skill-manage-ops.js.map +1 -1
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/skills/skill-view-path.js +1 -1
- package/dist/src/agent/skills/test-framework.js +1 -1
- package/dist/src/agent/skills/types.d.ts +1 -1
- package/dist/src/agent/skills/watcher.js +2 -5
- package/dist/src/agent/skills/watcher.js.map +1 -1
- package/dist/src/agent/skills/workspace-skills-dir.d.ts +1 -0
- package/dist/src/agent/skills/workspace-skills-dir.js +11 -0
- package/dist/src/agent/skills/workspace-skills-dir.js.map +1 -0
- package/dist/src/agent/starter-agents.js +1 -1
- package/dist/src/agent/tool-manuals/browser.d.ts +1 -1
- package/dist/src/agent/tool-manuals/browser.js +62 -3
- package/dist/src/agent/tool-manuals/browser.js.map +1 -1
- package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +4 -1
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +13 -4
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
- package/dist/src/agent/tools/browser/tool/schemas.d.ts +0 -2
- package/dist/src/agent/tools/browser/tool/schemas.js +1 -2
- package/dist/src/agent/tools/browser/tool/schemas.js.map +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/factory.js +1 -10
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/find.js +1 -1
- package/dist/src/agent/tools/grep.js +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +2 -2
- package/dist/src/agent/tools/skill-manage-tool.js.map +1 -1
- package/dist/src/agent/tools/workflow-tool.js +1 -1
- package/dist/src/agent/workflow/catalog.js +1 -1
- package/dist/src/agent/workflow/snapshot.d.ts +10 -0
- package/dist/src/agent/workflow/snapshot.js +136 -1
- package/dist/src/agent/workflow/snapshot.js.map +1 -1
- package/dist/src/agent/workflow/subagent-runner.js +18 -1
- package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
- package/dist/src/ai-assist/text-assist.js +1 -1
- package/dist/src/auth/credentials.js +2 -2
- package/dist/src/auth/profiles/store.js +2 -2
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/actions/extension-registry-bridge.js +91 -7
- package/dist/src/browser/actions/extension-registry-bridge.js.map +1 -1
- package/dist/src/browser/actions/registry.js +383 -7
- package/dist/src/browser/actions/registry.js.map +1 -1
- package/dist/src/browser/actions/types.d.ts +11 -3
- package/dist/src/browser/cache-dir-policy.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +2 -2
- package/dist/src/browser/index.js +2 -2
- package/dist/src/browser/pipeline/output.d.ts +18 -16
- package/dist/src/browser/pipeline/output.js +28 -20
- package/dist/src/browser/pipeline/output.js.map +1 -1
- package/dist/src/browser/pipeline/runner.d.ts +7 -14
- package/dist/src/browser/pipeline/runner.js +349 -102
- package/dist/src/browser/pipeline/runner.js.map +1 -1
- package/dist/src/browser/pipeline/schema.d.ts +1 -0
- package/dist/src/browser/pipeline/schema.js +35 -58
- package/dist/src/browser/pipeline/schema.js.map +1 -1
- package/dist/src/browser/pipeline/source.d.ts +2 -0
- package/dist/src/browser/pipeline/source.js +10 -1
- package/dist/src/browser/pipeline/source.js.map +1 -1
- package/dist/src/browser/pipeline/template.d.ts +10 -2
- package/dist/src/browser/pipeline/template.js +50 -8
- package/dist/src/browser/pipeline/template.js.map +1 -1
- package/dist/src/browser/providers/browser-ext-install.js +4 -4
- package/dist/src/browser/providers/cloakbrowser.js +5 -5
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/stealth.js +1 -1
- package/dist/src/channels/catalog/channel-catalog-service.d.ts +2 -1
- package/dist/src/channels/catalog/channel-catalog-service.js +133 -16
- package/dist/src/channels/catalog/channel-catalog-service.js.map +1 -1
- package/dist/src/channels/catalog/channel-catalog-types.d.ts +13 -0
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/chat-commands/agent-edit.js +2 -2
- package/dist/src/chat-commands/builtins/config.js +5 -7
- package/dist/src/chat-commands/builtins/config.js.map +1 -1
- package/dist/src/chat-commands/context.d.ts +5 -0
- package/dist/src/chat-commands/context.js +18 -9
- package/dist/src/chat-commands/context.js.map +1 -1
- package/dist/src/chat-commands/index.d.ts +1 -1
- package/dist/src/chat-commands/index.js +2 -2
- package/dist/src/chat-commands/index.js.map +1 -1
- package/dist/src/chat-commands/processor.js +22 -21
- package/dist/src/chat-commands/processor.js.map +1 -1
- package/dist/src/chat-commands/session-key.d.ts +3 -15
- package/dist/src/chat-commands/session-key.js +3 -49
- package/dist/src/chat-commands/session-key.js.map +1 -1
- package/dist/src/chat-commands/types.d.ts +4 -0
- package/dist/src/cli/commands/browser-cli-helpers.js +11 -5
- package/dist/src/cli/commands/browser-cli-helpers.js.map +1 -1
- package/dist/src/cli/commands/config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-config.js +14 -1
- package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +8 -8
- package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
- package/dist/src/cli/commands/extension-create.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +2 -2
- package/dist/src/cli/commands/extension-marketplace.js +2 -2
- package/dist/src/cli/commands/extension-pack.js +2 -2
- package/dist/src/cli/commands/extension.js +3 -3
- package/dist/src/cli/commands/gateway/logs.js +1 -1
- package/dist/src/cli/commands/image.js +1 -1
- package/dist/src/cli/commands/init.js +2 -2
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/skills-test.js +1 -1
- package/dist/src/cli/templates.js +1 -1
- package/dist/src/cli/utils/gateway-client.js +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -2
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/agent-typed-models.js +1 -1
- package/dist/src/config/gateway-bind.js +1 -1
- package/dist/src/config/index.js +7 -7
- package/dist/src/config/loader.js +4 -4
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/paths-state.js +1 -1
- package/dist/src/config/paths.js +1 -1
- package/dist/src/config/profile.js +1 -1
- package/dist/src/config/reload.js +1 -1
- package/dist/src/config/rules.js +5 -0
- package/dist/src/config/rules.js.map +1 -1
- package/dist/src/config/schema.d.ts +8 -0
- package/dist/src/config/schema.js +7 -0
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/web-patch.d.ts +1 -0
- package/dist/src/config/web-patch.js +1 -0
- package/dist/src/config/web-patch.js.map +1 -1
- package/dist/src/config/workspace-path.js +1 -1
- package/dist/src/connectors/builtin-catalog.js +180 -1
- package/dist/src/connectors/builtin-catalog.js.map +1 -1
- package/dist/src/connectors/health.js +18 -9
- package/dist/src/connectors/health.js.map +1 -1
- package/dist/src/connectors/types.d.ts +19 -0
- package/dist/src/connectors/usage.js +12 -4
- package/dist/src/connectors/usage.js.map +1 -1
- package/dist/src/cron/executor.js +1 -1
- package/dist/src/cron/service.js +1 -1
- package/dist/src/daemon/constants.js +1 -1
- package/dist/src/daemon/install-plan.js +2 -2
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/schtasks.js +2 -2
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +2 -2
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/install.js +2 -2
- package/dist/src/extensions/loader.js +2 -2
- package/dist/src/extensions/lockfile.js +3 -3
- package/dist/src/extensions/security.js +1 -1
- package/dist/src/extensions/types/tui.d.ts +2 -0
- package/dist/src/extensions/update.js +2 -2
- package/dist/src/gateway/agents-admin.js +2 -2
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +13 -1
- package/dist/src/gateway/heartbeat/service.js.map +1 -1
- package/dist/src/gateway/hono/app.js +18 -5
- package/dist/src/gateway/hono/app.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +3 -1
- package/dist/src/gateway/hono/lib/config-payload.js +7 -4
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +2 -2
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +4 -0
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js +19 -5
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js.map +1 -1
- package/dist/src/gateway/hono/oauth-async.js +1 -1
- package/dist/src/gateway/hono/routes/agent-stream.js +6 -6
- package/dist/src/gateway/hono/routes/agent-stream.js.map +1 -1
- package/dist/src/gateway/hono/routes/agents.js +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/channels.js +18 -14
- package/dist/src/gateway/hono/routes/channels.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +1 -1
- package/dist/src/gateway/hono/routes/config-patch/gateway.js +6 -0
- package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/deps.d.ts +1 -0
- package/dist/src/gateway/hono/routes/dreaming.js +1 -1
- package/dist/src/gateway/hono/routes/goals.js +16 -3
- package/dist/src/gateway/hono/routes/goals.js.map +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +2 -2
- package/dist/src/gateway/hono/routes/logs.js +1 -0
- package/dist/src/gateway/hono/routes/logs.js.map +1 -1
- package/dist/src/gateway/hono/routes/mcp.js +27 -8
- package/dist/src/gateway/hono/routes/mcp.js.map +1 -1
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/notes.js +14 -2
- package/dist/src/gateway/hono/routes/notes.js.map +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +62 -4
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/shares.js +1 -1
- package/dist/src/gateway/hono/routes/workflows.js +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +5 -68
- package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
- package/dist/src/gateway/hono/sse.d.ts +2 -2
- package/dist/src/gateway/hono/sse.js +7 -15
- package/dist/src/gateway/hono/sse.js.map +1 -1
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/ports.js +1 -1
- package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
- package/dist/src/gateway/rate-limit/buckets.js +12 -0
- package/dist/src/gateway/rate-limit/buckets.js.map +1 -1
- package/dist/src/gateway/resolve-webchat-session-key.d.ts +2 -6
- package/dist/src/gateway/resolve-webchat-session-key.js +5 -31
- package/dist/src/gateway/resolve-webchat-session-key.js.map +1 -1
- package/dist/src/gateway/service/agent-runner.d.ts +2 -3
- package/dist/src/gateway/service/agent-runner.js +9 -22
- package/dist/src/gateway/service/agent-runner.js.map +1 -1
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service/marketplace-service.js +2 -2
- package/dist/src/gateway/service/run-gateway-agent.js +9 -7
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.d.ts +9 -0
- package/dist/src/gateway/service/sessions-api.js +11 -0
- package/dist/src/gateway/service/sessions-api.js.map +1 -1
- package/dist/src/gateway/service.d.ts +1 -1
- package/dist/src/gateway/service.js +23 -9
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-file-search.d.ts +9 -0
- package/dist/src/gateway/workspace-file-search.js +76 -0
- package/dist/src/gateway/workspace-file-search.js.map +1 -0
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/goals/goal-notifications.d.ts +2 -0
- package/dist/src/goals/goal-notifications.js +16 -11
- package/dist/src/goals/goal-notifications.js.map +1 -1
- package/dist/src/goals/goal-service.js +1 -6
- package/dist/src/goals/goal-service.js.map +1 -1
- package/dist/src/goals/goal-workflow-judge.js +2 -2
- package/dist/src/i18n/goals-bundle.js +1 -1
- package/dist/src/i18n/index.js +1 -1
- package/dist/src/i18n/share-tool-bundle.js +2 -2
- package/dist/src/infra/brew.js +1 -1
- package/dist/src/infra/package-json.js +1 -1
- package/dist/src/infra/package-update-steps.js +1 -1
- package/dist/src/infra/path-env.js +2 -2
- package/dist/src/infra/restart.js +1 -1
- package/dist/src/infra/stable-node-path.js +1 -1
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-global.js +1 -1
- package/dist/src/infra/update-lock.js +2 -2
- package/dist/src/infra/update-restart.js +1 -1
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +1 -1
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/media/store.js +1 -1
- package/dist/src/notes/agent-context.js +1 -1
- package/dist/src/notes/service.js +1 -1
- package/dist/src/notes/store.js +2 -2
- package/dist/src/project-trust/trust-store.js +4 -2
- package/dist/src/project-trust/trust-store.js.map +1 -1
- package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
- package/dist/src/providers/index.js +1 -1
- package/dist/src/providers/model-registry.js +4 -4
- package/dist/src/session/index.d.ts +1 -1
- package/dist/src/session/index.js +2 -2
- package/dist/src/session/init-session-turn.js +7 -10
- package/dist/src/session/init-session-turn.js.map +1 -1
- package/dist/src/session/manager.d.ts +5 -1
- package/dist/src/session/manager.js +5 -2
- package/dist/src/session/manager.js.map +1 -1
- package/dist/src/session/reset-type.d.ts +0 -2
- package/dist/src/session/reset-type.js +3 -9
- package/dist/src/session/reset-type.js.map +1 -1
- package/dist/src/session/resolve-session.js +10 -21
- package/dist/src/session/resolve-session.js.map +1 -1
- package/dist/src/session/session-title.js +2 -2
- package/dist/src/session/store.d.ts +11 -3
- package/dist/src/session/store.js +30 -14
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/session/types.d.ts +2 -4
- package/dist/src/session/types.js.map +1 -1
- package/dist/src/share/share-auto.js +2 -2
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/share/share-thumbnail.js +2 -2
- package/dist/src/share/share-zip.js +1 -1
- package/dist/src/share/site-share-store.js +3 -3
- package/dist/src/share/site-static-serve.js +1 -1
- package/dist/src/storage/sqlite/connection.js +1 -1
- package/dist/src/storage/sqlite/index.d.ts +2 -2
- package/dist/src/storage/sqlite/index.js +3 -3
- package/dist/src/storage/sqlite/memory-index-repository.js +2 -2
- package/dist/src/storage/sqlite/migrations/010_session_id_identity.sql +30 -0
- package/dist/src/storage/sqlite/migrations/discover.js +1 -1
- package/dist/src/storage/sqlite/migrations/runner.d.ts +2 -2
- package/dist/src/storage/sqlite/migrations/runner.js +5 -5
- package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/runner.ts +2 -2
- package/dist/src/storage/sqlite/row-mappers.d.ts +4 -4
- package/dist/src/storage/sqlite/row-mappers.js +11 -14
- package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
- package/dist/src/storage/sqlite/schema.js +4 -4
- package/dist/src/storage/sqlite/schema.js.map +1 -1
- package/dist/src/storage/sqlite/schema.sql +37 -10
- package/dist/src/storage/sqlite/session-metadata.d.ts +2 -7
- package/dist/src/storage/sqlite/session-metadata.js +18 -72
- package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
- package/dist/src/storage/sqlite/session-repository.d.ts +6 -5
- package/dist/src/storage/sqlite/session-repository.js +34 -40
- package/dist/src/storage/sqlite/session-repository.js.map +1 -1
- package/dist/src/storage/sqlite/transcript-repository.d.ts +2 -2
- package/dist/src/storage/sqlite/transcript-repository.js +52 -52
- package/dist/src/storage/sqlite/transcript-repository.js.map +1 -1
- package/dist/src/tui/backends/embedded-backend.d.ts +18 -4
- package/dist/src/tui/backends/embedded-backend.js +100 -1
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.d.ts +5 -1
- package/dist/src/tui/backends/gateway-sse-backend.js +45 -2
- package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
- package/dist/src/tui/clipboard-image.js +3 -3
- package/dist/src/tui/components/chat-log.d.ts +2 -0
- package/dist/src/tui/components/chat-log.js +19 -0
- package/dist/src/tui/components/chat-log.js.map +1 -1
- package/dist/src/tui/extension-host/autocomplete.d.ts +3 -2
- package/dist/src/tui/extension-host/autocomplete.js +29 -12
- package/dist/src/tui/extension-host/autocomplete.js.map +1 -1
- package/dist/src/tui/extension-host/load-extensions.js +1 -1
- package/dist/src/tui/extension-host/runtime.d.ts +12 -0
- package/dist/src/tui/extension-host/runtime.js +6 -4
- package/dist/src/tui/extension-host/runtime.js.map +1 -1
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/tui-backend.d.ts +23 -0
- package/dist/src/tui/tui-command-formatters.js +4 -4
- package/dist/src/tui/tui-commands.d.ts +16 -3
- package/dist/src/tui/tui-commands.js +134 -27
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/tui-file-autocomplete.d.ts +5 -0
- package/dist/src/tui/tui-file-autocomplete.js +26 -0
- package/dist/src/tui/tui-file-autocomplete.js.map +1 -0
- package/dist/src/tui/tui-keybindings-file.js +1 -1
- package/dist/src/tui/tui-picker-overlay.js +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/tui/tui-startup-text.js +1 -1
- package/dist/src/tui/tui-startup-text.js.map +1 -1
- package/dist/src/tui/tui.js +106 -17
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/tunnel/frpc-binary.js +4 -4
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/context.d.ts +2 -2
- package/dist/src/utils/logger/context.js +2 -1
- package/dist/src/utils/logger/context.js.map +1 -1
- package/dist/src/utils/logger/log-store.js +2 -1
- package/dist/src/utils/logger/log-store.js.map +1 -1
- package/dist/src/utils/logger/pino-record.js +3 -0
- package/dist/src/utils/logger/pino-record.js.map +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/utils/logger/streams.js +1 -1
- package/dist/src/utils/logger/types.d.ts +5 -0
- package/dist/src/utils/logger/types.js.map +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +2 -2
- package/dist/src/workflows/draft/workflow-draft-service.js +1 -1
- package/dist/src/workflows/service/workflow-run-service.js +1 -1
- package/dist/src/workflows/service/workflow-session-bridge.js +13 -1
- package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
- package/dist/src/workflows/store/event-store.js +1 -1
- package/dist/src/workflows/store/run-store.js +1 -1
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/agent-browser-settings-page-rGbKc2Hh.js +0 -6
- package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-CtwVbjOA.js +0 -1
- package/dist/gateway/static/root/assets/agents-CCBmGcwc.js +0 -71
- package/dist/gateway/static/root/assets/apps-page-xwCsJS15.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-C044DcYk.js +0 -1
- package/dist/gateway/static/root/assets/connectors-settings-8VEWUOTj.js +0 -2
- package/dist/gateway/static/root/assets/cron-page-DqmNGNOy.js +0 -3
- package/dist/gateway/static/root/assets/goal-detail-page-bv0VRDaf.js +0 -1
- package/dist/gateway/static/root/assets/goals-page-1Ywnt4Cb.js +0 -2
- package/dist/gateway/static/root/assets/goals-settings-ceEBjnfc.js +0 -1
- package/dist/gateway/static/root/assets/index-Cxm6xsps.js +0 -122
- package/dist/gateway/static/root/assets/index-b_R4tKqt.css +0 -1
- package/dist/gateway/static/root/assets/logs-page-B_wrxhee.js +0 -2
- package/dist/gateway/static/root/assets/messages-CkT-lcgP.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-D0JDSbNu.js +0 -2
- package/dist/gateway/static/root/assets/note-detail-page-DpFV-EO6.js +0 -2
- package/dist/gateway/static/root/assets/notes-page-CdkjTch8.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DSYVAi96.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-CenkcVjF.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-D9sva86V.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-DL35U0x0.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Ctwbp9Er.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-DIM3JNsr.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DAlNaNzL.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-CLrHVzAt.js +0 -2
- package/dist/gateway/static/root/assets/voice-api-key-field-vYAO71Gn.js +0 -1
- package/dist/gateway/static/root/assets/workflow-page.utils-sgHjOXOm.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-DYyOTmFx.js +0 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"turn-dispatcher.js","names":[],"sources":["../../../../src/agent/inbound/turn-dispatcher.ts"],"sourcesContent":["/**\n * TurnDispatcher — single entry point for direct (non-bus) agent turns.\n *\n * Wraps the two existing direct-turn runners (one-shot and streaming) so the\n * parent `AgentService` no longer carries a pair of huge `createXxxDeps()`\n * factories. The public surface — `processDirect`, `processDirectStreaming`,\n * `steerWebchatSession`, `enqueueWebchatSseEvent`,\n * `notifyWebchatTranscriptAppend` — matches what `AgentService` exposed\n * previously, so callers (gateway, CLI) are unchanged.\n *\n * Like `OutboundCoordinator` and `InboundLoop`, this class accepts a wide\n * dependency bag in its constructor (the direct-turn pipeline touches almost\n * every other subsystem). The win is that AgentService becomes the only place\n * that wires those dependencies together; individual responsibilities now live\n * in their own classes and are unit-testable.\n */\n\nimport type { Config } from '../../config/schema.js';\nimport type { ContextualLogger } from '../../utils/logger/types.js';\n\nimport type { AgentManager } from '../agent-manager.js';\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionConfigStore } from '../../session/index.js';\nimport type { SessionStore } from '../../session/store.js';\nimport type {\n SessionContext,\n SessionHydrator,\n SessionStateBag,\n} from '../session/index.js';\nimport { queueEmbeddedSteer } from '../embedded/runs.js';\nimport type {\n InboundAttachmentInput,\n MediaRef,\n} from '../../channels/attachments/inbound-persist.js';\nimport {\n buildDirectUserMessageContent,\n} from '../service/build-direct-message-content.js';\nimport {\n runProcessDirectStreaming,\n type ProcessDirectStreamingDeps,\n type ProcessDirectStreamingSseEvent,\n} from '../service/process-direct-streaming.js';\nimport {\n runProcessDirect,\n type RunProcessDirectDeps,\n} from '../service/process-direct-one-shot.js';\nimport { maybeEmitWebchatTts } from '../service/webchat-tts.js';\nimport type { AgentSourceContextResolver } from '../source-context/types.js';\n\nexport interface TurnDispatcherConfig {\n log: ContextualLogger;\n agentManager: AgentManager;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n sessionConfigStore: SessionConfigStore;\n sessionState: SessionStateBag;\n commandHandler: CommandHandler;\n getConfig: () => Config | undefined;\n /** Strict accessor — required for direct-turn paths that must have a config. */\n requireConfig: () => Config;\n parseSessionKey: (sessionKey: string) => { channel: string; chatId: string };\n /** Establish per-session context (also creates the Agent + subscribes to events). */\n initSessionContext: (sessionKey: string, channel: string, chatId: string) => SessionContext;\n /** Per-session config hydration: workspace, model, thinking. */\n sessionHydrator: SessionHydrator;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: InboundAttachmentInput[],\n ) => Promise<MediaRef[] | undefined>;\n enqueueMaybeAutoTitleAfterPersist: (sessionKey: string) => void;\n enqueueProvisionalSessionTitle?: (sessionKey: string, userText: string) => void;\n endDirectRequestContext: () => void;\n /** Gateway hook fired after assistant text lands on disk (UI refetch). */\n onSessionTranscriptUpdated?: (sessionKey: string) => void;\n resetSession: (sessionKey: string) => Promise<{ sessionId: string; previousSessionId: string } | null>;\n sourceContextResolver?: AgentSourceContextResolver;\n}\n\nexport type DirectAttachment = InboundAttachmentInput;\n\nexport class TurnDispatcher {\n private readonly cfg: TurnDispatcherConfig;\n private readonly log: ContextualLogger;\n\n constructor(cfg: TurnDispatcherConfig) {\n this.cfg = cfg;\n this.log = cfg.log;\n }\n\n /** One-shot direct turn (CLI / embedded TUI). */\n processDirect(\n content: string,\n sessionKey = 'agent:main:main',\n attachments?: DirectAttachment[],\n thinking?: string,\n ): Promise<string> {\n return runProcessDirect(this.buildOneShotDeps(), {\n content,\n sessionKey,\n attachments,\n thinking,\n });\n }\n\n /** Streaming direct turn (webchat SSE / CLI streaming). */\n async *processDirectStreaming(\n content: string,\n sessionKey = 'agent:main:main',\n attachments?: DirectAttachment[],\n thinking?: string,\n options?: { signal?: AbortSignal; runId?: string },\n ): AsyncGenerator<ProcessDirectStreamingSseEvent, void, unknown> {\n yield* runProcessDirectStreaming(this.buildStreamingDeps(), {\n content,\n sessionKey,\n attachments,\n thinking,\n signal: options?.signal,\n runId: options?.runId,\n });\n }\n\n /** Push an out-of-band event into the live webchat stream for a session. */\n enqueueWebchatSseEvent(\n sessionKey: string,\n event: { type: string; [key: string]: unknown },\n ): void {\n const pub = this.cfg.sessionState.getWebchatPublisher(sessionKey);\n if (pub) {\n pub(event);\n }\n }\n\n /** Stream assistant text to live webchat session + notify transcript listeners. */\n notifyWebchatTranscriptAppend(sessionKey: string, assistantText: string): void {\n const trimmed = assistantText.trim();\n if (trimmed) {\n const message = {\n role: 'assistant',\n content: [{ type: 'text', text: trimmed }],\n timestamp: Date.now(),\n };\n this.enqueueWebchatSseEvent(sessionKey, { type: 'message_start', message });\n this.enqueueWebchatSseEvent(sessionKey, { type: 'message_update', message });\n this.enqueueWebchatSseEvent(sessionKey, { type: 'message_end', message });\n }\n this.cfg.onSessionTranscriptUpdated?.(sessionKey);\n }\n\n /**\n * Queue a steering user message into pi-agent's in-flight run (delivered\n * after current tool work, before the next LLM call). See `Agent.steer`\n * in `@earendil-works/pi-agent-core`.\n */\n async steerWebchatSession(sessionKey: string, text: string): Promise<boolean> {\n const trimmed = text.trim();\n if (!trimmed) return false;\n try {\n return await queueEmbeddedSteer(sessionKey, trimmed);\n } catch (err) {\n this.log.warn({ err, sessionKey }, 'steerWebchatSession failed');\n return false;\n }\n }\n\n private buildStreamingDeps(): ProcessDirectStreamingDeps {\n const c = this.cfg;\n return {\n log: this.log,\n parseSessionKey: c.parseSessionKey,\n initDirectStreamingSession: c.initSessionContext,\n registerWebchatSsePublisher: (sk, publisher) =>\n c.sessionState.registerWebchatPublisher(sk, publisher),\n unregisterWebchatSsePublisher: (sk) => c.sessionState.unregisterWebchatPublisher(sk),\n agentManager: c.agentManager,\n hydrateSessionWorkspaceFromStore: (sk) => c.sessionHydrator.workspace(sk),\n hydrateSessionModelFromStore: (sk) => c.sessionHydrator.model(sk),\n sessionStore: c.sessionStore,\n modelManager: c.modelManager,\n applyResolvedThinkingLevel: (sk, t) => c.sessionHydrator.thinking(sk, t),\n getConfig: c.getConfig,\n sessionConfigStore: c.sessionConfigStore,\n commandHandler: c.commandHandler,\n prepareInboundAttachments: c.prepareInboundAttachments,\n buildTranscriptUserMessage: async (text, prepared, sk) =>\n buildDirectUserMessageContent({\n content: text,\n attachments: prepared,\n sessionKey: sk,\n config: c.requireConfig(),\n agentManager: c.agentManager,\n modelManager: c.modelManager,\n }),\n recordPersistentGoalStreamOutcome: (sk, o) =>\n c.sessionState.recordPersistentGoalStreamOutcome(sk, o),\n enqueueProvisionalSessionTitle: (sk, userText) => {\n c.enqueueProvisionalSessionTitle?.(sk, userText);\n },\n onTurnComplete: (sk, text) => {\n if (text) {\n c.sessionState.setLastAssistantText(sk, text);\n }\n c.enqueueMaybeAutoTitleAfterPersist(sk);\n },\n reloadWebchatTranscript: (sk) => {\n c.onSessionTranscriptUpdated?.(sk);\n },\n sourceContextResolver: c.sourceContextResolver,\n maybeEmitWebchatTts: (sk, hadVoice) =>\n maybeEmitWebchatTts(\n {\n config: c.getConfig(),\n sessionStore: c.sessionStore,\n getLastAssistantPlainText: (sessionKey) =>\n c.sessionState.getLastAssistantText(sessionKey) ??\n c.agentManager.getLastAssistantContent(sessionKey) ??\n '',\n log: this.log,\n },\n sk,\n hadVoice,\n ),\n endDirectRequestContext: c.endDirectRequestContext,\n resetSession: c.resetSession,\n };\n }\n\n private buildOneShotDeps(): RunProcessDirectDeps {\n const c = this.cfg;\n const cfg = c.requireConfig();\n return {\n log: this.log,\n config: cfg,\n parseSessionKey: c.parseSessionKey,\n initSessionContext: (sk, channel, chatId) => {\n void c.initSessionContext(sk, channel, chatId);\n },\n hydrateSessionWorkspaceFromStore: (sk) => c.sessionHydrator.workspace(sk),\n hydrateSessionModelFromStore: (sk) => c.sessionHydrator.model(sk),\n agentManager: c.agentManager,\n sessionStore: c.sessionStore,\n modelManager: c.modelManager,\n applyResolvedThinkingLevel: (sk, t) => c.sessionHydrator.thinking(sk, t),\n prepareInboundAttachments: c.prepareInboundAttachments,\n commandHandler: c.commandHandler,\n onTurnComplete: (sk, text) => {\n if (text) {\n c.sessionState.setLastAssistantText(sk, text);\n }\n c.enqueueMaybeAutoTitleAfterPersist(sk);\n },\n endDirectRequestContext: c.endDirectRequestContext,\n resetSession: c.resetSession,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"turn-dispatcher.js","names":[],"sources":["../../../../src/agent/inbound/turn-dispatcher.ts"],"sourcesContent":["/**\n * TurnDispatcher — single entry point for direct (non-bus) agent turns.\n *\n * Wraps the two existing direct-turn runners (one-shot and streaming) so the\n * parent `AgentService` no longer carries a pair of huge `createXxxDeps()`\n * factories. The public surface — `processDirect`, `processDirectStreaming`,\n * `steerWebchatSession`, `enqueueWebchatSseEvent`,\n * `notifyWebchatTranscriptAppend` — matches what `AgentService` exposed\n * previously, so callers (gateway, CLI) are unchanged.\n *\n * Like `OutboundCoordinator` and `InboundLoop`, this class accepts a wide\n * dependency bag in its constructor (the direct-turn pipeline touches almost\n * every other subsystem). The win is that AgentService becomes the only place\n * that wires those dependencies together; individual responsibilities now live\n * in their own classes and are unit-testable.\n */\n\nimport type { Config } from '../../config/schema.js';\nimport type { ContextualLogger } from '../../utils/logger/types.js';\n\nimport type { AgentManager } from '../agent-manager.js';\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionConfigStore } from '../../session/index.js';\nimport type { SessionStore } from '../../session/store.js';\nimport type {\n SessionContext,\n SessionHydrator,\n SessionStateBag,\n} from '../session/index.js';\nimport { queueEmbeddedSteer } from '../embedded/runs.js';\nimport type {\n InboundAttachmentInput,\n MediaRef,\n} from '../../channels/attachments/inbound-persist.js';\nimport {\n buildDirectUserMessageContent,\n} from '../service/build-direct-message-content.js';\nimport {\n runProcessDirectStreaming,\n type ProcessDirectStreamingDeps,\n type ProcessDirectStreamingSseEvent,\n} from '../service/process-direct-streaming.js';\nimport {\n runProcessDirect,\n type RunProcessDirectDeps,\n} from '../service/process-direct-one-shot.js';\nimport { maybeEmitWebchatTts } from '../service/webchat-tts.js';\nimport type { AgentSourceContextResolver } from '../source-context/types.js';\n\nexport interface TurnDispatcherConfig {\n log: ContextualLogger;\n agentManager: AgentManager;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n sessionConfigStore: SessionConfigStore;\n sessionState: SessionStateBag;\n commandHandler: CommandHandler;\n getConfig: () => Config | undefined;\n /** Strict accessor — required for direct-turn paths that must have a config. */\n requireConfig: () => Config;\n resolveSessionEndpoint: (sessionKey: string) => Promise<{ channel: string; chatId: string }>;\n /** Establish per-session context (also creates the Agent + subscribes to events). */\n initSessionContext: (sessionKey: string, channel: string, chatId: string) => SessionContext;\n /** Per-session config hydration: workspace, model, thinking. */\n sessionHydrator: SessionHydrator;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: InboundAttachmentInput[],\n ) => Promise<MediaRef[] | undefined>;\n enqueueMaybeAutoTitleAfterPersist: (sessionKey: string) => void;\n enqueueProvisionalSessionTitle?: (sessionKey: string, userText: string) => void;\n endDirectRequestContext: () => void;\n /** Gateway hook fired after assistant text lands on disk (UI refetch). */\n onSessionTranscriptUpdated?: (sessionKey: string) => void;\n resetSession: (sessionKey: string) => Promise<{ sessionId: string; previousSessionId: string } | null>;\n sourceContextResolver?: AgentSourceContextResolver;\n}\n\nexport type DirectAttachment = InboundAttachmentInput;\n\nexport class TurnDispatcher {\n private readonly cfg: TurnDispatcherConfig;\n private readonly log: ContextualLogger;\n\n constructor(cfg: TurnDispatcherConfig) {\n this.cfg = cfg;\n this.log = cfg.log;\n }\n\n /** One-shot direct turn (CLI / embedded TUI). */\n processDirect(\n content: string,\n sessionKey = 'agent:main:main',\n attachments?: DirectAttachment[],\n thinking?: string,\n ): Promise<string> {\n return runProcessDirect(this.buildOneShotDeps(), {\n content,\n sessionKey,\n attachments,\n thinking,\n });\n }\n\n /** Streaming direct turn (webchat SSE / CLI streaming). */\n async *processDirectStreaming(\n content: string,\n sessionKey = 'agent:main:main',\n attachments?: DirectAttachment[],\n thinking?: string,\n options?: { signal?: AbortSignal; runId?: string },\n ): AsyncGenerator<ProcessDirectStreamingSseEvent, void, unknown> {\n yield* runProcessDirectStreaming(this.buildStreamingDeps(), {\n content,\n sessionKey,\n attachments,\n thinking,\n signal: options?.signal,\n runId: options?.runId,\n });\n }\n\n /** Push an out-of-band event into the live webchat stream for a session. */\n enqueueWebchatSseEvent(\n sessionKey: string,\n event: { type: string; [key: string]: unknown },\n ): void {\n const pub = this.cfg.sessionState.getWebchatPublisher(sessionKey);\n if (pub) {\n pub(event);\n }\n }\n\n /** Stream assistant text to live webchat session + notify transcript listeners. */\n notifyWebchatTranscriptAppend(sessionKey: string, assistantText: string): void {\n const trimmed = assistantText.trim();\n if (trimmed) {\n const message = {\n role: 'assistant',\n content: [{ type: 'text', text: trimmed }],\n timestamp: Date.now(),\n };\n this.enqueueWebchatSseEvent(sessionKey, { type: 'message_start', message });\n this.enqueueWebchatSseEvent(sessionKey, { type: 'message_update', message });\n this.enqueueWebchatSseEvent(sessionKey, { type: 'message_end', message });\n }\n this.cfg.onSessionTranscriptUpdated?.(sessionKey);\n }\n\n /**\n * Queue a steering user message into pi-agent's in-flight run (delivered\n * after current tool work, before the next LLM call). See `Agent.steer`\n * in `@earendil-works/pi-agent-core`.\n */\n async steerWebchatSession(sessionKey: string, text: string): Promise<boolean> {\n const trimmed = text.trim();\n if (!trimmed) return false;\n try {\n return await queueEmbeddedSteer(sessionKey, trimmed);\n } catch (err) {\n this.log.warn({ err, sessionKey }, 'steerWebchatSession failed');\n return false;\n }\n }\n\n private buildStreamingDeps(): ProcessDirectStreamingDeps {\n const c = this.cfg;\n return {\n log: this.log,\n resolveSessionEndpoint: c.resolveSessionEndpoint,\n initDirectStreamingSession: c.initSessionContext,\n registerWebchatSsePublisher: (sk, publisher) =>\n c.sessionState.registerWebchatPublisher(sk, publisher),\n unregisterWebchatSsePublisher: (sk) => c.sessionState.unregisterWebchatPublisher(sk),\n agentManager: c.agentManager,\n hydrateSessionWorkspaceFromStore: (sk) => c.sessionHydrator.workspace(sk),\n hydrateSessionModelFromStore: (sk) => c.sessionHydrator.model(sk),\n sessionStore: c.sessionStore,\n modelManager: c.modelManager,\n applyResolvedThinkingLevel: (sk, t) => c.sessionHydrator.thinking(sk, t),\n getConfig: c.getConfig,\n sessionConfigStore: c.sessionConfigStore,\n commandHandler: c.commandHandler,\n prepareInboundAttachments: c.prepareInboundAttachments,\n buildTranscriptUserMessage: async (text, prepared, sk) =>\n buildDirectUserMessageContent({\n content: text,\n attachments: prepared,\n sessionKey: sk,\n config: c.requireConfig(),\n agentManager: c.agentManager,\n modelManager: c.modelManager,\n }),\n recordPersistentGoalStreamOutcome: (sk, o) =>\n c.sessionState.recordPersistentGoalStreamOutcome(sk, o),\n enqueueProvisionalSessionTitle: (sk, userText) => {\n c.enqueueProvisionalSessionTitle?.(sk, userText);\n },\n onTurnComplete: (sk, text) => {\n if (text) {\n c.sessionState.setLastAssistantText(sk, text);\n }\n c.enqueueMaybeAutoTitleAfterPersist(sk);\n },\n reloadWebchatTranscript: (sk) => {\n c.onSessionTranscriptUpdated?.(sk);\n },\n sourceContextResolver: c.sourceContextResolver,\n maybeEmitWebchatTts: (sk, hadVoice) =>\n maybeEmitWebchatTts(\n {\n config: c.getConfig(),\n sessionStore: c.sessionStore,\n getLastAssistantPlainText: (sessionKey) =>\n c.sessionState.getLastAssistantText(sessionKey) ??\n c.agentManager.getLastAssistantContent(sessionKey) ??\n '',\n log: this.log,\n },\n sk,\n hadVoice,\n ),\n endDirectRequestContext: c.endDirectRequestContext,\n resetSession: c.resetSession,\n };\n }\n\n private buildOneShotDeps(): RunProcessDirectDeps {\n const c = this.cfg;\n const cfg = c.requireConfig();\n return {\n log: this.log,\n config: cfg,\n resolveSessionEndpoint: c.resolveSessionEndpoint,\n initSessionContext: (sk, channel, chatId) => {\n void c.initSessionContext(sk, channel, chatId);\n },\n hydrateSessionWorkspaceFromStore: (sk) => c.sessionHydrator.workspace(sk),\n hydrateSessionModelFromStore: (sk) => c.sessionHydrator.model(sk),\n agentManager: c.agentManager,\n sessionStore: c.sessionStore,\n modelManager: c.modelManager,\n applyResolvedThinkingLevel: (sk, t) => c.sessionHydrator.thinking(sk, t),\n prepareInboundAttachments: c.prepareInboundAttachments,\n commandHandler: c.commandHandler,\n onTurnComplete: (sk, text) => {\n if (text) {\n c.sessionState.setLastAssistantText(sk, text);\n }\n c.enqueueMaybeAutoTitleAfterPersist(sk);\n },\n endDirectRequestContext: c.endDirectRequestContext,\n resetSession: c.resetSession,\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
|
|
2
|
-
import { init_paths, resolveAgentDir } from "../../config/paths.js";
|
|
3
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
4
2
|
import { init_logger } from "../../utils/logger.js";
|
|
5
|
-
import {
|
|
3
|
+
import { init_paths, resolveAgentDir } from "../../config/paths.js";
|
|
4
|
+
import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
|
|
6
5
|
import { join } from "path";
|
|
6
|
+
import { existsSync, watch } from "fs";
|
|
7
7
|
import { mkdir, readFile, readdir, rename } from "fs/promises";
|
|
8
8
|
//#region src/agent/ipc/inbox.ts
|
|
9
9
|
init_write_file_atomic();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { init_paths, resolveSocketPath } from "../../config/paths.js";
|
|
2
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
3
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { init_paths, resolveSocketPath } from "../../config/paths.js";
|
|
4
4
|
import { isValidIPCMessage } from "./types.js";
|
|
5
5
|
import { dirname } from "path";
|
|
6
6
|
import { mkdir } from "fs/promises";
|
|
@@ -6,12 +6,39 @@ export type McpGatewayToolEntry = {
|
|
|
6
6
|
shortName: string;
|
|
7
7
|
description: string;
|
|
8
8
|
};
|
|
9
|
+
export type McpGatewayResourceEntry = {
|
|
10
|
+
uri: string;
|
|
11
|
+
name: string;
|
|
12
|
+
title?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
mimeType?: string;
|
|
15
|
+
};
|
|
16
|
+
export type McpGatewayPromptEntry = {
|
|
17
|
+
name: string;
|
|
18
|
+
title?: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
argumentCount: number;
|
|
21
|
+
};
|
|
22
|
+
export type McpGatewayCapabilitySummary = {
|
|
23
|
+
serverId: string;
|
|
24
|
+
toolCount: number;
|
|
25
|
+
resourceCount: number;
|
|
26
|
+
promptCount: number;
|
|
27
|
+
tools: McpGatewayToolEntry[];
|
|
28
|
+
resources: McpGatewayResourceEntry[];
|
|
29
|
+
prompts: McpGatewayPromptEntry[];
|
|
30
|
+
};
|
|
9
31
|
export declare function mapBundleMcpToolsForGateway(tools: AnyAgentTool[], serverId: string): McpGatewayToolEntry[];
|
|
10
32
|
export declare function listBundleMcpServerToolsForGateway(params: {
|
|
11
33
|
workspaceDir: string;
|
|
12
34
|
cfg?: Config;
|
|
13
35
|
serverId: string;
|
|
14
36
|
}): Promise<McpGatewayToolEntry[]>;
|
|
37
|
+
export declare function listBundleMcpServerCapabilitiesForGateway(params: {
|
|
38
|
+
workspaceDir: string;
|
|
39
|
+
cfg?: Config;
|
|
40
|
+
serverId: string;
|
|
41
|
+
}): Promise<McpGatewayCapabilitySummary>;
|
|
15
42
|
export declare function materializeBundleMcpToolsForRun(params: {
|
|
16
43
|
runtime: SessionMcpRuntime;
|
|
17
44
|
reservedToolNames?: Iterable<string>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { init_string_coerce, normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "../../utils/string-coerce.js";
|
|
1
2
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
3
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { init_string_coerce, normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "../../utils/string-coerce.js";
|
|
4
4
|
import { buildSafeToolName, normalizeReservedToolNames } from "./bundle-mcp-names.js";
|
|
5
5
|
import { setPluginToolMeta } from "./mcp-tool-meta.js";
|
|
6
6
|
import crypto from "node:crypto";
|
|
@@ -31,6 +31,54 @@ async function listBundleMcpServerToolsForGateway(params) {
|
|
|
31
31
|
await runtime.dispose();
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
+
function mapBundleMcpResourcesForGateway(resources, serverId) {
|
|
35
|
+
return resources.filter((resource) => resource.serverName === serverId).map((resource) => ({
|
|
36
|
+
uri: resource.uri,
|
|
37
|
+
name: resource.name,
|
|
38
|
+
title: resource.title,
|
|
39
|
+
description: resource.description,
|
|
40
|
+
mimeType: resource.mimeType
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
function mapBundleMcpPromptsForGateway(prompts, serverId) {
|
|
44
|
+
return prompts.filter((prompt) => prompt.serverName === serverId).map((prompt) => ({
|
|
45
|
+
name: prompt.name,
|
|
46
|
+
title: prompt.title,
|
|
47
|
+
description: prompt.description,
|
|
48
|
+
argumentCount: prompt.argumentCount
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
async function listBundleMcpServerCapabilitiesForGateway(params) {
|
|
52
|
+
const createRuntime = (await import("./bundle-mcp-runtime.js")).createSessionMcpRuntime;
|
|
53
|
+
const runtime = createRuntime({
|
|
54
|
+
sessionId: `bundle-mcp:${crypto.randomUUID()}`,
|
|
55
|
+
workspaceDir: params.workspaceDir,
|
|
56
|
+
cfg: params.cfg
|
|
57
|
+
});
|
|
58
|
+
try {
|
|
59
|
+
const catalog = await runtime.getCatalog();
|
|
60
|
+
const tools = mapBundleMcpToolsForGateway(await materializeBundleMcpToolsForRun({ runtime }).then(async (toolRuntime) => {
|
|
61
|
+
try {
|
|
62
|
+
return toolRuntime.tools;
|
|
63
|
+
} finally {
|
|
64
|
+
await toolRuntime.dispose();
|
|
65
|
+
}
|
|
66
|
+
}), params.serverId);
|
|
67
|
+
const resources = mapBundleMcpResourcesForGateway(catalog.resources, params.serverId);
|
|
68
|
+
const prompts = mapBundleMcpPromptsForGateway(catalog.prompts, params.serverId);
|
|
69
|
+
return {
|
|
70
|
+
serverId: params.serverId,
|
|
71
|
+
toolCount: tools.length,
|
|
72
|
+
resourceCount: resources.length,
|
|
73
|
+
promptCount: prompts.length,
|
|
74
|
+
tools,
|
|
75
|
+
resources,
|
|
76
|
+
prompts
|
|
77
|
+
};
|
|
78
|
+
} finally {
|
|
79
|
+
await runtime.dispose();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
34
82
|
function toAgentToolResult(params) {
|
|
35
83
|
const content = Array.isArray(params.result.content) ? params.result.content : [];
|
|
36
84
|
const normalizedContent = content.length > 0 ? content : params.result.structuredContent !== void 0 ? [{
|
|
@@ -132,6 +180,6 @@ async function createBundleMcpToolRuntime(params) {
|
|
|
132
180
|
});
|
|
133
181
|
}
|
|
134
182
|
//#endregion
|
|
135
|
-
export { createBundleMcpToolRuntime, listBundleMcpServerToolsForGateway, mapBundleMcpToolsForGateway, materializeBundleMcpToolsForRun };
|
|
183
|
+
export { createBundleMcpToolRuntime, listBundleMcpServerCapabilitiesForGateway, listBundleMcpServerToolsForGateway, mapBundleMcpToolsForGateway, materializeBundleMcpToolsForRun };
|
|
136
184
|
|
|
137
185
|
//# sourceMappingURL=bundle-mcp-materialize.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundle-mcp-materialize.js","names":[],"sources":["../../../../src/agent/mcp/bundle-mcp-materialize.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport type { AgentToolResult } from '@earendil-works/pi-agent-core';\nimport type { AgentTool as AnyAgentTool } from \"@earendil-works/pi-agent-core\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { Config } from \"../../config/schema.js\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"Mcp:Bundle\");\nimport { setPluginToolMeta } from \"./mcp-tool-meta.js\";\nimport {\n normalizeLowercaseStringOrEmpty,\n normalizeOptionalString,\n} from \"../../utils/string-coerce.js\";\nimport {\n buildSafeToolName,\n normalizeReservedToolNames,\n TOOL_NAME_SEPARATOR,\n} from \"./bundle-mcp-names.js\";\nimport type { BundleMcpToolRuntime, SessionMcpRuntime } from \"./bundle-mcp-types.js\";\n\nexport type McpGatewayToolEntry = {\n name: string;\n shortName: string;\n description: string;\n};\n\nfunction readMaterializedToolDescription(tool: AnyAgentTool): string {\n const raw = tool as { description?: unknown; label?: unknown };\n return (\n normalizeOptionalString(raw.description) ??\n normalizeOptionalString(raw.label) ??\n tool.name\n );\n}\n\nexport function mapBundleMcpToolsForGateway(\n tools: AnyAgentTool[],\n serverId: string,\n): McpGatewayToolEntry[] {\n const prefix = `${serverId.trim()}${TOOL_NAME_SEPARATOR}`;\n return tools\n .filter((tool) => tool.name.startsWith(prefix))\n .map((tool) => ({\n name: tool.name,\n shortName: tool.name.slice(prefix.length),\n description: readMaterializedToolDescription(tool),\n }));\n}\n\nexport async function listBundleMcpServerToolsForGateway(params: {\n workspaceDir: string;\n cfg?: Config;\n serverId: string;\n}): Promise<McpGatewayToolEntry[]> {\n const runtime = await createBundleMcpToolRuntime({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n try {\n return mapBundleMcpToolsForGateway(runtime.tools, params.serverId);\n } finally {\n await runtime.dispose();\n }\n}\n\nfunction toAgentToolResult(params: {\n serverName: string;\n toolName: string;\n result: CallToolResult;\n}): AgentToolResult<unknown> {\n const content = Array.isArray(params.result.content)\n ? (params.result.content as AgentToolResult<unknown>[\"content\"])\n : [];\n const normalizedContent: AgentToolResult<unknown>[\"content\"] =\n content.length > 0\n ? content\n : params.result.structuredContent !== undefined\n ? [\n {\n type: \"text\",\n text: JSON.stringify(params.result.structuredContent, null, 2),\n },\n ]\n : ([\n {\n type: \"text\",\n text: JSON.stringify(\n {\n status: params.result.isError === true ? \"error\" : \"ok\",\n server: params.serverName,\n tool: params.toolName,\n },\n null,\n 2,\n ),\n },\n ] as AgentToolResult<unknown>[\"content\"]);\n const details: Record<string, unknown> = {\n mcpServer: params.serverName,\n mcpTool: params.toolName,\n };\n if (params.result.structuredContent !== undefined) {\n details.structuredContent = params.result.structuredContent;\n }\n if (params.result.isError === true) {\n details.status = \"error\";\n }\n return {\n content: normalizedContent,\n details,\n };\n}\n\nexport async function materializeBundleMcpToolsForRun(params: {\n runtime: SessionMcpRuntime;\n reservedToolNames?: Iterable<string>;\n disposeRuntime?: () => Promise<void>;\n}): Promise<BundleMcpToolRuntime> {\n let disposed = false;\n const releaseLease = params.runtime.acquireLease?.();\n params.runtime.markUsed();\n let catalog;\n try {\n catalog = await params.runtime.getCatalog();\n } catch (error) {\n releaseLease?.();\n throw error;\n }\n const reservedNames = normalizeReservedToolNames(params.reservedToolNames);\n const tools: BundleMcpToolRuntime[\"tools\"] = [];\n const sortedCatalogTools = [...catalog.tools].toSorted((a, b) => {\n const serverOrder = a.safeServerName.localeCompare(b.safeServerName);\n if (serverOrder !== 0) {\n return serverOrder;\n }\n const toolOrder = a.toolName.localeCompare(b.toolName);\n if (toolOrder !== 0) {\n return toolOrder;\n }\n return a.serverName.localeCompare(b.serverName);\n });\n\n for (const tool of sortedCatalogTools) {\n const originalName = tool.toolName.trim();\n if (!originalName) {\n continue;\n }\n const safeToolName = buildSafeToolName({\n serverName: tool.safeServerName,\n toolName: originalName,\n reservedNames,\n });\n if (safeToolName !== `${tool.safeServerName}${TOOL_NAME_SEPARATOR}${originalName}`) {\n log.warn(\n `bundle-mcp: tool \"${tool.toolName}\" from server \"${tool.serverName}\" registered as \"${safeToolName}\" to keep the tool name provider-safe.`,\n );\n }\n reservedNames.add(normalizeLowercaseStringOrEmpty(safeToolName));\n const agentTool = {\n name: safeToolName,\n label: tool.title ?? tool.toolName,\n description: tool.description || tool.title || tool.fallbackDescription,\n parameters: tool.inputSchema,\n execute: async (_toolCallId: string, input: unknown) => {\n params.runtime.markUsed();\n const result = await params.runtime.callTool(tool.serverName, tool.toolName, input);\n return toAgentToolResult({\n serverName: tool.serverName,\n toolName: tool.toolName,\n result,\n });\n },\n } as unknown as AnyAgentTool;\n setPluginToolMeta(agentTool, {\n pluginId: \"bundle-mcp\",\n optional: false,\n });\n tools.push(agentTool);\n }\n\n // Sort tools deterministically by name so the tools block in API requests is stable across\n // turns (defensive — listTools() order is usually stable but not guaranteed).\n // Cannot fix name collisions: collision suffixes above are order-dependent.\n tools.sort((a, b) => a.name.localeCompare(b.name));\n\n return {\n tools,\n dispose: async () => {\n if (disposed) {\n return;\n }\n disposed = true;\n releaseLease?.();\n await params.disposeRuntime?.();\n },\n };\n}\n\nexport async function createBundleMcpToolRuntime(params: {\n workspaceDir: string;\n cfg?: Config;\n reservedToolNames?: Iterable<string>;\n createRuntime?: (params: {\n sessionId: string;\n workspaceDir: string;\n cfg?: Config;\n }) => SessionMcpRuntime;\n}): Promise<BundleMcpToolRuntime> {\n const createRuntime =\n params.createRuntime ?? (await import(\"./bundle-mcp-runtime.js\")).createSessionMcpRuntime;\n const runtime = createRuntime({\n sessionId: `bundle-mcp:${crypto.randomUUID()}`,\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n const materialized = await materializeBundleMcpToolsForRun({\n runtime,\n reservedToolNames: params.reservedToolNames,\n disposeRuntime: async () => {\n await runtime.dispose();\n },\n });\n return materialized;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bundle-mcp-materialize.js","names":[],"sources":["../../../../src/agent/mcp/bundle-mcp-materialize.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport type { AgentToolResult } from '@earendil-works/pi-agent-core';\nimport type { AgentTool as AnyAgentTool } from \"@earendil-works/pi-agent-core\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { Config } from \"../../config/schema.js\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"Mcp:Bundle\");\nimport { setPluginToolMeta } from \"./mcp-tool-meta.js\";\nimport {\n normalizeLowercaseStringOrEmpty,\n normalizeOptionalString,\n} from \"../../utils/string-coerce.js\";\nimport {\n buildSafeToolName,\n normalizeReservedToolNames,\n TOOL_NAME_SEPARATOR,\n} from \"./bundle-mcp-names.js\";\nimport type { BundleMcpToolRuntime, SessionMcpRuntime } from \"./bundle-mcp-types.js\";\nimport type { McpCatalogPrompt, McpCatalogResource } from \"./bundle-mcp-types.js\";\n\nexport type McpGatewayToolEntry = {\n name: string;\n shortName: string;\n description: string;\n};\n\nexport type McpGatewayResourceEntry = {\n uri: string;\n name: string;\n title?: string;\n description?: string;\n mimeType?: string;\n};\n\nexport type McpGatewayPromptEntry = {\n name: string;\n title?: string;\n description?: string;\n argumentCount: number;\n};\n\nexport type McpGatewayCapabilitySummary = {\n serverId: string;\n toolCount: number;\n resourceCount: number;\n promptCount: number;\n tools: McpGatewayToolEntry[];\n resources: McpGatewayResourceEntry[];\n prompts: McpGatewayPromptEntry[];\n};\n\nfunction readMaterializedToolDescription(tool: AnyAgentTool): string {\n const raw = tool as { description?: unknown; label?: unknown };\n return (\n normalizeOptionalString(raw.description) ??\n normalizeOptionalString(raw.label) ??\n tool.name\n );\n}\n\nexport function mapBundleMcpToolsForGateway(\n tools: AnyAgentTool[],\n serverId: string,\n): McpGatewayToolEntry[] {\n const prefix = `${serverId.trim()}${TOOL_NAME_SEPARATOR}`;\n return tools\n .filter((tool) => tool.name.startsWith(prefix))\n .map((tool) => ({\n name: tool.name,\n shortName: tool.name.slice(prefix.length),\n description: readMaterializedToolDescription(tool),\n }));\n}\n\nexport async function listBundleMcpServerToolsForGateway(params: {\n workspaceDir: string;\n cfg?: Config;\n serverId: string;\n}): Promise<McpGatewayToolEntry[]> {\n const runtime = await createBundleMcpToolRuntime({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n try {\n return mapBundleMcpToolsForGateway(runtime.tools, params.serverId);\n } finally {\n await runtime.dispose();\n }\n}\n\nfunction mapBundleMcpResourcesForGateway(\n resources: McpCatalogResource[],\n serverId: string,\n): McpGatewayResourceEntry[] {\n return resources\n .filter((resource) => resource.serverName === serverId)\n .map((resource) => ({\n uri: resource.uri,\n name: resource.name,\n title: resource.title,\n description: resource.description,\n mimeType: resource.mimeType,\n }));\n}\n\nfunction mapBundleMcpPromptsForGateway(\n prompts: McpCatalogPrompt[],\n serverId: string,\n): McpGatewayPromptEntry[] {\n return prompts\n .filter((prompt) => prompt.serverName === serverId)\n .map((prompt) => ({\n name: prompt.name,\n title: prompt.title,\n description: prompt.description,\n argumentCount: prompt.argumentCount,\n }));\n}\n\nexport async function listBundleMcpServerCapabilitiesForGateway(params: {\n workspaceDir: string;\n cfg?: Config;\n serverId: string;\n}): Promise<McpGatewayCapabilitySummary> {\n const createRuntime =\n (await import(\"./bundle-mcp-runtime.js\")).createSessionMcpRuntime;\n const runtime = createRuntime({\n sessionId: `bundle-mcp:${crypto.randomUUID()}`,\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n try {\n const catalog = await runtime.getCatalog();\n const tools = mapBundleMcpToolsForGateway(\n await materializeBundleMcpToolsForRun({ runtime }).then(async (toolRuntime) => {\n try {\n return toolRuntime.tools;\n } finally {\n await toolRuntime.dispose();\n }\n }),\n params.serverId,\n );\n const resources = mapBundleMcpResourcesForGateway(catalog.resources, params.serverId);\n const prompts = mapBundleMcpPromptsForGateway(catalog.prompts, params.serverId);\n return {\n serverId: params.serverId,\n toolCount: tools.length,\n resourceCount: resources.length,\n promptCount: prompts.length,\n tools,\n resources,\n prompts,\n };\n } finally {\n await runtime.dispose();\n }\n}\n\nfunction toAgentToolResult(params: {\n serverName: string;\n toolName: string;\n result: CallToolResult;\n}): AgentToolResult<unknown> {\n const content = Array.isArray(params.result.content)\n ? (params.result.content as AgentToolResult<unknown>[\"content\"])\n : [];\n const normalizedContent: AgentToolResult<unknown>[\"content\"] =\n content.length > 0\n ? content\n : params.result.structuredContent !== undefined\n ? [\n {\n type: \"text\",\n text: JSON.stringify(params.result.structuredContent, null, 2),\n },\n ]\n : ([\n {\n type: \"text\",\n text: JSON.stringify(\n {\n status: params.result.isError === true ? \"error\" : \"ok\",\n server: params.serverName,\n tool: params.toolName,\n },\n null,\n 2,\n ),\n },\n ] as AgentToolResult<unknown>[\"content\"]);\n const details: Record<string, unknown> = {\n mcpServer: params.serverName,\n mcpTool: params.toolName,\n };\n if (params.result.structuredContent !== undefined) {\n details.structuredContent = params.result.structuredContent;\n }\n if (params.result.isError === true) {\n details.status = \"error\";\n }\n return {\n content: normalizedContent,\n details,\n };\n}\n\nexport async function materializeBundleMcpToolsForRun(params: {\n runtime: SessionMcpRuntime;\n reservedToolNames?: Iterable<string>;\n disposeRuntime?: () => Promise<void>;\n}): Promise<BundleMcpToolRuntime> {\n let disposed = false;\n const releaseLease = params.runtime.acquireLease?.();\n params.runtime.markUsed();\n let catalog;\n try {\n catalog = await params.runtime.getCatalog();\n } catch (error) {\n releaseLease?.();\n throw error;\n }\n const reservedNames = normalizeReservedToolNames(params.reservedToolNames);\n const tools: BundleMcpToolRuntime[\"tools\"] = [];\n const sortedCatalogTools = [...catalog.tools].toSorted((a, b) => {\n const serverOrder = a.safeServerName.localeCompare(b.safeServerName);\n if (serverOrder !== 0) {\n return serverOrder;\n }\n const toolOrder = a.toolName.localeCompare(b.toolName);\n if (toolOrder !== 0) {\n return toolOrder;\n }\n return a.serverName.localeCompare(b.serverName);\n });\n\n for (const tool of sortedCatalogTools) {\n const originalName = tool.toolName.trim();\n if (!originalName) {\n continue;\n }\n const safeToolName = buildSafeToolName({\n serverName: tool.safeServerName,\n toolName: originalName,\n reservedNames,\n });\n if (safeToolName !== `${tool.safeServerName}${TOOL_NAME_SEPARATOR}${originalName}`) {\n log.warn(\n `bundle-mcp: tool \"${tool.toolName}\" from server \"${tool.serverName}\" registered as \"${safeToolName}\" to keep the tool name provider-safe.`,\n );\n }\n reservedNames.add(normalizeLowercaseStringOrEmpty(safeToolName));\n const agentTool = {\n name: safeToolName,\n label: tool.title ?? tool.toolName,\n description: tool.description || tool.title || tool.fallbackDescription,\n parameters: tool.inputSchema,\n execute: async (_toolCallId: string, input: unknown) => {\n params.runtime.markUsed();\n const result = await params.runtime.callTool(tool.serverName, tool.toolName, input);\n return toAgentToolResult({\n serverName: tool.serverName,\n toolName: tool.toolName,\n result,\n });\n },\n } as unknown as AnyAgentTool;\n setPluginToolMeta(agentTool, {\n pluginId: \"bundle-mcp\",\n optional: false,\n });\n tools.push(agentTool);\n }\n\n // Sort tools deterministically by name so the tools block in API requests is stable across\n // turns (defensive — listTools() order is usually stable but not guaranteed).\n // Cannot fix name collisions: collision suffixes above are order-dependent.\n tools.sort((a, b) => a.name.localeCompare(b.name));\n\n return {\n tools,\n dispose: async () => {\n if (disposed) {\n return;\n }\n disposed = true;\n releaseLease?.();\n await params.disposeRuntime?.();\n },\n };\n}\n\nexport async function createBundleMcpToolRuntime(params: {\n workspaceDir: string;\n cfg?: Config;\n reservedToolNames?: Iterable<string>;\n createRuntime?: (params: {\n sessionId: string;\n workspaceDir: string;\n cfg?: Config;\n }) => SessionMcpRuntime;\n}): Promise<BundleMcpToolRuntime> {\n const createRuntime =\n params.createRuntime ?? (await import(\"./bundle-mcp-runtime.js\")).createSessionMcpRuntime;\n const runtime = createRuntime({\n sessionId: `bundle-mcp:${crypto.randomUUID()}`,\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n const materialized = await materializeBundleMcpToolsForRun({\n runtime,\n reservedToolNames: params.reservedToolNames,\n disposeRuntime: async () => {\n await runtime.dispose();\n },\n });\n return materialized;\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
|
|
1
2
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
3
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
|
|
4
4
|
import { resolveGlobalSingleton } from "../../utils/global-singleton.js";
|
|
5
5
|
import { sanitizeServerName } from "./bundle-mcp-names.js";
|
|
6
6
|
import { redactSensitiveUrlLikeString } from "../../utils/redact-sensitive-url.js";
|
|
@@ -73,6 +73,39 @@ async function listAllTools(client) {
|
|
|
73
73
|
} while (cursor);
|
|
74
74
|
return tools;
|
|
75
75
|
}
|
|
76
|
+
async function listAllResources(client) {
|
|
77
|
+
const resources = [];
|
|
78
|
+
let cursor;
|
|
79
|
+
do {
|
|
80
|
+
const page = await client.listResources(cursor ? { cursor } : void 0);
|
|
81
|
+
resources.push(...page.resources);
|
|
82
|
+
cursor = page.nextCursor;
|
|
83
|
+
} while (cursor);
|
|
84
|
+
return resources;
|
|
85
|
+
}
|
|
86
|
+
async function listAllPrompts(client) {
|
|
87
|
+
const prompts = [];
|
|
88
|
+
let cursor;
|
|
89
|
+
do {
|
|
90
|
+
const page = await client.listPrompts(cursor ? { cursor } : void 0);
|
|
91
|
+
prompts.push(...page.prompts);
|
|
92
|
+
cursor = page.nextCursor;
|
|
93
|
+
} while (cursor);
|
|
94
|
+
return prompts;
|
|
95
|
+
}
|
|
96
|
+
async function listOptionalMcpCapability(params) {
|
|
97
|
+
try {
|
|
98
|
+
return await params.list();
|
|
99
|
+
} catch (error) {
|
|
100
|
+
log.debug({
|
|
101
|
+
phase: "agent.mcp_connect",
|
|
102
|
+
serverName: params.serverName,
|
|
103
|
+
capability: params.capability,
|
|
104
|
+
errorMessage: redactErrorUrls(error)
|
|
105
|
+
}, `bundle-mcp: server "${params.serverName}" did not list ${params.capability}`);
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
76
109
|
async function disposeSession(session) {
|
|
77
110
|
session.detachStderr?.();
|
|
78
111
|
if (session.transportType === "streamable-http") await session.transport.terminateSession().catch(() => {});
|
|
@@ -130,10 +163,14 @@ function createSessionMcpRuntime(params) {
|
|
|
130
163
|
version: 1,
|
|
131
164
|
generatedAt: Date.now(),
|
|
132
165
|
servers: {},
|
|
133
|
-
tools: []
|
|
166
|
+
tools: [],
|
|
167
|
+
resources: [],
|
|
168
|
+
prompts: []
|
|
134
169
|
};
|
|
135
170
|
const servers = {};
|
|
136
171
|
const tools = [];
|
|
172
|
+
const resources = [];
|
|
173
|
+
const prompts = [];
|
|
137
174
|
const usedServerNames = /* @__PURE__ */ new Set();
|
|
138
175
|
try {
|
|
139
176
|
for (const [serverName, rawServer] of Object.entries(loaded.mcpServers)) {
|
|
@@ -163,11 +200,23 @@ function createSessionMcpRuntime(params) {
|
|
|
163
200
|
await connectWithTimeout(client, resolved.transport, resolved.connectionTimeoutMs);
|
|
164
201
|
failIfDisposed();
|
|
165
202
|
const listedTools = await listAllTools(client);
|
|
203
|
+
const listedResources = await listOptionalMcpCapability({
|
|
204
|
+
serverName,
|
|
205
|
+
capability: "resources",
|
|
206
|
+
list: () => listAllResources(client)
|
|
207
|
+
});
|
|
208
|
+
const listedPrompts = await listOptionalMcpCapability({
|
|
209
|
+
serverName,
|
|
210
|
+
capability: "prompts",
|
|
211
|
+
list: () => listAllPrompts(client)
|
|
212
|
+
});
|
|
166
213
|
failIfDisposed();
|
|
167
214
|
servers[serverName] = {
|
|
168
215
|
serverName,
|
|
169
216
|
launchSummary: resolved.description,
|
|
170
|
-
toolCount: listedTools.length
|
|
217
|
+
toolCount: listedTools.length,
|
|
218
|
+
resourceCount: listedResources.length,
|
|
219
|
+
promptCount: listedPrompts.length
|
|
171
220
|
};
|
|
172
221
|
for (const tool of listedTools) {
|
|
173
222
|
const toolName = tool.name.trim();
|
|
@@ -182,6 +231,30 @@ function createSessionMcpRuntime(params) {
|
|
|
182
231
|
fallbackDescription: `Provided by bundle MCP server "${serverName}" (${resolved.description}).`
|
|
183
232
|
});
|
|
184
233
|
}
|
|
234
|
+
for (const resource of listedResources) {
|
|
235
|
+
const uri = resource.uri.trim();
|
|
236
|
+
const name = resource.name.trim();
|
|
237
|
+
if (!uri || !name) continue;
|
|
238
|
+
resources.push({
|
|
239
|
+
serverName,
|
|
240
|
+
uri,
|
|
241
|
+
name,
|
|
242
|
+
title: resource.title,
|
|
243
|
+
description: normalizeOptionalString(resource.description),
|
|
244
|
+
mimeType: normalizeOptionalString(resource.mimeType)
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
for (const prompt of listedPrompts) {
|
|
248
|
+
const name = prompt.name.trim();
|
|
249
|
+
if (!name) continue;
|
|
250
|
+
prompts.push({
|
|
251
|
+
serverName,
|
|
252
|
+
name,
|
|
253
|
+
title: prompt.title,
|
|
254
|
+
description: normalizeOptionalString(prompt.description),
|
|
255
|
+
argumentCount: Array.isArray(prompt.arguments) ? prompt.arguments.length : 0
|
|
256
|
+
});
|
|
257
|
+
}
|
|
185
258
|
} catch (error) {
|
|
186
259
|
if (!disposed) log.warn(`bundle-mcp: failed to start server "${serverName}" (${resolved.description}): ${redactErrorUrls(error)}`);
|
|
187
260
|
await disposeSession(session);
|
|
@@ -194,7 +267,9 @@ function createSessionMcpRuntime(params) {
|
|
|
194
267
|
version: 1,
|
|
195
268
|
generatedAt: Date.now(),
|
|
196
269
|
servers,
|
|
197
|
-
tools
|
|
270
|
+
tools,
|
|
271
|
+
resources,
|
|
272
|
+
prompts
|
|
198
273
|
};
|
|
199
274
|
} catch (error) {
|
|
200
275
|
await Promise.allSettled(Array.from(sessions.values(), (session) => disposeSession(session)));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundle-mcp-runtime.js","names":[],"sources":["../../../../src/agent/mcp/bundle-mcp-runtime.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport Ajv2020 from \"ajv/dist/2020.js\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { AjvJsonSchemaValidator } from \"@modelcontextprotocol/sdk/validation/ajv-provider.js\";\nimport type {\n JsonSchemaType,\n JsonSchemaValidator,\n jsonSchemaValidator,\n} from \"@modelcontextprotocol/sdk/validation/types.js\";\nimport type { Config } from \"../../config/schema.js\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"Mcp:Bundle\");\nimport { resolveGlobalSingleton } from \"../../utils/global-singleton.js\";\nimport { redactSensitiveUrlLikeString } from \"../../utils/redact-sensitive-url.js\";\nimport { normalizeOptionalString } from \"../../utils/string-coerce.js\";\nimport { loadEmbeddedMcpConfig } from \"./embedded-mcp.js\";\nimport { resolveConnectorSecretReferences } from \"../../connectors/secret-store.js\";\nimport { isMcpConfigRecord } from \"./mcp-config-shared.js\";\nimport { resolveMcpTransport } from \"./mcp-transport.js\";\nimport { sanitizeServerName } from \"./bundle-mcp-names.js\";\nimport type {\n McpCatalogTool,\n McpServerCatalog,\n McpToolCatalog,\n SessionMcpRuntime,\n SessionMcpRuntimeManager,\n} from \"./bundle-mcp-types.js\";\n\ntype BundleMcpSession = {\n serverName: string;\n client: Client;\n transport: Transport;\n transportType: \"stdio\" | \"sse\" | \"streamable-http\";\n detachStderr?: () => void;\n};\n\ntype LoadedMcpConfig = ReturnType<typeof loadEmbeddedMcpConfig>;\ntype ListedTool = Awaited<ReturnType<Client[\"listTools\"]>>[\"tools\"][number];\ntype CreateSessionMcpRuntime = (\n params: Parameters<typeof createSessionMcpRuntime>[0] & { configFingerprint?: string },\n) => SessionMcpRuntime;\n\nconst SESSION_MCP_RUNTIME_MANAGER_KEY = Symbol.for(\"xopc.sessionMcpRuntimeManager\");\nconst DRAFT_2020_12_SCHEMA = \"https://json-schema.org/draft/2020-12/schema\";\nconst DEFAULT_SESSION_MCP_RUNTIME_IDLE_TTL_MS = 10 * 60 * 1000;\nconst SESSION_MCP_RUNTIME_SWEEP_INTERVAL_MS = 60 * 1000;\n\nfunction isDraft202012Schema(schema: JsonSchemaType): boolean {\n return (schema as { $schema?: unknown }).$schema === DRAFT_2020_12_SCHEMA;\n}\n\nexport function createBundleMcpJsonSchemaValidator(): jsonSchemaValidator {\n const defaultValidator = new AjvJsonSchemaValidator();\n const ajv2020 = new Ajv2020({\n strict: false,\n validateFormats: false,\n validateSchema: false,\n allErrors: true,\n });\n\n return {\n getValidator<T>(schema: JsonSchemaType): JsonSchemaValidator<T> {\n if (!isDraft202012Schema(schema)) {\n return defaultValidator.getValidator<T>(schema);\n }\n const ajvValidator = ajv2020.compile(schema);\n return (input: unknown) => {\n const valid = ajvValidator(input);\n if (valid) {\n return {\n valid: true,\n data: input as T,\n errorMessage: undefined,\n };\n }\n return {\n valid: false,\n data: undefined,\n errorMessage: ajv2020.errorsText(ajvValidator.errors),\n };\n };\n },\n };\n}\n\nfunction connectWithTimeout(\n client: Client,\n transport: Transport,\n timeoutMs: number,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const timer = setTimeout(\n () => reject(new Error(`MCP server connection timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n client.connect(transport).then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n}\n\nfunction redactErrorUrls(error: unknown): string {\n return redactSensitiveUrlLikeString(String(error));\n}\n\nasync function listAllTools(client: Client) {\n const tools: ListedTool[] = [];\n let cursor: string | undefined;\n do {\n const page = await client.listTools(cursor ? { cursor } : undefined);\n tools.push(...page.tools);\n cursor = page.nextCursor;\n } while (cursor);\n return tools;\n}\n\nasync function disposeSession(session: BundleMcpSession) {\n session.detachStderr?.();\n if (session.transportType === \"streamable-http\") {\n await (session.transport as StreamableHTTPClientTransport).terminateSession().catch(() => {});\n }\n await session.transport.close().catch(() => {});\n await session.client.close().catch(() => {});\n}\n\nfunction createCatalogFingerprint(servers: Record<string, unknown>): string {\n return crypto.createHash(\"sha1\").update(JSON.stringify(servers)).digest(\"hex\");\n}\n\nfunction loadSessionMcpConfig(params: {\n workspaceDir: string;\n cfg?: Config;\n logDiagnostics?: boolean;\n}): {\n loaded: LoadedMcpConfig;\n fingerprint: string;\n} {\n const loaded = loadEmbeddedMcpConfig({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n if (params.logDiagnostics !== false) {\n for (const diagnostic of loaded.diagnostics) {\n log.warn(\n {\n phase: 'agent.mcp_connect',\n extensionId: diagnostic.extensionId,\n message: diagnostic.message,\n },\n `bundle-mcp diagnostic: ${diagnostic.extensionId}: ${diagnostic.message}`,\n );\n }\n }\n return {\n loaded,\n fingerprint: createCatalogFingerprint(loaded.mcpServers),\n };\n}\n\nfunction createDisposedError(sessionId: string): Error {\n return new Error(`bundle-mcp runtime disposed for session ${sessionId}`);\n}\n\nfunction resolveSessionMcpRuntimeIdleTtlMs(cfg?: Config): number {\n const raw = cfg?.mcp?.sessionIdleTtlMs;\n if (typeof raw === \"number\" && Number.isFinite(raw) && raw >= 0) {\n return Math.floor(raw);\n }\n return DEFAULT_SESSION_MCP_RUNTIME_IDLE_TTL_MS;\n}\n\nexport function createSessionMcpRuntime(params: {\n sessionId: string;\n sessionKey?: string;\n workspaceDir: string;\n cfg?: Config;\n}): SessionMcpRuntime {\n const { loaded, fingerprint: configFingerprint } = loadSessionMcpConfig({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n logDiagnostics: true,\n });\n const createdAt = Date.now();\n let lastUsedAt = createdAt;\n let activeLeases = 0;\n let disposed = false;\n let catalog: McpToolCatalog | null = null;\n let catalogInFlight: Promise<McpToolCatalog> | undefined;\n const sessions = new Map<string, BundleMcpSession>();\n const failIfDisposed = () => {\n if (disposed) {\n throw createDisposedError(params.sessionId);\n }\n };\n\n const getCatalog = async (): Promise<McpToolCatalog> => {\n failIfDisposed();\n if (catalog) {\n return catalog;\n }\n if (catalogInFlight) {\n return catalogInFlight;\n }\n catalogInFlight = (async () => {\n if (Object.keys(loaded.mcpServers).length === 0) {\n return {\n version: 1,\n generatedAt: Date.now(),\n servers: {},\n tools: [],\n };\n }\n\n const servers: Record<string, McpServerCatalog> = {};\n const tools: McpCatalogTool[] = [];\n const usedServerNames = new Set<string>();\n\n try {\n for (const [serverName, rawServer] of Object.entries(loaded.mcpServers)) {\n failIfDisposed();\n const resolvedServer = await resolveConnectorSecretReferences(rawServer);\n const resolved = resolveMcpTransport(serverName, resolvedServer);\n if (!resolved) {\n continue;\n }\n const safeServerName = sanitizeServerName(serverName, usedServerNames);\n if (safeServerName !== serverName) {\n log.warn(\n {\n phase: 'agent.mcp_connect',\n serverName,\n safeServerName,\n },\n `bundle-mcp: server key \"${serverName}\" registered as \"${safeServerName}\" for provider-safe tool names`,\n );\n }\n\n const client = new Client(\n {\n name: \"xopc-bundle-mcp\",\n version: \"0.0.0\",\n },\n {\n jsonSchemaValidator: createBundleMcpJsonSchemaValidator(),\n },\n );\n const session: BundleMcpSession = {\n serverName,\n client,\n transport: resolved.transport,\n transportType: resolved.transportType,\n detachStderr: resolved.detachStderr,\n };\n sessions.set(serverName, session);\n\n try {\n failIfDisposed();\n await connectWithTimeout(client, resolved.transport, resolved.connectionTimeoutMs);\n failIfDisposed();\n const listedTools = await listAllTools(client);\n failIfDisposed();\n servers[serverName] = {\n serverName,\n launchSummary: resolved.description,\n toolCount: listedTools.length,\n };\n for (const tool of listedTools) {\n const toolName = tool.name.trim();\n if (!toolName) {\n continue;\n }\n tools.push({\n serverName,\n safeServerName,\n toolName,\n title: tool.title,\n description:\n normalizeOptionalString(tool.description) ?? normalizeOptionalString(tool.title),\n inputSchema: tool.inputSchema,\n fallbackDescription: `Provided by bundle MCP server \"${serverName}\" (${resolved.description}).`,\n });\n }\n } catch (error) {\n if (!disposed) {\n log.warn(\n `bundle-mcp: failed to start server \"${serverName}\" (${resolved.description}): ${redactErrorUrls(error)}`,\n );\n }\n await disposeSession(session);\n sessions.delete(serverName);\n failIfDisposed();\n }\n }\n\n failIfDisposed();\n return {\n version: 1,\n generatedAt: Date.now(),\n servers,\n tools,\n };\n } catch (error) {\n await Promise.allSettled(\n Array.from(sessions.values(), (session) => disposeSession(session)),\n );\n sessions.clear();\n throw error;\n }\n })();\n\n try {\n const nextCatalog = await catalogInFlight;\n failIfDisposed();\n catalog = nextCatalog;\n return nextCatalog;\n } finally {\n catalogInFlight = undefined;\n }\n };\n\n return {\n sessionId: params.sessionId,\n sessionKey: params.sessionKey,\n workspaceDir: params.workspaceDir,\n configFingerprint,\n createdAt,\n get lastUsedAt() {\n return lastUsedAt;\n },\n get activeLeases() {\n return activeLeases;\n },\n acquireLease() {\n activeLeases += 1;\n let released = false;\n return () => {\n if (released) {\n return;\n }\n released = true;\n activeLeases = Math.max(0, activeLeases - 1);\n lastUsedAt = Date.now();\n };\n },\n getCatalog,\n markUsed() {\n lastUsedAt = Date.now();\n },\n async callTool(serverName, toolName, input) {\n failIfDisposed();\n await getCatalog();\n const session = sessions.get(serverName);\n if (!session) {\n throw new Error(`bundle-mcp server \"${serverName}\" is not connected`);\n }\n return (await session.client.callTool({\n name: toolName,\n arguments: isMcpConfigRecord(input) ? input : {},\n })) as CallToolResult;\n },\n async dispose() {\n if (disposed) {\n return;\n }\n disposed = true;\n catalog = null;\n catalogInFlight = undefined;\n const sessionsToClose = Array.from(sessions.values());\n sessions.clear();\n await Promise.allSettled(sessionsToClose.map((session) => disposeSession(session)));\n },\n };\n}\n\nfunction createSessionMcpRuntimeManager(\n opts: {\n createRuntime?: CreateSessionMcpRuntime;\n now?: () => number;\n enableIdleSweepTimer?: boolean;\n idleSweepIntervalMs?: number;\n } = {},\n): SessionMcpRuntimeManager {\n const runtimesBySessionId = new Map<string, SessionMcpRuntime>();\n const sessionIdBySessionKey = new Map<string, string>();\n const idleTtlMsBySessionId = new Map<string, number>();\n const createRuntime = opts.createRuntime ?? createSessionMcpRuntime;\n const now = opts.now ?? Date.now;\n const createInFlight = new Map<\n string,\n {\n promise: Promise<SessionMcpRuntime>;\n workspaceDir: string;\n configFingerprint: string;\n }\n >();\n const idleSweepIntervalMs = opts.idleSweepIntervalMs ?? SESSION_MCP_RUNTIME_SWEEP_INTERVAL_MS;\n let idleSweepTimer: ReturnType<typeof setInterval> | undefined;\n let idleSweepInFlight: Promise<void> | undefined;\n\n const forgetSessionKeysForSessionId = (sessionId: string) => {\n for (const [sessionKey, mappedSessionId] of sessionIdBySessionKey.entries()) {\n if (mappedSessionId === sessionId) {\n sessionIdBySessionKey.delete(sessionKey);\n }\n }\n };\n\n const sweepIdleRuntimes = async (): Promise<number> => {\n const nowMs = now();\n const expired: SessionMcpRuntime[] = [];\n for (const [sessionId, runtime] of runtimesBySessionId.entries()) {\n const idleTtlMs =\n idleTtlMsBySessionId.get(sessionId) ?? DEFAULT_SESSION_MCP_RUNTIME_IDLE_TTL_MS;\n if (idleTtlMs <= 0 || (runtime.activeLeases ?? 0) > 0) {\n continue;\n }\n if (nowMs - runtime.lastUsedAt < idleTtlMs) {\n continue;\n }\n runtimesBySessionId.delete(sessionId);\n idleTtlMsBySessionId.delete(sessionId);\n forgetSessionKeysForSessionId(sessionId);\n expired.push(runtime);\n }\n await Promise.allSettled(expired.map((runtime) => runtime.dispose()));\n return expired.length;\n };\n\n const queueIdleSweep = () => {\n if (idleSweepInFlight) {\n return;\n }\n idleSweepInFlight = sweepIdleRuntimes()\n .then(() => undefined)\n .catch((error: unknown) => {\n const em = error instanceof Error ? error.message : String(error);\n log.warn(\n { err: error, errorMessage: em, phase: 'agent.mcp_connect' },\n `bundle-mcp: idle runtime sweep failed: ${em}`,\n );\n })\n .finally(() => {\n idleSweepInFlight = undefined;\n });\n };\n\n const ensureIdleSweepTimer = () => {\n if (opts.enableIdleSweepTimer === false || idleSweepIntervalMs <= 0 || idleSweepTimer) {\n return;\n }\n idleSweepTimer = setInterval(queueIdleSweep, idleSweepIntervalMs);\n idleSweepTimer.unref?.();\n };\n\n const clearIdleSweepTimer = () => {\n if (!idleSweepTimer) {\n return;\n }\n clearInterval(idleSweepTimer);\n idleSweepTimer = undefined;\n };\n\n return {\n async getOrCreate(params) {\n const idleTtlMs = resolveSessionMcpRuntimeIdleTtlMs(params.cfg);\n if (runtimesBySessionId.has(params.sessionId)) {\n idleTtlMsBySessionId.set(params.sessionId, idleTtlMs);\n }\n await sweepIdleRuntimes();\n if (idleTtlMs > 0) {\n ensureIdleSweepTimer();\n }\n if (params.sessionKey) {\n sessionIdBySessionKey.set(params.sessionKey, params.sessionId);\n }\n const { fingerprint: nextFingerprint } = loadSessionMcpConfig({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n logDiagnostics: false,\n });\n const existing = runtimesBySessionId.get(params.sessionId);\n if (existing) {\n if (\n existing.workspaceDir !== params.workspaceDir ||\n existing.configFingerprint !== nextFingerprint\n ) {\n runtimesBySessionId.delete(params.sessionId);\n await existing.dispose();\n } else {\n existing.markUsed();\n idleTtlMsBySessionId.set(params.sessionId, idleTtlMs);\n return existing;\n }\n }\n const inFlight = createInFlight.get(params.sessionId);\n if (inFlight) {\n if (\n inFlight.workspaceDir === params.workspaceDir &&\n inFlight.configFingerprint === nextFingerprint\n ) {\n return inFlight.promise;\n }\n createInFlight.delete(params.sessionId);\n const staleRuntime = await inFlight.promise.catch(() => undefined);\n runtimesBySessionId.delete(params.sessionId);\n idleTtlMsBySessionId.delete(params.sessionId);\n await staleRuntime?.dispose();\n }\n const created = Promise.resolve(\n createRuntime({\n sessionId: params.sessionId,\n sessionKey: params.sessionKey,\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n }),\n ).then((runtime) => {\n runtime.markUsed();\n runtimesBySessionId.set(params.sessionId, runtime);\n idleTtlMsBySessionId.set(params.sessionId, idleTtlMs);\n return runtime;\n });\n createInFlight.set(params.sessionId, {\n promise: created,\n workspaceDir: params.workspaceDir,\n configFingerprint: nextFingerprint,\n });\n try {\n return await created;\n } finally {\n createInFlight.delete(params.sessionId);\n }\n },\n bindSessionKey(sessionKey, sessionId) {\n sessionIdBySessionKey.set(sessionKey, sessionId);\n },\n resolveSessionId(sessionKey) {\n return sessionIdBySessionKey.get(sessionKey);\n },\n async disposeSession(sessionId) {\n const inFlight = createInFlight.get(sessionId);\n createInFlight.delete(sessionId);\n let runtime = runtimesBySessionId.get(sessionId);\n if (!runtime && inFlight) {\n runtime = await inFlight.promise.catch(() => undefined);\n }\n runtimesBySessionId.delete(sessionId);\n idleTtlMsBySessionId.delete(sessionId);\n if (!runtime) {\n forgetSessionKeysForSessionId(sessionId);\n return;\n }\n forgetSessionKeysForSessionId(sessionId);\n await runtime.dispose();\n },\n async disposeAll() {\n clearIdleSweepTimer();\n const inFlightRuntimes = Array.from(createInFlight.values());\n createInFlight.clear();\n const runtimes = Array.from(runtimesBySessionId.values());\n runtimesBySessionId.clear();\n sessionIdBySessionKey.clear();\n idleTtlMsBySessionId.clear();\n const lateRuntimes = await Promise.all(\n inFlightRuntimes.map(async ({ promise }) => await promise.catch(() => undefined)),\n );\n const allRuntimes = new Set<SessionMcpRuntime>(runtimes);\n for (const runtime of lateRuntimes) {\n if (runtime) {\n allRuntimes.add(runtime);\n }\n }\n await Promise.allSettled(Array.from(allRuntimes, (runtime) => runtime.dispose()));\n },\n sweepIdleRuntimes,\n listSessionIds() {\n return Array.from(runtimesBySessionId.keys());\n },\n };\n}\n\nexport function getSessionMcpRuntimeManager(): SessionMcpRuntimeManager {\n return resolveGlobalSingleton(SESSION_MCP_RUNTIME_MANAGER_KEY, createSessionMcpRuntimeManager);\n}\n\nexport async function getOrCreateSessionMcpRuntime(params: {\n sessionId: string;\n sessionKey?: string;\n workspaceDir: string;\n cfg?: Config;\n}): Promise<SessionMcpRuntime> {\n return await getSessionMcpRuntimeManager().getOrCreate(params);\n}\n\nexport async function disposeSessionMcpRuntime(sessionId: string): Promise<void> {\n await getSessionMcpRuntimeManager().disposeSession(sessionId);\n}\n\nexport async function retireSessionMcpRuntime(params: {\n sessionId?: string | null;\n reason: string;\n onError?: (error: unknown, sessionId: string, reason: string) => void;\n}): Promise<boolean> {\n const sessionId = normalizeOptionalString(params.sessionId);\n if (!sessionId) {\n return false;\n }\n try {\n await disposeSessionMcpRuntime(sessionId);\n return true;\n } catch (error) {\n params.onError?.(error, sessionId, params.reason);\n return false;\n }\n}\n\nexport async function retireSessionMcpRuntimeForSessionKey(params: {\n sessionKey?: string | null;\n reason: string;\n onError?: (error: unknown, sessionId: string, reason: string) => void;\n}): Promise<boolean> {\n const sessionKey = normalizeOptionalString(params.sessionKey);\n if (!sessionKey) {\n return false;\n }\n const sessionId = getSessionMcpRuntimeManager().resolveSessionId(sessionKey);\n return await retireSessionMcpRuntime({\n sessionId,\n reason: params.reason,\n onError: params.onError,\n });\n}\n\nexport async function disposeAllSessionMcpRuntimes(): Promise<void> {\n await getSessionMcpRuntimeManager().disposeAll();\n}\n\nexport const __testing = {\n createSessionMcpRuntimeManager,\n async resetSessionMcpRuntimeManager() {\n await disposeAllSessionMcpRuntimes();\n },\n getCachedSessionIds() {\n return getSessionMcpRuntimeManager().listSessionIds();\n },\n resolveSessionMcpRuntimeIdleTtlMs,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bundle-mcp-runtime.js","names":[],"sources":["../../../../src/agent/mcp/bundle-mcp-runtime.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport Ajv2020 from \"ajv/dist/2020.js\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { AjvJsonSchemaValidator } from \"@modelcontextprotocol/sdk/validation/ajv-provider.js\";\nimport type {\n JsonSchemaType,\n JsonSchemaValidator,\n jsonSchemaValidator,\n} from \"@modelcontextprotocol/sdk/validation/types.js\";\nimport type { Config } from \"../../config/schema.js\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"Mcp:Bundle\");\nimport { resolveGlobalSingleton } from \"../../utils/global-singleton.js\";\nimport { redactSensitiveUrlLikeString } from \"../../utils/redact-sensitive-url.js\";\nimport { normalizeOptionalString } from \"../../utils/string-coerce.js\";\nimport { loadEmbeddedMcpConfig } from \"./embedded-mcp.js\";\nimport { resolveConnectorSecretReferences } from \"../../connectors/secret-store.js\";\nimport { isMcpConfigRecord } from \"./mcp-config-shared.js\";\nimport { resolveMcpTransport } from \"./mcp-transport.js\";\nimport { sanitizeServerName } from \"./bundle-mcp-names.js\";\nimport type {\n McpCatalogTool,\n McpServerCatalog,\n McpToolCatalog,\n SessionMcpRuntime,\n SessionMcpRuntimeManager,\n} from \"./bundle-mcp-types.js\";\n\ntype BundleMcpSession = {\n serverName: string;\n client: Client;\n transport: Transport;\n transportType: \"stdio\" | \"sse\" | \"streamable-http\";\n detachStderr?: () => void;\n};\n\ntype LoadedMcpConfig = ReturnType<typeof loadEmbeddedMcpConfig>;\ntype ListedTool = Awaited<ReturnType<Client[\"listTools\"]>>[\"tools\"][number];\ntype ListedResource = Awaited<ReturnType<Client[\"listResources\"]>>[\"resources\"][number];\ntype ListedPrompt = Awaited<ReturnType<Client[\"listPrompts\"]>>[\"prompts\"][number];\ntype CreateSessionMcpRuntime = (\n params: Parameters<typeof createSessionMcpRuntime>[0] & { configFingerprint?: string },\n) => SessionMcpRuntime;\n\nconst SESSION_MCP_RUNTIME_MANAGER_KEY = Symbol.for(\"xopc.sessionMcpRuntimeManager\");\nconst DRAFT_2020_12_SCHEMA = \"https://json-schema.org/draft/2020-12/schema\";\nconst DEFAULT_SESSION_MCP_RUNTIME_IDLE_TTL_MS = 10 * 60 * 1000;\nconst SESSION_MCP_RUNTIME_SWEEP_INTERVAL_MS = 60 * 1000;\n\nfunction isDraft202012Schema(schema: JsonSchemaType): boolean {\n return (schema as { $schema?: unknown }).$schema === DRAFT_2020_12_SCHEMA;\n}\n\nexport function createBundleMcpJsonSchemaValidator(): jsonSchemaValidator {\n const defaultValidator = new AjvJsonSchemaValidator();\n const ajv2020 = new Ajv2020({\n strict: false,\n validateFormats: false,\n validateSchema: false,\n allErrors: true,\n });\n\n return {\n getValidator<T>(schema: JsonSchemaType): JsonSchemaValidator<T> {\n if (!isDraft202012Schema(schema)) {\n return defaultValidator.getValidator<T>(schema);\n }\n const ajvValidator = ajv2020.compile(schema);\n return (input: unknown) => {\n const valid = ajvValidator(input);\n if (valid) {\n return {\n valid: true,\n data: input as T,\n errorMessage: undefined,\n };\n }\n return {\n valid: false,\n data: undefined,\n errorMessage: ajv2020.errorsText(ajvValidator.errors),\n };\n };\n },\n };\n}\n\nfunction connectWithTimeout(\n client: Client,\n transport: Transport,\n timeoutMs: number,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const timer = setTimeout(\n () => reject(new Error(`MCP server connection timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n client.connect(transport).then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n}\n\nfunction redactErrorUrls(error: unknown): string {\n return redactSensitiveUrlLikeString(String(error));\n}\n\nasync function listAllTools(client: Client) {\n const tools: ListedTool[] = [];\n let cursor: string | undefined;\n do {\n const page = await client.listTools(cursor ? { cursor } : undefined);\n tools.push(...page.tools);\n cursor = page.nextCursor;\n } while (cursor);\n return tools;\n}\n\nasync function listAllResources(client: Client) {\n const resources: ListedResource[] = [];\n let cursor: string | undefined;\n do {\n const page = await client.listResources(cursor ? { cursor } : undefined);\n resources.push(...page.resources);\n cursor = page.nextCursor;\n } while (cursor);\n return resources;\n}\n\nasync function listAllPrompts(client: Client) {\n const prompts: ListedPrompt[] = [];\n let cursor: string | undefined;\n do {\n const page = await client.listPrompts(cursor ? { cursor } : undefined);\n prompts.push(...page.prompts);\n cursor = page.nextCursor;\n } while (cursor);\n return prompts;\n}\n\nasync function listOptionalMcpCapability<T>(params: {\n serverName: string;\n capability: \"resources\" | \"prompts\";\n list: () => Promise<T[]>;\n}): Promise<T[]> {\n try {\n return await params.list();\n } catch (error) {\n log.debug(\n {\n phase: \"agent.mcp_connect\",\n serverName: params.serverName,\n capability: params.capability,\n errorMessage: redactErrorUrls(error),\n },\n `bundle-mcp: server \"${params.serverName}\" did not list ${params.capability}`,\n );\n return [];\n }\n}\n\nasync function disposeSession(session: BundleMcpSession) {\n session.detachStderr?.();\n if (session.transportType === \"streamable-http\") {\n await (session.transport as StreamableHTTPClientTransport).terminateSession().catch(() => {});\n }\n await session.transport.close().catch(() => {});\n await session.client.close().catch(() => {});\n}\n\nfunction createCatalogFingerprint(servers: Record<string, unknown>): string {\n return crypto.createHash(\"sha1\").update(JSON.stringify(servers)).digest(\"hex\");\n}\n\nfunction loadSessionMcpConfig(params: {\n workspaceDir: string;\n cfg?: Config;\n logDiagnostics?: boolean;\n}): {\n loaded: LoadedMcpConfig;\n fingerprint: string;\n} {\n const loaded = loadEmbeddedMcpConfig({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n if (params.logDiagnostics !== false) {\n for (const diagnostic of loaded.diagnostics) {\n log.warn(\n {\n phase: 'agent.mcp_connect',\n extensionId: diagnostic.extensionId,\n message: diagnostic.message,\n },\n `bundle-mcp diagnostic: ${diagnostic.extensionId}: ${diagnostic.message}`,\n );\n }\n }\n return {\n loaded,\n fingerprint: createCatalogFingerprint(loaded.mcpServers),\n };\n}\n\nfunction createDisposedError(sessionId: string): Error {\n return new Error(`bundle-mcp runtime disposed for session ${sessionId}`);\n}\n\nfunction resolveSessionMcpRuntimeIdleTtlMs(cfg?: Config): number {\n const raw = cfg?.mcp?.sessionIdleTtlMs;\n if (typeof raw === \"number\" && Number.isFinite(raw) && raw >= 0) {\n return Math.floor(raw);\n }\n return DEFAULT_SESSION_MCP_RUNTIME_IDLE_TTL_MS;\n}\n\nexport function createSessionMcpRuntime(params: {\n sessionId: string;\n sessionKey?: string;\n workspaceDir: string;\n cfg?: Config;\n}): SessionMcpRuntime {\n const { loaded, fingerprint: configFingerprint } = loadSessionMcpConfig({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n logDiagnostics: true,\n });\n const createdAt = Date.now();\n let lastUsedAt = createdAt;\n let activeLeases = 0;\n let disposed = false;\n let catalog: McpToolCatalog | null = null;\n let catalogInFlight: Promise<McpToolCatalog> | undefined;\n const sessions = new Map<string, BundleMcpSession>();\n const failIfDisposed = () => {\n if (disposed) {\n throw createDisposedError(params.sessionId);\n }\n };\n\n const getCatalog = async (): Promise<McpToolCatalog> => {\n failIfDisposed();\n if (catalog) {\n return catalog;\n }\n if (catalogInFlight) {\n return catalogInFlight;\n }\n catalogInFlight = (async () => {\n if (Object.keys(loaded.mcpServers).length === 0) {\n return {\n version: 1,\n generatedAt: Date.now(),\n servers: {},\n tools: [],\n resources: [],\n prompts: [],\n };\n }\n\n const servers: Record<string, McpServerCatalog> = {};\n const tools: McpCatalogTool[] = [];\n const resources: McpToolCatalog[\"resources\"] = [];\n const prompts: McpToolCatalog[\"prompts\"] = [];\n const usedServerNames = new Set<string>();\n\n try {\n for (const [serverName, rawServer] of Object.entries(loaded.mcpServers)) {\n failIfDisposed();\n const resolvedServer = await resolveConnectorSecretReferences(rawServer);\n const resolved = resolveMcpTransport(serverName, resolvedServer);\n if (!resolved) {\n continue;\n }\n const safeServerName = sanitizeServerName(serverName, usedServerNames);\n if (safeServerName !== serverName) {\n log.warn(\n {\n phase: 'agent.mcp_connect',\n serverName,\n safeServerName,\n },\n `bundle-mcp: server key \"${serverName}\" registered as \"${safeServerName}\" for provider-safe tool names`,\n );\n }\n\n const client = new Client(\n {\n name: \"xopc-bundle-mcp\",\n version: \"0.0.0\",\n },\n {\n jsonSchemaValidator: createBundleMcpJsonSchemaValidator(),\n },\n );\n const session: BundleMcpSession = {\n serverName,\n client,\n transport: resolved.transport,\n transportType: resolved.transportType,\n detachStderr: resolved.detachStderr,\n };\n sessions.set(serverName, session);\n\n try {\n failIfDisposed();\n await connectWithTimeout(client, resolved.transport, resolved.connectionTimeoutMs);\n failIfDisposed();\n const listedTools = await listAllTools(client);\n const listedResources = await listOptionalMcpCapability({\n serverName,\n capability: \"resources\",\n list: () => listAllResources(client),\n });\n const listedPrompts = await listOptionalMcpCapability({\n serverName,\n capability: \"prompts\",\n list: () => listAllPrompts(client),\n });\n failIfDisposed();\n servers[serverName] = {\n serverName,\n launchSummary: resolved.description,\n toolCount: listedTools.length,\n resourceCount: listedResources.length,\n promptCount: listedPrompts.length,\n };\n for (const tool of listedTools) {\n const toolName = tool.name.trim();\n if (!toolName) {\n continue;\n }\n tools.push({\n serverName,\n safeServerName,\n toolName,\n title: tool.title,\n description:\n normalizeOptionalString(tool.description) ?? normalizeOptionalString(tool.title),\n inputSchema: tool.inputSchema,\n fallbackDescription: `Provided by bundle MCP server \"${serverName}\" (${resolved.description}).`,\n });\n }\n for (const resource of listedResources) {\n const uri = resource.uri.trim();\n const name = resource.name.trim();\n if (!uri || !name) {\n continue;\n }\n resources.push({\n serverName,\n uri,\n name,\n title: resource.title,\n description: normalizeOptionalString(resource.description),\n mimeType: normalizeOptionalString(resource.mimeType),\n });\n }\n for (const prompt of listedPrompts) {\n const name = prompt.name.trim();\n if (!name) {\n continue;\n }\n prompts.push({\n serverName,\n name,\n title: prompt.title,\n description: normalizeOptionalString(prompt.description),\n argumentCount: Array.isArray(prompt.arguments) ? prompt.arguments.length : 0,\n });\n }\n } catch (error) {\n if (!disposed) {\n log.warn(\n `bundle-mcp: failed to start server \"${serverName}\" (${resolved.description}): ${redactErrorUrls(error)}`,\n );\n }\n await disposeSession(session);\n sessions.delete(serverName);\n failIfDisposed();\n }\n }\n\n failIfDisposed();\n return {\n version: 1,\n generatedAt: Date.now(),\n servers,\n tools,\n resources,\n prompts,\n };\n } catch (error) {\n await Promise.allSettled(\n Array.from(sessions.values(), (session) => disposeSession(session)),\n );\n sessions.clear();\n throw error;\n }\n })();\n\n try {\n const nextCatalog = await catalogInFlight;\n failIfDisposed();\n catalog = nextCatalog;\n return nextCatalog;\n } finally {\n catalogInFlight = undefined;\n }\n };\n\n return {\n sessionId: params.sessionId,\n sessionKey: params.sessionKey,\n workspaceDir: params.workspaceDir,\n configFingerprint,\n createdAt,\n get lastUsedAt() {\n return lastUsedAt;\n },\n get activeLeases() {\n return activeLeases;\n },\n acquireLease() {\n activeLeases += 1;\n let released = false;\n return () => {\n if (released) {\n return;\n }\n released = true;\n activeLeases = Math.max(0, activeLeases - 1);\n lastUsedAt = Date.now();\n };\n },\n getCatalog,\n markUsed() {\n lastUsedAt = Date.now();\n },\n async callTool(serverName, toolName, input) {\n failIfDisposed();\n await getCatalog();\n const session = sessions.get(serverName);\n if (!session) {\n throw new Error(`bundle-mcp server \"${serverName}\" is not connected`);\n }\n return (await session.client.callTool({\n name: toolName,\n arguments: isMcpConfigRecord(input) ? input : {},\n })) as CallToolResult;\n },\n async dispose() {\n if (disposed) {\n return;\n }\n disposed = true;\n catalog = null;\n catalogInFlight = undefined;\n const sessionsToClose = Array.from(sessions.values());\n sessions.clear();\n await Promise.allSettled(sessionsToClose.map((session) => disposeSession(session)));\n },\n };\n}\n\nfunction createSessionMcpRuntimeManager(\n opts: {\n createRuntime?: CreateSessionMcpRuntime;\n now?: () => number;\n enableIdleSweepTimer?: boolean;\n idleSweepIntervalMs?: number;\n } = {},\n): SessionMcpRuntimeManager {\n const runtimesBySessionId = new Map<string, SessionMcpRuntime>();\n const sessionIdBySessionKey = new Map<string, string>();\n const idleTtlMsBySessionId = new Map<string, number>();\n const createRuntime = opts.createRuntime ?? createSessionMcpRuntime;\n const now = opts.now ?? Date.now;\n const createInFlight = new Map<\n string,\n {\n promise: Promise<SessionMcpRuntime>;\n workspaceDir: string;\n configFingerprint: string;\n }\n >();\n const idleSweepIntervalMs = opts.idleSweepIntervalMs ?? SESSION_MCP_RUNTIME_SWEEP_INTERVAL_MS;\n let idleSweepTimer: ReturnType<typeof setInterval> | undefined;\n let idleSweepInFlight: Promise<void> | undefined;\n\n const forgetSessionKeysForSessionId = (sessionId: string) => {\n for (const [sessionKey, mappedSessionId] of sessionIdBySessionKey.entries()) {\n if (mappedSessionId === sessionId) {\n sessionIdBySessionKey.delete(sessionKey);\n }\n }\n };\n\n const sweepIdleRuntimes = async (): Promise<number> => {\n const nowMs = now();\n const expired: SessionMcpRuntime[] = [];\n for (const [sessionId, runtime] of runtimesBySessionId.entries()) {\n const idleTtlMs =\n idleTtlMsBySessionId.get(sessionId) ?? DEFAULT_SESSION_MCP_RUNTIME_IDLE_TTL_MS;\n if (idleTtlMs <= 0 || (runtime.activeLeases ?? 0) > 0) {\n continue;\n }\n if (nowMs - runtime.lastUsedAt < idleTtlMs) {\n continue;\n }\n runtimesBySessionId.delete(sessionId);\n idleTtlMsBySessionId.delete(sessionId);\n forgetSessionKeysForSessionId(sessionId);\n expired.push(runtime);\n }\n await Promise.allSettled(expired.map((runtime) => runtime.dispose()));\n return expired.length;\n };\n\n const queueIdleSweep = () => {\n if (idleSweepInFlight) {\n return;\n }\n idleSweepInFlight = sweepIdleRuntimes()\n .then(() => undefined)\n .catch((error: unknown) => {\n const em = error instanceof Error ? error.message : String(error);\n log.warn(\n { err: error, errorMessage: em, phase: 'agent.mcp_connect' },\n `bundle-mcp: idle runtime sweep failed: ${em}`,\n );\n })\n .finally(() => {\n idleSweepInFlight = undefined;\n });\n };\n\n const ensureIdleSweepTimer = () => {\n if (opts.enableIdleSweepTimer === false || idleSweepIntervalMs <= 0 || idleSweepTimer) {\n return;\n }\n idleSweepTimer = setInterval(queueIdleSweep, idleSweepIntervalMs);\n idleSweepTimer.unref?.();\n };\n\n const clearIdleSweepTimer = () => {\n if (!idleSweepTimer) {\n return;\n }\n clearInterval(idleSweepTimer);\n idleSweepTimer = undefined;\n };\n\n return {\n async getOrCreate(params) {\n const idleTtlMs = resolveSessionMcpRuntimeIdleTtlMs(params.cfg);\n if (runtimesBySessionId.has(params.sessionId)) {\n idleTtlMsBySessionId.set(params.sessionId, idleTtlMs);\n }\n await sweepIdleRuntimes();\n if (idleTtlMs > 0) {\n ensureIdleSweepTimer();\n }\n if (params.sessionKey) {\n sessionIdBySessionKey.set(params.sessionKey, params.sessionId);\n }\n const { fingerprint: nextFingerprint } = loadSessionMcpConfig({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n logDiagnostics: false,\n });\n const existing = runtimesBySessionId.get(params.sessionId);\n if (existing) {\n if (\n existing.workspaceDir !== params.workspaceDir ||\n existing.configFingerprint !== nextFingerprint\n ) {\n runtimesBySessionId.delete(params.sessionId);\n await existing.dispose();\n } else {\n existing.markUsed();\n idleTtlMsBySessionId.set(params.sessionId, idleTtlMs);\n return existing;\n }\n }\n const inFlight = createInFlight.get(params.sessionId);\n if (inFlight) {\n if (\n inFlight.workspaceDir === params.workspaceDir &&\n inFlight.configFingerprint === nextFingerprint\n ) {\n return inFlight.promise;\n }\n createInFlight.delete(params.sessionId);\n const staleRuntime = await inFlight.promise.catch(() => undefined);\n runtimesBySessionId.delete(params.sessionId);\n idleTtlMsBySessionId.delete(params.sessionId);\n await staleRuntime?.dispose();\n }\n const created = Promise.resolve(\n createRuntime({\n sessionId: params.sessionId,\n sessionKey: params.sessionKey,\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n }),\n ).then((runtime) => {\n runtime.markUsed();\n runtimesBySessionId.set(params.sessionId, runtime);\n idleTtlMsBySessionId.set(params.sessionId, idleTtlMs);\n return runtime;\n });\n createInFlight.set(params.sessionId, {\n promise: created,\n workspaceDir: params.workspaceDir,\n configFingerprint: nextFingerprint,\n });\n try {\n return await created;\n } finally {\n createInFlight.delete(params.sessionId);\n }\n },\n bindSessionKey(sessionKey, sessionId) {\n sessionIdBySessionKey.set(sessionKey, sessionId);\n },\n resolveSessionId(sessionKey) {\n return sessionIdBySessionKey.get(sessionKey);\n },\n async disposeSession(sessionId) {\n const inFlight = createInFlight.get(sessionId);\n createInFlight.delete(sessionId);\n let runtime = runtimesBySessionId.get(sessionId);\n if (!runtime && inFlight) {\n runtime = await inFlight.promise.catch(() => undefined);\n }\n runtimesBySessionId.delete(sessionId);\n idleTtlMsBySessionId.delete(sessionId);\n if (!runtime) {\n forgetSessionKeysForSessionId(sessionId);\n return;\n }\n forgetSessionKeysForSessionId(sessionId);\n await runtime.dispose();\n },\n async disposeAll() {\n clearIdleSweepTimer();\n const inFlightRuntimes = Array.from(createInFlight.values());\n createInFlight.clear();\n const runtimes = Array.from(runtimesBySessionId.values());\n runtimesBySessionId.clear();\n sessionIdBySessionKey.clear();\n idleTtlMsBySessionId.clear();\n const lateRuntimes = await Promise.all(\n inFlightRuntimes.map(async ({ promise }) => await promise.catch(() => undefined)),\n );\n const allRuntimes = new Set<SessionMcpRuntime>(runtimes);\n for (const runtime of lateRuntimes) {\n if (runtime) {\n allRuntimes.add(runtime);\n }\n }\n await Promise.allSettled(Array.from(allRuntimes, (runtime) => runtime.dispose()));\n },\n sweepIdleRuntimes,\n listSessionIds() {\n return Array.from(runtimesBySessionId.keys());\n },\n };\n}\n\nexport function getSessionMcpRuntimeManager(): SessionMcpRuntimeManager {\n return resolveGlobalSingleton(SESSION_MCP_RUNTIME_MANAGER_KEY, createSessionMcpRuntimeManager);\n}\n\nexport async function getOrCreateSessionMcpRuntime(params: {\n sessionId: string;\n sessionKey?: string;\n workspaceDir: string;\n cfg?: Config;\n}): Promise<SessionMcpRuntime> {\n return await getSessionMcpRuntimeManager().getOrCreate(params);\n}\n\nexport async function disposeSessionMcpRuntime(sessionId: string): Promise<void> {\n await getSessionMcpRuntimeManager().disposeSession(sessionId);\n}\n\nexport async function retireSessionMcpRuntime(params: {\n sessionId?: string | null;\n reason: string;\n onError?: (error: unknown, sessionId: string, reason: string) => void;\n}): Promise<boolean> {\n const sessionId = normalizeOptionalString(params.sessionId);\n if (!sessionId) {\n return false;\n }\n try {\n await disposeSessionMcpRuntime(sessionId);\n return true;\n } catch (error) {\n params.onError?.(error, sessionId, params.reason);\n return false;\n }\n}\n\nexport async function retireSessionMcpRuntimeForSessionKey(params: {\n sessionKey?: string | null;\n reason: string;\n onError?: (error: unknown, sessionId: string, reason: string) => void;\n}): Promise<boolean> {\n const sessionKey = normalizeOptionalString(params.sessionKey);\n if (!sessionKey) {\n return false;\n }\n const sessionId = getSessionMcpRuntimeManager().resolveSessionId(sessionKey);\n return await retireSessionMcpRuntime({\n sessionId,\n reason: params.reason,\n onError: params.onError,\n });\n}\n\nexport async function disposeAllSessionMcpRuntimes(): Promise<void> {\n await getSessionMcpRuntimeManager().disposeAll();\n}\n\nexport const __testing = {\n createSessionMcpRuntimeManager,\n async resetSessionMcpRuntimeManager() {\n await disposeAllSessionMcpRuntimes();\n },\n getCachedSessionIds() {\n return getSessionMcpRuntimeManager().listSessionIds();\n },\n resolveSessionMcpRuntimeIdleTtlMs,\n};\n"],"mappings":"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"}
|
|
@@ -10,6 +10,8 @@ export type McpServerCatalog = {
|
|
|
10
10
|
serverName: string;
|
|
11
11
|
launchSummary: string;
|
|
12
12
|
toolCount: number;
|
|
13
|
+
resourceCount: number;
|
|
14
|
+
promptCount: number;
|
|
13
15
|
};
|
|
14
16
|
export type McpCatalogTool = {
|
|
15
17
|
serverName: string;
|
|
@@ -20,11 +22,28 @@ export type McpCatalogTool = {
|
|
|
20
22
|
inputSchema: JsonSchemaType;
|
|
21
23
|
fallbackDescription: string;
|
|
22
24
|
};
|
|
25
|
+
export type McpCatalogResource = {
|
|
26
|
+
serverName: string;
|
|
27
|
+
uri: string;
|
|
28
|
+
name: string;
|
|
29
|
+
title?: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
mimeType?: string;
|
|
32
|
+
};
|
|
33
|
+
export type McpCatalogPrompt = {
|
|
34
|
+
serverName: string;
|
|
35
|
+
name: string;
|
|
36
|
+
title?: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
argumentCount: number;
|
|
39
|
+
};
|
|
23
40
|
export type McpToolCatalog = {
|
|
24
41
|
version: number;
|
|
25
42
|
generatedAt: number;
|
|
26
43
|
servers: Record<string, McpServerCatalog>;
|
|
27
44
|
tools: McpCatalogTool[];
|
|
45
|
+
resources: McpCatalogResource[];
|
|
46
|
+
prompts: McpCatalogPrompt[];
|
|
28
47
|
};
|
|
29
48
|
export type SessionMcpRuntime = {
|
|
30
49
|
sessionId: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { init_string_coerce, normalizeLowercaseStringOrEmpty } from "../../utils/string-coerce.js";
|
|
1
2
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
3
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { init_string_coerce, normalizeLowercaseStringOrEmpty } from "../../utils/string-coerce.js";
|
|
4
4
|
import { resolveXopcMcpTransportAlias } from "../../config/mcp-config-normalize.js";
|
|
5
5
|
import { sanitizeForLog } from "../../utils/sanitize-log.js";
|
|
6
6
|
import { describeHttpMcpServerLaunchConfig, resolveHttpMcpServerLaunchConfig } from "./mcp-http.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
|
|
1
2
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
3
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
|
|
4
4
|
import { XopcStdioClientTransport } from "./mcp-stdio-transport.js";
|
|
5
5
|
import { resolveMcpTransportConfig } from "./mcp-transport-config.js";
|
|
6
6
|
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
1
2
|
import { existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
2
3
|
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
3
|
-
import { join } from "node:path";
|
|
4
4
|
import lockfile from "proper-lockfile";
|
|
5
5
|
//#region src/agent/memory/builtin-memory-store.ts
|
|
6
6
|
/**
|
|
@@ -4,8 +4,8 @@ import { MEMORY_MD_FILENAME } from "./constants.js";
|
|
|
4
4
|
import { clamp01, compareCandidatesByScore, computeCandidateScore, extractPromotionMarkers, isContaminatedSnippet, isExpiredEntry, isoDay, readFileLines, resolveDeepDefaults, sliceRange, snippetHash } from "./utils.js";
|
|
5
5
|
import { loadDreamingStore, saveDreamingStore, withDreamingPromotionLock } from "./short-term-store.js";
|
|
6
6
|
import { emptyDeepPhaseSkipped, writeDreamingDeepLastRun } from "./last-run.js";
|
|
7
|
-
import fs from "node:fs/promises";
|
|
8
7
|
import path from "node:path";
|
|
8
|
+
import fs from "node:fs/promises";
|
|
9
9
|
//#region src/agent/memory/dreaming/deep-promotion.ts
|
|
10
10
|
init_logger();
|
|
11
11
|
const log = createLogger("Dreaming:Deep");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DREAMING_DIR_RELATIVE, DREAMING_EVENTS_LOG_RELATIVE } from "./constants.js";
|
|
2
|
-
import fs from "node:fs/promises";
|
|
3
2
|
import path from "node:path";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
4
|
//#region src/agent/memory/dreaming/events.ts
|
|
5
5
|
/**
|
|
6
6
|
* Append a single event line to `memory/.dreams/events.jsonl`.
|