@code-yeongyu/senpi 2026.8.29 → 2026.8.30-2
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 +122 -0
- package/dist/core/agent-session.d.ts +45 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +329 -29
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +155 -37
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction/compaction-execution.d.ts +14 -0
- package/dist/core/compaction/compaction-execution.d.ts.map +1 -0
- package/dist/core/compaction/compaction-execution.js +121 -0
- package/dist/core/compaction/compaction-execution.js.map +1 -0
- package/dist/core/compaction/compaction-settings.d.ts +17 -0
- package/dist/core/compaction/compaction-settings.d.ts.map +1 -0
- package/dist/core/compaction/compaction-settings.js +17 -0
- package/dist/core/compaction/compaction-settings.js.map +1 -0
- package/dist/core/compaction/compaction.d.ts +13 -26
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +7 -136
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/ideal-compaction-settings.d.ts +9 -0
- package/dist/core/compaction/ideal-compaction-settings.d.ts.map +1 -0
- package/dist/core/compaction/ideal-compaction-settings.js +7 -0
- package/dist/core/compaction/ideal-compaction-settings.js.map +1 -0
- package/dist/core/compaction-settings-access.d.ts +19 -0
- package/dist/core/compaction-settings-access.d.ts.map +1 -0
- package/dist/core/compaction-settings-access.js +10 -0
- package/dist/core/compaction-settings-access.js.map +1 -0
- package/dist/core/compaction-settings-resolver.d.ts +22 -0
- package/dist/core/compaction-settings-resolver.d.ts.map +1 -0
- package/dist/core/compaction-settings-resolver.js +46 -0
- package/dist/core/compaction-settings-resolver.js.map +1 -0
- package/dist/core/credential-accounts.d.ts.map +1 -1
- package/dist/core/credential-accounts.js +23 -9
- package/dist/core/credential-accounts.js.map +1 -1
- package/dist/core/credential-pool/env-slots.d.ts.map +1 -1
- package/dist/core/credential-pool/env-slots.js +2 -0
- package/dist/core/credential-pool/env-slots.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/context-pipeline.d.ts +17 -0
- package/dist/core/extensions/builtin/compaction/context-pipeline.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/context-pipeline.js +28 -0
- package/dist/core/extensions/builtin/compaction/context-pipeline.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +8 -2
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +163 -48
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/emergency-prune.d.ts +17 -0
- package/dist/core/extensions/builtin/compaction/emergency-prune.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/emergency-prune.js +64 -0
- package/dist/core/extensions/builtin/compaction/emergency-prune.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/extension-wiring.d.ts +27 -0
- package/dist/core/extensions/builtin/compaction/extension-wiring.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/extension-wiring.js +84 -0
- package/dist/core/extensions/builtin/compaction/extension-wiring.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/idle.d.ts +1 -0
- package/dist/core/extensions/builtin/compaction/idle.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/idle.js +13 -2
- package/dist/core/extensions/builtin/compaction/idle.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +121 -147
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/log.d.ts +1 -1
- package/dist/core/extensions/builtin/compaction/log.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/log.js +2 -0
- package/dist/core/extensions/builtin/compaction/log.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/model-selection.d.ts +14 -0
- package/dist/core/extensions/builtin/compaction/model-selection.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/model-selection.js +37 -0
- package/dist/core/extensions/builtin/compaction/model-selection.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.d.ts +9 -0
- package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.js +2 -0
- package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +3 -6
- package/dist/core/extensions/builtin/compaction/openai-remote.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/openai-remote.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/orchestration.d.ts +56 -0
- package/dist/core/extensions/builtin/compaction/orchestration.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/orchestration.js +136 -0
- package/dist/core/extensions/builtin/compaction/orchestration.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/policy.d.ts +5 -2
- package/dist/core/extensions/builtin/compaction/policy.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/policy.js +43 -26
- package/dist/core/extensions/builtin/compaction/policy.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/retained-message-safety.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/retained-message-safety.js +31 -8
- package/dist/core/extensions/builtin/compaction/retained-message-safety.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculation-lead.d.ts +8 -0
- package/dist/core/extensions/builtin/compaction/speculation-lead.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculation-lead.js +17 -0
- package/dist/core/extensions/builtin/compaction/speculation-lead.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative-job.d.ts +22 -0
- package/dist/core/extensions/builtin/compaction/speculative-job.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative-job.js +16 -0
- package/dist/core/extensions/builtin/compaction/speculative-job.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts +22 -0
- package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative-summary.js +131 -0
- package/dist/core/extensions/builtin/compaction/speculative-summary.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative.d.ts +8 -13
- package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.js +7 -196
- package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/token-budget-reminder.d.ts +18 -0
- package/dist/core/extensions/builtin/compaction/token-budget-reminder.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/token-budget-reminder.js +18 -0
- package/dist/core/extensions/builtin/compaction/token-budget-reminder.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/tool-admission.d.ts +36 -0
- package/dist/core/extensions/builtin/compaction/tool-admission.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/tool-admission.js +92 -0
- package/dist/core/extensions/builtin/compaction/tool-admission.js.map +1 -0
- package/dist/core/extensions/builtin/cursor-cli-oauth/stream.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/stream.js +8 -28
- package/dist/core/extensions/builtin/cursor-cli-oauth/stream.js.map +1 -1
- package/dist/core/extensions/builtin/permission-system/external-dir.d.ts.map +1 -1
- package/dist/core/extensions/builtin/permission-system/external-dir.js +15 -5
- package/dist/core/extensions/builtin/permission-system/external-dir.js.map +1 -1
- package/dist/core/extensions/builtin/permission-system/parsers.d.ts.map +1 -1
- package/dist/core/extensions/builtin/permission-system/parsers.js +16 -1
- package/dist/core/extensions/builtin/permission-system/parsers.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/manager.d.ts +5 -0
- package/dist/core/extensions/builtin/terminal/manager.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/manager.js +31 -3
- package/dist/core/extensions/builtin/terminal/manager.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-permission.d.ts +8 -0
- package/dist/core/extensions/builtin/terminal/monitor-permission.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/monitor-permission.js +16 -0
- package/dist/core/extensions/builtin/terminal/monitor-permission.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +13 -0
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-registry.js +403 -3
- package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/session-bundle.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/session-bundle.js +1 -0
- package/dist/core/extensions/builtin/terminal/session-bundle.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/kill-bash.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/kill-bash.js +5 -2
- package/dist/core/extensions/builtin/terminal/tools/kill-bash.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts +4 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.js +40 -2
- package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -1
- package/dist/core/model-resolver.js +2 -2
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +10 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +15 -85
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +15 -17
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-public-types.d.ts +11 -0
- package/dist/core/settings-public-types.d.ts.map +1 -0
- package/dist/core/settings-public-types.js +2 -0
- package/dist/core/settings-public-types.js.map +1 -0
- package/dist/core/settings-shapes.d.ts +36 -0
- package/dist/core/settings-shapes.d.ts.map +1 -0
- package/dist/core/settings-shapes.js +2 -0
- package/dist/core/settings-shapes.js.map +1 -0
- package/dist/core/shared-host-policy.d.ts +6 -0
- package/dist/core/shared-host-policy.d.ts.map +1 -0
- package/dist/core/shared-host-policy.js +7 -0
- package/dist/core/shared-host-policy.js.map +1 -0
- package/dist/core/terminal-settings.d.ts +22 -0
- package/dist/core/terminal-settings.d.ts.map +1 -0
- package/dist/core/terminal-settings.js +2 -0
- package/dist/core/terminal-settings.js.map +1 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +97 -15
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -0
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +8 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +76 -34
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +17 -5
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +7 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +34 -8
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/grok/chrome.d.ts +2 -0
- package/dist/modes/interactive/grok/chrome.d.ts.map +1 -1
- package/dist/modes/interactive/grok/chrome.js.map +1 -1
- package/dist/modes/interactive/interactive-host-runtime.d.ts +121 -1
- package/dist/modes/interactive/interactive-host-runtime.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-host-runtime.js +336 -65
- package/dist/modes/interactive/interactive-host-runtime.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +7 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +114 -2
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/connection-handler.d.ts +8 -1
- package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
- package/dist/modes/rpc/connection-handler.js +145 -49
- package/dist/modes/rpc/connection-handler.js.map +1 -1
- package/dist/modes/rpc/host-ensure.d.ts +19 -0
- package/dist/modes/rpc/host-ensure.d.ts.map +1 -1
- package/dist/modes/rpc/host-ensure.js +79 -15
- package/dist/modes/rpc/host-ensure.js.map +1 -1
- package/dist/modes/rpc/host-lifecycle.d.ts +29 -0
- package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
- package/dist/modes/rpc/host-lifecycle.js +96 -25
- package/dist/modes/rpc/host-lifecycle.js.map +1 -1
- package/dist/modes/rpc/host-watchdog.d.ts +2 -0
- package/dist/modes/rpc/host-watchdog.d.ts.map +1 -1
- package/dist/modes/rpc/host-watchdog.js +23 -12
- package/dist/modes/rpc/host-watchdog.js.map +1 -1
- package/dist/modes/rpc/multi-session-host.js +6 -4
- package/dist/modes/rpc/multi-session-host.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +10 -4
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +47 -10
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-input-validation.d.ts +1 -0
- package/dist/modes/rpc/rpc-input-validation.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-input-validation.js +66 -0
- package/dist/modes/rpc/rpc-input-validation.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +86 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/rpc/session-binding.d.ts +1 -0
- package/dist/modes/rpc/session-binding.d.ts.map +1 -1
- package/dist/modes/rpc/session-binding.js +21 -1
- package/dist/modes/rpc/session-binding.js.map +1 -1
- package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
- package/dist/modes/rpc/session-command-router.js +1 -0
- package/dist/modes/rpc/session-command-router.js.map +1 -1
- package/dist/modes/rpc/session-event-writer.d.ts +2 -0
- package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
- package/dist/modes/rpc/session-event-writer.js +54 -7
- package/dist/modes/rpc/session-event-writer.js.map +1 -1
- package/dist/modes/rpc/session-extension-ui-requests.d.ts +1 -0
- package/dist/modes/rpc/session-extension-ui-requests.d.ts.map +1 -1
- package/dist/modes/rpc/session-extension-ui-requests.js +5 -0
- package/dist/modes/rpc/session-extension-ui-requests.js.map +1 -1
- package/dist/modes/rpc/session-registry.d.ts +10 -2
- package/dist/modes/rpc/session-registry.d.ts.map +1 -1
- package/dist/modes/rpc/session-registry.js +58 -4
- package/dist/modes/rpc/session-registry.js.map +1 -1
- package/dist/modes/rpc/socket-event-fanout.d.ts +22 -0
- package/dist/modes/rpc/socket-event-fanout.d.ts.map +1 -0
- package/dist/modes/rpc/socket-event-fanout.js +84 -0
- package/dist/modes/rpc/socket-event-fanout.js.map +1 -0
- package/docs/rpc.md +18 -2
- package/docs/settings.md +34 -0
- package/docs/windows.md +2 -0
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +50 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-indirect-eval.js +139 -90
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +4 -4
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.js +40 -20
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts +3 -3
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/shell-output.d.ts +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/shell-output.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/shell-output.js +28 -9
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/shell-output.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +67 -38
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.d.ts +20 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.js +443 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai-coding-cn.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +7 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +5 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/mux.d.ts +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/mux.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/mux.js +2 -2
- package/node_modules/@earendil-works/pi-tui/dist/mux.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +19 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { rm } from "node:fs/promises";
|
|
1
3
|
import { executeBashWithOperations } from "../../core/bash-executor.js";
|
|
2
4
|
import { SessionManager } from "../../core/session-manager.js";
|
|
3
5
|
import { SettingsManager } from "../../core/settings-manager.js";
|
|
@@ -27,6 +29,14 @@ export async function createInteractiveHostRuntime(localRuntime, options) {
|
|
|
27
29
|
thinkingLevel: localRuntime.session.thinkingLevel,
|
|
28
30
|
});
|
|
29
31
|
const remoteSession = createRemoteSessionProxy(localRuntime.session, localRuntime.services.agentDir, client, opened.state, options.onWarning);
|
|
32
|
+
if (opened.state.isBashRunning && !opened.attached) {
|
|
33
|
+
// Only a newly opened session can have an execution orphaned by a
|
|
34
|
+
// previous connection. An attach is an observer of the same live runtime;
|
|
35
|
+
// aborting it would cancel work owned by the surviving attachment.
|
|
36
|
+
await client.abortBash().catch(() => { });
|
|
37
|
+
}
|
|
38
|
+
if (opened.attached)
|
|
39
|
+
await remoteSession.refresh();
|
|
30
40
|
return new RemoteInteractiveRuntime(localRuntime, remoteSession, client);
|
|
31
41
|
}
|
|
32
42
|
catch (cause) {
|
|
@@ -39,7 +49,7 @@ export async function createInteractiveHostRuntime(localRuntime, options) {
|
|
|
39
49
|
return localRuntime;
|
|
40
50
|
}
|
|
41
51
|
}
|
|
42
|
-
class RemoteInteractiveRuntime {
|
|
52
|
+
export class RemoteInteractiveRuntime {
|
|
43
53
|
#local;
|
|
44
54
|
#remoteSession;
|
|
45
55
|
#client;
|
|
@@ -74,71 +84,104 @@ class RemoteInteractiveRuntime {
|
|
|
74
84
|
setRebindSession(callback) {
|
|
75
85
|
this.#rebindSession = callback;
|
|
76
86
|
}
|
|
87
|
+
setHostUiHandler(callback) {
|
|
88
|
+
this.#remoteSession.setHostUiHandler(callback);
|
|
89
|
+
}
|
|
77
90
|
async dispose() {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
91
|
+
const errors = [];
|
|
92
|
+
for (const cleanup of [
|
|
93
|
+
() => this.#remoteSession.abortLocalBash(),
|
|
94
|
+
() => this.#client.closeSession(),
|
|
95
|
+
() => this.#client.stop(),
|
|
96
|
+
() => this.#local.dispose(),
|
|
97
|
+
]) {
|
|
98
|
+
try {
|
|
99
|
+
await cleanup();
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
errors.push(error);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (errors.length > 0)
|
|
106
|
+
throw errors[0];
|
|
81
107
|
}
|
|
82
108
|
async newSession(options) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
await this.#client.appendSessionEntry(entry);
|
|
109
|
+
// Suppresses for the ENTIRE command, not just the refresh tail: a
|
|
110
|
+
// multi-session host emits session_replaced while completing it, so the echo
|
|
111
|
+
// can arrive before the refresh/rebind sequence below starts and race it -
|
|
112
|
+
// newSession transports setup entries between two refreshes.
|
|
113
|
+
return this.#remoteSession.aroundLocalReplacement(async () => {
|
|
114
|
+
const result = await this.#client.newSession(options?.parentSession);
|
|
115
|
+
if (!result.cancelled) {
|
|
116
|
+
this.#beforeSessionInvalidate?.();
|
|
117
|
+
this.#remoteSession.abortLocalBash();
|
|
93
118
|
await this.#remoteSession.refresh();
|
|
119
|
+
if (options?.setup) {
|
|
120
|
+
const capture = SessionManager.inMemory(this.#remoteSession.session.sessionManager.getCwd());
|
|
121
|
+
await options.setup(capture);
|
|
122
|
+
for (const entry of capture.getEntries())
|
|
123
|
+
await this.#client.appendSessionEntry(entry);
|
|
124
|
+
await this.#remoteSession.refresh();
|
|
125
|
+
}
|
|
126
|
+
await this.#rebindSession?.();
|
|
127
|
+
if (options?.withSession)
|
|
128
|
+
await options.withSession(this.#remoteSession.createReplacedSessionContext());
|
|
94
129
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
await options.withSession(this.#remoteSession.createReplacedSessionContext());
|
|
98
|
-
}
|
|
99
|
-
return result;
|
|
130
|
+
return result;
|
|
131
|
+
});
|
|
100
132
|
}
|
|
101
133
|
async switchSession(sessionPath, options) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
this.#
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
134
|
+
// See newSession: the suppression must cover the command itself, since the
|
|
135
|
+
// host emits session_replaced while completing it.
|
|
136
|
+
return this.#remoteSession.aroundLocalReplacement(async () => {
|
|
137
|
+
const result = await this.#client.switchSession(sessionPath, options?.cwdOverride === undefined ? undefined : { cwdOverride: options.cwdOverride });
|
|
138
|
+
if (!result.cancelled) {
|
|
139
|
+
this.#beforeSessionInvalidate?.();
|
|
140
|
+
this.#remoteSession.abortLocalBash();
|
|
141
|
+
await this.#remoteSession.refresh();
|
|
142
|
+
await this.#rebindSession?.();
|
|
143
|
+
// The shared host already resolved trust; this callback is retained for
|
|
144
|
+
// compatibility, but its result cannot override host-authoritative state.
|
|
145
|
+
options?.projectTrustContextFactory?.(this.#remoteSession.session.sessionManager.getCwd());
|
|
146
|
+
if (options?.withSession)
|
|
147
|
+
await options.withSession(this.#remoteSession.createReplacedSessionContext());
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
150
|
+
});
|
|
115
151
|
}
|
|
116
152
|
async fork(entryId, options) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
this.#
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
await
|
|
124
|
-
|
|
125
|
-
|
|
153
|
+
// See newSession: the suppression must cover the command itself.
|
|
154
|
+
return this.#remoteSession.aroundLocalReplacement(async () => {
|
|
155
|
+
const result = await this.#client.fork(entryId, options);
|
|
156
|
+
if (!result.cancelled) {
|
|
157
|
+
this.#beforeSessionInvalidate?.();
|
|
158
|
+
this.#remoteSession.abortLocalBash();
|
|
159
|
+
await this.#refreshAndRebind();
|
|
160
|
+
if (options?.withSession)
|
|
161
|
+
await options.withSession(this.#remoteSession.createReplacedSessionContext());
|
|
162
|
+
}
|
|
163
|
+
return { cancelled: result.cancelled, selectedText: result.text };
|
|
164
|
+
});
|
|
126
165
|
}
|
|
127
166
|
async importFromJsonl(inputPath, cwdOverride) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
this.#
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
167
|
+
// See newSession: the suppression must cover the command itself.
|
|
168
|
+
return this.#remoteSession.aroundLocalReplacement(async () => {
|
|
169
|
+
const result = await this.#client.importJsonl(inputPath, cwdOverride);
|
|
170
|
+
if (!result.cancelled) {
|
|
171
|
+
this.#beforeSessionInvalidate?.();
|
|
172
|
+
this.#remoteSession.abortLocalBash();
|
|
173
|
+
await this.#refreshAndRebind();
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
176
|
+
});
|
|
135
177
|
}
|
|
136
178
|
async #refreshAndRebind() {
|
|
137
179
|
await this.#remoteSession.refresh();
|
|
138
180
|
await this.#rebindSession?.();
|
|
139
181
|
}
|
|
140
182
|
}
|
|
141
|
-
|
|
183
|
+
/** Exported for direct coverage of the wire-event handling below. */
|
|
184
|
+
export function createRemoteSessionProxy(local, agentDir, client, initialState, onWarning) {
|
|
142
185
|
// Fire-and-forget setters keep the sync AgentSession signature, but their RPC
|
|
143
186
|
// failures must not vanish: the matching *_changed wire event confirms success,
|
|
144
187
|
// and a rejection here is the only signal of failure.
|
|
@@ -150,10 +193,65 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
150
193
|
});
|
|
151
194
|
};
|
|
152
195
|
let state = { ...initialState };
|
|
153
|
-
|
|
196
|
+
const waitForBashCallbacks = async (promises, allowAbandonment) => {
|
|
197
|
+
if (promises.size === 0)
|
|
198
|
+
return true;
|
|
199
|
+
const settled = Promise.allSettled([...promises]).then(() => true);
|
|
200
|
+
let timeout;
|
|
201
|
+
const bounded = new Promise((resolve) => {
|
|
202
|
+
timeout = setTimeout(resolve, allowAbandonment ? 100 : 5_000, false);
|
|
203
|
+
timeout.unref?.();
|
|
204
|
+
});
|
|
205
|
+
try {
|
|
206
|
+
return await Promise.race([settled, bounded]);
|
|
207
|
+
}
|
|
208
|
+
finally {
|
|
209
|
+
if (timeout)
|
|
210
|
+
clearTimeout(timeout);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
const executionNamespace = randomUUID();
|
|
214
|
+
const cleanupRemoteBashOutput = async (path) => {
|
|
215
|
+
let cleanupTimeout;
|
|
216
|
+
try {
|
|
217
|
+
await Promise.race([
|
|
218
|
+
client.cleanupBashOutput(path),
|
|
219
|
+
new Promise((_, reject) => {
|
|
220
|
+
cleanupTimeout = setTimeout(() => reject(new Error("RPC cleanup timed out")), 1_000);
|
|
221
|
+
}),
|
|
222
|
+
]);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
catch (transportError) {
|
|
226
|
+
// Spill paths are shared host filesystem paths. If the RPC transport is
|
|
227
|
+
// already unavailable, remove locally as a bounded best-effort fallback;
|
|
228
|
+
// a later reconnect is not required to prevent this callback failure from
|
|
229
|
+
// permanently leaking the host-owned artifact.
|
|
230
|
+
try {
|
|
231
|
+
await rm(path, { force: true });
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
catch (localError) {
|
|
235
|
+
onWarning?.({
|
|
236
|
+
type: "interactive_host_action_failed",
|
|
237
|
+
message: `Warning: failed to clean up shared bash output spill: ${localError instanceof Error ? localError.message : String(localError)}`,
|
|
238
|
+
cause: new AggregateError([transportError, localError]),
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
finally {
|
|
243
|
+
if (cleanupTimeout)
|
|
244
|
+
clearTimeout(cleanupTimeout);
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
let nextBashExecutionId = 0;
|
|
248
|
+
const bashExecutions = new Map();
|
|
249
|
+
let hostUiHandler;
|
|
250
|
+
const pendingUiRequests = [];
|
|
154
251
|
let localBashAbortController;
|
|
155
252
|
let localBashRunning = false;
|
|
156
253
|
let hostBashRunning = initialState.isBashRunning;
|
|
254
|
+
let nextQueuedInputOrder = Math.max(0, ...initialState.ordered.map((item) => item.enqueueOrder));
|
|
157
255
|
let sessionManager = local.sessionManager;
|
|
158
256
|
let settingsManager = SettingsManager.create(initialState.cwd, agentDir, {
|
|
159
257
|
projectTrusted: initialState.projectTrusted,
|
|
@@ -166,6 +264,8 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
166
264
|
if (property === "appendLabelChange") {
|
|
167
265
|
return (entryId, label) => void client.setLabel(entryId, label);
|
|
168
266
|
}
|
|
267
|
+
if (property === "getCwd")
|
|
268
|
+
return () => state.cwd;
|
|
169
269
|
if (property === "getSessionName")
|
|
170
270
|
return () => state.sessionName;
|
|
171
271
|
if (property === "getUsageTotals")
|
|
@@ -176,8 +276,36 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
176
276
|
});
|
|
177
277
|
let streamingAssistant;
|
|
178
278
|
let mirroredCurrentAssistantUsage = false;
|
|
279
|
+
/** Non-zero while this runtime is driving its own replacement sequence. */
|
|
280
|
+
let localReplacementDepth = 0;
|
|
179
281
|
const listeners = new Set();
|
|
180
282
|
client.onEvent((wireEvent) => {
|
|
283
|
+
if (wireEvent.type === "extension_ui_request") {
|
|
284
|
+
const request = wireEvent;
|
|
285
|
+
if (hostUiHandler)
|
|
286
|
+
void Promise.resolve(hostUiHandler(request)).then((response) => response && client.sendExtensionUIResponse(response));
|
|
287
|
+
else
|
|
288
|
+
pendingUiRequests.push(request);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (wireEvent.type === "session_replaced") {
|
|
292
|
+
// The host swapped the live session behind this connection - another
|
|
293
|
+
// attached client issued the replacement, or an extension drove one that no
|
|
294
|
+
// client issued. Nothing else re-reads the binding, so without this the
|
|
295
|
+
// proxy keeps serving the previous session's manager, settings and message
|
|
296
|
+
// mirror while the host has already moved on. The command response carries
|
|
297
|
+
// only `{ cancelled }`, so this event is the only signal available here.
|
|
298
|
+
//
|
|
299
|
+
// A multi-session host broadcasts the event to every connection including
|
|
300
|
+
// the one that issued the replacement, and this runtime's own replacement
|
|
301
|
+
// methods already run an ordered refresh/rebind - newSession additionally
|
|
302
|
+
// transports setup entries between two refreshes. Refreshing again from
|
|
303
|
+
// here would race that sequence, so self-driven replacements are skipped.
|
|
304
|
+
if (localReplacementDepth === 0) {
|
|
305
|
+
void refresh().catch(reportActionFailure("session refresh after replacement"));
|
|
306
|
+
}
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
181
309
|
if (wireEvent.type === "agent_settled")
|
|
182
310
|
state = { ...state, isStreaming: false, retryAttempt: 0 };
|
|
183
311
|
if (wireEvent.type === "bash_start") {
|
|
@@ -188,8 +316,30 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
188
316
|
hostBashRunning = false;
|
|
189
317
|
updateBashState();
|
|
190
318
|
}
|
|
191
|
-
if (wireEvent.type === "bash_execution_update")
|
|
192
|
-
|
|
319
|
+
if (wireEvent.type === "bash_execution_update" && wireEvent.id) {
|
|
320
|
+
const execution = bashExecutions.get(wireEvent.id);
|
|
321
|
+
if (execution?.chunk && !execution.hasError) {
|
|
322
|
+
try {
|
|
323
|
+
const callbackPromise = Promise.resolve(execution.chunk(wireEvent.delta)).catch((error) => {
|
|
324
|
+
if (!execution.hasError) {
|
|
325
|
+
execution.error = error;
|
|
326
|
+
execution.hasError = true;
|
|
327
|
+
void client.abortBash().catch(() => { });
|
|
328
|
+
}
|
|
329
|
+
throw error;
|
|
330
|
+
});
|
|
331
|
+
execution.promises.add(callbackPromise);
|
|
332
|
+
void callbackPromise.catch(() => { }).finally(() => execution.promises.delete(callbackPromise));
|
|
333
|
+
}
|
|
334
|
+
catch (error) {
|
|
335
|
+
if (!execution.hasError) {
|
|
336
|
+
execution.error = error;
|
|
337
|
+
execution.hasError = true;
|
|
338
|
+
void client.abortBash().catch(() => { });
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
193
343
|
if (wireEvent.type === "agent_start")
|
|
194
344
|
state = { ...state, isStreaming: true };
|
|
195
345
|
if (wireEvent.type === "compaction_start")
|
|
@@ -201,6 +351,7 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
201
351
|
if (wireEvent.type === "auto_retry_end")
|
|
202
352
|
state = { ...state, retryAttempt: 0 };
|
|
203
353
|
if (wireEvent.type === "queue_update") {
|
|
354
|
+
nextQueuedInputOrder = Math.max(nextQueuedInputOrder, ...wireEvent.ordered.map((item) => item.enqueueOrder));
|
|
204
355
|
state = {
|
|
205
356
|
...state,
|
|
206
357
|
steering: [...wireEvent.steering],
|
|
@@ -217,6 +368,23 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
217
368
|
if (wireEvent.type === "service_tier_changed") {
|
|
218
369
|
state = { ...state, serviceTier: wireEvent.tier, fastMode: wireEvent.fastMode };
|
|
219
370
|
}
|
|
371
|
+
if (wireEvent.type === "session_settings_changed") {
|
|
372
|
+
state = {
|
|
373
|
+
...state,
|
|
374
|
+
steeringMode: wireEvent.steeringMode,
|
|
375
|
+
followUpMode: wireEvent.followUpMode,
|
|
376
|
+
autoCompactionEnabled: wireEvent.autoCompactionEnabled,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
if (wireEvent.type === "entry_appended") {
|
|
380
|
+
try {
|
|
381
|
+
sessionManager.appendEntry(wireEvent.entry);
|
|
382
|
+
local.agent.state.messages = sessionManager.buildSessionContext().messages;
|
|
383
|
+
}
|
|
384
|
+
catch {
|
|
385
|
+
// Non-fatal if the local snapshot cannot accept a concurrent entry.
|
|
386
|
+
}
|
|
387
|
+
}
|
|
220
388
|
if (wireEvent.type === "session_info_changed")
|
|
221
389
|
state = { ...state, sessionName: wireEvent.name };
|
|
222
390
|
if (wireEvent.type === "message_start") {
|
|
@@ -233,8 +401,13 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
233
401
|
if (usage && !mirroredCurrentAssistantUsage) {
|
|
234
402
|
mirroredCurrentAssistantUsage = true;
|
|
235
403
|
const latestPromptTokens = usage.input + usage.cacheRead + usage.cacheWrite;
|
|
404
|
+
const contextWindow = state.model?.contextWindow ?? 0;
|
|
405
|
+
const contextTokens = usage.input + usage.cacheRead + usage.cacheWrite;
|
|
236
406
|
state = {
|
|
237
407
|
...state,
|
|
408
|
+
contextUsage: contextWindow > 0
|
|
409
|
+
? { tokens: contextTokens, contextWindow, percent: (contextTokens / contextWindow) * 100 }
|
|
410
|
+
: undefined,
|
|
238
411
|
usageTotals: {
|
|
239
412
|
...state.usageTotals,
|
|
240
413
|
input: state.usageTotals.input + usage.input,
|
|
@@ -254,7 +427,9 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
254
427
|
}
|
|
255
428
|
if (wireEvent.type === "compaction_end" && wireEvent.accepted && !wireEvent.aborted) {
|
|
256
429
|
try {
|
|
257
|
-
sessionManager.reloadFromDisk?.();
|
|
430
|
+
local.sessionManager.reloadFromDisk?.();
|
|
431
|
+
if (sessionManager !== local.sessionManager)
|
|
432
|
+
sessionManager.reloadFromDisk?.();
|
|
258
433
|
local.agent.state.messages = sessionManager.buildSessionContext().messages;
|
|
259
434
|
}
|
|
260
435
|
catch {
|
|
@@ -265,17 +440,26 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
265
440
|
for (const listener of listeners)
|
|
266
441
|
listener(event);
|
|
267
442
|
});
|
|
268
|
-
const
|
|
443
|
+
const performRefresh = async () => {
|
|
269
444
|
const nextState = await client.getState();
|
|
270
445
|
state = { ...stateFromRpc(nextState) };
|
|
446
|
+
nextQueuedInputOrder = Math.max(0, ...nextState.ordered.map((item) => item.enqueueOrder));
|
|
271
447
|
let messages;
|
|
272
448
|
settingsManager = SettingsManager.create(nextState.cwd, agentDir, {
|
|
273
449
|
projectTrusted: nextState.projectTrusted,
|
|
274
450
|
});
|
|
275
451
|
if (nextState.sessionFile) {
|
|
276
|
-
//
|
|
277
|
-
//
|
|
278
|
-
|
|
452
|
+
// Keep the caller-owned manager identity when refreshing the same session.
|
|
453
|
+
// Navigation and host-side mutations must update every existing mirror, not
|
|
454
|
+
// leave the interactive runtime holding the pre-refresh snapshot.
|
|
455
|
+
if (sessionManager.getSessionFile() === nextState.sessionFile) {
|
|
456
|
+
sessionManager.reloadFromDisk?.();
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
// SessionManager.open retains the explicit path even when the host has
|
|
460
|
+
// deferred creating the file for a setup-only session.
|
|
461
|
+
sessionManager = SessionManager.open(nextState.sessionFile, undefined, nextState.cwd);
|
|
462
|
+
}
|
|
279
463
|
if (nextState.entries?.length && !sessionManager.getEntries().length) {
|
|
280
464
|
for (const entry of nextState.entries)
|
|
281
465
|
sessionManager.appendEntry(entry);
|
|
@@ -288,6 +472,16 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
288
472
|
local.agent.state.messages.splice(0, local.agent.state.messages.length, ...structuredClone(messages));
|
|
289
473
|
streamingAssistant = undefined;
|
|
290
474
|
};
|
|
475
|
+
// Refreshes must not interleave: each one reassigns sessionManager,
|
|
476
|
+
// settingsManager and the mirrored message list, so two in flight can commit a
|
|
477
|
+
// mixed snapshot of two different sessions. A replacement-driven refresh races
|
|
478
|
+
// exactly that way against a caller-driven one, so run them in order.
|
|
479
|
+
let refreshChain = Promise.resolve();
|
|
480
|
+
const refresh = () => {
|
|
481
|
+
const next = refreshChain.then(performRefresh, performRefresh);
|
|
482
|
+
refreshChain = next.then(() => { }, () => { });
|
|
483
|
+
return next;
|
|
484
|
+
};
|
|
291
485
|
const session = new Proxy(local, {
|
|
292
486
|
get(target, property, receiver) {
|
|
293
487
|
if (property === "prompt")
|
|
@@ -295,6 +489,12 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
295
489
|
...(options?.images ? { images: options.images } : {}),
|
|
296
490
|
...(options?.streamingBehavior ? { streamingBehavior: options.streamingBehavior } : {}),
|
|
297
491
|
...(options?.thinkingLevel ? { thinkingLevel: options.thinkingLevel } : {}),
|
|
492
|
+
...(options?.sessionTitlePrompt !== undefined
|
|
493
|
+
? { sessionTitlePrompt: options.sessionTitlePrompt }
|
|
494
|
+
: {}),
|
|
495
|
+
...(options?.expandPromptTemplates !== undefined
|
|
496
|
+
? { expandPromptTemplates: options.expandPromptTemplates }
|
|
497
|
+
: {}),
|
|
298
498
|
...(options?.promptDisposition ? { promptDisposition: options.promptDisposition } : {}),
|
|
299
499
|
...(options?.preflightResult ? { preflightResult: options.preflightResult } : {}),
|
|
300
500
|
});
|
|
@@ -328,13 +528,35 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
328
528
|
return () => client.waitForIdle();
|
|
329
529
|
if (property === "getLastAssistantText")
|
|
330
530
|
return () => target.getLastAssistantText();
|
|
331
|
-
if (property === "setModel")
|
|
531
|
+
if (property === "setModel" || property === "setSessionModel")
|
|
332
532
|
return async (model) => {
|
|
333
533
|
const next = await client.setModel(model.provider, model.id);
|
|
334
534
|
return { systemPromptName: next.systemPromptName, model: next };
|
|
335
535
|
};
|
|
536
|
+
if (property === "setSessionThinkingLevel")
|
|
537
|
+
return (level) => void client
|
|
538
|
+
.setThinkingLevel(level, { scope: "turn" })
|
|
539
|
+
.catch(reportActionFailure("setSessionThinkingLevel"));
|
|
540
|
+
if (property === "setSessionFastMode")
|
|
541
|
+
return (enabled) => void client.setFastMode(enabled).catch(reportActionFailure("setSessionFastMode"));
|
|
542
|
+
if (property === "abortRetry")
|
|
543
|
+
return () => void client.abortRetry().catch(reportActionFailure("abortRetry"));
|
|
544
|
+
if (property === "setAutoRetryEnabled")
|
|
545
|
+
return (enabled) => void client.setAutoRetry(enabled).catch(reportActionFailure("setAutoRetryEnabled"));
|
|
546
|
+
if (property === "reserveQueuedInputOrder")
|
|
547
|
+
return () => ++nextQueuedInputOrder;
|
|
548
|
+
if (property === "setFavoriteModels")
|
|
549
|
+
return (models) => {
|
|
550
|
+
state = { ...state, favoriteModels: [...models] };
|
|
551
|
+
void client.setFavoriteModels(models).catch(reportActionFailure("setFavoriteModels"));
|
|
552
|
+
};
|
|
553
|
+
if (property === "setScopedModels")
|
|
554
|
+
return (models) => {
|
|
555
|
+
state = { ...state, scopedModels: [...models] };
|
|
556
|
+
void client.setScopedModels(models).catch(reportActionFailure("setScopedModels"));
|
|
557
|
+
};
|
|
336
558
|
if (property === "cycleModel")
|
|
337
|
-
return () => client.cycleModel();
|
|
559
|
+
return (direction) => client.cycleModel(direction);
|
|
338
560
|
if (property === "setThinkingLevel")
|
|
339
561
|
return (level) => void client.setThinkingLevel(level).catch(reportActionFailure("setThinkingLevel"));
|
|
340
562
|
if (property === "cycleThinkingLevel")
|
|
@@ -372,15 +594,35 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
372
594
|
updateBashState();
|
|
373
595
|
}
|
|
374
596
|
}
|
|
375
|
-
|
|
597
|
+
const executionId = `bash-${executionNamespace}-${++nextBashExecutionId}`;
|
|
598
|
+
const execution = {
|
|
599
|
+
chunk: onChunk,
|
|
600
|
+
promises: new Set(),
|
|
601
|
+
error: undefined,
|
|
602
|
+
hasError: false,
|
|
603
|
+
};
|
|
604
|
+
bashExecutions.set(executionId, execution);
|
|
376
605
|
try {
|
|
377
|
-
|
|
606
|
+
const result = await client.bash(command, {
|
|
378
607
|
excludeFromContext: options?.excludeFromContext,
|
|
608
|
+
executionId,
|
|
379
609
|
operations: options?.operations,
|
|
380
610
|
});
|
|
611
|
+
const callbacksSettled = await waitForBashCallbacks(execution.promises, false);
|
|
612
|
+
if (!callbacksSettled) {
|
|
613
|
+
if (result.fullOutputPath)
|
|
614
|
+
await cleanupRemoteBashOutput(result.fullOutputPath);
|
|
615
|
+
throw new Error("Bash output callback did not settle within 5000ms");
|
|
616
|
+
}
|
|
617
|
+
if (execution.hasError) {
|
|
618
|
+
if (result.fullOutputPath)
|
|
619
|
+
await cleanupRemoteBashOutput(result.fullOutputPath);
|
|
620
|
+
throw execution.error;
|
|
621
|
+
}
|
|
622
|
+
return result;
|
|
381
623
|
}
|
|
382
624
|
finally {
|
|
383
|
-
|
|
625
|
+
bashExecutions.delete(executionId);
|
|
384
626
|
}
|
|
385
627
|
};
|
|
386
628
|
if (property === "abortBash")
|
|
@@ -390,10 +632,12 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
390
632
|
else
|
|
391
633
|
void client.abortBash().catch(reportActionFailure("abortBash"));
|
|
392
634
|
};
|
|
635
|
+
if (property === "getContextUsage")
|
|
636
|
+
return () => state.contextUsage;
|
|
393
637
|
if (property === "getSessionStats")
|
|
394
638
|
return () => client.getSessionStats();
|
|
395
639
|
if (property === "exportToHtml")
|
|
396
|
-
return (outputPath) => client.exportHtml(outputPath).then((result) => result.path);
|
|
640
|
+
return (outputPath, options) => client.exportHtml(outputPath, options?.themeName).then((result) => result.path);
|
|
397
641
|
if (property === "setSessionName")
|
|
398
642
|
return (name) => client.setSessionName(name).catch(reportActionFailure("setSessionName"));
|
|
399
643
|
if (property === "navigateTree")
|
|
@@ -416,10 +660,10 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
416
660
|
};
|
|
417
661
|
if (property === "isStreaming")
|
|
418
662
|
return state.isStreaming;
|
|
663
|
+
if (property === "isIdle")
|
|
664
|
+
return !state.isStreaming;
|
|
419
665
|
if (property === "isCompacting")
|
|
420
666
|
return state.isCompacting;
|
|
421
|
-
if (property === "isFastModeActive")
|
|
422
|
-
return () => state.fastMode;
|
|
423
667
|
if (property === "pendingMessageCount")
|
|
424
668
|
return state.pendingMessageCount;
|
|
425
669
|
if (property === "getSteeringMessages")
|
|
@@ -475,12 +719,24 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
475
719
|
return state.sessionName;
|
|
476
720
|
if (property === "serviceTier")
|
|
477
721
|
return state.serviceTier;
|
|
722
|
+
if (property === "steeringMode")
|
|
723
|
+
return state.steeringMode;
|
|
724
|
+
if (property === "followUpMode")
|
|
725
|
+
return state.followUpMode;
|
|
726
|
+
if (property === "autoCompactionEnabled")
|
|
727
|
+
return state.autoCompactionEnabled;
|
|
728
|
+
if (property === "isFastModeActive")
|
|
729
|
+
return () => state.fastMode;
|
|
478
730
|
if (property === "sessionManager")
|
|
479
731
|
return remoteSessionManager;
|
|
480
732
|
if (property === "settingsManager")
|
|
481
733
|
return settingsManager;
|
|
482
734
|
if (property === "messages")
|
|
483
735
|
return target.messages;
|
|
736
|
+
if (property === "favoriteModels")
|
|
737
|
+
return state.favoriteModels;
|
|
738
|
+
if (property === "scopedModels")
|
|
739
|
+
return state.scopedModels;
|
|
484
740
|
if (property === "model")
|
|
485
741
|
return state.model ?? target.model;
|
|
486
742
|
if (property === "thinkingLevel")
|
|
@@ -490,7 +746,22 @@ function createRemoteSessionProxy(local, agentDir, client, initialState, onWarni
|
|
|
490
746
|
});
|
|
491
747
|
return {
|
|
492
748
|
session,
|
|
749
|
+
setHostUiHandler: (callback) => {
|
|
750
|
+
hostUiHandler = callback;
|
|
751
|
+
if (callback)
|
|
752
|
+
for (const request of pendingUiRequests.splice(0))
|
|
753
|
+
void Promise.resolve(callback(request)).then((response) => response && client.sendExtensionUIResponse(response));
|
|
754
|
+
},
|
|
493
755
|
refresh,
|
|
756
|
+
aroundLocalReplacement: async (body) => {
|
|
757
|
+
localReplacementDepth++;
|
|
758
|
+
try {
|
|
759
|
+
return await body();
|
|
760
|
+
}
|
|
761
|
+
finally {
|
|
762
|
+
localReplacementDepth--;
|
|
763
|
+
}
|
|
764
|
+
},
|
|
494
765
|
abortLocalBash: () => localBashAbortController?.abort(),
|
|
495
766
|
createReplacedSessionContext: () => {
|
|
496
767
|
const context = local.createReplacedSessionContext();
|