@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
|
@@ -33,14 +33,16 @@ export class BtwPanel {
|
|
|
33
33
|
if (this.disposed)
|
|
34
34
|
return;
|
|
35
35
|
this.tui.requestRender();
|
|
36
|
-
|
|
36
|
+
const state = this.getState();
|
|
37
|
+
const busy = state.phase === "ready" && state.conversation.busy;
|
|
38
|
+
if (busy && !this.timer) {
|
|
37
39
|
this.timer = setTimeout(() => {
|
|
38
40
|
this.timer = undefined;
|
|
39
41
|
this.changed();
|
|
40
42
|
}, 150);
|
|
41
43
|
this.timer.unref?.();
|
|
42
44
|
}
|
|
43
|
-
else if (!
|
|
45
|
+
else if (!busy && this.timer) {
|
|
44
46
|
clearTimeout(this.timer);
|
|
45
47
|
this.timer = undefined;
|
|
46
48
|
}
|
|
@@ -68,12 +70,13 @@ export class BtwPanel {
|
|
|
68
70
|
if (this.disposed || width < 1)
|
|
69
71
|
return [];
|
|
70
72
|
const state = this.getState();
|
|
73
|
+
const busy = state.phase === "ready" && state.conversation.busy;
|
|
71
74
|
const theme = this.getTheme();
|
|
72
75
|
const innerWidth = Math.max(1, width - 4);
|
|
73
76
|
const lines = this.body(state, innerWidth, theme);
|
|
74
77
|
const cap = Math.max(1, Math.floor(this.tui.terminal.rows / 3) - 2);
|
|
75
78
|
const needed = Math.min(cap, Math.max(1, lines.length));
|
|
76
|
-
this.heldHeight =
|
|
79
|
+
this.heldHeight = busy ? Math.min(cap, Math.max(this.heldHeight, needed)) : needed;
|
|
77
80
|
this.maxOffset = Math.max(0, lines.length - this.heldHeight);
|
|
78
81
|
this.offset = this.follow ? this.maxOffset : Math.min(this.offset, this.maxOffset);
|
|
79
82
|
const body = lines.slice(this.offset, this.offset + this.heldHeight);
|
|
@@ -84,7 +87,7 @@ export class BtwPanel {
|
|
|
84
87
|
const title = [
|
|
85
88
|
theme.fg("accent", theme.bold("BTW")),
|
|
86
89
|
close && theme.fg("text", close) + theme.fg("muted", " close"),
|
|
87
|
-
|
|
90
|
+
busy && cancel && theme.fg("text", cancel) + theme.fg("muted", " stop"),
|
|
88
91
|
]
|
|
89
92
|
.filter(Boolean)
|
|
90
93
|
.join(theme.fg("muted", " · "));
|
|
@@ -103,29 +106,34 @@ export class BtwPanel {
|
|
|
103
106
|
if (state.phase === "opening")
|
|
104
107
|
return [theme.fg("muted", "Capturing context…")];
|
|
105
108
|
if (state.phase === "error")
|
|
106
|
-
return new Text(theme.fg("error", state.error
|
|
107
|
-
if (!state.turns.length) {
|
|
109
|
+
return new Text(theme.fg("error", state.error), 0, 0).render(width);
|
|
110
|
+
if (!state.conversation.turns.length) {
|
|
108
111
|
return [
|
|
109
112
|
...new Text(theme.fg("text", "Ask a side question in the editor below."), 0, 0).render(width),
|
|
110
|
-
...new Text(theme.fg("muted", `Context at ${new Date(state.capturedAt
|
|
113
|
+
...new Text(theme.fg("muted", `Context at ${new Date(state.capturedAt).toTimeString().slice(0, 8)} · ${state.model}`), 0, 0).render(width),
|
|
111
114
|
];
|
|
112
115
|
}
|
|
113
116
|
const lines = [];
|
|
114
|
-
for (const [index, turn] of state.turns.entries()) {
|
|
117
|
+
for (const [index, turn] of state.conversation.turns.entries()) {
|
|
115
118
|
if (index > 0)
|
|
116
119
|
lines.push("");
|
|
117
120
|
lines.push(...new Text(theme.fg("accent", theme.bold(`Q${index + 1}: `)) + theme.fg("text", turn.question), 0, 0).render(width));
|
|
118
121
|
if (turn.answer) {
|
|
119
|
-
let
|
|
120
|
-
if (!
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
let answer = this.answers.get(turn);
|
|
123
|
+
if (!answer) {
|
|
124
|
+
answer = {
|
|
125
|
+
text: turn.answer,
|
|
126
|
+
markdown: new Markdown(turn.answer, 0, 0, getMarkdownTheme(), {
|
|
127
|
+
color: (text) => theme.fg("text", text),
|
|
128
|
+
}),
|
|
129
|
+
};
|
|
130
|
+
this.answers.set(turn, answer);
|
|
131
|
+
}
|
|
132
|
+
else if (answer.text !== turn.answer) {
|
|
133
|
+
answer.text = turn.answer;
|
|
134
|
+
answer.markdown.setText(turn.answer);
|
|
125
135
|
}
|
|
126
|
-
|
|
127
|
-
markdown.setText(turn.answer);
|
|
128
|
-
lines.push(...markdown.render(width));
|
|
136
|
+
lines.push(...answer.markdown.render(width));
|
|
129
137
|
}
|
|
130
138
|
else if (turn.thinking && (turn.status === "streaming" || turn.status === "cancelling")) {
|
|
131
139
|
lines.push(...wrapTextWithAnsi(theme.fg("muted", turn.thinking.trimEnd()), width).slice(-2));
|
|
@@ -149,8 +157,9 @@ export class BtwPanel {
|
|
|
149
157
|
label(" scroll ") +
|
|
150
158
|
value(`${this.offset + 1}–${this.offset + this.heldHeight}/${this.maxOffset + this.heldHeight}`));
|
|
151
159
|
}
|
|
152
|
-
|
|
153
|
-
|
|
160
|
+
if (state.phase === "ready") {
|
|
161
|
+
const { conversation } = state;
|
|
162
|
+
const { usage } = conversation;
|
|
154
163
|
const stats = [];
|
|
155
164
|
if (usage.input > 0)
|
|
156
165
|
stats.push(`↑${tokens(usage.input)}`);
|
|
@@ -160,20 +169,20 @@ export class BtwPanel {
|
|
|
160
169
|
stats.push(`R${tokens(usage.cacheRead)}`);
|
|
161
170
|
if (usage.cacheWrite > 0)
|
|
162
171
|
stats.push(`W${tokens(usage.cacheWrite)}`);
|
|
163
|
-
if (
|
|
164
|
-
stats.push(`CH${
|
|
172
|
+
if (conversation.latestCacheHitPercent !== undefined)
|
|
173
|
+
stats.push(`CH${conversation.latestCacheHitPercent.toFixed(1)}%`);
|
|
165
174
|
if (usage.cost.total > 0)
|
|
166
175
|
stats.push(`$${usage.cost.total.toFixed(3)}${state.usesSubscription ? " (sub)" : ""}`);
|
|
167
176
|
if (stats.length)
|
|
168
177
|
parts.push(value(stats.join(" ")));
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
178
|
+
if (conversation.blockedTools)
|
|
179
|
+
parts.push(value(String(conversation.blockedTools)) + label(" tools blocked"));
|
|
180
|
+
const turn = conversation.turns.at(-1);
|
|
181
|
+
if (turn && !conversation.busy) {
|
|
182
|
+
parts.push(value(`${(turn.elapsedMs / 1000).toFixed(1)}s`));
|
|
183
|
+
if (turn.firstAnswerMs !== undefined)
|
|
184
|
+
parts.push(label("first ") + value(`${(turn.firstAnswerMs / 1000).toFixed(1)}s`));
|
|
185
|
+
}
|
|
177
186
|
}
|
|
178
187
|
return parts.join(label(" · "));
|
|
179
188
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"panel.js","sourceRoot":"","sources":["../../../src/extensions/btw/panel.ts"],"names":[],"mappings":"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","sourcesContent":["import \"./keybindings.ts\";\nimport type { Usage } from \"@earendil-works/pi-ai\";\nimport {\n\ttype Component,\n\tMarkdown,\n\tText,\n\ttype TUI,\n\ttruncateToWidth,\n\tvisibleWidth,\n\twrapTextWithAnsi,\n} from \"@earendil-works/pi-tui\";\nimport { keyLabel } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport { getMarkdownTheme, type Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport type { BtwTurn } from \"./agent.ts\";\n\nexport interface BtwPanelState {\n\tphase: \"opening\" | \"ready\" | \"error\";\n\terror?: string;\n\tcapturedAt?: number;\n\tmodel?: string;\n\tbusy: boolean;\n\tturns: readonly BtwTurn[];\n\tusage?: Usage;\n\tlatestCacheHitPercent?: number;\n\tusesSubscription?: boolean;\n\tblockedTools: number;\n}\n\nfunction tokens(value: number): string {\n\tif (value < 1000) return String(value);\n\tif (value < 10_000) return `${(value / 1000).toFixed(1)}k`;\n\tif (value < 1_000_000) return `${Math.round(value / 1000)}k`;\n\tif (value < 10_000_000) return `${(value / 1_000_000).toFixed(1)}M`;\n\treturn `${Math.round(value / 1_000_000)}M`;\n}\n\n/** A bounded, scrollable widget above the normal editor. It never takes keyboard focus. */\nexport class BtwPanel implements Component {\n\tprivate readonly tui: Pick<TUI, \"terminal\" | \"requestRender\">;\n\tprivate readonly getTheme: () => Theme;\n\tprivate readonly getState: () => BtwPanelState;\n\tprivate readonly answers = new Map<BtwTurn, Markdown>();\n\tprivate follow = true;\n\tprivate offset = 0;\n\tprivate maxOffset = 0;\n\tprivate heldHeight = 0;\n\tprivate timer?: ReturnType<typeof setTimeout>;\n\tprivate disposed = false;\n\n\tconstructor(tui: Pick<TUI, \"terminal\" | \"requestRender\">, getTheme: () => Theme, getState: () => BtwPanelState) {\n\t\tthis.tui = tui;\n\t\tthis.getTheme = getTheme;\n\t\tthis.getState = getState;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.answers.clear();\n\t}\n\n\tchanged(): void {\n\t\tif (this.disposed) return;\n\t\tthis.tui.requestRender();\n\t\tif (this.getState().busy && !this.timer) {\n\t\t\tthis.timer = setTimeout(() => {\n\t\t\t\tthis.timer = undefined;\n\t\t\t\tthis.changed();\n\t\t\t}, 150);\n\t\t\tthis.timer.unref?.();\n\t\t} else if (!this.getState().busy && this.timer) {\n\t\t\tclearTimeout(this.timer);\n\t\t\tthis.timer = undefined;\n\t\t}\n\t}\n\n\tfollowTail(): void {\n\t\tthis.follow = true;\n\t\tthis.changed();\n\t}\n\n\tscroll(delta: number): boolean {\n\t\tif (this.maxOffset === 0) return false;\n\t\tthis.offset = Math.max(0, Math.min(this.maxOffset, this.offset + delta));\n\t\tthis.follow = this.offset === this.maxOffset;\n\t\tthis.tui.requestRender();\n\t\treturn true;\n\t}\n\n\tdispose(): void {\n\t\tthis.disposed = true;\n\t\tif (this.timer) clearTimeout(this.timer);\n\t\tthis.timer = undefined;\n\t\tthis.answers.clear();\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.disposed || width < 1) return [];\n\t\tconst state = this.getState();\n\t\tconst theme = this.getTheme();\n\t\tconst innerWidth = Math.max(1, width - 4);\n\t\tconst lines = this.body(state, innerWidth, theme);\n\t\tconst cap = Math.max(1, Math.floor(this.tui.terminal.rows / 3) - 2);\n\t\tconst needed = Math.min(cap, Math.max(1, lines.length));\n\t\tthis.heldHeight = state.busy ? Math.min(cap, Math.max(this.heldHeight, needed)) : needed;\n\t\tthis.maxOffset = Math.max(0, lines.length - this.heldHeight);\n\t\tthis.offset = this.follow ? this.maxOffset : Math.min(this.offset, this.maxOffset);\n\t\tconst body = lines.slice(this.offset, this.offset + this.heldHeight);\n\t\twhile (body.length < this.heldHeight) body.push(\"\");\n\t\tconst close = keyLabel(\"app.btw.close\");\n\t\tconst cancel = keyLabel(\"app.btw.cancel\");\n\t\tconst title = [\n\t\t\ttheme.fg(\"accent\", theme.bold(\"BTW\")),\n\t\t\tclose && theme.fg(\"text\", close) + theme.fg(\"muted\", \" close\"),\n\t\t\tstate.busy && cancel && theme.fg(\"text\", cancel) + theme.fg(\"muted\", \" stop\"),\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.join(theme.fg(\"muted\", \" · \"));\n\t\tconst footer = this.footer(state, theme);\n\t\tif (width < 6) return body.map((line) => truncateToWidth(line, width));\n\t\treturn [\n\t\t\tthis.border(title, width, true, theme),\n\t\t\t...body.map(\n\t\t\t\t(line) =>\n\t\t\t\t\ttheme.fg(\"borderAccent\", \"│ \") +\n\t\t\t\t\ttruncateToWidth(line, innerWidth, \"…\", true) +\n\t\t\t\t\ttheme.fg(\"borderAccent\", \" │\"),\n\t\t\t),\n\t\t\tthis.border(footer, width, false, theme),\n\t\t];\n\t}\n\n\tprivate body(state: BtwPanelState, width: number, theme: Theme): string[] {\n\t\tif (state.phase === \"opening\") return [theme.fg(\"muted\", \"Capturing context…\")];\n\t\tif (state.phase === \"error\")\n\t\t\treturn new Text(theme.fg(\"error\", state.error ?? \"Could not open BTW.\"), 0, 0).render(width);\n\t\tif (!state.turns.length) {\n\t\t\treturn [\n\t\t\t\t...new Text(theme.fg(\"text\", \"Ask a side question in the editor below.\"), 0, 0).render(width),\n\t\t\t\t...new Text(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"muted\",\n\t\t\t\t\t\t`Context at ${new Date(state.capturedAt ?? Date.now()).toTimeString().slice(0, 8)} · ${state.model ?? \"\"}`,\n\t\t\t\t\t),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t).render(width),\n\t\t\t];\n\t\t}\n\t\tconst lines: string[] = [];\n\t\tfor (const [index, turn] of state.turns.entries()) {\n\t\t\tif (index > 0) lines.push(\"\");\n\t\t\tlines.push(\n\t\t\t\t...new Text(\n\t\t\t\t\ttheme.fg(\"accent\", theme.bold(`Q${index + 1}: `)) + theme.fg(\"text\", turn.question),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t).render(width),\n\t\t\t);\n\t\t\tif (turn.answer) {\n\t\t\t\tlet markdown = this.answers.get(turn);\n\t\t\t\tif (!markdown) {\n\t\t\t\t\tmarkdown = new Markdown(turn.answer, 0, 0, getMarkdownTheme(), {\n\t\t\t\t\t\tcolor: (text) => theme.fg(\"text\", text),\n\t\t\t\t\t});\n\t\t\t\t\tthis.answers.set(turn, markdown);\n\t\t\t\t} else markdown.setText(turn.answer);\n\t\t\t\tlines.push(...markdown.render(width));\n\t\t\t} else if (turn.thinking && (turn.status === \"streaming\" || turn.status === \"cancelling\")) {\n\t\t\t\tlines.push(...wrapTextWithAnsi(theme.fg(\"muted\", turn.thinking.trimEnd()), width).slice(-2));\n\t\t\t}\n\t\t\tif (turn.status === \"streaming\" || turn.status === \"cancelling\") {\n\t\t\t\tconst elapsed = ((Date.now() - turn.startedAt) / 1000).toFixed(1);\n\t\t\t\tlines.push(theme.fg(\"muted\", `${turn.status === \"cancelling\" ? \"Stopping\" : \"Answering\"}… ${elapsed}s`));\n\t\t\t}\n\t\t\tif (turn.notice)\n\t\t\t\tlines.push(\n\t\t\t\t\t...new Text(theme.fg(turn.status === \"error\" ? \"error\" : \"muted\", turn.notice), 0, 0).render(width),\n\t\t\t\t);\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate footer(state: BtwPanelState, theme: Theme): string {\n\t\tconst parts: string[] = [];\n\t\tconst label = (text: string) => theme.fg(\"muted\", text);\n\t\tconst value = (text: string) => theme.fg(\"text\", text);\n\t\tif (this.maxOffset > 0) {\n\t\t\tconst keys = [keyLabel(\"app.btw.scrollUp\"), keyLabel(\"app.btw.scrollDown\")].filter(Boolean).join(\"/\");\n\t\t\tparts.push(\n\t\t\t\tvalue(keys) +\n\t\t\t\t\tlabel(\" scroll \") +\n\t\t\t\t\tvalue(`${this.offset + 1}–${this.offset + this.heldHeight}/${this.maxOffset + this.heldHeight}`),\n\t\t\t);\n\t\t}\n\t\tconst usage = state.usage;\n\t\tif (usage) {\n\t\t\tconst stats: string[] = [];\n\t\t\tif (usage.input > 0) stats.push(`↑${tokens(usage.input)}`);\n\t\t\tif (usage.output > 0) stats.push(`↓${tokens(usage.output)}`);\n\t\t\tif (usage.cacheRead > 0) stats.push(`R${tokens(usage.cacheRead)}`);\n\t\t\tif (usage.cacheWrite > 0) stats.push(`W${tokens(usage.cacheWrite)}`);\n\t\t\tif (state.latestCacheHitPercent !== undefined) stats.push(`CH${state.latestCacheHitPercent.toFixed(1)}%`);\n\t\t\tif (usage.cost.total > 0)\n\t\t\t\tstats.push(`$${usage.cost.total.toFixed(3)}${state.usesSubscription ? \" (sub)\" : \"\"}`);\n\t\t\tif (stats.length) parts.push(value(stats.join(\" \")));\n\t\t}\n\t\tif (state.blockedTools) parts.push(value(String(state.blockedTools)) + label(\" tools blocked\"));\n\t\tconst turn = state.turns.at(-1);\n\t\tif (turn && !state.busy) {\n\t\t\tparts.push(value(`${(turn.elapsedMs / 1000).toFixed(1)}s`));\n\t\t\tif (turn.firstAnswerMs !== undefined)\n\t\t\t\tparts.push(label(\"first \") + value(`${(turn.firstAnswerMs / 1000).toFixed(1)}s`));\n\t\t}\n\t\treturn parts.join(label(\" · \"));\n\t}\n\n\tprivate border(label: string, width: number, top: boolean, theme: Theme): string {\n\t\tconst text = label ? ` ${truncateToWidth(label, Math.max(0, width - 4))} ` : \"\";\n\t\treturn (\n\t\t\ttheme.fg(\"borderAccent\", top ? \"╭\" : \"╰\") +\n\t\t\ttext +\n\t\t\ttheme.fg(\"borderAccent\", `${\"─\".repeat(Math.max(0, width - visibleWidth(text) - 2))}${top ? \"╮\" : \"╯\"}`)\n\t\t);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"panel.js","sourceRoot":"","sources":["../../../src/extensions/btw/panel.ts"],"names":[],"mappings":"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","sourcesContent":["import \"./keybindings.ts\";\nimport {\n\ttype Component,\n\tMarkdown,\n\tText,\n\ttype TUI,\n\ttruncateToWidth,\n\tvisibleWidth,\n\twrapTextWithAnsi,\n} from \"@earendil-works/pi-tui\";\nimport { keyLabel } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport { getMarkdownTheme, type Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport type { BtwConversationState, BtwTurn } from \"./agent.ts\";\n\nexport type BtwPanelState<Conversation extends BtwConversationState = Readonly<BtwConversationState>> =\n\t| { phase: \"opening\" }\n\t| { phase: \"error\"; error: string }\n\t| {\n\t\t\tphase: \"ready\";\n\t\t\tcapturedAt: number;\n\t\t\tmodel: string;\n\t\t\tusesSubscription: boolean;\n\t\t\tconversation: Conversation;\n\t };\n\nfunction tokens(value: number): string {\n\tif (value < 1000) return String(value);\n\tif (value < 10_000) return `${(value / 1000).toFixed(1)}k`;\n\tif (value < 1_000_000) return `${Math.round(value / 1000)}k`;\n\tif (value < 10_000_000) return `${(value / 1_000_000).toFixed(1)}M`;\n\treturn `${Math.round(value / 1_000_000)}M`;\n}\n\n/** A bounded, scrollable widget above the normal editor. It never takes keyboard focus. */\nexport class BtwPanel implements Component {\n\tprivate readonly tui: Pick<TUI, \"terminal\" | \"requestRender\">;\n\tprivate readonly getTheme: () => Theme;\n\tprivate readonly getState: () => BtwPanelState;\n\tprivate readonly answers = new Map<BtwTurn, { text: string; markdown: Markdown }>();\n\tprivate follow = true;\n\tprivate offset = 0;\n\tprivate maxOffset = 0;\n\tprivate heldHeight = 0;\n\tprivate timer?: ReturnType<typeof setTimeout>;\n\tprivate disposed = false;\n\n\tconstructor(tui: Pick<TUI, \"terminal\" | \"requestRender\">, getTheme: () => Theme, getState: () => BtwPanelState) {\n\t\tthis.tui = tui;\n\t\tthis.getTheme = getTheme;\n\t\tthis.getState = getState;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.answers.clear();\n\t}\n\n\tchanged(): void {\n\t\tif (this.disposed) return;\n\t\tthis.tui.requestRender();\n\t\tconst state = this.getState();\n\t\tconst busy = state.phase === \"ready\" && state.conversation.busy;\n\t\tif (busy && !this.timer) {\n\t\t\tthis.timer = setTimeout(() => {\n\t\t\t\tthis.timer = undefined;\n\t\t\t\tthis.changed();\n\t\t\t}, 150);\n\t\t\tthis.timer.unref?.();\n\t\t} else if (!busy && this.timer) {\n\t\t\tclearTimeout(this.timer);\n\t\t\tthis.timer = undefined;\n\t\t}\n\t}\n\n\tfollowTail(): void {\n\t\tthis.follow = true;\n\t\tthis.changed();\n\t}\n\n\tscroll(delta: number): boolean {\n\t\tif (this.maxOffset === 0) return false;\n\t\tthis.offset = Math.max(0, Math.min(this.maxOffset, this.offset + delta));\n\t\tthis.follow = this.offset === this.maxOffset;\n\t\tthis.tui.requestRender();\n\t\treturn true;\n\t}\n\n\tdispose(): void {\n\t\tthis.disposed = true;\n\t\tif (this.timer) clearTimeout(this.timer);\n\t\tthis.timer = undefined;\n\t\tthis.answers.clear();\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.disposed || width < 1) return [];\n\t\tconst state = this.getState();\n\t\tconst busy = state.phase === \"ready\" && state.conversation.busy;\n\t\tconst theme = this.getTheme();\n\t\tconst innerWidth = Math.max(1, width - 4);\n\t\tconst lines = this.body(state, innerWidth, theme);\n\t\tconst cap = Math.max(1, Math.floor(this.tui.terminal.rows / 3) - 2);\n\t\tconst needed = Math.min(cap, Math.max(1, lines.length));\n\t\tthis.heldHeight = busy ? Math.min(cap, Math.max(this.heldHeight, needed)) : needed;\n\t\tthis.maxOffset = Math.max(0, lines.length - this.heldHeight);\n\t\tthis.offset = this.follow ? this.maxOffset : Math.min(this.offset, this.maxOffset);\n\t\tconst body = lines.slice(this.offset, this.offset + this.heldHeight);\n\t\twhile (body.length < this.heldHeight) body.push(\"\");\n\t\tconst close = keyLabel(\"app.btw.close\");\n\t\tconst cancel = keyLabel(\"app.btw.cancel\");\n\t\tconst title = [\n\t\t\ttheme.fg(\"accent\", theme.bold(\"BTW\")),\n\t\t\tclose && theme.fg(\"text\", close) + theme.fg(\"muted\", \" close\"),\n\t\t\tbusy && cancel && theme.fg(\"text\", cancel) + theme.fg(\"muted\", \" stop\"),\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.join(theme.fg(\"muted\", \" · \"));\n\t\tconst footer = this.footer(state, theme);\n\t\tif (width < 6) return body.map((line) => truncateToWidth(line, width));\n\t\treturn [\n\t\t\tthis.border(title, width, true, theme),\n\t\t\t...body.map(\n\t\t\t\t(line) =>\n\t\t\t\t\ttheme.fg(\"borderAccent\", \"│ \") +\n\t\t\t\t\ttruncateToWidth(line, innerWidth, \"…\", true) +\n\t\t\t\t\ttheme.fg(\"borderAccent\", \" │\"),\n\t\t\t),\n\t\t\tthis.border(footer, width, false, theme),\n\t\t];\n\t}\n\n\tprivate body(state: BtwPanelState, width: number, theme: Theme): string[] {\n\t\tif (state.phase === \"opening\") return [theme.fg(\"muted\", \"Capturing context…\")];\n\t\tif (state.phase === \"error\") return new Text(theme.fg(\"error\", state.error), 0, 0).render(width);\n\t\tif (!state.conversation.turns.length) {\n\t\t\treturn [\n\t\t\t\t...new Text(theme.fg(\"text\", \"Ask a side question in the editor below.\"), 0, 0).render(width),\n\t\t\t\t...new Text(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"muted\",\n\t\t\t\t\t\t`Context at ${new Date(state.capturedAt).toTimeString().slice(0, 8)} · ${state.model}`,\n\t\t\t\t\t),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t).render(width),\n\t\t\t];\n\t\t}\n\t\tconst lines: string[] = [];\n\t\tfor (const [index, turn] of state.conversation.turns.entries()) {\n\t\t\tif (index > 0) lines.push(\"\");\n\t\t\tlines.push(\n\t\t\t\t...new Text(\n\t\t\t\t\ttheme.fg(\"accent\", theme.bold(`Q${index + 1}: `)) + theme.fg(\"text\", turn.question),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t).render(width),\n\t\t\t);\n\t\t\tif (turn.answer) {\n\t\t\t\tlet answer = this.answers.get(turn);\n\t\t\t\tif (!answer) {\n\t\t\t\t\tanswer = {\n\t\t\t\t\t\ttext: turn.answer,\n\t\t\t\t\t\tmarkdown: new Markdown(turn.answer, 0, 0, getMarkdownTheme(), {\n\t\t\t\t\t\t\tcolor: (text) => theme.fg(\"text\", text),\n\t\t\t\t\t\t}),\n\t\t\t\t\t};\n\t\t\t\t\tthis.answers.set(turn, answer);\n\t\t\t\t} else if (answer.text !== turn.answer) {\n\t\t\t\t\tanswer.text = turn.answer;\n\t\t\t\t\tanswer.markdown.setText(turn.answer);\n\t\t\t\t}\n\t\t\t\tlines.push(...answer.markdown.render(width));\n\t\t\t} else if (turn.thinking && (turn.status === \"streaming\" || turn.status === \"cancelling\")) {\n\t\t\t\tlines.push(...wrapTextWithAnsi(theme.fg(\"muted\", turn.thinking.trimEnd()), width).slice(-2));\n\t\t\t}\n\t\t\tif (turn.status === \"streaming\" || turn.status === \"cancelling\") {\n\t\t\t\tconst elapsed = ((Date.now() - turn.startedAt) / 1000).toFixed(1);\n\t\t\t\tlines.push(theme.fg(\"muted\", `${turn.status === \"cancelling\" ? \"Stopping\" : \"Answering\"}… ${elapsed}s`));\n\t\t\t}\n\t\t\tif (turn.notice)\n\t\t\t\tlines.push(\n\t\t\t\t\t...new Text(theme.fg(turn.status === \"error\" ? \"error\" : \"muted\", turn.notice), 0, 0).render(width),\n\t\t\t\t);\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate footer(state: BtwPanelState, theme: Theme): string {\n\t\tconst parts: string[] = [];\n\t\tconst label = (text: string) => theme.fg(\"muted\", text);\n\t\tconst value = (text: string) => theme.fg(\"text\", text);\n\t\tif (this.maxOffset > 0) {\n\t\t\tconst keys = [keyLabel(\"app.btw.scrollUp\"), keyLabel(\"app.btw.scrollDown\")].filter(Boolean).join(\"/\");\n\t\t\tparts.push(\n\t\t\t\tvalue(keys) +\n\t\t\t\t\tlabel(\" scroll \") +\n\t\t\t\t\tvalue(`${this.offset + 1}–${this.offset + this.heldHeight}/${this.maxOffset + this.heldHeight}`),\n\t\t\t);\n\t\t}\n\t\tif (state.phase === \"ready\") {\n\t\t\tconst { conversation } = state;\n\t\t\tconst { usage } = conversation;\n\t\t\tconst stats: string[] = [];\n\t\t\tif (usage.input > 0) stats.push(`↑${tokens(usage.input)}`);\n\t\t\tif (usage.output > 0) stats.push(`↓${tokens(usage.output)}`);\n\t\t\tif (usage.cacheRead > 0) stats.push(`R${tokens(usage.cacheRead)}`);\n\t\t\tif (usage.cacheWrite > 0) stats.push(`W${tokens(usage.cacheWrite)}`);\n\t\t\tif (conversation.latestCacheHitPercent !== undefined)\n\t\t\t\tstats.push(`CH${conversation.latestCacheHitPercent.toFixed(1)}%`);\n\t\t\tif (usage.cost.total > 0)\n\t\t\t\tstats.push(`$${usage.cost.total.toFixed(3)}${state.usesSubscription ? \" (sub)\" : \"\"}`);\n\t\t\tif (stats.length) parts.push(value(stats.join(\" \")));\n\t\t\tif (conversation.blockedTools) parts.push(value(String(conversation.blockedTools)) + label(\" tools blocked\"));\n\t\t\tconst turn = conversation.turns.at(-1);\n\t\t\tif (turn && !conversation.busy) {\n\t\t\t\tparts.push(value(`${(turn.elapsedMs / 1000).toFixed(1)}s`));\n\t\t\t\tif (turn.firstAnswerMs !== undefined)\n\t\t\t\t\tparts.push(label(\"first \") + value(`${(turn.firstAnswerMs / 1000).toFixed(1)}s`));\n\t\t\t}\n\t\t}\n\t\treturn parts.join(label(\" · \"));\n\t}\n\n\tprivate border(label: string, width: number, top: boolean, theme: Theme): string {\n\t\tconst text = label ? ` ${truncateToWidth(label, Math.max(0, width - 4))} ` : \"\";\n\t\treturn (\n\t\t\ttheme.fg(\"borderAccent\", top ? \"╭\" : \"╰\") +\n\t\t\ttext +\n\t\t\ttheme.fg(\"borderAccent\", `${\"─\".repeat(Math.max(0, width - visibleWidth(text) - 2))}${top ? \"╮\" : \"╯\"}`)\n\t\t);\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/extensions/codemode/execute.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAmC,eAAe,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/extensions/codemode/execute.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAmC,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAqBtG,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,gCAAgC,CAAC;AAC1F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAGlE,OAAO,EAMN,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EAGxB,MAAM,WAAW,CAAC;AA6KnB,6FAA6F;AAC7F,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAU1F;AAsFD;;;GAGG;AACH,wBAAsB,eAAe,CACpC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,EAC9E,GAAG,EAAE,oBAAoB,GAAG,SAAS,EACrC,OAAO,GAAE,mBAAwB,GAC/B,OAAO,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC,CA2G/C"}
|
|
@@ -7,13 +7,13 @@ import { writeFile } from "node:fs/promises";
|
|
|
7
7
|
import { tmpdir } from "node:os";
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
import { CodemodeSandbox, loadQuickJSWasm, parseCodemodeSource, renderToolSample, toCodemodeIdentifier, } from "@earendil-works/pi-codemode";
|
|
10
|
-
import {
|
|
10
|
+
import { getCodemodeWorkerSpecifier, getQuickJSWasmPath } from "../../config.js";
|
|
11
11
|
import { combineUsage } from "../../core/usage-totals.js";
|
|
12
12
|
import { Bm25Ranker, createToolSearchDocument, DEFAULT_TOOL_SEARCH_LIMIT } from "./search.js";
|
|
13
|
-
import { CODEMODE_STORE_ENTRY_TYPE, getCodemodeCallableTools,
|
|
13
|
+
import { CODEMODE_DOCS_PATH, CODEMODE_STORE_ENTRY_TYPE, getCodemodeCallableTools, toCodemodeDeclaration, } from "./tool.js";
|
|
14
14
|
const ARGS_PREVIEW_CHARS = 200;
|
|
15
15
|
const ERROR_PREVIEW_CHARS = 500;
|
|
16
|
-
/**
|
|
16
|
+
/** `models.classify()` and `models.generateImages()` calls one script may have in flight; `Promise.all` over many items queues the rest. */
|
|
17
17
|
const MAX_CONCURRENT_MODEL_CALLS = 4;
|
|
18
18
|
/**
|
|
19
19
|
* Heap limit for the QuickJS VM. The worker shares pi's process, so without a limit a runaway
|
|
@@ -59,6 +59,90 @@ function toModelInfo(model) {
|
|
|
59
59
|
delete info.headers;
|
|
60
60
|
return info;
|
|
61
61
|
}
|
|
62
|
+
/** `an image`, `a classifier`. */
|
|
63
|
+
function withArticle(word) {
|
|
64
|
+
return `${/^[aeiou]/.test(word) ? "an" : "a"} ${word}`;
|
|
65
|
+
}
|
|
66
|
+
function isRecord(value) {
|
|
67
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
68
|
+
}
|
|
69
|
+
/** A script value in an error message: `undefined`, `a string`, `an array`, or its keys (`{ prompt }`). */
|
|
70
|
+
function describeValue(value) {
|
|
71
|
+
if (value === undefined || value === null)
|
|
72
|
+
return String(value);
|
|
73
|
+
if (Array.isArray(value))
|
|
74
|
+
return value.length === 0 ? "an empty array" : "an array";
|
|
75
|
+
if (typeof value === "object") {
|
|
76
|
+
const keys = Object.keys(value);
|
|
77
|
+
if (keys.length === 0)
|
|
78
|
+
return "{}";
|
|
79
|
+
return `{ ${keys.slice(0, 6).join(", ")}${keys.length > 6 ? ", ..." : ""} }`;
|
|
80
|
+
}
|
|
81
|
+
return typeof value === "string" ? "a string" : `a ${typeof value}`;
|
|
82
|
+
}
|
|
83
|
+
const CLASSIFIER_CONTEXT_SHAPE = '{ state: { ... }, questions: { <id>: { type: "choice", instructions, criteria: { <label>: <meaning> } } | { type: "score", instructions, criteria: [<lowest level>, ..., <highest level>] } | { type: "bool", instructions, criteria: { true: <meaning>, false: <meaning> } } } }';
|
|
84
|
+
/** Check a script's classifier context, so mistakes fail with the expected shape instead of a provider error. */
|
|
85
|
+
function checkClassifierContext(context) {
|
|
86
|
+
const fail = (problem) => new Error(`models.classify() ${problem}. Expected context: ${CLASSIFIER_CONTEXT_SHAPE}. See "Classify" in ${CODEMODE_DOCS_PATH}.`);
|
|
87
|
+
if (!isRecord(context))
|
|
88
|
+
throw fail(`expects a context object as its second argument, got ${describeValue(context)}`);
|
|
89
|
+
if (!isRecord(context.state))
|
|
90
|
+
throw fail(`context.state must be an object, got ${describeValue(context.state)}`);
|
|
91
|
+
const { questions } = context;
|
|
92
|
+
if (!isRecord(questions) || Object.keys(questions).length === 0) {
|
|
93
|
+
throw fail(`context.questions must map question IDs to questions, got ${describeValue(questions)}`);
|
|
94
|
+
}
|
|
95
|
+
const isStrings = (values) => values.length > 0 && values.every((value) => typeof value === "string");
|
|
96
|
+
for (const [id, question] of Object.entries(questions)) {
|
|
97
|
+
const at = `context.questions.${id}`;
|
|
98
|
+
if (!isRecord(question))
|
|
99
|
+
throw fail(`${at} must be a question object, got ${describeValue(question)}`);
|
|
100
|
+
if (typeof question.instructions !== "string")
|
|
101
|
+
throw fail(`${at}.instructions must be a string`);
|
|
102
|
+
const { criteria } = question;
|
|
103
|
+
if (question.type === "choice") {
|
|
104
|
+
if (!isRecord(criteria) || !isStrings(Object.values(criteria))) {
|
|
105
|
+
throw fail(`${at} is a "choice" question, so criteria must map each label to its meaning`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else if (question.type === "score") {
|
|
109
|
+
if (!Array.isArray(criteria) || !isStrings(criteria)) {
|
|
110
|
+
throw fail(`${at} is a "score" question, so criteria must list the levels as strings, lowest first`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else if (question.type === "bool") {
|
|
114
|
+
if (!isRecord(criteria) || typeof criteria.true !== "string" || typeof criteria.false !== "string") {
|
|
115
|
+
throw fail(`${at} is a "bool" question, so criteria must be { true: string, false: string }`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
throw fail(`${at}.type must be "choice", "score", or "bool", got ${JSON.stringify(question.type)}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return context;
|
|
123
|
+
}
|
|
124
|
+
/** Check a script's image context, so mistakes such as `{ prompt }` fail with the expected shape. */
|
|
125
|
+
function checkImagesContext(context) {
|
|
126
|
+
const fail = (problem) => new Error(`models.generateImages() ${problem}. Expected context: { input: [{ type: "text", text: <prompt> }, ...optional { type: "image", data: <base64>, mimeType } references] }. See "Generate images" in ${CODEMODE_DOCS_PATH}.`);
|
|
127
|
+
if (!isRecord(context))
|
|
128
|
+
throw fail(`expects a context object as its second argument, got ${describeValue(context)}`);
|
|
129
|
+
const { input } = context;
|
|
130
|
+
if (!Array.isArray(input) || input.length === 0) {
|
|
131
|
+
throw fail(`context.input must be a non-empty array of blocks, got ${describeValue(input)}`);
|
|
132
|
+
}
|
|
133
|
+
input.forEach((block, index) => {
|
|
134
|
+
if (isRecord(block) && block.type === "text" && typeof block.text === "string")
|
|
135
|
+
return;
|
|
136
|
+
if (isRecord(block) &&
|
|
137
|
+
block.type === "image" &&
|
|
138
|
+
typeof block.data === "string" &&
|
|
139
|
+
typeof block.mimeType === "string") {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
throw fail(`context.input[${index}] must be a text or image block, got ${describeValue(block)}`);
|
|
143
|
+
});
|
|
144
|
+
return context;
|
|
145
|
+
}
|
|
62
146
|
/** Runs at most `limit` calls at once, in call order. */
|
|
63
147
|
function createLimiter(limit) {
|
|
64
148
|
let active = 0;
|
|
@@ -188,6 +272,11 @@ export async function executeCodemode(toolCallId, input, signal, onUpdate, ctx,
|
|
|
188
272
|
const calls = [];
|
|
189
273
|
// Usage of the script's `models.*` calls. Nested tool calls report theirs through the session.
|
|
190
274
|
let modelUsage;
|
|
275
|
+
// Images returned by `models.generateImages()`, to notice a script that never shows them.
|
|
276
|
+
let generatedImages = 0;
|
|
277
|
+
const addGeneratedImages = (count) => {
|
|
278
|
+
generatedImages += count;
|
|
279
|
+
};
|
|
191
280
|
const addModelUsage = (usage) => {
|
|
192
281
|
modelUsage = modelUsage ? combineUsage(modelUsage, usage) : usage;
|
|
193
282
|
};
|
|
@@ -231,13 +320,13 @@ export async function executeCodemode(toolCallId, input, signal, onUpdate, ctx,
|
|
|
231
320
|
globals: [
|
|
232
321
|
...createDiscoveryGlobals(callable, samples, options),
|
|
233
322
|
...(options.models && ctx
|
|
234
|
-
? createModelGlobals(ctx.modelRegistry, toolCallId, calls, publish, addModelUsage)
|
|
323
|
+
? createModelGlobals(ctx.modelRegistry, toolCallId, calls, publish, addModelUsage, addGeneratedImages)
|
|
235
324
|
: []),
|
|
236
325
|
],
|
|
237
326
|
timeoutMs: sourceOptions.timeoutMs ?? Number.POSITIVE_INFINITY,
|
|
238
327
|
memoryLimitBytes: CODEMODE_MEMORY_LIMIT_BYTES,
|
|
239
328
|
wasm: loadQuickJSWasm(getQuickJSWasmPath()),
|
|
240
|
-
workerUrl:
|
|
329
|
+
workerUrl: getCodemodeWorkerSpecifier(),
|
|
241
330
|
});
|
|
242
331
|
let result;
|
|
243
332
|
try {
|
|
@@ -265,6 +354,12 @@ export async function executeCodemode(toolCallId, input, signal, onUpdate, ctx,
|
|
|
265
354
|
else {
|
|
266
355
|
items.push({ type: "text", text: `Script error:\n${formatError(result, calls)}` });
|
|
267
356
|
}
|
|
357
|
+
if (generatedImages > 0 && !items.some((item) => item.type === "image")) {
|
|
358
|
+
items.push({
|
|
359
|
+
type: "text",
|
|
360
|
+
text: `Note: models.generateImages() returned ${generatedImages} image${generatedImages === 1 ? "" : "s"} that the script did not show. Show each image block of result.output with image(block).`,
|
|
361
|
+
});
|
|
362
|
+
}
|
|
268
363
|
const truncated = await truncateOutput(items, sourceOptions.maxOutputTokens ?? DEFAULT_MAX_OUTPUT_TOKENS);
|
|
269
364
|
const wallTime = ((performance.now() - startedAt) / 1000).toFixed(1);
|
|
270
365
|
const header = `${result.ok ? "Script completed" : "Script failed"}\nWall time ${wallTime} seconds\nOutput:\n`;
|
|
@@ -278,7 +373,20 @@ export async function executeCodemode(toolCallId, input, signal, onUpdate, ctx,
|
|
|
278
373
|
...(result.ok ? {} : { isError: true }),
|
|
279
374
|
};
|
|
280
375
|
}
|
|
281
|
-
/**
|
|
376
|
+
/**
|
|
377
|
+
* Whether `query` names the namespace: its name, its script identifier (`mcp__dev-radius` is
|
|
378
|
+
* `mcp__dev_radius`), or the part after its last `__` in either form (`dev-radius`, `dev_radius`).
|
|
379
|
+
*/
|
|
380
|
+
function isNamespaceName(namespace, query) {
|
|
381
|
+
const id = toCodemodeIdentifier(namespace);
|
|
382
|
+
const queryId = toCodemodeIdentifier(query);
|
|
383
|
+
const suffix = (name) => (name.includes("__") ? name.slice(name.lastIndexOf("__") + 2) : undefined);
|
|
384
|
+
return namespace === query || id === queryId || suffix(namespace) === query || suffix(id) === queryId;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* `searchTools()`, `describeTool()`, and `describeNamespace()`: ranked search and lookup over the
|
|
388
|
+
* script's nested tools and their namespaces.
|
|
389
|
+
*/
|
|
282
390
|
function createDiscoveryGlobals(tools, samples, options) {
|
|
283
391
|
const ranker = new Bm25Ranker();
|
|
284
392
|
const entry = (name) => ({ name: toCodemodeIdentifier(name), description: samples.get(name) ?? "" });
|
|
@@ -300,7 +408,7 @@ function createDiscoveryGlobals(tools, samples, options) {
|
|
|
300
408
|
}
|
|
301
409
|
const documents = tools.flatMap((tool) => {
|
|
302
410
|
const toolNamespace = options.getToolNamespace?.(tool.name);
|
|
303
|
-
if (namespace && toolNamespace
|
|
411
|
+
if (namespace && (!toolNamespace || !isNamespaceName(toolNamespace.name, namespace)))
|
|
304
412
|
return [];
|
|
305
413
|
return [createToolSearchDocument(tool, toolNamespace)];
|
|
306
414
|
});
|
|
@@ -318,16 +426,86 @@ function createDiscoveryGlobals(tools, samples, options) {
|
|
|
318
426
|
return tool ? samples.get(tool.name) : undefined;
|
|
319
427
|
},
|
|
320
428
|
},
|
|
429
|
+
{
|
|
430
|
+
name: "describeNamespace",
|
|
431
|
+
spread: true,
|
|
432
|
+
execute: (args) => {
|
|
433
|
+
const [name] = args;
|
|
434
|
+
if (typeof name !== "string")
|
|
435
|
+
throw new Error("describeNamespace() expects a namespace name");
|
|
436
|
+
let namespace;
|
|
437
|
+
const names = [];
|
|
438
|
+
for (const tool of tools) {
|
|
439
|
+
const toolNamespace = options.getToolNamespace?.(tool.name);
|
|
440
|
+
if (!toolNamespace || !isNamespaceName(toolNamespace.name, name))
|
|
441
|
+
continue;
|
|
442
|
+
namespace ??= toolNamespace;
|
|
443
|
+
names.push(toCodemodeIdentifier(tool.name));
|
|
444
|
+
}
|
|
445
|
+
if (!namespace)
|
|
446
|
+
return undefined;
|
|
447
|
+
return {
|
|
448
|
+
name: namespace.name,
|
|
449
|
+
...(namespace.description ? { description: namespace.description } : {}),
|
|
450
|
+
...(namespace.instructions ? { instructions: namespace.instructions } : {}),
|
|
451
|
+
tools: names,
|
|
452
|
+
};
|
|
453
|
+
},
|
|
454
|
+
},
|
|
321
455
|
];
|
|
322
456
|
}
|
|
323
457
|
/**
|
|
324
|
-
* `models.*` for scripts: the model registry methods
|
|
325
|
-
* Classifier calls appear as nested call rows so the renderer shows them, and their usage
|
|
326
|
-
* `addUsage`.
|
|
458
|
+
* `models.*` for scripts: the model registry methods documented in docs/codemode.md.
|
|
459
|
+
* Classifier and image calls appear as nested call rows so the renderer shows them, and their usage
|
|
460
|
+
* goes to `addUsage`. Rows show only the model, never prompts or image data.
|
|
327
461
|
*/
|
|
328
|
-
function createModelGlobals(models, toolCallId, calls, publish, addUsage) {
|
|
462
|
+
function createModelGlobals(models, toolCallId, calls, publish, addUsage, addGeneratedImages) {
|
|
329
463
|
const limit = createLimiter(MAX_CONCURRENT_MODEL_CALLS);
|
|
330
|
-
let
|
|
464
|
+
let callCount = 0;
|
|
465
|
+
/**
|
|
466
|
+
* Resolve the script's model by provider and id only, check the context, then run the call as a
|
|
467
|
+
* nested call row. A script-supplied baseUrl or headers must never receive the credentials.
|
|
468
|
+
*/
|
|
469
|
+
const runModelCall = async (name, type, [model, context], checkContext, run) => {
|
|
470
|
+
const listHint = `List the ${type} models you can use with models.getAvailableOfType("${type}").`;
|
|
471
|
+
if (!isRecord(model) || typeof model.provider !== "string" || typeof model.id !== "string") {
|
|
472
|
+
// undefined arrives as null: spread arguments cross the sandbox as a JSON array.
|
|
473
|
+
const undefinedHint = model === undefined || model === null
|
|
474
|
+
? " models.getModelOfType() returns undefined for an unknown provider or id."
|
|
475
|
+
: "";
|
|
476
|
+
throw new Error(`${name}() expects ${withArticle(type)} model as its first argument, got ${describeValue(model)}.${undefinedHint} ${listHint}`);
|
|
477
|
+
}
|
|
478
|
+
const { provider, id } = model;
|
|
479
|
+
const ref = `${provider}/${id}`;
|
|
480
|
+
const resolved = models.getModelOfType(type, provider, id);
|
|
481
|
+
if (!resolved) {
|
|
482
|
+
const actualType = [...MODEL_TYPES].find((other) => other !== type && models.getModelOfType(other, provider, id) !== undefined);
|
|
483
|
+
throw new Error(actualType
|
|
484
|
+
? `"${ref}" is ${withArticle(actualType)} model, not ${withArticle(type)} model. ${listHint}`
|
|
485
|
+
: `Unknown ${type} model "${ref}". ${listHint}`);
|
|
486
|
+
}
|
|
487
|
+
const checked = checkContext(context);
|
|
488
|
+
const record = {
|
|
489
|
+
id: `${toolCallId}/${name}/${++callCount}`,
|
|
490
|
+
name,
|
|
491
|
+
args: `${resolved.provider}/${resolved.id}`,
|
|
492
|
+
status: "running",
|
|
493
|
+
};
|
|
494
|
+
calls.push(record);
|
|
495
|
+
publish();
|
|
496
|
+
const startedAt = performance.now();
|
|
497
|
+
const result = await limit(() => run(resolved, checked));
|
|
498
|
+
record.durationMs = performance.now() - startedAt;
|
|
499
|
+
record.status = result.stopReason === "stop" ? "ok" : result.stopReason === "aborted" ? "cancelled" : "error";
|
|
500
|
+
if (result.errorMessage)
|
|
501
|
+
record.error = truncateText(result.errorMessage, ERROR_PREVIEW_CHARS);
|
|
502
|
+
if (result.usage) {
|
|
503
|
+
record.cost = result.usage.cost.total;
|
|
504
|
+
addUsage(result.usage);
|
|
505
|
+
}
|
|
506
|
+
publish();
|
|
507
|
+
return result;
|
|
508
|
+
};
|
|
331
509
|
const implementations = {
|
|
332
510
|
"models.getModelsOfType": (args) => {
|
|
333
511
|
const [type, provider] = args;
|
|
@@ -341,50 +519,18 @@ function createModelGlobals(models, toolCallId, calls, publish, addUsage) {
|
|
|
341
519
|
"models.getModelOfType": (args) => {
|
|
342
520
|
const [type, provider, id] = args;
|
|
343
521
|
if (typeof provider !== "string" || typeof id !== "string") {
|
|
344
|
-
throw new Error(
|
|
522
|
+
throw new Error(`models.getModelOfType(type, provider, id) expects three strings, got (${args.map(describeValue).join(", ")}). The provider and the id are separate arguments, for example models.getModelOfType("classifier", "typesafe", "jev-latest").`);
|
|
345
523
|
}
|
|
346
524
|
const model = models.getModelOfType(toModelType(type), provider, id);
|
|
347
525
|
return model === undefined ? undefined : toModelInfo(model);
|
|
348
526
|
},
|
|
349
|
-
"models.classify":
|
|
350
|
-
|
|
351
|
-
const
|
|
352
|
-
|
|
353
|
-
ref === null ||
|
|
354
|
-
typeof ref.provider !== "string" ||
|
|
355
|
-
typeof ref.id !== "string") {
|
|
356
|
-
throw new Error("models.classify() expects a model from models.getModelOfType() or models.getAvailableOfType()");
|
|
357
|
-
}
|
|
358
|
-
// Only provider and id count. A script-supplied baseUrl or headers must never receive the credentials.
|
|
359
|
-
const resolved = models.getModelOfType("classifier", ref.provider, ref.id);
|
|
360
|
-
if (!resolved)
|
|
361
|
-
throw new Error(`Unknown classifier model "${ref.provider}/${ref.id}"`);
|
|
362
|
-
const record = {
|
|
363
|
-
id: `${toolCallId}/models.classify/${++classifyCount}`,
|
|
364
|
-
name: "models.classify",
|
|
365
|
-
args: `${resolved.provider}/${resolved.id}`,
|
|
366
|
-
status: "running",
|
|
367
|
-
};
|
|
368
|
-
calls.push(record);
|
|
369
|
-
publish();
|
|
370
|
-
const startedAt = performance.now();
|
|
371
|
-
const result = await limit(() => models.classify(resolved, context, { signal }));
|
|
372
|
-
record.durationMs = performance.now() - startedAt;
|
|
373
|
-
record.status = result.stopReason === "stop" ? "ok" : result.stopReason === "aborted" ? "cancelled" : "error";
|
|
374
|
-
if (result.errorMessage)
|
|
375
|
-
record.error = truncateText(result.errorMessage, ERROR_PREVIEW_CHARS);
|
|
376
|
-
if (result.usage) {
|
|
377
|
-
record.cost = result.usage.cost.total;
|
|
378
|
-
addUsage(result.usage);
|
|
379
|
-
}
|
|
380
|
-
publish();
|
|
527
|
+
"models.classify": (args, { signal }) => runModelCall("models.classify", "classifier", args, checkClassifierContext, (resolved, context) => models.classify(resolved, context, { signal })),
|
|
528
|
+
"models.generateImages": (args, { signal }) => runModelCall("models.generateImages", "image", args, checkImagesContext, async (resolved, context) => {
|
|
529
|
+
const result = await models.generateImages(resolved, context, { signal });
|
|
530
|
+
addGeneratedImages(result.output.filter((block) => block.type === "image").length);
|
|
381
531
|
return result;
|
|
382
|
-
},
|
|
532
|
+
}),
|
|
383
533
|
};
|
|
384
|
-
return
|
|
385
|
-
name: declaration.name,
|
|
386
|
-
spread: true,
|
|
387
|
-
execute: implementations[declaration.name],
|
|
388
|
-
}));
|
|
534
|
+
return Object.entries(implementations).map(([name, execute]) => ({ name, spread: true, execute }));
|
|
389
535
|
}
|
|
390
536
|
//# sourceMappingURL=execute.js.map
|