@astralyn/pi 0.99.0 → 1.0.1
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/CHANGELOG.md +58 -3
- package/dist/bundle/chunks/anthropic-messages-YET4T7BO.js +6 -0
- package/dist/bundle/chunks/anthropic.js +2 -2
- package/dist/bundle/chunks/azure-openai-responses-SBLL5YN3.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +3 -3
- package/dist/bundle/chunks/chunk-4TT2QGFL.js +2 -0
- package/dist/bundle/chunks/chunk-GIG5IHES.js +2 -0
- package/dist/bundle/chunks/{chunk-VW2P3X6P.js → chunk-H2N2THAO.js} +436 -668
- package/dist/bundle/chunks/{chunk-A576H74Y.js → chunk-IZ3S3GDX.js} +1 -1
- package/dist/bundle/chunks/{chunk-ABVRAYXT.js → chunk-NY3CWK44.js} +2 -2
- package/dist/bundle/chunks/chunk-SVJ7OGEB.js +2 -0
- package/dist/bundle/chunks/chunk-TRHTWM3C.js +2 -0
- package/dist/bundle/chunks/{chunk-DEWXBB6W.js → chunk-V66VGGOM.js} +1 -1
- package/dist/bundle/chunks/chunk-XDYM2567.js +20 -0
- package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-ZYSAFXXL.js → cloudflare-workers-ai-system-one-QI46LUZ6.js} +1 -1
- package/dist/bundle/chunks/codemode-worker.js +90 -10
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/{google-generative-ai-SDNQVVXA.js → google-generative-ai-YTZCSHQN.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-LZXOLBIO.js → google-vertex-OTFZJJXQ.js} +1 -1
- package/dist/bundle/chunks/{llama-cpp-classify-7IYGGPND.js → llama-cpp-classify-R7DQLTQN.js} +1 -1
- package/dist/bundle/chunks/{mistral-conversations-VYKPSSAM.js → mistral-conversations-ELH4V4TY.js} +1 -1
- package/dist/bundle/chunks/node-USQQ7C6M.js +16 -0
- package/dist/bundle/chunks/openai-chatgpt.js +2 -2
- package/dist/bundle/chunks/{openai-codex-responses-HZ4VUDXD.js → openai-codex-responses-OLVTU4UA.js} +1 -1
- package/dist/bundle/chunks/openai-codex.js +1 -1
- package/dist/bundle/chunks/openai-completions-53M2KJ67.js +7 -0
- package/dist/bundle/chunks/openai-responses-4ABDEL4Z.js +3 -0
- package/dist/bundle/chunks/{openrouter-images-5524IQHX.js → openrouter-images-YP3YVB54.js} +1 -1
- package/dist/bundle/chunks/openrouter.js +1 -1
- package/dist/bundle/chunks/radius.js +1 -1
- package/dist/bundle/chunks/{typesafe-system-one-Z2CDLKEY.js → typesafe-system-one-RREJAKWB.js} +1 -1
- package/dist/bundle/chunks/virtual-modules-YFKU7JZF.js +2 -0
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +5 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/config.d.ts +5 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +19 -13
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +21 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +65 -12
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/export-html/tool-renderer.d.ts +3 -3
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js +3 -3
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +18 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +6 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +15 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts +51 -11
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +11 -3
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/mcp-servers.d.ts +40 -7
- package/dist/core/mcp-servers.d.ts.map +1 -1
- package/dist/core/mcp-servers.js +63 -11
- package/dist/core/mcp-servers.js.map +1 -1
- package/dist/core/model-config.d.ts +36 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +14 -2
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts +3 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +4 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.js +1 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +6 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +22 -18
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/provider-composer.d.ts +2 -1
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +13 -0
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/radius.d.ts +2 -0
- package/dist/core/radius.d.ts.map +1 -1
- package/dist/core/radius.js +2 -0
- package/dist/core/radius.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +4 -9
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.d.ts +7 -5
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +2 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tasks/format.d.ts +7 -0
- package/dist/core/tasks/format.d.ts.map +1 -0
- package/dist/core/tasks/format.js +14 -0
- package/dist/core/tasks/format.js.map +1 -0
- package/dist/core/tasks/history.d.ts.map +1 -1
- package/dist/core/tasks/history.js +0 -19
- package/dist/core/tasks/history.js.map +1 -1
- package/dist/core/tasks/output.d.ts +8 -0
- package/dist/core/tasks/output.d.ts.map +1 -1
- package/dist/core/tasks/output.js +19 -0
- package/dist/core/tasks/output.js.map +1 -1
- package/dist/core/tasks/presentation.d.ts +1 -3
- package/dist/core/tasks/presentation.d.ts.map +1 -1
- package/dist/core/tasks/presentation.js +79 -166
- package/dist/core/tasks/presentation.js.map +1 -1
- package/dist/core/tasks/runtime.d.ts +16 -9
- package/dist/core/tasks/runtime.d.ts.map +1 -1
- package/dist/core/tasks/runtime.js +89 -106
- package/dist/core/tasks/runtime.js.map +1 -1
- package/dist/core/tasks/session.d.ts.map +1 -1
- package/dist/core/tasks/session.js +13 -4
- package/dist/core/tasks/session.js.map +1 -1
- package/dist/core/tasks/store.d.ts +20 -6
- package/dist/core/tasks/store.d.ts.map +1 -1
- package/dist/core/tasks/store.js +45 -18
- package/dist/core/tasks/store.js.map +1 -1
- package/dist/core/tasks/types.d.ts +14 -54
- package/dist/core/tasks/types.d.ts.map +1 -1
- package/dist/core/tasks/types.js +1 -5
- package/dist/core/tasks/types.js.map +1 -1
- package/dist/core/tools/renderers/bash.d.ts.map +1 -1
- package/dist/core/tools/renderers/bash.js +11 -34
- package/dist/core/tools/renderers/bash.js.map +1 -1
- package/dist/core/tools/renderers/index.d.ts +2 -2
- package/dist/core/tools/renderers/index.d.ts.map +1 -1
- package/dist/core/tools/renderers/index.js.map +1 -1
- package/dist/core/tools/shell-execution.d.ts +0 -1
- package/dist/core/tools/shell-execution.d.ts.map +1 -1
- package/dist/core/tools/shell-execution.js +3 -10
- package/dist/core/tools/shell-execution.js.map +1 -1
- package/dist/core/tools/shell-tool.d.ts.map +1 -1
- package/dist/core/tools/shell-tool.js +2 -4
- package/dist/core/tools/shell-tool.js.map +1 -1
- package/dist/core/tools/tasks/actions.d.ts +1 -1
- package/dist/core/tools/tasks/actions.d.ts.map +1 -1
- package/dist/core/tools/tasks/actions.js +26 -12
- package/dist/core/tools/tasks/actions.js.map +1 -1
- package/dist/core/tools/tasks/constants.d.ts +2 -6
- package/dist/core/tools/tasks/constants.d.ts.map +1 -1
- package/dist/core/tools/tasks/constants.js +2 -6
- package/dist/core/tools/tasks/constants.js.map +1 -1
- package/dist/core/tools/tasks/schema.d.ts +1 -1
- package/dist/core/tools/tasks/schema.d.ts.map +1 -1
- package/dist/core/tools/tasks/schema.js +8 -7
- package/dist/core/tools/tasks/schema.js.map +1 -1
- package/dist/core/tools/tasks/types.d.ts +8 -38
- package/dist/core/tools/tasks/types.d.ts.map +1 -1
- package/dist/core/tools/tasks/types.js +6 -11
- package/dist/core/tools/tasks/types.js.map +1 -1
- package/dist/core/virtual-models.d.ts +2 -0
- package/dist/core/virtual-models.d.ts.map +1 -1
- package/dist/core/virtual-models.js +19 -12
- package/dist/core/virtual-models.js.map +1 -1
- package/dist/extensions/btw/agent.d.ts +17 -8
- package/dist/extensions/btw/agent.d.ts.map +1 -1
- package/dist/extensions/btw/agent.js +74 -76
- package/dist/extensions/btw/agent.js.map +1 -1
- package/dist/extensions/btw/controller.d.ts +0 -1
- package/dist/extensions/btw/controller.d.ts.map +1 -1
- package/dist/extensions/btw/controller.js +26 -33
- package/dist/extensions/btw/controller.js.map +1 -1
- package/dist/extensions/btw/panel.d.ts +13 -14
- package/dist/extensions/btw/panel.d.ts.map +1 -1
- package/dist/extensions/btw/panel.js +38 -29
- package/dist/extensions/btw/panel.js.map +1 -1
- package/dist/extensions/codemode/execute.d.ts.map +1 -1
- package/dist/extensions/codemode/execute.js +197 -51
- package/dist/extensions/codemode/execute.js.map +1 -1
- package/dist/extensions/codemode/renderer.d.ts.map +1 -1
- package/dist/extensions/codemode/renderer.js +43 -25
- package/dist/extensions/codemode/renderer.js.map +1 -1
- package/dist/extensions/codemode/tool.d.ts +12 -11
- package/dist/extensions/codemode/tool.d.ts.map +1 -1
- package/dist/extensions/codemode/tool.js +73 -129
- package/dist/extensions/codemode/tool.js.map +1 -1
- package/dist/extensions/codemode/worker.d.ts +1 -1
- package/dist/extensions/codemode/worker.js +1 -1
- package/dist/extensions/codemode/worker.js.map +1 -1
- package/dist/extensions/deepwiki/schema.d.ts +1 -1
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +0 -2
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/mcp/cli.d.ts.map +1 -1
- package/dist/extensions/mcp/cli.js +23 -5
- package/dist/extensions/mcp/cli.js.map +1 -1
- package/dist/extensions/mcp/config.d.ts +19 -5
- package/dist/extensions/mcp/config.d.ts.map +1 -1
- package/dist/extensions/mcp/config.js +60 -12
- package/dist/extensions/mcp/config.js.map +1 -1
- package/dist/extensions/mcp/index.d.ts +36 -9
- package/dist/extensions/mcp/index.d.ts.map +1 -1
- package/dist/extensions/mcp/index.js +309 -100
- package/dist/extensions/mcp/index.js.map +1 -1
- package/dist/extensions/mcp/oauth.d.ts +14 -8
- package/dist/extensions/mcp/oauth.d.ts.map +1 -1
- package/dist/extensions/mcp/oauth.js +105 -36
- package/dist/extensions/mcp/oauth.js.map +1 -1
- package/dist/extensions/mcp/runtime.d.ts +2 -0
- package/dist/extensions/mcp/runtime.d.ts.map +1 -1
- package/dist/extensions/mcp/runtime.js +17 -9
- package/dist/extensions/mcp/runtime.js.map +1 -1
- package/dist/extensions/mcp/tools.d.ts +8 -5
- package/dist/extensions/mcp/tools.d.ts.map +1 -1
- package/dist/extensions/mcp/tools.js +50 -26
- package/dist/extensions/mcp/tools.js.map +1 -1
- package/dist/extensions/mcp/ui.d.ts.map +1 -1
- package/dist/extensions/mcp/ui.js +7 -1
- package/dist/extensions/mcp/ui.js.map +1 -1
- package/dist/extensions/provider/catalog.d.ts +8 -1
- package/dist/extensions/provider/catalog.d.ts.map +1 -1
- package/dist/extensions/provider/catalog.js +31 -0
- package/dist/extensions/provider/catalog.js.map +1 -1
- package/dist/extensions/provider/connection.d.ts +4 -1
- package/dist/extensions/provider/connection.d.ts.map +1 -1
- package/dist/extensions/provider/connection.js +1 -5
- package/dist/extensions/provider/connection.js.map +1 -1
- package/dist/extensions/provider/editing.d.ts +36 -0
- package/dist/extensions/provider/editing.d.ts.map +1 -0
- package/dist/extensions/provider/editing.js +99 -0
- package/dist/extensions/provider/editing.js.map +1 -0
- package/dist/extensions/provider/json-fields.d.ts +5 -0
- package/dist/extensions/provider/json-fields.d.ts.map +1 -0
- package/dist/extensions/provider/json-fields.js +31 -0
- package/dist/extensions/provider/json-fields.js.map +1 -0
- package/dist/extensions/provider/store.d.ts +1 -4
- package/dist/extensions/provider/store.d.ts.map +1 -1
- package/dist/extensions/provider/store.js +2 -30
- package/dist/extensions/provider/store.js.map +1 -1
- package/dist/extensions/provider/ui/builtin-data.d.ts +0 -2
- package/dist/extensions/provider/ui/builtin-data.d.ts.map +1 -1
- package/dist/extensions/provider/ui/builtin-data.js +14 -79
- package/dist/extensions/provider/ui/builtin-data.js.map +1 -1
- package/dist/extensions/provider/ui/compat.d.ts.map +1 -1
- package/dist/extensions/provider/ui/compat.js +6 -9
- package/dist/extensions/provider/ui/compat.js.map +1 -1
- package/dist/extensions/provider/ui/controls.d.ts +48 -0
- package/dist/extensions/provider/ui/controls.d.ts.map +1 -0
- package/dist/extensions/provider/ui/controls.js +108 -0
- package/dist/extensions/provider/ui/controls.js.map +1 -0
- package/dist/extensions/provider/ui/dictionary.d.ts.map +1 -1
- package/dist/extensions/provider/ui/dictionary.js +6 -9
- package/dist/extensions/provider/ui/dictionary.js.map +1 -1
- package/dist/extensions/provider/ui/editor.d.ts +3 -3
- package/dist/extensions/provider/ui/editor.d.ts.map +1 -1
- package/dist/extensions/provider/ui/editor.js +35 -140
- package/dist/extensions/provider/ui/editor.js.map +1 -1
- package/dist/extensions/provider/ui/fetch-models.d.ts +0 -3
- package/dist/extensions/provider/ui/fetch-models.d.ts.map +1 -1
- package/dist/extensions/provider/ui/fetch-models.js +49 -44
- package/dist/extensions/provider/ui/fetch-models.js.map +1 -1
- package/dist/extensions/provider/ui/model-fields.d.ts.map +1 -1
- package/dist/extensions/provider/ui/model-fields.js +11 -14
- package/dist/extensions/provider/ui/model-fields.js.map +1 -1
- package/dist/extensions/provider/ui/model-options.d.ts +4 -34
- package/dist/extensions/provider/ui/model-options.d.ts.map +1 -1
- package/dist/extensions/provider/ui/model-options.js +90 -271
- package/dist/extensions/provider/ui/model-options.js.map +1 -1
- package/dist/extensions/provider/ui/pane.d.ts +4 -18
- package/dist/extensions/provider/ui/pane.d.ts.map +1 -1
- package/dist/extensions/provider/ui/pane.js.map +1 -1
- package/dist/extensions/provider/ui/provider-fields.d.ts +2 -19
- package/dist/extensions/provider/ui/provider-fields.d.ts.map +1 -1
- package/dist/extensions/provider/ui/provider-fields.js +58 -171
- package/dist/extensions/provider/ui/provider-fields.js.map +1 -1
- package/dist/extensions/provider/ui/thinking-map.d.ts.map +1 -1
- package/dist/extensions/provider/ui/thinking-map.js +6 -9
- package/dist/extensions/provider/ui/thinking-map.js.map +1 -1
- package/dist/extensions/question/detail-pane.d.ts +7 -2
- package/dist/extensions/question/detail-pane.d.ts.map +1 -1
- package/dist/extensions/question/detail-pane.js +16 -5
- package/dist/extensions/question/detail-pane.js.map +1 -1
- package/dist/extensions/question/dialog-view.d.ts +41 -0
- package/dist/extensions/question/dialog-view.d.ts.map +1 -0
- package/dist/extensions/question/dialog-view.js +329 -0
- package/dist/extensions/question/dialog-view.js.map +1 -0
- package/dist/extensions/question/dialog.d.ts +3 -3
- package/dist/extensions/question/dialog.d.ts.map +1 -1
- package/dist/extensions/question/dialog.js +220 -634
- package/dist/extensions/question/dialog.js.map +1 -1
- package/dist/extensions/question/index.d.ts.map +1 -1
- package/dist/extensions/question/index.js +2 -3
- package/dist/extensions/question/index.js.map +1 -1
- package/dist/extensions/question/render.d.ts.map +1 -1
- package/dist/extensions/question/render.js +22 -32
- package/dist/extensions/question/render.js.map +1 -1
- package/dist/extensions/question/results.d.ts.map +1 -1
- package/dist/extensions/question/results.js +56 -12
- package/dist/extensions/question/results.js.map +1 -1
- package/dist/extensions/question/schema.d.ts +21 -6
- package/dist/extensions/question/schema.d.ts.map +1 -1
- package/dist/extensions/question/schema.js.map +1 -1
- package/dist/extensions/question/state.d.ts +9 -7
- package/dist/extensions/question/state.d.ts.map +1 -1
- package/dist/extensions/question/state.js +63 -54
- package/dist/extensions/question/state.js.map +1 -1
- package/dist/extensions/question/types.d.ts +41 -18
- package/dist/extensions/question/types.d.ts.map +1 -1
- package/dist/extensions/question/types.js.map +1 -1
- package/dist/extensions/statusline/index.d.ts +4 -0
- package/dist/extensions/statusline/index.d.ts.map +1 -1
- package/dist/extensions/statusline/index.js +18 -355
- package/dist/extensions/statusline/index.js.map +1 -1
- package/dist/extensions/statusline/render.d.ts +19 -0
- package/dist/extensions/statusline/render.d.ts.map +1 -0
- package/dist/extensions/statusline/render.js +163 -0
- package/dist/extensions/statusline/render.js.map +1 -0
- package/dist/extensions/statusline/usage.d.ts +12 -0
- package/dist/extensions/statusline/usage.d.ts.map +1 -0
- package/dist/extensions/statusline/usage.js +36 -0
- package/dist/extensions/statusline/usage.js.map +1 -0
- package/dist/extensions/tool-search/tool.d.ts +5 -4
- package/dist/extensions/tool-search/tool.d.ts.map +1 -1
- package/dist/extensions/tool-search/tool.js +7 -28
- package/dist/extensions/tool-search/tool.js.map +1 -1
- package/dist/extensions/web-search/execute.d.ts +1 -5
- package/dist/extensions/web-search/execute.d.ts.map +1 -1
- package/dist/extensions/web-search/execute.js +4 -9
- package/dist/extensions/web-search/execute.js.map +1 -1
- package/dist/extensions/web-search/format.d.ts +12 -3
- package/dist/extensions/web-search/format.d.ts.map +1 -1
- package/dist/extensions/web-search/format.js +33 -25
- package/dist/extensions/web-search/format.js.map +1 -1
- package/dist/extensions/web-search/index.d.ts.map +1 -1
- package/dist/extensions/web-search/index.js +6 -29
- package/dist/extensions/web-search/index.js.map +1 -1
- package/dist/extensions/web-search/providers/deepseek.d.ts.map +1 -1
- package/dist/extensions/web-search/providers/deepseek.js +0 -1
- package/dist/extensions/web-search/providers/deepseek.js.map +1 -1
- package/dist/extensions/web-search/providers/http.d.ts +1 -1
- package/dist/extensions/web-search/providers/http.d.ts.map +1 -1
- package/dist/extensions/web-search/providers/http.js.map +1 -1
- package/dist/extensions/web-search/providers/minimax.d.ts.map +1 -1
- package/dist/extensions/web-search/providers/minimax.js +0 -1
- package/dist/extensions/web-search/providers/minimax.js.map +1 -1
- package/dist/extensions/web-search/render.d.ts +7 -2
- package/dist/extensions/web-search/render.d.ts.map +1 -1
- package/dist/extensions/web-search/render.js +32 -4
- package/dist/extensions/web-search/render.js.map +1 -1
- package/dist/extensions/web-search/results.d.ts.map +1 -1
- package/dist/extensions/web-search/results.js +3 -8
- package/dist/extensions/web-search/results.js.map +1 -1
- package/dist/extensions/web-search/types.d.ts +4 -2
- package/dist/extensions/web-search/types.d.ts.map +1 -1
- package/dist/extensions/web-search/types.js.map +1 -1
- package/dist/index.d.ts +3 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +6 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts +3 -0
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js +7 -5
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/auth-url.d.ts +14 -0
- package/dist/modes/interactive/components/auth-url.d.ts.map +1 -0
- package/dist/modes/interactive/components/auth-url.js +34 -0
- package/dist/modes/interactive/components/auth-url.js.map +1 -0
- package/dist/modes/interactive/components/easter-egg-3d.d.ts +104 -0
- package/dist/modes/interactive/components/easter-egg-3d.d.ts.map +1 -0
- package/dist/modes/interactive/components/easter-egg-3d.js +1123 -0
- package/dist/modes/interactive/components/easter-egg-3d.js.map +1 -0
- package/dist/modes/interactive/components/easter-egg-3d.lazy.d.ts +6 -0
- package/dist/modes/interactive/components/easter-egg-3d.lazy.d.ts.map +1 -0
- package/dist/modes/interactive/components/easter-egg-3d.lazy.js +24 -0
- package/dist/modes/interactive/components/easter-egg-3d.lazy.js.map +1 -0
- package/dist/modes/interactive/components/index.d.ts +0 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +0 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +2 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +9 -5
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts +8 -2
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +24 -21
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/pi-logo.d.ts +7 -0
- package/dist/modes/interactive/components/pi-logo.d.ts.map +1 -1
- package/dist/modes/interactive/components/pi-logo.js +13 -1
- package/dist/modes/interactive/components/pi-logo.js.map +1 -1
- package/dist/modes/interactive/components/radius-login-selector.d.ts +15 -0
- package/dist/modes/interactive/components/radius-login-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/radius-login-selector.js +83 -0
- package/dist/modes/interactive/components/radius-login-selector.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -3
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +5 -5
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/status-marker.d.ts +0 -2
- package/dist/modes/interactive/components/status-marker.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-marker.js +0 -4
- package/dist/modes/interactive/components/status-marker.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +5 -4
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts +27 -3
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.js +36 -6
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +12 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +180 -55
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tasks/completion-render.d.ts +1 -1
- package/dist/modes/interactive/tasks/completion-render.d.ts.map +1 -1
- package/dist/modes/interactive/tasks/completion-render.js +28 -82
- package/dist/modes/interactive/tasks/completion-render.js.map +1 -1
- package/dist/modes/interactive/tasks/index.d.ts.map +1 -1
- package/dist/modes/interactive/tasks/index.js +18 -13
- package/dist/modes/interactive/tasks/index.js.map +1 -1
- package/dist/modes/interactive/tasks/inspector.d.ts +35 -0
- package/dist/modes/interactive/tasks/inspector.d.ts.map +1 -0
- package/dist/modes/interactive/tasks/inspector.js +93 -0
- package/dist/modes/interactive/tasks/inspector.js.map +1 -0
- package/dist/modes/interactive/tasks/layout.d.ts +40 -0
- package/dist/modes/interactive/tasks/layout.d.ts.map +1 -0
- package/dist/modes/interactive/tasks/layout.js +212 -0
- package/dist/modes/interactive/tasks/layout.js.map +1 -0
- package/dist/modes/interactive/tasks/list.d.ts +21 -0
- package/dist/modes/interactive/tasks/list.d.ts.map +1 -0
- package/dist/modes/interactive/tasks/list.js +96 -0
- package/dist/modes/interactive/tasks/list.js.map +1 -0
- package/dist/modes/interactive/tasks/manager.d.ts +29 -36
- package/dist/modes/interactive/tasks/manager.d.ts.map +1 -1
- package/dist/modes/interactive/tasks/manager.js +315 -315
- package/dist/modes/interactive/tasks/manager.js.map +1 -1
- package/dist/modes/interactive/tasks/model.d.ts +21 -0
- package/dist/modes/interactive/tasks/model.d.ts.map +1 -0
- package/dist/modes/interactive/tasks/model.js +41 -0
- package/dist/modes/interactive/tasks/model.js.map +1 -0
- package/dist/modes/interactive/tasks/render.d.ts +5 -19
- package/dist/modes/interactive/tasks/render.d.ts.map +1 -1
- package/dist/modes/interactive/tasks/render.js +18 -102
- package/dist/modes/interactive/tasks/render.js.map +1 -1
- package/dist/modes/interactive/tasks/task-view.d.ts +8 -48
- package/dist/modes/interactive/tasks/task-view.d.ts.map +1 -1
- package/dist/modes/interactive/tasks/task-view.js +11 -51
- package/dist/modes/interactive/tasks/task-view.js.map +1 -1
- package/dist/modes/interactive/tasks/text.d.ts +1 -7
- package/dist/modes/interactive/tasks/text.d.ts.map +1 -1
- package/dist/modes/interactive/tasks/text.js +6 -29
- package/dist/modes/interactive/tasks/text.js.map +1 -1
- package/dist/modes/interactive/tasks/viewport.d.ts +2 -0
- package/dist/modes/interactive/tasks/viewport.d.ts.map +1 -1
- package/dist/modes/interactive/tasks/viewport.js +17 -7
- package/dist/modes/interactive/tasks/viewport.js.map +1 -1
- package/dist/modes/interactive/tasks/views.d.ts +9 -0
- package/dist/modes/interactive/tasks/views.d.ts.map +1 -0
- package/dist/modes/interactive/tasks/views.js +42 -0
- package/dist/modes/interactive/tasks/views.js.map +1 -0
- package/dist/modes/interactive/theme/system-theme.d.ts +2 -1
- package/dist/modes/interactive/theme/system-theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/system-theme.js +16 -5
- package/dist/modes/interactive/theme/system-theme.js.map +1 -1
- package/dist/modes/interactive/tool-view/tool-execution.d.ts +4 -19
- package/dist/modes/interactive/tool-view/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/tool-view/tool-execution.js +23 -67
- package/dist/modes/interactive/tool-view/tool-execution.js.map +1 -1
- package/dist/utils/image-convert.d.ts +12 -0
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js +45 -6
- package/dist/utils/image-convert.js.map +1 -1
- package/docs/bundled/README.md +0 -1
- package/docs/bundled/extensions/question.md +2 -2
- package/docs/bundled/extensions/statusline.md +24 -15
- package/docs/bundled/tasks.md +34 -48
- package/docs/codemode.md +207 -0
- package/docs/docs.json +4 -4
- package/docs/environment-variables.md +1 -1
- package/docs/extensions.md +11 -9
- package/docs/keybindings.md +14 -7
- package/docs/mcp.md +164 -82
- package/docs/models.md +51 -3
- package/docs/providers.md +8 -0
- package/docs/sdk.md +2 -2
- package/docs/session-format.md +12 -22
- package/docs/settings.md +4 -2
- package/docs/tui.md +1 -1
- package/docs/usage.md +6 -16
- package/examples/README.md +1 -1
- package/examples/extensions/README.md +1 -2
- package/examples/extensions/built-in-tool-renderer.ts +16 -40
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/minimal-mode.ts +24 -96
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/sdk/14-codemode-mcp.ts +2 -2
- package/npm-shrinkwrap.json +73 -62
- package/package.json +11 -10
- package/dist/bundle/chunks/anthropic-messages-KIXY7EDT.js +0 -6
- package/dist/bundle/chunks/azure-openai-responses-RPBERDXD.js +0 -2
- package/dist/bundle/chunks/chunk-CLLDCO64.js +0 -2
- package/dist/bundle/chunks/chunk-PJVFYVHE.js +0 -42
- package/dist/bundle/chunks/chunk-UUSTLCVC.js +0 -2
- package/dist/bundle/chunks/chunk-VWCWZD6E.js +0 -2
- package/dist/bundle/chunks/node-CXWYTK2I.js +0 -16
- package/dist/bundle/chunks/openai-completions-SKDGF6OE.js +0 -7
- package/dist/bundle/chunks/openai-responses-FPML4SSG.js +0 -3
- package/dist/bundle/chunks/virtual-modules-TQRORWJQ.js +0 -2
- package/dist/core/tasks/view-data.d.ts +0 -8
- package/dist/core/tasks/view-data.d.ts.map +0 -1
- package/dist/core/tasks/view-data.js +0 -61
- package/dist/core/tasks/view-data.js.map +0 -1
- package/dist/core/tasks/view.d.ts +0 -30
- package/dist/core/tasks/view.d.ts.map +0 -1
- package/dist/core/tasks/view.js +0 -50
- package/dist/core/tasks/view.js.map +0 -1
- package/dist/core/tools/renderers/shell-task.d.ts +0 -4
- package/dist/core/tools/renderers/shell-task.d.ts.map +0 -1
- package/dist/core/tools/renderers/shell-task.js +0 -35
- package/dist/core/tools/renderers/shell-task.js.map +0 -1
- package/dist/extensions/todo/constants.d.ts +0 -16
- package/dist/extensions/todo/constants.d.ts.map +0 -1
- package/dist/extensions/todo/constants.js +0 -30
- package/dist/extensions/todo/constants.js.map +0 -1
- package/dist/extensions/todo/index.d.ts +0 -3
- package/dist/extensions/todo/index.d.ts.map +0 -1
- package/dist/extensions/todo/index.js +0 -98
- package/dist/extensions/todo/index.js.map +0 -1
- package/dist/extensions/todo/schema.d.ts +0 -60
- package/dist/extensions/todo/schema.d.ts.map +0 -1
- package/dist/extensions/todo/schema.js +0 -56
- package/dist/extensions/todo/schema.js.map +0 -1
- package/dist/extensions/todo/state.d.ts +0 -34
- package/dist/extensions/todo/state.d.ts.map +0 -1
- package/dist/extensions/todo/state.js +0 -425
- package/dist/extensions/todo/state.js.map +0 -1
- package/dist/extensions/todo/view.d.ts +0 -36
- package/dist/extensions/todo/view.d.ts.map +0 -1
- package/dist/extensions/todo/view.js +0 -580
- package/dist/extensions/todo/view.js.map +0 -1
- package/dist/extensions/todo/widget.d.ts +0 -15
- package/dist/extensions/todo/widget.d.ts.map +0 -1
- package/dist/extensions/todo/widget.js +0 -50
- package/dist/extensions/todo/widget.js.map +0 -1
- package/dist/modes/interactive/components/daxnuts.d.ts +0 -23
- package/dist/modes/interactive/components/daxnuts.d.ts.map +0 -1
- package/dist/modes/interactive/components/daxnuts.js +0 -138
- package/dist/modes/interactive/components/daxnuts.js.map +0 -1
- package/dist/modes/interactive/tasks/fallback-view.d.ts +0 -4
- package/dist/modes/interactive/tasks/fallback-view.d.ts.map +0 -1
- package/dist/modes/interactive/tasks/fallback-view.js +0 -27
- package/dist/modes/interactive/tasks/fallback-view.js.map +0 -1
- package/docs/bundled/extensions/todo.md +0 -104
- package/examples/extensions/todo.ts +0 -297
|
@@ -3,12 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Connects the servers from `mcp.json` and the servers extensions register with
|
|
5
5
|
* `pi.registerMcpServer()` when a session starts, and servers registered later right away. A server
|
|
6
|
-
* in `mcp.json` takes precedence over a registered server of the same name.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* the
|
|
6
|
+
* in `mcp.json` takes precedence over a registered server of the same name. Connections run in the
|
|
7
|
+
* background: the first prompt waits only for servers with `direct` tools, and codemode scripts,
|
|
8
|
+
* `tool_search`, and the resource tools wait for the servers they need when they run. Tools are
|
|
9
|
+
* registered as `mcp__<server>__<tool>`. By default (`"exposure": "codemode"`) the tools are only
|
|
10
|
+
* callable from codemode scripts, which keeps MCP tools out of the model's tool declarations and
|
|
11
|
+
* the codemode description: scripts find the tools with `searchTools()` and the server instructions
|
|
12
|
+
* with `describeNamespace()`. The codemode tool is activated for that unless `autoEnableCodemode` is
|
|
13
|
+
* false. `"deferred"` declares the tools to the model once the `tool_search` tool loads them, and
|
|
14
|
+
* activates `tool_search` instead of codemode.
|
|
12
15
|
* `"exposure": "direct"` declares them to the model right away, and `"hidden"` makes them
|
|
13
16
|
* unreachable. `toolExposure` overrides the exposure of single tools. Servers with resources are
|
|
14
17
|
* reached through Codex's `list_mcp_resources`, `list_mcp_resource_templates`, and
|
|
@@ -24,18 +27,23 @@
|
|
|
24
27
|
*/
|
|
25
28
|
import { join, resolve } from "node:path";
|
|
26
29
|
import { getAgentDir } from "../../config.js";
|
|
30
|
+
import { mcpNamespace } from "../../core/mcp-servers.js";
|
|
27
31
|
import { openBrowser } from "../../utils/open-browser.js";
|
|
28
32
|
import { getMcpToolExposure, loadMcpConfig, updateMcpServerConfig, } from "./config.js";
|
|
29
|
-
import { createMcpResourceToolDefinitions } from "./resources.js";
|
|
33
|
+
import { createMcpResourceToolDefinitions, LIST_MCP_RESOURCE_TEMPLATES_TOOL, LIST_MCP_RESOURCES_TOOL, READ_MCP_RESOURCE_TOOL, } from "./resources.js";
|
|
30
34
|
import { loadMcpRuntime } from "./runtime.lazy.js";
|
|
31
|
-
import { createMcpToolDefinition, createMcpToolName } from "./tools.js";
|
|
35
|
+
import { createMcpToolDefinition, createMcpToolName, createMcpToolRenderers } from "./tools.js";
|
|
32
36
|
import { showMcpManager } from "./ui.js";
|
|
33
37
|
const DEFAULT_STARTUP_WAIT_MS = 10_000;
|
|
34
38
|
const CODEMODE_TOOL_NAME = "codemode";
|
|
35
39
|
const TOOL_SEARCH_TOOL_NAME = "tool_search";
|
|
40
|
+
const RESOURCE_TOOL_NAMES = new Set([
|
|
41
|
+
LIST_MCP_RESOURCES_TOOL,
|
|
42
|
+
LIST_MCP_RESOURCE_TEMPLATES_TOOL,
|
|
43
|
+
READ_MCP_RESOURCE_TOOL,
|
|
44
|
+
]);
|
|
36
45
|
const EXPOSURE_DESCRIPTIONS = {
|
|
37
|
-
codemode: "called from codemode scripts,
|
|
38
|
-
"codemode-deferred": "called from codemode scripts, not listed; scripts find them with searchTools()",
|
|
46
|
+
codemode: "called from codemode scripts, which find them with searchTools()",
|
|
39
47
|
deferred: "not declared until tool_search loads them, then called directly; no codemode needed",
|
|
40
48
|
direct: "declared to the model like built-in tools",
|
|
41
49
|
};
|
|
@@ -51,6 +59,86 @@ function isEnabled(server) {
|
|
|
51
59
|
function exposureOf(entry) {
|
|
52
60
|
return entry.config.exposure ?? "codemode";
|
|
53
61
|
}
|
|
62
|
+
/** Exposures the server's tools can have, known from its config before it connects. */
|
|
63
|
+
function configuredExposures(entry) {
|
|
64
|
+
return new Set([exposureOf(entry), ...Object.values(entry.config.toolExposure ?? {})]);
|
|
65
|
+
}
|
|
66
|
+
/** Whether some of the server's tools are declared to the model, so the first prompt waits for them. */
|
|
67
|
+
function hasDirectTools(entry) {
|
|
68
|
+
return configuredExposures(entry).has("direct");
|
|
69
|
+
}
|
|
70
|
+
/** Whether some of the server's tools are reached through codemode or tool_search. */
|
|
71
|
+
function hasIndirectTools(entry) {
|
|
72
|
+
const exposures = configuredExposures(entry);
|
|
73
|
+
return exposures.has("codemode") || exposures.has("deferred");
|
|
74
|
+
}
|
|
75
|
+
/** Name of the system prompt section that lists the servers whose tools are not declared. */
|
|
76
|
+
export const MCP_SERVERS_SECTION = "mcp_servers";
|
|
77
|
+
/** Characters of a server description in the section, as Codex allows for deferred namespaces. */
|
|
78
|
+
const MAX_SERVER_DESCRIPTION_CHARS = 250;
|
|
79
|
+
/**
|
|
80
|
+
* Characters of the whole section. Descriptions shrink to fit; when the server lines alone do not
|
|
81
|
+
* fit, the last servers are left out and counted in a closing line.
|
|
82
|
+
*/
|
|
83
|
+
export const MAX_SERVERS_SECTION_CHARS = 4096;
|
|
84
|
+
/** The section's first line. It explains only the ways of reaching tools that the listed servers use. */
|
|
85
|
+
function serversSectionIntro(reaches) {
|
|
86
|
+
let intro = "MCP servers whose tools are not declared to you.";
|
|
87
|
+
if (reaches.has("codemode"))
|
|
88
|
+
intro += " Call the tools of `codemode` servers from codemode scripts.";
|
|
89
|
+
if (reaches.has("tool_search"))
|
|
90
|
+
intro += " Load the tools of `tool_search` servers with `tool_search`.";
|
|
91
|
+
return intro;
|
|
92
|
+
}
|
|
93
|
+
function truncate(text, max) {
|
|
94
|
+
if (text.length <= max)
|
|
95
|
+
return text;
|
|
96
|
+
return max <= 1 ? "" : `${text.slice(0, max - 1).trimEnd()}…`;
|
|
97
|
+
}
|
|
98
|
+
/** First line of the configured description, or of the server instructions once connected. */
|
|
99
|
+
function serverSummary(server) {
|
|
100
|
+
const text = server.entry.config.description?.trim() || server.connection?.instructions || "";
|
|
101
|
+
return (text.split("\n", 1)[0] ?? "").trim();
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The `mcp_servers` section: every enabled server with codemode or deferred tools, with how its
|
|
105
|
+
* tools are reached and a one-line summary. The model learns of the servers from it, since neither
|
|
106
|
+
* codemode nor tool_search lists them. Undefined when there are no such servers.
|
|
107
|
+
*/
|
|
108
|
+
export function renderServersSection(servers) {
|
|
109
|
+
const listed = servers
|
|
110
|
+
.filter((server) => isEnabled(server) && hasIndirectTools(server.entry))
|
|
111
|
+
.sort((a, b) => a.entry.name.localeCompare(b.entry.name));
|
|
112
|
+
if (listed.length === 0)
|
|
113
|
+
return undefined;
|
|
114
|
+
const reaches = listed.map((server) => configuredExposures(server.entry).has("codemode") ? "codemode" : "tool_search");
|
|
115
|
+
const intro = serversSectionIntro(new Set(reaches));
|
|
116
|
+
const heads = listed.map((server, index) => `- ${mcpNamespace(server.entry.name)} (${reaches[index]})`);
|
|
117
|
+
const omitted = (count) => count > 0 ? [`- … ${count} more server${count === 1 ? "" : "s"}; find their tools with searchTools()`] : [];
|
|
118
|
+
// Characters of the intro, the first `kept` server lines without descriptions, and the omission line.
|
|
119
|
+
const size = (kept) => [intro, ...heads.slice(0, kept), ...omitted(listed.length - kept)].join("\n").length;
|
|
120
|
+
let kept = listed.length;
|
|
121
|
+
while (kept > 0 && size(kept) > MAX_SERVERS_SECTION_CHARS)
|
|
122
|
+
kept--;
|
|
123
|
+
// Each description also takes a ": " separator.
|
|
124
|
+
const perServer = kept === 0
|
|
125
|
+
? 0
|
|
126
|
+
: Math.min(MAX_SERVER_DESCRIPTION_CHARS, Math.floor((MAX_SERVERS_SECTION_CHARS - size(kept)) / kept) - 2);
|
|
127
|
+
const lines = listed.slice(0, kept).map((server, index) => {
|
|
128
|
+
const summary = perServer > 0 ? truncate(serverSummary(server), perServer) : "";
|
|
129
|
+
return summary ? `${heads[index]}: ${summary}` : heads[index];
|
|
130
|
+
});
|
|
131
|
+
return [intro, ...lines, ...omitted(listed.length - kept)].join("\n");
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Whether a codemode script needs the server: it names the server's namespace, or searches,
|
|
135
|
+
* enumerates, or describes tools or namespaces, which may name the server in other forms.
|
|
136
|
+
*/
|
|
137
|
+
function scriptNeedsServer(code, server) {
|
|
138
|
+
if (/\b(searchTools|describeNamespace|describeTool|ALL_TOOLS)\b/.test(code))
|
|
139
|
+
return true;
|
|
140
|
+
return code.includes(mcpNamespace(server));
|
|
141
|
+
}
|
|
54
142
|
/** Short state for lists and the startup report. `withError` appends the first line of a failure. */
|
|
55
143
|
function describeState(server, withError = true) {
|
|
56
144
|
if (!isEnabled(server))
|
|
@@ -105,6 +193,8 @@ export function createMcpExtension(options = {}) {
|
|
|
105
193
|
/** Servers from `mcp.json`, which take precedence over registered servers of the same name. */
|
|
106
194
|
let configuredEntries = [];
|
|
107
195
|
let configErrors = [];
|
|
196
|
+
/** The trusted project's `mcp.json`, where `/mcp` saves project overrides of global servers. */
|
|
197
|
+
let projectConfig;
|
|
108
198
|
/** Registered servers that `mcp.json` overrides, shown in `/mcp`. */
|
|
109
199
|
let overridden = [];
|
|
110
200
|
/** Between session_start and session_shutdown. Registrations before that are read on session_start. */
|
|
@@ -121,9 +211,14 @@ export function createMcpExtension(options = {}) {
|
|
|
121
211
|
/** Working directory of the session, for stdio servers. */
|
|
122
212
|
let sessionCwd = process.cwd();
|
|
123
213
|
let credentials = options.credentials;
|
|
214
|
+
/** The session's model registry, which resolves `auth.provider` tokens. */
|
|
215
|
+
let modelRegistry;
|
|
124
216
|
let serverLog;
|
|
125
217
|
const openUrl = options.openUrl ?? openBrowser;
|
|
126
|
-
const updateConfig = options.updateConfig ??
|
|
218
|
+
const updateConfig = options.updateConfig ??
|
|
219
|
+
((entry, patch) => updateMcpServerConfig(entry.override ?? entry.source, entry.name, patch, {
|
|
220
|
+
override: entry.override !== undefined,
|
|
221
|
+
}));
|
|
127
222
|
const listeners = new Set();
|
|
128
223
|
const emitChange = () => {
|
|
129
224
|
for (const listener of listeners)
|
|
@@ -142,9 +237,9 @@ export function createMcpExtension(options = {}) {
|
|
|
142
237
|
const registered = [];
|
|
143
238
|
const overriddenNames = [];
|
|
144
239
|
for (const { name, config, extensionPath } of pi.getMcpServers()) {
|
|
145
|
-
const configured = configuredEntries.find((entry) => entry.name === name);
|
|
240
|
+
const configured = configuredEntries.find((entry) => mcpNamespace(entry.name) === mcpNamespace(name));
|
|
146
241
|
if (configured) {
|
|
147
|
-
overriddenNames.push(`"${name}" registered by ${extensionPath} is overridden by ${configured.source}`);
|
|
242
|
+
overriddenNames.push(`"${name}" registered by ${extensionPath} is overridden by "${configured.name}" in ${configured.source}`);
|
|
148
243
|
continue;
|
|
149
244
|
}
|
|
150
245
|
registered.push({
|
|
@@ -168,20 +263,31 @@ export function createMcpExtension(options = {}) {
|
|
|
168
263
|
const serverTools = new Map();
|
|
169
264
|
/** Last definition registered under each tool name, to re-register withdrawn tools as hidden. */
|
|
170
265
|
const definitions = new Map();
|
|
266
|
+
// A resumed session renders calls to MCP tools before their server connected, if it ever does.
|
|
267
|
+
pi.registerToolRenderer((toolName, next) => {
|
|
268
|
+
const match = /^mcp__(.+?)__(.+)$/.exec(toolName);
|
|
269
|
+
return next() ?? (match ? createMcpToolRenderers(`${match[1]}/${match[2]}`) : undefined);
|
|
270
|
+
});
|
|
171
271
|
const registerTools = (connection) => {
|
|
172
272
|
const server = connection.entry.name;
|
|
173
273
|
const entry = findServer(server)?.entry ?? connection.entry;
|
|
174
|
-
const
|
|
274
|
+
const description = entry.config.description?.trim();
|
|
175
275
|
const namespace = {
|
|
176
|
-
name:
|
|
177
|
-
description
|
|
276
|
+
name: mcpNamespace(server),
|
|
277
|
+
...(description ? { description } : {}),
|
|
278
|
+
...(connection.instructions ? { instructions: connection.instructions } : {}),
|
|
178
279
|
};
|
|
179
280
|
const previous = serverTools.get(server) ?? new Set();
|
|
180
281
|
const current = new Set();
|
|
282
|
+
// Like Codex, all tools whose names sanitize to the same name get the hash suffix, so which
|
|
283
|
+
// one would keep the plain name does not depend on the order of the list.
|
|
284
|
+
const plain = [...new Set(connection.tools.map((tool) => tool.name))].map((tool) => createMcpToolName(server, tool));
|
|
181
285
|
const assignName = (tool, owner) => {
|
|
182
286
|
const name = createMcpToolName(server, tool, (candidate) => {
|
|
183
287
|
const existing = toolOwners.get(candidate);
|
|
184
|
-
return (existing !== undefined && existing !== owner) ||
|
|
288
|
+
return ((existing !== undefined && existing !== owner) ||
|
|
289
|
+
current.has(candidate) ||
|
|
290
|
+
plain.indexOf(candidate) !== plain.lastIndexOf(candidate));
|
|
185
291
|
});
|
|
186
292
|
toolOwners.set(name, owner);
|
|
187
293
|
current.add(name);
|
|
@@ -232,7 +338,7 @@ export function createMcpExtension(options = {}) {
|
|
|
232
338
|
*/
|
|
233
339
|
const syncResourceTools = () => {
|
|
234
340
|
const exposures = new Set(serversWithResources().map((server) => exposureOf(server.entry)));
|
|
235
|
-
const exposure = ["direct", "codemode", "
|
|
341
|
+
const exposure = ["direct", "codemode", "deferred"].find((candidate) => exposures.has(candidate));
|
|
236
342
|
const next = exposure ?? "hidden";
|
|
237
343
|
if (next === resourceToolsExposure || (resourceToolsExposure === undefined && next === "hidden"))
|
|
238
344
|
return;
|
|
@@ -246,33 +352,40 @@ export function createMcpExtension(options = {}) {
|
|
|
246
352
|
pi.setActiveTools(pi.getActiveTools().filter((name) => !names.has(name)));
|
|
247
353
|
}
|
|
248
354
|
};
|
|
355
|
+
/**
|
|
356
|
+
* Which of the tools are the bundled codemode and tool_search tools. Other extensions' tools of
|
|
357
|
+
* the same names cannot reach MCP tools. The owning extensions identify their tools through the
|
|
358
|
+
* event bus, so this extension does not import their internals.
|
|
359
|
+
*/
|
|
360
|
+
const discoverOrchestrators = (tools) => {
|
|
361
|
+
const candidates = new Map(tools.map((tool) => [tool.name, tool.parameters]));
|
|
362
|
+
pi.events.emit("pi:discover-tool-orchestrators", candidates);
|
|
363
|
+
return {
|
|
364
|
+
codemode: candidates.get(CODEMODE_TOOL_NAME) === true,
|
|
365
|
+
toolSearch: candidates.get(TOOL_SEARCH_TOOL_NAME) === true,
|
|
366
|
+
};
|
|
367
|
+
};
|
|
249
368
|
/**
|
|
250
369
|
* Tools that are not declared to the model are reached through the codemode tool (scripts call
|
|
251
370
|
* them) or the tool_search tool (it declares them). Either reaches every such tool. Activate the
|
|
252
|
-
* one the tools' exposure asks for: codemode for `codemode`
|
|
253
|
-
*
|
|
371
|
+
* one the tools' exposure asks for: codemode for `codemode` unless `autoEnableCodemode` is false,
|
|
372
|
+
* tool_search for `deferred`.
|
|
254
373
|
*/
|
|
255
374
|
const ensureDiscoveryActive = (ctx) => {
|
|
375
|
+
// From the config, so the tool is active before the servers connect. Resource tools share
|
|
376
|
+
// their server's exposure.
|
|
256
377
|
const exposures = new Set();
|
|
257
|
-
for (const
|
|
258
|
-
if (
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
if (connection.hasResources)
|
|
262
|
-
exposures.add(exposureOf(entry));
|
|
263
|
-
for (const tool of connection.tools)
|
|
264
|
-
exposures.add(getMcpToolExposure(entry.config, tool.name));
|
|
378
|
+
for (const server of servers) {
|
|
379
|
+
if (isEnabled(server))
|
|
380
|
+
for (const exposure of configuredExposures(server.entry))
|
|
381
|
+
exposures.add(exposure);
|
|
265
382
|
}
|
|
266
|
-
const needsCodemode = exposures.has("codemode")
|
|
383
|
+
const needsCodemode = exposures.has("codemode");
|
|
267
384
|
const needsToolSearch = exposures.has("deferred");
|
|
268
385
|
if (!needsCodemode && !needsToolSearch)
|
|
269
386
|
return;
|
|
270
387
|
// Other extensions' tools of the same names cannot reach MCP tools, so never activate them.
|
|
271
|
-
const
|
|
272
|
-
const candidates = new Map(tools.map((tool) => [tool.name, tool.parameters]));
|
|
273
|
-
pi.events.emit("pi:discover-tool-orchestrators", candidates);
|
|
274
|
-
const hasCodemode = candidates.get(CODEMODE_TOOL_NAME) === true;
|
|
275
|
-
const hasToolSearch = candidates.get(TOOL_SEARCH_TOOL_NAME) === true;
|
|
388
|
+
const { codemode: hasCodemode, toolSearch: hasToolSearch } = discoverOrchestrators(pi.getAllTools());
|
|
276
389
|
const active = pi.getActiveTools();
|
|
277
390
|
const activate = [];
|
|
278
391
|
if (needsCodemode && hasCodemode && autoEnableCodemode && !active.includes(CODEMODE_TOOL_NAME)) {
|
|
@@ -301,7 +414,7 @@ export function createMcpExtension(options = {}) {
|
|
|
301
414
|
const tokensAtSignIn = new Map();
|
|
302
415
|
const storedTokens = (connection) => {
|
|
303
416
|
const url = connection.oauthUrl;
|
|
304
|
-
return url && credentials ? JSON.stringify(credentials.tokens(url) ?? null) : "null";
|
|
417
|
+
return url && credentials ? JSON.stringify(credentials.tokens(connection.name, url) ?? null) : "null";
|
|
305
418
|
};
|
|
306
419
|
const onConnectionChange = (connection) => {
|
|
307
420
|
if (connection.state !== "needs-auth")
|
|
@@ -328,6 +441,7 @@ export function createMcpExtension(options = {}) {
|
|
|
328
441
|
cwd: sessionCwd,
|
|
329
442
|
createTransport: options.createTransport ?? runtime.createDefaultTransport,
|
|
330
443
|
credentials: getCredentials(runtime),
|
|
444
|
+
providerToken: async (provider) => modelRegistry?.getApiKeyForProvider(provider),
|
|
331
445
|
log: getServerLog(runtime),
|
|
332
446
|
onTools: registerTools,
|
|
333
447
|
onChange: onConnectionChange,
|
|
@@ -336,6 +450,40 @@ export function createMcpExtension(options = {}) {
|
|
|
336
450
|
emitChange();
|
|
337
451
|
return connection;
|
|
338
452
|
};
|
|
453
|
+
/**
|
|
454
|
+
* Connect the server in the background. `server.ready` settles when it connected or failed;
|
|
455
|
+
* failures show in its state. It starts after `after`; `isCurrent` stops it when the session ended
|
|
456
|
+
* meanwhile. The returned promise rejects when the MCP runtime cannot be loaded.
|
|
457
|
+
*/
|
|
458
|
+
const startConnection = (server, isCurrent, after) => {
|
|
459
|
+
const ready = (async () => {
|
|
460
|
+
await after;
|
|
461
|
+
if (!isCurrent())
|
|
462
|
+
return;
|
|
463
|
+
const connection = await createConnection(server);
|
|
464
|
+
if (!isCurrent())
|
|
465
|
+
return;
|
|
466
|
+
await connection.getClient().catch(() => undefined);
|
|
467
|
+
})();
|
|
468
|
+
server.ready = ready.catch(() => undefined);
|
|
469
|
+
return ready;
|
|
470
|
+
};
|
|
471
|
+
/** Wait for servers still connecting, until they settle or `signal` aborts. */
|
|
472
|
+
const waitForServers = async (waiting, signal) => {
|
|
473
|
+
const ready = waiting.flatMap((server) => (server.ready ? [server.ready] : []));
|
|
474
|
+
if (ready.length === 0 || signal?.aborted)
|
|
475
|
+
return;
|
|
476
|
+
let onAbort;
|
|
477
|
+
await Promise.race([
|
|
478
|
+
Promise.all(ready),
|
|
479
|
+
new Promise((resolve) => {
|
|
480
|
+
onAbort = () => resolve();
|
|
481
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
482
|
+
}),
|
|
483
|
+
]);
|
|
484
|
+
if (onAbort)
|
|
485
|
+
signal?.removeEventListener("abort", onAbort);
|
|
486
|
+
};
|
|
339
487
|
/**
|
|
340
488
|
* One message for everything that needs the user after startup, or only for `only`, servers
|
|
341
489
|
* that connected later.
|
|
@@ -353,18 +501,20 @@ export function createMcpExtension(options = {}) {
|
|
|
353
501
|
};
|
|
354
502
|
/**
|
|
355
503
|
* Save a config change; returns an error message when the file could not be updated. Changes to
|
|
356
|
-
* registered servers only apply to the current session.
|
|
504
|
+
* registered servers only apply to the current session. `inProject` adds a project override.
|
|
357
505
|
*/
|
|
358
|
-
const saveConfig = (server, patch) => {
|
|
359
|
-
|
|
506
|
+
const saveConfig = (server, patch, inProject = false) => {
|
|
507
|
+
const override = inProject ? projectConfig : server.entry.override;
|
|
508
|
+
const entry = override ? { ...server.entry, override } : server.entry;
|
|
509
|
+
if (entry.scope !== "extension") {
|
|
360
510
|
try {
|
|
361
|
-
updateConfig(
|
|
511
|
+
updateConfig(entry, patch);
|
|
362
512
|
}
|
|
363
513
|
catch (error) {
|
|
364
|
-
return `Could not update ${
|
|
514
|
+
return `Could not update ${entry.override ?? entry.source}: ${errorMessage(error)}`;
|
|
365
515
|
}
|
|
366
516
|
}
|
|
367
|
-
server.entry = { ...
|
|
517
|
+
server.entry = { ...entry, config: { ...entry.config, ...patch } };
|
|
368
518
|
return undefined;
|
|
369
519
|
};
|
|
370
520
|
const signIn = async (server, prompt) => {
|
|
@@ -376,7 +526,7 @@ export function createMcpExtension(options = {}) {
|
|
|
376
526
|
try {
|
|
377
527
|
await runtime.signInMcpServer({
|
|
378
528
|
serverUrl: url,
|
|
379
|
-
store: getCredentials(runtime).forServer(url),
|
|
529
|
+
store: getCredentials(runtime).forServer(server.entry.name, url),
|
|
380
530
|
settings: connection.oauthSettings(),
|
|
381
531
|
challenge: connection.challenge,
|
|
382
532
|
prompt,
|
|
@@ -402,7 +552,7 @@ export function createMcpExtension(options = {}) {
|
|
|
402
552
|
const url = connection?.oauthUrl;
|
|
403
553
|
if (!connection || !url)
|
|
404
554
|
return false;
|
|
405
|
-
const removed = getCredentials(await loadMcpRuntime()).remove(url);
|
|
555
|
+
const removed = getCredentials(await loadMcpRuntime()).remove(server.entry.name, url);
|
|
406
556
|
await connection.signOut();
|
|
407
557
|
return removed;
|
|
408
558
|
};
|
|
@@ -419,8 +569,8 @@ export function createMcpExtension(options = {}) {
|
|
|
419
569
|
}
|
|
420
570
|
};
|
|
421
571
|
/** Returns an error message when the config could not be saved; connection errors show in the state. */
|
|
422
|
-
const setEnabled = async (server, enabled) => {
|
|
423
|
-
const failed = saveConfig(server, { enabled });
|
|
572
|
+
const setEnabled = async (server, enabled, inProject = false) => {
|
|
573
|
+
const failed = saveConfig(server, { enabled }, inProject);
|
|
424
574
|
if (failed)
|
|
425
575
|
return failed;
|
|
426
576
|
if (!enabled) {
|
|
@@ -431,8 +581,7 @@ export function createMcpExtension(options = {}) {
|
|
|
431
581
|
await connection?.close();
|
|
432
582
|
return undefined;
|
|
433
583
|
}
|
|
434
|
-
|
|
435
|
-
await connection.getClient().catch(() => undefined);
|
|
584
|
+
await startConnection(server, () => true);
|
|
436
585
|
return undefined;
|
|
437
586
|
};
|
|
438
587
|
const setExposure = (server, exposure) => {
|
|
@@ -467,7 +616,7 @@ export function createMcpExtension(options = {}) {
|
|
|
467
616
|
.map((server) => ({
|
|
468
617
|
value: server.entry.name,
|
|
469
618
|
label: server.entry.name,
|
|
470
|
-
description: `${describeState(server)} · ${exposureOf(server.entry)} · ${server.entry.scope ?? server.entry.source}`,
|
|
619
|
+
description: `${describeState(server)} · ${exposureOf(server.entry)} · ${server.entry.override ? "global, project override" : (server.entry.scope ?? server.entry.source)}`,
|
|
471
620
|
})),
|
|
472
621
|
empty: `No MCP servers configured. Add them to ${resolve(getAgentDir(), "mcp.json")} or .pi/mcp.json.`,
|
|
473
622
|
confirmLabel: "manage",
|
|
@@ -487,12 +636,20 @@ export function createMcpExtension(options = {}) {
|
|
|
487
636
|
const { entry, connection } = server;
|
|
488
637
|
const saved = entry.scope === "extension"
|
|
489
638
|
? "for this session"
|
|
490
|
-
: entry.
|
|
491
|
-
?
|
|
492
|
-
:
|
|
639
|
+
: entry.override
|
|
640
|
+
? "saved to the project mcp.json"
|
|
641
|
+
: entry.scope
|
|
642
|
+
? `saved to the ${entry.scope} mcp.json`
|
|
643
|
+
: "saved to mcp.json";
|
|
644
|
+
// Global servers without an override can be turned on or off for the trusted project alone.
|
|
645
|
+
const inProject = entry.scope === "global" && !entry.override && projectConfig !== undefined;
|
|
646
|
+
const inProjectSaved = "saved to the project mcp.json";
|
|
493
647
|
const items = [];
|
|
494
648
|
if (!isEnabled(server)) {
|
|
495
649
|
items.push({ value: "enable", label: "Enable", description: saved });
|
|
650
|
+
if (inProject) {
|
|
651
|
+
items.push({ value: "enable-project", label: "Enable in this project", description: inProjectSaved });
|
|
652
|
+
}
|
|
496
653
|
}
|
|
497
654
|
else {
|
|
498
655
|
const state = connection?.state;
|
|
@@ -509,10 +666,14 @@ export function createMcpExtension(options = {}) {
|
|
|
509
666
|
}
|
|
510
667
|
items.push({ value: "exposure", label: "Exposure", description: exposureOf(entry) });
|
|
511
668
|
items.push({ value: "disable", label: "Disable", description: saved });
|
|
669
|
+
if (inProject) {
|
|
670
|
+
items.push({ value: "disable-project", label: "Disable in this project", description: inProjectSaved });
|
|
671
|
+
}
|
|
512
672
|
}
|
|
513
673
|
const details = [
|
|
514
674
|
describeTransport(entry),
|
|
515
675
|
`${entry.scope ?? "config"}: ${entry.source}`,
|
|
676
|
+
...(entry.override ? [`project override: ${entry.override}`] : []),
|
|
516
677
|
`State: ${describeState(server, false)}`,
|
|
517
678
|
];
|
|
518
679
|
const error = [server.message, connection?.state === "connected" ? undefined : connection?.error]
|
|
@@ -554,7 +715,7 @@ export function createMcpExtension(options = {}) {
|
|
|
554
715
|
title: `Exposure of ${server.entry.name}`,
|
|
555
716
|
details: server.entry.scope === "extension"
|
|
556
717
|
? `Applies to this session; the server is registered by ${server.entry.source}.`
|
|
557
|
-
: `Saved to ${server.entry.source}.`,
|
|
718
|
+
: `Saved to ${server.entry.override ?? server.entry.source}.`,
|
|
558
719
|
items: Object.keys(EXPOSURE_DESCRIPTIONS).map((exposure) => ({
|
|
559
720
|
value: exposure,
|
|
560
721
|
label: `${exposure === current ? "✓ " : " "}${exposure}`,
|
|
@@ -568,27 +729,30 @@ export function createMcpExtension(options = {}) {
|
|
|
568
729
|
return undefined;
|
|
569
730
|
return setExposure(server, choice);
|
|
570
731
|
};
|
|
732
|
+
/** Sign in with the manager view's sign-in screen, which shows the URL with a copy key. */
|
|
733
|
+
const signInWithUi = (ui, server) => {
|
|
734
|
+
const title = `Sign in to ${server.entry.name}`;
|
|
735
|
+
let authorizationUrl = "";
|
|
736
|
+
ui.status(title, "Contacting the authorization server…");
|
|
737
|
+
return signIn(server, {
|
|
738
|
+
showAuthorizationUrl: (url) => {
|
|
739
|
+
authorizationUrl = url.href;
|
|
740
|
+
openUrl(url.href);
|
|
741
|
+
},
|
|
742
|
+
promptForRedirectUrl: async (signal) => {
|
|
743
|
+
const value = await ui.redirectUrl(title, authorizationUrl, signal);
|
|
744
|
+
ui.status(title, "Connecting…");
|
|
745
|
+
return value;
|
|
746
|
+
},
|
|
747
|
+
});
|
|
748
|
+
};
|
|
571
749
|
const runAction = async (ui, ctx, server, action) => {
|
|
572
750
|
const { name } = server.entry;
|
|
573
751
|
let message;
|
|
574
752
|
switch (action) {
|
|
575
|
-
case "signin":
|
|
576
|
-
|
|
577
|
-
let authorizationUrl = "";
|
|
578
|
-
ui.status(title, "Contacting the authorization server…");
|
|
579
|
-
message = await signIn(server, {
|
|
580
|
-
showAuthorizationUrl: (url) => {
|
|
581
|
-
authorizationUrl = url.href;
|
|
582
|
-
openUrl(url.href);
|
|
583
|
-
},
|
|
584
|
-
promptForRedirectUrl: async (signal) => {
|
|
585
|
-
const value = await ui.redirectUrl(title, authorizationUrl, signal);
|
|
586
|
-
ui.status(title, "Connecting…");
|
|
587
|
-
return value;
|
|
588
|
-
},
|
|
589
|
-
});
|
|
753
|
+
case "signin":
|
|
754
|
+
message = await signInWithUi(ui, server);
|
|
590
755
|
break;
|
|
591
|
-
}
|
|
592
756
|
case "reconnect":
|
|
593
757
|
// A failure shows as the connection's state and error.
|
|
594
758
|
ui.status(`MCP server ${name}`, "Reconnecting…");
|
|
@@ -605,9 +769,13 @@ export function createMcpExtension(options = {}) {
|
|
|
605
769
|
break;
|
|
606
770
|
case "enable":
|
|
607
771
|
case "disable":
|
|
608
|
-
|
|
609
|
-
|
|
772
|
+
case "enable-project":
|
|
773
|
+
case "disable-project": {
|
|
774
|
+
const enable = action.startsWith("enable");
|
|
775
|
+
ui.status(`MCP server ${name}`, enable ? "Connecting…" : "Disconnecting…");
|
|
776
|
+
message = await setEnabled(server, enable, action.endsWith("-project"));
|
|
610
777
|
break;
|
|
778
|
+
}
|
|
611
779
|
}
|
|
612
780
|
server.message = message;
|
|
613
781
|
ensureDiscoveryActive(ctx);
|
|
@@ -692,13 +860,21 @@ export function createMcpExtension(options = {}) {
|
|
|
692
860
|
ctx.ui.notify(`Signing in to MCP server "${name}" requires interactive mode.`, "error");
|
|
693
861
|
return;
|
|
694
862
|
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
|
|
863
|
+
let failure;
|
|
864
|
+
if (ctx.mode === "tui") {
|
|
865
|
+
await showMcpManager(ctx, async (ui) => {
|
|
866
|
+
failure = await signInWithUi(ui, server);
|
|
867
|
+
});
|
|
868
|
+
}
|
|
869
|
+
else {
|
|
870
|
+
failure = await signIn(server, {
|
|
871
|
+
showAuthorizationUrl: (url) => {
|
|
872
|
+
ctx.ui.notify(`Sign in to MCP server "${name}" in your browser:\n${url.href}`, "info");
|
|
873
|
+
openUrl(url.href);
|
|
874
|
+
},
|
|
875
|
+
promptForRedirectUrl: (signal) => ctx.ui.input(`Waiting for sign-in to "${name}". If the browser cannot reach this machine, paste the URL it was redirected to.`, "http://127.0.0.1:.../callback?code=...", { signal }),
|
|
876
|
+
});
|
|
877
|
+
}
|
|
702
878
|
if (failure) {
|
|
703
879
|
ctx.ui.notify(failure, failure === "Sign-in cancelled." ? "info" : "error");
|
|
704
880
|
return;
|
|
@@ -709,10 +885,12 @@ export function createMcpExtension(options = {}) {
|
|
|
709
885
|
pi.on("session_start", (_event, ctx) => {
|
|
710
886
|
const loaded = (options.loadConfig ?? defaultLoadConfig)(ctx);
|
|
711
887
|
configErrors = loaded.errors;
|
|
888
|
+
projectConfig = loaded.projectConfig;
|
|
712
889
|
autoEnableCodemode = loaded.autoEnableCodemode ?? true;
|
|
713
890
|
warnedUnreachable = false;
|
|
714
891
|
waitedForStartup = false;
|
|
715
892
|
sessionCwd = ctx.cwd;
|
|
893
|
+
modelRegistry = ctx.modelRegistry;
|
|
716
894
|
const current = ++generation;
|
|
717
895
|
sessionActive = true;
|
|
718
896
|
configuredEntries = loaded.servers;
|
|
@@ -720,6 +898,9 @@ export function createMcpExtension(options = {}) {
|
|
|
720
898
|
overridden = registered.overridden;
|
|
721
899
|
servers = [...loaded.servers.map((entry) => ({ entry })), ...registered.servers];
|
|
722
900
|
emitChange();
|
|
901
|
+
// Codemode or tool_search is activated from the config: the first prompt does not wait for
|
|
902
|
+
// servers whose tools are not declared to the model, and scripts or searches wait for them.
|
|
903
|
+
ensureDiscoveryActive(ctx);
|
|
723
904
|
const enabled = servers.filter(isEnabled);
|
|
724
905
|
if (enabled.length === 0) {
|
|
725
906
|
reportProblems(ctx);
|
|
@@ -727,19 +908,12 @@ export function createMcpExtension(options = {}) {
|
|
|
727
908
|
}
|
|
728
909
|
// The MCP client loads only now, so sessions without servers never pay for it. Waiting one
|
|
729
910
|
// event loop turn lets the first render happen before loading and connecting.
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
if (current !== generation)
|
|
737
|
-
return;
|
|
738
|
-
await Promise.allSettled(started.map((connection) => connection.getClient()));
|
|
739
|
-
if (current !== generation)
|
|
740
|
-
return;
|
|
741
|
-
ensureDiscoveryActive(ctx);
|
|
742
|
-
reportProblems(ctx);
|
|
911
|
+
const runtime = new Promise((resolve) => setImmediate(resolve)).then(() => loadMcpRuntime());
|
|
912
|
+
const isCurrent = () => current === generation;
|
|
913
|
+
pending = Promise.all(enabled.map((server) => startConnection(server, isCurrent, runtime)))
|
|
914
|
+
.then(() => {
|
|
915
|
+
if (isCurrent())
|
|
916
|
+
reportProblems(ctx);
|
|
743
917
|
})
|
|
744
918
|
.catch((error) => {
|
|
745
919
|
// The session may have been disposed meanwhile, which makes ctx stale.
|
|
@@ -749,16 +923,19 @@ export function createMcpExtension(options = {}) {
|
|
|
749
923
|
catch { }
|
|
750
924
|
});
|
|
751
925
|
});
|
|
752
|
-
// The first prompt waits for
|
|
753
|
-
// indefinitely: a slow or hanging server must not hold up the
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
if (
|
|
926
|
+
// The first prompt waits for servers whose tools are declared to the model, so they are declared
|
|
927
|
+
// in its first request, but not indefinitely: a slow or hanging server must not hold up the
|
|
928
|
+
// prompt. Other servers are waited for when a script or search needs them (below).
|
|
929
|
+
const waitForDirectServers = async (ctx) => {
|
|
930
|
+
if (waitedForStartup)
|
|
757
931
|
return;
|
|
758
932
|
waitedForStartup = true;
|
|
933
|
+
const ready = servers.flatMap((server) => isEnabled(server) && hasDirectTools(server.entry) && server.ready ? [server.ready] : []);
|
|
934
|
+
if (ready.length === 0)
|
|
935
|
+
return;
|
|
759
936
|
let timer;
|
|
760
937
|
const finished = await Promise.race([
|
|
761
|
-
|
|
938
|
+
Promise.all(ready).then(() => true),
|
|
762
939
|
new Promise((resolve) => {
|
|
763
940
|
timer = setTimeout(() => resolve(false), startupWaitMs);
|
|
764
941
|
}),
|
|
@@ -767,6 +944,39 @@ export function createMcpExtension(options = {}) {
|
|
|
767
944
|
if (!finished) {
|
|
768
945
|
ctx.ui.notify("MCP servers are still connecting; their tools become available once connected.", "info");
|
|
769
946
|
}
|
|
947
|
+
};
|
|
948
|
+
// Every prompt lists the servers in the `mcp_servers` section as they are when it starts. Pi
|
|
949
|
+
// appends the section to the conversation when it changed, for example after a server connected.
|
|
950
|
+
pi.on("before_agent_start", async (event, ctx) => {
|
|
951
|
+
await waitForDirectServers(ctx);
|
|
952
|
+
const { sections } = event.systemPromptOptions;
|
|
953
|
+
const section = renderServersSection(servers);
|
|
954
|
+
if (section)
|
|
955
|
+
sections[MCP_SERVERS_SECTION] = section;
|
|
956
|
+
else
|
|
957
|
+
delete sections[MCP_SERVERS_SECTION];
|
|
958
|
+
});
|
|
959
|
+
// A codemode script waits for the servers it names, or for every server when it searches or
|
|
960
|
+
// enumerates tools, so their tools are registered before the script runs. tool_search and the
|
|
961
|
+
// resource tools reach every server, so they wait for all of them.
|
|
962
|
+
pi.on("tool_call", async (event, ctx) => {
|
|
963
|
+
const tool = pi.getAllTools().find((candidate) => candidate.name === event.toolName);
|
|
964
|
+
if (!tool)
|
|
965
|
+
return;
|
|
966
|
+
const pendingServers = servers.filter((server) => isEnabled(server) && server.connection?.state !== "connected" && server.ready);
|
|
967
|
+
if (pendingServers.length === 0)
|
|
968
|
+
return;
|
|
969
|
+
let waiting = [];
|
|
970
|
+
const orchestrator = discoverOrchestrators([tool]);
|
|
971
|
+
if (orchestrator.codemode) {
|
|
972
|
+
const { code } = event.input;
|
|
973
|
+
const source = typeof code === "string" ? code : "";
|
|
974
|
+
waiting = pendingServers.filter((server) => scriptNeedsServer(source, server.entry.name));
|
|
975
|
+
}
|
|
976
|
+
else if (orchestrator.toolSearch || RESOURCE_TOOL_NAMES.has(tool.name)) {
|
|
977
|
+
waiting = pendingServers;
|
|
978
|
+
}
|
|
979
|
+
await waitForServers(waiting, ctx.signal);
|
|
770
980
|
});
|
|
771
981
|
// Pick up sign-ins done outside the session, such as `pi mcp login` run by the agent.
|
|
772
982
|
pi.on("turn_start", async (_event, ctx) => {
|
|
@@ -790,17 +1000,17 @@ export function createMcpExtension(options = {}) {
|
|
|
790
1000
|
const added = registered.servers.filter((server) => !findServer(server.entry.name));
|
|
791
1001
|
servers.push(...added);
|
|
792
1002
|
emitChange();
|
|
1003
|
+
ensureDiscoveryActive(ctx);
|
|
793
1004
|
await Promise.all(removed.map((server) => server.connection?.close()));
|
|
794
1005
|
const connecting = added.filter(isEnabled);
|
|
795
1006
|
if (current !== generation || connecting.length === 0)
|
|
796
1007
|
return;
|
|
797
1008
|
try {
|
|
798
|
-
|
|
1009
|
+
await Promise.all(connecting.map((server) => startConnection(server, () => current === generation)));
|
|
799
1010
|
if (current !== generation) {
|
|
800
|
-
await Promise.all(
|
|
1011
|
+
await Promise.all(connecting.map((server) => server.connection?.close()));
|
|
801
1012
|
return;
|
|
802
1013
|
}
|
|
803
|
-
await Promise.allSettled(started.map((connection) => connection.getClient()));
|
|
804
1014
|
}
|
|
805
1015
|
catch (error) {
|
|
806
1016
|
ctx.ui.notify(`MCP failed to load: ${errorMessage(error)}`, "error");
|
|
@@ -808,7 +1018,6 @@ export function createMcpExtension(options = {}) {
|
|
|
808
1018
|
}
|
|
809
1019
|
if (current !== generation)
|
|
810
1020
|
return;
|
|
811
|
-
ensureDiscoveryActive(ctx);
|
|
812
1021
|
reportProblems(ctx, connecting);
|
|
813
1022
|
});
|
|
814
1023
|
pi.on("session_shutdown", async () => {
|