@astralyn/pi 0.87.5 → 0.99.0
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 +51 -6
- package/README.md +3 -3
- package/dist/bun/runtime-setup.js +4 -1
- package/dist/bun/runtime-setup.js.map +1 -1
- package/dist/bundle/chunks/anthropic-messages-KIXY7EDT.js +6 -0
- package/dist/bundle/chunks/anthropic.js +2 -2
- package/dist/bundle/chunks/azure-openai-responses-RPBERDXD.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +8 -8
- package/dist/bundle/chunks/{chunk-LPQCB2VJ.js → chunk-A576H74Y.js} +2 -2
- package/dist/bundle/chunks/{chunk-NW5FIDD7.js → chunk-ABVRAYXT.js} +3 -3
- package/dist/bundle/chunks/{chunk-I5IVW2WS.js → chunk-CLLDCO64.js} +1 -1
- package/dist/bundle/chunks/chunk-DEWXBB6W.js +2 -0
- package/dist/bundle/chunks/chunk-G4RY3GN7.js +11 -0
- package/dist/bundle/chunks/chunk-GCKVOFWP.js +2 -0
- package/dist/bundle/chunks/chunk-MPDALHNJ.js +2 -0
- package/dist/bundle/chunks/chunk-OO6DJ3CL.js +31 -0
- package/dist/bundle/chunks/{chunk-EWLAVDVN.js → chunk-VW2P3X6P.js} +921 -293
- package/dist/bundle/chunks/chunk-VWCWZD6E.js +2 -0
- package/dist/bundle/chunks/cloudflare-workers-ai-system-one-ZYSAFXXL.js +2 -0
- package/dist/bundle/chunks/codemode-worker.js +295 -0
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/google-generative-ai-SDNQVVXA.js +2 -0
- package/dist/bundle/chunks/google-vertex-LZXOLBIO.js +2 -0
- package/dist/bundle/chunks/llama-cpp-classify-7IYGGPND.js +22 -0
- package/dist/bundle/chunks/meta.js +2 -0
- package/dist/bundle/chunks/mistral-conversations-VYKPSSAM.js +5 -0
- package/dist/bundle/chunks/openai-chatgpt.js +75 -0
- package/dist/bundle/chunks/openai-codex-responses-HZ4VUDXD.js +10 -0
- package/dist/bundle/chunks/openai-codex.js +2 -2
- package/dist/bundle/chunks/openai-completions-SKDGF6OE.js +7 -0
- package/dist/bundle/chunks/openai-responses-FPML4SSG.js +3 -0
- package/dist/bundle/chunks/{openrouter-images-6XDE2CEW.js → openrouter-images-5524IQHX.js} +1 -1
- package/dist/bundle/chunks/openrouter.js +2 -2
- package/dist/bundle/chunks/{pi-messages-MQMPIPNC.js → pi-messages-HZZ7GEEW.js} +2 -2
- package/dist/bundle/chunks/radius.js +2 -2
- package/dist/bundle/chunks/typesafe-system-one-Z2CDLKEY.js +2 -0
- package/dist/bundle/chunks/virtual-modules-TQRORWJQ.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 +4 -3
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +38 -30
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/config.d.ts +18 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +30 -4
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +13 -13
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +2 -2
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +14 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +107 -58
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +505 -298
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bug-report.js +1 -1
- package/dist/core/bug-report.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +1 -22
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/utils.d.ts +2 -1
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js +25 -18
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/context-snapshot.d.ts +17 -4
- package/dist/core/context-snapshot.d.ts.map +1 -1
- package/dist/core/context-snapshot.js +48 -50
- package/dist/core/context-snapshot.js.map +1 -1
- package/dist/core/crash-log.d.ts.map +1 -1
- package/dist/core/crash-log.js +2 -1
- package/dist/core/crash-log.js.map +1 -1
- package/dist/core/export-html/template.css +10 -0
- package/dist/core/export-html/template.js +66 -17
- package/dist/core/extensions/distribution-api.d.ts +1 -8
- package/dist/core/extensions/distribution-api.d.ts.map +1 -1
- package/dist/core/extensions/distribution-api.js +6 -6
- package/dist/core/extensions/distribution-api.js.map +1 -1
- package/dist/core/extensions/index.d.ts +3 -3
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +58 -7
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +22 -3
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +124 -8
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +306 -30
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts +2 -2
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +3 -3
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/keybindings.d.ts +40 -5
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +10 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/mcp-servers.d.ts +98 -0
- package/dist/core/mcp-servers.d.ts.map +1 -0
- package/dist/core/mcp-servers.js +158 -0
- package/dist/core/mcp-servers.js.map +1 -0
- package/dist/core/model-registry.d.ts +13 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +25 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +2 -2
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +5 -5
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +41 -3
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +167 -17
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/nested-tool-calls.d.ts +102 -0
- package/dist/core/nested-tool-calls.d.ts.map +1 -0
- package/dist/core/nested-tool-calls.js +177 -0
- package/dist/core/nested-tool-calls.js.map +1 -0
- package/dist/core/package-manager.d.ts +4 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +58 -12
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/provider-composer.d.ts +40 -21
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +92 -40
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts +8 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +18 -3
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts +7 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +160 -35
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +3 -3
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +84 -14
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +9 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +22 -22
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +36 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +108 -2
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/source-info.d.ts +8 -0
- package/dist/core/source-info.d.ts.map +1 -1
- package/dist/core/source-info.js +16 -0
- package/dist/core/source-info.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/delivery.d.ts +40 -0
- package/dist/core/tasks/delivery.d.ts.map +1 -0
- package/dist/core/tasks/delivery.js +157 -0
- package/dist/core/tasks/delivery.js.map +1 -0
- package/dist/core/tasks/history.d.ts +4 -0
- package/dist/core/tasks/history.d.ts.map +1 -0
- package/dist/core/{background → tasks}/history.js +24 -48
- package/dist/core/tasks/history.js.map +1 -0
- package/dist/core/{background → tasks}/output.d.ts +4 -4
- package/dist/core/tasks/output.d.ts.map +1 -0
- package/dist/core/{background → tasks}/output.js +11 -11
- package/dist/core/tasks/output.js.map +1 -0
- package/dist/core/tasks/presentation.d.ts +9 -0
- package/dist/core/tasks/presentation.d.ts.map +1 -0
- package/dist/core/{background → tasks}/presentation.js +53 -51
- package/dist/core/tasks/presentation.js.map +1 -0
- package/dist/core/{background/service.d.ts → tasks/runtime.d.ts} +22 -23
- package/dist/core/tasks/runtime.d.ts.map +1 -0
- package/dist/core/{background/service.js → tasks/runtime.js} +154 -198
- package/dist/core/tasks/runtime.js.map +1 -0
- package/dist/core/tasks/session.d.ts +49 -0
- package/dist/core/tasks/session.d.ts.map +1 -0
- package/dist/core/tasks/session.js +129 -0
- package/dist/core/tasks/session.js.map +1 -0
- package/dist/core/tasks/store.d.ts +32 -0
- package/dist/core/tasks/store.d.ts.map +1 -0
- package/dist/core/tasks/store.js +135 -0
- package/dist/core/tasks/store.js.map +1 -0
- package/dist/core/{background → tasks}/types.d.ts +80 -62
- package/dist/core/tasks/types.d.ts.map +1 -0
- package/dist/core/{background → tasks}/types.js +9 -9
- package/dist/core/tasks/types.js.map +1 -0
- package/dist/core/tasks/view-data.d.ts +8 -0
- package/dist/core/tasks/view-data.d.ts.map +1 -0
- package/dist/core/tasks/view-data.js +61 -0
- package/dist/core/tasks/view-data.js.map +1 -0
- package/dist/core/tasks/view.d.ts +30 -0
- package/dist/core/tasks/view.d.ts.map +1 -0
- package/dist/core/tasks/view.js +50 -0
- package/dist/core/tasks/view.js.map +1 -0
- package/dist/core/tools/bash.d.ts +8 -95
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +8 -240
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +0 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +2 -0
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +2 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +2 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +9 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +0 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +11 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +36 -0
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/powershell.d.ts +6 -2
- package/dist/core/tools/powershell.d.ts.map +1 -1
- package/dist/core/tools/powershell.js +1 -1
- package/dist/core/tools/powershell.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +0 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +6 -7
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +26 -11
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/renderers/bash.d.ts +1 -1
- package/dist/core/tools/renderers/bash.d.ts.map +1 -1
- package/dist/core/tools/renderers/bash.js +65 -12
- package/dist/core/tools/renderers/bash.js.map +1 -1
- package/dist/core/tools/renderers/edit.d.ts.map +1 -1
- package/dist/core/tools/renderers/edit.js +4 -22
- package/dist/core/tools/renderers/edit.js.map +1 -1
- package/dist/core/tools/renderers/find.d.ts.map +1 -1
- package/dist/core/tools/renderers/find.js +7 -6
- package/dist/core/tools/renderers/find.js.map +1 -1
- package/dist/core/tools/renderers/grep.d.ts.map +1 -1
- package/dist/core/tools/renderers/grep.js +8 -7
- package/dist/core/tools/renderers/grep.js.map +1 -1
- package/dist/core/tools/renderers/index.d.ts.map +1 -1
- package/dist/core/tools/renderers/index.js +5 -7
- package/dist/core/tools/renderers/index.js.map +1 -1
- package/dist/core/tools/renderers/ls.d.ts.map +1 -1
- package/dist/core/tools/renderers/ls.js +3 -2
- package/dist/core/tools/renderers/ls.js.map +1 -1
- package/dist/core/tools/renderers/read.d.ts.map +1 -1
- package/dist/core/tools/renderers/read.js +10 -14
- package/dist/core/tools/renderers/read.js.map +1 -1
- package/dist/core/tools/renderers/shell-task.d.ts +4 -0
- package/dist/core/tools/renderers/shell-task.d.ts.map +1 -0
- package/dist/core/tools/renderers/shell-task.js +35 -0
- package/dist/core/tools/renderers/shell-task.js.map +1 -0
- package/dist/core/tools/renderers/write.d.ts.map +1 -1
- package/dist/core/tools/renderers/write.js +3 -2
- package/dist/core/tools/renderers/write.js.map +1 -1
- package/dist/core/tools/shell-execution.d.ts +4 -5
- package/dist/core/tools/shell-execution.d.ts.map +1 -1
- package/dist/core/tools/shell-execution.js +19 -3
- package/dist/core/tools/shell-execution.js.map +1 -1
- package/dist/core/tools/shell-tool.d.ts +93 -0
- package/dist/core/tools/shell-tool.d.ts.map +1 -0
- package/dist/core/tools/shell-tool.js +251 -0
- package/dist/core/tools/shell-tool.js.map +1 -0
- package/dist/core/tools/tasks/actions.d.ts +12 -0
- package/dist/core/tools/tasks/actions.d.ts.map +1 -0
- package/dist/{extensions/background → core/tools/tasks}/actions.js +20 -19
- package/dist/core/tools/tasks/actions.js.map +1 -0
- package/dist/core/tools/tasks/constants.d.ts +24 -0
- package/dist/core/tools/tasks/constants.d.ts.map +1 -0
- package/dist/{extensions/background → core/tools/tasks}/constants.js +11 -9
- package/dist/core/tools/tasks/constants.js.map +1 -0
- package/dist/{extensions/background → core/tools/tasks}/schema.d.ts +6 -6
- package/dist/core/tools/tasks/schema.d.ts.map +1 -0
- package/dist/{extensions/background → core/tools/tasks}/schema.js +17 -17
- package/dist/core/tools/tasks/schema.js.map +1 -0
- package/dist/{extensions/background → core/tools/tasks}/types.d.ts +15 -17
- package/dist/core/tools/tasks/types.d.ts.map +1 -0
- package/dist/core/tools/tasks/types.js.map +1 -0
- package/dist/core/tools/tasks.d.ts +14 -0
- package/dist/core/tools/tasks.d.ts.map +1 -0
- package/dist/core/tools/tasks.js +40 -0
- package/dist/core/tools/tasks.js.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts +5 -8
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +4 -4
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/tools/truncate.d.ts +14 -0
- package/dist/core/tools/truncate.d.ts.map +1 -1
- package/dist/core/tools/truncate.js +29 -0
- package/dist/core/tools/truncate.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +1 -0
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/usage-totals.d.ts +5 -3
- package/dist/core/usage-totals.d.ts.map +1 -1
- package/dist/core/usage-totals.js +27 -4
- package/dist/core/usage-totals.js.map +1 -1
- package/dist/core/virtual-models.d.ts +115 -0
- package/dist/core/virtual-models.d.ts.map +1 -0
- package/dist/core/virtual-models.js +117 -0
- package/dist/core/virtual-models.js.map +1 -0
- package/dist/extensions/codemode/execute.d.ts +16 -0
- package/dist/extensions/codemode/execute.d.ts.map +1 -0
- package/dist/extensions/codemode/execute.js +390 -0
- package/dist/extensions/codemode/execute.js.map +1 -0
- package/dist/extensions/codemode/execute.lazy.d.ts +3 -0
- package/dist/extensions/codemode/execute.lazy.d.ts.map +1 -0
- package/dist/extensions/codemode/execute.lazy.js +3 -0
- package/dist/extensions/codemode/execute.lazy.js.map +1 -0
- package/dist/extensions/codemode/index.d.ts +21 -0
- package/dist/extensions/codemode/index.d.ts.map +1 -0
- package/dist/extensions/codemode/index.js +36 -0
- package/dist/extensions/codemode/index.js.map +1 -0
- package/dist/extensions/codemode/renderer.d.ts +12 -0
- package/dist/extensions/codemode/renderer.d.ts.map +1 -0
- package/dist/extensions/codemode/renderer.js +119 -0
- package/dist/extensions/codemode/renderer.js.map +1 -0
- package/dist/extensions/codemode/search.d.ts +33 -0
- package/dist/extensions/codemode/search.d.ts.map +1 -0
- package/dist/extensions/codemode/search.js +117 -0
- package/dist/extensions/codemode/search.js.map +1 -0
- package/dist/extensions/codemode/tool.d.ts +122 -0
- package/dist/extensions/codemode/tool.d.ts.map +1 -0
- package/dist/extensions/codemode/tool.js +324 -0
- package/dist/extensions/codemode/tool.js.map +1 -0
- package/dist/extensions/codemode/worker.d.ts +7 -0
- package/dist/extensions/codemode/worker.d.ts.map +1 -0
- package/dist/extensions/codemode/worker.js +7 -0
- package/dist/extensions/codemode/worker.js.map +1 -0
- package/dist/extensions/deepwiki/schema.d.ts +1 -1
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +14 -12
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +65 -13
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/extensions/mcp/cli.d.ts +21 -0
- package/dist/extensions/mcp/cli.d.ts.map +1 -0
- package/dist/extensions/mcp/cli.js +485 -0
- package/dist/extensions/mcp/cli.js.map +1 -0
- package/dist/extensions/mcp/cli.lazy.d.ts +3 -0
- package/dist/extensions/mcp/cli.lazy.d.ts.map +1 -0
- package/dist/extensions/mcp/cli.lazy.js +3 -0
- package/dist/extensions/mcp/cli.lazy.js.map +1 -0
- package/dist/extensions/mcp/config.d.ts +70 -0
- package/dist/extensions/mcp/config.d.ts.map +1 -0
- package/dist/extensions/mcp/config.js +146 -0
- package/dist/extensions/mcp/config.js.map +1 -0
- package/dist/extensions/mcp/index.d.ts +52 -0
- package/dist/extensions/mcp/index.d.ts.map +1 -0
- package/dist/extensions/mcp/index.js +904 -0
- package/dist/extensions/mcp/index.js.map +1 -0
- package/dist/extensions/mcp/log.d.ts +16 -0
- package/dist/extensions/mcp/log.d.ts.map +1 -0
- package/dist/extensions/mcp/log.js +64 -0
- package/dist/extensions/mcp/log.js.map +1 -0
- package/dist/extensions/mcp/oauth.d.ts +94 -0
- package/dist/extensions/mcp/oauth.d.ts.map +1 -0
- package/dist/extensions/mcp/oauth.js +330 -0
- package/dist/extensions/mcp/oauth.js.map +1 -0
- package/dist/extensions/mcp/resources.d.ts +43 -0
- package/dist/extensions/mcp/resources.d.ts.map +1 -0
- package/dist/extensions/mcp/resources.js +262 -0
- package/dist/extensions/mcp/resources.js.map +1 -0
- package/dist/extensions/mcp/runtime.d.ts +96 -0
- package/dist/extensions/mcp/runtime.d.ts.map +1 -0
- package/dist/extensions/mcp/runtime.js +372 -0
- package/dist/extensions/mcp/runtime.js.map +1 -0
- package/dist/extensions/mcp/runtime.lazy.d.ts +3 -0
- package/dist/extensions/mcp/runtime.lazy.d.ts.map +1 -0
- package/dist/extensions/mcp/runtime.lazy.js +3 -0
- package/dist/extensions/mcp/runtime.lazy.js.map +1 -0
- package/dist/extensions/mcp/tools.d.ts +83 -0
- package/dist/extensions/mcp/tools.d.ts.map +1 -0
- package/dist/extensions/mcp/tools.js +233 -0
- package/dist/extensions/mcp/tools.js.map +1 -0
- package/dist/extensions/mcp/ui.d.ts +60 -0
- package/dist/extensions/mcp/ui.d.ts.map +1 -0
- package/dist/extensions/mcp/ui.js +166 -0
- package/dist/extensions/mcp/ui.js.map +1 -0
- package/dist/extensions/question/detail-pane.d.ts +12 -0
- package/dist/extensions/question/detail-pane.d.ts.map +1 -0
- package/dist/extensions/question/detail-pane.js +42 -0
- package/dist/extensions/question/detail-pane.js.map +1 -0
- package/dist/extensions/question/dialog.d.ts.map +1 -1
- package/dist/extensions/question/dialog.js +175 -105
- package/dist/extensions/question/dialog.js.map +1 -1
- package/dist/extensions/question/option-window.d.ts +26 -0
- package/dist/extensions/question/option-window.d.ts.map +1 -0
- package/dist/extensions/question/option-window.js +53 -0
- package/dist/extensions/question/option-window.js.map +1 -0
- package/dist/extensions/question/render-cache.d.ts +4 -4
- package/dist/extensions/question/render-cache.d.ts.map +1 -1
- package/dist/extensions/question/render-cache.js +10 -11
- package/dist/extensions/question/render-cache.js.map +1 -1
- package/dist/extensions/statusline/index.js +2 -2
- package/dist/extensions/statusline/index.js.map +1 -1
- package/dist/extensions/todo/index.d.ts.map +1 -1
- package/dist/extensions/todo/index.js +12 -8
- package/dist/extensions/todo/index.js.map +1 -1
- package/dist/extensions/todo/view.d.ts +3 -3
- package/dist/extensions/todo/view.d.ts.map +1 -1
- package/dist/extensions/todo/view.js +7 -6
- package/dist/extensions/todo/view.js.map +1 -1
- package/dist/extensions/tool-search/index.d.ts +12 -0
- package/dist/extensions/tool-search/index.d.ts.map +1 -0
- package/dist/extensions/tool-search/index.js +20 -0
- package/dist/extensions/tool-search/index.js.map +1 -0
- package/dist/extensions/tool-search/tool.d.ts +72 -0
- package/dist/extensions/tool-search/tool.d.ts.map +1 -0
- package/dist/extensions/tool-search/tool.js +208 -0
- package/dist/extensions/tool-search/tool.js.map +1 -0
- package/dist/index.d.ts +13 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +10 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +13 -3
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +3 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts +4 -4
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +8 -2
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +7 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +42 -3
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/pi-logo.d.ts +12 -0
- package/dist/modes/interactive/components/pi-logo.d.ts.map +1 -0
- package/dist/modes/interactive/components/pi-logo.js +25 -0
- package/dist/modes/interactive/components/pi-logo.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +28 -6
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/status-marker.d.ts +4 -4
- package/dist/modes/interactive/components/status-marker.js +4 -4
- package/dist/modes/interactive/components/status-marker.js.map +1 -1
- package/dist/modes/interactive/components/themed-text.d.ts +17 -0
- package/dist/modes/interactive/components/themed-text.d.ts.map +1 -0
- package/dist/modes/interactive/components/themed-text.js +28 -0
- package/dist/modes/interactive/components/themed-text.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +2 -4
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +221 -173
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tasks/completion-render.d.ts +8 -0
- package/dist/modes/interactive/tasks/completion-render.d.ts.map +1 -0
- package/dist/{extensions/background → modes/interactive/tasks}/completion-render.js +33 -30
- package/dist/modes/interactive/tasks/completion-render.js.map +1 -0
- package/dist/modes/interactive/tasks/fallback-view.d.ts +4 -0
- package/dist/modes/interactive/tasks/fallback-view.d.ts.map +1 -0
- package/dist/modes/interactive/tasks/fallback-view.js +27 -0
- package/dist/modes/interactive/tasks/fallback-view.js.map +1 -0
- package/dist/modes/interactive/tasks/index.d.ts +12 -0
- package/dist/modes/interactive/tasks/index.d.ts.map +1 -0
- package/dist/modes/interactive/tasks/index.js +97 -0
- package/dist/modes/interactive/tasks/index.js.map +1 -0
- package/dist/modes/interactive/tasks/manager.d.ts +67 -0
- package/dist/modes/interactive/tasks/manager.d.ts.map +1 -0
- package/dist/modes/interactive/tasks/manager.js +380 -0
- package/dist/modes/interactive/tasks/manager.js.map +1 -0
- package/dist/{extensions/background → modes/interactive/tasks}/render.d.ts +13 -13
- package/dist/modes/interactive/tasks/render.d.ts.map +1 -0
- package/dist/{extensions/background → modes/interactive/tasks}/render.js +18 -18
- package/dist/modes/interactive/tasks/render.js.map +1 -0
- package/dist/{extensions/background → modes/interactive/tasks}/task-view.d.ts +7 -7
- package/dist/modes/interactive/tasks/task-view.d.ts.map +1 -0
- package/dist/{extensions/background → modes/interactive/tasks}/task-view.js +4 -4
- package/dist/modes/interactive/tasks/task-view.js.map +1 -0
- package/dist/{extensions/background → modes/interactive/tasks}/text.d.ts +1 -1
- package/dist/modes/interactive/tasks/text.d.ts.map +1 -0
- package/dist/{extensions/background → modes/interactive/tasks}/text.js +1 -1
- package/dist/modes/interactive/tasks/text.js.map +1 -0
- package/dist/modes/interactive/tasks/viewport.d.ts +15 -0
- package/dist/modes/interactive/tasks/viewport.d.ts.map +1 -0
- package/dist/modes/interactive/tasks/viewport.js +49 -0
- package/dist/modes/interactive/tasks/viewport.js.map +1 -0
- package/dist/modes/interactive/theme/dark.json +59 -72
- package/dist/modes/interactive/theme/light.json +57 -69
- package/dist/modes/interactive/theme/system-theme.d.ts +54 -0
- package/dist/modes/interactive/theme/system-theme.d.ts.map +1 -0
- package/dist/modes/interactive/theme/system-theme.js +535 -0
- package/dist/modes/interactive/theme/system-theme.js.map +1 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +46 -6
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +125 -47
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-json.d.ts +1 -0
- package/dist/modes/interactive/theme/theme-json.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-json.js +3 -1
- package/dist/modes/interactive/theme/theme-json.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +7 -2
- package/dist/modes/interactive/theme/theme.d.ts +70 -39
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +247 -314
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/interactive/tool-view/chat.d.ts +20 -0
- package/dist/modes/interactive/tool-view/chat.d.ts.map +1 -0
- package/dist/modes/interactive/tool-view/chat.js +46 -0
- package/dist/modes/interactive/tool-view/chat.js.map +1 -0
- package/dist/modes/interactive/tool-view/fallback.d.ts +14 -0
- package/dist/modes/interactive/tool-view/fallback.d.ts.map +1 -0
- package/dist/modes/interactive/tool-view/fallback.js +55 -0
- package/dist/modes/interactive/tool-view/fallback.js.map +1 -0
- package/dist/modes/interactive/tool-view/style.d.ts +63 -0
- package/dist/modes/interactive/tool-view/style.d.ts.map +1 -0
- package/dist/modes/interactive/tool-view/style.js +83 -0
- package/dist/modes/interactive/tool-view/style.js.map +1 -0
- package/dist/modes/interactive/{components → tool-view}/tool-execution.d.ts +17 -24
- package/dist/modes/interactive/tool-view/tool-execution.d.ts.map +1 -0
- package/dist/modes/interactive/{components → tool-view}/tool-execution.js +42 -116
- package/dist/modes/interactive/tool-view/tool-execution.js.map +1 -0
- package/dist/modes/interactive/tui-renderer.d.ts +2 -1
- package/dist/modes/interactive/tui-renderer.d.ts.map +1 -1
- package/dist/modes/interactive/tui-renderer.js +1 -0
- package/dist/modes/interactive/tui-renderer.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +6 -6
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +12 -8
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +7 -9
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +10 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +6 -2
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +14 -17
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard.d.ts +2 -0
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +5 -0
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/paths.d.ts +3 -3
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +5 -4
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/shell.d.ts +1 -3
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +3 -30
- package/dist/utils/shell.js.map +1 -1
- package/docs/bundled/README.md +22 -8
- package/docs/bundled/extensions/question.md +6 -5
- package/docs/bundled/extensions/statusline.md +2 -2
- package/docs/bundled/tasks.md +141 -0
- package/docs/bundled/tool-presentation.md +41 -31
- package/docs/custom-provider.md +44 -0
- package/docs/docs.json +10 -6
- package/docs/extensions.md +90 -90
- package/docs/index.md +2 -1
- package/docs/keybindings.md +19 -7
- package/docs/llama-cpp.md +12 -1
- package/docs/mcp.md +188 -0
- package/docs/models.md +35 -0
- package/docs/packages.md +4 -0
- package/docs/providers.md +6 -0
- package/docs/rpc.md +5 -3
- package/docs/sdk.md +26 -16
- package/docs/security.md +4 -0
- package/docs/session-format.md +18 -11
- package/docs/settings.md +26 -2
- package/docs/themes.md +27 -5
- package/docs/tui.md +20 -0
- package/docs/usage.md +61 -3
- package/docs/virtual-models.md +114 -0
- package/docs/windows.md +2 -0
- package/examples/README.md +1 -1
- package/examples/extensions/README.md +2 -0
- 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/custom-provider-gitlab-duo/test.ts +4 -4
- package/examples/extensions/debug-provider.ts +90 -0
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/jev-router.ts +113 -0
- 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/rpc-client.ts +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/14-codemode-mcp.ts +61 -0
- package/examples/sdk/README.md +1 -0
- package/npm-shrinkwrap.json +409 -423
- package/package.json +13 -10
- package/dist/bundle/chunks/anthropic-messages-XWFTZP2N.js +0 -6
- package/dist/bundle/chunks/azure-openai-responses-HS35BQV6.js +0 -2
- package/dist/bundle/chunks/chunk-2IO5GDBS.js +0 -11
- package/dist/bundle/chunks/chunk-APQ4ACY3.js +0 -2
- package/dist/bundle/chunks/chunk-EDBLK2JQ.js +0 -2
- package/dist/bundle/chunks/chunk-NUHFSC37.js +0 -25
- package/dist/bundle/chunks/google-generative-ai-NOVAJBFC.js +0 -2
- package/dist/bundle/chunks/google-vertex-4VHCZJV5.js +0 -2
- package/dist/bundle/chunks/mistral-conversations-WC6A2WCJ.js +0 -5
- package/dist/bundle/chunks/openai-codex-responses-XCDG75W2.js +0 -10
- package/dist/bundle/chunks/openai-completions-SHS3CAEL.js +0 -7
- package/dist/bundle/chunks/openai-responses-UT6XFKC7.js +0 -2
- package/dist/bundle/chunks/virtual-modules-W3OGMIX7.js +0 -2
- package/dist/core/background/history.d.ts +0 -4
- package/dist/core/background/history.d.ts.map +0 -1
- package/dist/core/background/history.js.map +0 -1
- package/dist/core/background/output.d.ts.map +0 -1
- package/dist/core/background/output.js.map +0 -1
- package/dist/core/background/presentation.d.ts +0 -9
- package/dist/core/background/presentation.d.ts.map +0 -1
- package/dist/core/background/presentation.js.map +0 -1
- package/dist/core/background/service.d.ts.map +0 -1
- package/dist/core/background/service.js.map +0 -1
- package/dist/core/background/session.d.ts +0 -63
- package/dist/core/background/session.d.ts.map +0 -1
- package/dist/core/background/session.js +0 -222
- package/dist/core/background/session.js.map +0 -1
- package/dist/core/background/types.d.ts.map +0 -1
- package/dist/core/background/types.js.map +0 -1
- package/dist/core/model-stream-options.d.ts +0 -6
- package/dist/core/model-stream-options.d.ts.map +0 -1
- package/dist/core/model-stream-options.js +0 -20
- package/dist/core/model-stream-options.js.map +0 -1
- package/dist/extensions/background/actions.d.ts +0 -11
- package/dist/extensions/background/actions.d.ts.map +0 -1
- package/dist/extensions/background/actions.js.map +0 -1
- package/dist/extensions/background/completion-render.d.ts +0 -8
- package/dist/extensions/background/completion-render.d.ts.map +0 -1
- package/dist/extensions/background/completion-render.js.map +0 -1
- package/dist/extensions/background/constants.d.ts +0 -22
- package/dist/extensions/background/constants.d.ts.map +0 -1
- package/dist/extensions/background/constants.js.map +0 -1
- package/dist/extensions/background/index.d.ts +0 -7
- package/dist/extensions/background/index.d.ts.map +0 -1
- package/dist/extensions/background/index.js +0 -109
- package/dist/extensions/background/index.js.map +0 -1
- package/dist/extensions/background/keybindings.d.ts +0 -10
- package/dist/extensions/background/keybindings.d.ts.map +0 -1
- package/dist/extensions/background/keybindings.js +0 -14
- package/dist/extensions/background/keybindings.js.map +0 -1
- package/dist/extensions/background/manager.d.ts +0 -80
- package/dist/extensions/background/manager.d.ts.map +0 -1
- package/dist/extensions/background/manager.js +0 -673
- package/dist/extensions/background/manager.js.map +0 -1
- package/dist/extensions/background/render.d.ts.map +0 -1
- package/dist/extensions/background/render.js.map +0 -1
- package/dist/extensions/background/schema.d.ts.map +0 -1
- package/dist/extensions/background/schema.js.map +0 -1
- package/dist/extensions/background/task-view.d.ts.map +0 -1
- package/dist/extensions/background/task-view.js.map +0 -1
- package/dist/extensions/background/text.d.ts.map +0 -1
- package/dist/extensions/background/text.js.map +0 -1
- package/dist/extensions/background/types.d.ts.map +0 -1
- package/dist/extensions/background/types.js.map +0 -1
- package/dist/extensions/subagent/activity.d.ts +0 -34
- package/dist/extensions/subagent/activity.d.ts.map +0 -1
- package/dist/extensions/subagent/activity.js +0 -192
- package/dist/extensions/subagent/activity.js.map +0 -1
- package/dist/extensions/subagent/agents-command.d.ts +0 -4
- package/dist/extensions/subagent/agents-command.d.ts.map +0 -1
- package/dist/extensions/subagent/agents-command.js +0 -230
- package/dist/extensions/subagent/agents-command.js.map +0 -1
- package/dist/extensions/subagent/agents.d.ts +0 -6
- package/dist/extensions/subagent/agents.d.ts.map +0 -1
- package/dist/extensions/subagent/agents.js +0 -53
- package/dist/extensions/subagent/agents.js.map +0 -1
- package/dist/extensions/subagent/budget.d.ts +0 -15
- package/dist/extensions/subagent/budget.d.ts.map +0 -1
- package/dist/extensions/subagent/budget.js +0 -123
- package/dist/extensions/subagent/budget.js.map +0 -1
- package/dist/extensions/subagent/cancellation.d.ts +0 -29
- package/dist/extensions/subagent/cancellation.d.ts.map +0 -1
- package/dist/extensions/subagent/cancellation.js +0 -91
- package/dist/extensions/subagent/cancellation.js.map +0 -1
- package/dist/extensions/subagent/constants.d.ts +0 -25
- package/dist/extensions/subagent/constants.d.ts.map +0 -1
- package/dist/extensions/subagent/constants.js +0 -50
- package/dist/extensions/subagent/constants.js.map +0 -1
- package/dist/extensions/subagent/index.d.ts +0 -3
- package/dist/extensions/subagent/index.d.ts.map +0 -1
- package/dist/extensions/subagent/index.js +0 -151
- package/dist/extensions/subagent/index.js.map +0 -1
- package/dist/extensions/subagent/model-selection.d.ts +0 -16
- package/dist/extensions/subagent/model-selection.d.ts.map +0 -1
- package/dist/extensions/subagent/model-selection.js +0 -51
- package/dist/extensions/subagent/model-selection.js.map +0 -1
- package/dist/extensions/subagent/render.d.ts +0 -24
- package/dist/extensions/subagent/render.d.ts.map +0 -1
- package/dist/extensions/subagent/render.js +0 -336
- package/dist/extensions/subagent/render.js.map +0 -1
- package/dist/extensions/subagent/resolve.d.ts +0 -31
- package/dist/extensions/subagent/resolve.d.ts.map +0 -1
- package/dist/extensions/subagent/resolve.js +0 -111
- package/dist/extensions/subagent/resolve.js.map +0 -1
- package/dist/extensions/subagent/runner.d.ts +0 -35
- package/dist/extensions/subagent/runner.d.ts.map +0 -1
- package/dist/extensions/subagent/runner.js +0 -255
- package/dist/extensions/subagent/runner.js.map +0 -1
- package/dist/extensions/subagent/schema.d.ts +0 -28
- package/dist/extensions/subagent/schema.d.ts.map +0 -1
- package/dist/extensions/subagent/schema.js +0 -58
- package/dist/extensions/subagent/schema.js.map +0 -1
- package/dist/extensions/subagent/sdk-runner.d.ts +0 -33
- package/dist/extensions/subagent/sdk-runner.d.ts.map +0 -1
- package/dist/extensions/subagent/sdk-runner.js +0 -331
- package/dist/extensions/subagent/sdk-runner.js.map +0 -1
- package/dist/extensions/subagent/settings.d.ts +0 -8
- package/dist/extensions/subagent/settings.d.ts.map +0 -1
- package/dist/extensions/subagent/settings.js +0 -206
- package/dist/extensions/subagent/settings.js.map +0 -1
- package/dist/extensions/subagent/state.d.ts +0 -102
- package/dist/extensions/subagent/state.d.ts.map +0 -1
- package/dist/extensions/subagent/state.js +0 -383
- package/dist/extensions/subagent/state.js.map +0 -1
- package/dist/extensions/subagent/text.d.ts +0 -6
- package/dist/extensions/subagent/text.d.ts.map +0 -1
- package/dist/extensions/subagent/text.js +0 -66
- package/dist/extensions/subagent/text.js.map +0 -1
- package/dist/extensions/subagent/types.d.ts +0 -91
- package/dist/extensions/subagent/types.d.ts.map +0 -1
- package/dist/extensions/subagent/types.js +0 -2
- package/dist/extensions/subagent/types.js.map +0 -1
- package/dist/extensions/subagent/ui/agents-dialog.d.ts +0 -4
- package/dist/extensions/subagent/ui/agents-dialog.d.ts.map +0 -1
- package/dist/extensions/subagent/ui/agents-dialog.js +0 -84
- package/dist/extensions/subagent/ui/agents-dialog.js.map +0 -1
- package/dist/extensions/subagent/ui/choice-menu.d.ts +0 -39
- package/dist/extensions/subagent/ui/choice-menu.d.ts.map +0 -1
- package/dist/extensions/subagent/ui/choice-menu.js +0 -93
- package/dist/extensions/subagent/ui/choice-menu.js.map +0 -1
- package/dist/extensions/subagent/ui/choices.d.ts +0 -36
- package/dist/extensions/subagent/ui/choices.d.ts.map +0 -1
- package/dist/extensions/subagent/ui/choices.js +0 -54
- package/dist/extensions/subagent/ui/choices.js.map +0 -1
- package/dist/extensions/subagent/ui/model-list.d.ts +0 -66
- package/dist/extensions/subagent/ui/model-list.d.ts.map +0 -1
- package/dist/extensions/subagent/ui/model-list.js +0 -235
- package/dist/extensions/subagent/ui/model-list.js.map +0 -1
- package/dist/extensions/subagent/ui/model-picker.d.ts +0 -47
- package/dist/extensions/subagent/ui/model-picker.d.ts.map +0 -1
- package/dist/extensions/subagent/ui/model-picker.js +0 -143
- package/dist/extensions/subagent/ui/model-picker.js.map +0 -1
- package/dist/extensions/subagent/ui/profile-settings-menu.d.ts +0 -41
- package/dist/extensions/subagent/ui/profile-settings-menu.d.ts.map +0 -1
- package/dist/extensions/subagent/ui/profile-settings-menu.js +0 -98
- package/dist/extensions/subagent/ui/profile-settings-menu.js.map +0 -1
- package/dist/modes/interactive/components/tool-chrome.d.ts +0 -28
- package/dist/modes/interactive/components/tool-chrome.d.ts.map +0 -1
- package/dist/modes/interactive/components/tool-chrome.js +0 -84
- package/dist/modes/interactive/components/tool-chrome.js.map +0 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +0 -1
- package/dist/modes/interactive/components/tool-execution.js.map +0 -1
- package/dist/modes/interactive/components/tool-group.d.ts +0 -17
- package/dist/modes/interactive/components/tool-group.d.ts.map +0 -1
- package/dist/modes/interactive/components/tool-group.js +0 -78
- package/dist/modes/interactive/components/tool-group.js.map +0 -1
- package/dist/modes/interactive/tool-chat.d.ts +0 -21
- package/dist/modes/interactive/tool-chat.d.ts.map +0 -1
- package/dist/modes/interactive/tool-chat.js +0 -58
- package/dist/modes/interactive/tool-chat.js.map +0 -1
- package/docs/bundled/extensions/background.md +0 -132
- package/docs/bundled/extensions/subagent.md +0 -148
- /package/dist/{extensions/background → core/tools/tasks}/types.js +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createTasksToolDefinition } from "./tools/tasks.js";
|
|
1
2
|
/**
|
|
2
3
|
* AgentSession - Core abstraction for agent lifecycle and session management.
|
|
3
4
|
*
|
|
@@ -14,6 +15,7 @@
|
|
|
14
15
|
*/
|
|
15
16
|
import { readFileSync } from "node:fs";
|
|
16
17
|
import { basename, dirname } from "node:path";
|
|
18
|
+
import { runToolCall, } from "@earendil-works/pi-agent-core";
|
|
17
19
|
import { contentText, getCurrentSystemMessage, getSystemMessageText, retryDelayMs } from "@earendil-works/pi-ai";
|
|
18
20
|
import { clampThinkingLevel, cleanupSessionResources, getSupportedThinkingLevels, isContextOverflow, isRecoverableLength, isRetryableAssistantError, modelsAreEqual, resetApiProviders, streamSimple, } from "@earendil-works/pi-ai/compat";
|
|
19
21
|
import { getThemeByName, theme } from "../modes/interactive/theme/theme.js";
|
|
@@ -22,27 +24,28 @@ import { processImage } from "../utils/image-process.js";
|
|
|
22
24
|
import { sleep } from "../utils/sleep.js";
|
|
23
25
|
import { normalizeToolResultImages } from "../utils/tool-result-images.js";
|
|
24
26
|
import { formatNoApiKeyFoundMessage, formatNoModelSelectedMessage } from "./auth-guidance.js";
|
|
25
|
-
import { BackgroundSession } from "./background/session.js";
|
|
26
27
|
import { executeBashWithOperations } from "./bash-executor.js";
|
|
27
28
|
import { generateBugReportSummary } from "./bug-report.js";
|
|
28
29
|
import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateProjectedContextTokens, estimateTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
|
|
29
30
|
import { DEFAULT_THINKING_LEVEL, THINKING_LEVEL_OPTIONS } from "./defaults.js";
|
|
30
31
|
import { exportSessionToHtml } from "./export-html/index.js";
|
|
31
32
|
import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
|
|
32
|
-
import { ExtensionRunner,
|
|
33
|
+
import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
|
|
33
34
|
import { emitSessionShutdownEvent } from "./extensions/runner.js";
|
|
34
35
|
import { convertToLlm } from "./messages.js";
|
|
35
36
|
import { ModelRegistry } from "./model-registry.js";
|
|
36
|
-
import {
|
|
37
|
+
import { NestedToolCallRunner } from "./nested-tool-calls.js";
|
|
37
38
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
38
39
|
import { exportSessionToJsonl } from "./session-export.js";
|
|
39
40
|
import { getLatestCompactionEntry, SessionManager, } from "./session-manager.js";
|
|
40
|
-
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
41
|
+
import { BUILTIN_PATH_PREFIX, createSyntheticSourceInfo, isSyntheticPath } from "./source-info.js";
|
|
41
42
|
import { buildSystemPrompt, buildSystemPromptSections, diffSystemPromptSections, normalizeBuildSystemPromptOptions, } from "./system-prompt.js";
|
|
43
|
+
import { TaskSession } from "./tasks/session.js";
|
|
42
44
|
import { createLocalBashOperations } from "./tools/bash.js";
|
|
43
45
|
import { createAllToolDefinitions } from "./tools/index.js";
|
|
44
46
|
import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
|
|
45
|
-
import { addUsageToTotals, createUsageTotals, getAccountedUsages } from "./usage-totals.js";
|
|
47
|
+
import { addUsageToTotals, combineUsage, createUsageTotals, getAccountedUsages } from "./usage-totals.js";
|
|
48
|
+
import { findLatestResponse, getBranchSelection, getVirtualModelState, isVirtualModel, VIRTUAL_MODEL_STATE_ENTRY, } from "./virtual-models.js";
|
|
46
49
|
/**
|
|
47
50
|
* Parse a skill block from message text.
|
|
48
51
|
* Returns null if the text doesn't contain a skill block.
|
|
@@ -58,6 +61,9 @@ export function parseSkillBlock(text) {
|
|
|
58
61
|
userMessage: match[4]?.trim() || undefined,
|
|
59
62
|
};
|
|
60
63
|
}
|
|
64
|
+
// ============================================================================
|
|
65
|
+
// Types
|
|
66
|
+
// ============================================================================
|
|
61
67
|
function withoutDeletedHeaders(headers) {
|
|
62
68
|
return headers
|
|
63
69
|
? Object.fromEntries(Object.entries(headers).filter((entry) => entry[1] !== null))
|
|
@@ -86,8 +92,6 @@ export class AgentSession {
|
|
|
86
92
|
this._pendingNextTurnMessages = [];
|
|
87
93
|
/** Context-only custom messages queued during a run, flushed once the current turn's tool results are in. */
|
|
88
94
|
this._pendingCustomMessages = [];
|
|
89
|
-
/** Background completions queued for steering, awaiting the persistence that confirms delivery. */
|
|
90
|
-
this._queuedBackgroundCompletions = new Map();
|
|
91
95
|
// Compaction state
|
|
92
96
|
this._compactionAbortController = undefined;
|
|
93
97
|
this._autoCompactionAbortController = undefined;
|
|
@@ -113,20 +117,30 @@ export class AgentSession {
|
|
|
113
117
|
this._extensionMode = "print";
|
|
114
118
|
// Tool registry for extension getTools/setTools
|
|
115
119
|
this._toolRegistry = new Map();
|
|
120
|
+
/** Declared tools whose declarations requests leave out, from `prepareLoadout` hooks. */
|
|
121
|
+
this._hiddenDeclarations = new Set();
|
|
116
122
|
this._toolDefinitions = new Map();
|
|
117
123
|
this._toolPromptSnippets = new Map();
|
|
118
124
|
this._toolPromptGuidelines = new Map();
|
|
119
125
|
/** Internal handler for agent events - shared by subscribe and reconnect */
|
|
120
126
|
this._handleAgentEvent = async (event) => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
if (event.type === "message_start")
|
|
128
|
+
this._tasksHost.delivery.messageStarted(event.message);
|
|
129
|
+
// Record the calls a tool made through ctx.executeTool() and their usage on its result message.
|
|
130
|
+
if (this._nestedToolCalls) {
|
|
131
|
+
if (event.type === "message_start" && event.message.role === "toolResult") {
|
|
132
|
+
const message = event.message;
|
|
133
|
+
const summary = this._nestedToolCalls.takeRecord(message.toolCallId);
|
|
134
|
+
if (summary?.calls)
|
|
135
|
+
message.nestedCalls = summary.calls;
|
|
136
|
+
if (summary?.usage) {
|
|
137
|
+
message.usage = message.usage ? combineUsage(message.usage, summary.usage) : summary.usage;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else if (event.type === "agent_end") {
|
|
141
|
+
this._nestedToolCalls.clear();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
130
144
|
// When a user message starts, check if it's from either queue and remove it BEFORE emitting
|
|
131
145
|
// This ensures the UI sees the updated queue state
|
|
132
146
|
if (event.type === "message_start" && event.message.role === "user") {
|
|
@@ -154,10 +168,24 @@ export class AgentSession {
|
|
|
154
168
|
this._emit(event.type === "agent_end" ? { ...event, willRetry: this._willRetryAfterAgentEnd(event) } : event);
|
|
155
169
|
// Handle session persistence
|
|
156
170
|
if (event.type === "message_end") {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
171
|
+
let entryId;
|
|
172
|
+
// Check if this is a custom message from extensions
|
|
173
|
+
if (event.message.role === "custom") {
|
|
174
|
+
// Persist as CustomMessageEntry
|
|
175
|
+
entryId = this.sessionManager.appendCustomMessageEntry(event.message.customType, event.message.content, event.message.display, event.message.details);
|
|
176
|
+
}
|
|
177
|
+
else if (event.message.role === "system" ||
|
|
178
|
+
event.message.role === "user" ||
|
|
179
|
+
event.message.role === "assistant" ||
|
|
180
|
+
event.message.role === "toolResult") {
|
|
181
|
+
// Regular LLM message - persist as SessionMessageEntry
|
|
182
|
+
entryId = this.sessionManager.appendMessage(event.message);
|
|
160
183
|
}
|
|
184
|
+
if (entryId)
|
|
185
|
+
this._entryIdsByMessage.set(event.message, entryId);
|
|
186
|
+
if (entryId)
|
|
187
|
+
this._messagePersisted(event.message);
|
|
188
|
+
// Other message types (bashExecution, compactionSummary, branchSummary) are persisted elsewhere
|
|
161
189
|
if (event.message.role === "assistant") {
|
|
162
190
|
const assistantMsg = event.message;
|
|
163
191
|
this._lastAssistantMessage = assistantMsg;
|
|
@@ -186,14 +214,14 @@ export class AgentSession {
|
|
|
186
214
|
this._flushPendingCustomMessages();
|
|
187
215
|
}
|
|
188
216
|
if (event.type === "agent_end")
|
|
189
|
-
this.
|
|
217
|
+
this._tasksHost.delivery.agentEnded();
|
|
190
218
|
};
|
|
191
219
|
this.agent = config.agent;
|
|
192
220
|
this.sessionManager = config.sessionManager;
|
|
193
221
|
this.settingsManager = config.settingsManager;
|
|
194
|
-
this.
|
|
222
|
+
this._tasksHost = new TaskSession({
|
|
195
223
|
manager: this.sessionManager,
|
|
196
|
-
|
|
224
|
+
backgroundAllowed: config.backgroundAllowed,
|
|
197
225
|
canDeliver: () => {
|
|
198
226
|
if (this.model === undefined || this.isCompacting)
|
|
199
227
|
return false;
|
|
@@ -202,7 +230,14 @@ export class AgentSession {
|
|
|
202
230
|
// turn, so it still waits for the queues to drain.
|
|
203
231
|
return this.isStreaming || (this.pendingMessageCount === 0 && !this.agent.hasQueuedMessages());
|
|
204
232
|
},
|
|
205
|
-
deliver: (message) =>
|
|
233
|
+
deliver: (message, waitForPersistence) => {
|
|
234
|
+
if (this.isStreaming) {
|
|
235
|
+
this.agent.steer(message);
|
|
236
|
+
return waitForPersistence();
|
|
237
|
+
}
|
|
238
|
+
// Completion turns skip before_agent_start, but consume nextTurn context.
|
|
239
|
+
return this._runAgentPrompt([message, ...this._pendingNextTurnMessages]);
|
|
240
|
+
},
|
|
206
241
|
onEntry: (entry) => this._emit({ type: "entry_appended", entry }),
|
|
207
242
|
onError: (event, error) => this._extensionRunner?.emitError({ extensionPath: "<background>", event, error }),
|
|
208
243
|
});
|
|
@@ -211,7 +246,7 @@ export class AgentSession {
|
|
|
211
246
|
this._customTools = config.customTools ?? [];
|
|
212
247
|
this._cwd = config.cwd;
|
|
213
248
|
this._modelRuntime = config.modelRuntime;
|
|
214
|
-
this.
|
|
249
|
+
this._contextSource = config.contextSource;
|
|
215
250
|
this._cacheWarmer = config.cacheWarmer;
|
|
216
251
|
if (this._cacheWarmer) {
|
|
217
252
|
this._cacheWarmer.onWarmed = (entry) => this._emit({ type: "entry_appended", entry });
|
|
@@ -229,6 +264,7 @@ export class AgentSession {
|
|
|
229
264
|
this._installAgentNextTurnRefresh();
|
|
230
265
|
this._installAgentRequestProjection();
|
|
231
266
|
this._installAgentBoundaryHooks();
|
|
267
|
+
this._installHiddenDeclarationsProjection();
|
|
232
268
|
this._installAgentForcedPromptProjection();
|
|
233
269
|
this._buildRuntime({
|
|
234
270
|
activeToolNames: this._initialActiveToolNames,
|
|
@@ -237,26 +273,26 @@ export class AgentSession {
|
|
|
237
273
|
if (this._initialActiveToolNames === undefined)
|
|
238
274
|
this._restoreToolsFromTranscript();
|
|
239
275
|
}
|
|
240
|
-
get
|
|
241
|
-
return this.
|
|
276
|
+
get tasks() {
|
|
277
|
+
return this._tasksHost.service;
|
|
242
278
|
}
|
|
243
|
-
get
|
|
244
|
-
return this.
|
|
279
|
+
get quarantinedTaskSettlements() {
|
|
280
|
+
return this._tasksHost.quarantinedSettlements;
|
|
245
281
|
}
|
|
246
282
|
/** Pause delivery across asynchronous lifecycle/preflight gaps. Nestable. */
|
|
247
|
-
|
|
248
|
-
return this.
|
|
283
|
+
pauseTaskNotifications() {
|
|
284
|
+
return this._tasksHost.delivery.pause();
|
|
249
285
|
}
|
|
250
286
|
/** Explicit retry after a host delivery failure; never spins on a timer by itself. */
|
|
251
|
-
|
|
252
|
-
this.
|
|
287
|
+
retryTaskNotifications() {
|
|
288
|
+
this._tasksHost.delivery.retry();
|
|
253
289
|
}
|
|
254
290
|
/**
|
|
255
291
|
* Run a lifecycle operation with delivery paused across its asynchronous gaps.
|
|
256
292
|
* Lifecycle methods are thin shells over upstream bodies so those keep upstream's shape.
|
|
257
293
|
*/
|
|
258
|
-
async
|
|
259
|
-
const resumeBackground = this.
|
|
294
|
+
async _withTasksPaused(operation) {
|
|
295
|
+
const resumeBackground = this.pauseTaskNotifications();
|
|
260
296
|
try {
|
|
261
297
|
return await operation();
|
|
262
298
|
}
|
|
@@ -272,6 +308,14 @@ export class AgentSession {
|
|
|
272
308
|
const model = this.model;
|
|
273
309
|
if (!model)
|
|
274
310
|
throw new Error("No model selected");
|
|
311
|
+
const requestOptions = {
|
|
312
|
+
sessionId: this.agent.sessionId ?? this.sessionManager.getSessionId(),
|
|
313
|
+
transport: this.agent.transport,
|
|
314
|
+
thinkingBudgets: structuredClone(this.agent.thinkingBudgets),
|
|
315
|
+
maxRetryDelayMs: this.agent.maxRetryDelayMs,
|
|
316
|
+
onPayload: this.agent.onPayload,
|
|
317
|
+
onResponse: this.agent.onResponse,
|
|
318
|
+
};
|
|
275
319
|
const snapshot = {
|
|
276
320
|
capturedAt: Date.now(),
|
|
277
321
|
sessionId: this.sessionManager.getSessionId(),
|
|
@@ -284,22 +328,15 @@ export class AgentSession {
|
|
|
284
328
|
parameters: structuredClone(parameters),
|
|
285
329
|
...(constrainedSampling === undefined ? {} : { constrainedSampling: structuredClone(constrainedSampling) }),
|
|
286
330
|
})),
|
|
287
|
-
streamOptions:
|
|
288
|
-
sessionId: this.agent.sessionId ?? this.sessionManager.getSessionId(),
|
|
289
|
-
transport: this.agent.transport,
|
|
290
|
-
thinkingBudgets: structuredClone(this.agent.thinkingBudgets),
|
|
291
|
-
maxRetryDelayMs: this.agent.maxRetryDelayMs,
|
|
292
|
-
onPayload: this.agent.onPayload,
|
|
293
|
-
onResponse: this.agent.onResponse,
|
|
294
|
-
}),
|
|
331
|
+
streamOptions: this._contextSource?.resolveStreamOptions(model, requestOptions) ?? requestOptions,
|
|
295
332
|
};
|
|
296
333
|
const currentSystemPrompt = this.systemPrompt;
|
|
297
334
|
// The canonical projection is what the next request converts; the inspection cache may lag it.
|
|
298
335
|
const messages = structuredClone(this.sessionManager.buildSessionProjection().messages);
|
|
299
336
|
const convert = this.agent.convertToLlm;
|
|
300
337
|
const transform = this.agent.transformContext;
|
|
301
|
-
const prepared = this.
|
|
302
|
-
? await this.
|
|
338
|
+
const prepared = this._contextSource
|
|
339
|
+
? await this._contextSource.prepareMessages(messages)
|
|
303
340
|
: await convert(transform ? await transform(messages) : messages);
|
|
304
341
|
// The prepared transcript declares the prompt the provider received, including a forced
|
|
305
342
|
// prompt projected for the last request; before the first request there is none yet.
|
|
@@ -339,28 +376,71 @@ export class AgentSession {
|
|
|
339
376
|
}
|
|
340
377
|
throw new Error(formatNoApiKeyFoundMessage(model.provider));
|
|
341
378
|
}
|
|
342
|
-
async _getSummarizationRequestAuth(
|
|
379
|
+
async _getSummarizationRequestAuth(selectedModel, signal) {
|
|
380
|
+
// Route a virtual model first: summaries size their input and output from the model they get.
|
|
381
|
+
const { model, thinkingLevel } = isVirtualModel(selectedModel)
|
|
382
|
+
? await this._modelRuntime.resolveModel(selectedModel, convertToLlm(this.messages), {
|
|
383
|
+
reason: "direct",
|
|
384
|
+
thinkingLevel: this.thinkingLevel,
|
|
385
|
+
signal,
|
|
386
|
+
})
|
|
387
|
+
: { model: selectedModel, thinkingLevel: this.thinkingLevel };
|
|
343
388
|
if (this.agent.streamFunction === streamSimple) {
|
|
344
|
-
return this._getRequiredRequestAuth(model, signal);
|
|
389
|
+
return { ...(await this._getRequiredRequestAuth(model, signal)), thinkingLevel };
|
|
345
390
|
}
|
|
346
391
|
try {
|
|
347
392
|
const result = await this._modelRuntime.getAuth(model, { signal });
|
|
348
393
|
if (!result)
|
|
349
|
-
return { model };
|
|
394
|
+
return { model, thinkingLevel };
|
|
350
395
|
const requestModel = result.auth.baseUrl ? { ...model, baseUrl: result.auth.baseUrl } : model;
|
|
351
396
|
return {
|
|
352
397
|
model: requestModel,
|
|
353
398
|
apiKey: result.auth.apiKey,
|
|
354
399
|
headers: withoutDeletedHeaders(result.auth.headers),
|
|
355
400
|
env: result.env,
|
|
401
|
+
thinkingLevel,
|
|
356
402
|
};
|
|
357
403
|
}
|
|
358
404
|
catch (error) {
|
|
359
405
|
if (signal?.aborted)
|
|
360
406
|
throw error;
|
|
361
|
-
return { model };
|
|
407
|
+
return { model, thinkingLevel };
|
|
362
408
|
}
|
|
363
409
|
}
|
|
410
|
+
/**
|
|
411
|
+
* The model whose limits apply to `message`, or undefined when the message came from another
|
|
412
|
+
* model. Under a virtual selection, that is the physical model that produced it.
|
|
413
|
+
*/
|
|
414
|
+
_modelForMessage(message) {
|
|
415
|
+
const model = this.model;
|
|
416
|
+
if (model && isVirtualModel(model))
|
|
417
|
+
return this._modelRuntime.getPhysicalModel(message.provider, message.model);
|
|
418
|
+
return model?.provider === message.provider && model.id === message.model ? model : undefined;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Record the selection on the current branch when the branch implies another one, so a resume
|
|
422
|
+
* restores it. Tree navigation can leave the latest `model_change` on another branch; responses
|
|
423
|
+
* cannot record a virtual selection because they name physical models. Responses do record a
|
|
424
|
+
* physical selection unless the branch holds a virtual one; checking a physical selection against
|
|
425
|
+
* responses would record it on every prompt while `prepareRequest` redirects to another model.
|
|
426
|
+
*/
|
|
427
|
+
_recordSelection() {
|
|
428
|
+
const model = this.model;
|
|
429
|
+
if (!model)
|
|
430
|
+
return;
|
|
431
|
+
const getModel = (provider, modelId) => this._modelRuntime.getModel(provider, modelId);
|
|
432
|
+
const recorded = getBranchSelection(this.sessionManager.getBranch(), getModel);
|
|
433
|
+
if (!recorded || (recorded.provider === model.provider && recorded.modelId === model.id))
|
|
434
|
+
return;
|
|
435
|
+
const recordedModel = getModel(recorded.provider, recorded.modelId);
|
|
436
|
+
if (!isVirtualModel(model) && !(recordedModel && isVirtualModel(recordedModel)))
|
|
437
|
+
return;
|
|
438
|
+
this.sessionManager.appendModelChange(model.provider, model.id);
|
|
439
|
+
}
|
|
440
|
+
/** The model whose limits apply to the conversation. */
|
|
441
|
+
_limitsModel() {
|
|
442
|
+
return this.routedModel?.model ?? this.model;
|
|
443
|
+
}
|
|
364
444
|
/**
|
|
365
445
|
* Install tool hooks once on the Agent instance.
|
|
366
446
|
*
|
|
@@ -370,65 +450,112 @@ export class AgentSession {
|
|
|
370
450
|
* happens here instead of in wrappers.
|
|
371
451
|
*/
|
|
372
452
|
_installAgentToolHooks() {
|
|
373
|
-
this.agent.beforeToolCall =
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
}
|
|
390
|
-
throw new Error(`Extension failed, blocking execution: ${String(err)}`);
|
|
391
|
-
}
|
|
392
|
-
};
|
|
393
|
-
this.agent.afterToolCall = async ({ toolCall, args, result, isError }) => {
|
|
394
|
-
const runner = this._extensionRunner;
|
|
395
|
-
const hookResult = runner.hasHandlers("tool_result")
|
|
396
|
-
? await runner.emitToolResult({
|
|
397
|
-
type: "tool_result",
|
|
398
|
-
toolName: toolCall.name,
|
|
399
|
-
toolCallId: toolCall.id,
|
|
400
|
-
input: args,
|
|
401
|
-
content: result.content,
|
|
402
|
-
details: result.details,
|
|
403
|
-
isError,
|
|
404
|
-
usage: result.usage,
|
|
405
|
-
})
|
|
406
|
-
: undefined;
|
|
407
|
-
const content = hookResult?.content ?? result.content ?? [];
|
|
408
|
-
// Runs after the extension hook so images injected or replaced by extensions are normalized too.
|
|
409
|
-
const resizeOptions = this.model?.inputLimits?.images?.resize;
|
|
410
|
-
const normalizedContent = await normalizeToolResultImages(content, {
|
|
411
|
-
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
412
|
-
...(resizeOptions ? { resizeOptions } : {}),
|
|
453
|
+
this.agent.beforeToolCall = (context) => this._beforeToolCall(context);
|
|
454
|
+
this.agent.afterToolCall = (context) => this._afterToolCall(context);
|
|
455
|
+
}
|
|
456
|
+
/** `tool_call` handlers. `parentToolCallId` is set for calls another tool made. */
|
|
457
|
+
async _beforeToolCall({ toolCall, args }, parentToolCallId) {
|
|
458
|
+
const runner = this._extensionRunner;
|
|
459
|
+
if (!runner.hasHandlers("tool_call")) {
|
|
460
|
+
return undefined;
|
|
461
|
+
}
|
|
462
|
+
try {
|
|
463
|
+
return await runner.emitToolCall({
|
|
464
|
+
type: "tool_call",
|
|
465
|
+
toolName: toolCall.name,
|
|
466
|
+
toolCallId: toolCall.id,
|
|
467
|
+
...(parentToolCallId ? { parentToolCallId } : {}),
|
|
468
|
+
input: args,
|
|
413
469
|
});
|
|
414
|
-
|
|
415
|
-
|
|
470
|
+
}
|
|
471
|
+
catch (err) {
|
|
472
|
+
if (err instanceof Error) {
|
|
473
|
+
throw err;
|
|
416
474
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
475
|
+
throw new Error(`Extension failed, blocking execution: ${String(err)}`);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
/** `tool_result` handlers and image normalization. `parentToolCallId` is set for calls another tool made. */
|
|
479
|
+
async _afterToolCall({ toolCall, args, result, isError }, parentToolCallId) {
|
|
480
|
+
const runner = this._extensionRunner;
|
|
481
|
+
const hookResult = runner.hasHandlers("tool_result")
|
|
482
|
+
? await runner.emitToolResult({
|
|
483
|
+
type: "tool_result",
|
|
484
|
+
toolName: toolCall.name,
|
|
485
|
+
toolCallId: toolCall.id,
|
|
486
|
+
...(parentToolCallId ? { parentToolCallId } : {}),
|
|
487
|
+
input: args,
|
|
488
|
+
content: result.content,
|
|
489
|
+
details: result.details,
|
|
490
|
+
...(result.structuredContent === undefined ? {} : { structuredContent: result.structuredContent }),
|
|
491
|
+
isError,
|
|
492
|
+
usage: result.usage,
|
|
493
|
+
})
|
|
494
|
+
: undefined;
|
|
495
|
+
const content = hookResult?.content ?? result.content ?? [];
|
|
496
|
+
// Runs after the extension hook so images injected or replaced by extensions are normalized too.
|
|
497
|
+
const resizeOptions = this._limitsModel()?.inputLimits?.images?.resize;
|
|
498
|
+
const normalizedContent = await normalizeToolResultImages(content, {
|
|
499
|
+
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
500
|
+
...(resizeOptions ? { resizeOptions } : {}),
|
|
501
|
+
});
|
|
502
|
+
if (!hookResult && normalizedContent === content) {
|
|
503
|
+
return undefined;
|
|
504
|
+
}
|
|
505
|
+
// The hook result already dropped structured content that replaced content no longer matches.
|
|
506
|
+
return {
|
|
507
|
+
content: normalizedContent,
|
|
508
|
+
details: hookResult?.details,
|
|
509
|
+
structuredContent: hookResult ? hookResult.structuredContent : result.structuredContent,
|
|
510
|
+
isError: hookResult?.isError ?? isError,
|
|
511
|
+
usage: hookResult?.usage,
|
|
423
512
|
};
|
|
424
513
|
}
|
|
514
|
+
/**
|
|
515
|
+
* Run a call that the tool call `parentToolCallId` made through `ctx.executeTool()`. It goes
|
|
516
|
+
* through the agent's tool pipeline with the session's hooks, against the callable tools.
|
|
517
|
+
*/
|
|
518
|
+
async _executeNestedToolCall(parentToolCallId, name, args, options) {
|
|
519
|
+
this._nestedToolCalls ??= new NestedToolCallRunner({
|
|
520
|
+
getTools: () => this._getCallableTools(),
|
|
521
|
+
isSequential: () => this.agent.toolExecution === "sequential",
|
|
522
|
+
runToolCall: (toolCall, parentId, signal, onUpdate) => {
|
|
523
|
+
const assistantMessage = this._findLastAssistantMessage();
|
|
524
|
+
if (!assistantMessage) {
|
|
525
|
+
return Promise.resolve({
|
|
526
|
+
toolCall,
|
|
527
|
+
result: { content: [{ type: "text", text: "No assistant message issued this call" }], details: {} },
|
|
528
|
+
isError: true,
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
return runToolCall(toolCall, {
|
|
532
|
+
tools: this._getCallableTools(),
|
|
533
|
+
assistantMessage,
|
|
534
|
+
context: { messages: this.agent.state.messages, tools: this.agent.state.tools },
|
|
535
|
+
beforeToolCall: (context) => this._beforeToolCall(context, parentId),
|
|
536
|
+
afterToolCall: (context) => this._afterToolCall(context, parentId),
|
|
537
|
+
signal,
|
|
538
|
+
onUpdate,
|
|
539
|
+
});
|
|
540
|
+
},
|
|
541
|
+
emit: async (event) => {
|
|
542
|
+
await this._extensionRunner.emit(event);
|
|
543
|
+
this._emit(event);
|
|
544
|
+
},
|
|
545
|
+
});
|
|
546
|
+
return this._nestedToolCalls.execute(parentToolCallId, name, args, options);
|
|
547
|
+
}
|
|
548
|
+
/** Whether `projection`, the current session projection, exceeds the compaction threshold of `model`. */
|
|
549
|
+
_exceedsCompactionThreshold(model, projection) {
|
|
550
|
+
if (model.contextWindow <= 0)
|
|
551
|
+
return false;
|
|
552
|
+
return shouldCompact(estimateProjectedContextTokens(projection, this.sessionManager.getBranch()).tokens, model.contextWindow, this.settingsManager.getCompactionSettings(model));
|
|
553
|
+
}
|
|
425
554
|
async _compactBeforeNextAssistantResponse(context) {
|
|
426
|
-
const model = this.model;
|
|
427
|
-
const settings = this.settingsManager.getCompactionSettings(model);
|
|
428
555
|
const projection = this.sessionManager.buildSessionProjection();
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
556
|
+
// A virtual selection is checked in prepareRequest, against the model the request is routed to.
|
|
557
|
+
const model = this.model;
|
|
558
|
+
if (!model || isVirtualModel(model) || !this._exceedsCompactionThreshold(model, projection)) {
|
|
432
559
|
return { ...context, messages: projection.messages };
|
|
433
560
|
}
|
|
434
561
|
await this._runAutoCompaction("threshold", false);
|
|
@@ -437,24 +564,55 @@ export class AgentSession {
|
|
|
437
564
|
_installAgentRequestProjection() {
|
|
438
565
|
const previousPrepareRequest = this.agent.prepareRequest;
|
|
439
566
|
this.agent.prepareRequest = async (request, signal) => {
|
|
440
|
-
const
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
567
|
+
const failed = this._failedResponse;
|
|
568
|
+
this._failedResponse = undefined;
|
|
569
|
+
const prepare = async () => {
|
|
570
|
+
const projection = this.sessionManager.buildSessionProjection();
|
|
571
|
+
const canonicalContext = {
|
|
572
|
+
...request.context,
|
|
573
|
+
messages: projection.messages,
|
|
574
|
+
// Messages declare the provider-visible loadout; context.tools keeps executable implementations.
|
|
575
|
+
tools: this.agent.state.tools.slice(),
|
|
576
|
+
};
|
|
577
|
+
const previous = await previousPrepareRequest?.({
|
|
578
|
+
...request,
|
|
579
|
+
context: canonicalContext,
|
|
580
|
+
model: this.agent.state.model,
|
|
581
|
+
thinkingLevel: this.agent.state.thinkingLevel,
|
|
582
|
+
}, signal);
|
|
583
|
+
return { previous, context: previous?.context ?? canonicalContext, projection };
|
|
457
584
|
};
|
|
585
|
+
let { previous, context, projection } = await prepare();
|
|
586
|
+
const model = previous?.model ?? this.agent.state.model;
|
|
587
|
+
const thinkingLevel = previous?.thinkingLevel ?? this.agent.state.thinkingLevel;
|
|
588
|
+
if (!isVirtualModel(model))
|
|
589
|
+
return { ...previous, context, model, thinkingLevel };
|
|
590
|
+
// The selection stays in agent state; only this request uses the routed model. A routing
|
|
591
|
+
// failure rejects, which ends the run with an error response. Only messages the user wrote
|
|
592
|
+
// start a turn; extension messages can follow them, e.g. from before_agent_start.
|
|
593
|
+
const lastResponse = context.messages.findLastIndex((message) => message.role === "assistant");
|
|
594
|
+
const userTurn = context.messages.slice(lastResponse + 1).some((message) => message.role === "user");
|
|
595
|
+
const state = getVirtualModelState(this.sessionManager.getBranch(), model.provider, model.id);
|
|
596
|
+
const route = await this._modelRuntime.resolveModel(model, convertToLlm(context.messages), {
|
|
597
|
+
reason: failed ? "retry" : userTurn ? "user" : "continuation",
|
|
598
|
+
thinkingLevel,
|
|
599
|
+
signal,
|
|
600
|
+
failed,
|
|
601
|
+
state,
|
|
602
|
+
});
|
|
603
|
+
if (route.state !== undefined && route.state !== state) {
|
|
604
|
+
const data = { provider: model.provider, modelId: model.id, state: route.state };
|
|
605
|
+
const entry = this.sessionManager.getEntry(this.sessionManager.appendCustomEntry(VIRTUAL_MODEL_STATE_ENTRY, data));
|
|
606
|
+
if (entry)
|
|
607
|
+
this._emit({ type: "entry_appended", entry });
|
|
608
|
+
}
|
|
609
|
+
// The route stands: the router already decided this request. The state entry does not change
|
|
610
|
+
// the projection.
|
|
611
|
+
if (this._exceedsCompactionThreshold(route.model, projection)) {
|
|
612
|
+
await this._runAutoCompaction("threshold", false);
|
|
613
|
+
({ previous, context } = await prepare());
|
|
614
|
+
}
|
|
615
|
+
return { ...previous, context, model: route.model, thinkingLevel: route.thinkingLevel };
|
|
458
616
|
};
|
|
459
617
|
}
|
|
460
618
|
async _dispatchTurnEndBoundary(message, toolResults) {
|
|
@@ -510,10 +668,7 @@ export class AgentSession {
|
|
|
510
668
|
? async (_turn, signal) => await this.agent.prepareNextTurn?.(signal)
|
|
511
669
|
: undefined);
|
|
512
670
|
this.agent.prepareNextTurnWithContext = async (turn, signal) => {
|
|
513
|
-
const context = await this._compactBeforeNextAssistantResponse(
|
|
514
|
-
...turn.context,
|
|
515
|
-
messages: this.sessionManager.buildSessionProjection().messages,
|
|
516
|
-
});
|
|
671
|
+
const context = await this._compactBeforeNextAssistantResponse(turn.context);
|
|
517
672
|
const previousSnapshot = await previousPrepareNextTurnWithContext?.({ ...turn, context }, signal);
|
|
518
673
|
const nextContext = previousSnapshot?.context ?? context;
|
|
519
674
|
const runOptions = this._runSystemPromptOptions ?? this._baseSystemPromptOptions;
|
|
@@ -661,7 +816,7 @@ export class AgentSession {
|
|
|
661
816
|
* so a deferred prompt never races a delivery for the same idle gap.
|
|
662
817
|
*/
|
|
663
818
|
async _emitAgentSettled() {
|
|
664
|
-
return this.
|
|
819
|
+
return this._withTasksPaused(() => this._emitAgentSettledBody());
|
|
665
820
|
}
|
|
666
821
|
async _emitAgentSettledBody() {
|
|
667
822
|
this._cacheWarmer?.onAgentSettled();
|
|
@@ -688,31 +843,16 @@ export class AgentSession {
|
|
|
688
843
|
this._resolveIdleWaitIfIdle();
|
|
689
844
|
}
|
|
690
845
|
/**
|
|
691
|
-
*
|
|
692
|
-
*
|
|
846
|
+
* Called after a message's session entry is appended. Queued `nextTurn` context is consumed
|
|
847
|
+
* only here, so a failed append leaves it queued, and Background delivery is acknowledged.
|
|
693
848
|
*/
|
|
694
|
-
|
|
695
|
-
let entryId;
|
|
849
|
+
_messagePersisted(message) {
|
|
696
850
|
if (message.role === "custom") {
|
|
697
|
-
entryId = this.sessionManager.appendCustomMessageEntry(message.customType, message.content, message.display, message.details);
|
|
698
851
|
const pendingIndex = this._pendingNextTurnMessages.indexOf(message);
|
|
699
852
|
if (pendingIndex !== -1)
|
|
700
853
|
this._pendingNextTurnMessages.splice(pendingIndex, 1);
|
|
701
854
|
}
|
|
702
|
-
|
|
703
|
-
message.role === "user" ||
|
|
704
|
-
message.role === "assistant" ||
|
|
705
|
-
message.role === "toolResult") {
|
|
706
|
-
entryId = this.sessionManager.appendMessage(message);
|
|
707
|
-
}
|
|
708
|
-
else {
|
|
709
|
-
// Bash execution, compaction and branch summaries are persisted by their owners.
|
|
710
|
-
return undefined;
|
|
711
|
-
}
|
|
712
|
-
this._entryIdsByMessage.set(message, entryId);
|
|
713
|
-
if (message.role === "toolResult")
|
|
714
|
-
this._backgroundHost.acknowledgeWaitResult(message.details);
|
|
715
|
-
return entryId;
|
|
855
|
+
this._tasksHost.delivery.messagePersisted(message);
|
|
716
856
|
}
|
|
717
857
|
_willRetryAfterAgentEnd(event) {
|
|
718
858
|
if (this._agentRunAbortRequested)
|
|
@@ -909,10 +1049,7 @@ export class AgentSession {
|
|
|
909
1049
|
* Call this when completely done with the session.
|
|
910
1050
|
*/
|
|
911
1051
|
dispose() {
|
|
912
|
-
this.
|
|
913
|
-
for (const queued of [...this._queuedBackgroundCompletions.values()]) {
|
|
914
|
-
queued.reject(new Error("the session was disposed"));
|
|
915
|
-
}
|
|
1052
|
+
this._tasksHost.dispose();
|
|
916
1053
|
try {
|
|
917
1054
|
this.abortRetry();
|
|
918
1055
|
this.abortCompaction();
|
|
@@ -923,7 +1060,7 @@ export class AgentSession {
|
|
|
923
1060
|
catch {
|
|
924
1061
|
// Dispose must succeed even if an abort hook throws.
|
|
925
1062
|
}
|
|
926
|
-
this._extensionRunner.invalidate(
|
|
1063
|
+
this._extensionRunner.invalidate("This extension ctx is stale after session replacement or reload. Do not use a captured pi or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(), or ctx.reload(). For newSession, fork, and switchSession, move post-replacement work into withSession and use the ctx passed to withSession. For reload, do not use the old ctx after await ctx.reload().");
|
|
927
1064
|
this._disconnectFromAgent();
|
|
928
1065
|
this._eventListeners = [];
|
|
929
1066
|
if (this._cacheWarmer) {
|
|
@@ -960,6 +1097,14 @@ export class AgentSession {
|
|
|
960
1097
|
get thinkingLevel() {
|
|
961
1098
|
return this.agent.state.thinkingLevel;
|
|
962
1099
|
}
|
|
1100
|
+
/** Under a virtual selection, the physical model and thinking level of the latest successful response. */
|
|
1101
|
+
get routedModel() {
|
|
1102
|
+
if (!this.model || !isVirtualModel(this.model))
|
|
1103
|
+
return undefined;
|
|
1104
|
+
const latest = findLatestResponse(this.agent.state.messages);
|
|
1105
|
+
const model = latest && this._modelRuntime.getPhysicalModel(latest.provider, latest.model);
|
|
1106
|
+
return model && { model, thinkingLevel: latest?.thinkingLevel };
|
|
1107
|
+
}
|
|
963
1108
|
/** Whether the session is currently processing an agent run or post-run continuation. */
|
|
964
1109
|
get isStreaming() {
|
|
965
1110
|
return this._isAgentRunActive;
|
|
@@ -977,12 +1122,16 @@ export class AgentSession {
|
|
|
977
1122
|
return this._retryAttempt;
|
|
978
1123
|
}
|
|
979
1124
|
/**
|
|
980
|
-
* Get the names of currently active tools.
|
|
981
|
-
*
|
|
1125
|
+
* Get the names of currently active tools, which are the tools declared to the model.
|
|
1126
|
+
* Tools with `codemode` or `deferred` exposure are callable from other tools without being active.
|
|
982
1127
|
*/
|
|
983
1128
|
getActiveToolNames() {
|
|
984
1129
|
return this.agent.state.tools.map((t) => t.name);
|
|
985
1130
|
}
|
|
1131
|
+
/** Get the names of the tools that tools can call through `ctx.executeTool()`. */
|
|
1132
|
+
getCallableToolNames() {
|
|
1133
|
+
return this._getCallableTools().map((t) => t.name);
|
|
1134
|
+
}
|
|
986
1135
|
/**
|
|
987
1136
|
* Get all configured tools with name, description, parameter schema, prompt guidelines, and source metadata.
|
|
988
1137
|
*/
|
|
@@ -992,6 +1141,9 @@ export class AgentSession {
|
|
|
992
1141
|
description: definition.description,
|
|
993
1142
|
parameters: definition.parameters,
|
|
994
1143
|
promptGuidelines: definition.promptGuidelines,
|
|
1144
|
+
exposure: this._getToolExposure(definition.name),
|
|
1145
|
+
...(definition.namespace ? { namespace: definition.namespace } : {}),
|
|
1146
|
+
...(definition.annotations ? { annotations: { ...definition.annotations } } : {}),
|
|
995
1147
|
sourceInfo,
|
|
996
1148
|
}));
|
|
997
1149
|
}
|
|
@@ -1000,22 +1152,79 @@ export class AgentSession {
|
|
|
1000
1152
|
}
|
|
1001
1153
|
/**
|
|
1002
1154
|
* Set active tools by name.
|
|
1003
|
-
* Only tools in the registry can be enabled. Unknown tool names are ignored.
|
|
1155
|
+
* Only tools in the registry can be enabled. Unknown and hidden tool names are ignored.
|
|
1004
1156
|
* Also rebuilds the system prompt to reflect the new tool set.
|
|
1005
1157
|
* Changes take effect on the next agent turn.
|
|
1006
1158
|
*/
|
|
1007
1159
|
setActiveToolsByName(toolNames) {
|
|
1008
|
-
const tools =
|
|
1009
|
-
|
|
1010
|
-
|
|
1160
|
+
const tools = this._applyToolLoadout(toolNames);
|
|
1161
|
+
this._rebuildSystemPrompt(tools.map((tool) => tool.name));
|
|
1162
|
+
}
|
|
1163
|
+
_getToolExposure(name) {
|
|
1164
|
+
return this._toolDefinitions.get(name)?.definition.exposure ?? "direct";
|
|
1165
|
+
}
|
|
1166
|
+
/**
|
|
1167
|
+
* Tools callable through `ctx.executeTool()`: the active `direct` tools and every registered
|
|
1168
|
+
* `codemode` or `deferred` tool.
|
|
1169
|
+
*/
|
|
1170
|
+
_getCallableTools(active = new Set(this.getActiveToolNames())) {
|
|
1171
|
+
return [...this._toolRegistry.values()].filter((tool) => {
|
|
1172
|
+
const exposure = this._getToolExposure(tool.name);
|
|
1173
|
+
return exposure === "codemode" || exposure === "deferred" || (exposure === "direct" && active.has(tool.name));
|
|
1174
|
+
});
|
|
1175
|
+
}
|
|
1176
|
+
/**
|
|
1177
|
+
* Set the agent's tools for the given active tool names and return them. The active tools are
|
|
1178
|
+
* the registered, non-hidden ones; they are declared to the model. Active tools with a
|
|
1179
|
+
* `prepareLoadout` hook can change the declared descriptions and hide declarations from
|
|
1180
|
+
* requests (see {@link _installHiddenDeclarationsProjection}).
|
|
1181
|
+
*/
|
|
1182
|
+
_applyToolLoadout(toolNames) {
|
|
1183
|
+
const tools = [...new Set(toolNames)].flatMap((name) => {
|
|
1011
1184
|
const tool = this._toolRegistry.get(name);
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1185
|
+
return tool && this._getToolExposure(name) !== "hidden" ? [tool] : [];
|
|
1186
|
+
});
|
|
1187
|
+
const hooks = tools.flatMap((tool) => {
|
|
1188
|
+
const entry = this._toolDefinitions.get(tool.name);
|
|
1189
|
+
return entry?.definition.prepareLoadout ? [entry] : [];
|
|
1190
|
+
});
|
|
1191
|
+
const hidden = new Set();
|
|
1192
|
+
let declared = tools;
|
|
1193
|
+
if (hooks.length > 0) {
|
|
1194
|
+
const loadout = {
|
|
1195
|
+
declared: tools,
|
|
1196
|
+
callable: this._getCallableTools(new Set(tools.map((tool) => tool.name))),
|
|
1197
|
+
registered: [...this._toolRegistry.values()],
|
|
1198
|
+
getExposure: (name) => this._getToolExposure(name),
|
|
1199
|
+
getNamespace: (name) => this._toolDefinitions.get(name)?.definition.namespace,
|
|
1200
|
+
};
|
|
1201
|
+
const descriptions = new Map();
|
|
1202
|
+
for (const { definition, sourceInfo } of hooks) {
|
|
1203
|
+
try {
|
|
1204
|
+
const changes = definition.prepareLoadout?.(loadout);
|
|
1205
|
+
for (const [name, description] of Object.entries(changes?.descriptions ?? {})) {
|
|
1206
|
+
descriptions.set(name, description);
|
|
1207
|
+
}
|
|
1208
|
+
for (const name of changes?.hiddenDeclarations ?? [])
|
|
1209
|
+
hidden.add(name);
|
|
1210
|
+
}
|
|
1211
|
+
catch (error) {
|
|
1212
|
+
this._extensionRunner.emitError({
|
|
1213
|
+
extensionPath: sourceInfo.path,
|
|
1214
|
+
event: "prepare_loadout",
|
|
1215
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1216
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
1217
|
+
});
|
|
1218
|
+
}
|
|
1015
1219
|
}
|
|
1220
|
+
declared = tools.map((tool) => {
|
|
1221
|
+
const description = descriptions.get(tool.name);
|
|
1222
|
+
return description === undefined ? tool : { ...tool, description };
|
|
1223
|
+
});
|
|
1016
1224
|
}
|
|
1017
|
-
this.
|
|
1018
|
-
this.
|
|
1225
|
+
this._hiddenDeclarations = hidden;
|
|
1226
|
+
this.agent.state.tools = declared;
|
|
1227
|
+
return declared;
|
|
1019
1228
|
}
|
|
1020
1229
|
/** Whether compaction or branch summarization is currently running */
|
|
1021
1230
|
get isCompacting() {
|
|
@@ -1116,11 +1325,7 @@ export class AgentSession {
|
|
|
1116
1325
|
* {@link _installAgentForcedPromptProjection}.
|
|
1117
1326
|
*/
|
|
1118
1327
|
_preparePromptAndToolLoadout(options, messages = this.agent.state.messages) {
|
|
1119
|
-
options.selectedTools =
|
|
1120
|
-
this.agent.state.tools = options.selectedTools.flatMap((name) => {
|
|
1121
|
-
const tool = this._toolRegistry.get(name);
|
|
1122
|
-
return tool ? [tool] : [];
|
|
1123
|
-
});
|
|
1328
|
+
options.selectedTools = this._applyToolLoadout(options.selectedTools).map((tool) => tool.name);
|
|
1124
1329
|
const sections = diffSystemPromptSections(getCurrentSystemMessage(messages)?.sections ?? {}, buildSystemPromptSections(options));
|
|
1125
1330
|
return sections ? { role: "system", content: "", sections, timestamp: Date.now() } : undefined;
|
|
1126
1331
|
}
|
|
@@ -1134,6 +1339,32 @@ export class AgentSession {
|
|
|
1134
1339
|
* collapse into one head holding the forced text and the current tools. Runs after the
|
|
1135
1340
|
* `context` extension handlers.
|
|
1136
1341
|
*/
|
|
1342
|
+
/**
|
|
1343
|
+
* Remove the declarations that `prepareLoadout` hooks hide from every request. The whole
|
|
1344
|
+
* transcript is filtered with the current set, so the projected declarations stay consistent
|
|
1345
|
+
* across requests and only change when the loadout does.
|
|
1346
|
+
*/
|
|
1347
|
+
_installHiddenDeclarationsProjection() {
|
|
1348
|
+
const previousTransformContext = this.agent.transformContext;
|
|
1349
|
+
this.agent.transformContext = async (messages, signal) => {
|
|
1350
|
+
const transformed = previousTransformContext ? await previousTransformContext(messages, signal) : messages;
|
|
1351
|
+
const hidden = this._hiddenDeclarations;
|
|
1352
|
+
if (hidden.size === 0)
|
|
1353
|
+
return transformed;
|
|
1354
|
+
return transformed.map((message) => {
|
|
1355
|
+
if (message.role !== "system" || (!message.toolsAdded && !message.toolsRemoved))
|
|
1356
|
+
return message;
|
|
1357
|
+
const { toolsAdded, toolsRemoved, ...rest } = message;
|
|
1358
|
+
const added = toolsAdded?.filter((tool) => !hidden.has(tool.name)) ?? [];
|
|
1359
|
+
const removed = toolsRemoved?.filter((tool) => !hidden.has(tool.name)) ?? [];
|
|
1360
|
+
return {
|
|
1361
|
+
...rest,
|
|
1362
|
+
...(added.length > 0 ? { toolsAdded: added } : {}),
|
|
1363
|
+
...(removed.length > 0 ? { toolsRemoved: removed } : {}),
|
|
1364
|
+
};
|
|
1365
|
+
});
|
|
1366
|
+
};
|
|
1367
|
+
}
|
|
1137
1368
|
_installAgentForcedPromptProjection() {
|
|
1138
1369
|
const previousTransformContext = this.agent.transformContext;
|
|
1139
1370
|
this.agent.transformContext = async (messages, signal) => {
|
|
@@ -1151,25 +1382,25 @@ export class AgentSession {
|
|
|
1151
1382
|
return [head, ...transformed.filter((message) => message.role !== "system")];
|
|
1152
1383
|
};
|
|
1153
1384
|
}
|
|
1154
|
-
/**
|
|
1385
|
+
/**
|
|
1386
|
+
* Restore the active tool loadout declared by the session transcript, if it declares one.
|
|
1387
|
+
* Tools reachable only from other tools are never declared, but they do not depend on the active
|
|
1388
|
+
* set, so the transcript's declarations are the whole loadout.
|
|
1389
|
+
*/
|
|
1155
1390
|
_restoreToolsFromTranscript() {
|
|
1156
1391
|
const current = getCurrentSystemMessage(this.sessionManager.buildSessionContext().messages);
|
|
1157
1392
|
if (!current)
|
|
1158
1393
|
return;
|
|
1159
|
-
|
|
1160
|
-
.map((tool) => tool.name)
|
|
1161
|
-
.filter((name) => this._toolRegistry.has(name));
|
|
1162
|
-
this.agent.state.tools = toolNames.flatMap((name) => {
|
|
1163
|
-
const registered = this._toolRegistry.get(name);
|
|
1164
|
-
return registered ? [registered] : [];
|
|
1165
|
-
});
|
|
1166
|
-
this._rebuildSystemPrompt(toolNames);
|
|
1394
|
+
this.setActiveToolsByName((current.toolsAdded ?? []).map((tool) => tool.name));
|
|
1167
1395
|
}
|
|
1168
1396
|
// =========================================================================
|
|
1169
1397
|
// Prompting
|
|
1170
1398
|
// =========================================================================
|
|
1171
1399
|
async _runAgentPrompt(messages) {
|
|
1172
1400
|
this._agentRunAbortRequested = false;
|
|
1401
|
+
// Compaction before the prompt may have scheduled a retry; the new prompt replaces it.
|
|
1402
|
+
this._failedResponse = undefined;
|
|
1403
|
+
this._recordSelection();
|
|
1173
1404
|
this._isAgentRunActive = true;
|
|
1174
1405
|
try {
|
|
1175
1406
|
await this.agent.prompt(messages);
|
|
@@ -1190,61 +1421,13 @@ export class AgentSession {
|
|
|
1190
1421
|
finally {
|
|
1191
1422
|
if (this._agentRunAbortRequested)
|
|
1192
1423
|
this._finishCancelledRetry();
|
|
1424
|
+
this._failedResponse = undefined;
|
|
1193
1425
|
this._runSystemPromptOptions = undefined;
|
|
1194
1426
|
this._flushPendingBashMessages();
|
|
1195
1427
|
this._flushPendingCustomMessages();
|
|
1196
1428
|
await this._emitAgentSettled();
|
|
1197
1429
|
}
|
|
1198
1430
|
}
|
|
1199
|
-
/**
|
|
1200
|
-
* Deliver a background completion through the same queueing path as interactive input:
|
|
1201
|
-
* steering into an active run lands the result right after the current tool batch, and an
|
|
1202
|
-
* idle session starts its own turn. The promise settles only once the message is persisted,
|
|
1203
|
-
* or once it can no longer be persisted, so the caller never releases its claim for a
|
|
1204
|
-
* message the transcript does not contain.
|
|
1205
|
-
*/
|
|
1206
|
-
_deliverBackgroundCompletion(message) {
|
|
1207
|
-
if (!this.isStreaming) {
|
|
1208
|
-
// Completion turns skip before_agent_start, but consume nextTurn context.
|
|
1209
|
-
const asides = this._pendingNextTurnMessages.slice();
|
|
1210
|
-
return this._runAgentPrompt(asides.length ? [message, ...asides] : message);
|
|
1211
|
-
}
|
|
1212
|
-
return new Promise((resolve, reject) => {
|
|
1213
|
-
const queued = {
|
|
1214
|
-
drained: false,
|
|
1215
|
-
resolve: () => {
|
|
1216
|
-
if (this._queuedBackgroundCompletions.get(message) !== queued)
|
|
1217
|
-
return;
|
|
1218
|
-
this._queuedBackgroundCompletions.delete(message);
|
|
1219
|
-
resolve();
|
|
1220
|
-
},
|
|
1221
|
-
reject: (reason) => {
|
|
1222
|
-
if (this._queuedBackgroundCompletions.get(message) !== queued)
|
|
1223
|
-
return;
|
|
1224
|
-
this._queuedBackgroundCompletions.delete(message);
|
|
1225
|
-
reject(reason);
|
|
1226
|
-
},
|
|
1227
|
-
};
|
|
1228
|
-
this._queuedBackgroundCompletions.set(message, queued);
|
|
1229
|
-
try {
|
|
1230
|
-
this.agent.steer(message);
|
|
1231
|
-
}
|
|
1232
|
-
catch (error) {
|
|
1233
|
-
queued.reject(error);
|
|
1234
|
-
}
|
|
1235
|
-
});
|
|
1236
|
-
}
|
|
1237
|
-
/**
|
|
1238
|
-
* Fail deliveries the owning run emitted but never persisted. A completion still sitting in
|
|
1239
|
-
* the steering queue when its run ends stays claimed: the next run delivers it, so failing
|
|
1240
|
-
* it here would persist the same message twice.
|
|
1241
|
-
*/
|
|
1242
|
-
_failDrainedBackgroundCompletions() {
|
|
1243
|
-
for (const queued of [...this._queuedBackgroundCompletions.values()]) {
|
|
1244
|
-
if (queued.drained)
|
|
1245
|
-
queued.reject(new Error("the completion message was not persisted"));
|
|
1246
|
-
}
|
|
1247
|
-
}
|
|
1248
1431
|
async _handlePostAgentRun() {
|
|
1249
1432
|
const message = this._lastAssistantMessage;
|
|
1250
1433
|
const toolResults = this._lastAssistantToolResults;
|
|
@@ -1259,6 +1442,7 @@ export class AgentSession {
|
|
|
1259
1442
|
if (this._isRetryableError(message) && (await this._prepareRetry(message))) {
|
|
1260
1443
|
if (this._agentRunAbortRequested)
|
|
1261
1444
|
this._finishCancelledRetry();
|
|
1445
|
+
this._failedResponse = message;
|
|
1262
1446
|
return !this._agentRunAbortRequested;
|
|
1263
1447
|
}
|
|
1264
1448
|
if (this._agentRunAbortRequested) {
|
|
@@ -1326,7 +1510,7 @@ export class AgentSession {
|
|
|
1326
1510
|
for (const image of images) {
|
|
1327
1511
|
const processed = await processImage(Buffer.from(image.data, "base64"), image.mimeType, {
|
|
1328
1512
|
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
1329
|
-
resizeOptions: this.
|
|
1513
|
+
resizeOptions: this._limitsModel()?.inputLimits?.images?.resize,
|
|
1330
1514
|
});
|
|
1331
1515
|
if (!processed.ok) {
|
|
1332
1516
|
hints.push(processed.message);
|
|
@@ -1352,7 +1536,7 @@ export class AgentSession {
|
|
|
1352
1536
|
return;
|
|
1353
1537
|
}
|
|
1354
1538
|
// A user-initiated prompt is the recovery point for failed completion deliveries.
|
|
1355
|
-
this.
|
|
1539
|
+
this.retryTaskNotifications();
|
|
1356
1540
|
const expandPromptTemplates = options?.expandPromptTemplates ?? true;
|
|
1357
1541
|
const preflightResult = options?.preflightResult;
|
|
1358
1542
|
let messages;
|
|
@@ -1364,20 +1548,20 @@ export class AgentSession {
|
|
|
1364
1548
|
const handled = await this._tryExecuteExtensionCommand(text);
|
|
1365
1549
|
if (handled) {
|
|
1366
1550
|
// Extension command executed, no prompt to send
|
|
1367
|
-
preflightResult?.(
|
|
1551
|
+
preflightResult?.("handled");
|
|
1368
1552
|
return;
|
|
1369
1553
|
}
|
|
1370
1554
|
}
|
|
1371
1555
|
// Observer commands above may stay open indefinitely; only real model input owns
|
|
1372
1556
|
// the preflight pause, released once the user message is established.
|
|
1373
|
-
resumeBackground = this.
|
|
1557
|
+
resumeBackground = this.pauseTaskNotifications();
|
|
1374
1558
|
if (this._compactionAbortController !== undefined) {
|
|
1375
1559
|
throw new Error("Cannot submit a prompt while compaction is in progress. Wait for compaction to finish and retry.");
|
|
1376
1560
|
}
|
|
1377
1561
|
// Emit input event for extension interception (before skill/template expansion)
|
|
1378
1562
|
const processedInput = await this._runInputHandlers(text, options?.images, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
|
|
1379
1563
|
if (!processedInput) {
|
|
1380
|
-
preflightResult?.(
|
|
1564
|
+
preflightResult?.("handled");
|
|
1381
1565
|
return;
|
|
1382
1566
|
}
|
|
1383
1567
|
const { text: currentText, images: currentImages } = processedInput;
|
|
@@ -1398,7 +1582,7 @@ export class AgentSession {
|
|
|
1398
1582
|
else {
|
|
1399
1583
|
await this._queueSteer(expandedText, currentImages);
|
|
1400
1584
|
}
|
|
1401
|
-
preflightResult?.(
|
|
1585
|
+
preflightResult?.("queued");
|
|
1402
1586
|
return;
|
|
1403
1587
|
}
|
|
1404
1588
|
// Flush any pending bash and custom messages before the new prompt
|
|
@@ -1447,8 +1631,7 @@ export class AgentSession {
|
|
|
1447
1631
|
content: userContent,
|
|
1448
1632
|
timestamp: Date.now(),
|
|
1449
1633
|
});
|
|
1450
|
-
// Inject any pending "nextTurn" messages as context alongside the user message
|
|
1451
|
-
// They stay queued until _persistMessage() confirms the append.
|
|
1634
|
+
// Inject any pending "nextTurn" messages as context alongside the user message
|
|
1452
1635
|
for (const msg of this._pendingNextTurnMessages) {
|
|
1453
1636
|
messages.push(msg);
|
|
1454
1637
|
}
|
|
@@ -1468,18 +1651,12 @@ export class AgentSession {
|
|
|
1468
1651
|
if (updateMessage)
|
|
1469
1652
|
messages.unshift(updateMessage);
|
|
1470
1653
|
}
|
|
1471
|
-
catch (error) {
|
|
1472
|
-
preflightResult?.(false);
|
|
1473
|
-
throw error;
|
|
1474
|
-
}
|
|
1475
1654
|
finally {
|
|
1476
|
-
// Delivery is timer-scheduled, so a completion cannot start before the run below does.
|
|
1477
1655
|
resumeBackground?.();
|
|
1478
1656
|
}
|
|
1479
|
-
if (!messages)
|
|
1657
|
+
if (!messages)
|
|
1480
1658
|
return;
|
|
1481
|
-
|
|
1482
|
-
preflightResult?.(true);
|
|
1659
|
+
preflightResult?.("started");
|
|
1483
1660
|
await this._runAgentPrompt(messages);
|
|
1484
1661
|
}
|
|
1485
1662
|
/**
|
|
@@ -1545,7 +1722,7 @@ export class AgentSession {
|
|
|
1545
1722
|
}
|
|
1546
1723
|
const processedInput = await this._runInputHandlers(text, images, source, this.isStreaming ? behavior : undefined);
|
|
1547
1724
|
if (!processedInput)
|
|
1548
|
-
return;
|
|
1725
|
+
return "handled";
|
|
1549
1726
|
let expandedText = this._expandSkillCommand(processedInput.text);
|
|
1550
1727
|
expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
|
|
1551
1728
|
if (behavior === "steer") {
|
|
@@ -1554,6 +1731,7 @@ export class AgentSession {
|
|
|
1554
1731
|
else {
|
|
1555
1732
|
await this._queueFollowUp(expandedText, processedInput.images);
|
|
1556
1733
|
}
|
|
1734
|
+
return "queued";
|
|
1557
1735
|
}
|
|
1558
1736
|
/**
|
|
1559
1737
|
* Queue a steering message while the agent is running.
|
|
@@ -1565,7 +1743,7 @@ export class AgentSession {
|
|
|
1565
1743
|
* @throws Error if text is an extension command
|
|
1566
1744
|
*/
|
|
1567
1745
|
async steer(text, images, options) {
|
|
1568
|
-
|
|
1746
|
+
return this._queueUserInput(text, images, "steer", options?.source ?? "interactive");
|
|
1569
1747
|
}
|
|
1570
1748
|
/**
|
|
1571
1749
|
* Queue a follow-up message to be processed after the agent finishes.
|
|
@@ -1576,7 +1754,7 @@ export class AgentSession {
|
|
|
1576
1754
|
* @throws Error if text is an extension command
|
|
1577
1755
|
*/
|
|
1578
1756
|
async followUp(text, images, options) {
|
|
1579
|
-
|
|
1757
|
+
return this._queueUserInput(text, images, "followUp", options?.source ?? "interactive");
|
|
1580
1758
|
}
|
|
1581
1759
|
/**
|
|
1582
1760
|
* Internal: Queue a steering message (already expanded, no extension command check).
|
|
@@ -1670,9 +1848,9 @@ export class AgentSession {
|
|
|
1670
1848
|
}
|
|
1671
1849
|
}
|
|
1672
1850
|
_appendCustomMessage(appMessage) {
|
|
1673
|
-
this.
|
|
1851
|
+
this.sessionManager.appendCustomMessageEntry(appMessage.customType, appMessage.content, appMessage.display, appMessage.details);
|
|
1852
|
+
this._messagePersisted(appMessage);
|
|
1674
1853
|
this._refreshFinalizedContext();
|
|
1675
|
-
this._backgroundHost.messageAcknowledgement(appMessage)?.();
|
|
1676
1854
|
this._emit({ type: "message_start", message: appMessage });
|
|
1677
1855
|
this._emit({ type: "message_end", message: appMessage });
|
|
1678
1856
|
}
|
|
@@ -1737,10 +1915,7 @@ export class AgentSession {
|
|
|
1737
1915
|
this._steeringMessages = [];
|
|
1738
1916
|
this._followUpMessages = [];
|
|
1739
1917
|
this.agent.clearAllQueues();
|
|
1740
|
-
|
|
1741
|
-
for (const queued of [...this._queuedBackgroundCompletions.values()]) {
|
|
1742
|
-
queued.reject(new Error("the completion message was dequeued before delivery"));
|
|
1743
|
-
}
|
|
1918
|
+
this._tasksHost.delivery.queueCleared();
|
|
1744
1919
|
this._emitQueueUpdate();
|
|
1745
1920
|
return { steering, followUp };
|
|
1746
1921
|
}
|
|
@@ -1997,8 +2172,10 @@ export class AgentSession {
|
|
|
1997
2172
|
// Compaction
|
|
1998
2173
|
// =========================================================================
|
|
1999
2174
|
/** Generate Pi's built-in compaction summary for manual and automatic compaction. */
|
|
2000
|
-
async _runDefaultCompaction(preparation,
|
|
2001
|
-
|
|
2175
|
+
async _runDefaultCompaction(preparation, model, customInstructions, signal, reason) {
|
|
2176
|
+
// Resolve the request only when Pi summarizes itself: routing may call models or fail.
|
|
2177
|
+
const request = await this._getSummarizationRequestAuth(model, signal);
|
|
2178
|
+
return compact(preparation, request.model, request.apiKey, request.headers, customInstructions, signal, request.thinkingLevel, this.agent.streamFunction, request.env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }), undefined);
|
|
2002
2179
|
}
|
|
2003
2180
|
_clearManualCompactionState() {
|
|
2004
2181
|
this._compactionAbortController = undefined;
|
|
@@ -2020,7 +2197,7 @@ export class AgentSession {
|
|
|
2020
2197
|
* @param customInstructions Optional instructions for the compaction summary
|
|
2021
2198
|
*/
|
|
2022
2199
|
async compact(customInstructions) {
|
|
2023
|
-
return this.
|
|
2200
|
+
return this._withTasksPaused(() => this._compactBody(customInstructions));
|
|
2024
2201
|
}
|
|
2025
2202
|
async _compactBody(customInstructions) {
|
|
2026
2203
|
await this.abort();
|
|
@@ -2033,8 +2210,7 @@ export class AgentSession {
|
|
|
2033
2210
|
if (!model) {
|
|
2034
2211
|
throw new Error(formatNoModelSelectedMessage());
|
|
2035
2212
|
}
|
|
2036
|
-
const settings = this.settingsManager.getCompactionSettings(model);
|
|
2037
|
-
const { model: requestModel, apiKey, headers, env, } = await this._getSummarizationRequestAuth(model, this._compactionAbortController.signal);
|
|
2213
|
+
const settings = this.settingsManager.getCompactionSettings(this.routedModel?.model ?? model);
|
|
2038
2214
|
const pathEntries = this.sessionManager.getBranch();
|
|
2039
2215
|
const preparation = prepareCompaction(pathEntries, settings);
|
|
2040
2216
|
if (!preparation) {
|
|
@@ -2080,7 +2256,7 @@ export class AgentSession {
|
|
|
2080
2256
|
}
|
|
2081
2257
|
else {
|
|
2082
2258
|
// Shared default summary generator, also used by automatic compaction.
|
|
2083
|
-
const result = await this._runDefaultCompaction(preparation,
|
|
2259
|
+
const result = await this._runDefaultCompaction(preparation, model, customInstructions, this._compactionAbortController.signal, "manual");
|
|
2084
2260
|
summary = result.summary;
|
|
2085
2261
|
firstKeptEntryId = result.firstKeptEntryId;
|
|
2086
2262
|
tokensBefore = result.tokensBefore;
|
|
@@ -2185,18 +2361,20 @@ export class AgentSession {
|
|
|
2185
2361
|
* @returns Whether the post-run loop should call `agent.continue()` for overflow recovery or queued messages
|
|
2186
2362
|
*/
|
|
2187
2363
|
async _checkCompaction(assistantMessage, skipAbortedCheck = true, toolResults = []) {
|
|
2188
|
-
const settings = this.settingsManager.getCompactionSettings(this.model);
|
|
2364
|
+
const settings = this.settingsManager.getCompactionSettings(this._modelForMessage(assistantMessage) ?? this.model);
|
|
2189
2365
|
if (!settings.enabled)
|
|
2190
2366
|
return false;
|
|
2191
2367
|
// Skip if message was aborted (user cancelled) - unless skipAbortedCheck is false
|
|
2192
2368
|
if (skipAbortedCheck && assistantMessage.stopReason === "aborted")
|
|
2193
2369
|
return false;
|
|
2194
|
-
const contextWindow = this.model?.contextWindow ?? 0;
|
|
2195
2370
|
// Skip overflow check if the message came from a different model.
|
|
2196
2371
|
// This handles the case where user switched from a smaller-context model (e.g. opus)
|
|
2197
2372
|
// to a larger-context model (e.g. codex) - the overflow error from the old model
|
|
2198
|
-
// shouldn't trigger compaction for the new model.
|
|
2199
|
-
|
|
2373
|
+
// shouldn't trigger compaction for the new model. Under a virtual selection, the
|
|
2374
|
+
// physical model that produced the message supplies the limits.
|
|
2375
|
+
const messageModel = this._modelForMessage(assistantMessage);
|
|
2376
|
+
const sameModel = messageModel !== undefined;
|
|
2377
|
+
const contextWindow = (messageModel ?? this.model)?.contextWindow ?? 0;
|
|
2200
2378
|
// Skip compaction checks if this assistant message is older than the latest
|
|
2201
2379
|
// compaction boundary. This prevents a stale pre-compaction usage/error
|
|
2202
2380
|
// from retriggering compaction on the first prompt after compaction.
|
|
@@ -2228,7 +2406,7 @@ export class AgentSession {
|
|
|
2228
2406
|
const contextOverflow = sameModel &&
|
|
2229
2407
|
((explicitOverflow && assistantRetainedForExplicitRecovery) ||
|
|
2230
2408
|
(assistantUsageMatchesProjection && isContextOverflow(assistantMessage, contextWindow)));
|
|
2231
|
-
const recoverableLength = sameModel && assistantIsProjected && isRecoverableLength(assistantMessage,
|
|
2409
|
+
const recoverableLength = sameModel && assistantIsProjected && isRecoverableLength(assistantMessage, messageModel.maxTokens);
|
|
2232
2410
|
if (contextOverflow || recoverableLength) {
|
|
2233
2411
|
const willRetry = assistantMessage.stopReason !== "stop";
|
|
2234
2412
|
// Case 2: the response completed successfully. Compact, but do not retry because
|
|
@@ -2260,7 +2438,10 @@ export class AgentSession {
|
|
|
2260
2438
|
// Persistently omit the selected final attempt before post-run recovery compaction.
|
|
2261
2439
|
this._overflowRecoveryAttempted = true;
|
|
2262
2440
|
this._omitRecoveryAttempt(assistantMessage, toolResults);
|
|
2263
|
-
|
|
2441
|
+
const retry = await this._runAutoCompaction("overflow", willRetry);
|
|
2442
|
+
if (retry)
|
|
2443
|
+
this._failedResponse = assistantMessage;
|
|
2444
|
+
return retry;
|
|
2264
2445
|
}
|
|
2265
2446
|
// Case 3: threshold compaction without retry.
|
|
2266
2447
|
// For error messages or all-zero usage messages, estimate from the last valid response.
|
|
@@ -2310,11 +2491,11 @@ export class AgentSession {
|
|
|
2310
2491
|
* @returns Whether the post-run loop should call `agent.continue()`
|
|
2311
2492
|
*/
|
|
2312
2493
|
async _runAutoCompaction(reason, willRetry) {
|
|
2313
|
-
return this.
|
|
2494
|
+
return this._withTasksPaused(() => this._runAutoCompactionBody(reason, willRetry));
|
|
2314
2495
|
}
|
|
2315
2496
|
async _runAutoCompactionBody(reason, willRetry) {
|
|
2316
2497
|
const model = this.model;
|
|
2317
|
-
const settings = this.settingsManager.getCompactionSettings(model);
|
|
2498
|
+
const settings = this.settingsManager.getCompactionSettings(this.routedModel?.model ?? model);
|
|
2318
2499
|
let abortController;
|
|
2319
2500
|
let started = false;
|
|
2320
2501
|
let fromExtension = false;
|
|
@@ -2333,8 +2514,6 @@ export class AgentSession {
|
|
|
2333
2514
|
started = true;
|
|
2334
2515
|
this._emit({ type: "compaction_start", reason });
|
|
2335
2516
|
abortController.signal.throwIfAborted();
|
|
2336
|
-
const { model: requestModel, apiKey, headers, env, } = await this._getSummarizationRequestAuth(model, abortController.signal);
|
|
2337
|
-
abortController.signal.throwIfAborted();
|
|
2338
2517
|
let extensionCompaction;
|
|
2339
2518
|
if (this._extensionRunner.hasHandlers("session_before_compact")) {
|
|
2340
2519
|
const extensionResult = (await this._extensionRunner.emit({
|
|
@@ -2371,7 +2550,7 @@ export class AgentSession {
|
|
|
2371
2550
|
}
|
|
2372
2551
|
else {
|
|
2373
2552
|
// Shared default summary generator, also used by manual compaction.
|
|
2374
|
-
const compactResult = await this._runDefaultCompaction(preparation,
|
|
2553
|
+
const compactResult = await this._runDefaultCompaction(preparation, model, undefined, abortController.signal, reason);
|
|
2375
2554
|
summary = compactResult.summary;
|
|
2376
2555
|
firstKeptEntryId = compactResult.firstKeptEntryId;
|
|
2377
2556
|
tokensBefore = compactResult.tokensBefore;
|
|
@@ -2454,11 +2633,12 @@ export class AgentSession {
|
|
|
2454
2633
|
return this.settingsManager.getCompactionEnabled();
|
|
2455
2634
|
}
|
|
2456
2635
|
async bindExtensions(bindings) {
|
|
2457
|
-
return this.
|
|
2636
|
+
return this._withTasksPaused(() => this._bindExtensionsBody(bindings));
|
|
2458
2637
|
}
|
|
2459
2638
|
async _bindExtensionsBody(bindings) {
|
|
2460
|
-
if (bindings.
|
|
2461
|
-
this.
|
|
2639
|
+
if (bindings.tasksEnabled !== undefined) {
|
|
2640
|
+
this._tasksHost.setEnabled(bindings.tasksEnabled);
|
|
2641
|
+
this._refreshToolRegistry();
|
|
2462
2642
|
}
|
|
2463
2643
|
if (bindings.uiContext !== undefined) {
|
|
2464
2644
|
this._extensionUIContext = bindings.uiContext;
|
|
@@ -2480,6 +2660,7 @@ export class AgentSession {
|
|
|
2480
2660
|
}
|
|
2481
2661
|
this._applyExtensionBindings(this._extensionRunner);
|
|
2482
2662
|
await this._extensionRunner.emit(this._sessionStartEvent);
|
|
2663
|
+
this._extensionRunner.reportUnhandledMcpServers();
|
|
2483
2664
|
await this.extendResourcesFromExtensions(this._sessionStartEvent.reason === "reload" ? "reload" : "startup");
|
|
2484
2665
|
}
|
|
2485
2666
|
async extendResourcesFromExtensions(reason) {
|
|
@@ -2501,7 +2682,7 @@ export class AgentSession {
|
|
|
2501
2682
|
buildExtensionResourcePaths(entries) {
|
|
2502
2683
|
return entries.map((entry) => {
|
|
2503
2684
|
const source = this.getExtensionSourceLabel(entry.extensionPath);
|
|
2504
|
-
const baseDir = entry.extensionPath
|
|
2685
|
+
const baseDir = isSyntheticPath(entry.extensionPath) ? undefined : dirname(entry.extensionPath);
|
|
2505
2686
|
return {
|
|
2506
2687
|
path: entry.path,
|
|
2507
2688
|
metadata: {
|
|
@@ -2514,7 +2695,7 @@ export class AgentSession {
|
|
|
2514
2695
|
});
|
|
2515
2696
|
}
|
|
2516
2697
|
getExtensionSourceLabel(extensionPath) {
|
|
2517
|
-
if (extensionPath
|
|
2698
|
+
if (isSyntheticPath(extensionPath)) {
|
|
2518
2699
|
return `extension:${extensionPath.replace(/[<>]/g, "")}`;
|
|
2519
2700
|
}
|
|
2520
2701
|
const base = basename(extensionPath);
|
|
@@ -2599,6 +2780,7 @@ export class AgentSession {
|
|
|
2599
2780
|
},
|
|
2600
2781
|
getActiveTools: () => this.getActiveToolNames(),
|
|
2601
2782
|
getAllTools: () => this.getAllTools(),
|
|
2783
|
+
getSettings: () => this.settingsManager.getSettings(),
|
|
2602
2784
|
setActiveTools: (toolNames) => this.setActiveToolsByName(toolNames),
|
|
2603
2785
|
refreshTools: () => this._refreshToolRegistry(),
|
|
2604
2786
|
getCommands,
|
|
@@ -2611,7 +2793,9 @@ export class AgentSession {
|
|
|
2611
2793
|
getThinkingLevel: () => this.thinkingLevel,
|
|
2612
2794
|
setThinkingLevel: (level) => this.setThinkingLevel(level),
|
|
2613
2795
|
}, {
|
|
2614
|
-
|
|
2796
|
+
getTasks: () => this.tasks,
|
|
2797
|
+
getExtensionSettings: (namespace) => this.settingsManager.getExtensionSettings(namespace),
|
|
2798
|
+
setExtensionSettings: (namespace, value) => this.settingsManager.setExtensionSettings(namespace, value),
|
|
2615
2799
|
getModel: () => this.model,
|
|
2616
2800
|
getScopedModels: () => this._scopedModels,
|
|
2617
2801
|
isIdle: () => this.isIdle,
|
|
@@ -2644,6 +2828,8 @@ export class AgentSession {
|
|
|
2644
2828
|
},
|
|
2645
2829
|
getSystemPrompt: () => this.systemPrompt,
|
|
2646
2830
|
getSystemPromptOptions: () => this._baseSystemPromptOptions,
|
|
2831
|
+
executeTool: (callerId, name, args, options) => this._executeNestedToolCall(callerId, name, args, options),
|
|
2832
|
+
getCallableTools: () => this._getCallableTools(),
|
|
2647
2833
|
}, {
|
|
2648
2834
|
registerProvider: (name, config) => {
|
|
2649
2835
|
this._modelRuntime.registerProvider(name, config);
|
|
@@ -2657,10 +2843,20 @@ export class AgentSession {
|
|
|
2657
2843
|
this._modelRuntime.unregisterProvider(name);
|
|
2658
2844
|
this._refreshCurrentModelFromRegistry();
|
|
2659
2845
|
},
|
|
2846
|
+
registerVirtualModel: (definition) => {
|
|
2847
|
+
this._modelRuntime.registerVirtualModel(definition);
|
|
2848
|
+
this._refreshCurrentModelFromRegistry();
|
|
2849
|
+
},
|
|
2850
|
+
unregisterVirtualModel: (provider, id) => {
|
|
2851
|
+
this._modelRuntime.unregisterVirtualModel(provider, id);
|
|
2852
|
+
this._refreshCurrentModelFromRegistry();
|
|
2853
|
+
},
|
|
2660
2854
|
});
|
|
2661
2855
|
}
|
|
2662
2856
|
_refreshToolRegistry(options) {
|
|
2663
|
-
|
|
2857
|
+
// Tools that were already activated on registration. A tool whose exposure changes to
|
|
2858
|
+
// `direct` or `model-only` (for example from `hidden`) is activated like a new tool.
|
|
2859
|
+
const previousActivatedOnRegistration = new Set([...this._toolRegistry.keys()].filter((name) => this._isActivatedOnRegistration(name)));
|
|
2664
2860
|
const previousActiveToolNames = this.getActiveToolNames();
|
|
2665
2861
|
const allowedToolNames = this._allowedToolNames;
|
|
2666
2862
|
const excludedToolNames = this._excludedToolNames;
|
|
@@ -2679,7 +2875,7 @@ export class AgentSession {
|
|
|
2679
2875
|
name,
|
|
2680
2876
|
{
|
|
2681
2877
|
definition,
|
|
2682
|
-
sourceInfo: createSyntheticSourceInfo(
|
|
2878
|
+
sourceInfo: createSyntheticSourceInfo(`${BUILTIN_PATH_PREFIX}${name}`, { source: "builtin" }),
|
|
2683
2879
|
},
|
|
2684
2880
|
]));
|
|
2685
2881
|
for (const tool of allCustomTools) {
|
|
@@ -2707,7 +2903,9 @@ export class AgentSession {
|
|
|
2707
2903
|
.filter((definition) => isAllowedTool(definition.name))
|
|
2708
2904
|
.map((definition) => ({
|
|
2709
2905
|
definition,
|
|
2710
|
-
sourceInfo: createSyntheticSourceInfo(
|
|
2906
|
+
sourceInfo: createSyntheticSourceInfo(`${BUILTIN_PATH_PREFIX}${definition.name}`, {
|
|
2907
|
+
source: "builtin",
|
|
2908
|
+
}),
|
|
2711
2909
|
})), runner);
|
|
2712
2910
|
const toolRegistry = new Map(wrappedBuiltInTools.map((tool) => [tool.name, tool]));
|
|
2713
2911
|
for (const tool of wrappedExtensionTools) {
|
|
@@ -2717,25 +2915,41 @@ export class AgentSession {
|
|
|
2717
2915
|
const nextActiveToolNames = (options?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames]).filter((name) => isAllowedTool(name));
|
|
2718
2916
|
if (allowedToolNames) {
|
|
2719
2917
|
for (const toolName of this._toolRegistry.keys()) {
|
|
2720
|
-
|
|
2918
|
+
// Naming a tool activates it even when it is not active by default.
|
|
2919
|
+
if (allowedToolNames.has(toolName) && this._isDeclarable(toolName)) {
|
|
2721
2920
|
nextActiveToolNames.push(toolName);
|
|
2722
2921
|
}
|
|
2723
2922
|
}
|
|
2724
2923
|
}
|
|
2725
2924
|
else if (options?.includeAllExtensionTools) {
|
|
2726
2925
|
for (const tool of wrappedExtensionTools) {
|
|
2727
|
-
|
|
2926
|
+
if (this._isActivatedOnRegistration(tool.name))
|
|
2927
|
+
nextActiveToolNames.push(tool.name);
|
|
2728
2928
|
}
|
|
2729
2929
|
}
|
|
2730
2930
|
else if (!options?.activeToolNames) {
|
|
2731
2931
|
for (const toolName of this._toolRegistry.keys()) {
|
|
2732
|
-
if (!
|
|
2932
|
+
if (!previousActivatedOnRegistration.has(toolName) && this._isActivatedOnRegistration(toolName)) {
|
|
2733
2933
|
nextActiveToolNames.push(toolName);
|
|
2734
2934
|
}
|
|
2735
2935
|
}
|
|
2736
2936
|
}
|
|
2937
|
+
if (this.tasks.enabled &&
|
|
2938
|
+
this._initialActiveToolNames?.length !== 0 &&
|
|
2939
|
+
this._toolRegistry.has("tasks") &&
|
|
2940
|
+
isAllowedTool("tasks"))
|
|
2941
|
+
nextActiveToolNames.push("tasks");
|
|
2737
2942
|
this.setActiveToolsByName([...new Set(nextActiveToolNames)]);
|
|
2738
2943
|
}
|
|
2944
|
+
/** Whether activating the tool declares it to the model. */
|
|
2945
|
+
_isDeclarable(name) {
|
|
2946
|
+
const exposure = this._getToolExposure(name);
|
|
2947
|
+
return exposure === "direct" || exposure === "model-only";
|
|
2948
|
+
}
|
|
2949
|
+
/** Whether registering the tool activates it, which declares it to the model. */
|
|
2950
|
+
_isActivatedOnRegistration(name) {
|
|
2951
|
+
return this._isDeclarable(name) && this._toolDefinitions.get(name)?.definition.defaultActive !== false;
|
|
2952
|
+
}
|
|
2739
2953
|
_buildRuntime(options) {
|
|
2740
2954
|
const autoResizeImages = this.settingsManager.getImageAutoResize();
|
|
2741
2955
|
const shellCommandPrefix = this.settingsManager.getShellCommandPrefix();
|
|
@@ -2750,6 +2964,7 @@ export class AgentSession {
|
|
|
2750
2964
|
bash: { commandPrefix: shellCommandPrefix, shellPath },
|
|
2751
2965
|
});
|
|
2752
2966
|
this._baseToolDefinitions = new Map(Object.entries(baseToolDefinitions).map(([name, tool]) => [name, tool]));
|
|
2967
|
+
this._baseToolDefinitions.set("tasks", createTasksToolDefinition((callId, taskId) => this._tasksHost.delivery.prepareWait(callId, taskId)));
|
|
2753
2968
|
const extensionsResult = this._resourceLoader.getExtensions();
|
|
2754
2969
|
if (options.flagValues) {
|
|
2755
2970
|
for (const [name, value] of options.flagValues) {
|
|
@@ -2772,26 +2987,26 @@ export class AgentSession {
|
|
|
2772
2987
|
});
|
|
2773
2988
|
}
|
|
2774
2989
|
async reload(options) {
|
|
2775
|
-
return this.
|
|
2990
|
+
return this._withTasksPaused(() => this._reloadBody(options));
|
|
2776
2991
|
}
|
|
2777
2992
|
async _reloadBody(options) {
|
|
2778
2993
|
const oldRunner = this._extensionRunner;
|
|
2779
2994
|
const previousFlagValues = oldRunner.getFlagValues();
|
|
2780
|
-
this.
|
|
2781
|
-
await Promise.all([this.
|
|
2995
|
+
this.tasks.close();
|
|
2996
|
+
await Promise.all([this.tasks.shutdown(), this.abort()]);
|
|
2782
2997
|
await emitSessionShutdownEvent(oldRunner, { type: "session_shutdown", reason: "reload" });
|
|
2783
2998
|
oldRunner.invalidate();
|
|
2784
2999
|
await this.settingsManager.reload();
|
|
2785
3000
|
this.syncQueueModesFromSettings();
|
|
2786
3001
|
resetApiProviders();
|
|
2787
3002
|
await this._resourceLoader.reload();
|
|
2788
|
-
this.
|
|
3003
|
+
this._tasksHost.replaceService();
|
|
2789
3004
|
this._buildRuntime({
|
|
2790
3005
|
activeToolNames: this.getActiveToolNames(),
|
|
2791
3006
|
flagValues: previousFlagValues,
|
|
2792
3007
|
includeAllExtensionTools: true,
|
|
2793
3008
|
});
|
|
2794
|
-
const hasBindings = this.
|
|
3009
|
+
const hasBindings = this.tasks.enabled ||
|
|
2795
3010
|
this._extensionUIContext ||
|
|
2796
3011
|
this._extensionCommandContextActions ||
|
|
2797
3012
|
this._extensionShutdownHandler ||
|
|
@@ -2799,6 +3014,7 @@ export class AgentSession {
|
|
|
2799
3014
|
if (hasBindings) {
|
|
2800
3015
|
await options?.beforeSessionStart?.();
|
|
2801
3016
|
await this._extensionRunner.emit({ type: "session_start", reason: "reload" });
|
|
3017
|
+
this._extensionRunner.reportUnhandledMcpServers();
|
|
2802
3018
|
await this.extendResourcesFromExtensions("reload");
|
|
2803
3019
|
}
|
|
2804
3020
|
}
|
|
@@ -2811,7 +3027,7 @@ export class AgentSession {
|
|
|
2811
3027
|
*/
|
|
2812
3028
|
_isRetryableError(message) {
|
|
2813
3029
|
// Context overflow is handled by compaction, not retry.
|
|
2814
|
-
if (isContextOverflow(message, this.model?.contextWindow ?? 0))
|
|
3030
|
+
if (isContextOverflow(message, (this._modelForMessage(message) ?? this.model)?.contextWindow ?? 0))
|
|
2815
3031
|
return false;
|
|
2816
3032
|
return isRetryableAssistantError(message);
|
|
2817
3033
|
}
|
|
@@ -3066,7 +3282,7 @@ export class AgentSession {
|
|
|
3066
3282
|
replaceInstructions,
|
|
3067
3283
|
label,
|
|
3068
3284
|
};
|
|
3069
|
-
const resumeBackground = this.
|
|
3285
|
+
const resumeBackground = this.pauseTaskNotifications();
|
|
3070
3286
|
// Set up abort controller for summarization
|
|
3071
3287
|
this._branchSummaryAbortController = new AbortController();
|
|
3072
3288
|
try {
|
|
@@ -3102,15 +3318,11 @@ export class AgentSession {
|
|
|
3102
3318
|
let summaryDetails;
|
|
3103
3319
|
let summaryUsage;
|
|
3104
3320
|
if (options.summarize && entriesToSummarize.length > 0 && !extensionSummary) {
|
|
3105
|
-
const
|
|
3106
|
-
const { model: requestModel, apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
|
|
3321
|
+
const signal = this._branchSummaryAbortController.signal;
|
|
3107
3322
|
const branchSummarySettings = this.settingsManager.getBranchSummarySettings();
|
|
3108
3323
|
const result = await generateBranchSummary(entriesToSummarize, {
|
|
3109
|
-
model
|
|
3110
|
-
|
|
3111
|
-
headers,
|
|
3112
|
-
env,
|
|
3113
|
-
signal: this._branchSummaryAbortController.signal,
|
|
3324
|
+
...(await this._getSummarizationRequestAuth(this.model, signal)),
|
|
3325
|
+
signal,
|
|
3114
3326
|
customInstructions,
|
|
3115
3327
|
replaceInstructions,
|
|
3116
3328
|
reserveTokens: branchSummarySettings.reserveTokens,
|
|
@@ -3153,7 +3365,7 @@ export class AgentSession {
|
|
|
3153
3365
|
// Non-user message: leaf = selected node
|
|
3154
3366
|
newLeafId = targetId;
|
|
3155
3367
|
}
|
|
3156
|
-
await this.
|
|
3368
|
+
await this.tasks.cancelOutsideBranch(new Set(newLeafId === null ? [] : this.sessionManager.getBranch(newLeafId).map((entry) => entry.id)));
|
|
3157
3369
|
// Switch leaf (with or without summary)
|
|
3158
3370
|
// Summary is attached at the navigation target position (newLeafId), not the old branch
|
|
3159
3371
|
let summaryEntry;
|
|
@@ -3178,7 +3390,7 @@ export class AgentSession {
|
|
|
3178
3390
|
if (label && !summaryText) {
|
|
3179
3391
|
this.sessionManager.appendLabelChange(targetId, label);
|
|
3180
3392
|
}
|
|
3181
|
-
this.
|
|
3393
|
+
this._tasksHost.restoreHistory();
|
|
3182
3394
|
// Update finalized context from the canonical session projection.
|
|
3183
3395
|
this._refreshFinalizedContext();
|
|
3184
3396
|
this._restoreToolsFromTranscript();
|
|
@@ -3271,7 +3483,7 @@ export class AgentSession {
|
|
|
3271
3483
|
};
|
|
3272
3484
|
}
|
|
3273
3485
|
getContextUsage() {
|
|
3274
|
-
const model = this.
|
|
3486
|
+
const model = this._limitsModel();
|
|
3275
3487
|
if (!model)
|
|
3276
3488
|
return undefined;
|
|
3277
3489
|
const contextWindow = model.contextWindow ?? 0;
|
|
@@ -3343,16 +3555,11 @@ export class AgentSession {
|
|
|
3343
3555
|
if (!model) {
|
|
3344
3556
|
throw new Error("No model selected");
|
|
3345
3557
|
}
|
|
3346
|
-
const { model: requestModel, apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
|
|
3347
3558
|
return generateBugReportSummary({
|
|
3559
|
+
...(await this._getSummarizationRequestAuth(model, options.signal)),
|
|
3348
3560
|
messages: this.messages,
|
|
3349
3561
|
hint: options.hint,
|
|
3350
|
-
model: requestModel,
|
|
3351
|
-
apiKey,
|
|
3352
|
-
headers,
|
|
3353
|
-
env,
|
|
3354
3562
|
signal: options.signal,
|
|
3355
|
-
thinkingLevel: this.thinkingLevel,
|
|
3356
3563
|
streamFn: this.agent.streamFunction,
|
|
3357
3564
|
retry: this.settingsManager.getRetrySettings(),
|
|
3358
3565
|
sessionId: this.sessionId,
|