@selesai/code 0.5.28 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +9 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/credential-print.d.ts +23 -0
- package/dist/cli/credential-print.d.ts.map +1 -0
- package/dist/cli/credential-print.js +117 -0
- package/dist/cli/credential-print.js.map +1 -0
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +1 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +3 -0
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts +12 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +20 -14
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +11 -3
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +11 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +14 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +10 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/llama/provider.d.ts.map +1 -1
- package/dist/core/llama/provider.js +8 -3
- package/dist/core/llama/provider.js.map +1 -1
- package/dist/core/model-config.d.ts +30 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +6 -0
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +2 -2
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +20 -3
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +2 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +5 -4
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +13 -6
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +24 -11
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts +15 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +66 -9
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +19 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/system-prompt.test.d.ts +2 -0
- package/dist/core/system-prompt.test.d.ts.map +1 -0
- package/dist/core/system-prompt.test.js +89 -0
- package/dist/core/system-prompt.test.js.map +1 -0
- package/dist/core/tools/bash.d.ts +2 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +34 -5
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +3 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/defaults/models.json +13 -45
- package/dist/defaults/settings.json +1 -2
- package/dist/extensions/copy-turn.test.ts +131 -0
- package/dist/extensions/copy-turn.ts +6 -1
- package/dist/extensions/package.json +0 -1
- package/dist/extensions/pi-intercom/CHANGELOG.md +249 -0
- package/dist/extensions/pi-intercom/README.md +102 -39
- package/dist/extensions/pi-intercom/broker/broker.ts +1233 -36
- package/dist/extensions/pi-intercom/broker/client.test.ts +83 -0
- package/dist/extensions/pi-intercom/broker/client.ts +315 -12
- package/dist/extensions/pi-intercom/broker/extension-state.ts +186 -0
- package/dist/extensions/pi-intercom/broker/extension.test.ts +387 -0
- package/dist/extensions/pi-intercom/broker/framing.test.ts +114 -0
- package/dist/extensions/pi-intercom/broker/framing.ts +82 -24
- package/dist/extensions/pi-intercom/broker/paths.test.ts +153 -0
- package/dist/extensions/pi-intercom/broker/paths.ts +117 -8
- package/dist/extensions/pi-intercom/broker/runtime-claim.test.ts +34 -0
- package/dist/extensions/pi-intercom/broker/runtime-claim.ts +21 -0
- package/dist/extensions/pi-intercom/broker/spawn.test.ts +160 -23
- package/dist/extensions/pi-intercom/broker/spawn.ts +113 -27
- package/dist/extensions/pi-intercom/config.test.ts +93 -0
- package/dist/extensions/pi-intercom/config.ts +55 -6
- package/dist/extensions/pi-intercom/cwd.test.ts +40 -0
- package/dist/extensions/pi-intercom/cwd.ts +31 -0
- package/dist/extensions/pi-intercom/extension-api.ts +44 -0
- package/dist/extensions/pi-intercom/format-context.test.ts +31 -0
- package/dist/extensions/pi-intercom/format-context.ts +32 -0
- package/dist/extensions/pi-intercom/index.ts +742 -145
- package/dist/extensions/pi-intercom/intercom.integration.test.ts +2646 -0
- package/dist/extensions/pi-intercom/package.json +15 -5
- package/dist/extensions/pi-intercom/reply-tracker.test.ts +134 -0
- package/dist/extensions/pi-intercom/reply-tracker.ts +31 -13
- package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +13 -11
- package/dist/extensions/pi-intercom/test/inline-message.test.ts +184 -0
- package/dist/extensions/pi-intercom/test/overlay-width.test.ts +66 -0
- package/dist/extensions/pi-intercom/types.ts +94 -4
- package/dist/extensions/pi-intercom/ui/compose.ts +8 -4
- package/dist/extensions/pi-intercom/ui/inline-message.ts +61 -25
- package/dist/extensions/pi-intercom/ui/session-list.ts +7 -3
- package/dist/extensions/pi-subagents/CHANGELOG.md +88 -0
- package/dist/extensions/pi-subagents/LICENSE +21 -0
- package/dist/extensions/pi-subagents/README.md +158 -69
- package/dist/extensions/pi-subagents/agents/architect.md +5 -4
- package/dist/extensions/pi-subagents/agents/builder.md +6 -4
- package/dist/extensions/pi-subagents/agents/commentator.md +3 -2
- package/dist/extensions/pi-subagents/agents/explorer.md +3 -2
- package/dist/extensions/pi-subagents/agents/recapper.md +3 -2
- package/dist/extensions/pi-subagents/agents/researcher.md +4 -3
- package/dist/extensions/pi-subagents/package-lock.json +2 -2
- package/dist/extensions/pi-subagents/package.json +3 -3
- package/dist/extensions/pi-subagents/prompts/review-loop.md +1 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +22 -988
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +257 -0
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +431 -0
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +144 -0
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +281 -0
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +125 -37
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +4 -0
- package/dist/extensions/pi-subagents/src/agents/agents.ts +118 -9
- package/dist/extensions/pi-subagents/src/agents/skills.ts +14 -12
- package/dist/extensions/pi-subagents/src/agents/task-aware-routing.ts +125 -0
- package/dist/extensions/pi-subagents/src/api/delegation.ts +3 -0
- package/dist/extensions/pi-subagents/src/api/preflight.ts +17 -13
- package/dist/extensions/pi-subagents/src/extension/chain-validation.ts +17 -1
- package/dist/extensions/pi-subagents/src/extension/index.ts +22 -8
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +248 -6
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +33 -8
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +32 -14
- package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +9 -4
- package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +33 -4
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +86 -21
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +24 -13
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +7 -5
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -2
- package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +48 -5
- package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +68 -1
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +56 -5
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +92 -11
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +29 -3
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +388 -29
- package/dist/extensions/pi-subagents/src/runs/foreground/async-stop-action.ts +65 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +3 -3
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +214 -60
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +546 -252
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +42 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +553 -154
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +19 -13
- package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +51 -19
- package/dist/extensions/pi-subagents/src/runs/shared/chain-outputs.ts +3 -1
- package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +44 -11
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +8 -0
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +97 -20
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +43 -12
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +52 -4
- package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +19 -0
- package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +45 -9
- package/dist/extensions/pi-subagents/src/runs/shared/runtime-acknowledged-extensions.ts +71 -0
- package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +63 -9
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +31 -1
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +101 -0
- package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +22 -1
- package/dist/extensions/pi-subagents/src/runs/shared/usage-budget.ts +65 -0
- package/dist/extensions/pi-subagents/src/runs/shared/workflow-graph.ts +26 -1
- package/dist/extensions/pi-subagents/src/shared/settings.ts +17 -1
- package/dist/extensions/pi-subagents/src/shared/types.ts +196 -12
- package/dist/extensions/pi-subagents/src/shared/utils.ts +102 -5
- package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +10 -1
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +46 -4
- package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +5 -3
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +87 -24
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +182 -9
- package/dist/extensions/pi-subagents/src/tui/render.ts +55 -34
- package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +14 -7
- package/dist/extensions/pi-subagents/src/watchdog/review.ts +5 -4
- package/dist/extensions/pi-subagents/src/watchdog/runtime.ts +170 -17
- package/dist/extensions/pi-subagents/src/watchdog/scope.ts +62 -0
- package/dist/extensions/pi-subagents/src/watchdog/settings.ts +41 -1
- package/dist/extensions/pi-subagents/src/watchdog/types.ts +10 -0
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +113 -8
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +419 -47
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +84 -0
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +4 -2
- package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +51 -2
- package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +62 -22
- package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +48 -0
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +8 -6
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +231 -19
- package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +48 -7
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +44 -0
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +199 -17
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +898 -16
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +112 -23
- package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +17 -5
- package/dist/extensions/pi-subagents/test/support/mock-pi.ts +2 -0
- package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +18 -2
- package/dist/extensions/pi-subagents/test/support/register-loader.mjs +3 -3
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +3 -1
- package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +198 -6
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +161 -1
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +47 -2
- package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +60 -0
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +8 -0
- package/dist/extensions/pi-subagents/test/unit/builtin-agent-documentation.test.ts +63 -0
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +136 -0
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +6 -0
- package/dist/extensions/pi-subagents/test/unit/chain-validation.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +48 -48
- package/dist/extensions/pi-subagents/test/unit/config-dir-runtime.test.ts +23 -0
- package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +28 -2
- package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +1 -0
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +176 -8
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +164 -5
- package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +41 -1
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +17 -12
- package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +18 -2
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +20 -1
- package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +30 -2
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +39 -2
- package/dist/extensions/pi-subagents/test/unit/parallel-utils.test.ts +22 -0
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +103 -0
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +18 -0
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +48 -0
- package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +13 -1
- package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +29 -4
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +223 -4
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +30 -0
- package/dist/extensions/pi-subagents/test/unit/runtime-acknowledged-extensions.test.ts +52 -0
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +46 -2
- package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +91 -1
- package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/streamed-progress-bounds.test.ts +78 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +41 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +77 -0
- package/dist/extensions/pi-subagents/test/unit/task-aware-routing.test.ts +213 -0
- package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +26 -1
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +61 -10
- package/dist/extensions/pi-subagents/test/unit/total-cost.test.ts +1 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +210 -1
- package/dist/extensions/pi-subagents/test/unit/watchdog-scope.test.ts +33 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +32 -0
- package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +43 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +3 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +10 -2
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts +1 -2
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +16 -46
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +4 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +22 -13
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts +12 -0
- package/dist/modes/interactive/external-editor.d.ts.map +1 -0
- package/dist/modes/interactive/external-editor.js +37 -0
- package/dist/modes/interactive/external-editor.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +72 -64
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +14 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/skills/ponytail/SKILL.md +1 -3
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +19 -8
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +1 -1
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +1 -1
- package/docs/custom-provider.md +14 -5
- package/docs/environment-variables.md +86 -0
- package/docs/extensions.md +15 -5
- package/docs/index.md +1 -0
- package/docs/models.md +9 -2
- package/docs/plans/subagent-delegation/phase-0-correctness.md +265 -0
- package/docs/plans/subagent-delegation/phase-1-behavioral-contract.md +486 -0
- package/docs/plans/subagent-delegation/phase-2-context-controls.md +282 -0
- package/docs/plans/subagent-delegation/phase-3-advisory-routing.md +362 -0
- package/docs/plans/subagent-delegation/phase-4-optional-enforcement.md +381 -0
- package/docs/providers.md +21 -2
- package/docs/rpc.md +23 -6
- package/docs/session-format.md +2 -0
- package/docs/settings.md +1 -1
- package/docs/usage.md +0 -13
- package/examples/extensions/custom-compaction.ts +5 -2
- package/examples/extensions/custom-provider-anthropic/index.ts +9 -3
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/handoff.ts +11 -3
- package/examples/extensions/message-renderer.ts +3 -3
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/summarize.ts +5 -2
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/sdk/12-full-control.ts +3 -1
- package/package.json +16 -7
- package/dist/extensions/caveman/caveman-instructions.cjs +0 -11
- package/dist/extensions/caveman/index.js +0 -118
- package/dist/extensions/caveman/package.json +0 -8
- package/dist/extensions/caveman/test/extension.test.js +0 -203
- package/dist/extensions/caveman/test/helpers.test.js +0 -58
- package/dist/skills/caveman/SKILL.md +0 -50
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
+
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
3
4
|
import { getMarkdownTheme, type ExtensionContext } from "@selesai/code";
|
|
4
5
|
import { Key, matchesKey, truncateToWidth, visibleWidth, wrapTextWithAnsi, type Component, type MarkdownTheme } from "@earendil-works/pi-tui";
|
|
5
6
|
import { getArtifactPaths, getArtifactsDir } from "../shared/artifacts.ts";
|
|
6
|
-
import { formatDuration, formatTokens, shortenPath } from "../shared/formatters.ts";
|
|
7
|
-
import { RESULTS_DIR, type AsyncJobState, type ForegroundChildControl, type ForegroundResumeChild, type ForegroundResumeRun, type ForegroundRunControl, type SubagentState } from "../shared/types.ts";
|
|
7
|
+
import { formatDuration, formatModelThinking, formatTokens, shortenPath } from "../shared/formatters.ts";
|
|
8
|
+
import { RESULTS_DIR, type AsyncJobState, type Details, type ForegroundChildControl, type ForegroundResumeChild, type ForegroundResumeRun, type ForegroundRunControl, type SubagentState } from "../shared/types.ts";
|
|
8
9
|
import { readStatus } from "../shared/utils.ts";
|
|
9
10
|
import { formatAsyncRunTranscript } from "../runs/background/fleet-view.ts";
|
|
10
11
|
import { listAsyncRuns, type AsyncRunSummary } from "../runs/background/async-status.ts";
|
|
12
|
+
import { steerAsyncRun } from "../runs/foreground/async-steering-action.ts";
|
|
13
|
+
import { stopAsyncRun } from "../runs/foreground/async-stop-action.ts";
|
|
11
14
|
import { contextModeBadge, contextModeLabel } from "../runs/shared/context-mode.ts";
|
|
12
15
|
import { FLEET_STATUS_WIDGET_KEY } from "./fleet-status.ts";
|
|
13
16
|
import { readFleetTranscript, renderFleetTranscript, type FleetTranscript } from "./fleet-transcript.ts";
|
|
@@ -34,12 +37,23 @@ export interface FleetSnapshot {
|
|
|
34
37
|
error?: string;
|
|
35
38
|
}
|
|
36
39
|
|
|
40
|
+
export interface FleetActionResult {
|
|
41
|
+
text: string;
|
|
42
|
+
isError?: boolean;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface FleetActionHandlers {
|
|
46
|
+
steer(input: { runId: string; asyncDir: string; index?: number; message: string }): Promise<FleetActionResult>;
|
|
47
|
+
stop(input: { runId: string; asyncDir: string; index?: number }): Promise<FleetActionResult> | FleetActionResult;
|
|
48
|
+
}
|
|
49
|
+
|
|
37
50
|
export interface FleetViewOptions {
|
|
38
51
|
asyncDirRoot?: string;
|
|
39
52
|
resultsDir?: string;
|
|
40
53
|
refreshMs?: number;
|
|
41
54
|
initialKey?: string;
|
|
42
55
|
markdownTheme?: MarkdownTheme;
|
|
56
|
+
actions?: FleetActionHandlers;
|
|
43
57
|
}
|
|
44
58
|
|
|
45
59
|
function belongsToCurrentSession(sessionId: string | undefined, currentSessionId: string | null): boolean {
|
|
@@ -209,12 +223,14 @@ function statusGlyph(item: FleetItem, theme: Theme): string {
|
|
|
209
223
|
function foregroundActiveDetail(item: Extract<FleetItem, { kind: "foreground-active" }>): string[] {
|
|
210
224
|
const { control } = item;
|
|
211
225
|
const live = item.activeChild ?? control;
|
|
226
|
+
const modelThinking = formatModelThinking(live.model, live.thinking);
|
|
212
227
|
const lines = [
|
|
213
228
|
`Run: ${item.runId}`,
|
|
214
229
|
"Source: foreground",
|
|
215
230
|
`State: running`,
|
|
216
231
|
`Mode: ${control.mode}`,
|
|
217
232
|
item.index !== undefined ? `Child: ${item.index} (${item.agent})` : `Agent: ${item.agent}`,
|
|
233
|
+
modelThinking ? `Model: ${modelThinking}` : undefined,
|
|
218
234
|
`Started: ${new Date(live.startedAt).toISOString()}`,
|
|
219
235
|
live.currentTool ? `Current tool: ${live.currentTool}${live.currentPath ? ` · ${shortenPath(live.currentPath)}` : ""}` : undefined,
|
|
220
236
|
live.turnCount !== undefined ? `Turns: ${live.turnCount}` : undefined,
|
|
@@ -230,12 +246,14 @@ function foregroundActiveDetail(item: Extract<FleetItem, { kind: "foreground-act
|
|
|
230
246
|
function foregroundRecentDetail(item: Extract<FleetItem, { kind: "foreground-recent" }>): string[] {
|
|
231
247
|
const { child, run } = item;
|
|
232
248
|
const outputPath = child.artifactPaths?.outputPath ?? child.savedOutputPath;
|
|
249
|
+
const modelThinking = formatModelThinking(child.model, child.thinking);
|
|
233
250
|
const lines = [
|
|
234
251
|
`Run: ${item.runId}`,
|
|
235
252
|
"Source: foreground",
|
|
236
253
|
`State: ${child.status}`,
|
|
237
254
|
`Mode: ${run.mode}`,
|
|
238
255
|
`Child: ${child.index} (${child.agent})${contextModeLabel(child.context) ? ` ${contextModeLabel(child.context)}` : ""}`,
|
|
256
|
+
modelThinking ? `Model: ${modelThinking}` : undefined,
|
|
239
257
|
`Updated: ${new Date(child.updatedAt ?? run.updatedAt).toISOString()}`,
|
|
240
258
|
outputPath ? `Output: ${outputPath}` : undefined,
|
|
241
259
|
child.sessionFile ? `Session: ${child.sessionFile}` : undefined,
|
|
@@ -282,6 +300,16 @@ function detailLines(item: FleetItem | undefined, error: string | undefined): st
|
|
|
282
300
|
return lines;
|
|
283
301
|
}
|
|
284
302
|
|
|
303
|
+
function isActionableAsyncState(state: string): boolean {
|
|
304
|
+
return state === "running" || state === "queued" || state === "pending";
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function firstToolResultText(result: AgentToolResult<Details> | null, fallback: string): FleetActionResult {
|
|
308
|
+
if (!result) return { text: fallback, isError: true };
|
|
309
|
+
const text = result.content.find((item) => item.type === "text")?.text ?? fallback;
|
|
310
|
+
return { text, ...(result.isError ? { isError: true } : {}) };
|
|
311
|
+
}
|
|
312
|
+
|
|
285
313
|
function uniquePaths(values: Array<string | undefined>): string[] {
|
|
286
314
|
return [...new Set(values.filter((value): value is string => Boolean(value)).map((value) => path.resolve(value)))];
|
|
287
315
|
}
|
|
@@ -353,10 +381,12 @@ function itemStats(item: FleetItem): string[] {
|
|
|
353
381
|
let durationMs: number | undefined;
|
|
354
382
|
if (item.kind === "foreground-active") {
|
|
355
383
|
const live = item.activeChild ?? item.control;
|
|
384
|
+
model = formatModelThinking(live.model, live.thinking) || undefined;
|
|
356
385
|
tokens = live.tokens;
|
|
357
386
|
tools = live.toolCount;
|
|
358
387
|
durationMs = Math.max(0, Date.now() - live.startedAt);
|
|
359
388
|
} else if (item.kind === "foreground-recent") {
|
|
389
|
+
model = formatModelThinking(item.child.model, item.child.thinking) || undefined;
|
|
360
390
|
tokens = item.child.tokens;
|
|
361
391
|
tools = item.child.toolCount;
|
|
362
392
|
} else {
|
|
@@ -436,6 +466,10 @@ export class SubagentFleetComponent implements Component {
|
|
|
436
466
|
private detailViewportHeight = 8;
|
|
437
467
|
private bodyHeight = 8;
|
|
438
468
|
private expandedTools = false;
|
|
469
|
+
private actionNotice: FleetActionResult | undefined;
|
|
470
|
+
private steerDraft: string | undefined;
|
|
471
|
+
private stopConfirming = false;
|
|
472
|
+
private actionBusy = false;
|
|
439
473
|
private transcriptCache: FleetTranscriptCache | undefined;
|
|
440
474
|
private disposed = false;
|
|
441
475
|
private readonly timer: ReturnType<typeof setInterval>;
|
|
@@ -463,7 +497,7 @@ export class SubagentFleetComponent implements Component {
|
|
|
463
497
|
this.refresh();
|
|
464
498
|
this.timer = setInterval(() => {
|
|
465
499
|
if (this.disposed) return;
|
|
466
|
-
this.
|
|
500
|
+
this.invalidate();
|
|
467
501
|
this.tui.requestRender();
|
|
468
502
|
}, options.refreshMs ?? REFRESH_MS);
|
|
469
503
|
this.timer.unref?.();
|
|
@@ -482,9 +516,67 @@ export class SubagentFleetComponent implements Component {
|
|
|
482
516
|
this.selected = Math.max(0, Math.min(this.snapshot.items.length - 1, this.selected + delta));
|
|
483
517
|
this.selectedKey = this.snapshot.items[this.selected]?.key;
|
|
484
518
|
this.detailAutoFollow = true;
|
|
519
|
+
this.resetActionInput();
|
|
520
|
+
this.tui.requestRender();
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
private resetActionInput(): void {
|
|
524
|
+
this.steerDraft = undefined;
|
|
525
|
+
this.stopConfirming = false;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
private selectedAsyncAction(): { item: Extract<FleetItem, { kind: "async" }> } | { reason: string } {
|
|
529
|
+
const item = this.snapshot.items[this.selected];
|
|
530
|
+
if (!item) return { reason: "No child is selected." };
|
|
531
|
+
if (item.kind !== "async") return { reason: "Fleet controls are available for current-session top-level async runs only." };
|
|
532
|
+
if (!isActionableAsyncState(item.run.state) || !isActionableAsyncState(item.state)) return { reason: `Selected child is ${item.state}; controls require a running or queued async child.` };
|
|
533
|
+
return { item };
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
private actionLines(): string[] {
|
|
537
|
+
const lines: string[] = [];
|
|
538
|
+
if (this.actionBusy) lines.push(this.theme.fg("accent", "Action pending..."));
|
|
539
|
+
if (this.steerDraft !== undefined) {
|
|
540
|
+
lines.push(this.theme.fg("accent", `Steer message: ${this.steerDraft}${this.theme.fg("dim", "▌")}`));
|
|
541
|
+
lines.push(this.theme.fg("dim", "Enter sends · Esc cancels · Backspace edits"));
|
|
542
|
+
} else if (this.stopConfirming) {
|
|
543
|
+
const selected = this.snapshot.items[this.selected];
|
|
544
|
+
lines.push(this.theme.fg("warning", `Confirm stop for async run ${selected?.runId ?? "selected run"}?`));
|
|
545
|
+
lines.push(this.theme.fg("dim", "Stop ends the run; use interrupt for a resumable pause. Enter/Y confirms · N returns · Esc cancels"));
|
|
546
|
+
} else if (this.actionNotice) {
|
|
547
|
+
lines.push(this.theme.fg(this.actionNotice.isError ? "error" : "success", this.actionNotice.text));
|
|
548
|
+
}
|
|
549
|
+
return lines;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
private withActionLines(body: string[]): string[] {
|
|
553
|
+
const actionLines = this.actionLines();
|
|
554
|
+
return actionLines.length ? [...actionLines, "", ...body] : body;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
private setActionNotice(result: FleetActionResult): void {
|
|
558
|
+
this.actionNotice = result;
|
|
559
|
+
this.resetActionInput();
|
|
560
|
+
this.detailAutoFollow = false;
|
|
561
|
+
this.detailScroll = 0;
|
|
562
|
+
this.refresh();
|
|
485
563
|
this.tui.requestRender();
|
|
486
564
|
}
|
|
487
565
|
|
|
566
|
+
private runAction(action: () => Promise<FleetActionResult>): void {
|
|
567
|
+
if (this.actionBusy) return;
|
|
568
|
+
this.actionBusy = true;
|
|
569
|
+
this.actionNotice = undefined;
|
|
570
|
+
this.tui.requestRender();
|
|
571
|
+
void action()
|
|
572
|
+
.then((result) => this.setActionNotice(result))
|
|
573
|
+
.catch((error) => this.setActionNotice({ text: error instanceof Error ? error.message : String(error), isError: true }))
|
|
574
|
+
.finally(() => {
|
|
575
|
+
this.actionBusy = false;
|
|
576
|
+
if (!this.disposed) this.tui.requestRender();
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
|
|
488
580
|
private scrollDetail(delta: number): void {
|
|
489
581
|
const maxScroll = Math.max(0, this.detailLineCount - this.detailViewportHeight);
|
|
490
582
|
this.detailScroll = Math.max(0, Math.min(maxScroll, this.detailScroll + delta));
|
|
@@ -493,6 +585,53 @@ export class SubagentFleetComponent implements Component {
|
|
|
493
585
|
}
|
|
494
586
|
|
|
495
587
|
handleInput(data: string): void {
|
|
588
|
+
if (this.steerDraft !== undefined) {
|
|
589
|
+
if (matchesKey(data, "escape") || matchesKey(data, "ctrl+c")) {
|
|
590
|
+
this.resetActionInput();
|
|
591
|
+
this.tui.requestRender();
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
if (matchesKey(data, "return") || data === "\r" || data === "\n") {
|
|
595
|
+
const message = this.steerDraft.trim();
|
|
596
|
+
if (!message) {
|
|
597
|
+
this.setActionNotice({ text: "Steer message cannot be empty.", isError: true });
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
const target = this.selectedAsyncAction();
|
|
601
|
+
if ("reason" in target || !this.options.actions) {
|
|
602
|
+
this.setActionNotice({ text: "reason" in target ? target.reason : "Fleet controls are unavailable in this context.", isError: true });
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
this.runAction(() => this.options.actions!.steer({ runId: target.item.runId, asyncDir: target.item.run.asyncDir, ...(target.item.index !== undefined ? { index: target.item.index } : {}), message }));
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
if (matchesKey(data, "backspace") || data === "\x7f") {
|
|
609
|
+
this.steerDraft = this.steerDraft.slice(0, -1);
|
|
610
|
+
this.tui.requestRender();
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
if (data.length === 1 && data >= " " && data !== "\x7f") {
|
|
614
|
+
this.steerDraft += data;
|
|
615
|
+
this.tui.requestRender();
|
|
616
|
+
}
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
if (this.stopConfirming) {
|
|
620
|
+
if (matchesKey(data, "return") || data.toLowerCase() === "y") {
|
|
621
|
+
const target = this.selectedAsyncAction();
|
|
622
|
+
if ("reason" in target || !this.options.actions) {
|
|
623
|
+
this.setActionNotice({ text: "reason" in target ? target.reason : "Fleet controls are unavailable in this context.", isError: true });
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
this.runAction(() => Promise.resolve(this.options.actions!.stop({ runId: target.item.runId, asyncDir: target.item.run.asyncDir, ...(target.item.index !== undefined ? { index: target.item.index } : {}) })));
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
if (matchesKey(data, "escape") || matchesKey(data, "ctrl+c") || data.toLowerCase() === "n" || matchesKey(data, "backspace")) {
|
|
630
|
+
this.resetActionInput();
|
|
631
|
+
this.tui.requestRender();
|
|
632
|
+
}
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
496
635
|
if (matchesKey(data, "escape") || matchesKey(data, "ctrl+c") || matchesKey(data, "q")) {
|
|
497
636
|
this.done(undefined);
|
|
498
637
|
return;
|
|
@@ -511,6 +650,30 @@ export class SubagentFleetComponent implements Component {
|
|
|
511
650
|
this.tui.requestRender();
|
|
512
651
|
return;
|
|
513
652
|
}
|
|
653
|
+
if (data === "s") {
|
|
654
|
+
const target = this.selectedAsyncAction();
|
|
655
|
+
if ("reason" in target || !this.options.actions) this.setActionNotice({ text: "reason" in target ? target.reason : "Fleet controls are unavailable in this context.", isError: true });
|
|
656
|
+
else {
|
|
657
|
+
this.actionNotice = undefined;
|
|
658
|
+
this.steerDraft = "";
|
|
659
|
+
this.detailAutoFollow = false;
|
|
660
|
+
this.detailScroll = 0;
|
|
661
|
+
this.tui.requestRender();
|
|
662
|
+
}
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
if (data === "D") {
|
|
666
|
+
const target = this.selectedAsyncAction();
|
|
667
|
+
if ("reason" in target || !this.options.actions) this.setActionNotice({ text: "reason" in target ? target.reason : "Fleet controls are unavailable in this context.", isError: true });
|
|
668
|
+
else {
|
|
669
|
+
this.actionNotice = undefined;
|
|
670
|
+
this.stopConfirming = true;
|
|
671
|
+
this.detailAutoFollow = false;
|
|
672
|
+
this.detailScroll = 0;
|
|
673
|
+
this.tui.requestRender();
|
|
674
|
+
}
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
514
677
|
if (data.toLowerCase() === "x" || matchesKey(data, "ctrl+o")) {
|
|
515
678
|
this.expandedTools = !this.expandedTools;
|
|
516
679
|
this.transcriptCache = undefined;
|
|
@@ -567,7 +730,7 @@ export class SubagentFleetComponent implements Component {
|
|
|
567
730
|
: latest?.kind === "tool"
|
|
568
731
|
? `${latest.name} · ${latest.status}`
|
|
569
732
|
: "activity";
|
|
570
|
-
return { header: structuredHeader(selected, width, this.theme, conversationState), body };
|
|
733
|
+
return { header: structuredHeader(selected, width, this.theme, conversationState), body: this.withActionLines(body) };
|
|
571
734
|
}
|
|
572
735
|
}
|
|
573
736
|
}
|
|
@@ -576,7 +739,7 @@ export class SubagentFleetComponent implements Component {
|
|
|
576
739
|
if (transcriptWarning) raw.unshift(`Transcript preview warning: ${transcriptWarning}`, "");
|
|
577
740
|
const lines: string[] = [];
|
|
578
741
|
for (const line of raw) {
|
|
579
|
-
const styled = /^(Run|State|Mode|Source|Child|Agent):/.test(line)
|
|
742
|
+
const styled = /^(Run|State|Mode|Source|Child|Agent|Model):/.test(line)
|
|
580
743
|
? this.theme.bold(line)
|
|
581
744
|
: /^(Transcript|Result transcript tail)/.test(line)
|
|
582
745
|
? this.theme.fg("accent", line)
|
|
@@ -588,7 +751,7 @@ export class SubagentFleetComponent implements Component {
|
|
|
588
751
|
const wrapped = wrapTextWithAnsi(styled, Math.max(1, width));
|
|
589
752
|
lines.push(...(wrapped.length ? wrapped : [""]));
|
|
590
753
|
}
|
|
591
|
-
return { header: [], body: lines };
|
|
754
|
+
return { header: [], body: this.withActionLines(lines) };
|
|
592
755
|
}
|
|
593
756
|
|
|
594
757
|
render(width: number): string[] {
|
|
@@ -612,7 +775,7 @@ export class SubagentFleetComponent implements Component {
|
|
|
612
775
|
];
|
|
613
776
|
const lines = [this.theme.fg("border", `╭${"─".repeat(innerWidth)}╮`)];
|
|
614
777
|
const selected = this.snapshot.items[this.selected];
|
|
615
|
-
const title = ` ${this.theme.bold("Subagent fleet inspector")} ${this.theme.fg("dim", "·
|
|
778
|
+
const title = ` ${this.theme.bold("Subagent fleet inspector")} ${this.theme.fg("dim", "· live controls")}`;
|
|
616
779
|
const selectedStatus = selected
|
|
617
780
|
? `${statusGlyph(selected, this.theme)} ${selected.agent} · ${selected.state} `
|
|
618
781
|
: this.theme.fg("dim", "no children ");
|
|
@@ -629,7 +792,7 @@ export class SubagentFleetComponent implements Component {
|
|
|
629
792
|
}
|
|
630
793
|
lines.push(this.theme.fg("border", `├${"─".repeat(rosterWidth)}┴${"─".repeat(detailWidth)}┤`));
|
|
631
794
|
const position = this.snapshot.items.length ? `${this.selected + 1}/${this.snapshot.items.length}` : "0/0";
|
|
632
|
-
const footer = ` ↑↓/jk agent ·
|
|
795
|
+
const footer = ` ↑↓/jk agent · s steer · D stop · x/Ctrl+O tools · r refresh · Esc close · ${position}`;
|
|
633
796
|
lines.push(this.theme.fg("border", "│") + fit(this.theme.fg("dim", footer), innerWidth) + this.theme.fg("border", "│"));
|
|
634
797
|
lines.push(this.theme.fg("border", `╰${"─".repeat(innerWidth)}╯`));
|
|
635
798
|
return lines.map((line) => truncateToWidth(line, width));
|
|
@@ -650,9 +813,19 @@ export async function openSubagentFleet(ctx: ExtensionContext, state: SubagentSt
|
|
|
650
813
|
const wasOpen = state.fleetInspectorOpen === true;
|
|
651
814
|
state.fleetInspectorOpen = true;
|
|
652
815
|
if (typeof ctx.ui.setWidget === "function") ctx.ui.setWidget(FLEET_STATUS_WIDGET_KEY, undefined);
|
|
816
|
+
const actions = options.actions ?? {
|
|
817
|
+
steer: async (input: { runId: string; asyncDir: string; index?: number; message: string }) => firstToolResultText(await steerAsyncRun({
|
|
818
|
+
state,
|
|
819
|
+
runId: input.runId,
|
|
820
|
+
...(input.index !== undefined ? { index: input.index } : {}),
|
|
821
|
+
message: input.message,
|
|
822
|
+
location: { asyncDir: input.asyncDir, resolvedId: input.runId },
|
|
823
|
+
}), `Failed to steer async run ${input.runId}.`),
|
|
824
|
+
stop: (input: { runId: string; asyncDir: string; index?: number }) => firstToolResultText(stopAsyncRun(state, input.runId, undefined, { asyncDir: input.asyncDir, resolvedId: input.runId }), `Failed to stop async run ${input.runId}.`),
|
|
825
|
+
} satisfies FleetActionHandlers;
|
|
653
826
|
try {
|
|
654
827
|
await ctx.ui.custom<undefined>(
|
|
655
|
-
(tui, theme, _keybindings, done) => new SubagentFleetComponent(tui, theme, state, done, options),
|
|
828
|
+
(tui, theme, _keybindings, done) => new SubagentFleetComponent(tui, theme, state, done, { ...options, actions }),
|
|
656
829
|
);
|
|
657
830
|
} finally {
|
|
658
831
|
state.fleetInspectorOpen = wasOpen;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Rendering functions for subagent results
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import * as fs from "node:fs";
|
|
5
6
|
import * as path from "node:path";
|
|
6
7
|
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
7
8
|
import { getMarkdownTheme, keyText, type ExtensionContext } from "@selesai/code";
|
|
@@ -27,6 +28,27 @@ import { contextModeBadge, contextModePrefix } from "../runs/shared/context-mode
|
|
|
27
28
|
|
|
28
29
|
type Theme = ExtensionContext["ui"]["theme"];
|
|
29
30
|
|
|
31
|
+
/**
|
|
32
|
+
* UI-side output projection: completed terminal results strip `finalOutput`/
|
|
33
|
+
* `truncation` when an authoritative saved output path exists (see
|
|
34
|
+
* compactForegroundResult). The UI recovers the full text from that path so
|
|
35
|
+
* widgets keep showing output without reintroducing it into model-facing
|
|
36
|
+
* details.
|
|
37
|
+
*/
|
|
38
|
+
function resultOutputForUi(r: Details["results"][number]): string {
|
|
39
|
+
const output = r.truncation?.text || getSingleResultOutput(r);
|
|
40
|
+
if (output) return output;
|
|
41
|
+
if (r.savedOutputPath) {
|
|
42
|
+
try {
|
|
43
|
+
const content = fs.readFileSync(r.savedOutputPath, "utf-8").trim();
|
|
44
|
+
return content || output;
|
|
45
|
+
} catch {
|
|
46
|
+
return output;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return output;
|
|
50
|
+
}
|
|
51
|
+
|
|
30
52
|
function liveDetailKeyText(): string {
|
|
31
53
|
return keyText("app.tools.expand");
|
|
32
54
|
}
|
|
@@ -40,6 +62,7 @@ function getTermWidth(): number {
|
|
|
40
62
|
}
|
|
41
63
|
|
|
42
64
|
const segmenter = new Intl.Segmenter(undefined, { granularity: "grapheme" });
|
|
65
|
+
const ansiStylePattern = /\x1b\[[0-9;]*m/y;
|
|
43
66
|
|
|
44
67
|
/**
|
|
45
68
|
* Truncate a line to maxWidth, preserving ANSI styling through the ellipsis.
|
|
@@ -50,7 +73,7 @@ const segmenter = new Intl.Segmenter(undefined, { granularity: "grapheme" });
|
|
|
50
73
|
*
|
|
51
74
|
* Uses Intl.Segmenter for proper Unicode/emoji handling (not char-by-char).
|
|
52
75
|
*/
|
|
53
|
-
function truncLine(text: string, maxWidth: number): string {
|
|
76
|
+
export function truncLine(text: string, maxWidth: number): string {
|
|
54
77
|
if (visibleWidth(text) <= maxWidth) return text;
|
|
55
78
|
|
|
56
79
|
const targetWidth = maxWidth - 1;
|
|
@@ -60,7 +83,8 @@ function truncLine(text: string, maxWidth: number): string {
|
|
|
60
83
|
let i = 0;
|
|
61
84
|
|
|
62
85
|
while (i < text.length) {
|
|
63
|
-
|
|
86
|
+
ansiStylePattern.lastIndex = i;
|
|
87
|
+
const ansiMatch = ansiStylePattern.exec(text);
|
|
64
88
|
if (ansiMatch) {
|
|
65
89
|
const code = ansiMatch[0];
|
|
66
90
|
result += code;
|
|
@@ -74,11 +98,9 @@ function truncLine(text: string, maxWidth: number): string {
|
|
|
74
98
|
continue;
|
|
75
99
|
}
|
|
76
100
|
|
|
77
|
-
let end = i;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
101
|
+
let end = text.indexOf("\x1b[", i);
|
|
102
|
+
if (end === i) end = text.indexOf("\x1b[", i + 2);
|
|
103
|
+
if (end === -1) end = text.length;
|
|
82
104
|
const textPortion = text.slice(i, end);
|
|
83
105
|
for (const seg of segmenter.segment(textPortion)) {
|
|
84
106
|
const grapheme = seg.segment;
|
|
@@ -529,17 +551,15 @@ function buildChainStepSpans(details: Pick<Details, "chainAgents" | "workflowGra
|
|
|
529
551
|
return spans;
|
|
530
552
|
}
|
|
531
553
|
|
|
532
|
-
function isChainParallelGroupActive(details: Pick<Details, "mode" | "chainAgents" | "currentStepIndex" | "workflowGraph">): boolean {
|
|
533
|
-
if (details.mode !== "chain") return false;
|
|
534
|
-
if (details.currentStepIndex === undefined) return false;
|
|
535
|
-
return buildChainStepSpans(details).some((span) => span.stepIndex === details.currentStepIndex && span.isParallel);
|
|
536
|
-
}
|
|
537
|
-
|
|
538
554
|
function buildAsyncChainStepSpans(total: number, stepCount: number, parallelGroups: AsyncParallelGroupStatus[] = []): ChainStepSpan[] {
|
|
555
|
+
const groupsByStep = new Map<number, AsyncParallelGroupStatus>();
|
|
556
|
+
for (const group of parallelGroups) {
|
|
557
|
+
if (!groupsByStep.has(group.stepIndex)) groupsByStep.set(group.stepIndex, group);
|
|
558
|
+
}
|
|
539
559
|
const spans: ChainStepSpan[] = [];
|
|
540
560
|
let flatIndex = 0;
|
|
541
561
|
for (let stepIndex = 0; stepIndex < total; stepIndex++) {
|
|
542
|
-
const group =
|
|
562
|
+
const group = groupsByStep.get(stepIndex);
|
|
543
563
|
if (group) {
|
|
544
564
|
spans.push({ stepIndex, start: group.start, count: group.count, isParallel: true });
|
|
545
565
|
flatIndex = Math.max(flatIndex, group.start + group.count);
|
|
@@ -567,6 +587,7 @@ interface ChainRenderResultEntry {
|
|
|
567
587
|
kind: "result";
|
|
568
588
|
resultIndex: number;
|
|
569
589
|
rowNumber: number;
|
|
590
|
+
rowLabel?: string;
|
|
570
591
|
agentName: string;
|
|
571
592
|
}
|
|
572
593
|
|
|
@@ -601,6 +622,7 @@ function buildChainRenderEntries(details: Details, label: MultiProgressLabel): C
|
|
|
601
622
|
kind: "result",
|
|
602
623
|
resultIndex: index,
|
|
603
624
|
rowNumber: index + 1,
|
|
625
|
+
rowLabel: span.isParallel ? `Agent ${index - span.start + 1}/${span.count}` : `Step ${span.stepIndex + 1}`,
|
|
604
626
|
agentName: details.results[index]?.agent ?? details.chainAgents?.[span.stepIndex] ?? `step-${span.stepIndex + 1}`,
|
|
605
627
|
});
|
|
606
628
|
}
|
|
@@ -622,7 +644,9 @@ interface MultiProgressLabel {
|
|
|
622
644
|
function buildMultiProgressLabel(details: Pick<Details, "mode" | "results" | "progress" | "totalSteps" | "currentStepIndex" | "chainAgents" | "workflowGraph">, hasRunning: boolean): MultiProgressLabel {
|
|
623
645
|
const stepSpans = buildChainStepSpans(details);
|
|
624
646
|
const hasParallelInChain = details.mode === "chain" && stepSpans.some((span) => span.isParallel);
|
|
625
|
-
const activeParallelGroup =
|
|
647
|
+
const activeParallelGroup = details.mode === "chain"
|
|
648
|
+
&& details.currentStepIndex !== undefined
|
|
649
|
+
&& stepSpans.some((span) => span.stepIndex === details.currentStepIndex && span.isParallel);
|
|
626
650
|
const itemTitle: "Step" | "Agent" = details.mode === "parallel" || activeParallelGroup ? "Agent" : "Step";
|
|
627
651
|
|
|
628
652
|
if (details.mode === "parallel") {
|
|
@@ -708,15 +732,10 @@ function buildMultiProgressLabel(details: Pick<Details, "mode" | "results" | "pr
|
|
|
708
732
|
return { headerLabel, itemTitle, totalCount, hasParallelInChain, activeParallelGroup, groupStartIndex: 0, groupEndIndex: details.results.length, showActiveGroupOnly: false };
|
|
709
733
|
}
|
|
710
734
|
|
|
711
|
-
function resultRowLabel(
|
|
712
|
-
if (details.mode === "chain" && label.hasParallelInChain) {
|
|
713
|
-
const span = buildChainStepSpans(details).find((candidate) => resultIndex >= candidate.start && resultIndex < candidate.start + candidate.count);
|
|
714
|
-
if (span?.isParallel) return `Agent ${resultIndex - span.start + 1}/${span.count}`;
|
|
715
|
-
if (span) return `Step ${span.stepIndex + 1}`;
|
|
716
|
-
}
|
|
735
|
+
function resultRowLabel(label: MultiProgressLabel, resultIndex: number, stepNumber: number): string {
|
|
717
736
|
if (label.itemTitle === "Agent") {
|
|
718
737
|
const localStepNumber = label.activeParallelGroup
|
|
719
|
-
?
|
|
738
|
+
? resultIndex - label.groupStartIndex + 1
|
|
720
739
|
: stepNumber;
|
|
721
740
|
return `Agent ${localStepNumber}/${label.totalCount}`;
|
|
722
741
|
}
|
|
@@ -1311,7 +1330,7 @@ export function renderWidget(ctx: ExtensionContext, jobs: AsyncJobState[]): void
|
|
|
1311
1330
|
}
|
|
1312
1331
|
|
|
1313
1332
|
function renderSingleCompact(d: Details, r: Details["results"][number], theme: Theme, frame?: number): Component {
|
|
1314
|
-
const output =
|
|
1333
|
+
const output = resultOutputForUi(r);
|
|
1315
1334
|
const progress = r.progress || r.progressSummary;
|
|
1316
1335
|
const isRunning = r.progress?.status === "running";
|
|
1317
1336
|
const contextBadge = contextModeBadge(theme, r.context ?? d.context);
|
|
@@ -1321,7 +1340,7 @@ function renderSingleCompact(d: Details, r: Details["results"][number], theme: T
|
|
|
1321
1340
|
]);
|
|
1322
1341
|
const c = new Container();
|
|
1323
1342
|
const width = getTermWidth() - 4;
|
|
1324
|
-
const modelDisplay = modelThinkingBadge(theme, r.model);
|
|
1343
|
+
const modelDisplay = modelThinkingBadge(theme, r.model ?? r.progress?.model, r.thinking ?? r.progress?.thinking);
|
|
1325
1344
|
c.addChild(new Text(truncLine(`${resultGlyph(r, output, theme, isRunning, undefined, frame)} ${theme.fg("toolTitle", theme.bold(r.agent))}${modelDisplay}${contextBadge}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`, width), 0, 0));
|
|
1326
1345
|
|
|
1327
1346
|
if (isRunning && r.progress) {
|
|
@@ -1417,11 +1436,11 @@ function renderMultiCompact(d: Details, theme: Theme, frame?: number): Component
|
|
|
1417
1436
|
const rowNumber = entry.rowNumber;
|
|
1418
1437
|
const agentName = entry.agentName;
|
|
1419
1438
|
if (!r) {
|
|
1420
|
-
const pendingLabel =
|
|
1439
|
+
const pendingLabel = entry.rowLabel ?? `${itemTitle} ${rowNumber}`;
|
|
1421
1440
|
c.addChild(new Text(truncLine(theme.fg("dim", ` ◦ ${pendingLabel}: ${agentName} · pending`), width), 0, 0));
|
|
1422
1441
|
continue;
|
|
1423
1442
|
}
|
|
1424
|
-
const output =
|
|
1443
|
+
const output = resultOutputForUi(r);
|
|
1425
1444
|
const progressFromArray = d.progress?.find((p) => p.index === i) || d.progress?.find((p) => p.agent === r.agent && p.status === "running");
|
|
1426
1445
|
const rProg = r.progress || progressFromArray || r.progressSummary;
|
|
1427
1446
|
const rRunning = rProg && "status" in rProg && rProg.status === "running";
|
|
@@ -1430,8 +1449,10 @@ function renderMultiCompact(d: Details, theme: Theme, frame?: number): Component
|
|
|
1430
1449
|
const stepStats = formatProgressStats(theme, rProg);
|
|
1431
1450
|
const glyph = rPending ? theme.fg("dim", "◦") : resultGlyph(r, output, theme, rRunning, progressRunningSeed(rProg), frame);
|
|
1432
1451
|
const pendingLabel = rPending ? ` ${theme.fg("dim", "· pending")}` : "";
|
|
1433
|
-
const stepLabel = resultRowLabel(
|
|
1434
|
-
const
|
|
1452
|
+
const stepLabel = entry.rowLabel ?? resultRowLabel(multiLabel, i, stepNumber);
|
|
1453
|
+
const rowProgressModel = rProg && "status" in rProg ? rProg : undefined;
|
|
1454
|
+
const rowModelDisplay = modelThinkingBadge(theme, r.model ?? rowProgressModel?.model, r.thinking ?? rowProgressModel?.thinking);
|
|
1455
|
+
const line = `${glyph} ${stepLabel}: ${themeBold(theme, agentName)}${contextModeBadge(theme, r.context)}${rowModelDisplay}${stepStats ? ` ${theme.fg("dim", "·")} ${stepStats}` : ""}${pendingLabel}`;
|
|
1435
1456
|
c.addChild(new Text(truncLine(` ${line}`, width), 0, 0));
|
|
1436
1457
|
if (rRunning && rProg && "status" in rProg) {
|
|
1437
1458
|
const activity = compactCurrentActivity(rProg);
|
|
@@ -1501,7 +1522,7 @@ export function renderSubagentResult(
|
|
|
1501
1522
|
? theme.fg("success", "ok")
|
|
1502
1523
|
: theme.fg("error", "failed");
|
|
1503
1524
|
const contextBadge = contextModeBadge(theme, r.context ?? d.context);
|
|
1504
|
-
const output =
|
|
1525
|
+
const output = resultOutputForUi(r);
|
|
1505
1526
|
|
|
1506
1527
|
const progressInfo = isRunning && r.progress
|
|
1507
1528
|
? ` | ${r.progress.toolCount} tools, ${formatTokens(r.progress.tokens)} tok, ${formatDuration(r.progress.durationMs)}`
|
|
@@ -1601,7 +1622,7 @@ export function renderSubagentResult(
|
|
|
1601
1622
|
const hasEmptyWithoutTarget = d.results.some((r) =>
|
|
1602
1623
|
r.exitCode === 0
|
|
1603
1624
|
&& r.progress?.status !== "running"
|
|
1604
|
-
&& hasEmptyTextOutputWithoutOutputTarget(r.task,
|
|
1625
|
+
&& hasEmptyTextOutputWithoutOutputTarget(r.task, resultOutputForUi(r)),
|
|
1605
1626
|
);
|
|
1606
1627
|
const hasWorkflowFailure = workflowGraphHasStatus(d, ["failed"]);
|
|
1607
1628
|
const hasWorkflowStop = d.results.some((r) => r.stopped && r.progress?.status !== "running") || workflowGraphHasStatus(d, ["stopped"]);
|
|
@@ -1659,7 +1680,7 @@ export function renderSubagentResult(
|
|
|
1659
1680
|
const isComplete = result && result.exitCode === 0 && result.progress?.status !== "running";
|
|
1660
1681
|
const isEmptyWithoutTarget = Boolean(result)
|
|
1661
1682
|
&& Boolean(isComplete)
|
|
1662
|
-
&& hasEmptyTextOutputWithoutOutputTarget(result.task,
|
|
1683
|
+
&& hasEmptyTextOutputWithoutOutputTarget(result.task, resultOutputForUi(result));
|
|
1663
1684
|
const isCurrent = i === (d.currentStepIndex ?? d.results.length);
|
|
1664
1685
|
const stepIcon = isFailed
|
|
1665
1686
|
? theme.fg("error", "failed")
|
|
@@ -1717,7 +1738,7 @@ export function renderSubagentResult(
|
|
|
1717
1738
|
const agentName = entry.agentName;
|
|
1718
1739
|
|
|
1719
1740
|
if (!r) {
|
|
1720
|
-
const pendingLabel =
|
|
1741
|
+
const pendingLabel = entry.rowLabel ?? `${itemTitle} ${rowNumber}`;
|
|
1721
1742
|
c.addChild(new Text(fit(theme.fg("dim", ` ${pendingLabel}: ${agentName}`)), 0, 0));
|
|
1722
1743
|
c.addChild(new Text(theme.fg("dim", ` status: pending`), 0, 0));
|
|
1723
1744
|
c.addChild(new Spacer(1));
|
|
@@ -1730,7 +1751,7 @@ export function renderSubagentResult(
|
|
|
1730
1751
|
const rRunning = rProg?.status === "running";
|
|
1731
1752
|
const stepNumber = typeof rProg?.index === "number" ? rProg.index + 1 : i + 1;
|
|
1732
1753
|
|
|
1733
|
-
const resultOutput =
|
|
1754
|
+
const resultOutput = resultOutputForUi(r);
|
|
1734
1755
|
const statusIcon = rRunning
|
|
1735
1756
|
? theme.fg("warning", "running")
|
|
1736
1757
|
: r.exitCode !== 0
|
|
@@ -1740,7 +1761,7 @@ export function renderSubagentResult(
|
|
|
1740
1761
|
: theme.fg("success", "done");
|
|
1741
1762
|
const stats = rProg ? ` | ${rProg.toolCount} tools, ${formatDuration(rProg.durationMs)}` : "";
|
|
1742
1763
|
const modelDisplay = modelThinkingBadge(theme, r.model);
|
|
1743
|
-
const stepLabel = resultRowLabel(
|
|
1764
|
+
const stepLabel = entry.rowLabel ?? resultRowLabel(multiLabel, i, stepNumber);
|
|
1744
1765
|
const contextBadge = contextModeBadge(theme, r.context);
|
|
1745
1766
|
const stepHeader = rRunning
|
|
1746
1767
|
? `${statusIcon} ${stepLabel}: ${theme.bold(theme.fg("warning", r.agent))}${contextBadge}${modelDisplay}${stats}`
|
|
@@ -111,6 +111,8 @@ export function buildWatchdogStatus(snapshot: ReturnType<MainWatchdogRuntime["ge
|
|
|
111
111
|
`Main: ${boolLabel(snapshot.enabled)}${!snapshot.config.enabled && snapshot.sessionOverride === undefined ? " (default off)" : ""}`,
|
|
112
112
|
`Runtime: ${statusLabel(snapshot.status)}${snapshot.bufferedDeltas > 0 ? ` · buffered deltas ${snapshot.bufferedDeltas}` : ""}`,
|
|
113
113
|
`Review trigger: ${snapshot.reviewTrigger === "repo-edits" ? "repo edits only" : "every non-empty turn delta"}`,
|
|
114
|
+
`Scope context: ${snapshot.config.scope.enabled ? "on" : "off"}`,
|
|
115
|
+
`Cadence: ${snapshot.config.cadence.everyNTools === null ? "boundary only" : `every ${snapshot.config.cadence.everyNTools} tools + boundary`}`,
|
|
114
116
|
lspLine(snapshot),
|
|
115
117
|
`Session override: ${snapshot.sessionOverride === undefined ? "none" : boolLabel(snapshot.sessionOverride)}`,
|
|
116
118
|
mainModelLine(snapshot, ctx),
|
|
@@ -118,7 +120,7 @@ export function buildWatchdogStatus(snapshot: ReturnType<MainWatchdogRuntime["ge
|
|
|
118
120
|
childrenLine(snapshot),
|
|
119
121
|
recommendationLine(ctx),
|
|
120
122
|
`Agent-end timeout: ${snapshot.config.agentEndTimeoutMs}ms`,
|
|
121
|
-
`Auto-follow:
|
|
123
|
+
`Auto-follow: ${snapshot.enabled && snapshot.config.autoFollow.blockers ? "on for blockers" : "off"} · attempts ${snapshot.autoFollowAttempts}${snapshot.config.autoFollow.maxAttempts === null ? "" : `/${snapshot.config.autoFollow.maxAttempts}`}${snapshot.autoFollowQueued ? " · queued" : ""}${snapshot.autoFollowStalemate ? " · stalemate" : ""}`,
|
|
122
124
|
`Review model call: ${snapshot.reviewDescription}`,
|
|
123
125
|
];
|
|
124
126
|
if (snapshot.failedReviews > 0) lines.push(`Failed reviews: ${snapshot.failedReviews}`);
|
|
@@ -236,7 +238,7 @@ function createTestWarning(severity: "concern" | "blocker", text: string): Watch
|
|
|
236
238
|
summary: text,
|
|
237
239
|
evidence: `Manual /subagents-watchdog test ${severity} message from the main session.`,
|
|
238
240
|
recommendedAction: severity === "blocker"
|
|
239
|
-
? "Verify the renderer
|
|
241
|
+
? "Verify the renderer, transcript delivery, and auto-follow policy."
|
|
240
242
|
: "Verify the renderer and transcript delivery; decide manually whether any action is needed.",
|
|
241
243
|
};
|
|
242
244
|
}
|
|
@@ -381,9 +383,10 @@ export function registerMainWatchdog(pi: ExtensionAPI, options: RegisterMainWatc
|
|
|
381
383
|
review: options.review ?? createMainWatchdogReview(() => currentContext, { getThinkingLevel: () => pi.getThinkingLevel() }),
|
|
382
384
|
reviewDescription: options.review ? "injected seam" : "real model review",
|
|
383
385
|
reviewChangesOnly: true,
|
|
384
|
-
displayWarning: (details) => {
|
|
385
|
-
pi.sendMessage(createWatchdogWarningMessage(details, { display: true, details }));
|
|
386
|
+
displayWarning: (details, delivery) => {
|
|
387
|
+
pi.sendMessage(createWatchdogWarningMessage(details, { display: true, details }), delivery?.deliverAs === "steer" ? { deliverAs: "steer" } : undefined);
|
|
386
388
|
},
|
|
389
|
+
sendUserMessage: (message) => pi.sendUserMessage(message),
|
|
387
390
|
});
|
|
388
391
|
|
|
389
392
|
pi.registerMessageRenderer<WatchdogWarningDetails>(SUBAGENT_WATCHDOG_WARNING_TYPE, (message, renderOptions, theme) => {
|
|
@@ -417,13 +420,17 @@ export function registerMainWatchdog(pi: ExtensionAPI, options: RegisterMainWatc
|
|
|
417
420
|
rememberContext(ctx);
|
|
418
421
|
runtime.handleTurnEnd(event, ctx);
|
|
419
422
|
});
|
|
423
|
+
pi.on("tool_result", (_event, ctx) => {
|
|
424
|
+
rememberContext(ctx);
|
|
425
|
+
runtime.handleToolResult(ctx);
|
|
426
|
+
});
|
|
420
427
|
pi.on("agent_end", (event, ctx) => {
|
|
421
428
|
rememberContext(ctx);
|
|
422
429
|
return runtime.handleAgentEnd(event, ctx);
|
|
423
430
|
});
|
|
424
|
-
pi.on("session_before_switch", () => runtime.reset("session switch", { clearReviewInputSignature: true, clearLspLedger: true }));
|
|
425
|
-
pi.on("session_before_fork", () => runtime.reset("session fork", { clearReviewInputSignature: true, clearLspLedger: true }));
|
|
426
|
-
pi.on("session_compact", () => runtime.reset("session compact"));
|
|
431
|
+
pi.on("session_before_switch", () => runtime.reset("session switch", { clearReviewInputSignature: true, clearLspLedger: true, clearScope: true, resetAutoFollow: true }));
|
|
432
|
+
pi.on("session_before_fork", () => runtime.reset("session fork", { clearReviewInputSignature: true, clearLspLedger: true, clearScope: true, resetAutoFollow: true }));
|
|
433
|
+
pi.on("session_compact", () => runtime.reset("session compact", { clearScope: true }));
|
|
427
434
|
pi.on("session_shutdown", () => {
|
|
428
435
|
currentContext = undefined;
|
|
429
436
|
runtime.dispose();
|