@selesai/code 0.13.39 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -0
- package/dist/bun/runtime-setup.js +4 -1
- package/dist/cli/args.d.ts +3 -1
- package/dist/cli/args.js +76 -33
- package/dist/cli/auth-check.d.ts +18 -0
- package/dist/cli/auth-check.js +49 -0
- package/dist/cli/credential-print.d.ts +5 -15
- package/dist/cli/credential-print.js +42 -82
- package/dist/cli/file-processor.d.ts +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/list-models.d.ts +1 -1
- package/dist/cli/list-models.js +2 -2
- package/dist/cli/startup-ui.js +38 -30
- package/dist/config.d.ts +35 -6
- package/dist/config.js +95 -17
- package/dist/core/agent-session-custom-tools.test.js +64 -0
- package/dist/core/agent-session-length-continuation.test.js +7 -3
- package/dist/core/agent-session-runtime.js +2 -2
- package/dist/core/agent-session-services.d.ts +1 -0
- package/dist/core/agent-session-services.js +14 -0
- package/dist/core/agent-session.d.ts +180 -40
- package/dist/core/agent-session.js +1061 -485
- package/dist/core/auth-storage.d.ts +25 -15
- package/dist/core/auth-storage.js +242 -66
- package/dist/core/bash-executor.js +42 -52
- package/dist/core/bug-report.js +1 -1
- package/dist/core/cache-warmer.d.ts +1 -0
- package/dist/core/cache-warmer.js +15 -1
- package/dist/core/compaction/branch-summarization.js +3 -0
- package/dist/core/compaction/compaction.d.ts +3 -1
- package/dist/core/compaction/compaction.js +156 -79
- package/dist/core/compaction/utils.d.ts +2 -1
- package/dist/core/compaction/utils.js +25 -18
- package/dist/core/crash-log.d.ts +5 -0
- package/dist/core/crash-log.js +69 -0
- package/dist/core/defaults.d.ts +1 -1
- package/dist/core/defaults.js +1 -1
- package/dist/core/export-html/template.css +10 -0
- package/dist/core/export-html/template.js +72 -18
- package/dist/core/export-html/tool-renderer.d.ts +3 -3
- package/dist/core/export-html/tool-renderer.js +5 -3
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/loader.js +138 -55
- package/dist/core/extensions/runner.d.ts +38 -5
- package/dist/core/extensions/runner.js +220 -7
- package/dist/core/extensions/types.d.ts +438 -51
- package/dist/core/extensions/types.js +3 -0
- package/dist/core/extensions/virtual-modules.js +6 -0
- package/dist/core/extensions/wrapper.d.ts +2 -2
- package/dist/core/extensions/wrapper.js +3 -3
- package/dist/core/footer-data-provider.d.ts +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/handoff.d.ts +0 -1
- package/dist/core/handoff.js +0 -1
- package/dist/core/http-dispatcher.js +5 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/core/intercom-rpc.d.ts +135 -0
- package/dist/core/intercom-rpc.js +64 -0
- package/dist/core/keybindings.d.ts +25 -24
- package/dist/core/keybindings.js +27 -6
- package/dist/core/mcp-servers.d.ts +134 -0
- package/dist/core/mcp-servers.js +223 -0
- package/dist/core/model-config.d.ts +122 -5
- package/dist/core/model-config.js +35 -1
- package/dist/core/model-registry.d.ts +23 -15
- package/dist/core/model-registry.js +46 -22
- package/dist/core/model-resolver.d.ts +6 -5
- package/dist/core/model-resolver.js +51 -21
- package/dist/core/model-runtime.d.ts +73 -14
- package/dist/core/model-runtime.js +398 -104
- package/dist/core/models-store.d.ts +12 -7
- package/dist/core/models-store.js +85 -15
- package/dist/core/nested-tool-calls.d.ts +102 -0
- package/dist/core/nested-tool-calls.js +178 -0
- package/dist/core/package-manager.d.ts +8 -1
- package/dist/core/package-manager.js +144 -61
- package/dist/core/package-manager.test.js +5 -5
- package/dist/core/pi-manifest.d.ts +9 -0
- package/dist/core/pi-manifest.js +25 -0
- package/dist/core/prompt-templates.d.ts +6 -1
- package/dist/core/prompt-templates.js +61 -35
- package/dist/core/provider-composer.d.ts +44 -19
- package/dist/core/provider-composer.js +166 -64
- package/dist/core/radius.d.ts +2 -0
- package/dist/core/radius.js +2 -0
- package/dist/core/release-rpc.d.ts +137 -0
- package/dist/core/release-rpc.js +77 -0
- package/dist/core/remote-catalog-provider.d.ts +8 -1
- package/dist/core/remote-catalog-provider.js +25 -13
- package/dist/core/resource-loader.d.ts +12 -1
- package/dist/core/resource-loader.js +180 -45
- package/dist/core/runtime-credentials.d.ts +5 -5
- package/dist/core/runtime-credentials.js +11 -8
- package/dist/core/sdk.d.ts +16 -7
- package/dist/core/sdk.js +57 -24
- package/dist/core/session-manager.d.ts +45 -9
- package/dist/core/session-manager.js +124 -31
- package/dist/core/settings-diagnostics.d.ts +8 -0
- package/dist/core/settings-diagnostics.js +20 -0
- package/dist/core/settings-manager.d.ts +62 -32
- package/dist/core/settings-manager.js +147 -69
- package/dist/core/skills.d.ts +5 -2
- package/dist/core/skills.js +58 -35
- package/dist/core/slash-commands.js +2 -1
- package/dist/core/source-info.d.ts +8 -0
- package/dist/core/source-info.js +16 -0
- package/dist/core/subagent-rpc.d.ts +110 -0
- package/dist/core/subagent-rpc.js +60 -0
- package/dist/core/system-prompt.d.ts +9 -3
- package/dist/core/system-prompt.js +9 -12
- package/dist/core/system-prompt.test.js +2 -7
- package/dist/core/tools/bash.d.ts +12 -0
- package/dist/core/tools/bash.js +33 -2
- package/dist/core/tools/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.js +2 -5
- package/dist/core/tools/edit.d.ts +4 -0
- package/dist/core/tools/edit.js +31 -11
- package/dist/core/tools/find.d.ts +7 -0
- package/dist/core/tools/find.js +16 -19
- package/dist/core/tools/grep.d.ts +4 -0
- package/dist/core/tools/grep.js +5 -1
- package/dist/core/tools/index.d.ts +1 -1
- package/dist/core/tools/index.js +11 -2
- package/dist/core/tools/ls.d.ts +4 -0
- package/dist/core/tools/ls.js +5 -1
- package/dist/core/tools/output-accumulator.d.ts +11 -0
- package/dist/core/tools/output-accumulator.js +40 -10
- package/dist/core/tools/read.d.ts +17 -2
- package/dist/core/tools/read.js +23 -2
- package/dist/core/tools/render-utils.d.ts +6 -0
- package/dist/core/tools/render-utils.js +26 -0
- package/dist/core/tools/renderers/bash.js +19 -35
- package/dist/core/tools/renderers/edit.js +5 -4
- package/dist/core/tools/renderers/index.d.ts +2 -2
- package/dist/core/tools/renderers/read.js +3 -2
- package/dist/core/tools/tool-definition-wrapper.d.ts +5 -3
- package/dist/core/tools/tool-definition-wrapper.js +3 -1
- package/dist/core/tools/truncate.d.ts +14 -0
- package/dist/core/tools/truncate.js +29 -0
- package/dist/core/tools/write.d.ts +4 -0
- package/dist/core/tools/write.js +6 -2
- package/dist/core/trust-manager.js +3 -1
- package/dist/core/usage-totals.d.ts +2 -0
- package/dist/core/usage-totals.js +23 -0
- package/dist/core/virtual-models.d.ts +116 -0
- package/dist/core/virtual-models.js +123 -0
- package/dist/defaults/models.json +32 -0
- package/dist/defaults/settings.json +1 -9
- package/dist/extensions/agent-browser.ts +9 -0
- package/dist/extensions/codemode/execute.d.ts +15 -0
- package/dist/extensions/codemode/execute.js +633 -0
- package/dist/extensions/codemode/execute.lazy.d.ts +2 -0
- package/dist/extensions/codemode/execute.lazy.js +2 -0
- package/dist/extensions/codemode/index.d.ts +20 -0
- package/dist/extensions/codemode/index.js +31 -0
- package/dist/extensions/codemode/renderer.d.ts +11 -0
- package/dist/extensions/codemode/renderer.js +136 -0
- package/dist/extensions/codemode/tool.d.ts +129 -0
- package/dist/extensions/codemode/tool.js +275 -0
- package/dist/extensions/context-compaction-reminder.ts +1 -1
- package/dist/extensions/grep-app/index.ts +2 -10
- package/dist/extensions/herdr-agent-state.ts +1 -1
- package/dist/extensions/{pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts → index.d.ts} +0 -1
- package/dist/extensions/index.js +12 -0
- package/dist/extensions/jev/classifier-context.ts +54 -0
- package/dist/extensions/jev/classifier.test.ts +85 -0
- package/dist/extensions/jev/classifier.ts +105 -0
- package/dist/extensions/jev/decisions.test.ts +35 -47
- package/dist/extensions/jev/decisions.ts +58 -104
- package/dist/extensions/jev/test-support.ts +33 -38
- package/dist/extensions/jev-advisory-lifecycle.test.ts +12 -12
- package/dist/extensions/jev-advisory-memory.test.ts +9 -9
- package/dist/extensions/jev-advisory-recommendations.test.ts +8 -8
- package/dist/extensions/jev-ask-tool.test.ts +41 -45
- package/dist/extensions/jev-ask-tool.ts +10 -38
- package/dist/extensions/jev-find-source.test.ts +26 -0
- package/dist/extensions/jev-find-source.ts +58 -19
- package/dist/{core → extensions}/llama/client.d.ts +2 -0
- package/dist/{core → extensions}/llama/client.js +7 -3
- package/dist/{core → extensions}/llama/index.js +13 -2
- package/dist/{core → extensions}/llama/provider.d.ts +1 -1
- package/dist/extensions/llama/provider.js +235 -0
- package/dist/extensions/mcp/cli.d.ts +20 -0
- package/dist/extensions/mcp/cli.js +496 -0
- package/dist/extensions/mcp/cli.lazy.d.ts +2 -0
- package/dist/extensions/mcp/cli.lazy.js +2 -0
- package/dist/extensions/mcp/config.d.ts +83 -0
- package/dist/extensions/mcp/config.js +193 -0
- package/dist/extensions/mcp/index.d.ts +78 -0
- package/dist/extensions/mcp/index.js +1201 -0
- package/dist/extensions/mcp/log.d.ts +15 -0
- package/dist/extensions/mcp/log.js +65 -0
- package/dist/extensions/mcp/oauth.d.ts +97 -0
- package/dist/extensions/mcp/oauth.js +401 -0
- package/dist/extensions/mcp/resources.d.ts +41 -0
- package/dist/extensions/mcp/resources.js +260 -0
- package/dist/extensions/mcp/runtime.d.ts +96 -0
- package/dist/extensions/mcp/runtime.js +412 -0
- package/dist/extensions/mcp/runtime.lazy.d.ts +2 -0
- package/dist/extensions/mcp/runtime.lazy.js +2 -0
- package/dist/extensions/mcp/tools.d.ts +86 -0
- package/dist/extensions/mcp/tools.js +252 -0
- package/dist/extensions/mcp/ui.d.ts +59 -0
- package/dist/extensions/mcp/ui.js +185 -0
- package/dist/extensions/package.json +1 -1
- package/dist/extensions/pi-graft/tools.ts +6 -0
- package/dist/extensions/pi-hermes-memory/CHANGELOG.md +25 -0
- package/dist/extensions/pi-hermes-memory/README.md +140 -4
- package/dist/extensions/pi-hermes-memory/package-lock.json +624 -2720
- package/dist/extensions/pi-hermes-memory/package.json +9 -7
- package/dist/extensions/pi-hermes-memory/scripts/benchmark-memory-startup.mjs +72 -0
- package/dist/extensions/pi-hermes-memory/scripts/check-production-install.mjs +107 -0
- package/dist/extensions/pi-hermes-memory/src/auto-consolidation-warning.ts +2 -1
- package/dist/extensions/pi-hermes-memory/src/config.ts +35 -0
- package/dist/extensions/pi-hermes-memory/src/constants.ts +62 -15
- package/dist/extensions/pi-hermes-memory/src/handlers/auto-consolidate.ts +374 -50
- package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +7 -4
- package/dist/extensions/pi-hermes-memory/src/handlers/correction-detector.ts +19 -14
- package/dist/extensions/pi-hermes-memory/src/handlers/insights.ts +75 -1
- package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +322 -22
- package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +8 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/session-flush.ts +193 -54
- package/dist/extensions/pi-hermes-memory/src/handlers/skills-command.ts +6 -2
- package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +33 -5
- package/dist/extensions/pi-hermes-memory/src/index.ts +116 -47
- package/dist/extensions/pi-hermes-memory/src/memory-initialization.ts +101 -0
- package/dist/extensions/pi-hermes-memory/src/store/atomic-lock-coordinator.ts +10 -2
- package/dist/extensions/pi-hermes-memory/src/store/db.ts +34 -9
- package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +44 -8
- package/dist/extensions/pi-hermes-memory/src/store/schema.ts +3 -1
- package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +141 -0
- package/dist/extensions/pi-hermes-memory/src/store/standing-instructions.ts +17 -6
- package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +20 -10
- package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +1 -17
- package/dist/extensions/pi-hermes-memory/src/tools/session-search-tool.ts +2 -10
- package/dist/extensions/pi-hermes-memory/src/tools/skill-tool.ts +4 -8
- package/dist/extensions/pi-hermes-memory/src/types.ts +48 -0
- package/dist/extensions/pi-hermes-memory/tests/config.test.ts +108 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/auto-consolidate.test.ts +1185 -42
- package/dist/extensions/pi-hermes-memory/tests/handlers/insights.test.ts +57 -1
- package/dist/extensions/pi-hermes-memory/tests/handlers/lazy-memory-hooks.test.ts +128 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +844 -1
- package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +16 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/session-flush.test.ts +512 -3
- package/dist/extensions/pi-hermes-memory/tests/handlers/skills-command.test.ts +38 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/sync-markdown-memories.test.ts +183 -2
- package/dist/extensions/pi-hermes-memory/tests/handlers/system-prompt.test.ts +1 -3
- package/dist/extensions/pi-hermes-memory/tests/index.test.ts +17 -0
- package/dist/extensions/pi-hermes-memory/tests/integration/corruption-recovery-integration.test.ts +21 -0
- package/dist/extensions/pi-hermes-memory/tests/lazy-startup.test.ts +313 -0
- package/dist/extensions/pi-hermes-memory/tests/memory-initialization.test.ts +182 -0
- package/dist/extensions/pi-hermes-memory/tests/prompt-injection.test.ts +184 -0
- package/dist/extensions/pi-hermes-memory/tests/skill-discovery-contract.test.ts +60 -0
- package/dist/extensions/pi-hermes-memory/tests/store/atomic-lock-lazy-probe.test.ts +80 -0
- package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +2 -0
- package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +79 -0
- package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +268 -0
- package/dist/extensions/pi-hermes-memory/tests/store/standing-instructions.test.ts +29 -0
- package/dist/extensions/pi-hermes-memory/tests/store/usage-tracking.test.ts +170 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +80 -1
- package/dist/extensions/pi-hermes-memory/tests/tools/skill-tool.test.ts +51 -0
- package/dist/extensions/pi-intercom/CHANGELOG.md +66 -0
- package/dist/extensions/pi-intercom/README.md +115 -12
- package/dist/extensions/pi-intercom/broker/broker.ts +304 -24
- package/dist/extensions/pi-intercom/broker/client.ts +9 -2
- package/dist/extensions/pi-intercom/broker/cross-machine-provenance.test.ts +63 -0
- package/dist/extensions/pi-intercom/broker/mailbox-persistence.test.ts +523 -0
- package/dist/extensions/pi-intercom/broker/paths.test.ts +4 -4
- package/dist/extensions/pi-intercom/broker/paths.ts +4 -2
- package/dist/extensions/pi-intercom/broker/protocol.ts +64 -0
- package/dist/extensions/pi-intercom/broker/spawn.test.ts +58 -169
- package/dist/extensions/pi-intercom/broker/spawn.ts +40 -87
- package/dist/extensions/pi-intercom/cli.mjs +6 -0
- package/dist/extensions/pi-intercom/cli.test.ts +428 -0
- package/dist/extensions/pi-intercom/cli.ts +343 -0
- package/dist/extensions/pi-intercom/config.test.ts +61 -1
- package/dist/extensions/pi-intercom/config.ts +53 -2
- package/dist/extensions/pi-intercom/cross-machine-discovery.test.ts +218 -0
- package/dist/extensions/pi-intercom/cross-machine-discovery.ts +140 -0
- package/dist/extensions/pi-intercom/cross-machine-envelope.test.ts +106 -0
- package/dist/extensions/pi-intercom/cross-machine-envelope.ts +92 -0
- package/dist/extensions/pi-intercom/cross-machine-integration.test.ts +25 -0
- package/dist/extensions/pi-intercom/cross-machine-transport.test.ts +106 -0
- package/dist/extensions/pi-intercom/cross-machine-transport.ts +110 -0
- package/dist/extensions/pi-intercom/extension-api.ts +24 -0
- package/dist/extensions/pi-intercom/handover.test.ts +88 -0
- package/dist/extensions/pi-intercom/handover.ts +115 -0
- package/dist/extensions/pi-intercom/herdr-location.test.ts +173 -0
- package/dist/extensions/pi-intercom/herdr-location.ts +137 -0
- package/dist/extensions/pi-intercom/human-priority.pi.test.ts +489 -0
- package/dist/extensions/pi-intercom/index.ts +770 -172
- package/dist/extensions/pi-intercom/intercom.integration.test.ts +869 -21
- package/dist/extensions/pi-intercom/package.json +12 -2
- package/dist/extensions/pi-intercom/project-agent.ts +1 -1
- package/dist/extensions/pi-intercom/release-readiness.test.ts +116 -0
- package/dist/extensions/pi-intercom/release-readiness.ts +93 -0
- package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +26 -2
- package/dist/extensions/pi-intercom/test/handover-picker.test.ts +134 -0
- package/dist/extensions/pi-intercom/test/inline-message.test.ts +43 -0
- package/dist/extensions/pi-intercom/types.d.ts +247 -0
- package/dist/extensions/pi-intercom/types.js +2 -0
- package/dist/extensions/pi-intercom/types.ts +39 -1
- package/dist/extensions/pi-intercom/ui/handover-picker.ts +318 -0
- package/dist/extensions/pi-intercom/ui/inline-message.ts +10 -3
- package/dist/extensions/pi-intercom/ui/session-list.ts +28 -15
- package/dist/extensions/pi-subagents/.github/workflows/release.yml +5 -1
- package/dist/extensions/pi-subagents/.github/workflows/test.yml +188 -18
- package/dist/extensions/pi-subagents/CHANGELOG.md +514 -1
- package/dist/extensions/pi-subagents/README.md +7 -5
- package/dist/extensions/pi-subagents/VISION.md +6 -0
- package/dist/extensions/pi-subagents/agents/reviewer.md +7 -5
- package/dist/extensions/pi-subagents/agents/worker.md +1 -1
- package/dist/extensions/pi-subagents/docs/agents.md +75 -35
- package/dist/extensions/pi-subagents/docs/configuration.md +156 -25
- package/dist/extensions/pi-subagents/docs/extension-api.md +121 -29
- package/dist/extensions/pi-subagents/docs/missions.md +46 -14
- package/dist/extensions/pi-subagents/docs/models.md +22 -84
- package/dist/extensions/pi-subagents/docs/observability.md +57 -24
- package/dist/extensions/pi-subagents/docs/standalone-background.md +59 -0
- package/dist/extensions/pi-subagents/docs/tool-reference.md +167 -116
- package/dist/extensions/pi-subagents/docs/watchdog.md +41 -10
- package/dist/extensions/pi-subagents/docs/workflows.md +239 -163
- package/dist/extensions/pi-subagents/examples/typed-gate/.pi/agents/classifier.md +14 -0
- package/dist/extensions/pi-subagents/examples/typed-gate/README.md +42 -0
- package/dist/extensions/pi-subagents/examples/typed-gate/classify +38 -0
- package/dist/extensions/pi-subagents/examples/typed-gate/workflow.js +32 -0
- package/dist/extensions/pi-subagents/index.ts +11 -3
- package/dist/extensions/pi-subagents/inspector-runner.mjs +3 -3
- package/dist/extensions/pi-subagents/package-lock.json +517 -1129
- package/dist/extensions/pi-subagents/package.json +22 -11
- package/dist/extensions/pi-subagents/prompts/council.md +7 -4
- package/dist/extensions/pi-subagents/prompts/parallel-review.md +2 -2
- package/dist/extensions/pi-subagents/prompts/review-loop.md +2 -2
- package/dist/extensions/pi-subagents/runner-peer-loader.mjs +21 -0
- package/dist/extensions/pi-subagents/runner-peer-preload.mjs +30 -0
- package/dist/extensions/pi-subagents/scripts/build-package.mjs +79 -0
- package/dist/extensions/pi-subagents/skills/council-mode/SKILL.md +2 -2
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +46 -27
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +11 -7
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +78 -73
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +4 -5
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +10 -2
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +69 -67
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/review-and-validation.md +3 -3
- package/dist/extensions/pi-subagents/src/agents/advertised-agent-prompt.ts +21 -10
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +113 -113
- package/dist/extensions/pi-subagents/src/agents/agent-memory.ts +91 -4
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +15 -9
- package/dist/extensions/pi-subagents/src/agents/agents.ts +432 -193
- package/dist/extensions/pi-subagents/src/agents/chain-serializer.ts +6 -1
- package/dist/extensions/pi-subagents/src/agents/global-npm-root.ts +58 -0
- package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +5 -2
- package/dist/extensions/pi-subagents/src/agents/runtime-agent-registry.ts +22 -18
- package/dist/extensions/pi-subagents/src/agents/skills.ts +43 -10
- package/dist/extensions/pi-subagents/src/api/delegation.ts +20 -1
- package/dist/extensions/pi-subagents/src/api/inspectors.ts +27 -0
- package/dist/extensions/pi-subagents/src/api/preflight.ts +140 -62
- package/dist/extensions/pi-subagents/src/api/required-child-extensions.ts +6 -0
- package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -0
- package/dist/extensions/pi-subagents/src/extension/config.ts +24 -40
- package/dist/extensions/pi-subagents/src/extension/control-notices.ts +4 -1
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +18 -15
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +87 -13
- package/dist/extensions/pi-subagents/src/extension/herdr-pi-bridge.ts +162 -0
- package/dist/extensions/pi-subagents/src/extension/index.ts +331 -269
- package/dist/extensions/pi-subagents/src/extension/observability.ts +164 -0
- package/dist/extensions/pi-subagents/src/extension/public-execution.ts +76 -37
- package/dist/extensions/pi-subagents/src/extension/release-readiness.ts +367 -0
- package/dist/extensions/pi-subagents/src/extension/reply-workflow-script.ts +67 -0
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +42 -12
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +116 -205
- package/dist/extensions/pi-subagents/src/extension/subagent-guide.ts +13 -5
- package/dist/extensions/pi-subagents/src/extension/tool-activation.ts +146 -0
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +77 -90
- package/dist/extensions/pi-subagents/src/extension/upgrade-notice.ts +40 -0
- package/dist/extensions/pi-subagents/src/inspectors/actions.ts +148 -0
- package/dist/extensions/pi-subagents/src/inspectors/ghostty/actions.ts +74 -0
- package/dist/extensions/pi-subagents/src/inspectors/ghostty/plugin.ts +29 -0
- package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +100 -180
- package/dist/extensions/pi-subagents/src/inspectors/herdr/plugin.ts +20 -0
- package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +2 -2
- package/dist/extensions/pi-subagents/src/inspectors/{herdr/inspector-runner.ts → inspector-runner.ts} +13 -13
- package/dist/extensions/pi-subagents/src/inspectors/plugins.ts +75 -0
- package/dist/extensions/pi-subagents/src/inspectors/{herdr/session-roots-codec.ts → session-roots-codec.ts} +4 -15
- package/dist/extensions/pi-subagents/src/inspectors/{herdr/shell-command.ts → shell-command.ts} +1 -1
- package/dist/extensions/pi-subagents/src/inspectors/types.ts +51 -0
- package/dist/extensions/pi-subagents/src/integrations/herdr-status.ts +38 -53
- package/dist/extensions/pi-subagents/src/integrations/pi-web-session-liveness.ts +7 -1
- package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +53 -9
- package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +69 -55
- package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +7 -2
- package/dist/extensions/pi-subagents/src/missions/goal-driver.ts +45 -32
- package/dist/extensions/pi-subagents/src/missions/store.ts +11 -2
- package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +1 -44
- package/dist/extensions/pi-subagents/src/policy/authority.ts +5 -1
- package/dist/extensions/pi-subagents/src/profiles/profiles.ts +30 -18
- package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +59 -9
- package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +18 -2
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +463 -248
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +112 -66
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +33 -20
- package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +47 -17
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -5
- package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +24 -11
- package/dist/extensions/pi-subagents/src/runs/background/await-async-run.ts +78 -0
- package/dist/extensions/pi-subagents/src/runs/background/binary-bootstrap.ts +66 -0
- package/dist/extensions/pi-subagents/src/runs/background/calendar-schedule.ts +90 -0
- package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +19 -38
- package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +62 -3
- package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +82 -10
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +272 -24
- package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +30 -3
- package/dist/extensions/pi-subagents/src/runs/background/pid-namespace.ts +18 -0
- package/dist/extensions/pi-subagents/src/runs/background/process-terminal-candidate.ts +98 -0
- package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +18 -97
- package/dist/extensions/pi-subagents/src/runs/background/result-delivery-ownership.ts +269 -7
- package/dist/extensions/pi-subagents/src/runs/background/result-files.ts +14 -5
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +77 -22
- package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +4 -3
- package/dist/extensions/pi-subagents/src/runs/background/retained-nested-route-tracker.ts +15 -3
- package/dist/extensions/pi-subagents/src/runs/background/run-child-session.ts +126 -45
- package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +11 -6
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +18 -7
- package/dist/extensions/pi-subagents/src/runs/background/runner-aliases.ts +43 -51
- package/dist/extensions/pi-subagents/src/runs/background/runner-child-launch.ts +8 -1
- package/dist/extensions/pi-subagents/src/runs/background/runner-child-sessions.ts +5 -4
- package/dist/extensions/pi-subagents/src/runs/background/runner-http-dispatcher.ts +119 -0
- package/dist/extensions/pi-subagents/src/runs/background/runner-startup-failure.ts +56 -0
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +297 -69
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +67 -16
- package/dist/extensions/pi-subagents/src/runs/background/steering.ts +21 -3
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner-bootstrap.ts +276 -0
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +660 -578
- package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +177 -29
- package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +77 -28
- package/dist/extensions/pi-subagents/src/runs/background/wait-subscriptions.ts +10 -4
- package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +7 -13
- package/dist/extensions/pi-subagents/src/runs/background/workflow-terminal-proof.ts +41 -23
- package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +19 -8
- package/dist/extensions/pi-subagents/src/runs/foreground/async-stop-action.ts +130 -7
- package/dist/extensions/pi-subagents/src/runs/foreground/command-action.ts +41 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +267 -385
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +4 -2
- package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +6 -10
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +1158 -413
- package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +3 -1
- package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +2 -1
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +200 -74
- package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +133 -34
- package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +6 -1
- package/dist/extensions/pi-subagents/src/runs/shared/child-commands.ts +228 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-hooks.ts +18 -18
- package/dist/extensions/pi-subagents/src/runs/shared/child-launch-plan.ts +16 -4
- package/dist/extensions/pi-subagents/src/runs/shared/child-launch.ts +55 -12
- package/dist/extensions/pi-subagents/src/runs/shared/child-lifecycle.ts +6 -3
- package/dist/extensions/pi-subagents/src/runs/shared/child-runtime-config.ts +11 -1
- package/dist/extensions/pi-subagents/src/runs/shared/child-session.ts +367 -74
- package/dist/extensions/pi-subagents/src/runs/shared/child-tool-plan.ts +50 -86
- package/dist/extensions/pi-subagents/src/runs/shared/claude-code-adapter.ts +288 -0
- package/dist/extensions/pi-subagents/src/runs/shared/codex-exec-adapter.ts +129 -0
- package/dist/extensions/pi-subagents/src/runs/shared/cursor-agent-adapter.ts +114 -0
- package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +5 -5
- package/dist/extensions/pi-subagents/src/runs/shared/effective-system-prompt.ts +33 -0
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-contract.ts +49 -10
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +61 -9
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-runner.ts +16 -9
- package/dist/extensions/pi-subagents/src/runs/shared/external-job-bridge.ts +55 -1
- package/dist/extensions/pi-subagents/src/runs/shared/git-environment.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/herdr-connection.ts +134 -0
- package/dist/extensions/pi-subagents/src/runs/shared/herdr-external-adapters.ts +169 -0
- package/dist/extensions/pi-subagents/src/runs/shared/herdr-machine.ts +279 -0
- package/dist/extensions/pi-subagents/src/runs/shared/herdr-pi-protocol.ts +59 -0
- package/dist/extensions/pi-subagents/src/runs/shared/herdr-placed-run.ts +263 -0
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-config-sources.ts +6 -2
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +108 -13
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-grant.ts +23 -7
- package/dist/extensions/pi-subagents/src/runs/shared/model-resolution-diagnostic.ts +76 -0
- package/dist/extensions/pi-subagents/src/runs/shared/{model-fallback.ts → model-resolution.ts} +65 -245
- package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +30 -11
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +24 -3
- package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +5 -4
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +55 -7
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +14 -4
- package/dist/extensions/pi-subagents/src/runs/shared/partial-output.ts +48 -0
- package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +12 -4
- package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +88 -1
- package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +12 -3
- package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +160 -9
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +49 -35
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +58 -19
- package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +21 -0
- package/dist/extensions/pi-subagents/src/runs/shared/usage-reconciliation.ts +73 -0
- package/dist/extensions/pi-subagents/src/runs/shared/workflow-async-child-guidance.ts +18 -0
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-apply.ts +160 -0
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +42 -20
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-lock.ts +29 -0
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-setup-command.ts +27 -4
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +94 -26
- package/dist/extensions/pi-subagents/src/shared/child-cache-retention.ts +43 -0
- package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +5 -3
- package/dist/extensions/pi-subagents/src/shared/disabled-features.ts +123 -0
- package/dist/extensions/pi-subagents/src/shared/extension-context.ts +14 -1
- package/dist/extensions/pi-subagents/src/shared/file-lease.ts +74 -0
- package/dist/extensions/pi-subagents/src/shared/fork-context.ts +27 -77
- package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +70 -10
- package/dist/extensions/pi-subagents/src/shared/model-info.ts +10 -1
- package/dist/extensions/pi-subagents/src/shared/opencode-session-headers.ts +30 -0
- package/dist/extensions/pi-subagents/src/shared/owner-record.ts +107 -0
- package/dist/extensions/pi-subagents/src/shared/package-version.ts +17 -0
- package/dist/extensions/pi-subagents/src/shared/parent-wake.ts +66 -0
- package/dist/extensions/pi-subagents/src/shared/process-identity.ts +87 -0
- package/dist/extensions/pi-subagents/src/shared/pruned-fork.ts +71 -58
- package/dist/extensions/pi-subagents/src/shared/required-child-extensions.ts +115 -0
- package/dist/extensions/pi-subagents/src/shared/settings-file-lease.ts +36 -0
- package/dist/extensions/pi-subagents/src/shared/settings.ts +7 -4
- package/dist/extensions/pi-subagents/src/shared/shortcuts.ts +1 -5
- package/dist/extensions/pi-subagents/src/shared/types.ts +155 -48
- package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +28 -2
- package/dist/extensions/pi-subagents/src/slash/delegation-request.ts +15 -1
- package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +19 -4
- package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +13 -2
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +15 -15
- package/dist/extensions/pi-subagents/src/slash/subagent-cost.ts +46 -9
- package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +29 -16
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +201 -26
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +33 -16
- package/dist/extensions/pi-subagents/src/tui/render.ts +334 -103
- package/dist/extensions/pi-subagents/src/tui/running-tone.ts +28 -0
- package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +27 -28
- package/dist/extensions/pi-subagents/src/watchdog/diff-tool.ts +47 -12
- package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +2 -2
- package/dist/extensions/pi-subagents/src/watchdog/model-selection.ts +22 -2
- package/dist/extensions/pi-subagents/src/watchdog/permission-arbiter.ts +17 -17
- package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +24 -8
- package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +43 -39
- package/dist/extensions/pi-subagents/src/watchdog/render.ts +2 -2
- package/dist/extensions/pi-subagents/src/watchdog/review.ts +127 -78
- package/dist/extensions/pi-subagents/src/watchdog/rules.ts +1 -1
- package/dist/extensions/pi-subagents/src/watchdog/runtime.ts +107 -31
- package/dist/extensions/pi-subagents/src/watchdog/scope.ts +1 -1
- package/dist/extensions/pi-subagents/src/watchdog/settings.ts +22 -14
- package/dist/extensions/pi-subagents/src/watchdog/tool-actions.ts +14 -13
- package/dist/extensions/pi-subagents/src/watchdog/turn-delta.ts +35 -6
- package/dist/extensions/pi-subagents/src/watchdog/types.ts +6 -4
- package/dist/extensions/pi-subagents/src/watchdog/warning-format.ts +2 -2
- package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -3
- package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +500 -65
- package/dist/extensions/pi-subagents/src/workflows/structured-workflow-scripts.ts +177 -0
- package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +8 -2
- package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +5 -3
- package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +70 -10
- package/dist/extensions/pi-subagents/src/workflows/workflow-resources.ts +57 -18
- package/dist/extensions/pi-subagents/src/workflows/workflow-reuse.ts +120 -0
- package/dist/extensions/pi-subagents/src/workflows/workflow-revival.ts +123 -0
- package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +5 -2
- package/dist/extensions/pi-subagents/test/fixtures/cwd-workflow-child.ts +37 -0
- package/dist/extensions/pi-subagents/test/fixtures/herdr-allocation-lock-child.ts +16 -0
- package/dist/extensions/pi-subagents/test/fixtures/herdr-provision-child.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/native-nested-wait-provider.ts +76 -0
- package/dist/extensions/pi-subagents/test/fixtures/runner-bootstrap-harness.ts +36 -0
- package/dist/extensions/pi-subagents/test/fixtures/schedule-history-writer.mjs +48 -0
- package/dist/extensions/pi-subagents/test/fixtures/settings-race-writer.mjs +57 -0
- package/dist/extensions/pi-subagents/test/fixtures/workflow-cwd-access-failure.ts +33 -0
- package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +40 -7
- package/dist/extensions/pi-subagents/test/integration/async-attention-clearing.test.ts +192 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-1.test.ts +435 -276
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-2.test.ts +435 -397
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-3.test.ts +918 -497
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-4.test.ts +264 -17
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +185 -22
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +3 -2
- package/dist/extensions/pi-subagents/test/integration/claude-code-dispatch.test.ts +127 -0
- package/dist/extensions/pi-subagents/test/integration/deadline-checkpoint.test.ts +126 -0
- package/dist/extensions/pi-subagents/test/integration/doctor-executor.test.ts +29 -1
- package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +88 -0
- package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +450 -13
- package/dist/extensions/pi-subagents/test/integration/foreign-workflow-steering.test.ts +10 -6
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +105 -86
- package/dist/extensions/pi-subagents/test/integration/in-process-child.test.ts +403 -18
- package/dist/extensions/pi-subagents/test/integration/inline-workflow-visibility.test.ts +351 -0
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +195 -10
- package/dist/extensions/pi-subagents/test/integration/model-resolution-diagnostic.test.ts +108 -0
- package/dist/extensions/pi-subagents/test/integration/nested-async-wait.test.ts +61 -0
- package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +5 -4
- package/dist/extensions/pi-subagents/test/integration/recovered-assistant-error.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +6 -4
- package/dist/extensions/pi-subagents/test/integration/render-widget-mouse.test.ts +84 -0
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +242 -16
- package/dist/extensions/pi-subagents/test/integration/result-publication.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +221 -4
- package/dist/extensions/pi-subagents/test/integration/single-execution.part-1.test.ts +1435 -248
- package/dist/extensions/pi-subagents/test/integration/single-execution.part-2.test.ts +454 -515
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +140 -21
- package/dist/extensions/pi-subagents/test/integration/stop-all-background.test.ts +142 -0
- package/dist/extensions/pi-subagents/test/integration/structured-workflows.test.ts +105 -0
- package/dist/extensions/pi-subagents/test/integration/workflow-result-publication.test.ts +90 -11
- package/dist/extensions/pi-subagents/test/integration/workflow-steer-inbox.test.ts +18 -15
- package/dist/extensions/pi-subagents/test/integration/workflow-worktree-admission.test.ts +100 -0
- package/dist/extensions/pi-subagents/test/smoke/clean-install.mjs +106 -0
- package/dist/extensions/pi-subagents/test/smoke/npm-background.mjs +43 -0
- package/dist/extensions/pi-subagents/test/smoke/packed-runner-selection.mjs +42 -0
- package/dist/extensions/pi-subagents/test/smoke/runner-loader-capability.mjs +50 -0
- package/dist/extensions/pi-subagents/test/smoke/sdk-child.ts +57 -0
- package/dist/extensions/pi-subagents/test/smoke/{pi085-extension.ts → sdk-extension.ts} +2 -2
- package/dist/extensions/pi-subagents/test/smoke/standalone-background.mjs +140 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-fault.ts +43 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-matrix.mjs +65 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-observer.ts +8 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-parent.ts +220 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-provider.ts +58 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-release.json +8 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-revival.ts +109 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-shared.ts +79 -0
- package/dist/extensions/pi-subagents/test/smoke/tool-activation.test.ts +128 -0
- package/dist/extensions/pi-subagents/test/support/async-execution-fixture.ts +6 -25
- package/dist/extensions/pi-subagents/test/support/async-result-timeout-evidence.ts +61 -0
- package/dist/extensions/pi-subagents/test/support/fake-child-session.ts +130 -9
- package/dist/extensions/pi-subagents/test/support/foreign-workflow-steer-host.mjs +15 -7
- package/dist/extensions/pi-subagents/test/support/helpers.ts +11 -14
- package/dist/extensions/pi-subagents/test/support/isolated-temp-root.mjs +21 -3
- package/dist/extensions/pi-subagents/test/support/native-peer-loader.mjs +15 -0
- package/dist/extensions/pi-subagents/test/support/node-command.ts +29 -6
- package/dist/extensions/pi-subagents/test/support/notify-diagnostics-fixture.ts +5 -3
- package/dist/extensions/pi-subagents/test/support/single-execution-fixture.ts +7 -15
- package/dist/extensions/pi-subagents/test/support/watchdog-stable-host-loader.mjs +23 -0
- package/dist/extensions/pi-subagents/test/unit/acceptance-compaction.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +158 -155
- package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +52 -1
- package/dist/extensions/pi-subagents/test/unit/advertised-agent-prompt.test.ts +21 -17
- package/dist/extensions/pi-subagents/test/unit/advertised-agent-refresh.test.ts +105 -36
- package/dist/extensions/pi-subagents/test/unit/advertisement-barrier.test.ts +151 -0
- package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +1 -2
- package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +33 -3
- package/dist/extensions/pi-subagents/test/unit/agent-end-auto-drain.test.ts +149 -0
- package/dist/extensions/pi-subagents/test/unit/agent-exclude-dirs.test.ts +246 -0
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +62 -87
- package/dist/extensions/pi-subagents/test/unit/agent-global-root-override.test.ts +86 -0
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +398 -48
- package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +126 -1
- package/dist/extensions/pi-subagents/test/unit/agent-name-resolution.test.ts +75 -0
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +94 -42
- package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +73 -3
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +428 -2
- package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +4 -4
- package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +112 -1
- package/dist/extensions/pi-subagents/test/unit/async-result-timeout-evidence.test.ts +53 -0
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +92 -4
- package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +58 -6
- package/dist/extensions/pi-subagents/test/unit/async-run-history.test.ts +123 -0
- package/dist/extensions/pi-subagents/test/unit/async-spawn-package-dir.test.ts +203 -0
- package/dist/extensions/pi-subagents/test/unit/async-spawn-preload.test.ts +26 -35
- package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +185 -0
- package/dist/extensions/pi-subagents/test/unit/authority-policy.test.ts +9 -1
- package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +106 -1
- package/dist/extensions/pi-subagents/test/unit/await-async-run.test.ts +202 -0
- package/dist/extensions/pi-subagents/test/unit/binary-async-spawn.test.ts +115 -0
- package/dist/extensions/pi-subagents/test/unit/binary-pi-spawn.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/unit/calendar-schedule.test.ts +70 -0
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +38 -0
- package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +10 -2
- package/dist/extensions/pi-subagents/test/unit/changelog-format.test.ts +11 -0
- package/dist/extensions/pi-subagents/test/unit/child-cache-retention.test.ts +87 -0
- package/dist/extensions/pi-subagents/test/unit/child-commands.test.ts +243 -0
- package/dist/extensions/pi-subagents/test/unit/child-external-job-bridge.test.ts +126 -0
- package/dist/extensions/pi-subagents/test/unit/child-launch-plan.test.ts +12 -1
- package/dist/extensions/pi-subagents/test/unit/child-lifecycle.test.ts +36 -0
- package/dist/extensions/pi-subagents/test/unit/child-runtime-config.test.ts +24 -0
- package/dist/extensions/pi-subagents/test/unit/child-session-commands.test.ts +162 -0
- package/dist/extensions/pi-subagents/test/unit/child-session-host-sdk.test.ts +226 -0
- package/dist/extensions/pi-subagents/test/unit/child-session-parent-providers.test.ts +200 -0
- package/dist/extensions/pi-subagents/test/unit/child-session-queued.test.ts +260 -0
- package/dist/extensions/pi-subagents/test/unit/child-tool-plan-permission-system.test.ts +3 -98
- package/dist/extensions/pi-subagents/test/unit/child-tool-plan.test.ts +222 -1
- package/dist/extensions/pi-subagents/test/unit/claude-code-adapter.test.ts +314 -0
- package/dist/extensions/pi-subagents/test/unit/claude-code-dispatch.test.ts +182 -0
- package/dist/extensions/pi-subagents/test/unit/codex-exec-adapter.test.ts +157 -0
- package/dist/extensions/pi-subagents/test/unit/command-action.test.ts +50 -0
- package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +25 -11
- package/dist/extensions/pi-subagents/test/unit/completion-replay.test.ts +3 -1
- package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +18 -0
- package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +7 -1
- package/dist/extensions/pi-subagents/test/unit/cursor-agent-adapter.test.ts +220 -0
- package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +104 -32
- package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +138 -1
- package/dist/extensions/pi-subagents/test/unit/disabled-features.test.ts +227 -0
- package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +48 -9
- package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +7 -4
- package/dist/extensions/pi-subagents/test/unit/extension-lazy-loading.test.ts +21 -0
- package/dist/extensions/pi-subagents/test/unit/extension-maintenance-lifecycle.test.ts +66 -0
- package/dist/extensions/pi-subagents/test/unit/extension-module-preload.test.ts +49 -0
- package/dist/extensions/pi-subagents/test/unit/external-cli-runner.test.ts +104 -3
- package/dist/extensions/pi-subagents/test/unit/file-lease.test.ts +17 -0
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +316 -0
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +58 -7
- package/dist/extensions/pi-subagents/test/unit/fork-context.test.ts +25 -96
- package/dist/extensions/pi-subagents/test/unit/ghostty-inspector.test.ts +92 -0
- package/dist/extensions/pi-subagents/test/unit/global-npm-root.test.ts +108 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-connection.test.ts +43 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-external-adapters.test.ts +89 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-inspector-bootstrap.test.ts +11 -20
- package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +113 -19
- package/dist/extensions/pi-subagents/test/unit/herdr-machine.test.ts +161 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-native-placement.test.ts +187 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-session-roots-codec.test.ts +7 -12
- package/dist/extensions/pi-subagents/test/unit/herdr-shell-command.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +182 -87
- package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +68 -49
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +295 -135
- package/dist/extensions/pi-subagents/test/unit/inspect-rpc.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/inspector-authority-policy.test.ts +144 -0
- package/dist/extensions/pi-subagents/test/unit/inspector-registration.test.ts +128 -0
- package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +49 -1
- package/dist/extensions/pi-subagents/test/unit/mcp-direct-tool-grant.test.ts +74 -1
- package/dist/extensions/pi-subagents/test/unit/mcp-direct-tool-resolution.test.ts +112 -0
- package/dist/extensions/pi-subagents/test/unit/mission-global-projection.test.ts +215 -0
- package/dist/extensions/pi-subagents/test/unit/mission-goal-driver.test.ts +65 -1
- package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +2 -1
- package/dist/extensions/pi-subagents/test/unit/model-resolution-diagnostic.test.ts +78 -0
- package/dist/extensions/pi-subagents/test/unit/model-resolution.test.ts +153 -0
- package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +43 -1
- package/dist/extensions/pi-subagents/test/unit/mutation-evidence.test.ts +1 -21
- package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +279 -2
- package/dist/extensions/pi-subagents/test/unit/nested-control-fanout.test.ts +73 -0
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +297 -3
- package/dist/extensions/pi-subagents/test/unit/notify-diagnostics.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +431 -23
- package/dist/extensions/pi-subagents/test/unit/observability.test.ts +198 -0
- package/dist/extensions/pi-subagents/test/unit/opencode-session-headers.test.ts +32 -0
- package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +89 -21
- package/dist/extensions/pi-subagents/test/unit/owned-process-tree.test.ts +31 -1
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +18 -24
- package/dist/extensions/pi-subagents/test/unit/parent-wake.test.ts +206 -0
- package/dist/extensions/pi-subagents/test/unit/partial-output.test.ts +53 -0
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +216 -32
- package/dist/extensions/pi-subagents/test/unit/pi-spawn-host-root.test.ts +82 -0
- package/dist/extensions/pi-subagents/test/unit/pi-subagents-policy-guidance.test.ts +28 -0
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +193 -104
- package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +16 -1
- package/dist/extensions/pi-subagents/test/unit/process-identity.test.ts +75 -0
- package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +17 -1
- package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +89 -9
- package/dist/extensions/pi-subagents/test/unit/prompt-audit-optional-peers.test.ts +6 -0
- package/dist/extensions/pi-subagents/test/unit/prompt-audit-provider-routing.test.ts +69 -0
- package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +23 -1
- package/dist/extensions/pi-subagents/test/unit/pruned-fork.test.ts +117 -3
- package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +35 -14
- package/dist/extensions/pi-subagents/test/unit/readonly-drain-observation.test.ts +3 -2
- package/dist/extensions/pi-subagents/test/unit/release-readiness.test.ts +715 -0
- package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +261 -9
- package/dist/extensions/pi-subagents/test/unit/reply-workflow-script.test.ts +37 -0
- package/dist/extensions/pi-subagents/test/unit/required-child-extensions.test.ts +114 -0
- package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +11 -1
- package/dist/extensions/pi-subagents/test/unit/result-takeover.test.ts +332 -0
- package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +22 -2
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +125 -18
- package/dist/extensions/pi-subagents/test/unit/run-child-session.test.ts +230 -0
- package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +50 -1
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +301 -4
- package/dist/extensions/pi-subagents/test/unit/runner-bootstrap.test.ts +182 -0
- package/dist/extensions/pi-subagents/test/unit/runner-http-dispatcher.test.ts +136 -0
- package/dist/extensions/pi-subagents/test/unit/runner-peer-loader.test.ts +68 -0
- package/dist/extensions/pi-subagents/test/unit/runner-peer-symlinks.test.ts +50 -0
- package/dist/extensions/pi-subagents/test/unit/running-tone.test.ts +13 -0
- package/dist/extensions/pi-subagents/test/unit/runtime-agent-registration.test.ts +155 -4
- package/dist/extensions/pi-subagents/test/unit/schedule-claim-initialization.test.ts +71 -0
- package/dist/extensions/pi-subagents/test/unit/schedule-claim-preservation.test.ts +98 -0
- package/dist/extensions/pi-subagents/test/unit/schedule-history-transactions.test.ts +201 -0
- package/dist/extensions/pi-subagents/test/unit/scheduled-mission.test.ts +317 -0
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +412 -11
- package/dist/extensions/pi-subagents/test/unit/scheduled-store-root.test.ts +2 -8
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +70 -71
- package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +748 -5
- package/dist/extensions/pi-subagents/test/unit/session-liveness-delivery.test.ts +337 -0
- package/dist/extensions/pi-subagents/test/unit/settings-atomic-save.test.ts +419 -0
- package/dist/extensions/pi-subagents/test/unit/settings-transactions.test.ts +88 -0
- package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +13 -1
- package/dist/extensions/pi-subagents/test/unit/skills-disable-model-invocation.test.ts +164 -0
- package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +35 -2
- package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +334 -9
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +170 -0
- package/dist/extensions/pi-subagents/test/unit/steering.test.ts +34 -5
- package/dist/extensions/pi-subagents/test/unit/structured-output-validation.test.ts +199 -0
- package/dist/extensions/pi-subagents/test/unit/structured-workflow-resources.test.ts +241 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +47 -38
- package/dist/extensions/pi-subagents/test/unit/subagent-cost.test.ts +97 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +10 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +343 -44
- package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +410 -11
- package/dist/extensions/pi-subagents/test/unit/supervisor-ask-registration.test.ts +459 -22
- package/dist/extensions/pi-subagents/test/unit/temp-paths.test.ts +43 -3
- package/dist/extensions/pi-subagents/test/unit/timeout-defaults.test.ts +11 -1
- package/dist/extensions/pi-subagents/test/unit/tool-activation-stale-peer.test.ts +32 -0
- package/dist/extensions/pi-subagents/test/unit/tool-activation.test.ts +313 -0
- package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +14 -0
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +76 -89
- package/dist/extensions/pi-subagents/test/unit/typed-gate-output.test.ts +141 -0
- package/dist/extensions/pi-subagents/test/unit/upgrade-notice.test.ts +31 -0
- package/dist/extensions/pi-subagents/test/unit/usage-reconciliation-owners.test.ts +66 -0
- package/dist/extensions/pi-subagents/test/unit/usage-reconciliation.test.ts +23 -0
- package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +195 -1
- package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +3 -1
- package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +48 -45
- package/dist/extensions/pi-subagents/test/unit/watchdog-compaction-scope.test.ts +94 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-diff-tool.test.ts +48 -3
- package/dist/extensions/pi-subagents/test/unit/watchdog-native-scheduling.test.ts +107 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-permission-arbiter.test.ts +95 -7
- package/dist/extensions/pi-subagents/test/unit/watchdog-register-child.test.ts +79 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-render.test.ts +7 -4
- package/dist/extensions/pi-subagents/test/unit/watchdog-review.test.ts +111 -24
- package/dist/extensions/pi-subagents/test/unit/watchdog-rules.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +283 -2
- package/dist/extensions/pi-subagents/test/unit/watchdog-scope.test.ts +3 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +12 -1
- package/dist/extensions/pi-subagents/test/unit/watchdog-stable-host-layout.test.ts +23 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +30 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-turn-delta.test.ts +39 -2
- package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +18 -1
- package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +8 -4
- package/dist/extensions/pi-subagents/test/unit/workflow-child-summary.test.ts +10 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +6 -3
- package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +44 -1
- package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +28 -1
- package/dist/extensions/pi-subagents/test/unit/workflow-revival.test.ts +85 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-scripts-feature.test.ts +177 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-terminal-proof.test.ts +8 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-worktree-admission.test.ts +29 -0
- package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +343 -4
- package/dist/extensions/pi-subagents/test/unit/worktree-lock.test.ts +123 -0
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +252 -22
- package/dist/extensions/pi-subagents/tsconfig.build.json +13 -0
- package/dist/extensions/pi-tool-display/tests/custom-tool-overrides.test.ts +1 -1
- package/dist/extensions/pi-tool-display/tests/tool-overrides-config.test.ts +1 -1
- package/dist/extensions/pi-tool-display/tests/tool-overrides-mcp.test.ts +24 -1
- package/dist/extensions/pi-tool-display/tests/tool-overrides-registration.test.ts +6 -2
- package/dist/extensions/pi-web-agent/src/extension.ts +1 -5
- package/dist/extensions/pi-zentui/.github/workflows/ci.yml +67 -4
- package/dist/extensions/pi-zentui/AGENTS.md +3 -2
- package/dist/extensions/pi-zentui/README.md +60 -32
- package/dist/extensions/pi-zentui/docs/configuration.md +662 -51
- package/dist/extensions/pi-zentui/docs/footer-format.md +174 -5
- package/dist/extensions/pi-zentui/extensions/zentui/accent-rail-editor.ts +15 -4
- package/dist/extensions/pi-zentui/extensions/zentui/average-token-rate.ts +146 -0
- package/dist/extensions/pi-zentui/extensions/zentui/codex-quota-display.ts +34 -0
- package/dist/extensions/pi-zentui/extensions/zentui/codex-quota.ts +298 -0
- package/dist/extensions/pi-zentui/extensions/zentui/component-colors.ts +172 -0
- package/dist/extensions/pi-zentui/extensions/zentui/component-settings.ts +243 -0
- package/dist/extensions/pi-zentui/extensions/zentui/config.ts +851 -114
- package/dist/extensions/pi-zentui/extensions/zentui/custom-value-colors.ts +93 -0
- package/dist/extensions/pi-zentui/extensions/zentui/custom-variable-demand.ts +61 -0
- package/dist/extensions/pi-zentui/extensions/zentui/custom-variable-format.ts +80 -0
- package/dist/extensions/pi-zentui/extensions/zentui/custom-variables.ts +152 -0
- package/dist/extensions/pi-zentui/extensions/zentui/editor-metadata-format.ts +138 -23
- package/dist/extensions/pi-zentui/extensions/zentui/editor-mouse.ts +89 -0
- package/dist/extensions/pi-zentui/extensions/zentui/extension-status-controller.ts +148 -0
- package/dist/extensions/pi-zentui/extensions/zentui/extension-status-settings.ts +40 -0
- package/dist/extensions/pi-zentui/extensions/zentui/extension-status.ts +109 -1
- package/dist/extensions/pi-zentui/extensions/zentui/footer-format.ts +203 -23
- package/dist/extensions/pi-zentui/extensions/zentui/footer-layout.ts +80 -3
- package/dist/extensions/pi-zentui/extensions/zentui/footer-text.ts +1 -1
- package/dist/extensions/pi-zentui/extensions/zentui/footer.ts +432 -125
- package/dist/extensions/pi-zentui/extensions/zentui/format.ts +92 -4
- package/dist/extensions/pi-zentui/extensions/zentui/git.ts +47 -30
- package/dist/extensions/pi-zentui/extensions/zentui/github-status.ts +575 -0
- package/dist/extensions/pi-zentui/extensions/zentui/host-project-changes.ts +25 -0
- package/dist/extensions/pi-zentui/extensions/zentui/host-template-values.ts +29 -0
- package/dist/extensions/pi-zentui/extensions/zentui/icons.ts +53 -13
- package/dist/extensions/pi-zentui/extensions/zentui/index.ts +778 -258
- package/dist/extensions/pi-zentui/extensions/zentui/interaction-summary.ts +70 -5
- package/dist/extensions/pi-zentui/extensions/zentui/layered-editor.ts +55 -0
- package/dist/extensions/pi-zentui/extensions/zentui/live-context.ts +6 -1
- package/dist/extensions/pi-zentui/extensions/zentui/live-metadata-demand.ts +72 -0
- package/dist/extensions/pi-zentui/extensions/zentui/live-metadata-display.ts +21 -0
- package/dist/extensions/pi-zentui/extensions/zentui/live-metadata.ts +255 -0
- package/dist/extensions/pi-zentui/extensions/zentui/minimalist-editor.ts +476 -36
- package/dist/extensions/pi-zentui/extensions/zentui/minimalist-settings.ts +118 -0
- package/dist/extensions/pi-zentui/extensions/zentui/minimalist-template.ts +177 -0
- package/dist/extensions/pi-zentui/extensions/zentui/omp-editor-frame.ts +148 -0
- package/dist/extensions/pi-zentui/extensions/zentui/omp-statusline.ts +569 -0
- package/dist/extensions/pi-zentui/extensions/zentui/omp-template-lookups.ts +344 -0
- package/dist/extensions/pi-zentui/extensions/zentui/omp-template-metrics.ts +91 -0
- package/dist/extensions/pi-zentui/extensions/zentui/omp-template-modes.ts +323 -0
- package/dist/extensions/pi-zentui/extensions/zentui/omp-ui.ts +210 -0
- package/dist/extensions/pi-zentui/extensions/zentui/package-version.ts +30 -12
- package/dist/extensions/pi-zentui/extensions/zentui/project-demand.ts +46 -0
- package/dist/extensions/pi-zentui/extensions/zentui/project-discovery.ts +58 -0
- package/dist/extensions/pi-zentui/extensions/zentui/project-refresh.ts +10 -3
- package/dist/extensions/pi-zentui/extensions/zentui/project-state.ts +37 -0
- package/dist/extensions/pi-zentui/extensions/zentui/repository-root.ts +1 -0
- package/dist/extensions/pi-zentui/extensions/zentui/runtime.ts +119 -43
- package/dist/extensions/pi-zentui/extensions/zentui/selector-border.ts +40 -29
- package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +1268 -722
- package/dist/extensions/pi-zentui/extensions/zentui/settings-keys.ts +59 -0
- package/dist/extensions/pi-zentui/extensions/zentui/settings-list-selection.ts +13 -0
- package/dist/extensions/pi-zentui/extensions/zentui/settings-previews.ts +11 -4
- package/dist/extensions/pi-zentui/extensions/zentui/state.ts +24 -11
- package/dist/extensions/pi-zentui/extensions/zentui/style.ts +6 -0
- package/dist/extensions/pi-zentui/extensions/zentui/telemetry.ts +113 -11
- package/dist/extensions/pi-zentui/extensions/zentui/thinking-experimental.ts +234 -46
- package/dist/extensions/pi-zentui/extensions/zentui/thinking-steps.ts +20 -5
- package/dist/extensions/pi-zentui/extensions/zentui/token-rate.ts +313 -0
- package/dist/extensions/pi-zentui/extensions/zentui/turn-summary-format.ts +59 -0
- package/dist/extensions/pi-zentui/extensions/zentui/turn-summary-rate.ts +52 -0
- package/dist/extensions/pi-zentui/extensions/zentui/ui.ts +640 -172
- package/dist/extensions/pi-zentui/extensions/zentui/user-message-styles.ts +72 -34
- package/dist/extensions/pi-zentui/extensions/zentui/user-message.ts +219 -34
- package/dist/extensions/pi-zentui/extensions/zentui/working-line.ts +495 -119
- package/dist/extensions/pi-zentui/omp.ts +157 -0
- package/dist/extensions/pi-zentui/package-lock.json +3762 -1507
- package/dist/extensions/pi-zentui/package.json +50 -12
- package/dist/extensions/pi-zentui/test/accent-rail-editor.test.ts +13 -2
- package/dist/extensions/pi-zentui/test/average-token-rate.test.ts +297 -0
- package/dist/extensions/pi-zentui/test/behavior-compatibility.mjs +89 -0
- package/dist/extensions/pi-zentui/test/codex-quota-lifecycle.test.ts +284 -0
- package/dist/extensions/pi-zentui/test/codex-quota-rendering.test.ts +466 -0
- package/dist/extensions/pi-zentui/test/codex-quota.test.ts +440 -0
- package/dist/extensions/pi-zentui/test/component-colors.test.ts +554 -0
- package/dist/extensions/pi-zentui/test/component-settings.test.ts +364 -0
- package/dist/extensions/pi-zentui/test/config-component-independence.test.ts +402 -0
- package/dist/extensions/pi-zentui/test/config-extension-status-choice.test.ts +233 -0
- package/dist/extensions/pi-zentui/test/config-hidden-extension-status-colors.test.ts +118 -0
- package/dist/extensions/pi-zentui/test/config-hidden-extension-status-placement.test.ts +142 -0
- package/dist/extensions/pi-zentui/test/config-minimalist-templates.test.ts +240 -0
- package/dist/extensions/pi-zentui/test/config-template-variables.test.ts +85 -0
- package/dist/extensions/pi-zentui/test/config.test.ts +80 -17
- package/dist/extensions/pi-zentui/test/custom-value-colors-integration.test.ts +453 -0
- package/dist/extensions/pi-zentui/test/custom-value-colors.test.ts +399 -0
- package/dist/extensions/pi-zentui/test/custom-variable-alias-prototypes.test.ts +177 -0
- package/dist/extensions/pi-zentui/test/custom-variable-consumers.test.ts +194 -0
- package/dist/extensions/pi-zentui/test/custom-variable-demand.test.ts +169 -0
- package/dist/extensions/pi-zentui/test/custom-variable-probe-reservation.test.ts +141 -0
- package/dist/extensions/pi-zentui/test/custom-variables-lifecycle.integration.test.ts +365 -0
- package/dist/extensions/pi-zentui/test/custom-variables.test.ts +330 -0
- package/dist/extensions/pi-zentui/test/editor-metadata-format.test.ts +121 -0
- package/dist/extensions/pi-zentui/test/editor-mouse.test.ts +507 -0
- package/dist/extensions/pi-zentui/test/editor-viewport-indicators.test.ts +247 -20
- package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +204 -260
- package/dist/extensions/pi-zentui/test/extension-status-controller.test.ts +323 -0
- package/dist/extensions/pi-zentui/test/extension-status-lifecycle.integration.test.ts +466 -0
- package/dist/extensions/pi-zentui/test/extension-status-settings.test.ts +79 -0
- package/dist/extensions/pi-zentui/test/footer-alignment.test.ts +135 -0
- package/dist/extensions/pi-zentui/test/footer-authority.test.ts +69 -0
- package/dist/extensions/pi-zentui/test/footer-auto-compaction.test.ts +148 -0
- package/dist/extensions/pi-zentui/test/footer-format-cache.test.ts +186 -0
- package/dist/extensions/pi-zentui/test/footer-format.test.ts +154 -4
- package/dist/extensions/pi-zentui/test/footer-hidden.test.ts +312 -0
- package/dist/extensions/pi-zentui/test/footer-hyperlink.test.ts +22 -0
- package/dist/extensions/pi-zentui/test/footer-layout.test.ts +80 -0
- package/dist/extensions/pi-zentui/test/footer-thinking-level.test.ts +123 -0
- package/dist/extensions/pi-zentui/test/format.test.ts +75 -1
- package/dist/extensions/pi-zentui/test/git-probes.test.ts +182 -0
- package/dist/extensions/pi-zentui/test/github-status.test.ts +931 -0
- package/dist/extensions/pi-zentui/test/host-template-surfaces.test.ts +287 -0
- package/dist/extensions/pi-zentui/test/icons.test.ts +86 -16
- package/dist/extensions/pi-zentui/test/layered-editor.test.ts +53 -0
- package/dist/extensions/pi-zentui/test/live-context-integration.test.ts +154 -7
- package/dist/extensions/pi-zentui/test/live-context.test.ts +45 -0
- package/dist/extensions/pi-zentui/test/live-metadata-lifecycle.integration.test.ts +963 -0
- package/dist/extensions/pi-zentui/test/live-metadata.test.ts +767 -0
- package/dist/extensions/pi-zentui/test/minimalist-cache-hit-colors.test.ts +183 -0
- package/dist/extensions/pi-zentui/test/minimalist-editor.test.ts +222 -4
- package/dist/extensions/pi-zentui/test/minimalist-settings.test.ts +103 -0
- package/dist/extensions/pi-zentui/test/minimalist-templates.test.ts +489 -0
- package/dist/extensions/pi-zentui/test/omp-editor-composers.test.ts +324 -0
- package/dist/extensions/pi-zentui/test/omp-statusline.test.ts +579 -0
- package/dist/extensions/pi-zentui/test/omp-template-lookups.test.ts +630 -0
- package/dist/extensions/pi-zentui/test/omp-template-metrics.test.ts +72 -0
- package/dist/extensions/pi-zentui/test/omp-template-modes.test.ts +557 -0
- package/dist/extensions/pi-zentui/test/omp-ui.test.ts +93 -0
- package/dist/extensions/pi-zentui/test/package-contents.mjs +1 -0
- package/dist/extensions/pi-zentui/test/pi-version-policy.test.ts +37 -0
- package/dist/extensions/pi-zentui/test/project-demand-integration.test.ts +542 -0
- package/dist/extensions/pi-zentui/test/project-discovery.test.ts +412 -0
- package/dist/extensions/pi-zentui/test/project-refresh.test.ts +44 -0
- package/dist/extensions/pi-zentui/test/project-state.test.ts +38 -1
- package/dist/extensions/pi-zentui/test/responsive-dependencies.test.ts +7 -7
- package/dist/extensions/pi-zentui/test/runtime.test.ts +127 -2
- package/dist/extensions/pi-zentui/test/selesai-v030-gate.json +939 -0
- package/dist/extensions/pi-zentui/test/settings-command.test.ts +1330 -82
- package/dist/extensions/pi-zentui/test/settings-keys.test.ts +41 -0
- package/dist/extensions/pi-zentui/test/settings-list-selection.test.ts +88 -0
- package/dist/extensions/pi-zentui/test/settings-previews.test.ts +4 -1
- package/dist/extensions/pi-zentui/test/state.test.ts +15 -1
- package/dist/extensions/pi-zentui/test/telemetry-lifecycle-integration.test.ts +214 -12
- package/dist/extensions/pi-zentui/test/telemetry-snapshot.test.ts +246 -0
- package/dist/extensions/pi-zentui/test/thinking-experimental-cache.test.ts +246 -0
- package/dist/extensions/pi-zentui/test/thinking-experimental-rows.test.ts +22 -0
- package/dist/extensions/pi-zentui/test/thinking-experimental-tui.mjs +113 -51
- package/dist/extensions/pi-zentui/test/thinking-experimental.test.ts +576 -76
- package/dist/extensions/pi-zentui/test/thinking-steps.test.ts +23 -0
- package/dist/extensions/pi-zentui/test/token-rate.test.ts +450 -0
- package/dist/extensions/pi-zentui/test/turn-summary-format.test.ts +207 -0
- package/dist/extensions/pi-zentui/test/turn-summary-lifecycle.integration.test.ts +72 -5
- package/dist/extensions/pi-zentui/test/turn-summary-rate.test.ts +158 -0
- package/dist/extensions/pi-zentui/test/usage-lifecycle-integration.test.ts +421 -0
- package/dist/extensions/pi-zentui/test/usage-snapshot.test.ts +154 -0
- package/dist/extensions/pi-zentui/test/user-message-cache.test.ts +239 -0
- package/dist/extensions/pi-zentui/test/user-message-native-reduced-capabilities.test.ts +61 -0
- package/dist/extensions/pi-zentui/test/user-message-native.test.ts +447 -0
- package/dist/extensions/pi-zentui/test/user-message-styles.test.ts +2 -2
- package/dist/extensions/pi-zentui/test/working-line-editor-placement.test.ts +317 -0
- package/dist/extensions/pi-zentui/test/working-line-generation-cache.test.ts +238 -0
- package/dist/extensions/pi-zentui/test/working-line-lifecycle.integration.test.ts +674 -179
- package/dist/extensions/pi-zentui/test/working-line-message-ownership.test.ts +239 -0
- package/dist/extensions/pi-zentui/test/working-line-metric-animation.test.ts +284 -0
- package/dist/extensions/pi-zentui/test/working-line-placement.test.ts +298 -0
- package/dist/extensions/pi-zentui/test/working-line.test.ts +386 -18
- package/dist/extensions/pi-zentui/test/wrapped-editor-consumers.integration.test.ts +579 -0
- package/dist/extensions/pi-zentui/test/wrapped-editor-usage.integration.test.ts +298 -0
- package/dist/extensions/pi-zentui/tsconfig.json +1 -1
- package/dist/extensions/pi-zentui/vitest.host.config.ts +33 -0
- package/dist/extensions/question/index.ts +1 -5
- package/dist/extensions/rtk.test.ts +28 -15
- package/dist/extensions/rtk.ts +22 -22
- package/dist/extensions/skills-index/index.test.ts +99 -0
- package/dist/extensions/skills-index/index.ts +105 -0
- package/dist/extensions/skills-index/package.json +9 -0
- package/dist/extensions/tokenin-onboarding.ts +52 -210
- package/dist/extensions/tool-search/index.d.ts +11 -0
- package/dist/extensions/tool-search/index.js +14 -0
- package/dist/extensions/tool-search/tool.d.ts +72 -0
- package/dist/extensions/tool-search/tool.js +188 -0
- package/dist/index.d.ts +21 -9
- package/dist/index.js +17 -5
- package/dist/main.d.ts +10 -0
- package/dist/main.js +107 -43
- package/dist/migrations.js +4 -3
- package/dist/modes/index.d.ts +2 -1
- package/dist/modes/interactive/bug-report.js +4 -0
- package/dist/modes/interactive/components/armin.d.ts +3 -0
- package/dist/modes/interactive/components/armin.js +7 -5
- package/dist/modes/interactive/components/assistant-message.js +1 -1
- package/dist/modes/interactive/components/auth-url.d.ts +13 -0
- package/dist/modes/interactive/components/auth-url.js +36 -0
- package/dist/modes/interactive/components/bash-execution.d.ts +5 -1
- package/dist/modes/interactive/components/bash-execution.js +17 -14
- package/dist/modes/interactive/components/branch-summary-message.d.ts +2 -1
- package/dist/modes/interactive/components/branch-summary-message.js +5 -2
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +2 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +5 -2
- package/dist/modes/interactive/components/config-selector.js +13 -3
- package/dist/modes/interactive/components/custom-editor.js +7 -0
- package/dist/modes/interactive/components/custom-entry.d.ts +3 -1
- package/dist/modes/interactive/components/custom-entry.js +8 -2
- package/dist/modes/interactive/components/custom-message.js +1 -0
- package/dist/modes/interactive/components/first-time-setup.d.ts +4 -4
- package/dist/modes/interactive/components/first-time-setup.js +8 -2
- package/dist/modes/interactive/components/footer.d.ts +7 -0
- package/dist/modes/interactive/components/footer.js +44 -4
- package/dist/modes/interactive/components/index.d.ts +0 -1
- package/dist/modes/interactive/components/index.js +0 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +2 -0
- package/dist/modes/interactive/components/login-dialog.js +11 -5
- package/dist/modes/interactive/components/mermaid.d.ts +10 -0
- package/dist/modes/interactive/components/mermaid.js +74 -0
- package/dist/modes/interactive/components/model-selector.d.ts +14 -9
- package/dist/modes/interactive/components/model-selector.js +79 -31
- package/dist/modes/interactive/components/oauth-selector.d.ts +8 -2
- package/dist/modes/interactive/components/oauth-selector.js +24 -21
- package/dist/modes/interactive/components/pi-logo.d.ts +18 -0
- package/dist/modes/interactive/components/pi-logo.js +36 -0
- package/dist/modes/interactive/components/radius-login-selector.d.ts +14 -0
- package/dist/modes/interactive/components/radius-login-selector.js +84 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +4 -0
- package/dist/modes/interactive/components/scoped-models-selector.js +26 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +8 -11
- package/dist/modes/interactive/components/settings-selector.js +60 -102
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +5 -2
- package/dist/modes/interactive/components/themed-text.d.ts +16 -0
- package/dist/modes/interactive/components/themed-text.js +28 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +11 -18
- package/dist/modes/interactive/components/tool-execution.js +34 -47
- package/dist/modes/interactive/components/tree-selector.js +7 -0
- package/dist/modes/interactive/components/user-message.d.ts +3 -1
- package/dist/modes/interactive/components/user-message.js +14 -6
- package/dist/modes/interactive/components/visual-truncate.d.ts +27 -3
- package/dist/modes/interactive/components/visual-truncate.js +39 -6
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/interactive-mode.d.ts +41 -8
- package/dist/modes/interactive/interactive-mode.js +854 -492
- package/dist/modes/interactive/program-status-reporter.d.ts +33 -0
- package/dist/modes/interactive/program-status-reporter.js +109 -0
- package/dist/modes/interactive/theme/dark.json +59 -72
- package/dist/modes/interactive/theme/light.json +57 -69
- package/dist/modes/interactive/theme/system-theme.d.ts +54 -0
- package/dist/modes/interactive/theme/system-theme.js +545 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +46 -6
- package/dist/modes/interactive/theme/theme-controller.js +127 -47
- package/dist/modes/interactive/theme/theme-json.d.ts +1 -0
- package/dist/modes/interactive/theme/theme-json.js +3 -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.js +243 -320
- package/dist/modes/interactive/tui-renderer.d.ts +2 -1
- package/dist/modes/interactive/tui-renderer.js +1 -0
- package/dist/modes/json-event.d.ts +33 -0
- package/dist/modes/json-event.js +28 -0
- package/dist/modes/print-mode.js +12 -2
- package/dist/modes/rpc/intercom-bridge.d.ts +14 -0
- package/dist/modes/rpc/intercom-bridge.js +75 -0
- package/dist/modes/rpc/intercom-bridge.test.js +65 -0
- package/dist/modes/rpc/release-bridge.d.ts +35 -0
- package/dist/modes/rpc/release-bridge.js +159 -0
- package/dist/modes/rpc/release-bridge.test.d.ts +1 -0
- package/dist/modes/rpc/release-bridge.test.js +347 -0
- package/dist/modes/rpc/rpc-client.d.ts +43 -27
- package/dist/modes/rpc/rpc-client.js +97 -37
- package/dist/modes/rpc/rpc-intercom-transport.test.d.ts +1 -0
- package/dist/modes/rpc/rpc-intercom-transport.test.js +85 -0
- package/dist/modes/rpc/rpc-mode.d.ts +1 -13
- package/dist/modes/rpc/rpc-mode.js +250 -34
- package/dist/modes/rpc/rpc-release-transport.test.d.ts +1 -0
- package/dist/modes/rpc/rpc-release-transport.test.js +329 -0
- package/dist/modes/rpc/rpc-subagent-transport.test.d.ts +1 -0
- package/dist/modes/rpc/rpc-subagent-transport.test.js +60 -0
- package/dist/modes/rpc/rpc-types.d.ts +22 -23
- package/dist/modes/rpc/rpc-types.js +0 -6
- package/dist/modes/rpc/subagent-bridge.d.ts +23 -0
- package/dist/modes/rpc/subagent-bridge.js +93 -0
- package/dist/modes/rpc/test-fixtures/intercom-host.d.ts +1 -0
- package/dist/modes/rpc/test-fixtures/intercom-host.js +13 -0
- package/dist/package-manager-cli.js +16 -5
- package/dist/rpc-entry.js +1 -0
- package/dist/skills/pi-subagents/SKILL.md +109 -35
- package/dist/skills/pi-subagents/references/constraints-and-recipes.md +38 -238
- package/dist/skills/pi-subagents/references/execution-controls.md +181 -83
- package/dist/skills/pi-subagents/references/management-authoring-rpc.md +9 -9
- package/dist/skills/pi-subagents/references/multi-lane-orchestration.md +24 -2
- package/dist/skills/pi-subagents/references/prompting-and-roles.md +121 -91
- package/dist/skills/pi-subagents/references/review-and-validation.md +73 -0
- package/dist/utils/ansi.d.ts +8 -0
- package/dist/utils/ansi.js +30 -11
- package/dist/utils/clipboard-image.js +14 -17
- package/dist/utils/clipboard.d.ts +2 -0
- package/dist/utils/clipboard.js +17 -11
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/image-convert.d.ts +12 -0
- package/dist/utils/image-convert.js +45 -6
- package/dist/utils/image-resize-core.d.ts +12 -0
- package/dist/utils/image-resize-core.js +5 -0
- package/dist/utils/image-resize-worker.js +3 -2
- package/dist/utils/image-resize.js +9 -10
- package/dist/utils/mime.js +1 -1
- package/dist/utils/output-files.d.ts +14 -0
- package/dist/utils/output-files.js +29 -0
- package/dist/utils/paths.d.ts +6 -3
- package/dist/utils/paths.js +28 -5
- package/dist/utils/shell.d.ts +1 -3
- package/dist/utils/shell.js +3 -30
- package/dist/utils/syntax-highlight.d.ts +1 -0
- package/dist/utils/syntax-highlight.js +68 -2
- package/dist/utils/tool-result-images.d.ts +20 -0
- package/dist/utils/tool-result-images.js +47 -0
- package/dist/utils/tools-manager.d.ts +5 -0
- package/dist/utils/tools-manager.js +6 -6
- package/dist/utils/version-check.d.ts +4 -0
- package/dist/utils/version-check.js +20 -2
- package/docs/cli-integration.md +104 -0
- package/docs/cli.md +333 -0
- package/docs/codemode.md +230 -0
- package/docs/configuration.md +47 -0
- package/docs/environment-variables.md +5 -0
- package/docs/extensions.md +107 -30
- package/docs/json.md +8 -4
- package/docs/keybindings.md +10 -10
- package/docs/mcp.md +262 -0
- package/docs/models.md +104 -3
- package/docs/providers.md +20 -2
- package/docs/rpc-subagent.schema.json +491 -0
- package/docs/rpc.md +223 -13
- package/docs/sdk.md +41 -33
- package/docs/security.md +21 -20
- package/docs/settings.md +18 -46
- package/docs/terminal-setup.md +14 -0
- package/docs/virtual-models.md +114 -0
- package/examples/extensions/jev-router.ts +113 -0
- package/examples/extensions/tokenin-usage-widget.ts +124 -0
- package/examples/rpc-client.ts +35 -0
- package/examples/sdk/14-codemode-mcp.ts +67 -0
- package/package.json +16 -8
- package/dist/core/agent-session-auto-handoff.test.js +0 -195
- package/dist/core/built-in-extensions.d.ts +0 -2
- package/dist/core/built-in-extensions.js +0 -2
- package/dist/core/llama/provider.js +0 -143
- package/dist/core/settings-manager-auto-handoff.test.js +0 -53
- package/dist/extensions/capability-gateway/catalog.ts +0 -177
- package/dist/extensions/capability-gateway/index.test.ts +0 -226
- package/dist/extensions/capability-gateway/index.ts +0 -669
- package/dist/extensions/capability-gateway/integration.test.ts +0 -803
- package/dist/extensions/capability-gateway/package.json +0 -16
- package/dist/extensions/capability-gateway/routing.test.ts +0 -574
- package/dist/extensions/capability-gateway/routing.ts +0 -403
- package/dist/extensions/pi-subagents/runner-server-preload.mjs +0 -13
- package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +0 -89
- package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +0 -259
- package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +0 -312
- package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +0 -374
- package/dist/extensions/pi-subagents/src/runs/shared/readonly-model-continuation.ts +0 -69
- package/dist/extensions/pi-subagents/src/runs/shared/readonly-session-evidence.ts +0 -307
- package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +0 -211
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +0 -2
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +0 -17
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +0 -57
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +0 -16
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +0 -15
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +0 -18
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +0 -9
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +0 -10
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +0 -10
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +0 -20
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +0 -96
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +0 -119
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +0 -85
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +0 -620
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +0 -5
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +0 -56
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +0 -32
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +0 -49
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +0 -93
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +0 -128
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +0 -7
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +0 -38
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +0 -15
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +0 -9
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +0 -29
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +0 -2
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +0 -22
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +0 -37
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +0 -34
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +0 -12
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +0 -23
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +0 -171
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +0 -1261
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +0 -20
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +0 -54
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +0 -22
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +0 -13
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +0 -358
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +0 -77
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +0 -512
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +0 -43
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +0 -121
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +0 -82
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +0 -17
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +0 -7
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +0 -210
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +0 -15
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +0 -54
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +0 -4
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +0 -55
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +0 -2
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +0 -5
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +0 -30
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +0 -206
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +0 -15
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +0 -106
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +0 -19
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +0 -356
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +0 -297
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +0 -60
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +0 -15
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +0 -18
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +0 -28
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +0 -10
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +0 -68
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +0 -106
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +0 -51
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +0 -6
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +0 -35
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +0 -37
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +0 -40
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +0 -37
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +0 -52
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +0 -10
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +0 -35
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +0 -24
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +0 -14
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +0 -70
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +0 -26
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +0 -36
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +0 -19
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +0 -61
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +0 -23
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +0 -10
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +0 -42
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +0 -35
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +0 -12
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +0 -33
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +0 -9
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +0 -34
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +0 -22
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +0 -34
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +0 -16
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +0 -16
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +0 -16
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +0 -102
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +0 -14
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +0 -21
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +0 -19
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +0 -20
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +0 -23
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +0 -12
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +0 -15
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +0 -5
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +0 -22
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +0 -23
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +0 -26
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +0 -25
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +0 -32
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +0 -34
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +0 -13
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +0 -52
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +0 -54
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +0 -33
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +0 -42
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +0 -23
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +0 -95
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +0 -77
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +0 -10
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +0 -17
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +0 -28
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +0 -11
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +0 -11
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +0 -63
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +0 -94
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +0 -23
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +0 -30
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +0 -14
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +0 -24
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +0 -394
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +0 -12
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +0 -29
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +0 -120
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +0 -28
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +0 -17
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +0 -246
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +0 -20
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +0 -457
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +0 -8
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +0 -2
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +0 -22
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +0 -18
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +0 -11
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +0 -11
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +0 -4
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +0 -4
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +0 -5
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +0 -8
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +0 -5
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +0 -26
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +0 -7
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +0 -10
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +0 -18
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +0 -30
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +0 -2
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +0 -16
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +0 -9
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +0 -31
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +0 -21
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +0 -2
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +0 -31
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +0 -5
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +0 -12
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +0 -15
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/smoke/pi085-child.ts +0 -31
- package/dist/extensions/pi-subagents/test/smoke/pi085-clean-install.mjs +0 -74
- package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +0 -150
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +0 -766
- package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +0 -327
- package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +0 -309
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +0 -1093
- package/dist/extensions/pi-subagents/test/unit/readonly-model-continuation.test.ts +0 -94
- package/dist/extensions/pi-subagents/test/unit/readonly-session-evidence.test.ts +0 -1329
- package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +0 -153
- package/dist/extensions/pi-zentui/extensions/zentui/accent-rail-layout-patch.ts +0 -457
- package/dist/extensions/pi-zentui/test/accent-rail-layout-patch.test.ts +0 -669
- package/dist/extensions/pi-zentui/test/thinking-experimental-docs.test.ts +0 -51
- package/dist/modes/interactive/components/daxnuts.d.ts +0 -22
- package/dist/modes/interactive/components/daxnuts.js +0 -139
- /package/dist/core/{agent-session-auto-handoff.test.d.ts → agent-session-custom-tools.test.d.ts} +0 -0
- /package/dist/{core → extensions}/llama/huggingface.d.ts +0 -0
- /package/dist/{core → extensions}/llama/huggingface.js +0 -0
- /package/dist/{core → extensions}/llama/index.d.ts +0 -0
- /package/dist/{core → extensions}/llama/ui.d.ts +0 -0
- /package/dist/{core → extensions}/llama/ui.js +0 -0
- /package/dist/{core/settings-manager-auto-handoff.test.d.ts → modes/rpc/intercom-bridge.test.d.ts} +0 -0
|
@@ -12,34 +12,41 @@
|
|
|
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
|
+
import { runToolCall, } from "@earendil-works/pi-agent-core";
|
|
17
18
|
import { contentText, getCurrentSystemMessage, 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";
|
|
20
21
|
import { stripFrontmatter } from "../utils/frontmatter.js";
|
|
21
|
-
import {
|
|
22
|
+
import { processImage } from "../utils/image-process.js";
|
|
22
23
|
import { sleep } from "../utils/sleep.js";
|
|
23
24
|
import { normalizeAssistantThinkingTags } from "../utils/thinking-tags.js";
|
|
25
|
+
import { normalizeToolResultImages } from "../utils/tool-result-images.js";
|
|
24
26
|
import { formatNoApiKeyFoundMessage, formatNoModelSelectedMessage } from "./auth-guidance.js";
|
|
25
27
|
import { executeBashWithOperations } from "./bash-executor.js";
|
|
26
28
|
import { generateBugReportSummary } from "./bug-report.js";
|
|
27
|
-
import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
|
|
29
|
+
import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateProjectedContextTokens, estimateTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
|
|
28
30
|
import { DEFAULT_THINKING_LEVEL, THINKING_LEVEL_OPTIONS } from "./defaults.js";
|
|
29
31
|
import { exportSessionToHtml } from "./export-html/index.js";
|
|
30
32
|
import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
|
|
31
|
-
import { AUTO_HANDOFF_GOAL } from "./handoff.js";
|
|
32
33
|
import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
|
|
33
34
|
import { emitSessionShutdownEvent } from "./extensions/runner.js";
|
|
35
|
+
import { createToolNameMatcher, isMcpToolName } from "./mcp-servers.js";
|
|
36
|
+
import { convertToLlm } from "./messages.js";
|
|
34
37
|
import { ModelRegistry } from "./model-registry.js";
|
|
38
|
+
import { NestedToolCallRunner } from "./nested-tool-calls.js";
|
|
35
39
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
40
|
+
import { exportSessionToJsonl } from "./session-export.js";
|
|
41
|
+
import { getLatestCompactionEntry, SessionManager, } from "./session-manager.js";
|
|
42
|
+
import { applyToolModifiers, DEFAULT_TOOL_NAMES, } from "./settings-manager.js";
|
|
43
|
+
import { BUILTIN_PATH_PREFIX, createSyntheticSourceInfo, isSyntheticPath } from "./source-info.js";
|
|
38
44
|
import { buildSystemPrompt, buildSystemPromptSections, diffSystemPromptSections, normalizeBuildSystemPromptOptions, } from "./system-prompt.js";
|
|
39
45
|
import { createLocalBashOperations } from "./tools/bash.js";
|
|
40
46
|
import { createAllToolDefinitions } from "./tools/index.js";
|
|
41
47
|
import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
|
|
42
|
-
import { addUsageToTotals, createUsageTotals } from "./usage-totals.js";
|
|
48
|
+
import { addUsageToTotals, combineUsage, createUsageTotals } from "./usage-totals.js";
|
|
49
|
+
import { findLatestResponse, getBranchSelection, getVirtualModelState, isVirtualModel, VIRTUAL_MODEL_STATE_ENTRY, } from "./virtual-models.js";
|
|
43
50
|
import { captionImageWithModel } from "./vision-caption.js";
|
|
44
51
|
/** Parse consecutive skill blocks at the start of a user message. */
|
|
45
52
|
export function parseSkillBlocks(text) {
|
|
@@ -120,6 +127,11 @@ export class AgentSession {
|
|
|
120
127
|
// Retry state
|
|
121
128
|
_retryAbortController = undefined;
|
|
122
129
|
_retryAttempt = 0;
|
|
130
|
+
/**
|
|
131
|
+
* Failed response that the next request repeats, set by auto-retry and overflow recovery. The
|
|
132
|
+
* retry is routed with it as `failed`, since the context no longer contains it.
|
|
133
|
+
*/
|
|
134
|
+
_failedResponse;
|
|
123
135
|
// Length-stop continuation state (consecutive output-token-limit continuations)
|
|
124
136
|
_lengthContinuations = 0;
|
|
125
137
|
// Bash execution state
|
|
@@ -128,14 +140,37 @@ export class AgentSession {
|
|
|
128
140
|
// Extension system
|
|
129
141
|
_extensionRunner;
|
|
130
142
|
_turnIndex = 0;
|
|
143
|
+
_entryIdsByMessage = new WeakMap();
|
|
144
|
+
_boundaryDispatchedMessages = new WeakSet();
|
|
145
|
+
_lastAssistantMessage;
|
|
146
|
+
_lastAssistantToolResults = [];
|
|
147
|
+
_lastActivityOutcome = "completed";
|
|
148
|
+
_isBeforeSettle = false;
|
|
149
|
+
_abortDuringBeforeSettle = false;
|
|
150
|
+
_isEmittingAgentSettled = false;
|
|
151
|
+
_deferredSettledActions = [];
|
|
131
152
|
_resourceLoader;
|
|
132
153
|
_customTools;
|
|
133
154
|
_baseToolDefinitions = new Map();
|
|
134
155
|
_cwd;
|
|
135
156
|
_extensionRunnerRef;
|
|
136
157
|
_initialActiveToolNames;
|
|
137
|
-
|
|
138
|
-
|
|
158
|
+
/**
|
|
159
|
+
* Tools of the restored or reloaded loadout that are not registered yet, such as tools of MCP
|
|
160
|
+
* servers that are still connecting. They are activated when they are registered, and dropped when
|
|
161
|
+
* `setActiveToolsByName()` deactivates a tool or the next agent run starts.
|
|
162
|
+
*/
|
|
163
|
+
_pendingToolNames = new Set();
|
|
164
|
+
_usesDefaultTools;
|
|
165
|
+
_defaultToolModifiers;
|
|
166
|
+
/** Matches the `--tools` entries: tool names or patterns. */
|
|
167
|
+
_allowedTools;
|
|
168
|
+
/**
|
|
169
|
+
* Whether the allowlist filters MCP tools: it is empty (`--no-tools`) or names an MCP tool
|
|
170
|
+
* (`mcp__*`). Otherwise it keeps MCP tools registered for codemode and tool_search.
|
|
171
|
+
*/
|
|
172
|
+
_allowlistFiltersMcp = false;
|
|
173
|
+
_excludedTools;
|
|
139
174
|
_baseToolsOverride;
|
|
140
175
|
_sessionStartEvent;
|
|
141
176
|
_extensionUIContext;
|
|
@@ -149,6 +184,10 @@ export class AgentSession {
|
|
|
149
184
|
_cacheWarmer;
|
|
150
185
|
// Tool registry for extension getTools/setTools
|
|
151
186
|
_toolRegistry = new Map();
|
|
187
|
+
/** Created on the first `ctx.executeTool()` call. */
|
|
188
|
+
_nestedToolCalls;
|
|
189
|
+
/** Declared tools whose declarations requests leave out, from `prepareLoadout` hooks. */
|
|
190
|
+
_hiddenDeclarations = new Set();
|
|
152
191
|
_toolDefinitions = new Map();
|
|
153
192
|
_toolPromptSnippets = new Map();
|
|
154
193
|
_toolPromptGuidelines = new Map();
|
|
@@ -170,8 +209,14 @@ export class AgentSession {
|
|
|
170
209
|
}
|
|
171
210
|
this._extensionRunnerRef = config.extensionRunnerRef;
|
|
172
211
|
this._initialActiveToolNames = config.initialActiveToolNames;
|
|
173
|
-
this.
|
|
174
|
-
this.
|
|
212
|
+
this._usesDefaultTools = config.usesDefaultTools ?? false;
|
|
213
|
+
this._defaultToolModifiers = config.defaultToolModifiers ?? [];
|
|
214
|
+
if (config.allowedToolNames) {
|
|
215
|
+
this._allowedTools = createToolNameMatcher(config.allowedToolNames);
|
|
216
|
+
this._allowlistFiltersMcp =
|
|
217
|
+
config.allowedToolNames.length === 0 || config.allowedToolNames.some((entry) => entry.startsWith("mcp__"));
|
|
218
|
+
}
|
|
219
|
+
this._excludedTools = config.excludedToolNames ? createToolNameMatcher(config.excludedToolNames) : undefined;
|
|
175
220
|
this._baseToolsOverride = config.baseToolsOverride;
|
|
176
221
|
this._sessionStartEvent = config.sessionStartEvent ?? { type: "session_start", reason: "startup" };
|
|
177
222
|
// Always subscribe to agent events for internal handling
|
|
@@ -179,6 +224,9 @@ export class AgentSession {
|
|
|
179
224
|
this._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);
|
|
180
225
|
this._installAgentToolHooks();
|
|
181
226
|
this._installAgentNextTurnRefresh();
|
|
227
|
+
this._installAgentRequestProjection();
|
|
228
|
+
this._installAgentBoundaryHooks();
|
|
229
|
+
this._installHiddenDeclarationsProjection();
|
|
182
230
|
this._installAgentForcedPromptProjection();
|
|
183
231
|
this._buildRuntime({
|
|
184
232
|
activeToolNames: this._initialActiveToolNames,
|
|
@@ -219,28 +267,71 @@ export class AgentSession {
|
|
|
219
267
|
}
|
|
220
268
|
throw new Error(formatNoApiKeyFoundMessage(model.provider));
|
|
221
269
|
}
|
|
222
|
-
async _getSummarizationRequestAuth(
|
|
270
|
+
async _getSummarizationRequestAuth(selectedModel, signal) {
|
|
271
|
+
// Route a virtual model first: summaries size their input and output from the model they get.
|
|
272
|
+
const { model, thinkingLevel } = isVirtualModel(selectedModel)
|
|
273
|
+
? await this._modelRuntime.resolveModel(selectedModel, convertToLlm(this.messages), {
|
|
274
|
+
reason: "direct",
|
|
275
|
+
thinkingLevel: this.thinkingLevel,
|
|
276
|
+
signal,
|
|
277
|
+
})
|
|
278
|
+
: { model: selectedModel, thinkingLevel: this.thinkingLevel };
|
|
223
279
|
if (this.agent.streamFunction === streamSimple) {
|
|
224
|
-
return this._getRequiredRequestAuth(model, signal);
|
|
280
|
+
return { ...(await this._getRequiredRequestAuth(model, signal)), thinkingLevel };
|
|
225
281
|
}
|
|
226
282
|
try {
|
|
227
283
|
const result = await this._modelRuntime.getAuth(model, { signal });
|
|
228
284
|
if (!result)
|
|
229
|
-
return { model };
|
|
285
|
+
return { model, thinkingLevel };
|
|
230
286
|
const requestModel = result.auth.baseUrl ? { ...model, baseUrl: result.auth.baseUrl } : model;
|
|
231
287
|
return {
|
|
232
288
|
model: requestModel,
|
|
233
289
|
apiKey: result.auth.apiKey,
|
|
234
290
|
headers: withoutDeletedHeaders(result.auth.headers),
|
|
235
291
|
env: result.env,
|
|
292
|
+
thinkingLevel,
|
|
236
293
|
};
|
|
237
294
|
}
|
|
238
295
|
catch (error) {
|
|
239
296
|
if (signal?.aborted)
|
|
240
297
|
throw error;
|
|
241
|
-
return { model };
|
|
298
|
+
return { model, thinkingLevel };
|
|
242
299
|
}
|
|
243
300
|
}
|
|
301
|
+
/**
|
|
302
|
+
* The model whose limits apply to `message`, or undefined when the message came from another
|
|
303
|
+
* model. Under a virtual selection, that is the physical model that produced it.
|
|
304
|
+
*/
|
|
305
|
+
_modelForMessage(message) {
|
|
306
|
+
const model = this.model;
|
|
307
|
+
if (model && isVirtualModel(model))
|
|
308
|
+
return this._modelRuntime.getPhysicalModel(message.provider, message.model);
|
|
309
|
+
return model?.provider === message.provider && model.id === message.model ? model : undefined;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Record the selection on the current branch when the branch implies another one, so a resume
|
|
313
|
+
* restores it. Tree navigation can leave the latest `model_change` on another branch; responses
|
|
314
|
+
* cannot record a virtual selection because they name physical models. Responses do record a
|
|
315
|
+
* physical selection unless the branch holds a virtual one; checking a physical selection against
|
|
316
|
+
* responses would record it on every prompt while `prepareRequest` redirects to another model.
|
|
317
|
+
*/
|
|
318
|
+
_recordSelection() {
|
|
319
|
+
const model = this.model;
|
|
320
|
+
if (!model)
|
|
321
|
+
return;
|
|
322
|
+
const getModel = (provider, modelId) => this._modelRuntime.getModel(provider, modelId);
|
|
323
|
+
const recorded = getBranchSelection(this.sessionManager.getBranch(), getModel);
|
|
324
|
+
if (!recorded || (recorded.provider === model.provider && recorded.modelId === model.id))
|
|
325
|
+
return;
|
|
326
|
+
const recordedModel = getModel(recorded.provider, recorded.modelId);
|
|
327
|
+
if (!isVirtualModel(model) && !(recordedModel && isVirtualModel(recordedModel)))
|
|
328
|
+
return;
|
|
329
|
+
this.sessionManager.appendModelChange(model.provider, model.id);
|
|
330
|
+
}
|
|
331
|
+
/** The model whose limits apply to the conversation. */
|
|
332
|
+
_limitsModel() {
|
|
333
|
+
return this.routedModel?.model ?? this.model;
|
|
334
|
+
}
|
|
244
335
|
/**
|
|
245
336
|
* Install tool hooks once on the Agent instance.
|
|
246
337
|
*
|
|
@@ -250,65 +341,217 @@ export class AgentSession {
|
|
|
250
341
|
* happens here instead of in wrappers.
|
|
251
342
|
*/
|
|
252
343
|
_installAgentToolHooks() {
|
|
253
|
-
this.agent.beforeToolCall =
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
const runner = this._extensionRunner;
|
|
275
|
-
if (!runner.hasHandlers("tool_result")) {
|
|
276
|
-
return undefined;
|
|
344
|
+
this.agent.beforeToolCall = (context) => this._beforeToolCall(context);
|
|
345
|
+
this.agent.afterToolCall = (context) => this._afterToolCall(context);
|
|
346
|
+
}
|
|
347
|
+
/** `tool_call` handlers. `parentToolCallId` is set for calls another tool made. */
|
|
348
|
+
async _beforeToolCall({ toolCall, args }, parentToolCallId) {
|
|
349
|
+
const runner = this._extensionRunner;
|
|
350
|
+
if (!runner.hasHandlers("tool_call")) {
|
|
351
|
+
return undefined;
|
|
352
|
+
}
|
|
353
|
+
try {
|
|
354
|
+
return await runner.emitToolCall({
|
|
355
|
+
type: "tool_call",
|
|
356
|
+
toolName: toolCall.name,
|
|
357
|
+
toolCallId: toolCall.id,
|
|
358
|
+
...(parentToolCallId ? { parentToolCallId } : {}),
|
|
359
|
+
input: args,
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
catch (err) {
|
|
363
|
+
if (err instanceof Error) {
|
|
364
|
+
throw err;
|
|
277
365
|
}
|
|
278
|
-
|
|
366
|
+
throw new Error(`Extension failed, blocking execution: ${String(err)}`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
/** `tool_result` handlers and image normalization. `parentToolCallId` is set for calls another tool made. */
|
|
370
|
+
async _afterToolCall({ toolCall, args, result, isError }, parentToolCallId) {
|
|
371
|
+
const runner = this._extensionRunner;
|
|
372
|
+
const hookResult = runner.hasHandlers("tool_result")
|
|
373
|
+
? await runner.emitToolResult({
|
|
279
374
|
type: "tool_result",
|
|
280
375
|
toolName: toolCall.name,
|
|
281
376
|
toolCallId: toolCall.id,
|
|
377
|
+
...(parentToolCallId ? { parentToolCallId } : {}),
|
|
282
378
|
input: args,
|
|
283
379
|
content: result.content,
|
|
284
380
|
details: result.details,
|
|
381
|
+
...(result.structuredContent === undefined ? {} : { structuredContent: result.structuredContent }),
|
|
285
382
|
isError,
|
|
286
383
|
usage: result.usage,
|
|
287
|
-
})
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
384
|
+
})
|
|
385
|
+
: undefined;
|
|
386
|
+
const content = hookResult?.content ?? result.content ?? [];
|
|
387
|
+
// Runs after the extension hook so images injected or replaced by extensions are normalized too.
|
|
388
|
+
const resizeOptions = this._limitsModel()?.inputLimits?.images?.resize;
|
|
389
|
+
const normalizedContent = await normalizeToolResultImages(content, {
|
|
390
|
+
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
391
|
+
...(resizeOptions ? { resizeOptions } : {}),
|
|
392
|
+
});
|
|
393
|
+
if (!hookResult && normalizedContent === content) {
|
|
394
|
+
return undefined;
|
|
395
|
+
}
|
|
396
|
+
// The hook result already dropped structured content that replaced content no longer matches.
|
|
397
|
+
return {
|
|
398
|
+
content: normalizedContent,
|
|
399
|
+
details: hookResult?.details,
|
|
400
|
+
structuredContent: hookResult ? hookResult.structuredContent : result.structuredContent,
|
|
401
|
+
isError: hookResult?.isError ?? isError,
|
|
402
|
+
usage: hookResult?.usage,
|
|
403
|
+
terminate: hookResult?.terminate,
|
|
298
404
|
};
|
|
299
405
|
}
|
|
406
|
+
/**
|
|
407
|
+
* Run a call that the tool call `parentToolCallId` made through `ctx.executeTool()`. It goes
|
|
408
|
+
* through the agent's tool pipeline with the session's hooks, against the callable tools.
|
|
409
|
+
*/
|
|
410
|
+
async _executeNestedToolCall(parentToolCallId, name, args, options) {
|
|
411
|
+
this._nestedToolCalls ??= new NestedToolCallRunner({
|
|
412
|
+
getTools: () => this._getCallableTools(),
|
|
413
|
+
isSequential: () => this.agent.toolExecution === "sequential",
|
|
414
|
+
runToolCall: (toolCall, parentId, signal, onUpdate) => {
|
|
415
|
+
const assistantMessage = this._findLastAssistantMessage();
|
|
416
|
+
if (!assistantMessage) {
|
|
417
|
+
return Promise.resolve({
|
|
418
|
+
toolCall,
|
|
419
|
+
result: { content: [{ type: "text", text: "No assistant message issued this call" }], details: {} },
|
|
420
|
+
isError: true,
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
return runToolCall(toolCall, {
|
|
424
|
+
tools: this._getCallableTools(),
|
|
425
|
+
assistantMessage,
|
|
426
|
+
context: { messages: this.agent.state.messages, tools: this.agent.state.tools },
|
|
427
|
+
beforeToolCall: (context) => this._beforeToolCall(context, parentId),
|
|
428
|
+
afterToolCall: (context) => this._afterToolCall(context, parentId),
|
|
429
|
+
signal,
|
|
430
|
+
onUpdate,
|
|
431
|
+
});
|
|
432
|
+
},
|
|
433
|
+
emit: async (event) => {
|
|
434
|
+
await this._extensionRunner.emit(event);
|
|
435
|
+
this._emit(event);
|
|
436
|
+
},
|
|
437
|
+
});
|
|
438
|
+
return this._nestedToolCalls.execute(parentToolCallId, name, args, options);
|
|
439
|
+
}
|
|
440
|
+
/** Whether `projection`, the current session projection, exceeds the compaction threshold of `model`. */
|
|
441
|
+
_exceedsCompactionThreshold(model, projection) {
|
|
442
|
+
if (model.contextWindow <= 0)
|
|
443
|
+
return false;
|
|
444
|
+
return shouldCompact(estimateProjectedContextTokens(projection, this.sessionManager.getBranch()).tokens, model.contextWindow, this.settingsManager.getCompactionSettings(this.model));
|
|
445
|
+
}
|
|
300
446
|
async _compactBeforeNextAssistantResponse(context) {
|
|
447
|
+
const projection = this.sessionManager.buildSessionProjection();
|
|
448
|
+
// A virtual selection is checked in prepareRequest, against the model the request is routed to.
|
|
301
449
|
const model = this.model;
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
model.contextWindow <= 0 ||
|
|
305
|
-
!shouldCompact(estimateContextTokens(context.messages).tokens, model.contextWindow, settings)) {
|
|
306
|
-
return context;
|
|
450
|
+
if (!model || isVirtualModel(model) || !this._exceedsCompactionThreshold(model, projection)) {
|
|
451
|
+
return { ...context, messages: projection.messages };
|
|
307
452
|
}
|
|
308
453
|
await this._runAutoCompaction("threshold", false);
|
|
309
|
-
return {
|
|
310
|
-
|
|
311
|
-
|
|
454
|
+
return { ...context, messages: this.sessionManager.buildSessionProjection().messages };
|
|
455
|
+
}
|
|
456
|
+
_installAgentRequestProjection() {
|
|
457
|
+
const previousPrepareRequest = this.agent.prepareRequest;
|
|
458
|
+
this.agent.prepareRequest = async (request, signal) => {
|
|
459
|
+
const failed = this._failedResponse;
|
|
460
|
+
this._failedResponse = undefined;
|
|
461
|
+
const prepare = async () => {
|
|
462
|
+
const projection = this.sessionManager.buildSessionProjection();
|
|
463
|
+
const canonicalContext = {
|
|
464
|
+
...request.context,
|
|
465
|
+
messages: projection.messages,
|
|
466
|
+
// Messages declare the provider-visible loadout; context.tools keeps executable implementations.
|
|
467
|
+
tools: this.agent.state.tools.slice(),
|
|
468
|
+
};
|
|
469
|
+
const previous = await previousPrepareRequest?.({
|
|
470
|
+
...request,
|
|
471
|
+
context: canonicalContext,
|
|
472
|
+
model: this.agent.state.model,
|
|
473
|
+
thinkingLevel: this.agent.state.thinkingLevel,
|
|
474
|
+
}, signal);
|
|
475
|
+
return { previous, context: previous?.context ?? canonicalContext, projection };
|
|
476
|
+
};
|
|
477
|
+
let { previous, context, projection } = await prepare();
|
|
478
|
+
const model = previous?.model ?? this.agent.state.model;
|
|
479
|
+
const thinkingLevel = previous?.thinkingLevel ?? this.agent.state.thinkingLevel;
|
|
480
|
+
if (!isVirtualModel(model))
|
|
481
|
+
return { ...previous, context, model, thinkingLevel };
|
|
482
|
+
// The selection stays in agent state; only this request uses the routed model. A routing
|
|
483
|
+
// failure rejects, which ends the run with an error response. Only messages the user wrote
|
|
484
|
+
// start a turn; extension messages can follow them, e.g. from before_agent_start.
|
|
485
|
+
const lastResponse = context.messages.findLastIndex((message) => message.role === "assistant");
|
|
486
|
+
const userTurn = context.messages.slice(lastResponse + 1).some((message) => message.role === "user");
|
|
487
|
+
const state = getVirtualModelState(this.sessionManager.getBranch(), model.provider, model.id);
|
|
488
|
+
const route = await this._modelRuntime.resolveModel(model, convertToLlm(context.messages), {
|
|
489
|
+
reason: failed ? "retry" : userTurn ? "user" : "continuation",
|
|
490
|
+
thinkingLevel,
|
|
491
|
+
signal,
|
|
492
|
+
failed,
|
|
493
|
+
state,
|
|
494
|
+
});
|
|
495
|
+
if (route.state !== undefined && route.state !== state) {
|
|
496
|
+
const data = { provider: model.provider, modelId: model.id, state: route.state };
|
|
497
|
+
const entry = this.sessionManager.getEntry(this.sessionManager.appendCustomEntry(VIRTUAL_MODEL_STATE_ENTRY, data));
|
|
498
|
+
if (entry)
|
|
499
|
+
this._emit({ type: "entry_appended", entry });
|
|
500
|
+
}
|
|
501
|
+
// The route stands: the router already decided this request. The state entry does not change
|
|
502
|
+
// the projection.
|
|
503
|
+
if (this._exceedsCompactionThreshold(route.model, projection)) {
|
|
504
|
+
await this._runAutoCompaction("threshold", false);
|
|
505
|
+
({ previous, context } = await prepare());
|
|
506
|
+
}
|
|
507
|
+
return { ...previous, context, model: route.model, thinkingLevel: route.thinkingLevel };
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
async _dispatchTurnEndBoundary(message, toolResults) {
|
|
511
|
+
this._lastActivityOutcome =
|
|
512
|
+
message.stopReason === "aborted" ? "aborted" : message.stopReason === "error" ? "error" : "completed";
|
|
513
|
+
const messageEntryId = this._findPersistedMessageEntryId(message);
|
|
514
|
+
if (!this._extensionRunner.hasHandlers("turn_end"))
|
|
515
|
+
return false;
|
|
516
|
+
if (!messageEntryId) {
|
|
517
|
+
this._extensionRunner.emitError({
|
|
518
|
+
extensionPath: "<boundary>",
|
|
519
|
+
event: "turn_end",
|
|
520
|
+
error: "turn_end could not resolve the persisted assistant entry ID",
|
|
521
|
+
});
|
|
522
|
+
return false;
|
|
523
|
+
}
|
|
524
|
+
const toolResultEntryIds = toolResults.flatMap((result) => {
|
|
525
|
+
const entryId = this._findPersistedMessageEntryId(result);
|
|
526
|
+
return entryId ? [entryId] : [];
|
|
527
|
+
});
|
|
528
|
+
const boundary = await this._extensionRunner.emitBoundary({
|
|
529
|
+
type: "turn_end",
|
|
530
|
+
turnIndex: this._turnIndex,
|
|
531
|
+
message,
|
|
532
|
+
toolResults,
|
|
533
|
+
messageEntryId,
|
|
534
|
+
toolResultEntryIds,
|
|
535
|
+
outcome: this._lastActivityOutcome,
|
|
536
|
+
}, (entries) => this._buildBoundaryContext(entries, "turn_end"));
|
|
537
|
+
this._commitBoundaryDrafts(boundary.entries);
|
|
538
|
+
if (boundary.continue && !this._buildBoundaryContext([], "turn_end").canContinue) {
|
|
539
|
+
this._reportInvalidBoundaryContinuation("turn_end");
|
|
540
|
+
return false;
|
|
541
|
+
}
|
|
542
|
+
return boundary.continue;
|
|
543
|
+
}
|
|
544
|
+
_installAgentBoundaryHooks() {
|
|
545
|
+
const previousFinishTurn = this.agent.finishTurn;
|
|
546
|
+
this.agent.finishTurn = async (turn, signal) => {
|
|
547
|
+
this._boundaryDispatchedMessages.add(turn.message);
|
|
548
|
+
const extensionContinue = await this._dispatchTurnEndBoundary(turn.message, turn.toolResults);
|
|
549
|
+
const previousDecision = await previousFinishTurn?.(turn, signal);
|
|
550
|
+
if (previousDecision?.action === "end")
|
|
551
|
+
return previousDecision;
|
|
552
|
+
if (extensionContinue || previousDecision?.action === "continue")
|
|
553
|
+
return { action: "continue" };
|
|
554
|
+
return undefined;
|
|
312
555
|
};
|
|
313
556
|
}
|
|
314
557
|
_installAgentNextTurnRefresh() {
|
|
@@ -347,6 +590,84 @@ export class AgentSession {
|
|
|
347
590
|
// =========================================================================
|
|
348
591
|
// Event Subscription
|
|
349
592
|
// =========================================================================
|
|
593
|
+
_refreshFinalizedContext() {
|
|
594
|
+
const projection = this.sessionManager.buildSessionProjection();
|
|
595
|
+
for (const entry of projection.entries) {
|
|
596
|
+
for (const message of entry.messages)
|
|
597
|
+
this._entryIdsByMessage.set(message, entry.sourceEntry.id);
|
|
598
|
+
}
|
|
599
|
+
this.agent.state.messages = projection.messages;
|
|
600
|
+
}
|
|
601
|
+
_applyBoundaryDrafts(manager, drafts) {
|
|
602
|
+
const appended = [];
|
|
603
|
+
for (const draft of drafts) {
|
|
604
|
+
let entryId;
|
|
605
|
+
switch (draft.type) {
|
|
606
|
+
case "custom":
|
|
607
|
+
entryId = manager.appendCustomEntry(draft.customType, draft.data);
|
|
608
|
+
break;
|
|
609
|
+
case "custom_message":
|
|
610
|
+
entryId = manager.appendCustomMessageEntry(draft.customType, draft.content, draft.display, draft.details);
|
|
611
|
+
break;
|
|
612
|
+
case "context_edit":
|
|
613
|
+
entryId = manager.appendContextEdit(draft.targetId, draft.replacement);
|
|
614
|
+
break;
|
|
615
|
+
case "compaction": {
|
|
616
|
+
const tokensBefore = estimateProjectedContextTokens(manager.buildSessionProjection(), manager.getBranch()).tokens;
|
|
617
|
+
entryId = manager.appendCompaction(draft.summary, draft.firstKeptEntryId, tokensBefore, draft.details, true, draft.usage);
|
|
618
|
+
break;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
const entry = manager.getEntry(entryId);
|
|
622
|
+
if (entry)
|
|
623
|
+
appended.push(entry);
|
|
624
|
+
}
|
|
625
|
+
return appended;
|
|
626
|
+
}
|
|
627
|
+
_createBoundaryPreviewManager(drafts) {
|
|
628
|
+
const header = this.sessionManager.getHeader();
|
|
629
|
+
if (!header)
|
|
630
|
+
throw new Error("Session header is missing");
|
|
631
|
+
const manager = SessionManager.inMemory(this._cwd, undefined, [header, ...this.sessionManager.getBranch()]);
|
|
632
|
+
this._applyBoundaryDrafts(manager, drafts);
|
|
633
|
+
return manager;
|
|
634
|
+
}
|
|
635
|
+
_getPendingBoundaryMessages() {
|
|
636
|
+
return [...this.agent.peekQueuedMessages(), ...this._pendingCustomMessages];
|
|
637
|
+
}
|
|
638
|
+
_buildBoundaryContext(drafts, boundary) {
|
|
639
|
+
const projection = this._createBoundaryPreviewManager(drafts).buildSessionProjection();
|
|
640
|
+
const pendingMessages = this._getPendingBoundaryMessages();
|
|
641
|
+
const llmMessages = convertToLlm(projection.messages);
|
|
642
|
+
const finalRole = llmMessages[llmMessages.length - 1]?.role;
|
|
643
|
+
const hasNonSystemContext = llmMessages.some((message) => message.role !== "system");
|
|
644
|
+
const contextCanContinue = hasNonSystemContext && finalRole !== "assistant";
|
|
645
|
+
const pendingCustomContext = this._pendingCustomMessages.length > 0;
|
|
646
|
+
return {
|
|
647
|
+
contextEntries: projection.entries,
|
|
648
|
+
contextMessages: projection.messages,
|
|
649
|
+
llmMessages,
|
|
650
|
+
pendingMessages,
|
|
651
|
+
canContinue: contextCanContinue ||
|
|
652
|
+
pendingCustomContext ||
|
|
653
|
+
(boundary === "turn_end"
|
|
654
|
+
? this.agent.hasQueuedMessages()
|
|
655
|
+
: finalRole === "assistant" && this.agent.hasQueuedMessages()),
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
_commitBoundaryDrafts(drafts) {
|
|
659
|
+
const appended = this._applyBoundaryDrafts(this.sessionManager, drafts);
|
|
660
|
+
this._refreshFinalizedContext();
|
|
661
|
+
for (const entry of appended)
|
|
662
|
+
this._emit({ type: "entry_appended", entry });
|
|
663
|
+
}
|
|
664
|
+
_reportInvalidBoundaryContinuation(event) {
|
|
665
|
+
this._extensionRunner.emitError({
|
|
666
|
+
extensionPath: "<boundary>",
|
|
667
|
+
event,
|
|
668
|
+
error: `${event} requested continuation without runnable model context`,
|
|
669
|
+
});
|
|
670
|
+
}
|
|
350
671
|
/** Emit an event to all listeners */
|
|
351
672
|
_emit(event) {
|
|
352
673
|
for (const l of this._eventListeners) {
|
|
@@ -385,56 +706,45 @@ export class AgentSession {
|
|
|
385
706
|
async _emitAgentSettled() {
|
|
386
707
|
this._cacheWarmer?.onAgentSettled();
|
|
387
708
|
this._isAgentRunActive = false;
|
|
709
|
+
this._isEmittingAgentSettled = true;
|
|
388
710
|
try {
|
|
389
|
-
|
|
390
|
-
this.
|
|
391
|
-
|
|
711
|
+
const aborted = this._agentRunAbortRequested;
|
|
712
|
+
await this._extensionRunner.emit({ type: "agent_settled", aborted });
|
|
713
|
+
this._emit({ type: "agent_settled", aborted });
|
|
392
714
|
}
|
|
393
715
|
finally {
|
|
394
|
-
this.
|
|
716
|
+
this._isEmittingAgentSettled = false;
|
|
395
717
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
if (usage.tokens < threshold) {
|
|
406
|
-
this._autoHandoffTriggered = false;
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
if (this._autoHandoffTriggered)
|
|
410
|
-
return;
|
|
411
|
-
// Auto-handoff is TUI-only: it runs at agent_settled, and headless/print
|
|
412
|
-
// modes should not churn sessions on their own. The handoff-new command
|
|
413
|
-
// itself now also works in non-TUI modes (direct generation, no loader).
|
|
414
|
-
if (this._extensionMode !== "tui")
|
|
415
|
-
return;
|
|
416
|
-
const command = this._extensionRunner.getCommand("handoff-new");
|
|
417
|
-
if (!command)
|
|
718
|
+
const deferred = this._deferredSettledActions.splice(0);
|
|
719
|
+
if (deferred.length > 0) {
|
|
720
|
+
try {
|
|
721
|
+
for (const action of deferred)
|
|
722
|
+
await action();
|
|
723
|
+
}
|
|
724
|
+
finally {
|
|
725
|
+
this._resolveIdleWaitIfIdle();
|
|
726
|
+
}
|
|
418
727
|
return;
|
|
419
|
-
this._autoHandoffTriggered = true;
|
|
420
|
-
const ctx = this._extensionRunner.createCommandContext();
|
|
421
|
-
try {
|
|
422
|
-
await command.handler(AUTO_HANDOFF_GOAL, ctx);
|
|
423
|
-
}
|
|
424
|
-
catch (err) {
|
|
425
|
-
// Retry on the next settled turn while the session remains above the threshold.
|
|
426
|
-
this._autoHandoffTriggered = false;
|
|
427
|
-
this._extensionRunner.emitError({
|
|
428
|
-
extensionPath: "command:handoff-new",
|
|
429
|
-
event: "auto-handoff",
|
|
430
|
-
error: err instanceof Error ? err.message : String(err),
|
|
431
|
-
});
|
|
432
728
|
}
|
|
729
|
+
this._resolveIdleWaitIfIdle();
|
|
433
730
|
}
|
|
434
|
-
// Track last assistant message for auto-compaction check
|
|
435
|
-
_lastAssistantMessage = undefined;
|
|
436
731
|
/** Internal handler for agent events - shared by subscribe and reconnect */
|
|
437
732
|
_handleAgentEvent = async (event) => {
|
|
733
|
+
// Record the calls a tool made through ctx.executeTool() and their usage on its result message.
|
|
734
|
+
if (this._nestedToolCalls) {
|
|
735
|
+
if (event.type === "message_start" && event.message.role === "toolResult") {
|
|
736
|
+
const message = event.message;
|
|
737
|
+
const summary = this._nestedToolCalls.takeRecord(message.toolCallId);
|
|
738
|
+
if (summary?.calls)
|
|
739
|
+
message.nestedCalls = summary.calls;
|
|
740
|
+
if (summary?.usage) {
|
|
741
|
+
message.usage = message.usage ? combineUsage(message.usage, summary.usage) : summary.usage;
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
else if (event.type === "agent_end") {
|
|
745
|
+
this._nestedToolCalls.clear();
|
|
746
|
+
}
|
|
747
|
+
}
|
|
438
748
|
// When a user message starts, check if it's from either queue and remove it BEFORE emitting
|
|
439
749
|
// This ensures the UI sees the updated queue state
|
|
440
750
|
if (event.type === "message_start" && event.message.role === "user") {
|
|
@@ -457,29 +767,30 @@ export class AgentSession {
|
|
|
457
767
|
}
|
|
458
768
|
}
|
|
459
769
|
}
|
|
460
|
-
// Emit to extensions first
|
|
770
|
+
// Emit to extensions first, then notify public listeners.
|
|
461
771
|
await this._emitExtensionEvent(event);
|
|
462
|
-
// Notify all listeners
|
|
463
772
|
this._emit(event.type === "agent_end" ? { ...event, willRetry: this._willRetryAfterAgentEnd(event) } : event);
|
|
464
773
|
// Handle session persistence
|
|
465
774
|
if (event.type === "message_end") {
|
|
775
|
+
let entryId;
|
|
466
776
|
// Check if this is a custom message from extensions
|
|
467
777
|
if (event.message.role === "custom") {
|
|
468
778
|
// Persist as CustomMessageEntry
|
|
469
|
-
this.sessionManager.appendCustomMessageEntry(event.message.customType, event.message.content, event.message.display, event.message.details);
|
|
779
|
+
entryId = this.sessionManager.appendCustomMessageEntry(event.message.customType, event.message.content, event.message.display, event.message.details);
|
|
470
780
|
}
|
|
471
781
|
else if (event.message.role === "system" ||
|
|
472
782
|
event.message.role === "user" ||
|
|
473
783
|
event.message.role === "assistant" ||
|
|
474
784
|
event.message.role === "toolResult") {
|
|
475
785
|
// Regular LLM message - persist as SessionMessageEntry
|
|
476
|
-
this.sessionManager.appendMessage(event.message);
|
|
786
|
+
entryId = this.sessionManager.appendMessage(event.message);
|
|
477
787
|
}
|
|
788
|
+
if (entryId)
|
|
789
|
+
this._entryIdsByMessage.set(event.message, entryId);
|
|
478
790
|
// Other message types (bashExecution, compactionSummary, branchSummary) are persisted elsewhere
|
|
479
|
-
// Track assistant message for auto-compaction (checked on agent_end)
|
|
480
791
|
if (event.message.role === "assistant") {
|
|
481
|
-
this._lastAssistantMessage = event.message;
|
|
482
792
|
const assistantMsg = event.message;
|
|
793
|
+
this._lastAssistantMessage = assistantMsg;
|
|
483
794
|
// A length stop is itself a recovery trigger, so it must not clear the
|
|
484
795
|
// one-shot overflow-recovery guard before the retry has run.
|
|
485
796
|
if (assistantMsg.stopReason !== "error" && assistantMsg.stopReason !== "length") {
|
|
@@ -508,6 +819,7 @@ export class AgentSession {
|
|
|
508
819
|
// extension and listener dispatch above also picks up messages that turn_end
|
|
509
820
|
// handlers queued.
|
|
510
821
|
if (event.type === "turn_end") {
|
|
822
|
+
this._lastAssistantToolResults = event.toolResults;
|
|
511
823
|
this._flushPendingCustomMessages();
|
|
512
824
|
}
|
|
513
825
|
};
|
|
@@ -526,6 +838,47 @@ export class AgentSession {
|
|
|
526
838
|
}
|
|
527
839
|
return false;
|
|
528
840
|
}
|
|
841
|
+
_findPersistedMessageEntryId(message) {
|
|
842
|
+
const mapped = this._entryIdsByMessage.get(message);
|
|
843
|
+
if (mapped)
|
|
844
|
+
return mapped;
|
|
845
|
+
for (const entry of [...this.sessionManager.getBranch()].reverse()) {
|
|
846
|
+
if (entry.type === "message" && entry.message === message)
|
|
847
|
+
return entry.id;
|
|
848
|
+
}
|
|
849
|
+
const messageIndex = this.agent.state.messages.indexOf(message);
|
|
850
|
+
if (messageIndex < 0)
|
|
851
|
+
return undefined;
|
|
852
|
+
const projection = this.sessionManager.buildSessionProjection();
|
|
853
|
+
let projectedIndex = 0;
|
|
854
|
+
for (const entry of projection.entries) {
|
|
855
|
+
for (let i = 0; i < entry.messages.length; i++) {
|
|
856
|
+
if (projectedIndex === messageIndex) {
|
|
857
|
+
this._entryIdsByMessage.set(message, entry.sourceEntry.id);
|
|
858
|
+
return entry.sourceEntry.id;
|
|
859
|
+
}
|
|
860
|
+
projectedIndex++;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
return undefined;
|
|
864
|
+
}
|
|
865
|
+
_omitRecoveryAttempt(message, toolResults = []) {
|
|
866
|
+
const targets = [message, ...toolResults];
|
|
867
|
+
const targetIds = targets.map((target) => this._findPersistedMessageEntryId(target));
|
|
868
|
+
const unresolvedProjectedTarget = targets.some((target, index) => targetIds[index] === undefined && this.agent.state.messages.includes(target));
|
|
869
|
+
if (unresolvedProjectedTarget) {
|
|
870
|
+
throw new Error("Cannot persist recovery omission because a projected message has no source entry");
|
|
871
|
+
}
|
|
872
|
+
for (const targetId of targetIds) {
|
|
873
|
+
if (!targetId)
|
|
874
|
+
continue;
|
|
875
|
+
const editId = this.sessionManager.appendContextEdit(targetId, null);
|
|
876
|
+
const entry = this.sessionManager.getEntry(editId);
|
|
877
|
+
if (entry)
|
|
878
|
+
this._emit({ type: "entry_appended", entry });
|
|
879
|
+
}
|
|
880
|
+
this._refreshFinalizedContext();
|
|
881
|
+
}
|
|
529
882
|
/** Find the last assistant message in agent state (including aborted ones) */
|
|
530
883
|
_findLastAssistantMessage() {
|
|
531
884
|
const messages = this.agent.state.messages;
|
|
@@ -575,13 +928,9 @@ export class AgentSession {
|
|
|
575
928
|
await this._extensionRunner.emit(extensionEvent);
|
|
576
929
|
}
|
|
577
930
|
else if (event.type === "turn_end") {
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
message: event.message,
|
|
582
|
-
toolResults: event.toolResults,
|
|
583
|
-
};
|
|
584
|
-
await this._extensionRunner.emit(extensionEvent);
|
|
931
|
+
if (event.message.role === "assistant" && !this._boundaryDispatchedMessages.delete(event.message)) {
|
|
932
|
+
await this._dispatchTurnEndBoundary(event.message, event.toolResults);
|
|
933
|
+
}
|
|
585
934
|
this._turnIndex++;
|
|
586
935
|
}
|
|
587
936
|
else if (event.type === "message_start") {
|
|
@@ -645,6 +994,7 @@ export class AgentSession {
|
|
|
645
994
|
toolName: event.toolName,
|
|
646
995
|
result: event.result,
|
|
647
996
|
isError: event.isError,
|
|
997
|
+
...(event.durationMs === undefined ? {} : { durationMs: event.durationMs }),
|
|
648
998
|
};
|
|
649
999
|
await this._extensionRunner.emit(extensionEvent);
|
|
650
1000
|
}
|
|
@@ -664,26 +1014,13 @@ export class AgentSession {
|
|
|
664
1014
|
}
|
|
665
1015
|
};
|
|
666
1016
|
}
|
|
667
|
-
/**
|
|
668
|
-
* Temporarily disconnect from agent events.
|
|
669
|
-
* User listeners are preserved and will receive events again after resubscribe().
|
|
670
|
-
* Used internally during operations that need to pause event processing.
|
|
671
|
-
*/
|
|
1017
|
+
/** Disconnect from agent events during disposal. */
|
|
672
1018
|
_disconnectFromAgent() {
|
|
673
1019
|
if (this._unsubscribeAgent) {
|
|
674
1020
|
this._unsubscribeAgent();
|
|
675
1021
|
this._unsubscribeAgent = undefined;
|
|
676
1022
|
}
|
|
677
1023
|
}
|
|
678
|
-
/**
|
|
679
|
-
* Reconnect to agent events after _disconnectFromAgent().
|
|
680
|
-
* Preserves all existing listeners.
|
|
681
|
-
*/
|
|
682
|
-
_reconnectToAgent() {
|
|
683
|
-
if (this._unsubscribeAgent)
|
|
684
|
-
return; // Already connected
|
|
685
|
-
this._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);
|
|
686
|
-
}
|
|
687
1024
|
/**
|
|
688
1025
|
* Remove all listeners and disconnect from agent.
|
|
689
1026
|
* Call this when completely done with the session.
|
|
@@ -711,6 +1048,10 @@ export class AgentSession {
|
|
|
711
1048
|
// =========================================================================
|
|
712
1049
|
// Read-only State Access
|
|
713
1050
|
// =========================================================================
|
|
1051
|
+
/** Refresh the public finalized transcript from the canonical session projection. */
|
|
1052
|
+
refreshContext() {
|
|
1053
|
+
this._refreshFinalizedContext();
|
|
1054
|
+
}
|
|
714
1055
|
/** Full agent state */
|
|
715
1056
|
get state() {
|
|
716
1057
|
return this.agent.state;
|
|
@@ -732,6 +1073,14 @@ export class AgentSession {
|
|
|
732
1073
|
get thinkingLevel() {
|
|
733
1074
|
return this.agent.state.thinkingLevel;
|
|
734
1075
|
}
|
|
1076
|
+
/** Under a virtual selection, the physical model and thinking level of the latest successful response. */
|
|
1077
|
+
get routedModel() {
|
|
1078
|
+
if (!this.model || !isVirtualModel(this.model))
|
|
1079
|
+
return undefined;
|
|
1080
|
+
const latest = findLatestResponse(this.agent.state.messages);
|
|
1081
|
+
const model = latest && this._modelRuntime.getPhysicalModel(latest.provider, latest.model);
|
|
1082
|
+
return model && { model, thinkingLevel: latest?.thinkingLevel };
|
|
1083
|
+
}
|
|
735
1084
|
/** Whether the session is currently processing an agent run or post-run continuation. */
|
|
736
1085
|
get isStreaming() {
|
|
737
1086
|
return this._isAgentRunActive;
|
|
@@ -749,12 +1098,16 @@ export class AgentSession {
|
|
|
749
1098
|
return this._retryAttempt;
|
|
750
1099
|
}
|
|
751
1100
|
/**
|
|
752
|
-
* Get the names of currently active tools.
|
|
753
|
-
*
|
|
1101
|
+
* Get the names of currently active tools, which are the tools declared to the model.
|
|
1102
|
+
* Tools with `codemode` or `deferred` exposure are callable from other tools without being active.
|
|
754
1103
|
*/
|
|
755
1104
|
getActiveToolNames() {
|
|
756
1105
|
return this.agent.state.tools.map((t) => t.name);
|
|
757
1106
|
}
|
|
1107
|
+
/** Get the names of the tools that tools can call through `ctx.executeTool()`. */
|
|
1108
|
+
getCallableToolNames() {
|
|
1109
|
+
return this._getCallableTools().map((t) => t.name);
|
|
1110
|
+
}
|
|
758
1111
|
/**
|
|
759
1112
|
* Get all configured tools with name, description, parameter schema, prompt guidelines, and source metadata.
|
|
760
1113
|
*/
|
|
@@ -764,7 +1117,9 @@ export class AgentSession {
|
|
|
764
1117
|
description: definition.description,
|
|
765
1118
|
parameters: definition.parameters,
|
|
766
1119
|
promptGuidelines: definition.promptGuidelines,
|
|
767
|
-
|
|
1120
|
+
exposure: this._getToolExposure(definition.name),
|
|
1121
|
+
...(definition.namespace ? { namespace: definition.namespace } : {}),
|
|
1122
|
+
...(definition.annotations ? { annotations: { ...definition.annotations } } : {}),
|
|
768
1123
|
sourceInfo,
|
|
769
1124
|
}));
|
|
770
1125
|
}
|
|
@@ -773,22 +1128,113 @@ export class AgentSession {
|
|
|
773
1128
|
}
|
|
774
1129
|
/**
|
|
775
1130
|
* Set active tools by name.
|
|
776
|
-
* Only tools in the registry can be enabled. Unknown tool names are ignored.
|
|
1131
|
+
* Only tools in the registry can be enabled. Unknown and hidden tool names are ignored.
|
|
777
1132
|
* Also rebuilds the system prompt to reflect the new tool set.
|
|
778
1133
|
* Changes take effect on the next agent turn.
|
|
779
1134
|
*/
|
|
780
1135
|
setActiveToolsByName(toolNames) {
|
|
781
|
-
const
|
|
782
|
-
|
|
783
|
-
|
|
1136
|
+
const previous = this.getActiveToolNames();
|
|
1137
|
+
this._setActiveTools(toolNames);
|
|
1138
|
+
// A loadout that deactivates a tool replaces the restored one, whose pending tools are dropped.
|
|
1139
|
+
// One that only adds tools, like activating tool_search, keeps them.
|
|
1140
|
+
const active = new Set(this.getActiveToolNames());
|
|
1141
|
+
if (previous.some((name) => !active.has(name)))
|
|
1142
|
+
this._pendingToolNames.clear();
|
|
1143
|
+
}
|
|
1144
|
+
_setActiveTools(toolNames) {
|
|
1145
|
+
const tools = this._applyToolLoadout(toolNames);
|
|
1146
|
+
for (const tool of tools)
|
|
1147
|
+
this._pendingToolNames.delete(tool.name);
|
|
1148
|
+
this._rebuildSystemPrompt(tools.map((tool) => tool.name));
|
|
1149
|
+
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Whether `--tools` and `--exclude-tools` keep the tool registered. MCP tools stay registered
|
|
1152
|
+
* unless the allowlist filters them (see `_allowlistFiltersMcp`).
|
|
1153
|
+
*/
|
|
1154
|
+
_isAllowedTool(name) {
|
|
1155
|
+
if (this._excludedTools?.(name))
|
|
1156
|
+
return false;
|
|
1157
|
+
if (!this._allowedTools || this._allowedTools(name))
|
|
1158
|
+
return true;
|
|
1159
|
+
return !this._allowlistFiltersMcp && isMcpToolName(name);
|
|
1160
|
+
}
|
|
1161
|
+
/**
|
|
1162
|
+
* Whether the tool may be active, which declares it to the model. MCP tools the allowlist keeps
|
|
1163
|
+
* without matching them are only for codemode and tool_search: they may be declared only when
|
|
1164
|
+
* tool_search can load them (non-`direct` exposure and tool_search registered). This also applies
|
|
1165
|
+
* to tools restored from the transcript or set by extensions.
|
|
1166
|
+
*/
|
|
1167
|
+
_isActivatable(name) {
|
|
1168
|
+
if (!this._allowedTools || this._allowedTools(name) || !isMcpToolName(name))
|
|
1169
|
+
return true;
|
|
1170
|
+
return this._getToolExposure(name) !== "direct" && this._toolRegistry.has("tool_search");
|
|
1171
|
+
}
|
|
1172
|
+
_getToolExposure(name) {
|
|
1173
|
+
return this._toolDefinitions.get(name)?.definition.exposure ?? "direct";
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Tools callable through `ctx.executeTool()`: the active `direct` tools and every registered
|
|
1177
|
+
* `codemode` or `deferred` tool.
|
|
1178
|
+
*/
|
|
1179
|
+
_getCallableTools(active = new Set(this.getActiveToolNames())) {
|
|
1180
|
+
return [...this._toolRegistry.values()].filter((tool) => {
|
|
1181
|
+
const exposure = this._getToolExposure(tool.name);
|
|
1182
|
+
return exposure === "codemode" || exposure === "deferred" || (exposure === "direct" && active.has(tool.name));
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
/**
|
|
1186
|
+
* Set the agent's tools for the given active tool names and return them. The active tools are
|
|
1187
|
+
* the registered, non-hidden ones; they are declared to the model. Active tools with a
|
|
1188
|
+
* `prepareLoadout` hook can change the declared descriptions and hide declarations from
|
|
1189
|
+
* requests (see {@link _installHiddenDeclarationsProjection}).
|
|
1190
|
+
*/
|
|
1191
|
+
_applyToolLoadout(toolNames) {
|
|
1192
|
+
const tools = [...new Set(toolNames)].flatMap((name) => {
|
|
784
1193
|
const tool = this._toolRegistry.get(name);
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
1194
|
+
return tool && this._getToolExposure(name) !== "hidden" && this._isActivatable(name) ? [tool] : [];
|
|
1195
|
+
});
|
|
1196
|
+
const hooks = tools.flatMap((tool) => {
|
|
1197
|
+
const entry = this._toolDefinitions.get(tool.name);
|
|
1198
|
+
return entry?.definition.prepareLoadout ? [entry] : [];
|
|
1199
|
+
});
|
|
1200
|
+
const hidden = new Set();
|
|
1201
|
+
let declared = tools;
|
|
1202
|
+
if (hooks.length > 0) {
|
|
1203
|
+
const loadout = {
|
|
1204
|
+
declared: tools,
|
|
1205
|
+
callable: this._getCallableTools(new Set(tools.map((tool) => tool.name))),
|
|
1206
|
+
registered: [...this._toolRegistry.values()],
|
|
1207
|
+
getExposure: (name) => this._getToolExposure(name),
|
|
1208
|
+
getNamespace: (name) => this._toolDefinitions.get(name)?.definition.namespace,
|
|
1209
|
+
getPromptGuidelines: (name) => this._toolPromptGuidelines.get(name) ?? [],
|
|
1210
|
+
};
|
|
1211
|
+
const descriptions = new Map();
|
|
1212
|
+
for (const { definition, sourceInfo } of hooks) {
|
|
1213
|
+
try {
|
|
1214
|
+
const changes = definition.prepareLoadout?.(loadout);
|
|
1215
|
+
for (const [name, description] of Object.entries(changes?.descriptions ?? {})) {
|
|
1216
|
+
descriptions.set(name, description);
|
|
1217
|
+
}
|
|
1218
|
+
for (const name of changes?.hiddenDeclarations ?? [])
|
|
1219
|
+
hidden.add(name);
|
|
1220
|
+
}
|
|
1221
|
+
catch (error) {
|
|
1222
|
+
this._extensionRunner.emitError({
|
|
1223
|
+
extensionPath: sourceInfo.path,
|
|
1224
|
+
event: "prepare_loadout",
|
|
1225
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1226
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
1227
|
+
});
|
|
1228
|
+
}
|
|
788
1229
|
}
|
|
1230
|
+
declared = tools.map((tool) => {
|
|
1231
|
+
const description = descriptions.get(tool.name);
|
|
1232
|
+
return description === undefined ? tool : { ...tool, description };
|
|
1233
|
+
});
|
|
789
1234
|
}
|
|
790
|
-
this.
|
|
791
|
-
this.
|
|
1235
|
+
this._hiddenDeclarations = hidden;
|
|
1236
|
+
this.agent.state.tools = declared;
|
|
1237
|
+
return declared;
|
|
792
1238
|
}
|
|
793
1239
|
/** Whether compaction or branch summarization is currently running */
|
|
794
1240
|
get isCompacting() {
|
|
@@ -859,6 +1305,7 @@ export class AgentSession {
|
|
|
859
1305
|
const toolSnippets = {};
|
|
860
1306
|
for (const name of this._toolRegistry.keys()) {
|
|
861
1307
|
const snippet = this._toolPromptSnippets.get(name);
|
|
1308
|
+
// Tools without a snippet are not listed.
|
|
862
1309
|
if (snippet)
|
|
863
1310
|
toolSnippets[name] = snippet;
|
|
864
1311
|
}
|
|
@@ -876,6 +1323,7 @@ export class AgentSession {
|
|
|
876
1323
|
customPrompt: loaderSystemPrompt,
|
|
877
1324
|
appendSystemPrompt,
|
|
878
1325
|
selectedTools: validToolNames,
|
|
1326
|
+
hiddenTools: [...this._hiddenDeclarations],
|
|
879
1327
|
toolSnippets,
|
|
880
1328
|
toolGuidelines: Object.fromEntries(this._toolPromptGuidelines),
|
|
881
1329
|
});
|
|
@@ -891,11 +1339,9 @@ export class AgentSession {
|
|
|
891
1339
|
* {@link _installAgentForcedPromptProjection}.
|
|
892
1340
|
*/
|
|
893
1341
|
_preparePromptAndToolLoadout(options, messages = this.agent.state.messages) {
|
|
894
|
-
options.selectedTools =
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
return tool ? [tool] : [];
|
|
898
|
-
});
|
|
1342
|
+
options.selectedTools = this._applyToolLoadout(options.selectedTools).map((tool) => tool.name);
|
|
1343
|
+
// The tool list and rules must match the declarations the request carries.
|
|
1344
|
+
options.hiddenTools = [...this._hiddenDeclarations];
|
|
899
1345
|
const sections = diffSystemPromptSections(getCurrentSystemMessage(messages)?.sections ?? {}, buildSystemPromptSections(options));
|
|
900
1346
|
return sections ? { role: "system", content: "", sections, timestamp: Date.now() } : undefined;
|
|
901
1347
|
}
|
|
@@ -909,6 +1355,32 @@ export class AgentSession {
|
|
|
909
1355
|
* collapse into one head holding the forced text and the current tools. Runs after the
|
|
910
1356
|
* `context` extension handlers.
|
|
911
1357
|
*/
|
|
1358
|
+
/**
|
|
1359
|
+
* Remove the declarations that `prepareLoadout` hooks hide from every request. The whole
|
|
1360
|
+
* transcript is filtered with the current set, so the projected declarations stay consistent
|
|
1361
|
+
* across requests and only change when the loadout does.
|
|
1362
|
+
*/
|
|
1363
|
+
_installHiddenDeclarationsProjection() {
|
|
1364
|
+
const previousTransformContext = this.agent.transformContext;
|
|
1365
|
+
this.agent.transformContext = async (messages, signal) => {
|
|
1366
|
+
const transformed = previousTransformContext ? await previousTransformContext(messages, signal) : messages;
|
|
1367
|
+
const hidden = this._hiddenDeclarations;
|
|
1368
|
+
if (hidden.size === 0)
|
|
1369
|
+
return transformed;
|
|
1370
|
+
return transformed.map((message) => {
|
|
1371
|
+
if (message.role !== "system" || (!message.toolsAdded && !message.toolsRemoved))
|
|
1372
|
+
return message;
|
|
1373
|
+
const { toolsAdded, toolsRemoved, ...rest } = message;
|
|
1374
|
+
const added = toolsAdded?.filter((tool) => !hidden.has(tool.name)) ?? [];
|
|
1375
|
+
const removed = toolsRemoved?.filter((tool) => !hidden.has(tool.name)) ?? [];
|
|
1376
|
+
return {
|
|
1377
|
+
...rest,
|
|
1378
|
+
...(added.length > 0 ? { toolsAdded: added } : {}),
|
|
1379
|
+
...(removed.length > 0 ? { toolsRemoved: removed } : {}),
|
|
1380
|
+
};
|
|
1381
|
+
});
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
912
1384
|
_installAgentForcedPromptProjection() {
|
|
913
1385
|
const previousTransformContext = this.agent.transformContext;
|
|
914
1386
|
this.agent.transformContext = async (messages, signal) => {
|
|
@@ -926,29 +1398,43 @@ export class AgentSession {
|
|
|
926
1398
|
return [head, ...transformed.filter((message) => message.role !== "system")];
|
|
927
1399
|
};
|
|
928
1400
|
}
|
|
929
|
-
/**
|
|
1401
|
+
/**
|
|
1402
|
+
* Restore the active tool loadout declared by the session transcript, if it declares one.
|
|
1403
|
+
* Tools reachable only from other tools are never declared, but they do not depend on the active
|
|
1404
|
+
* set, so the transcript's declarations are the whole loadout.
|
|
1405
|
+
*/
|
|
930
1406
|
_restoreToolsFromTranscript() {
|
|
1407
|
+
this._pendingToolNames.clear();
|
|
931
1408
|
const current = getCurrentSystemMessage(this.sessionManager.buildSessionContext().messages);
|
|
932
1409
|
if (!current)
|
|
933
1410
|
return;
|
|
934
|
-
const
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
this.agent.state.tools = toolNames.flatMap((name) => {
|
|
938
|
-
const registered = this._toolRegistry.get(name);
|
|
939
|
-
return registered ? [registered] : [];
|
|
940
|
-
});
|
|
941
|
-
this._rebuildSystemPrompt(toolNames);
|
|
1411
|
+
const names = (current.toolsAdded ?? []).map((tool) => tool.name);
|
|
1412
|
+
this._pendingToolNames = new Set(names.filter((name) => this._isAllowedTool(name)));
|
|
1413
|
+
this._setActiveTools(names);
|
|
942
1414
|
}
|
|
943
1415
|
// =========================================================================
|
|
944
1416
|
// Prompting
|
|
945
1417
|
// =========================================================================
|
|
946
1418
|
async _runAgentPrompt(messages) {
|
|
947
1419
|
this._agentRunAbortRequested = false;
|
|
1420
|
+
// Compaction before the prompt may have scheduled a retry; the new prompt replaces it.
|
|
1421
|
+
this._failedResponse = undefined;
|
|
1422
|
+
this._recordSelection();
|
|
1423
|
+
// The run records the loadout in the transcript; restored tools that did not register by now
|
|
1424
|
+
// are dropped, so a tool that never registers does not stay pending.
|
|
1425
|
+
this._pendingToolNames.clear();
|
|
948
1426
|
this._isAgentRunActive = true;
|
|
949
1427
|
try {
|
|
950
1428
|
await this.agent.prompt(messages);
|
|
951
|
-
while (
|
|
1429
|
+
while (!this._agentRunAbortRequested) {
|
|
1430
|
+
if (await this._handlePostAgentRun()) {
|
|
1431
|
+
if (this._agentRunAbortRequested)
|
|
1432
|
+
break;
|
|
1433
|
+
await this.agent.continue();
|
|
1434
|
+
continue;
|
|
1435
|
+
}
|
|
1436
|
+
if (this._agentRunAbortRequested || !(await this._runBeforeSettleBoundary()))
|
|
1437
|
+
break;
|
|
952
1438
|
if (this._agentRunAbortRequested)
|
|
953
1439
|
break;
|
|
954
1440
|
await this.agent.continue();
|
|
@@ -957,6 +1443,7 @@ export class AgentSession {
|
|
|
957
1443
|
finally {
|
|
958
1444
|
if (this._agentRunAbortRequested)
|
|
959
1445
|
this._finishCancelledRetry();
|
|
1446
|
+
this._failedResponse = undefined;
|
|
960
1447
|
this._runSystemPromptOptions = undefined;
|
|
961
1448
|
this._flushPendingBashMessages();
|
|
962
1449
|
this._flushPendingCustomMessages();
|
|
@@ -964,43 +1451,52 @@ export class AgentSession {
|
|
|
964
1451
|
}
|
|
965
1452
|
}
|
|
966
1453
|
async _handlePostAgentRun() {
|
|
967
|
-
const
|
|
1454
|
+
const message = this._lastAssistantMessage;
|
|
1455
|
+
const toolResults = this._lastAssistantToolResults;
|
|
968
1456
|
this._lastAssistantMessage = undefined;
|
|
1457
|
+
this._lastAssistantToolResults = [];
|
|
969
1458
|
if (this._agentRunAbortRequested) {
|
|
970
1459
|
this._finishCancelledRetry();
|
|
971
1460
|
return false;
|
|
972
1461
|
}
|
|
973
|
-
if (!
|
|
974
|
-
return
|
|
975
|
-
|
|
976
|
-
if (this._isRetryableError(msg) && (await this._prepareRetry(msg))) {
|
|
1462
|
+
if (!message)
|
|
1463
|
+
return this.agent.hasQueuedMessages();
|
|
1464
|
+
if (this._isRetryableError(message) && (await this._prepareRetry(message))) {
|
|
977
1465
|
if (this._agentRunAbortRequested)
|
|
978
1466
|
this._finishCancelledRetry();
|
|
1467
|
+
this._failedResponse = message;
|
|
979
1468
|
return !this._agentRunAbortRequested;
|
|
980
1469
|
}
|
|
981
1470
|
if (this._agentRunAbortRequested) {
|
|
982
1471
|
this._finishCancelledRetry();
|
|
983
1472
|
return false;
|
|
984
1473
|
}
|
|
985
|
-
if (
|
|
1474
|
+
if (message.stopReason === "error" && this._retryAttempt > 0) {
|
|
986
1475
|
this._emit({
|
|
987
1476
|
type: "auto_retry_end",
|
|
988
1477
|
success: false,
|
|
989
1478
|
attempt: this._retryAttempt,
|
|
990
|
-
finalError:
|
|
1479
|
+
finalError: message.errorMessage,
|
|
991
1480
|
});
|
|
992
1481
|
this._retryAttempt = 0;
|
|
993
1482
|
}
|
|
994
|
-
if (await this._checkCompaction(
|
|
1483
|
+
if (await this._checkCompaction(message, true, toolResults)) {
|
|
995
1484
|
return !this._agentRunAbortRequested;
|
|
996
1485
|
}
|
|
997
1486
|
// A length stop means the model hit the output token limit mid-response.
|
|
998
1487
|
// The agent loop already re-prompts when truncated tool calls are present;
|
|
999
1488
|
// here the loop stopped on truncated text, so queue a follow-up to continue.
|
|
1000
1489
|
// Compaction runs first: a length stop caused by context pressure (input
|
|
1001
|
-
// filling the window) should compact instead of blindly continuing.
|
|
1002
|
-
|
|
1003
|
-
|
|
1490
|
+
// filling the window) should compact instead of blindly continuing. Once
|
|
1491
|
+
// durable recovery omits an attempt, a failed compaction must not fall
|
|
1492
|
+
// through to continuation with that attempt absent from canonical context.
|
|
1493
|
+
const lengthEntryId = message.stopReason === "length" ? this._findPersistedMessageEntryId(message) : undefined;
|
|
1494
|
+
const lengthResponseRetained = lengthEntryId === undefined ||
|
|
1495
|
+
this.sessionManager.buildSessionProjection().entries.some((entry) => entry.sourceEntry.id === lengthEntryId &&
|
|
1496
|
+
entry.messages.some((projected) => projected.role === "assistant"));
|
|
1497
|
+
if (message.stopReason === "length" &&
|
|
1498
|
+
lengthResponseRetained &&
|
|
1499
|
+
!message.content.some((c) => c.type === "toolCall") &&
|
|
1004
1500
|
this._lengthContinuations < MAX_LENGTH_CONTINUATIONS) {
|
|
1005
1501
|
this._lengthContinuations++;
|
|
1006
1502
|
await this._queueFollowUp(LENGTH_CONTINUATION_MESSAGE);
|
|
@@ -1010,6 +1506,30 @@ export class AgentSession {
|
|
|
1010
1506
|
// here were queued by agent_end extension handlers and need a continuation.
|
|
1011
1507
|
return !this._agentRunAbortRequested && this.agent.hasQueuedMessages();
|
|
1012
1508
|
}
|
|
1509
|
+
async _runBeforeSettleBoundary() {
|
|
1510
|
+
if (!this._extensionRunner.hasHandlers("agent_before_settle"))
|
|
1511
|
+
return this.agent.hasQueuedMessages();
|
|
1512
|
+
this._isBeforeSettle = true;
|
|
1513
|
+
this._abortDuringBeforeSettle = false;
|
|
1514
|
+
try {
|
|
1515
|
+
const result = await this._extensionRunner.emitBoundary({ type: "agent_before_settle", outcome: this._lastActivityOutcome }, (entries) => this._buildBoundaryContext(entries, "agent_before_settle"));
|
|
1516
|
+
this._commitBoundaryDrafts(result.entries);
|
|
1517
|
+
this._flushPendingCustomMessages();
|
|
1518
|
+
const finalContext = this._buildBoundaryContext([], "agent_before_settle");
|
|
1519
|
+
if (this._abortDuringBeforeSettle)
|
|
1520
|
+
return false;
|
|
1521
|
+
const shouldContinue = result.continue || this.agent.hasQueuedMessages();
|
|
1522
|
+
if (shouldContinue && !finalContext.canContinue) {
|
|
1523
|
+
if (result.continue)
|
|
1524
|
+
this._reportInvalidBoundaryContinuation("agent_before_settle");
|
|
1525
|
+
return false;
|
|
1526
|
+
}
|
|
1527
|
+
return shouldContinue;
|
|
1528
|
+
}
|
|
1529
|
+
finally {
|
|
1530
|
+
this._isBeforeSettle = false;
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1013
1533
|
async _runInputHandlers(text, images, source, streamingBehavior) {
|
|
1014
1534
|
if (!this._extensionRunner.hasHandlers("input")) {
|
|
1015
1535
|
return { text, images };
|
|
@@ -1023,6 +1543,25 @@ export class AgentSession {
|
|
|
1023
1543
|
}
|
|
1024
1544
|
return { text, images };
|
|
1025
1545
|
}
|
|
1546
|
+
async _normalizePromptImages(images) {
|
|
1547
|
+
if (!images)
|
|
1548
|
+
return { images: [], hints: [] };
|
|
1549
|
+
const normalizedImages = [];
|
|
1550
|
+
const hints = [];
|
|
1551
|
+
for (const image of images) {
|
|
1552
|
+
const processed = await processImage(Buffer.from(image.data, "base64"), image.mimeType, {
|
|
1553
|
+
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
1554
|
+
resizeOptions: this._limitsModel()?.inputLimits?.images?.resize,
|
|
1555
|
+
});
|
|
1556
|
+
if (!processed.ok) {
|
|
1557
|
+
hints.push(processed.message);
|
|
1558
|
+
continue;
|
|
1559
|
+
}
|
|
1560
|
+
normalizedImages.push({ type: "image", data: processed.data, mimeType: processed.mimeType });
|
|
1561
|
+
hints.push(...processed.hints);
|
|
1562
|
+
}
|
|
1563
|
+
return { images: normalizedImages, hints };
|
|
1564
|
+
}
|
|
1026
1565
|
/**
|
|
1027
1566
|
* Send a prompt to the agent.
|
|
1028
1567
|
* - Handles extension commands (registered via pi.registerCommand) immediately, even during streaming
|
|
@@ -1033,149 +1572,137 @@ export class AgentSession {
|
|
|
1033
1572
|
* @throws Error if no model selected or no API key available (when not streaming)
|
|
1034
1573
|
*/
|
|
1035
1574
|
async prompt(text, options) {
|
|
1575
|
+
if (this._isEmittingAgentSettled) {
|
|
1576
|
+
this._deferredSettledActions.push(async () => await this.prompt(text, options));
|
|
1577
|
+
return;
|
|
1578
|
+
}
|
|
1036
1579
|
const expandPromptTemplates = options?.expandPromptTemplates ?? true;
|
|
1037
1580
|
const preflightResult = options?.preflightResult;
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
if (
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
// Extension command executed, no prompt to send
|
|
1046
|
-
preflightResult?.(true);
|
|
1047
|
-
return;
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
if (this._compactionAbortController !== undefined) {
|
|
1051
|
-
throw new Error("Cannot submit a prompt while compaction is in progress. Wait for compaction to finish and retry.");
|
|
1052
|
-
}
|
|
1053
|
-
// Emit input event for extension interception (before skill/template expansion)
|
|
1054
|
-
const processedInput = await this._runInputHandlers(text, options?.images, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
|
|
1055
|
-
if (!processedInput) {
|
|
1056
|
-
preflightResult?.(true);
|
|
1581
|
+
// Handle extension commands first (execute immediately, even during streaming)
|
|
1582
|
+
// Extension commands manage their own LLM interaction via pi.sendMessage()
|
|
1583
|
+
if (expandPromptTemplates && text.startsWith("/")) {
|
|
1584
|
+
const handled = await this._tryExecuteExtensionCommand(text);
|
|
1585
|
+
if (handled) {
|
|
1586
|
+
// Extension command executed, no prompt to send
|
|
1587
|
+
preflightResult?.("handled");
|
|
1057
1588
|
return;
|
|
1058
1589
|
}
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
preflightResult?.(true);
|
|
1087
|
-
return;
|
|
1590
|
+
}
|
|
1591
|
+
if (this._compactionAbortController !== undefined) {
|
|
1592
|
+
throw new Error("Cannot submit a prompt while compaction is in progress. Wait for compaction to finish and retry.");
|
|
1593
|
+
}
|
|
1594
|
+
// Emit input event for extension interception (before skill/template expansion)
|
|
1595
|
+
const processedInput = await this._runInputHandlers(text, options?.images, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
|
|
1596
|
+
if (!processedInput) {
|
|
1597
|
+
preflightResult?.("handled");
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1600
|
+
const { text: currentText, images: currentImages } = processedInput;
|
|
1601
|
+
// Expand skill commands (/skill:name args) and prompt templates (/template args)
|
|
1602
|
+
let expandedText = currentText;
|
|
1603
|
+
if (expandPromptTemplates) {
|
|
1604
|
+
expandedText = this._expandSkillCommand(expandedText);
|
|
1605
|
+
expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
|
|
1606
|
+
}
|
|
1607
|
+
// Fork vision relay: non-vision models receive the configured caption as text.
|
|
1608
|
+
if (currentImages && currentImages.length > 0) {
|
|
1609
|
+
const caption = await this._captionImagesForCurrentModel(currentImages, currentText);
|
|
1610
|
+
if (caption)
|
|
1611
|
+
expandedText += `\n\n${caption}`;
|
|
1612
|
+
}
|
|
1613
|
+
// If streaming, queue via steer() or followUp() based on option
|
|
1614
|
+
if (this.isStreaming) {
|
|
1615
|
+
if (!options?.streamingBehavior) {
|
|
1616
|
+
throw new Error("Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.");
|
|
1088
1617
|
}
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
this._flushPendingCustomMessages();
|
|
1092
|
-
// Validate model
|
|
1093
|
-
if (!this.model) {
|
|
1094
|
-
throw new Error(formatNoModelSelectedMessage());
|
|
1618
|
+
if (options.streamingBehavior === "followUp") {
|
|
1619
|
+
await this._queueFollowUp(expandedText, currentImages);
|
|
1095
1620
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
if (!hasConfiguredAuth) {
|
|
1099
|
-
const isOAuth = this._modelRuntime.isUsingOAuth(this.model.provider);
|
|
1100
|
-
if (isOAuth) {
|
|
1101
|
-
throw new Error(`Authentication failed for "${this.model.provider}". ` +
|
|
1102
|
-
`Credentials may have expired or network is unavailable. ` +
|
|
1103
|
-
`Run '/login ${this.model.provider}' to re-authenticate.`);
|
|
1104
|
-
}
|
|
1105
|
-
throw new Error(formatNoApiKeyFoundMessage(this.model.provider));
|
|
1621
|
+
else {
|
|
1622
|
+
await this._queueSteer(expandedText, currentImages);
|
|
1106
1623
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1624
|
+
preflightResult?.("queued");
|
|
1625
|
+
return;
|
|
1626
|
+
}
|
|
1627
|
+
// Flush any pending bash and custom messages before the new prompt
|
|
1628
|
+
this._flushPendingBashMessages();
|
|
1629
|
+
this._flushPendingCustomMessages();
|
|
1630
|
+
// Validate model
|
|
1631
|
+
if (!this.model) {
|
|
1632
|
+
throw new Error(formatNoModelSelectedMessage());
|
|
1633
|
+
}
|
|
1634
|
+
const hasConfiguredAuth = this._modelRuntime.hasConfiguredAuth(this.model.provider) ||
|
|
1635
|
+
(await this._modelRuntime.checkAuth(this.model.provider)) !== undefined;
|
|
1636
|
+
if (!hasConfiguredAuth) {
|
|
1637
|
+
const isOAuth = this._modelRuntime.isUsingOAuth(this.model.provider);
|
|
1638
|
+
if (isOAuth) {
|
|
1639
|
+
throw new Error(`Authentication failed for "${this.model.provider}". ` +
|
|
1640
|
+
`Credentials may have expired or network is unavailable. ` +
|
|
1641
|
+
`Run '/login ${this.model.provider}' to re-authenticate.`);
|
|
1642
|
+
}
|
|
1643
|
+
throw new Error(formatNoApiKeyFoundMessage(this.model.provider));
|
|
1644
|
+
}
|
|
1645
|
+
// Check if we need to compact before sending (catches aborted responses).
|
|
1646
|
+
// The user's new prompt is sent below, so do not call agent.continue() here.
|
|
1647
|
+
const lastAssistant = this._findLastAssistantMessage();
|
|
1648
|
+
if (lastAssistant) {
|
|
1649
|
+
await this._checkCompaction(lastAssistant, false);
|
|
1650
|
+
}
|
|
1651
|
+
// Emit before_agent_start before normalizing images so extension-driven model
|
|
1652
|
+
// selection determines the resize profile used for the request and history.
|
|
1653
|
+
const selectedToolsBefore = this._baseSystemPromptOptions.selectedTools;
|
|
1654
|
+
const result = await this._extensionRunner.emitBeforeAgentStart(expandedText, currentImages, this._baseSystemPromptOptions);
|
|
1655
|
+
// Handlers may edit event.systemPromptOptions.selectedTools or call setActiveTools(),
|
|
1656
|
+
// which updates the live loadout instead. An explicit edit wins; otherwise the live
|
|
1657
|
+
// loadout is authoritative, so a setActiveTools() call is not undone here.
|
|
1658
|
+
const handlerEditedTools = result.systemPromptOptions.selectedTools.length !== selectedToolsBefore.length ||
|
|
1659
|
+
result.systemPromptOptions.selectedTools.some((name, index) => name !== selectedToolsBefore[index]);
|
|
1660
|
+
if (!handlerEditedTools)
|
|
1661
|
+
result.systemPromptOptions.selectedTools = this.getActiveToolNames();
|
|
1662
|
+
const normalized = await this._normalizePromptImages(currentImages);
|
|
1663
|
+
const userText = normalized.hints.length > 0 ? `${expandedText}\n\n${normalized.hints.join("\n")}` : expandedText;
|
|
1664
|
+
// Another prompt can start while input/caption/auth/hooks preflight awaits.
|
|
1665
|
+
// Queue instead of racing it; do not consume pending next-turn messages yet.
|
|
1666
|
+
if (this.isStreaming) {
|
|
1667
|
+
if (options?.streamingBehavior === "steer") {
|
|
1668
|
+
await this._queueSteer(expandedText, currentImages);
|
|
1112
1669
|
}
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
// Add user message
|
|
1116
|
-
const userContent = [{ type: "text", text: expandedText }];
|
|
1117
|
-
if (currentImages) {
|
|
1118
|
-
userContent.push(...currentImages);
|
|
1670
|
+
else {
|
|
1671
|
+
await this._queueFollowUp(expandedText, currentImages);
|
|
1119
1672
|
}
|
|
1673
|
+
preflightResult?.("queued");
|
|
1674
|
+
return;
|
|
1675
|
+
}
|
|
1676
|
+
// Build messages only after hooks and image normalization have completed.
|
|
1677
|
+
const messages = [];
|
|
1678
|
+
const userContent = [{ type: "text", text: userText }];
|
|
1679
|
+
userContent.push(...normalized.images);
|
|
1680
|
+
messages.push({
|
|
1681
|
+
role: "user",
|
|
1682
|
+
content: userContent,
|
|
1683
|
+
timestamp: Date.now(),
|
|
1684
|
+
});
|
|
1685
|
+
// Inject any pending "nextTurn" messages as context alongside the user message
|
|
1686
|
+
for (const msg of this._pendingNextTurnMessages) {
|
|
1687
|
+
messages.push(msg);
|
|
1688
|
+
}
|
|
1689
|
+
this._pendingNextTurnMessages = [];
|
|
1690
|
+
for (const msg of result.messages) {
|
|
1120
1691
|
messages.push({
|
|
1121
|
-
role: "
|
|
1122
|
-
|
|
1692
|
+
role: "custom",
|
|
1693
|
+
customType: msg.customType,
|
|
1694
|
+
// Untyped extensions can pass null/missing content; normalize at ingestion.
|
|
1695
|
+
content: msg.content ?? [],
|
|
1696
|
+
display: msg.display,
|
|
1697
|
+
details: msg.details,
|
|
1123
1698
|
timestamp: Date.now(),
|
|
1124
1699
|
});
|
|
1125
|
-
// Inject any pending "nextTurn" messages as context alongside the user message
|
|
1126
|
-
for (const msg of this._pendingNextTurnMessages) {
|
|
1127
|
-
messages.push(msg);
|
|
1128
|
-
}
|
|
1129
|
-
this._pendingNextTurnMessages = [];
|
|
1130
|
-
// Emit before_agent_start extension event
|
|
1131
|
-
const selectedToolsBefore = this._baseSystemPromptOptions.selectedTools;
|
|
1132
|
-
const result = await this._extensionRunner.emitBeforeAgentStart(expandedText, currentImages, this._baseSystemPromptOptions);
|
|
1133
|
-
// Handlers may edit event.systemPromptOptions.selectedTools or call setActiveTools(),
|
|
1134
|
-
// which updates the live loadout instead. An explicit edit wins; otherwise the live
|
|
1135
|
-
// loadout is authoritative, so a setActiveTools() call is not undone here.
|
|
1136
|
-
const handlerEditedTools = result.systemPromptOptions.selectedTools.length !== selectedToolsBefore.length ||
|
|
1137
|
-
result.systemPromptOptions.selectedTools.some((name, index) => name !== selectedToolsBefore[index]);
|
|
1138
|
-
if (!handlerEditedTools)
|
|
1139
|
-
result.systemPromptOptions.selectedTools = this.getActiveToolNames();
|
|
1140
|
-
for (const msg of result.messages) {
|
|
1141
|
-
messages.push({
|
|
1142
|
-
role: "custom",
|
|
1143
|
-
customType: msg.customType,
|
|
1144
|
-
// Untyped extensions can pass null/missing content; normalize at ingestion.
|
|
1145
|
-
content: msg.content ?? [],
|
|
1146
|
-
display: msg.display,
|
|
1147
|
-
details: msg.details,
|
|
1148
|
-
timestamp: Date.now(),
|
|
1149
|
-
});
|
|
1150
|
-
}
|
|
1151
|
-
// Another prompt may have started while this one was preflighting (auth
|
|
1152
|
-
// checks, compaction, and extension events can take seconds). The agent is
|
|
1153
|
-
// now streaming, so queue instead of racing the active run: the RPC layer
|
|
1154
|
-
// has already reported preflight success, so throwing here would silently
|
|
1155
|
-
// drop the message. Default to a follow-up so it runs after the current turn.
|
|
1156
|
-
if (this.isStreaming) {
|
|
1157
|
-
if (options?.streamingBehavior === "steer") {
|
|
1158
|
-
await this._queueSteer(expandedText, currentImages);
|
|
1159
|
-
}
|
|
1160
|
-
else {
|
|
1161
|
-
await this._queueFollowUp(expandedText, currentImages);
|
|
1162
|
-
}
|
|
1163
|
-
preflightResult?.(true);
|
|
1164
|
-
return;
|
|
1165
|
-
}
|
|
1166
|
-
const updateMessage = this._preparePromptAndToolLoadout(result.systemPromptOptions);
|
|
1167
|
-
this._runSystemPromptOptions = result.systemPromptOptions;
|
|
1168
|
-
if (updateMessage)
|
|
1169
|
-
messages.unshift(updateMessage);
|
|
1170
|
-
}
|
|
1171
|
-
catch (error) {
|
|
1172
|
-
preflightResult?.(false);
|
|
1173
|
-
throw error;
|
|
1174
|
-
}
|
|
1175
|
-
if (!messages) {
|
|
1176
|
-
return;
|
|
1177
1700
|
}
|
|
1178
|
-
|
|
1701
|
+
const updateMessage = this._preparePromptAndToolLoadout(result.systemPromptOptions);
|
|
1702
|
+
this._runSystemPromptOptions = result.systemPromptOptions;
|
|
1703
|
+
if (updateMessage)
|
|
1704
|
+
messages.unshift(updateMessage);
|
|
1705
|
+
preflightResult?.("started");
|
|
1179
1706
|
await this._runAgentPrompt(messages);
|
|
1180
1707
|
}
|
|
1181
1708
|
/**
|
|
@@ -1241,7 +1768,7 @@ export class AgentSession {
|
|
|
1241
1768
|
}
|
|
1242
1769
|
const processedInput = await this._runInputHandlers(text, images, source, this.isStreaming ? behavior : undefined);
|
|
1243
1770
|
if (!processedInput)
|
|
1244
|
-
return;
|
|
1771
|
+
return "handled";
|
|
1245
1772
|
let expandedText = this._expandSkillCommand(processedInput.text);
|
|
1246
1773
|
expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
|
|
1247
1774
|
if (behavior === "steer") {
|
|
@@ -1250,6 +1777,7 @@ export class AgentSession {
|
|
|
1250
1777
|
else {
|
|
1251
1778
|
await this._queueFollowUp(expandedText, processedInput.images);
|
|
1252
1779
|
}
|
|
1780
|
+
return "queued";
|
|
1253
1781
|
}
|
|
1254
1782
|
/**
|
|
1255
1783
|
* Queue a steering message while the agent is running.
|
|
@@ -1261,7 +1789,7 @@ export class AgentSession {
|
|
|
1261
1789
|
* @throws Error if text is an extension command
|
|
1262
1790
|
*/
|
|
1263
1791
|
async steer(text, images, options) {
|
|
1264
|
-
|
|
1792
|
+
return this._queueUserInput(text, images, "steer", options?.source ?? "interactive");
|
|
1265
1793
|
}
|
|
1266
1794
|
/**
|
|
1267
1795
|
* Queue a follow-up message to be processed after the agent finishes.
|
|
@@ -1272,7 +1800,7 @@ export class AgentSession {
|
|
|
1272
1800
|
* @throws Error if text is an extension command
|
|
1273
1801
|
*/
|
|
1274
1802
|
async followUp(text, images, options) {
|
|
1275
|
-
|
|
1803
|
+
return this._queueUserInput(text, images, "followUp", options?.source ?? "interactive");
|
|
1276
1804
|
}
|
|
1277
1805
|
/**
|
|
1278
1806
|
* Internal: Queue a steering message (already expanded, no extension command check).
|
|
@@ -1300,11 +1828,7 @@ export class AgentSession {
|
|
|
1300
1828
|
if (images) {
|
|
1301
1829
|
content.push(...images);
|
|
1302
1830
|
}
|
|
1303
|
-
this.agent.followUp({
|
|
1304
|
-
role: "user",
|
|
1305
|
-
content,
|
|
1306
|
-
timestamp: Date.now(),
|
|
1307
|
-
});
|
|
1831
|
+
this.agent.followUp({ role: "user", content, timestamp: Date.now() });
|
|
1308
1832
|
}
|
|
1309
1833
|
/**
|
|
1310
1834
|
* Throw an error if the text is an extension command.
|
|
@@ -1352,6 +1876,10 @@ export class AgentSession {
|
|
|
1352
1876
|
}
|
|
1353
1877
|
}
|
|
1354
1878
|
else if (options?.triggerTurn) {
|
|
1879
|
+
if (this._isEmittingAgentSettled) {
|
|
1880
|
+
this._deferredSettledActions.push(async () => await this._runAgentPrompt(appMessage));
|
|
1881
|
+
return;
|
|
1882
|
+
}
|
|
1355
1883
|
await this._runAgentPrompt(appMessage);
|
|
1356
1884
|
}
|
|
1357
1885
|
else if (this.isStreaming) {
|
|
@@ -1366,8 +1894,8 @@ export class AgentSession {
|
|
|
1366
1894
|
}
|
|
1367
1895
|
}
|
|
1368
1896
|
_appendCustomMessage(appMessage) {
|
|
1369
|
-
this.agent.state.messages.push(appMessage);
|
|
1370
1897
|
this.sessionManager.appendCustomMessageEntry(appMessage.customType, appMessage.content, appMessage.display, appMessage.details);
|
|
1898
|
+
this._refreshFinalizedContext();
|
|
1371
1899
|
this._emit({ type: "message_start", message: appMessage });
|
|
1372
1900
|
this._emit({ type: "message_end", message: appMessage });
|
|
1373
1901
|
}
|
|
@@ -1541,6 +2069,7 @@ export class AgentSession {
|
|
|
1541
2069
|
*
|
|
1542
2070
|
* @param content User message content (string or content array)
|
|
1543
2071
|
* @param options.deliverAs Delivery mode when streaming: "steer" or "followUp"
|
|
2072
|
+
* @param options.expandPromptTemplates Whether to dispatch extension commands and expand skill commands and prompt templates. Default: false.
|
|
1544
2073
|
*/
|
|
1545
2074
|
async sendUserMessage(content, options) {
|
|
1546
2075
|
// Normalize content to text string + optional images
|
|
@@ -1564,7 +2093,6 @@ export class AgentSession {
|
|
|
1564
2093
|
if (images.length === 0)
|
|
1565
2094
|
images = undefined;
|
|
1566
2095
|
}
|
|
1567
|
-
// Use prompt() with expandPromptTemplates to control command handling and template expansion
|
|
1568
2096
|
await this.prompt(text, {
|
|
1569
2097
|
expandPromptTemplates: options?.expandPromptTemplates ?? false,
|
|
1570
2098
|
streamingBehavior: options?.deliverAs,
|
|
@@ -1622,6 +2150,8 @@ export class AgentSession {
|
|
|
1622
2150
|
this.abortRetry();
|
|
1623
2151
|
this.abortCompaction();
|
|
1624
2152
|
this.abortBranchSummary();
|
|
2153
|
+
if (this._isBeforeSettle)
|
|
2154
|
+
this._abortDuringBeforeSettle = true;
|
|
1625
2155
|
this.agent.abort();
|
|
1626
2156
|
await this.waitForIdle();
|
|
1627
2157
|
}
|
|
@@ -1646,7 +2176,8 @@ export class AgentSession {
|
|
|
1646
2176
|
}
|
|
1647
2177
|
/**
|
|
1648
2178
|
* Set model directly.
|
|
1649
|
-
* Validates that auth is configured
|
|
2179
|
+
* Validates that auth is configured and saves to the session transcript.
|
|
2180
|
+
* Persists to global defaults only when options.persist is true.
|
|
1650
2181
|
* @throws Error if no auth is configured for the model
|
|
1651
2182
|
*/
|
|
1652
2183
|
async setModel(model, options = {}) {
|
|
@@ -1661,6 +2192,9 @@ export class AgentSession {
|
|
|
1661
2192
|
this.settingsManager.setDefaultModelAndProvider(model.provider, model.id);
|
|
1662
2193
|
this._addPersistedDefaultToNonEmptyScope(model);
|
|
1663
2194
|
}
|
|
2195
|
+
// Apply thinking level for the new model.
|
|
2196
|
+
// Per-model thinking level overrides take priority over the global default.
|
|
2197
|
+
// Model persistence does not implicitly rewrite the global thinking default.
|
|
1664
2198
|
this.setThinkingLevel(thinkingLevel);
|
|
1665
2199
|
await this._emitModelSelect(model, previousModel, "set");
|
|
1666
2200
|
}
|
|
@@ -1691,11 +2225,8 @@ export class AgentSession {
|
|
|
1691
2225
|
return this._cycleAvailableModel(direction, options);
|
|
1692
2226
|
}
|
|
1693
2227
|
async _cycleScopedModel(direction, options) {
|
|
1694
|
-
const
|
|
1695
|
-
|
|
1696
|
-
auth: await this._modelRuntime.checkAuth(scoped.model.provider),
|
|
1697
|
-
})));
|
|
1698
|
-
const scopedModels = checks.filter(({ auth }) => auth !== undefined).map(({ scoped }) => scoped);
|
|
2228
|
+
const availableIds = new Set(this._modelRuntime.getAvailableSnapshot().map((model) => `${model.provider}\0${model.id}`));
|
|
2229
|
+
const scopedModels = this._scopedModels.filter((scoped) => availableIds.has(`${scoped.model.provider}\0${scoped.model.id}`));
|
|
1699
2230
|
if (scopedModels.length <= 1)
|
|
1700
2231
|
return undefined;
|
|
1701
2232
|
const currentModel = this.model;
|
|
@@ -1713,16 +2244,17 @@ export class AgentSession {
|
|
|
1713
2244
|
this.settingsManager.setDefaultModelAndProvider(next.model.provider, next.model.id);
|
|
1714
2245
|
this._addPersistedDefaultToNonEmptyScope(next.model);
|
|
1715
2246
|
}
|
|
1716
|
-
// Apply thinking level.
|
|
1717
|
-
// - Explicit scoped model thinking level overrides
|
|
1718
|
-
// -
|
|
2247
|
+
// Apply thinking level for the new model.
|
|
2248
|
+
// - Explicit scoped model thinking level overrides defaults
|
|
2249
|
+
// - Per-model thinking level overrides take priority over the global default
|
|
1719
2250
|
// setThinkingLevel clamps to model capabilities.
|
|
2251
|
+
// Model persistence does not implicitly rewrite the global thinking default.
|
|
1720
2252
|
this.setThinkingLevel(thinkingLevel);
|
|
1721
2253
|
await this._emitModelSelect(next.model, currentModel, "cycle");
|
|
1722
2254
|
return { model: next.model, thinkingLevel: this.thinkingLevel, isScoped: true };
|
|
1723
2255
|
}
|
|
1724
2256
|
async _cycleAvailableModel(direction, options) {
|
|
1725
|
-
const availableModels =
|
|
2257
|
+
const availableModels = this._modelRuntime.getAvailableSnapshot();
|
|
1726
2258
|
if (availableModels.length <= 1)
|
|
1727
2259
|
return undefined;
|
|
1728
2260
|
const currentModel = this.model;
|
|
@@ -1739,7 +2271,8 @@ export class AgentSession {
|
|
|
1739
2271
|
this.settingsManager.setDefaultModelAndProvider(nextModel.provider, nextModel.id);
|
|
1740
2272
|
this._addPersistedDefaultToNonEmptyScope(nextModel);
|
|
1741
2273
|
}
|
|
1742
|
-
//
|
|
2274
|
+
// Apply thinking level for the new model.
|
|
2275
|
+
// Model persistence does not implicitly rewrite the global thinking default.
|
|
1743
2276
|
this.setThinkingLevel(thinkingLevel);
|
|
1744
2277
|
await this._emitModelSelect(nextModel, currentModel, "cycle");
|
|
1745
2278
|
return { model: nextModel, thinkingLevel: this.thinkingLevel, isScoped: false };
|
|
@@ -1750,7 +2283,8 @@ export class AgentSession {
|
|
|
1750
2283
|
/**
|
|
1751
2284
|
* Set thinking level.
|
|
1752
2285
|
* Clamps to model capabilities based on available thinking levels.
|
|
1753
|
-
* Saves to session
|
|
2286
|
+
* Saves the clamped level to the session transcript only if the level actually changes.
|
|
2287
|
+
* Persists the requested level to global defaults only when options.persist is true.
|
|
1754
2288
|
*/
|
|
1755
2289
|
setThinkingLevel(level, options = {}) {
|
|
1756
2290
|
const availableLevels = this.getAvailableThinkingLevels();
|
|
@@ -1805,10 +2339,12 @@ export class AgentSession {
|
|
|
1805
2339
|
if (explicitLevel !== undefined) {
|
|
1806
2340
|
return explicitLevel;
|
|
1807
2341
|
}
|
|
2342
|
+
// Per-model default takes priority when switching to a model that has one
|
|
1808
2343
|
if (targetModel) {
|
|
1809
2344
|
const perModel = this.settingsManager.getModelThinkingLevel(targetModel.provider, targetModel.id);
|
|
1810
|
-
if (perModel !== undefined)
|
|
2345
|
+
if (perModel !== undefined) {
|
|
1811
2346
|
return perModel;
|
|
2347
|
+
}
|
|
1812
2348
|
}
|
|
1813
2349
|
return this.settingsManager.getDefaultThinkingLevel() ?? this.thinkingLevel ?? DEFAULT_THINKING_LEVEL;
|
|
1814
2350
|
}
|
|
@@ -1841,9 +2377,11 @@ export class AgentSession {
|
|
|
1841
2377
|
// =========================================================================
|
|
1842
2378
|
// Compaction
|
|
1843
2379
|
// =========================================================================
|
|
1844
|
-
/** Generate
|
|
1845
|
-
async _runDefaultCompaction(preparation,
|
|
1846
|
-
|
|
2380
|
+
/** Generate Pi's built-in compaction summary for manual and automatic compaction. */
|
|
2381
|
+
async _runDefaultCompaction(preparation, model, customInstructions, signal, reason) {
|
|
2382
|
+
// Resolve the request only when Pi summarizes itself: routing may call models or fail.
|
|
2383
|
+
const request = await this._getSummarizationRequestAuth(model, signal);
|
|
2384
|
+
return compact(preparation, request.model, request.apiKey, request.headers, customInstructions, signal, request.thinkingLevel, this.agent.streamFunction, request.env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }), undefined);
|
|
1847
2385
|
}
|
|
1848
2386
|
_clearManualCompactionState() {
|
|
1849
2387
|
this._compactionAbortController = undefined;
|
|
@@ -1851,11 +2389,20 @@ export class AgentSession {
|
|
|
1851
2389
|
}
|
|
1852
2390
|
/**
|
|
1853
2391
|
* Manually compact the session context.
|
|
1854
|
-
*
|
|
2392
|
+
*
|
|
2393
|
+
* This is the manual entry point used by `/compact`, RPC, and extensions. It is
|
|
2394
|
+
* separate from automatic threshold/overflow compaction, which enters through
|
|
2395
|
+
* `_checkCompaction()` and `_runAutoCompaction()`. After preparation and the
|
|
2396
|
+
* `session_before_compact` hook, both paths call the lower-level `compact()`
|
|
2397
|
+
* function imported from `./compaction/index.ts`, unless the hook cancels or
|
|
2398
|
+
* supplies a custom result.
|
|
2399
|
+
*
|
|
2400
|
+
* Aborts the current agent operation first. Manual compaction never retries or
|
|
2401
|
+
* continues the interrupted agent turn.
|
|
2402
|
+
*
|
|
1855
2403
|
* @param customInstructions Optional instructions for the compaction summary
|
|
1856
2404
|
*/
|
|
1857
2405
|
async compact(customInstructions) {
|
|
1858
|
-
this._disconnectFromAgent();
|
|
1859
2406
|
await this.abort();
|
|
1860
2407
|
this._compactionAbortController = new AbortController();
|
|
1861
2408
|
this._emit({ type: "compaction_start", reason: "manual" });
|
|
@@ -1867,7 +2414,6 @@ export class AgentSession {
|
|
|
1867
2414
|
throw new Error(formatNoModelSelectedMessage());
|
|
1868
2415
|
}
|
|
1869
2416
|
const settings = this.settingsManager.getCompactionSettings(model);
|
|
1870
|
-
const { model: requestModel, apiKey, headers, env, } = await this._getSummarizationRequestAuth(model, this._compactionAbortController.signal);
|
|
1871
2417
|
const pathEntries = this.sessionManager.getBranch();
|
|
1872
2418
|
const preparation = prepareCompaction(pathEntries, settings);
|
|
1873
2419
|
if (!preparation) {
|
|
@@ -1879,7 +2425,6 @@ export class AgentSession {
|
|
|
1879
2425
|
throw new Error("Nothing to compact (session too small)");
|
|
1880
2426
|
}
|
|
1881
2427
|
let extensionCompaction;
|
|
1882
|
-
let fromExtension = false;
|
|
1883
2428
|
if (this._extensionRunner.hasHandlers("session_before_compact")) {
|
|
1884
2429
|
const result = (await this._extensionRunner.emit({
|
|
1885
2430
|
type: "session_before_compact",
|
|
@@ -1914,7 +2459,7 @@ export class AgentSession {
|
|
|
1914
2459
|
}
|
|
1915
2460
|
else {
|
|
1916
2461
|
// Shared default summary generator, also used by automatic compaction.
|
|
1917
|
-
const result = await this._runDefaultCompaction(preparation,
|
|
2462
|
+
const result = await this._runDefaultCompaction(preparation, model, customInstructions, this._compactionAbortController.signal, "manual");
|
|
1918
2463
|
summary = result.summary;
|
|
1919
2464
|
firstKeptEntryId = result.firstKeptEntryId;
|
|
1920
2465
|
tokensBefore = result.tokensBefore;
|
|
@@ -1926,9 +2471,8 @@ export class AgentSession {
|
|
|
1926
2471
|
}
|
|
1927
2472
|
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension, usage);
|
|
1928
2473
|
const newEntries = this.sessionManager.getEntries();
|
|
1929
|
-
|
|
1930
|
-
this.
|
|
1931
|
-
const estimatedTokensAfter = estimateMessagesTokens(sessionContext.messages);
|
|
2474
|
+
this._refreshFinalizedContext();
|
|
2475
|
+
const estimatedTokensAfter = estimateMessagesTokens(this.sessionManager.buildSessionProjection().messages);
|
|
1932
2476
|
// Get the saved compaction entry for the extension event
|
|
1933
2477
|
const savedCompactionEntry = newEntries.find((e) => e.type === "compaction" && e.summary === summary);
|
|
1934
2478
|
if (this._extensionRunner && savedCompactionEntry) {
|
|
@@ -1977,13 +2521,12 @@ export class AgentSession {
|
|
|
1977
2521
|
errorMessage,
|
|
1978
2522
|
aborted,
|
|
1979
2523
|
willRetry: false,
|
|
1980
|
-
fromExtension
|
|
2524
|
+
fromExtension,
|
|
1981
2525
|
});
|
|
1982
2526
|
throw error;
|
|
1983
2527
|
}
|
|
1984
2528
|
finally {
|
|
1985
2529
|
this._clearManualCompactionState();
|
|
1986
|
-
this._reconnectToAgent();
|
|
1987
2530
|
}
|
|
1988
2531
|
}
|
|
1989
2532
|
/**
|
|
@@ -2000,29 +2543,41 @@ export class AgentSession {
|
|
|
2000
2543
|
this._branchSummaryAbortController?.abort();
|
|
2001
2544
|
}
|
|
2002
2545
|
/**
|
|
2003
|
-
*
|
|
2004
|
-
*
|
|
2546
|
+
* Dispatch automatic compaction after `agent_end` or before prompt submission.
|
|
2547
|
+
* Manual compaction does not call this method; it enters through `compact()`.
|
|
2548
|
+
*
|
|
2549
|
+
* Automatic cases:
|
|
2550
|
+
* 1. Overflow with retry: a context-overflow error or recoverable length stop;
|
|
2551
|
+
* remove the failed assistant message, compact, and retry the turn once.
|
|
2552
|
+
* 2. Overflow without retry: a successful response exceeded the configured
|
|
2553
|
+
* context window; compact but preserve the completed response.
|
|
2554
|
+
* 3. Threshold without retry: valid or estimated context usage crossed the
|
|
2555
|
+
* configured threshold; compact without retrying the completed response.
|
|
2005
2556
|
*
|
|
2006
|
-
*
|
|
2007
|
-
*
|
|
2008
|
-
*
|
|
2557
|
+
* Each case calls `_runAutoCompaction()`. After preparation and the
|
|
2558
|
+
* `session_before_compact` hook, that method calls the lower-level `compact()`
|
|
2559
|
+
* function imported from `./compaction/index.ts`, unless the hook cancels or
|
|
2560
|
+
* supplies a custom result.
|
|
2009
2561
|
*
|
|
2010
2562
|
* @param assistantMessage The assistant message to check
|
|
2011
2563
|
* @param skipAbortedCheck If false, include aborted messages (for pre-prompt check). Default: true
|
|
2564
|
+
* @returns Whether the post-run loop should call `agent.continue()` for overflow recovery or queued messages
|
|
2012
2565
|
*/
|
|
2013
|
-
async _checkCompaction(assistantMessage, skipAbortedCheck = true) {
|
|
2566
|
+
async _checkCompaction(assistantMessage, skipAbortedCheck = true, toolResults = []) {
|
|
2014
2567
|
const settings = this.settingsManager.getCompactionSettings(this.model);
|
|
2015
2568
|
if (!settings.enabled)
|
|
2016
2569
|
return false;
|
|
2017
2570
|
// Skip if message was aborted (user cancelled) - unless skipAbortedCheck is false
|
|
2018
2571
|
if (skipAbortedCheck && assistantMessage.stopReason === "aborted")
|
|
2019
2572
|
return false;
|
|
2020
|
-
const contextWindow = this.model?.contextWindow ?? 0;
|
|
2021
2573
|
// Skip overflow check if the message came from a different model.
|
|
2022
2574
|
// This handles the case where user switched from a smaller-context model (e.g. opus)
|
|
2023
2575
|
// to a larger-context model (e.g. codex) - the overflow error from the old model
|
|
2024
|
-
// shouldn't trigger compaction for the new model.
|
|
2025
|
-
|
|
2576
|
+
// shouldn't trigger compaction for the new model. Under a virtual selection, the
|
|
2577
|
+
// physical model that produced the message supplies the limits.
|
|
2578
|
+
const messageModel = this._modelForMessage(assistantMessage);
|
|
2579
|
+
const sameModel = messageModel !== undefined;
|
|
2580
|
+
const contextWindow = (messageModel ?? this.model)?.contextWindow ?? 0;
|
|
2026
2581
|
// Skip compaction checks if this assistant message is older than the latest
|
|
2027
2582
|
// compaction boundary. This prevents a stale pre-compaction usage/error
|
|
2028
2583
|
// from retriggering compaction on the first prompt after compaction.
|
|
@@ -2034,54 +2589,89 @@ export class AgentSession {
|
|
|
2034
2589
|
// Automatic cases 1 and 2: context overflow.
|
|
2035
2590
|
// A length stop is recoverable when output ended below the model's original desired limit,
|
|
2036
2591
|
// independent of the configured context size or any context-clamped provider request limit.
|
|
2037
|
-
const
|
|
2038
|
-
const
|
|
2592
|
+
const currentProjection = this.sessionManager.buildSessionProjection();
|
|
2593
|
+
const assistantEntryId = this._findPersistedMessageEntryId(assistantMessage);
|
|
2594
|
+
const assistantIsProjected = assistantEntryId === undefined ||
|
|
2595
|
+
currentProjection.entries.some((entry) => entry.sourceEntry.id === assistantEntryId &&
|
|
2596
|
+
entry.messages.some((message) => message.role === "assistant"));
|
|
2597
|
+
const branch = this.sessionManager.getBranch();
|
|
2598
|
+
const assistantIndex = assistantEntryId ? branch.findIndex((entry) => entry.id === assistantEntryId) : -1;
|
|
2599
|
+
const entriesAfterAssistant = assistantIndex >= 0 ? branch.slice(assistantIndex + 1) : [];
|
|
2600
|
+
const hasPostAssistantContextEdit = entriesAfterAssistant.some((entry) => entry.type === "context_edit");
|
|
2601
|
+
const latestAssistantEdit = entriesAfterAssistant
|
|
2602
|
+
.filter((entry) => entry.type === "context_edit" && entry.targetId === assistantEntryId)
|
|
2603
|
+
.at(-1);
|
|
2604
|
+
const assistantRetainedForExplicitRecovery = assistantEntryId === undefined ||
|
|
2605
|
+
(!entriesAfterAssistant.some((entry) => entry.type === "compaction") &&
|
|
2606
|
+
latestAssistantEdit?.replacement !== null);
|
|
2607
|
+
const assistantUsageMatchesProjection = assistantIsProjected && !hasPostAssistantContextEdit;
|
|
2608
|
+
const explicitOverflow = assistantMessage.stopReason === "error" && isContextOverflow(assistantMessage);
|
|
2609
|
+
const contextOverflow = sameModel &&
|
|
2610
|
+
((explicitOverflow && assistantRetainedForExplicitRecovery) ||
|
|
2611
|
+
(assistantUsageMatchesProjection && isContextOverflow(assistantMessage, contextWindow)));
|
|
2612
|
+
const recoverableLength = sameModel && assistantIsProjected && isRecoverableLength(assistantMessage, messageModel.maxTokens);
|
|
2039
2613
|
if (contextOverflow || recoverableLength) {
|
|
2040
2614
|
const willRetry = assistantMessage.stopReason !== "stop";
|
|
2615
|
+
// Case 2: the response completed successfully. Compact, but do not retry because
|
|
2616
|
+
// agent.continue() cannot continue from a completed assistant response.
|
|
2041
2617
|
if (!willRetry) {
|
|
2042
2618
|
return await this._runAutoCompaction("overflow", false);
|
|
2043
2619
|
}
|
|
2044
2620
|
if (this._overflowRecoveryAttempted) {
|
|
2621
|
+
const errorMessage = contextOverflow
|
|
2622
|
+
? "Context overflow recovery failed after one compact-and-retry attempt. Try reducing context or switching to a larger-context model."
|
|
2623
|
+
: "Truncated response recovery failed after one compact-and-retry attempt.";
|
|
2045
2624
|
this._emit({
|
|
2046
2625
|
type: "compaction_end",
|
|
2047
2626
|
reason: "overflow",
|
|
2048
2627
|
result: undefined,
|
|
2049
2628
|
aborted: false,
|
|
2050
2629
|
willRetry: false,
|
|
2051
|
-
errorMessage
|
|
2052
|
-
|
|
2053
|
-
|
|
2630
|
+
errorMessage,
|
|
2631
|
+
});
|
|
2632
|
+
await this._emitSessionCompactFailed({
|
|
2633
|
+
reason: "overflow",
|
|
2634
|
+
errorMessage,
|
|
2635
|
+
aborted: false,
|
|
2636
|
+
willRetry: false,
|
|
2637
|
+
fromExtension: false,
|
|
2054
2638
|
});
|
|
2055
2639
|
return false;
|
|
2056
2640
|
}
|
|
2641
|
+
// Persistently omit the selected final attempt before post-run recovery compaction.
|
|
2057
2642
|
this._overflowRecoveryAttempted = true;
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
}
|
|
2064
|
-
return await this._runAutoCompaction("overflow", willRetry);
|
|
2643
|
+
this._omitRecoveryAttempt(assistantMessage, toolResults);
|
|
2644
|
+
const retry = await this._runAutoCompaction("overflow", willRetry);
|
|
2645
|
+
if (retry)
|
|
2646
|
+
this._failedResponse = assistantMessage;
|
|
2647
|
+
return retry;
|
|
2065
2648
|
}
|
|
2066
|
-
// Case
|
|
2649
|
+
// Case 3: threshold compaction without retry.
|
|
2067
2650
|
// For error messages or all-zero usage messages, estimate from the last valid response.
|
|
2068
2651
|
// This ensures sessions that hit persistent API errors (e.g. 529) or malformed zero-usage
|
|
2069
2652
|
// responses can still compact and do not reset context accounting.
|
|
2070
2653
|
let contextTokens;
|
|
2654
|
+
const projection = currentProjection;
|
|
2655
|
+
const hasContextEdits = projection.entries.some((entry) => entry.sourceEntry.type === "context_edit");
|
|
2071
2656
|
const directContextTokens = assistantMessage.usage ? calculateContextTokens(assistantMessage.usage) : 0;
|
|
2072
|
-
if (
|
|
2657
|
+
if (hasContextEdits) {
|
|
2658
|
+
contextTokens = estimateProjectedContextTokens(projection, branch).tokens;
|
|
2659
|
+
}
|
|
2660
|
+
else if (assistantMessage.stopReason === "error" || directContextTokens === 0) {
|
|
2073
2661
|
const messages = this.agent.state.messages;
|
|
2074
2662
|
const estimate = estimateContextTokens(messages);
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2663
|
+
// Without provider usage, estimate.tokens is the pure message-size estimate.
|
|
2664
|
+
// Only usage-backed estimates need the stale pre-compaction check.
|
|
2665
|
+
if (estimate.lastUsageIndex !== null) {
|
|
2666
|
+
// Verify the usage source is post-compaction. Kept pre-compaction messages
|
|
2667
|
+
// have stale usage reflecting the old (larger) context and would falsely
|
|
2668
|
+
// trigger compaction right after one just finished.
|
|
2669
|
+
const usageMsg = messages[estimate.lastUsageIndex];
|
|
2670
|
+
if (compactionEntry &&
|
|
2671
|
+
usageMsg.role === "assistant" &&
|
|
2672
|
+
usageMsg.timestamp <= new Date(compactionEntry.timestamp).getTime()) {
|
|
2673
|
+
return false;
|
|
2674
|
+
}
|
|
2085
2675
|
}
|
|
2086
2676
|
contextTokens = estimate.tokens;
|
|
2087
2677
|
}
|
|
@@ -2094,7 +2684,14 @@ export class AgentSession {
|
|
|
2094
2684
|
return false;
|
|
2095
2685
|
}
|
|
2096
2686
|
/**
|
|
2097
|
-
*
|
|
2687
|
+
* Execute threshold or overflow compaction. Manual compaction uses
|
|
2688
|
+
* `AgentSession.compact()` instead. Both paths call the lower-level `compact()`
|
|
2689
|
+
* function imported from `./compaction/index.ts` after preparation and extension
|
|
2690
|
+
* interception.
|
|
2691
|
+
*
|
|
2692
|
+
* @param reason Automatic trigger selected by `_checkCompaction()`
|
|
2693
|
+
* @param willRetry Whether to continue the interrupted turn after overflow compaction
|
|
2694
|
+
* @returns Whether the post-run loop should call `agent.continue()`
|
|
2098
2695
|
*/
|
|
2099
2696
|
async _runAutoCompaction(reason, willRetry) {
|
|
2100
2697
|
const model = this.model;
|
|
@@ -2117,8 +2714,6 @@ export class AgentSession {
|
|
|
2117
2714
|
started = true;
|
|
2118
2715
|
this._emit({ type: "compaction_start", reason });
|
|
2119
2716
|
abortController.signal.throwIfAborted();
|
|
2120
|
-
const { model: requestModel, apiKey, headers, env, } = await this._getSummarizationRequestAuth(model, abortController.signal);
|
|
2121
|
-
abortController.signal.throwIfAborted();
|
|
2122
2717
|
let extensionCompaction;
|
|
2123
2718
|
if (this._extensionRunner.hasHandlers("session_before_compact")) {
|
|
2124
2719
|
const extensionResult = (await this._extensionRunner.emit({
|
|
@@ -2155,7 +2750,7 @@ export class AgentSession {
|
|
|
2155
2750
|
}
|
|
2156
2751
|
else {
|
|
2157
2752
|
// Shared default summary generator, also used by manual compaction.
|
|
2158
|
-
const compactResult = await this._runDefaultCompaction(preparation,
|
|
2753
|
+
const compactResult = await this._runDefaultCompaction(preparation, model, undefined, abortController.signal, reason);
|
|
2159
2754
|
summary = compactResult.summary;
|
|
2160
2755
|
firstKeptEntryId = compactResult.firstKeptEntryId;
|
|
2161
2756
|
tokensBefore = compactResult.tokensBefore;
|
|
@@ -2165,9 +2760,8 @@ export class AgentSession {
|
|
|
2165
2760
|
abortController.signal.throwIfAborted();
|
|
2166
2761
|
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension, usage);
|
|
2167
2762
|
const newEntries = this.sessionManager.getEntries();
|
|
2168
|
-
|
|
2169
|
-
this.
|
|
2170
|
-
const estimatedTokensAfter = estimateMessagesTokens(sessionContext.messages);
|
|
2763
|
+
this._refreshFinalizedContext();
|
|
2764
|
+
const estimatedTokensAfter = estimateMessagesTokens(this.sessionManager.buildSessionProjection().messages);
|
|
2171
2765
|
// Get the saved compaction entry for the extension event
|
|
2172
2766
|
const savedCompactionEntry = newEntries.find((e) => e.type === "compaction" && e.summary === summary);
|
|
2173
2767
|
if (this._extensionRunner && savedCompactionEntry) {
|
|
@@ -2188,18 +2782,8 @@ export class AgentSession {
|
|
|
2188
2782
|
details,
|
|
2189
2783
|
};
|
|
2190
2784
|
this._emit({ type: "compaction_end", reason, result, aborted: false, willRetry });
|
|
2191
|
-
if (willRetry)
|
|
2192
|
-
const messages = this.agent.state.messages;
|
|
2193
|
-
const lastMsg = messages[messages.length - 1];
|
|
2194
|
-
// The overflow response was persisted on message_end before _checkCompaction() removed it
|
|
2195
|
-
// from agent state. Rebuilding state from the new compaction can restore that kept entry,
|
|
2196
|
-
// leaving an assistant as the final message. agent.continue() rejects that state, so remove
|
|
2197
|
-
// the retriable error or truncated-length response again before continuing the interrupted turn.
|
|
2198
|
-
if (lastMsg?.role === "assistant" && (lastMsg.stopReason === "error" || lastMsg.stopReason === "length")) {
|
|
2199
|
-
this.agent.state.messages = messages.slice(0, -1);
|
|
2200
|
-
}
|
|
2785
|
+
if (willRetry)
|
|
2201
2786
|
return true;
|
|
2202
|
-
}
|
|
2203
2787
|
// Auto-compaction can complete while follow-up/steering/custom messages are waiting.
|
|
2204
2788
|
// Continue once so queued messages are delivered.
|
|
2205
2789
|
return this.agent.hasQueuedMessages();
|
|
@@ -2248,12 +2832,6 @@ export class AgentSession {
|
|
|
2248
2832
|
get autoCompactionEnabled() {
|
|
2249
2833
|
return this.settingsManager.getCompactionEnabled();
|
|
2250
2834
|
}
|
|
2251
|
-
get autoHandoffEnabled() {
|
|
2252
|
-
return this.settingsManager.getAutoHandoffEnabled();
|
|
2253
|
-
}
|
|
2254
|
-
get autoHandoffThresholdTokens() {
|
|
2255
|
-
return this.settingsManager.getAutoHandoffThresholdTokens();
|
|
2256
|
-
}
|
|
2257
2835
|
async bindExtensions(bindings) {
|
|
2258
2836
|
if (bindings.uiContext !== undefined) {
|
|
2259
2837
|
this._extensionUIContext = bindings.uiContext;
|
|
@@ -2275,6 +2853,7 @@ export class AgentSession {
|
|
|
2275
2853
|
}
|
|
2276
2854
|
this._applyExtensionBindings(this._extensionRunner);
|
|
2277
2855
|
await this._extensionRunner.emit(this._sessionStartEvent);
|
|
2856
|
+
this._extensionRunner.reportUnhandledMcpServers();
|
|
2278
2857
|
await this.extendResourcesFromExtensions(this._sessionStartEvent.reason === "reload" ? "reload" : "startup");
|
|
2279
2858
|
}
|
|
2280
2859
|
async extendResourcesFromExtensions(reason) {
|
|
@@ -2296,7 +2875,7 @@ export class AgentSession {
|
|
|
2296
2875
|
buildExtensionResourcePaths(entries) {
|
|
2297
2876
|
return entries.map((entry) => {
|
|
2298
2877
|
const source = this.getExtensionSourceLabel(entry.extensionPath);
|
|
2299
|
-
const baseDir = entry.extensionPath
|
|
2878
|
+
const baseDir = isSyntheticPath(entry.extensionPath) ? undefined : dirname(entry.extensionPath);
|
|
2300
2879
|
return {
|
|
2301
2880
|
path: entry.path,
|
|
2302
2881
|
metadata: {
|
|
@@ -2309,7 +2888,7 @@ export class AgentSession {
|
|
|
2309
2888
|
});
|
|
2310
2889
|
}
|
|
2311
2890
|
getExtensionSourceLabel(extensionPath) {
|
|
2312
|
-
if (extensionPath
|
|
2891
|
+
if (isSyntheticPath(extensionPath)) {
|
|
2313
2892
|
return `extension:${extensionPath.replace(/[<>]/g, "")}`;
|
|
2314
2893
|
}
|
|
2315
2894
|
const base = basename(extensionPath);
|
|
@@ -2394,6 +2973,7 @@ export class AgentSession {
|
|
|
2394
2973
|
},
|
|
2395
2974
|
getActiveTools: () => this.getActiveToolNames(),
|
|
2396
2975
|
getAllTools: () => this.getAllTools(),
|
|
2976
|
+
getSettings: () => this.settingsManager.getSettings(),
|
|
2397
2977
|
setActiveTools: (toolNames) => this.setActiveToolsByName(toolNames),
|
|
2398
2978
|
getResolvedSkills: () => this._resourceLoader.getResolvedSkills().map((resource) => {
|
|
2399
2979
|
const skill = this._resourceLoader.getSkills().skills.find((s) => s.filePath === resource.path);
|
|
@@ -2452,6 +3032,8 @@ export class AgentSession {
|
|
|
2452
3032
|
},
|
|
2453
3033
|
getSystemPrompt: () => this.systemPrompt,
|
|
2454
3034
|
getSystemPromptOptions: () => this._baseSystemPromptOptions,
|
|
3035
|
+
executeTool: (callerId, name, args, options) => this._executeNestedToolCall(callerId, name, args, options),
|
|
3036
|
+
getCallableTools: () => this._getCallableTools(),
|
|
2455
3037
|
}, {
|
|
2456
3038
|
registerProvider: (name, config) => {
|
|
2457
3039
|
this._modelRuntime.registerProvider(name, config);
|
|
@@ -2465,14 +3047,22 @@ export class AgentSession {
|
|
|
2465
3047
|
this._modelRuntime.unregisterProvider(name);
|
|
2466
3048
|
this._refreshCurrentModelFromRegistry();
|
|
2467
3049
|
},
|
|
3050
|
+
registerVirtualModel: (definition) => {
|
|
3051
|
+
this._modelRuntime.registerVirtualModel(definition);
|
|
3052
|
+
this._refreshCurrentModelFromRegistry();
|
|
3053
|
+
},
|
|
3054
|
+
unregisterVirtualModel: (provider, id) => {
|
|
3055
|
+
this._modelRuntime.unregisterVirtualModel(provider, id);
|
|
3056
|
+
this._refreshCurrentModelFromRegistry();
|
|
3057
|
+
},
|
|
2468
3058
|
});
|
|
2469
3059
|
}
|
|
2470
3060
|
_refreshToolRegistry(options) {
|
|
2471
|
-
|
|
3061
|
+
// Tools that were already activated on registration. A tool whose exposure changes to
|
|
3062
|
+
// `direct` or `model-only` (for example from `hidden`) is activated like a new tool.
|
|
3063
|
+
const previousActivatedOnRegistration = new Set([...this._toolRegistry.keys()].filter((name) => this._isActivatedOnRegistration(name)));
|
|
2472
3064
|
const previousActiveToolNames = this.getActiveToolNames();
|
|
2473
|
-
const
|
|
2474
|
-
const excludedToolNames = this._excludedToolNames;
|
|
2475
|
-
const isAllowedTool = (name) => (!allowedToolNames || allowedToolNames.has(name)) && !excludedToolNames?.has(name);
|
|
3065
|
+
const allowedTools = this._allowedTools;
|
|
2476
3066
|
const registeredTools = this._extensionRunner.getAllRegisteredTools();
|
|
2477
3067
|
const allCustomTools = [
|
|
2478
3068
|
...registeredTools,
|
|
@@ -2480,14 +3070,14 @@ export class AgentSession {
|
|
|
2480
3070
|
definition,
|
|
2481
3071
|
sourceInfo: createSyntheticSourceInfo(`<sdk:${definition.name}>`, { source: "sdk" }),
|
|
2482
3072
|
})),
|
|
2483
|
-
].filter((tool) =>
|
|
3073
|
+
].filter((tool) => this._isAllowedTool(tool.definition.name));
|
|
2484
3074
|
const definitionRegistry = new Map(Array.from(this._baseToolDefinitions.entries())
|
|
2485
|
-
.filter(([name]) =>
|
|
3075
|
+
.filter(([name]) => this._isAllowedTool(name))
|
|
2486
3076
|
.map(([name, definition]) => [
|
|
2487
3077
|
name,
|
|
2488
3078
|
{
|
|
2489
3079
|
definition,
|
|
2490
|
-
sourceInfo: createSyntheticSourceInfo(
|
|
3080
|
+
sourceInfo: createSyntheticSourceInfo(`${BUILTIN_PATH_PREFIX}${name}`, { source: "builtin" }),
|
|
2491
3081
|
},
|
|
2492
3082
|
]));
|
|
2493
3083
|
for (const tool of allCustomTools) {
|
|
@@ -2512,37 +3102,53 @@ export class AgentSession {
|
|
|
2512
3102
|
const runner = this._extensionRunner;
|
|
2513
3103
|
const wrappedExtensionTools = wrapRegisteredTools(allCustomTools, runner);
|
|
2514
3104
|
const wrappedBuiltInTools = wrapRegisteredTools(Array.from(this._baseToolDefinitions.values())
|
|
2515
|
-
.filter((definition) =>
|
|
3105
|
+
.filter((definition) => this._isAllowedTool(definition.name))
|
|
2516
3106
|
.map((definition) => ({
|
|
2517
3107
|
definition,
|
|
2518
|
-
sourceInfo: createSyntheticSourceInfo(
|
|
3108
|
+
sourceInfo: createSyntheticSourceInfo(`${BUILTIN_PATH_PREFIX}${definition.name}`, {
|
|
3109
|
+
source: "builtin",
|
|
3110
|
+
}),
|
|
2519
3111
|
})), runner);
|
|
2520
3112
|
const toolRegistry = new Map(wrappedBuiltInTools.map((tool) => [tool.name, tool]));
|
|
2521
3113
|
for (const tool of wrappedExtensionTools) {
|
|
2522
3114
|
toolRegistry.set(tool.name, tool);
|
|
2523
3115
|
}
|
|
2524
3116
|
this._toolRegistry = toolRegistry;
|
|
2525
|
-
const nextActiveToolNames = (options?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames]).filter((name) =>
|
|
2526
|
-
if (
|
|
3117
|
+
const nextActiveToolNames = (options?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames]).filter((name) => this._isAllowedTool(name));
|
|
3118
|
+
if (allowedTools) {
|
|
2527
3119
|
for (const toolName of this._toolRegistry.keys()) {
|
|
2528
|
-
|
|
3120
|
+
// Naming or matching a tool activates it even when it is not active by default. MCP tools
|
|
3121
|
+
// kept registered without being named stay inactive.
|
|
3122
|
+
if (allowedTools(toolName) && this._isDeclarable(toolName)) {
|
|
2529
3123
|
nextActiveToolNames.push(toolName);
|
|
2530
3124
|
}
|
|
2531
3125
|
}
|
|
2532
3126
|
}
|
|
2533
3127
|
else if (options?.includeAllExtensionTools) {
|
|
2534
3128
|
for (const tool of wrappedExtensionTools) {
|
|
2535
|
-
|
|
3129
|
+
if (this._isActivatedOnRegistration(tool.name))
|
|
3130
|
+
nextActiveToolNames.push(tool.name);
|
|
2536
3131
|
}
|
|
2537
3132
|
}
|
|
2538
3133
|
else if (!options?.activeToolNames) {
|
|
2539
3134
|
for (const toolName of this._toolRegistry.keys()) {
|
|
2540
|
-
if (!
|
|
3135
|
+
if (!previousActivatedOnRegistration.has(toolName) && this._isActivatedOnRegistration(toolName)) {
|
|
2541
3136
|
nextActiveToolNames.push(toolName);
|
|
2542
3137
|
}
|
|
2543
3138
|
}
|
|
2544
3139
|
}
|
|
2545
|
-
|
|
3140
|
+
// Pending tools that are registered now become active.
|
|
3141
|
+
nextActiveToolNames.push(...this._pendingToolNames);
|
|
3142
|
+
this._setActiveTools([...new Set(nextActiveToolNames)]);
|
|
3143
|
+
}
|
|
3144
|
+
/** Whether activating the tool declares it to the model. */
|
|
3145
|
+
_isDeclarable(name) {
|
|
3146
|
+
const exposure = this._getToolExposure(name);
|
|
3147
|
+
return exposure === "direct" || exposure === "model-only";
|
|
3148
|
+
}
|
|
3149
|
+
/** Whether registering the tool activates it, which declares it to the model. */
|
|
3150
|
+
_isActivatedOnRegistration(name) {
|
|
3151
|
+
return this._isDeclarable(name) && this._toolDefinitions.get(name)?.definition.defaultActive !== false;
|
|
2546
3152
|
}
|
|
2547
3153
|
_buildRuntime(options) {
|
|
2548
3154
|
const autoResizeImages = this.settingsManager.getImageAutoResize();
|
|
@@ -2581,15 +3187,28 @@ export class AgentSession {
|
|
|
2581
3187
|
});
|
|
2582
3188
|
}
|
|
2583
3189
|
async reload(options) {
|
|
2584
|
-
const
|
|
2585
|
-
|
|
3190
|
+
const oldRunner = this._extensionRunner;
|
|
3191
|
+
const previousFlagValues = oldRunner.getFlagValues();
|
|
3192
|
+
await emitSessionShutdownEvent(oldRunner, { type: "session_shutdown", reason: "reload" });
|
|
3193
|
+
oldRunner.invalidate();
|
|
3194
|
+
const getDefaultTools = () => this._usesDefaultTools
|
|
3195
|
+
? applyToolModifiers(this.settingsManager.getDefaultTools() ?? DEFAULT_TOOL_NAMES, this._defaultToolModifiers)
|
|
3196
|
+
: [];
|
|
3197
|
+
const previousDefaultTools = new Set(getDefaultTools());
|
|
2586
3198
|
await this.settingsManager.reload();
|
|
2587
3199
|
this.syncQueueModesFromSettings();
|
|
2588
3200
|
resetApiProviders();
|
|
2589
3201
|
await this._resourceLoader.reload();
|
|
3202
|
+
// Activate tools newly added to defaultTools. Removed ones stay active, and tools disabled
|
|
3203
|
+
// during the session stay disabled unless the setting newly adds them.
|
|
3204
|
+
const addedDefaultTools = getDefaultTools().filter((name) => !previousDefaultTools.has(name));
|
|
3205
|
+
// Tools the new extensions register later, such as MCP tools, are pending until then.
|
|
3206
|
+
for (const name of this.getActiveToolNames())
|
|
3207
|
+
this._pendingToolNames.add(name);
|
|
2590
3208
|
this._buildRuntime({
|
|
2591
|
-
activeToolNames: this.getActiveToolNames(),
|
|
3209
|
+
activeToolNames: [...this.getActiveToolNames(), ...addedDefaultTools],
|
|
2592
3210
|
flagValues: previousFlagValues,
|
|
3211
|
+
includeAllExtensionTools: true,
|
|
2593
3212
|
});
|
|
2594
3213
|
const hasBindings = this._extensionUIContext ||
|
|
2595
3214
|
this._extensionCommandContextActions ||
|
|
@@ -2598,6 +3217,7 @@ export class AgentSession {
|
|
|
2598
3217
|
if (hasBindings) {
|
|
2599
3218
|
await options?.beforeSessionStart?.();
|
|
2600
3219
|
await this._extensionRunner.emit({ type: "session_start", reason: "reload" });
|
|
3220
|
+
this._extensionRunner.reportUnhandledMcpServers();
|
|
2601
3221
|
await this.extendResourcesFromExtensions("reload");
|
|
2602
3222
|
}
|
|
2603
3223
|
}
|
|
@@ -2610,7 +3230,7 @@ export class AgentSession {
|
|
|
2610
3230
|
*/
|
|
2611
3231
|
_isRetryableError(message) {
|
|
2612
3232
|
// Context overflow is handled by compaction, not retry.
|
|
2613
|
-
if (isContextOverflow(message, this.model?.contextWindow ?? 0))
|
|
3233
|
+
if (isContextOverflow(message, (this._modelForMessage(message) ?? this.model)?.contextWindow ?? 0))
|
|
2614
3234
|
return false;
|
|
2615
3235
|
return isRetryableAssistantError(message);
|
|
2616
3236
|
}
|
|
@@ -2677,11 +3297,8 @@ export class AgentSession {
|
|
|
2677
3297
|
delayMs,
|
|
2678
3298
|
errorMessage: message.errorMessage || "Unknown error",
|
|
2679
3299
|
});
|
|
2680
|
-
//
|
|
2681
|
-
|
|
2682
|
-
if (messages.length > 0 && messages[messages.length - 1].role === "assistant") {
|
|
2683
|
-
this.agent.state.messages = messages.slice(0, -1);
|
|
2684
|
-
}
|
|
3300
|
+
// Keep the failed attempt in raw history while durably omitting it from model projection.
|
|
3301
|
+
this._omitRecoveryAttempt(message);
|
|
2685
3302
|
// Wait with exponential backoff (abortable)
|
|
2686
3303
|
this._retryAbortController = new AbortController();
|
|
2687
3304
|
try {
|
|
@@ -2773,10 +3390,8 @@ export class AgentSession {
|
|
|
2773
3390
|
this._pendingBashMessages.push(bashMessage);
|
|
2774
3391
|
}
|
|
2775
3392
|
else {
|
|
2776
|
-
// Add to agent state immediately
|
|
2777
|
-
this.agent.state.messages.push(bashMessage);
|
|
2778
|
-
// Save to session
|
|
2779
3393
|
this.sessionManager.appendMessage(bashMessage);
|
|
3394
|
+
this._refreshFinalizedContext();
|
|
2780
3395
|
}
|
|
2781
3396
|
}
|
|
2782
3397
|
/**
|
|
@@ -2803,12 +3418,10 @@ export class AgentSession {
|
|
|
2803
3418
|
if (this._pendingBashMessages.length === 0)
|
|
2804
3419
|
return;
|
|
2805
3420
|
for (const bashMessage of this._pendingBashMessages) {
|
|
2806
|
-
// Add to agent state
|
|
2807
|
-
this.agent.state.messages.push(bashMessage);
|
|
2808
|
-
// Save to session
|
|
2809
3421
|
this.sessionManager.appendMessage(bashMessage);
|
|
2810
3422
|
}
|
|
2811
3423
|
this._pendingBashMessages = [];
|
|
3424
|
+
this._refreshFinalizedContext();
|
|
2812
3425
|
}
|
|
2813
3426
|
// =========================================================================
|
|
2814
3427
|
// Session Management
|
|
@@ -2818,9 +3431,9 @@ export class AgentSession {
|
|
|
2818
3431
|
*/
|
|
2819
3432
|
setSessionName(name) {
|
|
2820
3433
|
this.sessionManager.appendSessionInfo(name);
|
|
2821
|
-
const
|
|
2822
|
-
this._emit(
|
|
2823
|
-
void this._extensionRunner.emit(
|
|
3434
|
+
const event = { type: "session_info_changed", name: this.sessionManager.getSessionName() };
|
|
3435
|
+
this._emit(event);
|
|
3436
|
+
void this._extensionRunner.emit(event);
|
|
2824
3437
|
}
|
|
2825
3438
|
// =========================================================================
|
|
2826
3439
|
// Tree Navigation
|
|
@@ -2907,15 +3520,11 @@ export class AgentSession {
|
|
|
2907
3520
|
let summaryDetails;
|
|
2908
3521
|
let summaryUsage;
|
|
2909
3522
|
if (options.summarize && entriesToSummarize.length > 0 && !extensionSummary) {
|
|
2910
|
-
const
|
|
2911
|
-
const { apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
|
|
3523
|
+
const signal = this._branchSummaryAbortController.signal;
|
|
2912
3524
|
const branchSummarySettings = this.settingsManager.getBranchSummarySettings();
|
|
2913
3525
|
const result = await generateBranchSummary(entriesToSummarize, {
|
|
2914
|
-
model,
|
|
2915
|
-
|
|
2916
|
-
headers,
|
|
2917
|
-
env,
|
|
2918
|
-
signal: this._branchSummaryAbortController.signal,
|
|
3526
|
+
...(await this._getSummarizationRequestAuth(this.model, signal)),
|
|
3527
|
+
signal,
|
|
2919
3528
|
customInstructions,
|
|
2920
3529
|
replaceInstructions,
|
|
2921
3530
|
reserveTokens: branchSummarySettings.reserveTokens,
|
|
@@ -2982,9 +3591,8 @@ export class AgentSession {
|
|
|
2982
3591
|
if (label && !summaryText) {
|
|
2983
3592
|
this.sessionManager.appendLabelChange(targetId, label);
|
|
2984
3593
|
}
|
|
2985
|
-
// Update
|
|
2986
|
-
|
|
2987
|
-
this.agent.state.messages = sessionContext.messages;
|
|
3594
|
+
// Update finalized context from the canonical session projection.
|
|
3595
|
+
this._refreshFinalizedContext();
|
|
2988
3596
|
this._restoreToolsFromTranscript();
|
|
2989
3597
|
// Emit session_tree event (extension runners + RPC stdout subscribers)
|
|
2990
3598
|
const treeEvent = {
|
|
@@ -3083,7 +3691,7 @@ export class AgentSession {
|
|
|
3083
3691
|
};
|
|
3084
3692
|
}
|
|
3085
3693
|
getContextUsage() {
|
|
3086
|
-
const model = this.
|
|
3694
|
+
const model = this._limitsModel();
|
|
3087
3695
|
if (!model)
|
|
3088
3696
|
return undefined;
|
|
3089
3697
|
const contextWindow = model.contextWindow ?? 0;
|
|
@@ -3092,30 +3700,24 @@ export class AgentSession {
|
|
|
3092
3700
|
// After compaction, the last assistant usage reflects pre-compaction context size.
|
|
3093
3701
|
// We can only trust usage from an assistant that responded after the latest compaction.
|
|
3094
3702
|
// If no such assistant exists, context token count is unknown until the next LLM response.
|
|
3095
|
-
const
|
|
3096
|
-
const
|
|
3703
|
+
const projection = this.sessionManager.buildSessionProjection();
|
|
3704
|
+
const branch = this.sessionManager.getBranch();
|
|
3705
|
+
const latestCompaction = getLatestCompactionEntry(branch);
|
|
3097
3706
|
if (latestCompaction) {
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
break;
|
|
3110
|
-
}
|
|
3111
|
-
}
|
|
3112
|
-
}
|
|
3113
|
-
}
|
|
3114
|
-
if (!hasPostCompactionUsage) {
|
|
3707
|
+
const projectedAssistants = new Set(projection.entries.flatMap((entry) => entry.messages.some((message) => message.role === "assistant" &&
|
|
3708
|
+
message.stopReason !== "aborted" &&
|
|
3709
|
+
message.stopReason !== "error" &&
|
|
3710
|
+
calculateContextTokens(message.usage) > 0)
|
|
3711
|
+
? [entry.sourceEntry.id]
|
|
3712
|
+
: []));
|
|
3713
|
+
const compactionIndex = branch.findIndex((entry) => entry.id === latestCompaction.id);
|
|
3714
|
+
const hasPostCompactionUsage = branch
|
|
3715
|
+
.slice(compactionIndex + 1)
|
|
3716
|
+
.some((entry) => projectedAssistants.has(entry.id));
|
|
3717
|
+
if (!hasPostCompactionUsage)
|
|
3115
3718
|
return { tokens: null, contextWindow, percent: null };
|
|
3116
|
-
}
|
|
3117
3719
|
}
|
|
3118
|
-
const estimate =
|
|
3720
|
+
const estimate = estimateProjectedContextTokens(projection, branch);
|
|
3119
3721
|
const percent = (estimate.tokens / contextWindow) * 100;
|
|
3120
3722
|
return {
|
|
3121
3723
|
tokens: estimate.tokens,
|
|
@@ -3126,13 +3728,14 @@ export class AgentSession {
|
|
|
3126
3728
|
/**
|
|
3127
3729
|
* Export session to HTML.
|
|
3128
3730
|
* @param outputPath Optional output path (defaults to session directory)
|
|
3731
|
+
* @param options Optional export presentation settings
|
|
3129
3732
|
* @returns Path to exported file
|
|
3130
3733
|
*/
|
|
3131
3734
|
async exportToHtml(outputPath, options = {}) {
|
|
3132
3735
|
const themeName = [options.themeName, this.settingsManager.getTheme()].find((candidate) => candidate !== undefined && getThemeByName(candidate) !== undefined);
|
|
3133
3736
|
// Create tool renderer if we have an extension runner (for custom tool HTML rendering)
|
|
3134
3737
|
const toolRenderer = createToolHtmlRenderer({
|
|
3135
|
-
|
|
3738
|
+
getToolRenderers: (name) => this._extensionRunner.resolveToolRenderers(name, () => this.getToolDefinition(name)),
|
|
3136
3739
|
theme,
|
|
3137
3740
|
cwd: this.sessionManager.getCwd(),
|
|
3138
3741
|
});
|
|
@@ -3149,29 +3752,7 @@ export class AgentSession {
|
|
|
3149
3752
|
* @returns The resolved output file path.
|
|
3150
3753
|
*/
|
|
3151
3754
|
exportToJsonl(outputPath) {
|
|
3152
|
-
|
|
3153
|
-
const dir = dirname(filePath);
|
|
3154
|
-
if (!existsSync(dir)) {
|
|
3155
|
-
mkdirSync(dir, { recursive: true });
|
|
3156
|
-
}
|
|
3157
|
-
const header = {
|
|
3158
|
-
type: "session",
|
|
3159
|
-
version: CURRENT_SESSION_VERSION,
|
|
3160
|
-
id: this.sessionManager.getSessionId(),
|
|
3161
|
-
timestamp: new Date().toISOString(),
|
|
3162
|
-
cwd: this.sessionManager.getCwd(),
|
|
3163
|
-
};
|
|
3164
|
-
const branchEntries = this.sessionManager.getBranch();
|
|
3165
|
-
const lines = [JSON.stringify(header)];
|
|
3166
|
-
// Re-chain parentIds to form a linear sequence
|
|
3167
|
-
let prevId = null;
|
|
3168
|
-
for (const entry of branchEntries) {
|
|
3169
|
-
const linear = { ...entry, parentId: prevId };
|
|
3170
|
-
lines.push(JSON.stringify(linear));
|
|
3171
|
-
prevId = entry.id;
|
|
3172
|
-
}
|
|
3173
|
-
writeFileSync(filePath, `${lines.join("\n")}\n`);
|
|
3174
|
-
return filePath;
|
|
3755
|
+
return exportSessionToJsonl(this.sessionManager, outputPath);
|
|
3175
3756
|
}
|
|
3176
3757
|
/**
|
|
3177
3758
|
* Ask the current model to describe what went wrong in this session for a bug report.
|
|
@@ -3182,16 +3763,11 @@ export class AgentSession {
|
|
|
3182
3763
|
if (!model) {
|
|
3183
3764
|
throw new Error("No model selected");
|
|
3184
3765
|
}
|
|
3185
|
-
const { model: requestModel, apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
|
|
3186
3766
|
return generateBugReportSummary({
|
|
3767
|
+
...(await this._getSummarizationRequestAuth(model, options.signal)),
|
|
3187
3768
|
messages: this.messages,
|
|
3188
3769
|
hint: options.hint,
|
|
3189
|
-
model: requestModel,
|
|
3190
|
-
apiKey,
|
|
3191
|
-
headers,
|
|
3192
|
-
env,
|
|
3193
3770
|
signal: options.signal,
|
|
3194
|
-
thinkingLevel: this.thinkingLevel,
|
|
3195
3771
|
streamFn: this.agent.streamFunction,
|
|
3196
3772
|
retry: this.settingsManager.getRetrySettings(),
|
|
3197
3773
|
sessionId: this.sessionId,
|