apex-code 0.0.1-alpha.7 → 0.0.1-alpha.9
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 +229 -0
- package/README.md +5 -0
- package/dist/cli/args.d.ts +4 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +44 -9
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/concurrent-session.d.ts +3 -0
- package/dist/cli/concurrent-session.d.ts.map +1 -0
- package/dist/cli/concurrent-session.js +13 -0
- package/dist/cli/concurrent-session.js.map +1 -0
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -2
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +3 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +21 -13
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +20 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +41 -9
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +172 -101
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +4 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +12 -9
- 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 +10 -9
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +3 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +4 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +41 -32
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/defaults.d.ts +1 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js +9 -0
- package/dist/core/defaults.js.map +1 -1
- package/dist/core/durable-state/sqlite.d.ts.map +1 -1
- package/dist/core/durable-state/sqlite.js +26 -2
- package/dist/core/durable-state/sqlite.js.map +1 -1
- package/dist/core/experimental.d.ts +4 -0
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +4 -0
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +115 -48
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +42 -9
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +3 -0
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts +1 -2
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +2 -17
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/http-idle-timeout.d.ts +12 -0
- package/dist/core/http-idle-timeout.d.ts.map +1 -0
- package/dist/core/http-idle-timeout.js +27 -0
- package/dist/core/http-idle-timeout.js.map +1 -0
- package/dist/core/keybindings.d.ts +38 -13
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +26 -5
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/lsp/client.d.ts +2 -0
- package/dist/core/lsp/client.d.ts.map +1 -1
- package/dist/core/lsp/client.js +27 -2
- package/dist/core/lsp/client.js.map +1 -1
- package/dist/core/model-config.d.ts +10 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +4 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +14 -8
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +2 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +22 -14
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +2 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +2 -1
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +3 -2
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sandbox/child-entry.d.ts.map +1 -1
- package/dist/core/sandbox/child-entry.js +8 -1
- package/dist/core/sandbox/child-entry.js.map +1 -1
- package/dist/core/sandbox/cli-launch.d.ts +3 -0
- package/dist/core/sandbox/cli-launch.d.ts.map +1 -1
- package/dist/core/sandbox/cli-launch.js +25 -4
- package/dist/core/sandbox/cli-launch.js.map +1 -1
- package/dist/core/sandbox/cli-supervisor.d.ts.map +1 -1
- package/dist/core/sandbox/cli-supervisor.js +53 -13
- package/dist/core/sandbox/cli-supervisor.js.map +1 -1
- package/dist/core/sandbox/linux-backend.d.ts.map +1 -1
- package/dist/core/sandbox/linux-backend.js +15 -0
- package/dist/core/sandbox/linux-backend.js.map +1 -1
- package/dist/core/sandbox/macos-backend.d.ts.map +1 -1
- package/dist/core/sandbox/macos-backend.js +24 -1
- package/dist/core/sandbox/macos-backend.js.map +1 -1
- package/dist/core/sandbox/rpc/credential-client.d.ts +20 -0
- package/dist/core/sandbox/rpc/credential-client.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/credential-client.js +170 -0
- package/dist/core/sandbox/rpc/credential-client.js.map +1 -0
- package/dist/core/sandbox/rpc/credential-proxy.d.ts +44 -0
- package/dist/core/sandbox/rpc/credential-proxy.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/credential-proxy.js +381 -0
- package/dist/core/sandbox/rpc/credential-proxy.js.map +1 -0
- package/dist/core/sandbox/supervisor.d.ts +11 -0
- package/dist/core/sandbox/supervisor.d.ts.map +1 -1
- package/dist/core/sandbox/supervisor.js.map +1 -1
- package/dist/core/sandbox/terminal-size.d.ts +40 -0
- package/dist/core/sandbox/terminal-size.d.ts.map +1 -0
- package/dist/core/sandbox/terminal-size.js +105 -0
- package/dist/core/sandbox/terminal-size.js.map +1 -0
- package/dist/core/sdk.d.ts +8 -5
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +26 -7
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-export.d.ts +4 -0
- package/dist/core/session-export.d.ts.map +1 -0
- package/dist/core/session-export.js +32 -0
- package/dist/core/session-export.js.map +1 -0
- package/dist/core/session-lease.d.ts +31 -0
- package/dist/core/session-lease.d.ts.map +1 -0
- package/dist/core/session-lease.js +138 -0
- package/dist/core/session-lease.js.map +1 -0
- package/dist/core/session-manager.d.ts +5 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +5 -4
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-diagnostics.d.ts +9 -0
- package/dist/core/settings-diagnostics.d.ts.map +1 -0
- package/dist/core/settings-diagnostics.js +21 -0
- package/dist/core/settings-diagnostics.js.map +1 -0
- package/dist/core/settings-manager.d.ts +35 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +93 -12
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +51 -33
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +4 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts +2 -2
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +53 -62
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +14 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +38 -20
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +24 -0
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +2 -5
- 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 +22 -4
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +2 -0
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +35 -10
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +4 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +9 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +2 -0
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +5 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/powershell.d.ts +16 -0
- package/dist/core/tools/powershell.d.ts.map +1 -0
- package/dist/core/tools/powershell.js +39 -0
- package/dist/core/tools/powershell.js.map +1 -0
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +2 -0
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/web-search-exa.d.ts +33 -0
- package/dist/core/tools/web-search-exa.d.ts.map +1 -0
- package/dist/core/tools/web-search-exa.js +128 -0
- package/dist/core/tools/web-search-exa.js.map +1 -0
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +2 -0
- 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 +2 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/web-search-provider.d.ts +64 -0
- package/dist/core/web-search-provider.d.ts.map +1 -0
- package/dist/core/web-search-provider.js +149 -0
- package/dist/core/web-search-provider.js.map +1 -0
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +2 -0
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +6 -2
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +5 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +38 -16
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +4 -3
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +23 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +105 -2
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts +7 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js +11 -2
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +4 -0
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +24 -6
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +6 -3
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/first-use-hints.d.ts +8 -0
- package/dist/modes/interactive/components/first-use-hints.d.ts.map +1 -0
- package/dist/modes/interactive/components/first-use-hints.js +22 -0
- package/dist/modes/interactive/components/first-use-hints.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +12 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +128 -9
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +12 -3
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +71 -14
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +10 -3
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +128 -56
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-submenu.js +165 -0
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
- package/dist/modes/interactive/components/splash-header.d.ts +29 -4
- package/dist/modes/interactive/components/splash-header.d.ts.map +1 -1
- package/dist/modes/interactive/components/splash-header.js +58 -23
- package/dist/modes/interactive/components/splash-header.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +74 -17
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +14 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +113 -35
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-panel.d.ts +30 -0
- package/dist/modes/interactive/components/tool-panel.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-panel.js +130 -0
- package/dist/modes/interactive/components/tool-panel.js.map +1 -0
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +55 -9
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +446 -87
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
- package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
- package/dist/modes/interactive/model-catalog-refresh.js +34 -0
- package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
- package/dist/modes/interactive/theme/apex.json +62 -63
- package/dist/modes/interactive/theme/dark.json +2 -0
- package/dist/modes/interactive/theme/light.json +2 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +25 -11
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +9 -1
- package/dist/modes/interactive/theme/theme.d.ts +14 -3
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +60 -10
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +18 -12
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +22 -5
- package/dist/modes/json-event.js.map +1 -1
- package/dist/package-manager-cli.d.ts +1 -0
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +197 -5
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/server/create-harness.d.ts.map +1 -1
- package/dist/server/create-harness.js +2 -0
- package/dist/server/create-harness.js.map +1 -1
- package/dist/themes/apex-logo.d.ts +36 -16
- package/dist/themes/apex-logo.d.ts.map +1 -1
- package/dist/themes/apex-logo.js +32 -28
- package/dist/themes/apex-logo.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/management-http.d.ts +5 -3
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js +14 -10
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/shell.d.ts +3 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +17 -5
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts +1 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +60 -1
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/text.d.ts +8 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -0
- package/dist/utils/tools-manager.d.ts +10 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +15 -20
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/compaction.md +18 -3
- package/docs/custom-provider.md +6 -3
- package/docs/environment-variables.md +1 -0
- package/docs/extensions.md +21 -7
- package/docs/json.md +12 -5
- package/docs/keybindings.md +15 -9
- package/docs/llama-cpp.md +2 -0
- package/docs/models.md +8 -2
- package/docs/packages.md +2 -2
- package/docs/rpc.md +24 -7
- package/docs/sdk.md +16 -2
- package/docs/settings.md +73 -2
- package/docs/skills.md +4 -3
- package/docs/terminal-setup.md +34 -9
- package/docs/themes.md +24 -3
- package/docs/tui.md +2 -2
- package/docs/usage.md +9 -4
- package/docs/windows.md +24 -2
- package/examples/extensions/border-status-editor.ts +1 -1
- 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/git-checkpoint.ts +2 -2
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/notify.ts +3 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/README.md +3 -1
- package/examples/extensions/subagent/agents.ts +40 -9
- package/examples/extensions/subagent/index.ts +27 -4
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/examples/sdk/README.md +1 -1
- package/npm-shrinkwrap.json +280 -445
- package/package.json +9 -11
|
@@ -12,20 +12,19 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Modes use this class and add their own I/O layer on top.
|
|
14
14
|
*/
|
|
15
|
-
import {
|
|
15
|
+
import { readFileSync } from "node:fs";
|
|
16
16
|
import { basename, dirname } from "node:path";
|
|
17
17
|
import { contentText } from "@earendil-works/pi-ai";
|
|
18
18
|
import { clampThinkingLevel, cleanupSessionResources, getSupportedThinkingLevels, isContextOverflow, isRecoverableLength, isRetryableAssistantError, modelsAreEqual, resetApiProviders, } from "@earendil-works/pi-ai/compat";
|
|
19
19
|
import { getThemeByName, theme } from "../modes/interactive/theme/theme.js";
|
|
20
20
|
import { stripFrontmatter } from "../utils/frontmatter.js";
|
|
21
|
-
import { resolvePath } from "../utils/paths.js";
|
|
22
21
|
import { sleep } from "../utils/sleep.js";
|
|
23
22
|
import { normalizeToolResultImages } from "../utils/tool-result-images.js";
|
|
24
23
|
import { formatNoApiKeyFoundMessage, formatNoModelSelectedMessage } from "./auth-guidance.js";
|
|
25
24
|
import { executeBashWithOperations } from "./bash-executor.js";
|
|
26
25
|
import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
|
|
27
26
|
import { evictionBudget, installContextPipeline, isDefaultStreamFunction } from "./context/pipeline.js";
|
|
28
|
-
import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
|
|
27
|
+
import { DEFAULT_THINKING_LEVEL, THINKING_LEVEL_OPTIONS } from "./defaults.js";
|
|
29
28
|
import { SessionEvidenceSink } from "./evidence.js";
|
|
30
29
|
import { exportSessionToHtml } from "./export-html/index.js";
|
|
31
30
|
import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
|
|
@@ -36,7 +35,8 @@ import { evaluateToolCall } from "./permissions/gate.js";
|
|
|
36
35
|
import { createInteractiveResponder } from "./permissions/responder.js";
|
|
37
36
|
import { resolveEffectiveModeWithOrigin } from "./permissions/startup.js";
|
|
38
37
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
39
|
-
import {
|
|
38
|
+
import { exportSessionToJsonl } from "./session-export.js";
|
|
39
|
+
import { getLatestCompactionEntry, TODO_CUSTOM_ENTRY_TYPE } from "./session-manager.js";
|
|
40
40
|
import { slugifySkillCommandName } from "./skills.js";
|
|
41
41
|
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
42
42
|
import { buildSystemPrompt } from "./system-prompt.js";
|
|
@@ -80,8 +80,6 @@ function estimateMessagesTokens(messages) {
|
|
|
80
80
|
// ============================================================================
|
|
81
81
|
// Constants
|
|
82
82
|
// ============================================================================
|
|
83
|
-
/** Standard thinking levels */
|
|
84
|
-
const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high"];
|
|
85
83
|
// ============================================================================
|
|
86
84
|
// AgentSession Class
|
|
87
85
|
// ============================================================================
|
|
@@ -131,6 +129,7 @@ export class AgentSession {
|
|
|
131
129
|
_evidenceSink;
|
|
132
130
|
_diagnosticsOperations;
|
|
133
131
|
_lspOperations;
|
|
132
|
+
_webSearchOperations;
|
|
134
133
|
_extensionUIContext;
|
|
135
134
|
_extensionMode = "print";
|
|
136
135
|
_extensionCommandContextActions;
|
|
@@ -168,6 +167,7 @@ export class AgentSession {
|
|
|
168
167
|
this._evidenceSink = config.evidenceSink ?? new SessionEvidenceSink(this.sessionManager);
|
|
169
168
|
this._diagnosticsOperations = config.diagnosticsOperations;
|
|
170
169
|
this._lspOperations = config.lspOperations;
|
|
170
|
+
this._webSearchOperations = config.webSearchOperations;
|
|
171
171
|
// Always subscribe to agent events for internal handling
|
|
172
172
|
// (session persistence, extensions, auto-compaction, retry logic)
|
|
173
173
|
this._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);
|
|
@@ -404,6 +404,11 @@ export class AgentSession {
|
|
|
404
404
|
followUp: [...this._followUpMessages],
|
|
405
405
|
});
|
|
406
406
|
}
|
|
407
|
+
async _emitSessionCompactFailed(event) {
|
|
408
|
+
if (this._extensionRunner.hasHandlers("session_compact_failed")) {
|
|
409
|
+
await this._extensionRunner.emit({ type: "session_compact_failed", ...event });
|
|
410
|
+
}
|
|
411
|
+
}
|
|
407
412
|
_getIdleWaitPromise() {
|
|
408
413
|
if (!this._idleWaitPromise) {
|
|
409
414
|
this._idleWaitPromise = new Promise((resolve) => {
|
|
@@ -1186,7 +1191,7 @@ export class AgentSession {
|
|
|
1186
1191
|
if (options?.deliverAs === "nextTurn") {
|
|
1187
1192
|
this._pendingNextTurnMessages.push(appMessage);
|
|
1188
1193
|
}
|
|
1189
|
-
else if (this.isStreaming) {
|
|
1194
|
+
else if (this.isStreaming && options?.triggerTurn !== false) {
|
|
1190
1195
|
if (options?.deliverAs === "followUp") {
|
|
1191
1196
|
this.agent.followUp(appMessage);
|
|
1192
1197
|
}
|
|
@@ -1210,6 +1215,7 @@ export class AgentSession {
|
|
|
1210
1215
|
*
|
|
1211
1216
|
* @param content User message content (string or content array)
|
|
1212
1217
|
* @param options.deliverAs Delivery mode when streaming: "steer" or "followUp"
|
|
1218
|
+
* @param options.expandPromptTemplates Whether to dispatch extension commands and expand skill commands and prompt templates. Default: false.
|
|
1213
1219
|
*/
|
|
1214
1220
|
async sendUserMessage(content, options) {
|
|
1215
1221
|
// Normalize content to text string + optional images
|
|
@@ -1233,9 +1239,8 @@ export class AgentSession {
|
|
|
1233
1239
|
if (images.length === 0)
|
|
1234
1240
|
images = undefined;
|
|
1235
1241
|
}
|
|
1236
|
-
// Use prompt() with expandPromptTemplates: false to skip command handling and template expansion
|
|
1237
1242
|
await this.prompt(text, {
|
|
1238
|
-
expandPromptTemplates: false,
|
|
1243
|
+
expandPromptTemplates: options?.expandPromptTemplates ?? false,
|
|
1239
1244
|
streamingBehavior: options?.deliverAs,
|
|
1240
1245
|
images,
|
|
1241
1246
|
source: "extension",
|
|
@@ -1326,19 +1331,24 @@ export class AgentSession {
|
|
|
1326
1331
|
}
|
|
1327
1332
|
/**
|
|
1328
1333
|
* Set model directly.
|
|
1329
|
-
* Validates that auth is configured
|
|
1334
|
+
* Validates that auth is configured and saves to the session transcript.
|
|
1335
|
+
* Persists to global defaults only when options.persist is true.
|
|
1330
1336
|
* @throws Error if no auth is configured for the model
|
|
1331
1337
|
*/
|
|
1332
|
-
async setModel(model) {
|
|
1338
|
+
async setModel(model, options = {}) {
|
|
1333
1339
|
if (!(await this._modelRuntime.checkAuth(model.provider))) {
|
|
1334
1340
|
throw new Error(`No API key for ${model.provider}/${model.id}`);
|
|
1335
1341
|
}
|
|
1336
1342
|
const previousModel = this.model;
|
|
1337
|
-
const thinkingLevel = this._getThinkingLevelForModelSwitch();
|
|
1343
|
+
const thinkingLevel = this._getThinkingLevelForModelSwitch(model);
|
|
1338
1344
|
this.agent.state.model = model;
|
|
1339
1345
|
this.sessionManager.appendModelChange(model.provider, model.id);
|
|
1340
|
-
|
|
1341
|
-
|
|
1346
|
+
if (options.persist) {
|
|
1347
|
+
this.settingsManager.setDefaultModelAndProvider(model.provider, model.id);
|
|
1348
|
+
}
|
|
1349
|
+
// Apply thinking level for the new model.
|
|
1350
|
+
// Per-model thinking level overrides take priority over the global default.
|
|
1351
|
+
// Model persistence does not implicitly rewrite the global thinking default.
|
|
1342
1352
|
this.setThinkingLevel(thinkingLevel);
|
|
1343
1353
|
await this._emitModelSelect(model, previousModel, "set");
|
|
1344
1354
|
}
|
|
@@ -1348,13 +1358,13 @@ export class AgentSession {
|
|
|
1348
1358
|
* @param direction - "forward" (default) or "backward"
|
|
1349
1359
|
* @returns The new model info, or undefined if only one model available
|
|
1350
1360
|
*/
|
|
1351
|
-
async cycleModel(direction = "forward") {
|
|
1361
|
+
async cycleModel(direction = "forward", options = {}) {
|
|
1352
1362
|
if (this._scopedModels.length > 0) {
|
|
1353
|
-
return this._cycleScopedModel(direction);
|
|
1363
|
+
return this._cycleScopedModel(direction, options);
|
|
1354
1364
|
}
|
|
1355
|
-
return this._cycleAvailableModel(direction);
|
|
1365
|
+
return this._cycleAvailableModel(direction, options);
|
|
1356
1366
|
}
|
|
1357
|
-
async _cycleScopedModel(direction) {
|
|
1367
|
+
async _cycleScopedModel(direction, options) {
|
|
1358
1368
|
const availableIds = new Set(this._modelRuntime.getAvailableSnapshot().map((model) => `${model.provider}\0${model.id}`));
|
|
1359
1369
|
const scopedModels = this._scopedModels.filter((scoped) => availableIds.has(`${scoped.model.provider}\0${scoped.model.id}`));
|
|
1360
1370
|
if (scopedModels.length <= 1)
|
|
@@ -1366,20 +1376,23 @@ export class AgentSession {
|
|
|
1366
1376
|
const len = scopedModels.length;
|
|
1367
1377
|
const nextIndex = direction === "forward" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;
|
|
1368
1378
|
const next = scopedModels[nextIndex];
|
|
1369
|
-
const thinkingLevel = this._getThinkingLevelForModelSwitch(next.thinkingLevel);
|
|
1379
|
+
const thinkingLevel = this._getThinkingLevelForModelSwitch(next.model, next.thinkingLevel);
|
|
1370
1380
|
// Apply model
|
|
1371
1381
|
this.agent.state.model = next.model;
|
|
1372
1382
|
this.sessionManager.appendModelChange(next.model.provider, next.model.id);
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
//
|
|
1383
|
+
if (options.persist) {
|
|
1384
|
+
this.settingsManager.setDefaultModelAndProvider(next.model.provider, next.model.id);
|
|
1385
|
+
}
|
|
1386
|
+
// Apply thinking level for the new model.
|
|
1387
|
+
// - Explicit scoped model thinking level overrides defaults
|
|
1388
|
+
// - Per-model thinking level overrides take priority over the global default
|
|
1377
1389
|
// setThinkingLevel clamps to model capabilities.
|
|
1390
|
+
// Model persistence does not implicitly rewrite the global thinking default.
|
|
1378
1391
|
this.setThinkingLevel(thinkingLevel);
|
|
1379
1392
|
await this._emitModelSelect(next.model, currentModel, "cycle");
|
|
1380
1393
|
return { model: next.model, thinkingLevel: this.thinkingLevel, isScoped: true };
|
|
1381
1394
|
}
|
|
1382
|
-
async _cycleAvailableModel(direction) {
|
|
1395
|
+
async _cycleAvailableModel(direction, options) {
|
|
1383
1396
|
const availableModels = this._modelRuntime.getAvailableSnapshot();
|
|
1384
1397
|
if (availableModels.length <= 1)
|
|
1385
1398
|
return undefined;
|
|
@@ -1390,11 +1403,14 @@ export class AgentSession {
|
|
|
1390
1403
|
const len = availableModels.length;
|
|
1391
1404
|
const nextIndex = direction === "forward" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;
|
|
1392
1405
|
const nextModel = availableModels[nextIndex];
|
|
1393
|
-
const thinkingLevel = this._getThinkingLevelForModelSwitch();
|
|
1406
|
+
const thinkingLevel = this._getThinkingLevelForModelSwitch(nextModel);
|
|
1394
1407
|
this.agent.state.model = nextModel;
|
|
1395
1408
|
this.sessionManager.appendModelChange(nextModel.provider, nextModel.id);
|
|
1396
|
-
|
|
1397
|
-
|
|
1409
|
+
if (options.persist) {
|
|
1410
|
+
this.settingsManager.setDefaultModelAndProvider(nextModel.provider, nextModel.id);
|
|
1411
|
+
}
|
|
1412
|
+
// Apply thinking level for the new model.
|
|
1413
|
+
// Model persistence does not implicitly rewrite the global thinking default.
|
|
1398
1414
|
this.setThinkingLevel(thinkingLevel);
|
|
1399
1415
|
await this._emitModelSelect(nextModel, currentModel, "cycle");
|
|
1400
1416
|
return { model: nextModel, thinkingLevel: this.thinkingLevel, isScoped: false };
|
|
@@ -1405,20 +1421,21 @@ export class AgentSession {
|
|
|
1405
1421
|
/**
|
|
1406
1422
|
* Set thinking level.
|
|
1407
1423
|
* Clamps to model capabilities based on available thinking levels.
|
|
1408
|
-
* Saves to session
|
|
1424
|
+
* Saves the clamped level to the session transcript only if the level actually changes.
|
|
1425
|
+
* Persists the requested level to global defaults only when options.persist is true.
|
|
1409
1426
|
*/
|
|
1410
|
-
setThinkingLevel(level) {
|
|
1427
|
+
setThinkingLevel(level, options = {}) {
|
|
1411
1428
|
const availableLevels = this.getAvailableThinkingLevels();
|
|
1412
1429
|
const effectiveLevel = availableLevels.includes(level) ? level : this._clampThinkingLevel(level, availableLevels);
|
|
1413
1430
|
// Only persist if actually changing
|
|
1414
1431
|
const previousLevel = this.agent.state.thinkingLevel;
|
|
1415
1432
|
const isChanging = effectiveLevel !== previousLevel;
|
|
1416
1433
|
this.agent.state.thinkingLevel = effectiveLevel;
|
|
1434
|
+
if (options.persist) {
|
|
1435
|
+
this.settingsManager.setDefaultThinkingLevel(level);
|
|
1436
|
+
}
|
|
1417
1437
|
if (isChanging) {
|
|
1418
1438
|
this.sessionManager.appendThinkingLevelChange(effectiveLevel);
|
|
1419
|
-
if (this.supportsThinking() || effectiveLevel !== "off") {
|
|
1420
|
-
this.settingsManager.setDefaultThinkingLevel(effectiveLevel);
|
|
1421
|
-
}
|
|
1422
1439
|
this._emit({ type: "thinking_level_changed", level: effectiveLevel });
|
|
1423
1440
|
void this._extensionRunner.emit({
|
|
1424
1441
|
type: "thinking_level_select",
|
|
@@ -1431,14 +1448,14 @@ export class AgentSession {
|
|
|
1431
1448
|
* Cycle to next thinking level.
|
|
1432
1449
|
* @returns New level, or undefined if model doesn't support thinking
|
|
1433
1450
|
*/
|
|
1434
|
-
cycleThinkingLevel() {
|
|
1451
|
+
cycleThinkingLevel(options = {}) {
|
|
1435
1452
|
if (!this.supportsThinking())
|
|
1436
1453
|
return undefined;
|
|
1437
1454
|
const levels = this.getAvailableThinkingLevels();
|
|
1438
1455
|
const currentIndex = levels.indexOf(this.thinkingLevel);
|
|
1439
1456
|
const nextIndex = (currentIndex + 1) % levels.length;
|
|
1440
1457
|
const nextLevel = levels[nextIndex];
|
|
1441
|
-
this.setThinkingLevel(nextLevel);
|
|
1458
|
+
this.setThinkingLevel(nextLevel, options);
|
|
1442
1459
|
return nextLevel;
|
|
1443
1460
|
}
|
|
1444
1461
|
/**
|
|
@@ -1447,7 +1464,7 @@ export class AgentSession {
|
|
|
1447
1464
|
*/
|
|
1448
1465
|
getAvailableThinkingLevels() {
|
|
1449
1466
|
if (!this.model)
|
|
1450
|
-
return
|
|
1467
|
+
return [...THINKING_LEVEL_OPTIONS];
|
|
1451
1468
|
return getSupportedThinkingLevels(this.model);
|
|
1452
1469
|
}
|
|
1453
1470
|
/**
|
|
@@ -1456,14 +1473,18 @@ export class AgentSession {
|
|
|
1456
1473
|
supportsThinking() {
|
|
1457
1474
|
return !!this.model?.reasoning;
|
|
1458
1475
|
}
|
|
1459
|
-
_getThinkingLevelForModelSwitch(explicitLevel) {
|
|
1476
|
+
_getThinkingLevelForModelSwitch(targetModel, explicitLevel) {
|
|
1460
1477
|
if (explicitLevel !== undefined) {
|
|
1461
1478
|
return explicitLevel;
|
|
1462
1479
|
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1480
|
+
// Per-model default takes priority when switching to a model that has one
|
|
1481
|
+
if (targetModel) {
|
|
1482
|
+
const perModel = this.settingsManager.getModelThinkingLevel(targetModel.provider, targetModel.id);
|
|
1483
|
+
if (perModel !== undefined) {
|
|
1484
|
+
return perModel;
|
|
1485
|
+
}
|
|
1465
1486
|
}
|
|
1466
|
-
return this.thinkingLevel;
|
|
1487
|
+
return this.settingsManager.getDefaultThinkingLevel() ?? this.thinkingLevel ?? DEFAULT_THINKING_LEVEL;
|
|
1467
1488
|
}
|
|
1468
1489
|
_clampThinkingLevel(level, _availableLevels) {
|
|
1469
1490
|
return this.model ? clampThinkingLevel(this.model, level) : "off";
|
|
@@ -1494,15 +1515,30 @@ export class AgentSession {
|
|
|
1494
1515
|
// =========================================================================
|
|
1495
1516
|
// Compaction
|
|
1496
1517
|
// =========================================================================
|
|
1518
|
+
/** Generate Pi's built-in compaction summary for manual and automatic compaction. */
|
|
1519
|
+
async _runDefaultCompaction(preparation, requestModel, apiKey, headers, customInstructions, signal, env, reason) {
|
|
1520
|
+
return compact(preparation, requestModel, apiKey, headers, customInstructions, signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }), undefined);
|
|
1521
|
+
}
|
|
1497
1522
|
/**
|
|
1498
1523
|
* Manually compact the session context.
|
|
1499
|
-
*
|
|
1524
|
+
*
|
|
1525
|
+
* This is the manual entry point used by `/compact`, RPC, and extensions. It is
|
|
1526
|
+
* separate from automatic threshold/overflow compaction, which enters through
|
|
1527
|
+
* `_checkCompaction()` and `_runAutoCompaction()`. After preparation and the
|
|
1528
|
+
* `session_before_compact` hook, both paths call the lower-level `compact()`
|
|
1529
|
+
* function imported from `./compaction/index.ts`, unless the hook cancels or
|
|
1530
|
+
* supplies a custom result.
|
|
1531
|
+
*
|
|
1532
|
+
* Aborts the current agent operation first. Manual compaction never retries or
|
|
1533
|
+
* continues the interrupted agent turn.
|
|
1534
|
+
*
|
|
1500
1535
|
* @param customInstructions Optional instructions for the compaction summary
|
|
1501
1536
|
*/
|
|
1502
1537
|
async compact(customInstructions) {
|
|
1503
1538
|
await this.abort();
|
|
1504
1539
|
this._compactionAbortController = new AbortController();
|
|
1505
1540
|
this._emit({ type: "compaction_start", reason: "manual" });
|
|
1541
|
+
let fromExtension = false;
|
|
1506
1542
|
try {
|
|
1507
1543
|
if (!this.model) {
|
|
1508
1544
|
throw new Error(formatNoModelSelectedMessage());
|
|
@@ -1520,7 +1556,6 @@ export class AgentSession {
|
|
|
1520
1556
|
throw new Error("Nothing to compact (session too small)");
|
|
1521
1557
|
}
|
|
1522
1558
|
let extensionCompaction;
|
|
1523
|
-
let fromExtension = false;
|
|
1524
1559
|
if (this._extensionRunner.hasHandlers("session_before_compact")) {
|
|
1525
1560
|
const result = (await this._extensionRunner.emit({
|
|
1526
1561
|
type: "session_before_compact",
|
|
@@ -1553,8 +1588,8 @@ export class AgentSession {
|
|
|
1553
1588
|
details = extensionCompaction.details;
|
|
1554
1589
|
}
|
|
1555
1590
|
else {
|
|
1556
|
-
//
|
|
1557
|
-
const result = await
|
|
1591
|
+
// Shared default summary generator, also used by automatic compaction.
|
|
1592
|
+
const result = await this._runDefaultCompaction(preparation, requestModel, apiKey, headers, customInstructions, this._compactionAbortController.signal, env, "manual");
|
|
1558
1593
|
summary = result.summary;
|
|
1559
1594
|
firstKeptEntryId = result.firstKeptEntryId;
|
|
1560
1595
|
tokensBefore = result.tokensBefore;
|
|
@@ -1602,6 +1637,7 @@ export class AgentSession {
|
|
|
1602
1637
|
catch (error) {
|
|
1603
1638
|
const message = error instanceof Error ? error.message : String(error);
|
|
1604
1639
|
const aborted = message === "Compaction cancelled" || (error instanceof Error && error.name === "AbortError");
|
|
1640
|
+
const errorMessage = aborted ? undefined : `Compaction failed: ${message}`;
|
|
1605
1641
|
this._compactionAbortController = undefined;
|
|
1606
1642
|
this._emit({
|
|
1607
1643
|
type: "compaction_end",
|
|
@@ -1609,7 +1645,14 @@ export class AgentSession {
|
|
|
1609
1645
|
result: undefined,
|
|
1610
1646
|
aborted,
|
|
1611
1647
|
willRetry: false,
|
|
1612
|
-
errorMessage
|
|
1648
|
+
errorMessage,
|
|
1649
|
+
});
|
|
1650
|
+
await this._emitSessionCompactFailed({
|
|
1651
|
+
reason: "manual",
|
|
1652
|
+
errorMessage,
|
|
1653
|
+
aborted,
|
|
1654
|
+
willRetry: false,
|
|
1655
|
+
fromExtension,
|
|
1613
1656
|
});
|
|
1614
1657
|
throw error;
|
|
1615
1658
|
}
|
|
@@ -1631,16 +1674,25 @@ export class AgentSession {
|
|
|
1631
1674
|
this._branchSummaryAbortController?.abort();
|
|
1632
1675
|
}
|
|
1633
1676
|
/**
|
|
1634
|
-
*
|
|
1635
|
-
*
|
|
1677
|
+
* Dispatch automatic compaction after `agent_end` or before prompt submission.
|
|
1678
|
+
* Manual compaction does not call this method; it enters through `compact()`.
|
|
1679
|
+
*
|
|
1680
|
+
* Automatic cases:
|
|
1681
|
+
* 1. Overflow with retry: a context-overflow error or recoverable length stop;
|
|
1682
|
+
* remove the failed assistant message, compact, and retry the turn once.
|
|
1683
|
+
* 2. Overflow without retry: a successful response exceeded the configured
|
|
1684
|
+
* context window; compact but preserve the completed response.
|
|
1685
|
+
* 3. Threshold without retry: valid or estimated context usage crossed the
|
|
1686
|
+
* configured threshold; compact without retrying the completed response.
|
|
1636
1687
|
*
|
|
1637
|
-
*
|
|
1638
|
-
*
|
|
1639
|
-
*
|
|
1640
|
-
*
|
|
1688
|
+
* Each case calls `_runAutoCompaction()`. After preparation and the
|
|
1689
|
+
* `session_before_compact` hook, that method calls the lower-level `compact()`
|
|
1690
|
+
* function imported from `./compaction/index.ts`, unless the hook cancels or
|
|
1691
|
+
* supplies a custom result.
|
|
1641
1692
|
*
|
|
1642
1693
|
* @param assistantMessage The assistant message to check
|
|
1643
1694
|
* @param skipAbortedCheck If false, include aborted messages (for pre-prompt check). Default: true
|
|
1695
|
+
* @returns Whether the post-run loop should call `agent.continue()` for overflow recovery or queued messages
|
|
1644
1696
|
*/
|
|
1645
1697
|
async _checkCompaction(assistantMessage, skipAbortedCheck = true) {
|
|
1646
1698
|
const settings = this.settingsManager.getCompactionSettings();
|
|
@@ -1663,38 +1715,49 @@ export class AgentSession {
|
|
|
1663
1715
|
if (assistantIsFromBeforeCompaction) {
|
|
1664
1716
|
return false;
|
|
1665
1717
|
}
|
|
1666
|
-
//
|
|
1718
|
+
// Automatic cases 1 and 2: context overflow.
|
|
1667
1719
|
// A length stop is recoverable when output ended below the model's original desired limit,
|
|
1668
1720
|
// independent of the configured context size or any context-clamped provider request limit.
|
|
1669
|
-
|
|
1670
|
-
// assistant answer already completed and agent.continue() cannot continue from an assistant.
|
|
1721
|
+
const contextOverflow = sameModel && isContextOverflow(assistantMessage, contextWindow);
|
|
1671
1722
|
const recoverableLength = sameModel && isRecoverableLength(assistantMessage, this.model?.maxTokens ?? 0);
|
|
1672
|
-
if (
|
|
1723
|
+
if (contextOverflow || recoverableLength) {
|
|
1673
1724
|
const willRetry = assistantMessage.stopReason !== "stop";
|
|
1725
|
+
// Case 2: the response completed successfully. Compact, but do not retry because
|
|
1726
|
+
// agent.continue() cannot continue from a completed assistant response.
|
|
1674
1727
|
if (!willRetry) {
|
|
1675
1728
|
return await this._runAutoCompaction("overflow", false);
|
|
1676
1729
|
}
|
|
1677
1730
|
if (this._overflowRecoveryAttempted) {
|
|
1731
|
+
const errorMessage = contextOverflow
|
|
1732
|
+
? "Context overflow recovery failed after one compact-and-retry attempt. Try reducing context or switching to a larger-context model."
|
|
1733
|
+
: "Truncated response recovery failed after one compact-and-retry attempt.";
|
|
1678
1734
|
this._emit({
|
|
1679
1735
|
type: "compaction_end",
|
|
1680
1736
|
reason: "overflow",
|
|
1681
1737
|
result: undefined,
|
|
1682
1738
|
aborted: false,
|
|
1683
1739
|
willRetry: false,
|
|
1684
|
-
errorMessage
|
|
1740
|
+
errorMessage,
|
|
1741
|
+
});
|
|
1742
|
+
await this._emitSessionCompactFailed({
|
|
1743
|
+
reason: "overflow",
|
|
1744
|
+
errorMessage,
|
|
1745
|
+
aborted: false,
|
|
1746
|
+
willRetry: false,
|
|
1747
|
+
fromExtension: false,
|
|
1685
1748
|
});
|
|
1686
1749
|
return false;
|
|
1687
1750
|
}
|
|
1751
|
+
// Case 1: remove the failed or truncated message from agent state, compact, and
|
|
1752
|
+
// retry once. The message remains in session history but is excluded from retry context.
|
|
1688
1753
|
this._overflowRecoveryAttempted = true;
|
|
1689
|
-
// Remove the failed or truncated message from agent state. It remains in session history,
|
|
1690
|
-
// but must not be included in the compact-and-retry context.
|
|
1691
1754
|
const messages = this.agent.state.messages;
|
|
1692
1755
|
if (messages.length > 0 && messages[messages.length - 1].role === "assistant") {
|
|
1693
1756
|
this.agent.state.messages = messages.slice(0, -1);
|
|
1694
1757
|
}
|
|
1695
1758
|
return await this._runAutoCompaction("overflow", willRetry);
|
|
1696
1759
|
}
|
|
1697
|
-
// Case
|
|
1760
|
+
// Case 3: threshold compaction without retry.
|
|
1698
1761
|
// For error messages or all-zero usage messages, estimate from the last valid response.
|
|
1699
1762
|
// This ensures sessions that hit persistent API errors (e.g. 529) or malformed zero-usage
|
|
1700
1763
|
// responses can still compact and do not reset context accounting.
|
|
@@ -1703,16 +1766,18 @@ export class AgentSession {
|
|
|
1703
1766
|
if (assistantMessage.stopReason === "error" || directContextTokens === 0) {
|
|
1704
1767
|
const messages = this.agent.state.messages;
|
|
1705
1768
|
const estimate = estimateContextTokens(messages);
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1769
|
+
// Without provider usage, estimate.tokens is the pure message-size estimate.
|
|
1770
|
+
// Only usage-backed estimates need the stale pre-compaction check.
|
|
1771
|
+
if (estimate.lastUsageIndex !== null) {
|
|
1772
|
+
// Verify the usage source is post-compaction. Kept pre-compaction messages
|
|
1773
|
+
// have stale usage reflecting the old (larger) context and would falsely
|
|
1774
|
+
// trigger compaction right after one just finished.
|
|
1775
|
+
const usageMsg = messages[estimate.lastUsageIndex];
|
|
1776
|
+
if (compactionEntry &&
|
|
1777
|
+
usageMsg.role === "assistant" &&
|
|
1778
|
+
usageMsg.timestamp <= new Date(compactionEntry.timestamp).getTime()) {
|
|
1779
|
+
return false;
|
|
1780
|
+
}
|
|
1716
1781
|
}
|
|
1717
1782
|
contextTokens = estimate.tokens;
|
|
1718
1783
|
}
|
|
@@ -1725,11 +1790,19 @@ export class AgentSession {
|
|
|
1725
1790
|
return false;
|
|
1726
1791
|
}
|
|
1727
1792
|
/**
|
|
1728
|
-
*
|
|
1793
|
+
* Execute threshold or overflow compaction. Manual compaction uses
|
|
1794
|
+
* `AgentSession.compact()` instead. Both paths call the lower-level `compact()`
|
|
1795
|
+
* function imported from `./compaction/index.ts` after preparation and extension
|
|
1796
|
+
* interception.
|
|
1797
|
+
*
|
|
1798
|
+
* @param reason Automatic trigger selected by `_checkCompaction()`
|
|
1799
|
+
* @param willRetry Whether to continue the interrupted turn after overflow compaction
|
|
1800
|
+
* @returns Whether the post-run loop should call `agent.continue()`
|
|
1729
1801
|
*/
|
|
1730
1802
|
async _runAutoCompaction(reason, willRetry) {
|
|
1731
1803
|
const settings = this.settingsManager.getCompactionSettings();
|
|
1732
1804
|
let started = false;
|
|
1805
|
+
let fromExtension = false;
|
|
1733
1806
|
try {
|
|
1734
1807
|
if (!this.model) {
|
|
1735
1808
|
return false;
|
|
@@ -1744,7 +1817,6 @@ export class AgentSession {
|
|
|
1744
1817
|
this._autoCompactionAbortController = new AbortController();
|
|
1745
1818
|
started = true;
|
|
1746
1819
|
let extensionCompaction;
|
|
1747
|
-
let fromExtension = false;
|
|
1748
1820
|
if (this._extensionRunner.hasHandlers("session_before_compact")) {
|
|
1749
1821
|
const extensionResult = (await this._extensionRunner.emit({
|
|
1750
1822
|
type: "session_before_compact",
|
|
@@ -1763,6 +1835,12 @@ export class AgentSession {
|
|
|
1763
1835
|
aborted: true,
|
|
1764
1836
|
willRetry: false,
|
|
1765
1837
|
});
|
|
1838
|
+
await this._emitSessionCompactFailed({
|
|
1839
|
+
reason,
|
|
1840
|
+
aborted: true,
|
|
1841
|
+
willRetry: false,
|
|
1842
|
+
fromExtension: false,
|
|
1843
|
+
});
|
|
1766
1844
|
return false;
|
|
1767
1845
|
}
|
|
1768
1846
|
if (extensionResult?.compaction) {
|
|
@@ -1784,8 +1862,8 @@ export class AgentSession {
|
|
|
1784
1862
|
details = extensionCompaction.details;
|
|
1785
1863
|
}
|
|
1786
1864
|
else {
|
|
1787
|
-
//
|
|
1788
|
-
const compactResult = await
|
|
1865
|
+
// Shared default summary generator, also used by manual compaction.
|
|
1866
|
+
const compactResult = await this._runDefaultCompaction(preparation, requestModel, apiKey, headers, undefined, this._autoCompactionAbortController.signal, env, reason);
|
|
1789
1867
|
summary = compactResult.summary;
|
|
1790
1868
|
firstKeptEntryId = compactResult.firstKeptEntryId;
|
|
1791
1869
|
tokensBefore = compactResult.tokensBefore;
|
|
@@ -1800,6 +1878,12 @@ export class AgentSession {
|
|
|
1800
1878
|
aborted: true,
|
|
1801
1879
|
willRetry: false,
|
|
1802
1880
|
});
|
|
1881
|
+
await this._emitSessionCompactFailed({
|
|
1882
|
+
reason,
|
|
1883
|
+
aborted: true,
|
|
1884
|
+
willRetry: false,
|
|
1885
|
+
fromExtension,
|
|
1886
|
+
});
|
|
1803
1887
|
return false;
|
|
1804
1888
|
}
|
|
1805
1889
|
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension, usage);
|
|
@@ -1846,15 +1930,23 @@ export class AgentSession {
|
|
|
1846
1930
|
catch (error) {
|
|
1847
1931
|
const errorMessage = error instanceof Error ? error.message : "compaction failed";
|
|
1848
1932
|
if (started) {
|
|
1933
|
+
const formattedErrorMessage = reason === "overflow"
|
|
1934
|
+
? `Context overflow recovery failed: ${errorMessage}`
|
|
1935
|
+
: `Auto-compaction failed: ${errorMessage}`;
|
|
1849
1936
|
this._emit({
|
|
1850
1937
|
type: "compaction_end",
|
|
1851
1938
|
reason,
|
|
1852
1939
|
result: undefined,
|
|
1853
1940
|
aborted: false,
|
|
1854
1941
|
willRetry: false,
|
|
1855
|
-
errorMessage:
|
|
1856
|
-
|
|
1857
|
-
|
|
1942
|
+
errorMessage: formattedErrorMessage,
|
|
1943
|
+
});
|
|
1944
|
+
await this._emitSessionCompactFailed({
|
|
1945
|
+
reason,
|
|
1946
|
+
errorMessage: formattedErrorMessage,
|
|
1947
|
+
aborted: false,
|
|
1948
|
+
willRetry: false,
|
|
1949
|
+
fromExtension,
|
|
1858
1950
|
});
|
|
1859
1951
|
}
|
|
1860
1952
|
return false;
|
|
@@ -2172,6 +2264,7 @@ export class AgentSession {
|
|
|
2172
2264
|
edit: { diagnosticsOperations: this._diagnosticsOperations },
|
|
2173
2265
|
write: { diagnosticsOperations: this._diagnosticsOperations },
|
|
2174
2266
|
...(this._lspOperations ? { lsp: { operations: this._lspOperations } } : {}),
|
|
2267
|
+
...(this._webSearchOperations ? { web_search: { operations: this._webSearchOperations } } : {}),
|
|
2175
2268
|
});
|
|
2176
2269
|
baseToolDefinitions.tool_schema = createToolSchemaToolDefinition({
|
|
2177
2270
|
getTool: (name) => {
|
|
@@ -2753,11 +2846,11 @@ export class AgentSession {
|
|
|
2753
2846
|
/**
|
|
2754
2847
|
* Export session to HTML.
|
|
2755
2848
|
* @param outputPath Optional output path (defaults to session directory)
|
|
2849
|
+
* @param options Optional export presentation settings
|
|
2756
2850
|
* @returns Path to exported file
|
|
2757
2851
|
*/
|
|
2758
|
-
async exportToHtml(outputPath) {
|
|
2759
|
-
const
|
|
2760
|
-
const themeName = configuredThemeName && getThemeByName(configuredThemeName) ? configuredThemeName : undefined;
|
|
2852
|
+
async exportToHtml(outputPath, options = {}) {
|
|
2853
|
+
const themeName = [options.themeName, this.settingsManager.getTheme()].find((candidate) => candidate !== undefined && getThemeByName(candidate) !== undefined);
|
|
2761
2854
|
// Create tool renderer if we have an extension runner (for custom tool HTML rendering)
|
|
2762
2855
|
const toolRenderer = createToolHtmlRenderer({
|
|
2763
2856
|
getToolDefinition: (name) => this.getToolDefinition(name),
|
|
@@ -2777,29 +2870,7 @@ export class AgentSession {
|
|
|
2777
2870
|
* @returns The resolved output file path.
|
|
2778
2871
|
*/
|
|
2779
2872
|
exportToJsonl(outputPath) {
|
|
2780
|
-
|
|
2781
|
-
const dir = dirname(filePath);
|
|
2782
|
-
if (!existsSync(dir)) {
|
|
2783
|
-
mkdirSync(dir, { recursive: true });
|
|
2784
|
-
}
|
|
2785
|
-
const header = {
|
|
2786
|
-
type: "session",
|
|
2787
|
-
version: CURRENT_SESSION_VERSION,
|
|
2788
|
-
id: this.sessionManager.getSessionId(),
|
|
2789
|
-
timestamp: new Date().toISOString(),
|
|
2790
|
-
cwd: this.sessionManager.getCwd(),
|
|
2791
|
-
};
|
|
2792
|
-
const branchEntries = this.sessionManager.getBranch();
|
|
2793
|
-
const lines = [JSON.stringify(header)];
|
|
2794
|
-
// Re-chain parentIds to form a linear sequence
|
|
2795
|
-
let prevId = null;
|
|
2796
|
-
for (const entry of branchEntries) {
|
|
2797
|
-
const linear = { ...entry, parentId: prevId };
|
|
2798
|
-
lines.push(JSON.stringify(linear));
|
|
2799
|
-
prevId = entry.id;
|
|
2800
|
-
}
|
|
2801
|
-
writeFileSync(filePath, `${lines.join("\n")}\n`);
|
|
2802
|
-
return filePath;
|
|
2873
|
+
return exportSessionToJsonl(this.sessionManager, outputPath);
|
|
2803
2874
|
}
|
|
2804
2875
|
// =========================================================================
|
|
2805
2876
|
// Utilities
|