@averyyy/pi-coding-agent 0.87.1-piclient.1 → 0.99.1-piclient.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +98 -0
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/restore-sandbox-env.d.ts.map +1 -1
- package/dist/bun/restore-sandbox-env.js.map +1 -1
- package/dist/bun/runtime-setup.d.ts.map +1 -1
- package/dist/bun/runtime-setup.js +4 -1
- package/dist/bun/runtime-setup.js.map +1 -1
- package/dist/bun/sandbox-env-setup.d.ts.map +1 -1
- package/dist/bundle/chunks/anthropic-messages-A6EXUBG6.js +6 -0
- package/dist/bundle/chunks/anthropic.js +2 -2
- package/dist/bundle/chunks/azure-openai-responses-YZ3Q2WVP.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +2 -2
- package/dist/bundle/chunks/chunk-3YXHSP6S.js +21 -0
- package/dist/bundle/chunks/chunk-7BINYQ2V.js +1548 -0
- package/dist/bundle/chunks/chunk-7JGR3GZN.js +11 -0
- package/dist/bundle/chunks/chunk-F6ORSP6L.js +187 -0
- package/dist/bundle/chunks/chunk-FJTXMIZI.js +150 -0
- package/dist/bundle/chunks/chunk-H3QXYIF7.js +31 -0
- package/dist/bundle/chunks/{chunk-S7SZN6Z3.js → chunk-HSPCVFST.js} +1 -1
- package/dist/bundle/chunks/chunk-J4CWPC4N.js +2 -0
- package/dist/bundle/chunks/chunk-KYJKN5BJ.js +2 -0
- package/dist/bundle/chunks/chunk-RO6I2QFQ.js +4 -0
- package/dist/bundle/chunks/{chunk-XDUWOHPL.js → chunk-S3GGRYIO.js} +2 -2
- package/dist/bundle/chunks/chunk-UTB4DTYQ.js +2 -0
- package/dist/bundle/chunks/{chunk-UZNGGY6N.js → chunk-V7V43FNB.js} +3 -3
- package/dist/bundle/chunks/{chunk-FUXEF6JQ.js → chunk-W2DOMZSC.js} +1 -1
- package/dist/bundle/chunks/chunk-WVKBMRQX.js +82 -0
- package/dist/bundle/chunks/cli-WF6HDHBO.js +49 -0
- package/dist/bundle/chunks/cloudflare-workers-ai-system-one-XJQQYGGU.js +2 -0
- package/dist/bundle/chunks/codemode-worker.js +295 -0
- package/dist/bundle/chunks/execute-AVGAUHMT.js +308 -0
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/google-generative-ai-CQAKKJTA.js +2 -0
- package/dist/bundle/chunks/google-vertex-AE36YXJU.js +2 -0
- package/dist/bundle/chunks/{lib-HGQMNYVT.js → lib-TEDK3E5I.js} +2 -2
- package/dist/bundle/chunks/llama-cpp-classify-PJJYKPLD.js +22 -0
- package/dist/bundle/chunks/mistral-conversations-KEYTXJM7.js +5 -0
- package/dist/bundle/chunks/openai-chatgpt.js +75 -0
- package/dist/bundle/chunks/{openai-codex-responses-SG7PGUUZ.js → openai-codex-responses-FUE7WESF.js} +2 -2
- package/dist/bundle/chunks/openai-codex.js +2 -2
- package/dist/bundle/chunks/{openai-completions-OBX42CLD.js → openai-completions-XW2Q5HVC.js} +2 -2
- package/dist/bundle/chunks/openai-responses-ZUXFVYPI.js +3 -0
- package/dist/bundle/chunks/{openrouter-images-N4XVVFSD.js → openrouter-images-TPQ4V6OR.js} +1 -1
- package/dist/bundle/chunks/openrouter.js +2 -2
- package/dist/bundle/chunks/{pi-messages-GFKBWJHZ.js → pi-messages-TM5SOOIW.js} +2 -2
- package/dist/bundle/chunks/radius.js +2 -2
- package/dist/bundle/chunks/runtime-6ZC4MGWD.js +2 -0
- package/dist/bundle/chunks/typesafe-system-one-E7A4HNJI.js +2 -0
- package/dist/bundle/chunks/virtual-modules-H7OCXN6W.js +2 -0
- package/dist/bundle/cli-runtime.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/auth-check.d.ts.map +1 -1
- package/dist/cli/auth-check.js.map +1 -1
- package/dist/cli/auth-command.d.ts.map +1 -1
- package/dist/cli/auth-command.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/credential-print.d.ts.map +1 -1
- package/dist/cli/credential-print.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/initial-message.d.ts +1 -1
- package/dist/cli/initial-message.d.ts.map +1 -1
- package/dist/cli/initial-message.js.map +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/project-trust.d.ts.map +1 -1
- package/dist/cli/project-trust.js.map +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.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/cli.d.ts.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.map +1 -1
- package/dist/core/agent-session-runtime.js +1 -1
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +13 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +120 -11
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +619 -289
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-guidance.d.ts.map +1 -1
- package/dist/core/auth-guidance.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/bug-report-upload.d.ts.map +1 -1
- package/dist/core/bug-report-upload.js.map +1 -1
- package/dist/core/bug-report.d.ts +1 -1
- package/dist/core/bug-report.d.ts.map +1 -1
- package/dist/core/bug-report.js +1 -1
- package/dist/core/bug-report.js.map +1 -1
- package/dist/core/cache-stats.d.ts.map +1 -1
- package/dist/core/cache-stats.js.map +1 -1
- package/dist/core/cache-warmer.d.ts.map +1 -1
- package/dist/core/cache-warmer.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +10 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +71 -33
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/index.d.ts.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/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/defaults.d.ts.map +1 -1
- package/dist/core/diagnostics.d.ts.map +1 -1
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js.map +1 -1
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
- package/dist/core/export-html/ansi-to-html.js.map +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.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/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/jiti-loader.d.ts.map +1 -1
- package/dist/core/extensions/jiti-static-loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +55 -5
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +18 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +99 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +296 -22
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/virtual-modules.d.ts.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/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/keybindings.d.ts +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +1 -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 +157 -0
- package/dist/core/mcp-servers.js.map +1 -0
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js.map +1 -1
- 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/models-store.d.ts.map +1 -1
- package/dist/core/models-store.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 +178 -0
- package/dist/core/nested-tool-calls.js.map +1 -0
- package/dist/core/output-guard.d.ts.map +1 -1
- package/dist/core/output-guard.js.map +1 -1
- 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 +59 -12
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-client-cli-adapter.d.ts.map +1 -1
- package/dist/core/pi-client-cli-adapter.js.map +1 -1
- package/dist/core/pi-client-runtime-update.d.ts.map +1 -1
- package/dist/core/pi-client-runtime-update.js.map +1 -1
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/pi-server-client.d.ts +5 -0
- package/dist/core/pi-server-client.d.ts.map +1 -1
- package/dist/core/pi-server-client.js +3 -0
- package/dist/core/pi-server-client.js.map +1 -1
- package/dist/core/pi-server-protocol.d.ts +2 -1
- package/dist/core/pi-server-protocol.d.ts.map +1 -1
- package/dist/core/pi-server-protocol.js +16 -0
- package/dist/core/pi-server-protocol.js.map +1 -1
- package/dist/core/pi-server-request.d.ts.map +1 -1
- package/dist/core/pi-server-request.js.map +1 -1
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.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/radius.d.ts.map +1 -1
- package/dist/core/radius.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/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.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 +161 -35
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-credentials.d.ts.map +1 -1
- package/dist/core/runtime-credentials.js.map +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +24 -6
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-cwd.d.ts.map +1 -1
- package/dist/core/session-cwd.js.map +1 -1
- package/dist/core/session-export.d.ts.map +1 -1
- package/dist/core/session-export.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-diagnostics.d.ts.map +1 -1
- package/dist/core/settings-diagnostics.js.map +1 -1
- package/dist/core/settings-manager.d.ts +31 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +72 -2
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.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.d.ts.map +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/bash.d.ts +12 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +35 -2
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- 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.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/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.js.map +1 -1
- package/dist/core/tools/powershell.d.ts.map +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.map +1 -1
- package/dist/core/tools/render-utils.d.ts +6 -0
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +26 -0
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/renderers/bash.d.ts.map +1 -1
- package/dist/core/tools/renderers/bash.js +9 -10
- 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.map +1 -1
- package/dist/core/tools/renderers/find.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/core/tools/renderers/index.d.ts.map +1 -1
- package/dist/core/tools/renderers/index.js.map +1 -1
- package/dist/core/tools/renderers/ls.d.ts.map +1 -1
- 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 +3 -2
- package/dist/core/tools/renderers/read.js.map +1 -1
- package/dist/core/tools/renderers/write.d.ts.map +1 -1
- package/dist/core/tools/renderers/write.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts +5 -3
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +3 -1
- 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/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.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 +2 -0
- package/dist/core/usage-totals.d.ts.map +1 -1
- package/dist/core/usage-totals.js +23 -0
- 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 +31 -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/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/index.d.ts.map +1 -1
- package/dist/extensions/index.js +11 -1
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/llama/client.d.ts.map +1 -1
- package/dist/extensions/llama/client.js.map +1 -1
- package/dist/extensions/llama/huggingface.d.ts.map +1 -1
- package/dist/extensions/llama/huggingface.js.map +1 -1
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/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/llama/ui.d.ts.map +1 -1
- package/dist/extensions/llama/ui.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 +902 -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 +66 -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 +333 -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 +388 -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 +172 -0
- package/dist/extensions/mcp/ui.js.map +1 -0
- 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 +15 -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 +210 -0
- package/dist/extensions/tool-search/tool.js.map +1 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- 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/migrations.d.ts.map +1 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/interactive/bug-report.d.ts.map +1 -1
- package/dist/modes/interactive/bug-report.js.map +1 -1
- package/dist/modes/interactive/chat-viewport.d.ts.map +1 -1
- package/dist/modes/interactive/chat-viewport.js.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.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/countdown-timer.d.ts.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-entry.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/dist/modes/interactive/components/diff.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.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 +43 -3
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
- package/dist/modes/interactive/components/mermaid.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.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/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- 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/settings-submenu.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.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 +29 -0
- package/dist/modes/interactive/components/themed-text.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +2 -2
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/trust-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +11 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +199 -161
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -1
- package/dist/modes/interactive/model-catalog-refresh.js.map +1 -1
- package/dist/modes/interactive/model-search.d.ts.map +1 -1
- package/dist/modes/interactive/model-search.js.map +1 -1
- package/dist/modes/interactive/session-share.d.ts.map +1 -1
- package/dist/modes/interactive/session-share.js.map +1 -1
- 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 +127 -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 +66 -39
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +238 -317
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- 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/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/jsonl.d.ts.map +1 -1
- package/dist/modes/rpc/jsonl.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/pi-client-cli.d.ts.map +1 -1
- package/dist/pi-client-cli.js.map +1 -1
- package/dist/rpc-entry.d.ts.map +1 -1
- package/dist/rpc-entry.js.map +1 -1
- package/dist/utils/abort.d.ts.map +1 -1
- package/dist/utils/abort.js.map +1 -1
- package/dist/utils/ansi.d.ts.map +1 -1
- package/dist/utils/ansi.js.map +1 -1
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/clipboard-command.d.ts.map +1 -1
- package/dist/utils/clipboard-command.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/deprecation.d.ts.map +1 -1
- package/dist/utils/deprecation.js.map +1 -1
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js.map +1 -1
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/html.d.ts.map +1 -1
- package/dist/utils/html.js.map +1 -1
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-process.d.ts.map +1 -1
- package/dist/utils/image-process.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts.map +1 -1
- package/dist/utils/image-resize-core.js.map +1 -1
- package/dist/utils/image-resize-worker.d.ts.map +1 -1
- package/dist/utils/image-resize-worker.js.map +1 -1
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/json.d.ts.map +1 -1
- package/dist/utils/json.js.map +1 -1
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/mime.d.ts.map +1 -1
- package/dist/utils/mime.js.map +1 -1
- package/dist/utils/open-browser.d.ts.map +1 -1
- package/dist/utils/open-browser.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/photon.d.ts.map +1 -1
- package/dist/utils/photon.js.map +1 -1
- package/dist/utils/pi-user-agent.d.ts.map +1 -1
- package/dist/utils/pi-user-agent.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/dist/utils/sleep.d.ts.map +1 -1
- package/dist/utils/sleep.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +2 -0
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/text.d.ts.map +1 -1
- package/dist/utils/text.js.map +1 -1
- package/dist/utils/tool-result-images.d.ts.map +1 -1
- package/dist/utils/tool-result-images.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/windows-self-update.d.ts.map +1 -1
- package/dist/utils/windows-self-update.js.map +1 -1
- package/dist/utils/wsl.d.ts.map +1 -1
- package/dist/utils/wsl.js.map +1 -1
- package/dist/utils/zip.d.ts.map +1 -1
- package/dist/utils/zip.js.map +1 -1
- package/docs/cli.md +64 -3
- package/docs/configuration.md +2 -0
- package/docs/custom-provider.md +43 -4
- package/docs/docs.json +8 -0
- package/docs/extensions.md +55 -0
- package/docs/keybindings.md +1 -1
- package/docs/llama-cpp.md +13 -0
- package/docs/mcp.md +188 -0
- package/docs/models.md +35 -0
- package/docs/packages.md +4 -2
- package/docs/providers.md +1 -0
- package/docs/rpc-commands.md +9 -3
- package/docs/rpc.md +3 -1
- package/docs/sdk.md +7 -2
- package/docs/security.md +2 -0
- package/docs/session-format.md +5 -1
- package/docs/settings.md +20 -3
- package/docs/themes.md +33 -7
- package/docs/tui.md +18 -0
- 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 +5 -5
- 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 +2 -1
- package/package.json +14 -12
- package/dist/bundle/chunks/anthropic-messages-J5WXPPPC.js +0 -6
- package/dist/bundle/chunks/azure-openai-responses-QJ7SPP5M.js +0 -2
- package/dist/bundle/chunks/chunk-6R7UI4IY.js +0 -2
- package/dist/bundle/chunks/chunk-CGLIERPR.js +0 -2
- package/dist/bundle/chunks/chunk-G4PLSCJV.js +0 -1669
- package/dist/bundle/chunks/chunk-NUHFSC37.js +0 -25
- package/dist/bundle/chunks/chunk-RCZIEVGO.js +0 -11
- package/dist/bundle/chunks/google-generative-ai-IMS5EK2Y.js +0 -2
- package/dist/bundle/chunks/google-vertex-O4YJEQUW.js +0 -2
- package/dist/bundle/chunks/mistral-conversations-NOSQHBEY.js +0 -5
- package/dist/bundle/chunks/openai-responses-AH7QTG23.js +0 -2
- package/dist/bundle/chunks/virtual-modules-LRIRMGSI.js +0 -2
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
16
16
|
import { basename, dirname } from "node:path";
|
|
17
|
+
import { runToolCall, } from "@earendil-works/pi-agent-core";
|
|
17
18
|
import { contentText, getCurrentSystemMessage, normalizeContext, retryDelayMs } from "@earendil-works/pi-ai";
|
|
18
19
|
import { clampThinkingLevel, cleanupSessionResources, getSupportedThinkingLevels, isContextOverflow, isRecoverableLength, isRetryableAssistantError, modelsAreEqual, resetApiProviders, streamSimple, } from "@earendil-works/pi-ai/compat";
|
|
19
20
|
import { getThemeByName, theme } from "../modes/interactive/theme/theme.js";
|
|
@@ -33,15 +34,18 @@ 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";
|
|
38
|
+
import { cancelPiServerOperations, compactPiServer, hashStaticContext, } from "./pi-server-client.js";
|
|
39
|
+
import { hashPiServerProviderMessages } from "./pi-server-protocol.js";
|
|
37
40
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
38
41
|
import { CURRENT_SESSION_VERSION, getLatestCompactionEntry, SessionManager, } from "./session-manager.js";
|
|
39
|
-
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
42
|
+
import { BUILTIN_PATH_PREFIX, createSyntheticSourceInfo, isSyntheticPath } from "./source-info.js";
|
|
40
43
|
import { buildSystemPrompt, buildSystemPromptSections, diffSystemPromptSections, normalizeBuildSystemPromptOptions, } from "./system-prompt.js";
|
|
41
44
|
import { createLocalBashOperations } from "./tools/bash.js";
|
|
42
45
|
import { createAllToolDefinitions } from "./tools/index.js";
|
|
43
46
|
import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
|
|
44
|
-
import { addUsageToTotals, createUsageTotals } from "./usage-totals.js";
|
|
47
|
+
import { addUsageToTotals, combineUsage, createUsageTotals } from "./usage-totals.js";
|
|
48
|
+
import { findLatestResponse, getBranchSelection, getVirtualModelState, isVirtualModel, VIRTUAL_MODEL_STATE_ENTRY, } from "./virtual-models.js";
|
|
45
49
|
/**
|
|
46
50
|
* Parse a skill block from message text.
|
|
47
51
|
* Returns null if the text doesn't contain a skill block.
|
|
@@ -195,12 +199,18 @@ export class AgentSession {
|
|
|
195
199
|
_prePromptCompletionPromise = undefined;
|
|
196
200
|
_overflowRecoveryAttempted = false;
|
|
197
201
|
_lastServerCompactionTimestamp = undefined;
|
|
202
|
+
_cachePrefixUnavailableReason;
|
|
198
203
|
// Branch summarization state
|
|
199
204
|
_branchSummaryAbortController = undefined;
|
|
200
205
|
_branchSummaryCompletionPromise = undefined;
|
|
201
206
|
// Retry state
|
|
202
207
|
_retryAbortController = undefined;
|
|
203
208
|
_retryAttempt = 0;
|
|
209
|
+
/**
|
|
210
|
+
* Failed response that the next request repeats, set by auto-retry and overflow recovery. The
|
|
211
|
+
* retry is routed with it as `failed`, since the context no longer contains it.
|
|
212
|
+
*/
|
|
213
|
+
_failedResponse;
|
|
204
214
|
// Post-turn session naming is a provider request too, so cancellation must reach it.
|
|
205
215
|
_sessionNameAbortController = undefined;
|
|
206
216
|
// Bash execution state
|
|
@@ -242,6 +252,10 @@ export class AgentSession {
|
|
|
242
252
|
_cacheWarmer;
|
|
243
253
|
// Tool registry for extension getTools/setTools
|
|
244
254
|
_toolRegistry = new Map();
|
|
255
|
+
/** Created on the first `ctx.executeTool()` call. */
|
|
256
|
+
_nestedToolCalls;
|
|
257
|
+
/** Declared tools whose declarations requests leave out, from `prepareLoadout` hooks. */
|
|
258
|
+
_hiddenDeclarations = new Set();
|
|
245
259
|
_toolDefinitions = new Map();
|
|
246
260
|
_toolPromptSnippets = new Map();
|
|
247
261
|
_toolPromptGuidelines = new Map();
|
|
@@ -278,6 +292,7 @@ export class AgentSession {
|
|
|
278
292
|
this._installAgentNextTurnRefresh();
|
|
279
293
|
this._installAgentRequestProjection();
|
|
280
294
|
this._installAgentBoundaryHooks();
|
|
295
|
+
this._installHiddenDeclarationsProjection();
|
|
281
296
|
this._installAgentForcedPromptProjection();
|
|
282
297
|
this._buildRuntime({
|
|
283
298
|
activeToolNames: this._initialActiveToolNames,
|
|
@@ -328,28 +343,71 @@ export class AgentSession {
|
|
|
328
343
|
}
|
|
329
344
|
throw new Error(formatNoApiKeyFoundMessage(model.provider));
|
|
330
345
|
}
|
|
331
|
-
async _getSummarizationRequestAuth(
|
|
346
|
+
async _getSummarizationRequestAuth(selectedModel, signal) {
|
|
347
|
+
// Route a virtual model first: summaries size their input and output from the model they get.
|
|
348
|
+
const { model, thinkingLevel } = isVirtualModel(selectedModel)
|
|
349
|
+
? await this._modelRuntime.resolveModel(selectedModel, convertToLlm(this.messages), {
|
|
350
|
+
reason: "direct",
|
|
351
|
+
thinkingLevel: this.thinkingLevel,
|
|
352
|
+
signal,
|
|
353
|
+
})
|
|
354
|
+
: { model: selectedModel, thinkingLevel: this.thinkingLevel };
|
|
332
355
|
if (this.agent.streamFunction === streamSimple) {
|
|
333
|
-
return this._getRequiredRequestAuth(model, signal);
|
|
356
|
+
return { ...(await this._getRequiredRequestAuth(model, signal)), thinkingLevel };
|
|
334
357
|
}
|
|
335
358
|
try {
|
|
336
359
|
const result = await this._modelRuntime.getAuth(model, { signal });
|
|
337
360
|
if (!result)
|
|
338
|
-
return { model };
|
|
361
|
+
return { model, thinkingLevel };
|
|
339
362
|
const requestModel = result.auth.baseUrl ? { ...model, baseUrl: result.auth.baseUrl } : model;
|
|
340
363
|
return {
|
|
341
364
|
model: requestModel,
|
|
342
365
|
apiKey: result.auth.apiKey,
|
|
343
366
|
headers: withoutDeletedHeaders(result.auth.headers),
|
|
344
367
|
env: result.env,
|
|
368
|
+
thinkingLevel,
|
|
345
369
|
};
|
|
346
370
|
}
|
|
347
371
|
catch (error) {
|
|
348
372
|
if (signal?.aborted)
|
|
349
373
|
throw error;
|
|
350
|
-
return { model };
|
|
374
|
+
return { model, thinkingLevel };
|
|
351
375
|
}
|
|
352
376
|
}
|
|
377
|
+
/**
|
|
378
|
+
* The model whose limits apply to `message`, or undefined when the message came from another
|
|
379
|
+
* model. Under a virtual selection, that is the physical model that produced it.
|
|
380
|
+
*/
|
|
381
|
+
_modelForMessage(message) {
|
|
382
|
+
const model = this.model;
|
|
383
|
+
if (model && isVirtualModel(model))
|
|
384
|
+
return this._modelRuntime.getPhysicalModel(message.provider, message.model);
|
|
385
|
+
return model?.provider === message.provider && model.id === message.model ? model : undefined;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Record the selection on the current branch when the branch implies another one, so a resume
|
|
389
|
+
* restores it. Tree navigation can leave the latest `model_change` on another branch; responses
|
|
390
|
+
* cannot record a virtual selection because they name physical models. Responses do record a
|
|
391
|
+
* physical selection unless the branch holds a virtual one; checking a physical selection against
|
|
392
|
+
* responses would record it on every prompt while `prepareRequest` redirects to another model.
|
|
393
|
+
*/
|
|
394
|
+
_recordSelection() {
|
|
395
|
+
const model = this.model;
|
|
396
|
+
if (!model)
|
|
397
|
+
return;
|
|
398
|
+
const getModel = (provider, modelId) => this._modelRuntime.getModel(provider, modelId);
|
|
399
|
+
const recorded = getBranchSelection(this.sessionManager.getBranch(), getModel);
|
|
400
|
+
if (!recorded || (recorded.provider === model.provider && recorded.modelId === model.id))
|
|
401
|
+
return;
|
|
402
|
+
const recordedModel = getModel(recorded.provider, recorded.modelId);
|
|
403
|
+
if (!isVirtualModel(model) && !(recordedModel && isVirtualModel(recordedModel)))
|
|
404
|
+
return;
|
|
405
|
+
this.sessionManager.appendModelChange(model.provider, model.id);
|
|
406
|
+
}
|
|
407
|
+
/** The model whose limits apply to the conversation. */
|
|
408
|
+
_limitsModel() {
|
|
409
|
+
return this.routedModel?.model ?? this.model;
|
|
410
|
+
}
|
|
353
411
|
/**
|
|
354
412
|
* Install tool hooks once on the Agent instance.
|
|
355
413
|
*
|
|
@@ -359,67 +417,114 @@ export class AgentSession {
|
|
|
359
417
|
* happens here instead of in wrappers.
|
|
360
418
|
*/
|
|
361
419
|
_installAgentToolHooks() {
|
|
362
|
-
this.agent.beforeToolCall =
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
}
|
|
379
|
-
throw new Error(`Extension failed, blocking execution: ${String(err)}`);
|
|
380
|
-
}
|
|
381
|
-
};
|
|
382
|
-
this.agent.afterToolCall = async ({ toolCall, args, result, isError }) => {
|
|
383
|
-
const runner = this._extensionRunner;
|
|
384
|
-
const hookResult = runner.hasHandlers("tool_result")
|
|
385
|
-
? await runner.emitToolResult({
|
|
386
|
-
type: "tool_result",
|
|
387
|
-
toolName: toolCall.name,
|
|
388
|
-
toolCallId: toolCall.id,
|
|
389
|
-
input: args,
|
|
390
|
-
content: result.content,
|
|
391
|
-
details: result.details,
|
|
392
|
-
isError,
|
|
393
|
-
usage: result.usage,
|
|
394
|
-
})
|
|
395
|
-
: undefined;
|
|
396
|
-
const content = hookResult?.content ?? result.content ?? [];
|
|
397
|
-
// Runs after the extension hook so images injected or replaced by extensions are normalized too.
|
|
398
|
-
const resizeOptions = this.model?.inputLimits?.images?.resize;
|
|
399
|
-
const normalizedContent = await normalizeToolResultImages(content, {
|
|
400
|
-
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
401
|
-
...(resizeOptions ? { resizeOptions } : {}),
|
|
420
|
+
this.agent.beforeToolCall = (context) => this._beforeToolCall(context);
|
|
421
|
+
this.agent.afterToolCall = (context) => this._afterToolCall(context);
|
|
422
|
+
}
|
|
423
|
+
/** `tool_call` handlers. `parentToolCallId` is set for calls another tool made. */
|
|
424
|
+
async _beforeToolCall({ toolCall, args }, parentToolCallId) {
|
|
425
|
+
const runner = this._extensionRunner;
|
|
426
|
+
if (!runner.hasHandlers("tool_call")) {
|
|
427
|
+
return undefined;
|
|
428
|
+
}
|
|
429
|
+
try {
|
|
430
|
+
return await runner.emitToolCall({
|
|
431
|
+
type: "tool_call",
|
|
432
|
+
toolName: toolCall.name,
|
|
433
|
+
toolCallId: toolCall.id,
|
|
434
|
+
...(parentToolCallId ? { parentToolCallId } : {}),
|
|
435
|
+
input: args,
|
|
402
436
|
});
|
|
403
|
-
|
|
404
|
-
|
|
437
|
+
}
|
|
438
|
+
catch (err) {
|
|
439
|
+
if (err instanceof Error) {
|
|
440
|
+
throw err;
|
|
405
441
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
442
|
+
throw new Error(`Extension failed, blocking execution: ${String(err)}`);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
/** `tool_result` handlers and image normalization. `parentToolCallId` is set for calls another tool made. */
|
|
446
|
+
async _afterToolCall({ toolCall, args, result, isError }, parentToolCallId) {
|
|
447
|
+
const runner = this._extensionRunner;
|
|
448
|
+
const hookResult = runner.hasHandlers("tool_result")
|
|
449
|
+
? await runner.emitToolResult({
|
|
450
|
+
type: "tool_result",
|
|
451
|
+
toolName: toolCall.name,
|
|
452
|
+
toolCallId: toolCall.id,
|
|
453
|
+
...(parentToolCallId ? { parentToolCallId } : {}),
|
|
454
|
+
input: args,
|
|
455
|
+
content: result.content,
|
|
456
|
+
details: result.details,
|
|
457
|
+
...(result.structuredContent === undefined ? {} : { structuredContent: result.structuredContent }),
|
|
458
|
+
isError,
|
|
459
|
+
usage: result.usage,
|
|
460
|
+
})
|
|
461
|
+
: undefined;
|
|
462
|
+
const content = hookResult?.content ?? result.content ?? [];
|
|
463
|
+
// Runs after the extension hook so images injected or replaced by extensions are normalized too.
|
|
464
|
+
const resizeOptions = this._limitsModel()?.inputLimits?.images?.resize;
|
|
465
|
+
const normalizedContent = await normalizeToolResultImages(content, {
|
|
466
|
+
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
467
|
+
...(resizeOptions ? { resizeOptions } : {}),
|
|
468
|
+
});
|
|
469
|
+
if (!hookResult && normalizedContent === content) {
|
|
470
|
+
return undefined;
|
|
471
|
+
}
|
|
472
|
+
// The hook result already dropped structured content that replaced content no longer matches.
|
|
473
|
+
return {
|
|
474
|
+
content: normalizedContent,
|
|
475
|
+
details: hookResult?.details,
|
|
476
|
+
structuredContent: hookResult ? hookResult.structuredContent : result.structuredContent,
|
|
477
|
+
isError: hookResult?.isError ?? isError,
|
|
478
|
+
usage: hookResult?.usage,
|
|
412
479
|
};
|
|
413
480
|
}
|
|
481
|
+
/**
|
|
482
|
+
* Run a call that the tool call `parentToolCallId` made through `ctx.executeTool()`. It goes
|
|
483
|
+
* through the agent's tool pipeline with the session's hooks, against the callable tools.
|
|
484
|
+
*/
|
|
485
|
+
async _executeNestedToolCall(parentToolCallId, name, args, options) {
|
|
486
|
+
this._nestedToolCalls ??= new NestedToolCallRunner({
|
|
487
|
+
getTools: () => this._getCallableTools(),
|
|
488
|
+
isSequential: () => this.agent.toolExecution === "sequential",
|
|
489
|
+
runToolCall: (toolCall, parentId, signal, onUpdate) => {
|
|
490
|
+
const assistantMessage = this._findLastAssistantMessage();
|
|
491
|
+
if (!assistantMessage) {
|
|
492
|
+
return Promise.resolve({
|
|
493
|
+
toolCall,
|
|
494
|
+
result: { content: [{ type: "text", text: "No assistant message issued this call" }], details: {} },
|
|
495
|
+
isError: true,
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
return runToolCall(toolCall, {
|
|
499
|
+
tools: this._getCallableTools(),
|
|
500
|
+
assistantMessage,
|
|
501
|
+
context: { messages: this.agent.state.messages, tools: this.agent.state.tools },
|
|
502
|
+
beforeToolCall: (context) => this._beforeToolCall(context, parentId),
|
|
503
|
+
afterToolCall: (context) => this._afterToolCall(context, parentId),
|
|
504
|
+
signal,
|
|
505
|
+
onUpdate,
|
|
506
|
+
});
|
|
507
|
+
},
|
|
508
|
+
emit: async (event) => {
|
|
509
|
+
await this._extensionRunner.emit(event);
|
|
510
|
+
this._emit(event);
|
|
511
|
+
},
|
|
512
|
+
});
|
|
513
|
+
return this._nestedToolCalls.execute(parentToolCallId, name, args, options);
|
|
514
|
+
}
|
|
515
|
+
/** Whether `projection`, the current session projection, exceeds the compaction threshold of `model`. */
|
|
516
|
+
_exceedsCompactionThreshold(model, projection) {
|
|
517
|
+
if (model.contextWindow <= 0)
|
|
518
|
+
return false;
|
|
519
|
+
return shouldCompact(estimateProjectedContextTokens(projection, this.sessionManager.getBranch()).tokens, model.contextWindow, this.settingsManager.getCompactionSettings(this.model));
|
|
520
|
+
}
|
|
414
521
|
async _compactBeforeNextAssistantResponse(context, signal) {
|
|
415
522
|
if (signal?.aborted)
|
|
416
523
|
return context;
|
|
417
|
-
const model = this.model;
|
|
418
|
-
const settings = this.settingsManager.getCompactionSettings(model);
|
|
419
524
|
const projection = this.sessionManager.buildSessionProjection();
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
525
|
+
// A virtual selection is checked in prepareRequest, against the model the request is routed to.
|
|
526
|
+
const model = this.model;
|
|
527
|
+
if (!model || isVirtualModel(model) || !this._exceedsCompactionThreshold(model, projection)) {
|
|
423
528
|
return { ...context, messages: projection.messages };
|
|
424
529
|
}
|
|
425
530
|
await this._runAutoCompaction("threshold", false, undefined, undefined, signal);
|
|
@@ -427,25 +532,58 @@ export class AgentSession {
|
|
|
427
532
|
}
|
|
428
533
|
_installAgentRequestProjection() {
|
|
429
534
|
const previousPrepareRequest = this.agent.prepareRequest;
|
|
535
|
+
if (previousPrepareRequest)
|
|
536
|
+
this._cachePrefixUnavailableReason ??= "custom_prepare_request";
|
|
430
537
|
this.agent.prepareRequest = async (request, signal) => {
|
|
431
|
-
const
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
538
|
+
const failed = this._failedResponse;
|
|
539
|
+
this._failedResponse = undefined;
|
|
540
|
+
const prepare = async () => {
|
|
541
|
+
const projection = this.sessionManager.buildSessionProjection();
|
|
542
|
+
const canonicalContext = {
|
|
543
|
+
...request.context,
|
|
544
|
+
messages: projection.messages,
|
|
545
|
+
// Messages declare the provider-visible loadout; context.tools keeps executable implementations.
|
|
546
|
+
tools: this.agent.state.tools.slice(),
|
|
547
|
+
};
|
|
548
|
+
const previous = await previousPrepareRequest?.({
|
|
549
|
+
...request,
|
|
550
|
+
context: canonicalContext,
|
|
551
|
+
model: this.agent.state.model,
|
|
552
|
+
thinkingLevel: this.agent.state.thinkingLevel,
|
|
553
|
+
}, signal);
|
|
554
|
+
return { previous, context: previous?.context ?? canonicalContext, projection };
|
|
448
555
|
};
|
|
556
|
+
let { previous, context, projection } = await prepare();
|
|
557
|
+
const model = previous?.model ?? this.agent.state.model;
|
|
558
|
+
const thinkingLevel = previous?.thinkingLevel ?? this.agent.state.thinkingLevel;
|
|
559
|
+
if (!isVirtualModel(model))
|
|
560
|
+
return { ...previous, context, model, thinkingLevel };
|
|
561
|
+
// The selection stays in agent state; only this request uses the routed model. A routing
|
|
562
|
+
// failure rejects, which ends the run with an error response. Only messages the user wrote
|
|
563
|
+
// start a turn; extension messages can follow them, e.g. from before_agent_start.
|
|
564
|
+
const lastResponse = context.messages.findLastIndex((message) => message.role === "assistant");
|
|
565
|
+
const userTurn = context.messages.slice(lastResponse + 1).some((message) => message.role === "user");
|
|
566
|
+
const state = getVirtualModelState(this.sessionManager.getBranch(), model.provider, model.id);
|
|
567
|
+
const route = await this._modelRuntime.resolveModel(model, convertToLlm(context.messages), {
|
|
568
|
+
reason: failed ? "retry" : userTurn ? "user" : "continuation",
|
|
569
|
+
thinkingLevel,
|
|
570
|
+
signal,
|
|
571
|
+
failed,
|
|
572
|
+
state,
|
|
573
|
+
});
|
|
574
|
+
if (route.state !== undefined && route.state !== state) {
|
|
575
|
+
const data = { provider: model.provider, modelId: model.id, state: route.state };
|
|
576
|
+
const entry = this.sessionManager.getEntry(this.sessionManager.appendCustomEntry(VIRTUAL_MODEL_STATE_ENTRY, data));
|
|
577
|
+
if (entry)
|
|
578
|
+
this._emit({ type: "entry_appended", entry });
|
|
579
|
+
}
|
|
580
|
+
// The route stands: the router already decided this request. The state entry does not change
|
|
581
|
+
// the projection.
|
|
582
|
+
if (this._exceedsCompactionThreshold(route.model, projection)) {
|
|
583
|
+
await this._runAutoCompaction("threshold", false, undefined, undefined, signal);
|
|
584
|
+
({ previous, context } = await prepare());
|
|
585
|
+
}
|
|
586
|
+
return { ...previous, context, model: route.model, thinkingLevel: route.thinkingLevel };
|
|
449
587
|
};
|
|
450
588
|
}
|
|
451
589
|
async _dispatchTurnEndBoundary(message, toolResults) {
|
|
@@ -501,19 +639,17 @@ export class AgentSession {
|
|
|
501
639
|
? async (_turn, signal) => await this.agent.prepareNextTurn?.(signal)
|
|
502
640
|
: undefined);
|
|
503
641
|
this.agent.prepareNextTurnWithContext = async (turn, signal) => {
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
? await this._compactBeforeNextAssistantResponse(projectedTurn.context, signal)
|
|
516
|
-
: (compactedContext ?? projectedTurn.context);
|
|
642
|
+
const compactedContext = await this._compactBeforeNextProviderRequest(turn, signal);
|
|
643
|
+
let context;
|
|
644
|
+
if (!signal?.aborted && compactedContext) {
|
|
645
|
+
context = compactedContext;
|
|
646
|
+
}
|
|
647
|
+
else if (!signal?.aborted && compactedContext === undefined) {
|
|
648
|
+
context = await this._compactBeforeNextAssistantResponse(turn.context, signal);
|
|
649
|
+
}
|
|
650
|
+
else {
|
|
651
|
+
context = { ...turn.context, messages: this.sessionManager.buildSessionProjection().messages };
|
|
652
|
+
}
|
|
517
653
|
const nextTurn = { ...turn, context };
|
|
518
654
|
const previousSnapshot = await previousPrepareNextTurnWithContext?.(nextTurn, signal);
|
|
519
655
|
const nextContext = previousSnapshot?.context ?? context;
|
|
@@ -683,6 +819,21 @@ export class AgentSession {
|
|
|
683
819
|
}
|
|
684
820
|
/** Internal handler for agent events - shared by subscribe and reconnect */
|
|
685
821
|
_handleAgentEvent = async (event, _signal) => {
|
|
822
|
+
// Record the calls a tool made through ctx.executeTool() and their usage on its result message.
|
|
823
|
+
if (this._nestedToolCalls) {
|
|
824
|
+
if (event.type === "message_start" && event.message.role === "toolResult") {
|
|
825
|
+
const message = event.message;
|
|
826
|
+
const summary = this._nestedToolCalls.takeRecord(message.toolCallId);
|
|
827
|
+
if (summary?.calls)
|
|
828
|
+
message.nestedCalls = summary.calls;
|
|
829
|
+
if (summary?.usage) {
|
|
830
|
+
message.usage = message.usage ? combineUsage(message.usage, summary.usage) : summary.usage;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
else if (event.type === "agent_end") {
|
|
834
|
+
this._nestedToolCalls.clear();
|
|
835
|
+
}
|
|
836
|
+
}
|
|
686
837
|
// When a user message starts, check if it's from either queue and remove it BEFORE emitting
|
|
687
838
|
// This ensures the UI sees the updated queue state
|
|
688
839
|
if (event.type === "message_start" && event.message.role === "user") {
|
|
@@ -1080,6 +1231,14 @@ export class AgentSession {
|
|
|
1080
1231
|
get thinkingLevel() {
|
|
1081
1232
|
return this.agent.state.thinkingLevel;
|
|
1082
1233
|
}
|
|
1234
|
+
/** Under a virtual selection, the physical model and thinking level of the latest successful response. */
|
|
1235
|
+
get routedModel() {
|
|
1236
|
+
if (!this.model || !isVirtualModel(this.model))
|
|
1237
|
+
return undefined;
|
|
1238
|
+
const latest = findLatestResponse(this.agent.state.messages);
|
|
1239
|
+
const model = latest && this._modelRuntime.getPhysicalModel(latest.provider, latest.model);
|
|
1240
|
+
return model && { model, thinkingLevel: latest?.thinkingLevel };
|
|
1241
|
+
}
|
|
1083
1242
|
/** Whether the session is currently processing an agent run or post-run continuation. */
|
|
1084
1243
|
get isStreaming() {
|
|
1085
1244
|
return this._isAgentRunActive;
|
|
@@ -1105,12 +1264,16 @@ export class AgentSession {
|
|
|
1105
1264
|
return this._retryAttempt;
|
|
1106
1265
|
}
|
|
1107
1266
|
/**
|
|
1108
|
-
* Get the names of currently active tools.
|
|
1109
|
-
*
|
|
1267
|
+
* Get the names of currently active tools, which are the tools declared to the model.
|
|
1268
|
+
* Tools with `codemode` or `deferred` exposure are callable from other tools without being active.
|
|
1110
1269
|
*/
|
|
1111
1270
|
getActiveToolNames() {
|
|
1112
1271
|
return this.agent.state.tools.map((t) => t.name);
|
|
1113
1272
|
}
|
|
1273
|
+
/** Get the names of the tools that tools can call through `ctx.executeTool()`. */
|
|
1274
|
+
getCallableToolNames() {
|
|
1275
|
+
return this._getCallableTools().map((t) => t.name);
|
|
1276
|
+
}
|
|
1114
1277
|
/**
|
|
1115
1278
|
* Get all configured tools with name, description, parameter schema, prompt guidelines, and source metadata.
|
|
1116
1279
|
*/
|
|
@@ -1120,6 +1283,9 @@ export class AgentSession {
|
|
|
1120
1283
|
description: definition.description,
|
|
1121
1284
|
parameters: definition.parameters,
|
|
1122
1285
|
promptGuidelines: definition.promptGuidelines,
|
|
1286
|
+
exposure: this._getToolExposure(definition.name),
|
|
1287
|
+
...(definition.namespace ? { namespace: definition.namespace } : {}),
|
|
1288
|
+
...(definition.annotations ? { annotations: { ...definition.annotations } } : {}),
|
|
1123
1289
|
sourceInfo,
|
|
1124
1290
|
}));
|
|
1125
1291
|
}
|
|
@@ -1128,22 +1294,79 @@ export class AgentSession {
|
|
|
1128
1294
|
}
|
|
1129
1295
|
/**
|
|
1130
1296
|
* Set active tools by name.
|
|
1131
|
-
* Only tools in the registry can be enabled. Unknown tool names are ignored.
|
|
1297
|
+
* Only tools in the registry can be enabled. Unknown and hidden tool names are ignored.
|
|
1132
1298
|
* Also rebuilds the system prompt to reflect the new tool set.
|
|
1133
1299
|
* Changes take effect on the next agent turn.
|
|
1134
1300
|
*/
|
|
1135
1301
|
setActiveToolsByName(toolNames) {
|
|
1136
|
-
const tools =
|
|
1137
|
-
|
|
1138
|
-
|
|
1302
|
+
const tools = this._applyToolLoadout(toolNames);
|
|
1303
|
+
this._rebuildSystemPrompt(tools.map((tool) => tool.name));
|
|
1304
|
+
}
|
|
1305
|
+
_getToolExposure(name) {
|
|
1306
|
+
return this._toolDefinitions.get(name)?.definition.exposure ?? "direct";
|
|
1307
|
+
}
|
|
1308
|
+
/**
|
|
1309
|
+
* Tools callable through `ctx.executeTool()`: the active `direct` tools and every registered
|
|
1310
|
+
* `codemode` or `deferred` tool.
|
|
1311
|
+
*/
|
|
1312
|
+
_getCallableTools(active = new Set(this.getActiveToolNames())) {
|
|
1313
|
+
return [...this._toolRegistry.values()].filter((tool) => {
|
|
1314
|
+
const exposure = this._getToolExposure(tool.name);
|
|
1315
|
+
return exposure === "codemode" || exposure === "deferred" || (exposure === "direct" && active.has(tool.name));
|
|
1316
|
+
});
|
|
1317
|
+
}
|
|
1318
|
+
/**
|
|
1319
|
+
* Set the agent's tools for the given active tool names and return them. The active tools are
|
|
1320
|
+
* the registered, non-hidden ones; they are declared to the model. Active tools with a
|
|
1321
|
+
* `prepareLoadout` hook can change the declared descriptions and hide declarations from
|
|
1322
|
+
* requests (see {@link _installHiddenDeclarationsProjection}).
|
|
1323
|
+
*/
|
|
1324
|
+
_applyToolLoadout(toolNames) {
|
|
1325
|
+
const tools = [...new Set(toolNames)].flatMap((name) => {
|
|
1139
1326
|
const tool = this._toolRegistry.get(name);
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1327
|
+
return tool && this._getToolExposure(name) !== "hidden" ? [tool] : [];
|
|
1328
|
+
});
|
|
1329
|
+
const hooks = tools.flatMap((tool) => {
|
|
1330
|
+
const entry = this._toolDefinitions.get(tool.name);
|
|
1331
|
+
return entry?.definition.prepareLoadout ? [entry] : [];
|
|
1332
|
+
});
|
|
1333
|
+
const hidden = new Set();
|
|
1334
|
+
let declared = tools;
|
|
1335
|
+
if (hooks.length > 0) {
|
|
1336
|
+
const loadout = {
|
|
1337
|
+
declared: tools,
|
|
1338
|
+
callable: this._getCallableTools(new Set(tools.map((tool) => tool.name))),
|
|
1339
|
+
registered: [...this._toolRegistry.values()],
|
|
1340
|
+
getExposure: (name) => this._getToolExposure(name),
|
|
1341
|
+
getNamespace: (name) => this._toolDefinitions.get(name)?.definition.namespace,
|
|
1342
|
+
};
|
|
1343
|
+
const descriptions = new Map();
|
|
1344
|
+
for (const { definition, sourceInfo } of hooks) {
|
|
1345
|
+
try {
|
|
1346
|
+
const changes = definition.prepareLoadout?.(loadout);
|
|
1347
|
+
for (const [name, description] of Object.entries(changes?.descriptions ?? {})) {
|
|
1348
|
+
descriptions.set(name, description);
|
|
1349
|
+
}
|
|
1350
|
+
for (const name of changes?.hiddenDeclarations ?? [])
|
|
1351
|
+
hidden.add(name);
|
|
1352
|
+
}
|
|
1353
|
+
catch (error) {
|
|
1354
|
+
this._extensionRunner.emitError({
|
|
1355
|
+
extensionPath: sourceInfo.path,
|
|
1356
|
+
event: "prepare_loadout",
|
|
1357
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1358
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
1359
|
+
});
|
|
1360
|
+
}
|
|
1143
1361
|
}
|
|
1362
|
+
declared = tools.map((tool) => {
|
|
1363
|
+
const description = descriptions.get(tool.name);
|
|
1364
|
+
return description === undefined ? tool : { ...tool, description };
|
|
1365
|
+
});
|
|
1144
1366
|
}
|
|
1145
|
-
this.
|
|
1146
|
-
this.
|
|
1367
|
+
this._hiddenDeclarations = hidden;
|
|
1368
|
+
this.agent.state.tools = declared;
|
|
1369
|
+
return declared;
|
|
1147
1370
|
}
|
|
1148
1371
|
/** Whether compaction or branch summarization is currently running */
|
|
1149
1372
|
get isCompacting() {
|
|
@@ -1244,11 +1467,7 @@ export class AgentSession {
|
|
|
1244
1467
|
* {@link _installAgentForcedPromptProjection}.
|
|
1245
1468
|
*/
|
|
1246
1469
|
_preparePromptAndToolLoadout(options, messages = this.agent.state.messages) {
|
|
1247
|
-
options.selectedTools =
|
|
1248
|
-
this.agent.state.tools = options.selectedTools.flatMap((name) => {
|
|
1249
|
-
const tool = this._toolRegistry.get(name);
|
|
1250
|
-
return tool ? [tool] : [];
|
|
1251
|
-
});
|
|
1470
|
+
options.selectedTools = this._applyToolLoadout(options.selectedTools).map((tool) => tool.name);
|
|
1252
1471
|
const sections = diffSystemPromptSections(getCurrentSystemMessage(messages)?.sections ?? {}, buildSystemPromptSections(options));
|
|
1253
1472
|
return sections ? { role: "system", content: "", sections, timestamp: Date.now() } : undefined;
|
|
1254
1473
|
}
|
|
@@ -1262,8 +1481,36 @@ export class AgentSession {
|
|
|
1262
1481
|
* collapse into one head holding the forced text and the current tools. Runs after the
|
|
1263
1482
|
* `context` extension handlers.
|
|
1264
1483
|
*/
|
|
1484
|
+
/**
|
|
1485
|
+
* Remove the declarations that `prepareLoadout` hooks hide from every request. The whole
|
|
1486
|
+
* transcript is filtered with the current set, so the projected declarations stay consistent
|
|
1487
|
+
* across requests and only change when the loadout does.
|
|
1488
|
+
*/
|
|
1489
|
+
_installHiddenDeclarationsProjection() {
|
|
1490
|
+
const previousTransformContext = this.agent.transformContext;
|
|
1491
|
+
this.agent.transformContext = async (messages, signal) => {
|
|
1492
|
+
const transformed = previousTransformContext ? await previousTransformContext(messages, signal) : messages;
|
|
1493
|
+
const hidden = this._hiddenDeclarations;
|
|
1494
|
+
if (hidden.size === 0)
|
|
1495
|
+
return transformed;
|
|
1496
|
+
return transformed.map((message) => {
|
|
1497
|
+
if (message.role !== "system" || (!message.toolsAdded && !message.toolsRemoved))
|
|
1498
|
+
return message;
|
|
1499
|
+
const { toolsAdded, toolsRemoved, ...rest } = message;
|
|
1500
|
+
const added = toolsAdded?.filter((tool) => !hidden.has(tool.name)) ?? [];
|
|
1501
|
+
const removed = toolsRemoved?.filter((tool) => !hidden.has(tool.name)) ?? [];
|
|
1502
|
+
return {
|
|
1503
|
+
...rest,
|
|
1504
|
+
...(added.length > 0 ? { toolsAdded: added } : {}),
|
|
1505
|
+
...(removed.length > 0 ? { toolsRemoved: removed } : {}),
|
|
1506
|
+
};
|
|
1507
|
+
});
|
|
1508
|
+
};
|
|
1509
|
+
}
|
|
1265
1510
|
_installAgentForcedPromptProjection() {
|
|
1266
1511
|
const previousTransformContext = this.agent.transformContext;
|
|
1512
|
+
if (previousTransformContext)
|
|
1513
|
+
this._cachePrefixUnavailableReason ??= "custom_context_transform";
|
|
1267
1514
|
this.agent.transformContext = async (messages, signal) => {
|
|
1268
1515
|
const transformed = previousTransformContext ? await previousTransformContext(messages, signal) : messages;
|
|
1269
1516
|
const forced = this._runSystemPromptOptions?.forceSystemPrompt;
|
|
@@ -1279,25 +1526,25 @@ export class AgentSession {
|
|
|
1279
1526
|
return [head, ...transformed.filter((message) => message.role !== "system")];
|
|
1280
1527
|
};
|
|
1281
1528
|
}
|
|
1282
|
-
/**
|
|
1529
|
+
/**
|
|
1530
|
+
* Restore the active tool loadout declared by the session transcript, if it declares one.
|
|
1531
|
+
* Tools reachable only from other tools are never declared, but they do not depend on the active
|
|
1532
|
+
* set, so the transcript's declarations are the whole loadout.
|
|
1533
|
+
*/
|
|
1283
1534
|
_restoreToolsFromTranscript() {
|
|
1284
1535
|
const current = getCurrentSystemMessage(this.sessionManager.buildSessionContext().messages);
|
|
1285
1536
|
if (!current)
|
|
1286
1537
|
return;
|
|
1287
|
-
|
|
1288
|
-
.map((tool) => tool.name)
|
|
1289
|
-
.filter((name) => this._toolRegistry.has(name));
|
|
1290
|
-
this.agent.state.tools = toolNames.flatMap((name) => {
|
|
1291
|
-
const registered = this._toolRegistry.get(name);
|
|
1292
|
-
return registered ? [registered] : [];
|
|
1293
|
-
});
|
|
1294
|
-
this._rebuildSystemPrompt(toolNames);
|
|
1538
|
+
this.setActiveToolsByName((current.toolsAdded ?? []).map((tool) => tool.name));
|
|
1295
1539
|
}
|
|
1296
1540
|
// =========================================================================
|
|
1297
1541
|
// Prompting
|
|
1298
1542
|
// =========================================================================
|
|
1299
1543
|
async _runAgentOperation(start) {
|
|
1300
1544
|
this._agentRunAbortRequested = false;
|
|
1545
|
+
// Compaction before the prompt may have scheduled a retry; the new prompt replaces it.
|
|
1546
|
+
this._failedResponse = undefined;
|
|
1547
|
+
this._recordSelection();
|
|
1301
1548
|
this._isAgentRunActive = true;
|
|
1302
1549
|
try {
|
|
1303
1550
|
await start();
|
|
@@ -1333,6 +1580,7 @@ export class AgentSession {
|
|
|
1333
1580
|
finally {
|
|
1334
1581
|
if (this._agentRunAbortRequested)
|
|
1335
1582
|
this._finishCancelledRetry();
|
|
1583
|
+
this._failedResponse = undefined;
|
|
1336
1584
|
this._runSystemPromptOptions = undefined;
|
|
1337
1585
|
this._flushPendingBashMessages();
|
|
1338
1586
|
this._flushPendingCustomMessages();
|
|
@@ -1433,6 +1681,7 @@ export class AgentSession {
|
|
|
1433
1681
|
if (this._isRetryableError(message) && (await this._prepareRetry(message))) {
|
|
1434
1682
|
if (this._agentRunAbortRequested)
|
|
1435
1683
|
this._finishCancelledRetry();
|
|
1684
|
+
this._failedResponse = message;
|
|
1436
1685
|
return !this._agentRunAbortRequested;
|
|
1437
1686
|
}
|
|
1438
1687
|
if (this._agentRunAbortRequested) {
|
|
@@ -1506,7 +1755,7 @@ export class AgentSession {
|
|
|
1506
1755
|
for (const image of images) {
|
|
1507
1756
|
const processed = await processImage(Buffer.from(image.data, "base64"), image.mimeType, {
|
|
1508
1757
|
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
1509
|
-
resizeOptions: this.
|
|
1758
|
+
resizeOptions: this._limitsModel()?.inputLimits?.images?.resize,
|
|
1510
1759
|
});
|
|
1511
1760
|
if (!processed.ok) {
|
|
1512
1761
|
hints.push(processed.message);
|
|
@@ -1533,152 +1782,140 @@ export class AgentSession {
|
|
|
1533
1782
|
}
|
|
1534
1783
|
const expandPromptTemplates = options?.expandPromptTemplates ?? true;
|
|
1535
1784
|
const preflightResult = options?.preflightResult;
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
if (
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
// Extension command executed, no prompt to send
|
|
1544
|
-
preflightResult?.(true);
|
|
1545
|
-
return;
|
|
1546
|
-
}
|
|
1547
|
-
}
|
|
1548
|
-
if (this._compactionAbortController !== undefined && !this._isAborting) {
|
|
1549
|
-
throw new Error("Cannot submit a prompt while compaction is in progress. Wait for compaction to finish and retry.");
|
|
1550
|
-
}
|
|
1551
|
-
// Emit input event for extension interception (before skill/template expansion)
|
|
1552
|
-
const processedInput = await this._runInputHandlers(text, options?.images, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
|
|
1553
|
-
if (!processedInput) {
|
|
1554
|
-
preflightResult?.(true);
|
|
1785
|
+
// Handle extension commands first (execute immediately, even during streaming)
|
|
1786
|
+
// Extension commands manage their own LLM interaction via pi.sendMessage()
|
|
1787
|
+
if (expandPromptTemplates && text.startsWith("/")) {
|
|
1788
|
+
const handled = await this._tryExecuteExtensionCommand(text);
|
|
1789
|
+
if (handled) {
|
|
1790
|
+
// Extension command executed, no prompt to send
|
|
1791
|
+
preflightResult?.("handled");
|
|
1555
1792
|
return;
|
|
1556
1793
|
}
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1794
|
+
}
|
|
1795
|
+
if (this._compactionAbortController !== undefined && !this._isAborting) {
|
|
1796
|
+
throw new Error("Cannot submit a prompt while compaction is in progress. Wait for compaction to finish and retry.");
|
|
1797
|
+
}
|
|
1798
|
+
// Emit input event for extension interception (before skill/template expansion)
|
|
1799
|
+
const processedInput = await this._runInputHandlers(text, options?.images, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
|
|
1800
|
+
if (!processedInput) {
|
|
1801
|
+
preflightResult?.("handled");
|
|
1802
|
+
return;
|
|
1803
|
+
}
|
|
1804
|
+
const { text: currentText, images: currentImages } = processedInput;
|
|
1805
|
+
// Expand skill commands (/skill:name args) and prompt templates (/template args)
|
|
1806
|
+
let expandedText = currentText;
|
|
1807
|
+
if (expandPromptTemplates) {
|
|
1808
|
+
expandedText = this._expandSkillCommand(expandedText);
|
|
1809
|
+
expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
|
|
1810
|
+
}
|
|
1811
|
+
// If streaming, queue via steer() or followUp() based on option
|
|
1812
|
+
if (this.isStreaming || this._isAborting) {
|
|
1813
|
+
if (!options?.streamingBehavior) {
|
|
1814
|
+
throw new Error("Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.");
|
|
1577
1815
|
}
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
this._flushPendingCustomMessages();
|
|
1581
|
-
// Validate model
|
|
1582
|
-
if (!this.model) {
|
|
1583
|
-
throw new Error(formatNoModelSelectedMessage());
|
|
1816
|
+
if (options.streamingBehavior === "followUp") {
|
|
1817
|
+
await this._queueFollowUp(expandedText, currentImages);
|
|
1584
1818
|
}
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
if (!hasConfiguredAuth) {
|
|
1588
|
-
const isOAuth = this._modelRuntime.isUsingOAuth(this.model.provider);
|
|
1589
|
-
if (isOAuth) {
|
|
1590
|
-
throw new Error(`Authentication failed for "${this.model.provider}". ` +
|
|
1591
|
-
`Credentials may have expired or network is unavailable. ` +
|
|
1592
|
-
`Run '/login ${this.model.provider}' to re-authenticate.`);
|
|
1593
|
-
}
|
|
1594
|
-
throw new Error(formatNoApiKeyFoundMessage(this.model.provider));
|
|
1819
|
+
else {
|
|
1820
|
+
await this._queueSteer(expandedText, currentImages);
|
|
1595
1821
|
}
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1822
|
+
preflightResult?.("queued");
|
|
1823
|
+
return;
|
|
1824
|
+
}
|
|
1825
|
+
// Flush any pending bash and custom messages before the new prompt
|
|
1826
|
+
this._flushPendingBashMessages();
|
|
1827
|
+
this._flushPendingCustomMessages();
|
|
1828
|
+
// Validate model
|
|
1829
|
+
if (!this.model) {
|
|
1830
|
+
throw new Error(formatNoModelSelectedMessage());
|
|
1831
|
+
}
|
|
1832
|
+
const hasConfiguredAuth = this._modelRuntime.hasConfiguredAuth(this.model.provider) ||
|
|
1833
|
+
(await this._modelRuntime.checkAuth(this.model.provider)) !== undefined;
|
|
1834
|
+
if (!hasConfiguredAuth) {
|
|
1835
|
+
const isOAuth = this._modelRuntime.isUsingOAuth(this.model.provider);
|
|
1836
|
+
if (isOAuth) {
|
|
1837
|
+
throw new Error(`Authentication failed for "${this.model.provider}". ` +
|
|
1838
|
+
`Credentials may have expired or network is unavailable. ` +
|
|
1839
|
+
`Run '/login ${this.model.provider}' to re-authenticate.`);
|
|
1601
1840
|
}
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1841
|
+
throw new Error(formatNoApiKeyFoundMessage(this.model.provider));
|
|
1842
|
+
}
|
|
1843
|
+
// Check if we need to compact before sending (catches aborted responses).
|
|
1844
|
+
// The user's new prompt is sent below, so do not call agent.continue() here.
|
|
1845
|
+
if (this._isAborting) {
|
|
1846
|
+
return;
|
|
1847
|
+
}
|
|
1848
|
+
const lastAssistant = this._findLastAssistantMessage();
|
|
1849
|
+
if (lastAssistant) {
|
|
1850
|
+
const prePromptAbortController = new AbortController();
|
|
1851
|
+
let resolvePrePromptCompletion;
|
|
1852
|
+
const prePromptCompletion = new Promise((resolve) => {
|
|
1853
|
+
resolvePrePromptCompletion = resolve;
|
|
1854
|
+
});
|
|
1855
|
+
this._prePromptAbortController = prePromptAbortController;
|
|
1856
|
+
this._prePromptCompletionPromise = prePromptCompletion;
|
|
1857
|
+
try {
|
|
1858
|
+
await this._checkCompaction(lastAssistant, false, [], prePromptAbortController.signal);
|
|
1859
|
+
}
|
|
1860
|
+
finally {
|
|
1861
|
+
if (this._prePromptAbortController === prePromptAbortController) {
|
|
1862
|
+
this._prePromptAbortController = undefined;
|
|
1622
1863
|
}
|
|
1623
|
-
if (
|
|
1624
|
-
|
|
1625
|
-
return;
|
|
1864
|
+
if (this._prePromptCompletionPromise === prePromptCompletion) {
|
|
1865
|
+
this._prePromptCompletionPromise = undefined;
|
|
1626
1866
|
}
|
|
1867
|
+
resolvePrePromptCompletion?.();
|
|
1627
1868
|
}
|
|
1628
|
-
if (
|
|
1629
|
-
|
|
1869
|
+
if (prePromptAbortController.signal.aborted || this._isAborting) {
|
|
1870
|
+
return;
|
|
1630
1871
|
}
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1872
|
+
}
|
|
1873
|
+
if (isPiServerMode()) {
|
|
1874
|
+
this._detachPiServerTerminalAssistantFailure();
|
|
1875
|
+
}
|
|
1876
|
+
// Emit before_agent_start before normalizing images so extension-driven model
|
|
1877
|
+
// selection determines the resize profile used for the request and history.
|
|
1878
|
+
const selectedToolsBefore = this._baseSystemPromptOptions.selectedTools;
|
|
1879
|
+
const result = await this._extensionRunner.emitBeforeAgentStart(expandedText, currentImages, this._baseSystemPromptOptions);
|
|
1880
|
+
// Handlers may edit event.systemPromptOptions.selectedTools or call setActiveTools(),
|
|
1881
|
+
// which updates the live loadout instead. An explicit edit wins; otherwise the live
|
|
1882
|
+
// loadout is authoritative, so a setActiveTools() call is not undone here.
|
|
1883
|
+
const handlerEditedTools = result.systemPromptOptions.selectedTools.length !== selectedToolsBefore.length ||
|
|
1884
|
+
result.systemPromptOptions.selectedTools.some((name, index) => name !== selectedToolsBefore[index]);
|
|
1885
|
+
if (!handlerEditedTools)
|
|
1886
|
+
result.systemPromptOptions.selectedTools = this.getActiveToolNames();
|
|
1887
|
+
const normalized = await this._normalizePromptImages(currentImages);
|
|
1888
|
+
const userText = normalized.hints.length > 0 ? `${expandedText}\n\n${normalized.hints.join("\n")}` : expandedText;
|
|
1889
|
+
// Build messages only after hooks and image normalization have completed.
|
|
1890
|
+
const messages = [];
|
|
1891
|
+
const userContent = [{ type: "text", text: userText }];
|
|
1892
|
+
userContent.push(...normalized.images);
|
|
1893
|
+
messages.push({
|
|
1894
|
+
role: "user",
|
|
1895
|
+
content: userContent,
|
|
1896
|
+
timestamp: Date.now(),
|
|
1897
|
+
});
|
|
1898
|
+
// Inject any pending "nextTurn" messages as context alongside the user message
|
|
1899
|
+
for (const msg of this._pendingNextTurnMessages) {
|
|
1900
|
+
messages.push(msg);
|
|
1901
|
+
}
|
|
1902
|
+
this._pendingNextTurnMessages = [];
|
|
1903
|
+
for (const msg of result.messages) {
|
|
1648
1904
|
messages.push({
|
|
1649
|
-
role: "
|
|
1650
|
-
|
|
1905
|
+
role: "custom",
|
|
1906
|
+
customType: msg.customType,
|
|
1907
|
+
// Untyped extensions can pass null/missing content; normalize at ingestion.
|
|
1908
|
+
content: msg.content ?? [],
|
|
1909
|
+
display: msg.display,
|
|
1910
|
+
details: msg.details,
|
|
1651
1911
|
timestamp: Date.now(),
|
|
1652
1912
|
});
|
|
1653
|
-
// Inject any pending "nextTurn" messages as context alongside the user message
|
|
1654
|
-
for (const msg of this._pendingNextTurnMessages) {
|
|
1655
|
-
messages.push(msg);
|
|
1656
|
-
}
|
|
1657
|
-
this._pendingNextTurnMessages = [];
|
|
1658
|
-
for (const msg of result.messages) {
|
|
1659
|
-
messages.push({
|
|
1660
|
-
role: "custom",
|
|
1661
|
-
customType: msg.customType,
|
|
1662
|
-
// Untyped extensions can pass null/missing content; normalize at ingestion.
|
|
1663
|
-
content: msg.content ?? [],
|
|
1664
|
-
display: msg.display,
|
|
1665
|
-
details: msg.details,
|
|
1666
|
-
timestamp: Date.now(),
|
|
1667
|
-
});
|
|
1668
|
-
}
|
|
1669
|
-
const updateMessage = this._preparePromptAndToolLoadout(result.systemPromptOptions);
|
|
1670
|
-
this._runSystemPromptOptions = result.systemPromptOptions;
|
|
1671
|
-
if (updateMessage)
|
|
1672
|
-
messages.unshift(updateMessage);
|
|
1673
1913
|
}
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
return;
|
|
1680
|
-
}
|
|
1681
|
-
preflightResult?.(true);
|
|
1914
|
+
const updateMessage = this._preparePromptAndToolLoadout(result.systemPromptOptions);
|
|
1915
|
+
this._runSystemPromptOptions = result.systemPromptOptions;
|
|
1916
|
+
if (updateMessage)
|
|
1917
|
+
messages.unshift(updateMessage);
|
|
1918
|
+
preflightResult?.("started");
|
|
1682
1919
|
await this._runAgentPrompt(messages);
|
|
1683
1920
|
}
|
|
1684
1921
|
/**
|
|
@@ -1744,7 +1981,7 @@ export class AgentSession {
|
|
|
1744
1981
|
}
|
|
1745
1982
|
const processedInput = await this._runInputHandlers(text, images, source, this.isStreaming ? behavior : undefined);
|
|
1746
1983
|
if (!processedInput)
|
|
1747
|
-
return;
|
|
1984
|
+
return "handled";
|
|
1748
1985
|
let expandedText = this._expandSkillCommand(processedInput.text);
|
|
1749
1986
|
expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
|
|
1750
1987
|
if (behavior === "steer") {
|
|
@@ -1753,6 +1990,7 @@ export class AgentSession {
|
|
|
1753
1990
|
else {
|
|
1754
1991
|
await this._queueFollowUp(expandedText, processedInput.images);
|
|
1755
1992
|
}
|
|
1993
|
+
return "queued";
|
|
1756
1994
|
}
|
|
1757
1995
|
/**
|
|
1758
1996
|
* Queue a steering message while the agent is running.
|
|
@@ -1764,7 +2002,7 @@ export class AgentSession {
|
|
|
1764
2002
|
* @throws Error if text is an extension command
|
|
1765
2003
|
*/
|
|
1766
2004
|
async steer(text, images, options) {
|
|
1767
|
-
|
|
2005
|
+
return this._queueUserInput(text, images, "steer", options?.source ?? "interactive");
|
|
1768
2006
|
}
|
|
1769
2007
|
/**
|
|
1770
2008
|
* Queue a follow-up message to be processed after the agent finishes.
|
|
@@ -1775,7 +2013,7 @@ export class AgentSession {
|
|
|
1775
2013
|
* @throws Error if text is an extension command
|
|
1776
2014
|
*/
|
|
1777
2015
|
async followUp(text, images, options) {
|
|
1778
|
-
|
|
2016
|
+
return this._queueUserInput(text, images, "followUp", options?.source ?? "interactive");
|
|
1779
2017
|
}
|
|
1780
2018
|
/**
|
|
1781
2019
|
* Internal: Queue a steering message (already expanded, no extension command check).
|
|
@@ -2280,6 +2518,58 @@ export class AgentSession {
|
|
|
2280
2518
|
// =========================================================================
|
|
2281
2519
|
// Compaction
|
|
2282
2520
|
// =========================================================================
|
|
2521
|
+
async _buildCompactionCacheInput(model, preparation) {
|
|
2522
|
+
if (this._cachePrefixUnavailableReason)
|
|
2523
|
+
return { reason: this._cachePrefixUnavailableReason };
|
|
2524
|
+
if (this.agent.onPayload)
|
|
2525
|
+
return { reason: "request_payload_hook_active" };
|
|
2526
|
+
if (this._runSystemPromptOptions?.forceSystemPrompt !== undefined) {
|
|
2527
|
+
return { reason: "forced_system_prompt_active" };
|
|
2528
|
+
}
|
|
2529
|
+
const activeModel = this.agent.state.model;
|
|
2530
|
+
if (!modelsAreEqual(model, activeModel) ||
|
|
2531
|
+
model.api !== activeModel.api ||
|
|
2532
|
+
model.baseUrl !== activeModel.baseUrl) {
|
|
2533
|
+
return { reason: "summary_model_mismatch" };
|
|
2534
|
+
}
|
|
2535
|
+
if (!this.agent.sessionId)
|
|
2536
|
+
return { reason: "session_id_unavailable" };
|
|
2537
|
+
const projectedMessages = this.sessionManager.buildSessionProjection().messages;
|
|
2538
|
+
if (JSON.stringify(projectedMessages) !== JSON.stringify(this.agent.state.messages)) {
|
|
2539
|
+
return { reason: "request_context_mismatch" };
|
|
2540
|
+
}
|
|
2541
|
+
const fullMessages = await this.agent.convertToLlm(projectedMessages);
|
|
2542
|
+
const fullContext = normalizeContext({ messages: fullMessages });
|
|
2543
|
+
const cacheOptions = {
|
|
2544
|
+
sessionId: this.agent.sessionId,
|
|
2545
|
+
transport: this.agent.transport,
|
|
2546
|
+
thinkingBudgets: this.agent.thinkingBudgets,
|
|
2547
|
+
maxRetryDelayMs: this.agent.maxRetryDelayMs,
|
|
2548
|
+
};
|
|
2549
|
+
if (!preparation) {
|
|
2550
|
+
return {
|
|
2551
|
+
cacheContextHash: hashPiServerProviderMessages(fullMessages),
|
|
2552
|
+
cacheStaticContextHash: hashStaticContext({
|
|
2553
|
+
systemPrompt: this.systemPrompt,
|
|
2554
|
+
tools: this.agent.state.tools,
|
|
2555
|
+
messages: [],
|
|
2556
|
+
}),
|
|
2557
|
+
cacheOptions,
|
|
2558
|
+
reason: "exact_prefix_unavailable",
|
|
2559
|
+
};
|
|
2560
|
+
}
|
|
2561
|
+
const prefixMessages = await this.agent.convertToLlm(preparation.cachePrefixMessages);
|
|
2562
|
+
const cachePrefixContext = normalizeContext({ messages: prefixMessages });
|
|
2563
|
+
if (cachePrefixContext.messages.length > fullContext.messages.length ||
|
|
2564
|
+
cachePrefixContext.messages.some((message, index) => JSON.stringify(message) !== JSON.stringify(fullContext.messages[index]))) {
|
|
2565
|
+
return { reason: "projected_prefix_mismatch" };
|
|
2566
|
+
}
|
|
2567
|
+
return {
|
|
2568
|
+
cachePrefixContext,
|
|
2569
|
+
cacheOptions,
|
|
2570
|
+
reason: "exact_prefix_unavailable",
|
|
2571
|
+
};
|
|
2572
|
+
}
|
|
2283
2573
|
async _applyPiServerCompactionResult(result, reason, willRetry) {
|
|
2284
2574
|
this.sessionManager.replaceTree(result.entries, result.leafId);
|
|
2285
2575
|
const sessionContext = this.sessionManager.buildSessionContext();
|
|
@@ -2335,22 +2625,27 @@ export class AgentSession {
|
|
|
2335
2625
|
throw new Error(formatNoModelSelectedMessage());
|
|
2336
2626
|
}
|
|
2337
2627
|
const settings = this.settingsManager.getCompactionSettings(model);
|
|
2338
|
-
const { model: requestModel, apiKey, headers, env, } = await this._getSummarizationRequestAuth(model, this._compactionAbortController.signal);
|
|
2339
2628
|
if (isPiServerMode()) {
|
|
2629
|
+
const { model: requestModel, apiKey, headers, thinkingLevel, } = await this._getSummarizationRequestAuth(model, this._compactionAbortController.signal);
|
|
2340
2630
|
this._detachPiServerTerminalAssistantFailure();
|
|
2631
|
+
const cacheInput = await this._buildCompactionCacheInput(requestModel);
|
|
2341
2632
|
const piServerResult = await compactPiServer(requestModel, {
|
|
2342
2633
|
systemPrompt: this.systemPrompt,
|
|
2343
2634
|
messages: this.agent.state.messages,
|
|
2344
2635
|
tools: this.agent.state.tools,
|
|
2345
2636
|
}, {
|
|
2637
|
+
...cacheInput.cacheOptions,
|
|
2346
2638
|
sessionId: this.sessionId,
|
|
2347
2639
|
apiKey,
|
|
2348
2640
|
headers,
|
|
2349
2641
|
customInstructions,
|
|
2642
|
+
cacheContextHash: cacheInput.cacheContextHash,
|
|
2643
|
+
cacheStaticContextHash: cacheInput.cacheStaticContextHash,
|
|
2644
|
+
cacheFallbackReason: cacheInput.reason,
|
|
2350
2645
|
settings: this.settingsManager.getCompactionSettings(),
|
|
2351
2646
|
sessionTree: buildPiServerSessionTree(this.sessionManager.getEntries(), this.sessionManager.getLeafId()),
|
|
2352
2647
|
signal: this._compactionAbortController.signal,
|
|
2353
|
-
reasoning: toProviderReasoning(
|
|
2648
|
+
reasoning: toProviderReasoning(thinkingLevel),
|
|
2354
2649
|
onHistoryReconciled: (snapshot) => this.reconcilePiServerHistory(snapshot),
|
|
2355
2650
|
});
|
|
2356
2651
|
const result = await this._applyPiServerCompactionResult(piServerResult, "manual", false);
|
|
@@ -2408,8 +2703,10 @@ export class AgentSession {
|
|
|
2408
2703
|
details = extensionCompaction.details;
|
|
2409
2704
|
}
|
|
2410
2705
|
else {
|
|
2411
|
-
//
|
|
2412
|
-
const
|
|
2706
|
+
// Resolve the request only when Pi summarizes itself: routing may call models or fail.
|
|
2707
|
+
const { model: requestModel, apiKey, headers, env, thinkingLevel, } = await this._getSummarizationRequestAuth(model, this._compactionAbortController.signal);
|
|
2708
|
+
const cacheInput = await this._buildCompactionCacheInput(requestModel, preparation);
|
|
2709
|
+
const result = await compact(preparation, requestModel, apiKey, headers, customInstructions, this._compactionAbortController.signal, thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason: "manual" }), undefined, cacheInput.cachePrefixContext, cacheInput.cacheOptions, cacheInput.reason);
|
|
2413
2710
|
summary = result.summary;
|
|
2414
2711
|
firstKeptEntryId = result.firstKeptEntryId;
|
|
2415
2712
|
tokensBefore = result.tokensBefore;
|
|
@@ -2521,12 +2818,14 @@ export class AgentSession {
|
|
|
2521
2818
|
// Skip if message was aborted (user cancelled) - unless skipAbortedCheck is false
|
|
2522
2819
|
if (skipAbortedCheck && assistantMessage.stopReason === "aborted")
|
|
2523
2820
|
return false;
|
|
2524
|
-
const contextWindow = this.model?.contextWindow ?? 0;
|
|
2525
2821
|
// Skip overflow check if the message came from a different model.
|
|
2526
2822
|
// This handles the case where user switched from a smaller-context model (e.g. opus)
|
|
2527
2823
|
// to a larger-context model (e.g. codex) - the overflow error from the old model
|
|
2528
|
-
// shouldn't trigger compaction for the new model.
|
|
2529
|
-
|
|
2824
|
+
// shouldn't trigger compaction for the new model. Under a virtual selection, the
|
|
2825
|
+
// physical model that produced the message supplies the limits.
|
|
2826
|
+
const messageModel = this._modelForMessage(assistantMessage);
|
|
2827
|
+
const sameModel = messageModel !== undefined;
|
|
2828
|
+
const contextWindow = (messageModel ?? this.model)?.contextWindow ?? 0;
|
|
2530
2829
|
// Skip compaction checks if this assistant message is older than the latest
|
|
2531
2830
|
// compaction boundary. This prevents a stale pre-compaction usage/error
|
|
2532
2831
|
// from retriggering compaction on the first prompt after compaction.
|
|
@@ -2560,7 +2859,7 @@ export class AgentSession {
|
|
|
2560
2859
|
const contextOverflow = sameModel &&
|
|
2561
2860
|
((explicitOverflow && assistantRetainedForExplicitRecovery) ||
|
|
2562
2861
|
(assistantUsageMatchesProjection && isContextOverflow(assistantMessage, contextWindow)));
|
|
2563
|
-
const recoverableLength = sameModel && assistantIsProjected && isRecoverableLength(assistantMessage,
|
|
2862
|
+
const recoverableLength = sameModel && assistantIsProjected && isRecoverableLength(assistantMessage, messageModel.maxTokens);
|
|
2564
2863
|
if (contextOverflow || recoverableLength) {
|
|
2565
2864
|
const willRetry = assistantMessage.stopReason !== "stop";
|
|
2566
2865
|
if (!willRetry) {
|
|
@@ -2585,7 +2884,10 @@ export class AgentSession {
|
|
|
2585
2884
|
this._omitRecoveryAttempt(assistantMessage, toolResults);
|
|
2586
2885
|
if (isPiServerMode())
|
|
2587
2886
|
this._detachPiServerTerminalAssistantFailure();
|
|
2588
|
-
|
|
2887
|
+
const retry = await this._runAutoCompaction("overflow", willRetry, undefined, undefined, externalSignal);
|
|
2888
|
+
if (retry)
|
|
2889
|
+
this._failedResponse = assistantMessage;
|
|
2890
|
+
return retry;
|
|
2589
2891
|
}
|
|
2590
2892
|
// Case 2: Threshold - context is getting large
|
|
2591
2893
|
// For error messages or all-zero usage messages, estimate from the last valid response.
|
|
@@ -2648,21 +2950,26 @@ export class AgentSession {
|
|
|
2648
2950
|
started = true;
|
|
2649
2951
|
this._emit({ type: "compaction_start", reason });
|
|
2650
2952
|
abortController.signal.throwIfAborted();
|
|
2651
|
-
const { model: requestModel, apiKey, headers, } = await this._getSummarizationRequestAuth(model, abortController.signal);
|
|
2953
|
+
const { model: requestModel, apiKey, headers, thinkingLevel, } = await this._getSummarizationRequestAuth(model, abortController.signal);
|
|
2652
2954
|
abortController.signal.throwIfAborted();
|
|
2955
|
+
const cacheInput = await this._buildCompactionCacheInput(requestModel);
|
|
2653
2956
|
const piServerResult = await compactPiServer(requestModel, {
|
|
2654
2957
|
systemPrompt: this.systemPrompt,
|
|
2655
2958
|
messages: this.agent.state.messages,
|
|
2656
2959
|
tools: this.agent.state.tools,
|
|
2657
2960
|
}, {
|
|
2961
|
+
...cacheInput.cacheOptions,
|
|
2658
2962
|
sessionId: this.sessionId,
|
|
2659
2963
|
apiKey,
|
|
2660
2964
|
headers,
|
|
2965
|
+
cacheContextHash: cacheInput.cacheContextHash,
|
|
2966
|
+
cacheStaticContextHash: cacheInput.cacheStaticContextHash,
|
|
2967
|
+
cacheFallbackReason: cacheInput.reason,
|
|
2661
2968
|
settings,
|
|
2662
2969
|
preparation: preparationOptions,
|
|
2663
2970
|
sessionTree: buildPiServerSessionTree(this.sessionManager.getEntries(), this.sessionManager.getLeafId()),
|
|
2664
2971
|
signal: abortController.signal,
|
|
2665
|
-
reasoning: toProviderReasoning(
|
|
2972
|
+
reasoning: toProviderReasoning(thinkingLevel),
|
|
2666
2973
|
onHistoryReconciled: (snapshot) => this.reconcilePiServerHistory(snapshot),
|
|
2667
2974
|
});
|
|
2668
2975
|
if (externalSignal?.aborted || abortController.signal.aborted) {
|
|
@@ -2690,8 +2997,6 @@ export class AgentSession {
|
|
|
2690
2997
|
started = true;
|
|
2691
2998
|
this._emit({ type: "compaction_start", reason });
|
|
2692
2999
|
abortController.signal.throwIfAborted();
|
|
2693
|
-
const { model: requestModel, apiKey, headers, env, } = await this._getSummarizationRequestAuth(model, abortController.signal);
|
|
2694
|
-
abortController.signal.throwIfAborted();
|
|
2695
3000
|
let extensionCompaction;
|
|
2696
3001
|
if (this._extensionRunner.hasHandlers("session_before_compact")) {
|
|
2697
3002
|
const extensionResult = (await this._extensionRunner.emit({
|
|
@@ -2726,7 +3031,10 @@ export class AgentSession {
|
|
|
2726
3031
|
details = extensionCompaction.details;
|
|
2727
3032
|
}
|
|
2728
3033
|
else {
|
|
2729
|
-
const
|
|
3034
|
+
const { model: requestModel, apiKey, headers, env, thinkingLevel, } = await this._getSummarizationRequestAuth(model, abortController.signal);
|
|
3035
|
+
abortController.signal.throwIfAborted();
|
|
3036
|
+
const cacheInput = await this._buildCompactionCacheInput(requestModel, preparation);
|
|
3037
|
+
const compactResult = await compact(preparation, requestModel, apiKey, headers, undefined, abortController.signal, thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }), undefined, cacheInput.cachePrefixContext, cacheInput.cacheOptions, cacheInput.reason);
|
|
2730
3038
|
summary = compactResult.summary;
|
|
2731
3039
|
firstKeptEntryId = compactResult.firstKeptEntryId;
|
|
2732
3040
|
tokensBefore = compactResult.tokensBefore;
|
|
@@ -2823,10 +3131,13 @@ export class AgentSession {
|
|
|
2823
3131
|
return this.settingsManager.getCompactionEnabled();
|
|
2824
3132
|
}
|
|
2825
3133
|
_shouldCompactBeforeNextProviderRequest(turn) {
|
|
3134
|
+
// A virtual selection is checked in prepareRequest, against the model the request is routed to.
|
|
3135
|
+
if (!this.model || isVirtualModel(this.model))
|
|
3136
|
+
return false;
|
|
2826
3137
|
const settings = this.settingsManager.getCompactionSettings(this.model);
|
|
2827
3138
|
if (!settings.enabled || turn.toolResults.length === 0)
|
|
2828
3139
|
return false;
|
|
2829
|
-
const contextWindow = this.model
|
|
3140
|
+
const contextWindow = this.model.contextWindow;
|
|
2830
3141
|
if (contextWindow <= 0)
|
|
2831
3142
|
return false;
|
|
2832
3143
|
const branch = this.sessionManager.getBranch();
|
|
@@ -2927,6 +3238,7 @@ export class AgentSession {
|
|
|
2927
3238
|
}
|
|
2928
3239
|
this._applyExtensionBindings(this._extensionRunner);
|
|
2929
3240
|
await this._extensionRunner.emit(this._sessionStartEvent);
|
|
3241
|
+
this._extensionRunner.reportUnhandledMcpServers();
|
|
2930
3242
|
await this.extendResourcesFromExtensions(this._sessionStartEvent.reason === "reload" ? "reload" : "startup");
|
|
2931
3243
|
}
|
|
2932
3244
|
async extendResourcesFromExtensions(reason) {
|
|
@@ -2948,7 +3260,7 @@ export class AgentSession {
|
|
|
2948
3260
|
buildExtensionResourcePaths(entries) {
|
|
2949
3261
|
return entries.map((entry) => {
|
|
2950
3262
|
const source = this.getExtensionSourceLabel(entry.extensionPath);
|
|
2951
|
-
const baseDir = entry.extensionPath
|
|
3263
|
+
const baseDir = isSyntheticPath(entry.extensionPath) ? undefined : dirname(entry.extensionPath);
|
|
2952
3264
|
return {
|
|
2953
3265
|
path: entry.path,
|
|
2954
3266
|
metadata: {
|
|
@@ -2961,7 +3273,7 @@ export class AgentSession {
|
|
|
2961
3273
|
});
|
|
2962
3274
|
}
|
|
2963
3275
|
getExtensionSourceLabel(extensionPath) {
|
|
2964
|
-
if (extensionPath
|
|
3276
|
+
if (isSyntheticPath(extensionPath)) {
|
|
2965
3277
|
return `extension:${extensionPath.replace(/[<>]/g, "")}`;
|
|
2966
3278
|
}
|
|
2967
3279
|
const base = basename(extensionPath);
|
|
@@ -3046,6 +3358,7 @@ export class AgentSession {
|
|
|
3046
3358
|
},
|
|
3047
3359
|
getActiveTools: () => this.getActiveToolNames(),
|
|
3048
3360
|
getAllTools: () => this.getAllTools(),
|
|
3361
|
+
getSettings: () => this.settingsManager.getSettings(),
|
|
3049
3362
|
setActiveTools: (toolNames) => this.setActiveToolsByName(toolNames),
|
|
3050
3363
|
refreshTools: () => this._refreshToolRegistry(),
|
|
3051
3364
|
getCommands,
|
|
@@ -3089,6 +3402,8 @@ export class AgentSession {
|
|
|
3089
3402
|
},
|
|
3090
3403
|
getSystemPrompt: () => this.systemPrompt,
|
|
3091
3404
|
getSystemPromptOptions: () => this._baseSystemPromptOptions,
|
|
3405
|
+
executeTool: (callerId, name, args, options) => this._executeNestedToolCall(callerId, name, args, options),
|
|
3406
|
+
getCallableTools: () => this._getCallableTools(),
|
|
3092
3407
|
}, {
|
|
3093
3408
|
registerProvider: (name, config) => {
|
|
3094
3409
|
this._modelRuntime.registerProvider(name, config);
|
|
@@ -3102,10 +3417,20 @@ export class AgentSession {
|
|
|
3102
3417
|
this._modelRuntime.unregisterProvider(name);
|
|
3103
3418
|
this._refreshCurrentModelFromRegistry();
|
|
3104
3419
|
},
|
|
3420
|
+
registerVirtualModel: (definition) => {
|
|
3421
|
+
this._modelRuntime.registerVirtualModel(definition);
|
|
3422
|
+
this._refreshCurrentModelFromRegistry();
|
|
3423
|
+
},
|
|
3424
|
+
unregisterVirtualModel: (provider, id) => {
|
|
3425
|
+
this._modelRuntime.unregisterVirtualModel(provider, id);
|
|
3426
|
+
this._refreshCurrentModelFromRegistry();
|
|
3427
|
+
},
|
|
3105
3428
|
});
|
|
3106
3429
|
}
|
|
3107
3430
|
_refreshToolRegistry(options) {
|
|
3108
|
-
|
|
3431
|
+
// Tools that were already activated on registration. A tool whose exposure changes to
|
|
3432
|
+
// `direct` or `model-only` (for example from `hidden`) is activated like a new tool.
|
|
3433
|
+
const previousActivatedOnRegistration = new Set([...this._toolRegistry.keys()].filter((name) => this._isActivatedOnRegistration(name)));
|
|
3109
3434
|
const previousActiveToolNames = this.getActiveToolNames();
|
|
3110
3435
|
const allowedToolNames = this._allowedToolNames;
|
|
3111
3436
|
const excludedToolNames = this._excludedToolNames;
|
|
@@ -3124,7 +3449,7 @@ export class AgentSession {
|
|
|
3124
3449
|
name,
|
|
3125
3450
|
{
|
|
3126
3451
|
definition,
|
|
3127
|
-
sourceInfo: createSyntheticSourceInfo(
|
|
3452
|
+
sourceInfo: createSyntheticSourceInfo(`${BUILTIN_PATH_PREFIX}${name}`, { source: "builtin" }),
|
|
3128
3453
|
},
|
|
3129
3454
|
]));
|
|
3130
3455
|
for (const tool of allCustomTools) {
|
|
@@ -3152,7 +3477,9 @@ export class AgentSession {
|
|
|
3152
3477
|
.filter((definition) => isAllowedTool(definition.name))
|
|
3153
3478
|
.map((definition) => ({
|
|
3154
3479
|
definition,
|
|
3155
|
-
sourceInfo: createSyntheticSourceInfo(
|
|
3480
|
+
sourceInfo: createSyntheticSourceInfo(`${BUILTIN_PATH_PREFIX}${definition.name}`, {
|
|
3481
|
+
source: "builtin",
|
|
3482
|
+
}),
|
|
3156
3483
|
})), runner);
|
|
3157
3484
|
const toolRegistry = new Map(wrappedBuiltInTools.map((tool) => [tool.name, tool]));
|
|
3158
3485
|
for (const tool of wrappedExtensionTools) {
|
|
@@ -3162,25 +3489,36 @@ export class AgentSession {
|
|
|
3162
3489
|
const nextActiveToolNames = (options?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames]).filter((name) => isAllowedTool(name));
|
|
3163
3490
|
if (allowedToolNames) {
|
|
3164
3491
|
for (const toolName of this._toolRegistry.keys()) {
|
|
3165
|
-
|
|
3492
|
+
// Naming a tool activates it even when it is not active by default.
|
|
3493
|
+
if (allowedToolNames.has(toolName) && this._isDeclarable(toolName)) {
|
|
3166
3494
|
nextActiveToolNames.push(toolName);
|
|
3167
3495
|
}
|
|
3168
3496
|
}
|
|
3169
3497
|
}
|
|
3170
3498
|
else if (options?.includeAllExtensionTools) {
|
|
3171
3499
|
for (const tool of wrappedExtensionTools) {
|
|
3172
|
-
|
|
3500
|
+
if (this._isActivatedOnRegistration(tool.name))
|
|
3501
|
+
nextActiveToolNames.push(tool.name);
|
|
3173
3502
|
}
|
|
3174
3503
|
}
|
|
3175
3504
|
else if (!options?.activeToolNames) {
|
|
3176
3505
|
for (const toolName of this._toolRegistry.keys()) {
|
|
3177
|
-
if (!
|
|
3506
|
+
if (!previousActivatedOnRegistration.has(toolName) && this._isActivatedOnRegistration(toolName)) {
|
|
3178
3507
|
nextActiveToolNames.push(toolName);
|
|
3179
3508
|
}
|
|
3180
3509
|
}
|
|
3181
3510
|
}
|
|
3182
3511
|
this.setActiveToolsByName([...new Set(nextActiveToolNames)]);
|
|
3183
3512
|
}
|
|
3513
|
+
/** Whether activating the tool declares it to the model. */
|
|
3514
|
+
_isDeclarable(name) {
|
|
3515
|
+
const exposure = this._getToolExposure(name);
|
|
3516
|
+
return exposure === "direct" || exposure === "model-only";
|
|
3517
|
+
}
|
|
3518
|
+
/** Whether registering the tool activates it, which declares it to the model. */
|
|
3519
|
+
_isActivatedOnRegistration(name) {
|
|
3520
|
+
return this._isDeclarable(name) && this._toolDefinitions.get(name)?.definition.defaultActive !== false;
|
|
3521
|
+
}
|
|
3184
3522
|
_buildRuntime(options) {
|
|
3185
3523
|
const autoResizeImages = this.settingsManager.getImageAutoResize();
|
|
3186
3524
|
const shellCommandPrefix = this.settingsManager.getShellCommandPrefix();
|
|
@@ -3237,6 +3575,7 @@ export class AgentSession {
|
|
|
3237
3575
|
if (hasBindings) {
|
|
3238
3576
|
await options?.beforeSessionStart?.();
|
|
3239
3577
|
await this._extensionRunner.emit({ type: "session_start", reason: "reload" });
|
|
3578
|
+
this._extensionRunner.reportUnhandledMcpServers();
|
|
3240
3579
|
await this.extendResourcesFromExtensions("reload");
|
|
3241
3580
|
}
|
|
3242
3581
|
}
|
|
@@ -3253,7 +3592,7 @@ export class AgentSession {
|
|
|
3253
3592
|
*/
|
|
3254
3593
|
_isRetryableError(message) {
|
|
3255
3594
|
// Context overflow is handled by compaction, not retry.
|
|
3256
|
-
if (isContextOverflow(message, this.model?.contextWindow ?? 0))
|
|
3595
|
+
if (isContextOverflow(message, (this._modelForMessage(message) ?? this.model)?.contextWindow ?? 0))
|
|
3257
3596
|
return false;
|
|
3258
3597
|
if (this._isPostAssistantPiServerSyncFailure(message))
|
|
3259
3598
|
return false;
|
|
@@ -3567,15 +3906,11 @@ export class AgentSession {
|
|
|
3567
3906
|
let summaryDetails;
|
|
3568
3907
|
let summaryUsage;
|
|
3569
3908
|
if (options.summarize && entriesToSummarize.length > 0 && !extensionSummary) {
|
|
3570
|
-
const
|
|
3571
|
-
const { model: requestModel, apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
|
|
3909
|
+
const signal = this._branchSummaryAbortController.signal;
|
|
3572
3910
|
const branchSummarySettings = this.settingsManager.getBranchSummarySettings();
|
|
3573
3911
|
const result = await generateBranchSummary(entriesToSummarize, {
|
|
3574
|
-
model
|
|
3575
|
-
|
|
3576
|
-
headers,
|
|
3577
|
-
env,
|
|
3578
|
-
signal: this._branchSummaryAbortController.signal,
|
|
3912
|
+
...(await this._getSummarizationRequestAuth(this.model, signal)),
|
|
3913
|
+
signal,
|
|
3579
3914
|
customInstructions,
|
|
3580
3915
|
replaceInstructions,
|
|
3581
3916
|
reserveTokens: branchSummarySettings.reserveTokens,
|
|
@@ -3744,7 +4079,7 @@ export class AgentSession {
|
|
|
3744
4079
|
};
|
|
3745
4080
|
}
|
|
3746
4081
|
getContextUsage() {
|
|
3747
|
-
const model = this.
|
|
4082
|
+
const model = this._limitsModel();
|
|
3748
4083
|
if (!model)
|
|
3749
4084
|
return undefined;
|
|
3750
4085
|
const contextWindow = model.contextWindow ?? 0;
|
|
@@ -3838,16 +4173,11 @@ export class AgentSession {
|
|
|
3838
4173
|
if (!model) {
|
|
3839
4174
|
throw new Error("No model selected");
|
|
3840
4175
|
}
|
|
3841
|
-
const { model: requestModel, apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
|
|
3842
4176
|
return generateBugReportSummary({
|
|
4177
|
+
...(await this._getSummarizationRequestAuth(model, options.signal)),
|
|
3843
4178
|
messages: this.messages,
|
|
3844
4179
|
hint: options.hint,
|
|
3845
|
-
model: requestModel,
|
|
3846
|
-
apiKey,
|
|
3847
|
-
headers,
|
|
3848
|
-
env,
|
|
3849
4180
|
signal: options.signal,
|
|
3850
|
-
thinkingLevel: this.thinkingLevel,
|
|
3851
4181
|
streamFn: this.agent.streamFunction,
|
|
3852
4182
|
retry: this.settingsManager.getRetrySettings(),
|
|
3853
4183
|
sessionId: this.sessionId,
|