@code-yeongyu/senpi 2026.7.25-2 → 2026.7.26
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 +52 -0
- package/README.md +1 -1
- package/dist/cli/args.d.ts +4 -16
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +9 -25
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/grok-neo-gate.d.ts +12 -0
- package/dist/cli/grok-neo-gate.d.ts.map +1 -0
- package/dist/cli/grok-neo-gate.js +18 -0
- package/dist/cli/grok-neo-gate.js.map +1 -0
- package/dist/cli-main.js +4 -0
- package/dist/cli-main.js.map +1 -1
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +2 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +33 -8
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts +9 -3
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +179 -57
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-providers.d.ts +2 -2
- package/dist/core/auth-providers.js +2 -2
- package/dist/core/auth-providers.js.map +1 -1
- package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts.map +1 -1
- package/dist/core/extensions/builtin/bash-timeout/timeout.js +3 -2
- package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +30 -2
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.js +28 -0
- package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
- package/dist/core/extensions/builtin/goal/command-registration.js +2 -2
- package/dist/core/extensions/builtin/goal/command-registration.js.map +1 -1
- package/dist/core/extensions/builtin/goal/format.d.ts +1 -1
- package/dist/core/extensions/builtin/goal/format.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/format.js +9 -2
- package/dist/core/extensions/builtin/goal/format.js.map +1 -1
- package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/index.js +38 -23
- package/dist/core/extensions/builtin/goal/index.js.map +1 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts +6 -0
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +19 -0
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -0
- package/dist/core/extensions/builtin/goal/persistence.d.ts +6 -0
- package/dist/core/extensions/builtin/goal/persistence.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/persistence.js +141 -0
- package/dist/core/extensions/builtin/goal/persistence.js.map +1 -0
- package/dist/core/extensions/builtin/goal/store.d.ts +7 -3
- package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/store.js +66 -181
- package/dist/core/extensions/builtin/goal/store.js.map +1 -1
- package/dist/core/extensions/builtin/goal/tool-registration.d.ts +1 -0
- package/dist/core/extensions/builtin/goal/tool-registration.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/tool-registration.js +26 -15
- package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
- package/dist/core/extensions/builtin/goal/transitions.d.ts +3 -0
- package/dist/core/extensions/builtin/goal/transitions.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/transitions.js +45 -0
- package/dist/core/extensions/builtin/goal/transitions.js.map +1 -0
- package/dist/core/extensions/builtin/goal/types.d.ts +10 -4
- package/dist/core/extensions/builtin/goal/types.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/types.js +2 -2
- package/dist/core/extensions/builtin/goal/types.js.map +1 -1
- package/dist/core/extensions/builtin/goal/ui.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/ui.js +2 -0
- package/dist/core/extensions/builtin/goal/ui.js.map +1 -1
- package/dist/core/extensions/builtin/goal/validation.d.ts +8 -1
- package/dist/core/extensions/builtin/goal/validation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/validation.js +24 -12
- package/dist/core/extensions/builtin/goal/validation.js.map +1 -1
- package/dist/core/extensions/builtin/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/index.js +0 -2
- package/dist/core/extensions/builtin/index.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/index.js +8 -5
- package/dist/core/extensions/builtin/mcp/index.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 +1 -0
- package/dist/core/extensions/builtin/permission-system/parsers.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.js +32 -0
- package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/index.d.ts +1 -1
- package/dist/core/extensions/builtin/terminal/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/index.js +1 -1
- package/dist/core/extensions/builtin/terminal/index.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts +29 -0
- package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/monitor-notify.js +185 -0
- package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +35 -0
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/monitor-registry.js +98 -0
- package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/notify.d.ts +9 -0
- package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/notify.js +30 -14
- package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/prompt.d.ts +1 -1
- package/dist/core/extensions/builtin/terminal/prompt.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/prompt.js +13 -5
- package/dist/core/extensions/builtin/terminal/prompt.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +3 -12
- package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/runtime-session.js +4 -59
- package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/settings.d.ts +8 -0
- package/dist/core/extensions/builtin/terminal/settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/settings.js +16 -2
- package/dist/core/extensions/builtin/terminal/settings.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/shared.d.ts +2 -2
- package/dist/core/extensions/builtin/terminal/shared.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/shared.js +2 -1
- package/dist/core/extensions/builtin/terminal/shared.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts +10 -4
- package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/bash-output.js +17 -96
- package/dist/core/extensions/builtin/terminal/tools/bash-output.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/context.d.ts +7 -0
- package/dist/core/extensions/builtin/terminal/tools/context.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/context.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts +41 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor.js +97 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/tools/render.d.ts +3 -0
- package/dist/core/extensions/builtin/terminal/tools/render.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/render.js +5 -2
- package/dist/core/extensions/builtin/terminal/tools/render.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/fuzzy-match.d.ts +19 -0
- package/dist/core/extensions/builtin/todotools/fuzzy-match.d.ts.map +1 -0
- package/dist/core/extensions/builtin/todotools/fuzzy-match.js +70 -0
- package/dist/core/extensions/builtin/todotools/fuzzy-match.js.map +1 -0
- package/dist/core/extensions/builtin/todotools/normalize.d.ts +8 -0
- package/dist/core/extensions/builtin/todotools/normalize.d.ts.map +1 -0
- package/dist/core/extensions/builtin/todotools/normalize.js +174 -0
- package/dist/core/extensions/builtin/todotools/normalize.js.map +1 -0
- package/dist/core/extensions/builtin/todotools/prompt.d.ts +2 -2
- package/dist/core/extensions/builtin/todotools/prompt.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/prompt.js +4 -2
- package/dist/core/extensions/builtin/todotools/prompt.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/state.d.ts +9 -8
- package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/state.js +99 -48
- package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/tools/todo.d.ts +1 -1
- package/dist/core/extensions/builtin/todotools/tools/todo.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/tools/todo.js +65 -38
- package/dist/core/extensions/builtin/todotools/tools/todo.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +12 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +5 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +12 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +23 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts +0 -5
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +0 -2
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/messages.d.ts +32 -0
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +91 -0
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-resolver.d.ts +9 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- 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 +4 -3
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/resource-loader.d.ts +9 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +10 -2
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/retry-fallback/cooldown.d.ts.map +1 -1
- package/dist/core/retry-fallback/cooldown.js +5 -0
- package/dist/core/retry-fallback/cooldown.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +11 -35
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.d.ts +5 -16
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +0 -13
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/timings.d.ts +7 -2
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +11 -0
- package/dist/core/timings.js.map +1 -1
- package/dist/inspector-policy.d.ts +22 -0
- package/dist/inspector-policy.d.ts.map +1 -0
- package/dist/inspector-policy.js +84 -0
- package/dist/inspector-policy.js.map +1 -0
- package/dist/main.d.ts +6 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +20 -23
- package/dist/main.js.map +1 -1
- package/dist/modes/app-server/runtime.d.ts.map +1 -1
- package/dist/modes/app-server/runtime.js +1 -0
- package/dist/modes/app-server/runtime.js.map +1 -1
- package/dist/modes/app-server/threads/goal-handlers.js +4 -2
- package/dist/modes/app-server/threads/goal-handlers.js.map +1 -1
- package/dist/modes/app-server/threads/goal-wire.d.ts.map +1 -1
- package/dist/modes/app-server/threads/goal-wire.js +1 -0
- package/dist/modes/app-server/threads/goal-wire.js.map +1 -1
- package/dist/modes/app-server/threads/handlers.d.ts +1 -0
- package/dist/modes/app-server/threads/handlers.d.ts.map +1 -1
- package/dist/modes/app-server/threads/handlers.js +2 -0
- package/dist/modes/app-server/threads/handlers.js.map +1 -1
- package/dist/modes/app-server/threads/turn-runtime.d.ts +1 -0
- package/dist/modes/app-server/threads/turn-runtime.d.ts.map +1 -1
- package/dist/modes/app-server/threads/turn-runtime.js.map +1 -1
- package/dist/modes/app-server/threads/turns.d.ts.map +1 -1
- package/dist/modes/app-server/threads/turns.js +47 -3
- package/dist/modes/app-server/threads/turns.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts +1 -0
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js +29 -4
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +5 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +43 -17
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/grok/chrome-tokens.d.ts +22 -0
- package/dist/modes/interactive/grok/chrome-tokens.d.ts.map +1 -0
- package/dist/modes/interactive/grok/chrome-tokens.js +27 -0
- package/dist/modes/interactive/grok/chrome-tokens.js.map +1 -0
- package/dist/modes/interactive/grok/chrome.d.ts +51 -0
- package/dist/modes/interactive/grok/chrome.d.ts.map +1 -0
- package/dist/modes/interactive/grok/chrome.js +105 -0
- package/dist/modes/interactive/grok/chrome.js.map +1 -0
- package/dist/modes/interactive/grok/footer.d.ts +14 -0
- package/dist/modes/interactive/grok/footer.d.ts.map +1 -0
- package/dist/modes/interactive/grok/footer.js +27 -0
- package/dist/modes/interactive/grok/footer.js.map +1 -0
- package/dist/modes/interactive/grok/input-card.d.ts +9 -0
- package/dist/modes/interactive/grok/input-card.d.ts.map +1 -0
- package/dist/modes/interactive/grok/input-card.js +30 -0
- package/dist/modes/interactive/grok/input-card.js.map +1 -0
- package/dist/modes/interactive/grok/palette.d.ts +145 -0
- package/dist/modes/interactive/grok/palette.d.ts.map +1 -0
- package/dist/modes/interactive/grok/palette.js +92 -0
- package/dist/modes/interactive/grok/palette.js.map +1 -0
- package/dist/modes/interactive/grok/tool-row.d.ts +17 -0
- package/dist/modes/interactive/grok/tool-row.d.ts.map +1 -0
- package/dist/modes/interactive/grok/tool-row.js +26 -0
- package/dist/modes/interactive/grok/tool-row.js.map +1 -0
- package/dist/modes/interactive/grok/welcome-card.d.ts +10 -0
- package/dist/modes/interactive/grok/welcome-card.d.ts.map +1 -0
- package/dist/modes/interactive/grok/welcome-card.js +30 -0
- package/dist/modes/interactive/grok/welcome-card.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +5 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +108 -52
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/grok-day.json +77 -0
- package/dist/modes/interactive/theme/grok-night.json +93 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +4 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/rpc/connection-handler.d.ts +3 -3
- package/dist/modes/rpc/connection-handler.js +6 -6
- package/dist/modes/rpc/connection-handler.js.map +1 -1
- package/dist/modes/rpc/custom-capability.d.ts +6 -7
- package/dist/modes/rpc/custom-capability.d.ts.map +1 -1
- package/dist/modes/rpc/custom-capability.js +6 -7
- package/dist/modes/rpc/custom-capability.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +2 -2
- package/dist/modes/rpc/rpc-mode.js +5 -5
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/senpi +2 -0
- package/docs/docs.json +4 -0
- package/docs/environment-variables.md +1 -0
- package/docs/grok-neo.md +77 -0
- package/docs/keybindings.md +0 -1
- package/docs/settings.md +3 -3
- package/docs/terminal-tools.md +6 -3
- package/docs/usage.md +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +35 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +39 -19
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
- package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/http-server.ts +6 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/output-bridge.ts +0 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/eval-notifier.ts +40 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +46 -66
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +5 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel-contract.ts +2 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel.ts +19 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/prelude.py +7 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +8 -5
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +23 -5
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +322 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +253 -18
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/interrupt-note.ts +58 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +28 -6
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/status-events.ts +20 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +65 -22
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +4 -41
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +3 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +2 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts +10 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js +38 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +5 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- 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 +135 -16
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +1 -4
- package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js +4 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +67 -31
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.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/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +10 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.js +7 -3
- package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.d.ts +9 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.js +16 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js +35 -3
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +6 -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.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts +32 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js +15 -7
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +8 -8
- package/dist/cli/neo/build-argv.d.ts +0 -19
- package/dist/cli/neo/build-argv.d.ts.map +0 -1
- package/dist/cli/neo/build-argv.js +0 -84
- package/dist/cli/neo/build-argv.js.map +0 -1
- package/dist/cli/neo/daemon-launch.d.ts +0 -25
- package/dist/cli/neo/daemon-launch.d.ts.map +0 -1
- package/dist/cli/neo/daemon-launch.js +0 -97
- package/dist/cli/neo/daemon-launch.js.map +0 -1
- package/dist/cli/neo/gate.d.ts +0 -15
- package/dist/cli/neo/gate.d.ts.map +0 -1
- package/dist/cli/neo/gate.js +0 -21
- package/dist/cli/neo/gate.js.map +0 -1
- package/dist/cli/neo/launch.d.ts +0 -24
- package/dist/cli/neo/launch.d.ts.map +0 -1
- package/dist/cli/neo/launch.js +0 -66
- package/dist/cli/neo/launch.js.map +0 -1
- package/dist/cli/neo/platform.d.ts +0 -38
- package/dist/cli/neo/platform.d.ts.map +0 -1
- package/dist/cli/neo/platform.js +0 -54
- package/dist/cli/neo/platform.js.map +0 -1
- package/dist/cli/neo/resolve-binary.d.ts +0 -39
- package/dist/cli/neo/resolve-binary.d.ts.map +0 -1
- package/dist/cli/neo/resolve-binary.js +0 -66
- package/dist/cli/neo/resolve-binary.js.map +0 -1
- package/dist/core/extensions/builtin/session-observer/index.d.ts +0 -5
- package/dist/core/extensions/builtin/session-observer/index.d.ts.map +0 -1
- package/dist/core/extensions/builtin/session-observer/index.js +0 -36
- package/dist/core/extensions/builtin/session-observer/index.js.map +0 -1
- package/dist/core/extensions/builtin/session-observer/loader.d.ts +0 -3
- package/dist/core/extensions/builtin/session-observer/loader.d.ts.map +0 -1
- package/dist/core/extensions/builtin/session-observer/loader.js +0 -20
- package/dist/core/extensions/builtin/session-observer/loader.js.map +0 -1
- package/dist/core/extensions/builtin/session-observer/overlay-format.d.ts +0 -7
- package/dist/core/extensions/builtin/session-observer/overlay-format.d.ts.map +0 -1
- package/dist/core/extensions/builtin/session-observer/overlay-format.js +0 -30
- package/dist/core/extensions/builtin/session-observer/overlay-format.js.map +0 -1
- package/dist/core/extensions/builtin/session-observer/overlay.d.ts +0 -51
- package/dist/core/extensions/builtin/session-observer/overlay.d.ts.map +0 -1
- package/dist/core/extensions/builtin/session-observer/overlay.js +0 -229
- package/dist/core/extensions/builtin/session-observer/overlay.js.map +0 -1
- package/dist/core/extensions/builtin/session-observer/scanner.d.ts +0 -10
- package/dist/core/extensions/builtin/session-observer/scanner.d.ts.map +0 -1
- package/dist/core/extensions/builtin/session-observer/scanner.js +0 -142
- package/dist/core/extensions/builtin/session-observer/scanner.js.map +0 -1
- package/dist/core/extensions/builtin/session-observer/text.d.ts +0 -7
- package/dist/core/extensions/builtin/session-observer/text.d.ts.map +0 -1
- package/dist/core/extensions/builtin/session-observer/text.js +0 -37
- package/dist/core/extensions/builtin/session-observer/text.js.map +0 -1
- package/dist/core/extensions/builtin/session-observer/transcript-entries.d.ts +0 -7
- package/dist/core/extensions/builtin/session-observer/transcript-entries.d.ts.map +0 -1
- package/dist/core/extensions/builtin/session-observer/transcript-entries.js +0 -71
- package/dist/core/extensions/builtin/session-observer/transcript-entries.js.map +0 -1
- package/dist/core/extensions/builtin/session-observer/transcript-format.d.ts +0 -11
- package/dist/core/extensions/builtin/session-observer/transcript-format.d.ts.map +0 -1
- package/dist/core/extensions/builtin/session-observer/transcript-format.js +0 -65
- package/dist/core/extensions/builtin/session-observer/transcript-format.js.map +0 -1
- package/dist/core/extensions/builtin/session-observer/transcript.d.ts +0 -4
- package/dist/core/extensions/builtin/session-observer/transcript.d.ts.map +0 -1
- package/dist/core/extensions/builtin/session-observer/transcript.js +0 -81
- package/dist/core/extensions/builtin/session-observer/transcript.js.map +0 -1
- package/dist/core/extensions/builtin/session-observer/types.d.ts +0 -33
- package/dist/core/extensions/builtin/session-observer/types.d.ts.map +0 -1
- package/dist/core/extensions/builtin/session-observer/types.js +0 -2
- package/dist/core/extensions/builtin/session-observer/types.js.map +0 -1
- package/dist/modes/rpc/neo-daemon-child-worker.d.ts +0 -29
- package/dist/modes/rpc/neo-daemon-child-worker.d.ts.map +0 -1
- package/dist/modes/rpc/neo-daemon-child-worker.js +0 -95
- package/dist/modes/rpc/neo-daemon-child-worker.js.map +0 -1
- package/dist/modes/rpc/neo-daemon-mode.d.ts +0 -110
- package/dist/modes/rpc/neo-daemon-mode.d.ts.map +0 -1
- package/dist/modes/rpc/neo-daemon-mode.js +0 -267
- package/dist/modes/rpc/neo-daemon-mode.js.map +0 -1
- package/dist/modes/rpc/neo-daemon-protocol.d.ts +0 -50
- package/dist/modes/rpc/neo-daemon-protocol.d.ts.map +0 -1
- package/dist/modes/rpc/neo-daemon-protocol.js +0 -66
- package/dist/modes/rpc/neo-daemon-protocol.js.map +0 -1
- package/dist/modes/rpc/neo-daemon-registry.d.ts +0 -98
- package/dist/modes/rpc/neo-daemon-registry.d.ts.map +0 -1
- package/dist/modes/rpc/neo-daemon-registry.js +0 -209
- package/dist/modes/rpc/neo-daemon-registry.js.map +0 -1
- package/dist/modes/rpc/neo-runtime-options-argv.d.ts +0 -17
- package/dist/modes/rpc/neo-runtime-options-argv.d.ts.map +0 -1
- package/dist/modes/rpc/neo-runtime-options-argv.js +0 -79
- package/dist/modes/rpc/neo-runtime-options-argv.js.map +0 -1
- package/dist/modes/rpc/neo-runtime-options.d.ts +0 -84
- package/dist/modes/rpc/neo-runtime-options.d.ts.map +0 -1
- package/dist/modes/rpc/neo-runtime-options.js +0 -92
- package/dist/modes/rpc/neo-runtime-options.js.map +0 -1
- package/docs/neo.md +0 -111
- package/node_modules/@code-yeongyu/senpi-codemode/src/codemode/runtime.ts +0 -258
- package/node_modules/@code-yeongyu/senpi-codemode/src/codemode/tools.ts +0 -106
package/docs/grok-neo.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
> senpi can wear a different chrome. Ask it to show you around.
|
|
2
|
+
|
|
3
|
+
# Grok Neo Mode (Experimental)
|
|
4
|
+
|
|
5
|
+
`--grok-neo` is an experimental alternative presentation ("chrome") for the standard interactive mode. It runs the same agent, tools, sessions, and keybindings as the classic TUI — only the visual layer changes.
|
|
6
|
+
|
|
7
|
+
## How It Differs from the Classic TUI
|
|
8
|
+
|
|
9
|
+
The classic TUI renders a bordered editor, a multi-line footer with token and cost details, and expandable tool executions. The grok chrome replaces that presentation with:
|
|
10
|
+
|
|
11
|
+
- **Input card** — the editor sits inside a rounded card (`╭─╮` / `╰─╯` borders) with a themed interior background.
|
|
12
|
+
- **Compact footer** — model and working directory only; the detailed token/cost readout is intentionally omitted.
|
|
13
|
+
- **Welcome card** — startup shows the app name and version inside a bordered card.
|
|
14
|
+
- **Single-line tool rows** — tool executions render as one-line rows with a stable guide column (`┃`) and a diamond marker (`◆`).
|
|
15
|
+
- **Braille working indicator** — the spinner uses the braille frame `⠹`, tinted with the active theme's accent colour.
|
|
16
|
+
|
|
17
|
+
All chrome colours resolve through tokens backed by the active theme, so the chrome stays coherent with `grok-day` and with custom themes.
|
|
18
|
+
|
|
19
|
+
### Overlay Policy
|
|
20
|
+
|
|
21
|
+
Overlay options control placement, sizing, visibility, and focus; they do not carry presentation colours. Existing modal components render their own borders from the active theme. A modal using the standard `DynamicBorder` therefore inherits the active `border` token (`#585858` under `grok-night`); components that explicitly request an accent border keep that component-specific choice. The modal colour is supplied by the active theme, not by a grok overlay-options seam.
|
|
22
|
+
|
|
23
|
+
## Enabling the Mode
|
|
24
|
+
|
|
25
|
+
The mode is gated behind an environment variable and is **off by default**:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
export SENPI_ENABLE_GROK_NEO=1 # also accepts "true" or "yes"
|
|
29
|
+
senpi --grok-neo
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Or for a single run:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
SENPI_ENABLE_GROK_NEO=1 senpi --grok-neo
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Without the gate, `--grok-neo` is absent from `--help` and parses as an unknown extension flag, exactly as if the feature did not exist.
|
|
39
|
+
|
|
40
|
+
## Themes
|
|
41
|
+
|
|
42
|
+
Two built-in themes ship with the mode:
|
|
43
|
+
|
|
44
|
+
- `grok-night` — dark palette (the fallback)
|
|
45
|
+
- `grok-day` — light palette
|
|
46
|
+
|
|
47
|
+
Theme selection follows one precedence rule: **an existing settings theme always wins.** `grok-night` is only an in-memory fallback used when no theme was ever chosen, and it is never written to `settings.json`. To use `grok-day` (or any other theme), select it explicitly via `/settings` or in `settings.json`:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"theme": "grok-day"
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Once you select a theme it is persisted and takes precedence on every later launch.
|
|
56
|
+
|
|
57
|
+
Modal and overlay components resolve their border through the normal theme `border` token. Both Grok themes map that token to the §Palette modal value, `#585858`; the input and card values remain available through the other schema border slots.
|
|
58
|
+
|
|
59
|
+
Note that `--theme <path>` **registers** a theme file or directory as a resource; it does not select one. Selection always happens through `/settings` or `settings.json`.
|
|
60
|
+
|
|
61
|
+
Senpi is a rebranded distribution, so its first-time setup is intentionally unavailable: that flow only runs for the official Pi package/app/config identity. A fresh `--grok-neo` launch therefore reaches the normal in-memory `grok-night` fallback directly; it does not show a Grok-specific setup or persist a theme.
|
|
62
|
+
|
|
63
|
+
## Architecture: One Process
|
|
64
|
+
|
|
65
|
+
`--grok-neo` runs **in-process**: the chrome is a presentation strategy inside the ordinary interactive mode, in the same senpi process. There is no separate binary and no daemon — unlike the retired `--neo`, which launched a Go TUI binary talking to senpi over a JSONL RPC daemon.
|
|
66
|
+
|
|
67
|
+
For the Bun-compiled binary (`npm run build:binary`) this means one process and one deployable directory. `bun build --compile` produces a single `dist/pi` executable, and its runtime assets ship alongside it in `dist/`: theme JSON files, image assets, the photon WASM module, and the pty native addon. Native `.node` addons are **not** embedded by `bun build --compile`; the pty addon is resolved as a sidecar relative to the executable (`dist/native/prebuilds/<platform-arch>/`). So the honest claim is "one process, one deployable directory" — not one file.
|
|
68
|
+
|
|
69
|
+
## Experimental Status
|
|
70
|
+
|
|
71
|
+
The mode is experimental: it is gated off by default, and its visuals and behaviour may change between releases. The classic TUI is unchanged and remains the default.
|
|
72
|
+
|
|
73
|
+
## Licence and Attribution
|
|
74
|
+
|
|
75
|
+
This mode is an **independent reimplementation** inspired by the style and techniques of [grok-build](https://github.com/xai-org/grok-build). grok-build is licensed under Apache-2.0; regardless of what that licence permits, no grok-build code was copied or translated into this project. The colour palette is colour data measured from terminal captures, not copied code.
|
|
76
|
+
|
|
77
|
+
This project is not affiliated with or endorsed by xAI.
|
package/docs/keybindings.md
CHANGED
|
@@ -89,7 +89,6 @@ Modifier combinations: `ctrl+shift+x`, `alt+ctrl+x`, `ctrl+shift+alt+x`, `ctrl+1
|
|
|
89
89
|
| `app.editor.external` | `ctrl+g` | Open in external editor (`externalEditor`, `$VISUAL`, `$EDITOR`, Notepad on Windows, or `nano` elsewhere) |
|
|
90
90
|
| `app.clipboard.pasteImage` | `ctrl+v` (`alt+v` on Windows) | Paste image from clipboard |
|
|
91
91
|
| `app.history.search` | `ctrl+r` | Search prompt history across sessions |
|
|
92
|
-
| `app.sessions.observe` | `ctrl+s` | Observe session transcripts |
|
|
93
92
|
|
|
94
93
|
### Sessions
|
|
95
94
|
|
package/docs/settings.md
CHANGED
|
@@ -212,9 +212,9 @@ Set `PI_SKIP_VERSION_CHECK=1` to disable the senpi version update check. Use `--
|
|
|
212
212
|
| `retry.abortServerSideFallback` | boolean | `true` | Abort a turn when the provider substitutes a different model after a classifier decline |
|
|
213
213
|
| `retry.provider.timeoutMs` | number | `300000` | Provider/SDK request timeout and stream idle timeout in milliseconds |
|
|
214
214
|
| `retry.provider.maxRetries` | number | `0` | Provider/SDK retry attempts |
|
|
215
|
-
| `retry.provider.maxRetryDelayMs` | number | `60000` | Max server-requested delay before
|
|
215
|
+
| `retry.provider.maxRetryDelayMs` | number | `60000` | Max server-requested delay honored on the same model before the fallback chain engages (60s) |
|
|
216
216
|
|
|
217
|
-
|
|
217
|
+
A server-requested retry delay at or below `retry.provider.maxRetryDelayMs` is honored on the same model. A longer delay means the model is unavailable rather than busy, so Senpi engages the configured fallback chain instead of waiting, suppressing the primary for the requested duration; the turn fails with an informative error only when no chain candidate can take over.
|
|
218
218
|
|
|
219
219
|
Keep `retry.provider.maxRetries` at `0` unless provider-level retries are explicitly needed. Setting it above `0` can make SDK/provider retries handle out-of-usage-limit errors before senpi sees them, which may block the agent until the provider quota resets in some circumstances.
|
|
220
220
|
|
|
@@ -257,7 +257,7 @@ A fallback entry with `:thinking-level` requests that level on the target model;
|
|
|
257
257
|
|
|
258
258
|
#### Fallback behavior and diagnostics
|
|
259
259
|
|
|
260
|
-
With `retry.enabled` and `retry.modelFallback` enabled, Senpi can switch from a transient or eligible hard provider failure to the next configured candidate. The switch continues the current turn without changing the existing conversation prefix, preserving prompt-cache inputs; fallback lifecycle events are never added to model context. Returning to a primary model happens only at a turn boundary, never while a response is streaming.
|
|
260
|
+
With `retry.enabled` and `retry.modelFallback` enabled, Senpi can switch from a transient or eligible hard provider failure to the next configured candidate. Transient failures (timeouts, overload, 429, 5xx, transport drops) first retry the same model on the existing exponential backoff; the chain engages only after `retry.maxRetries` attempts are spent, and each fallback candidate starts with a fresh retry budget. Hard failures (quota, auth, model-not-found) and classifier refusals still switch immediately. The switch continues the current turn without changing the existing conversation prefix, preserving prompt-cache inputs; fallback lifecycle events are never added to model context. Returning to a primary model happens only at a turn boundary, never while a response is streaming. Selector cooldowns are error-derived, and a provider retry-after hint always wins: quota and billing failures park a model for 30 minutes, rate limits for 30 seconds, overload for 45 seconds plus jitter, 5xx for 20 seconds, and timeout or connection/transport failures for 60 seconds; unmatched failures default to five minutes. A fully failing chain costs up to `1 + (chainLength + 1) * maxRetries` provider calls plus per-rung backoff before the turn fails; with `maxRetries: 0` every failure switches immediately, costing `1 + chainLength` calls.
|
|
261
261
|
|
|
262
262
|
Anthropic streaming refusals are identified from typed `stopDetails`. A configured candidate receives an immediate **pinned** fallback switch with a user-visible fallback notice: Senpi does not retry the refusing model and a pinned fallback never auto-reverts. Set `retry.fallbackRevertPolicy` to `"cooldown-expiry"` (the default) to return an unpinned fallback to its primary after the primary's cooldown expires, or `"never"` to keep the fallback until you change models.
|
|
263
263
|
|
package/docs/terminal-tools.md
CHANGED
|
@@ -11,7 +11,8 @@ platform/runtime).
|
|
|
11
11
|
| Tool | Purpose |
|
|
12
12
|
|------|---------|
|
|
13
13
|
| `bash` | Run a command in a PTY. `run_in_background: true` starts a persistent session and returns a `bash_id` immediately. Foreground `timeout` (seconds) is a kill deadline. |
|
|
14
|
-
| `bash_output` |
|
|
14
|
+
| `bash_output` | Peek at a session without blocking: new output since the last read, or the status line. `filter` regex-filters lines; `view: "screen"` returns the rendered xterm grid. |
|
|
15
|
+
| `monitor` | Watch a long-running command (`description`, `command`, `filter?`, `timeout_ms?`, `persistent?`) and inject matching stdout lines as coalesced events. |
|
|
15
16
|
| `bash_input` | Send stdin (`input`) or named keys (`keys: ["ctrl+c"]`, `["enter"]`, `["up"]`) to steer a REPL or interrupt a process. |
|
|
16
17
|
| `bash_resize` | Resize a session's PTY (`cols`, `rows`) so full-screen TUIs reflow. |
|
|
17
18
|
| `kill_bash` | Tree-kill one session (`bash_id`) or all (`all: true`), leaving no orphans. |
|
|
@@ -20,8 +21,10 @@ Background sessions are NEVER killed by `timeout` (they live until they exit or
|
|
|
20
21
|
call `kill_bash`), even though the bash-timeout extension injects a default `timeout`
|
|
21
22
|
into every `bash` call. Foreground calls behave like the classic `bash` tool.
|
|
22
23
|
|
|
23
|
-
Typical flow: start with `run_in_background: true`,
|
|
24
|
-
|
|
24
|
+
Typical flow: start with `run_in_background: true`, watch for patterns with `monitor`,
|
|
25
|
+
peek with `bash_output`, steer with `bash_input`, then `kill_bash` when done. Completion
|
|
26
|
+
arrives as a notification carrying the exit code and output tail, so a follow-up
|
|
27
|
+
`bash_output` read is only needed when the tail is not enough.
|
|
25
28
|
|
|
26
29
|
## Mutual exclusion with native Anthropic bash
|
|
27
30
|
|
package/docs/usage.md
CHANGED
|
@@ -57,7 +57,7 @@ Type `/` in the editor to open command completion. Extensions can register custo
|
|
|
57
57
|
| `/reload` | Reload keybindings, extensions, skills, prompts, themes, and context files |
|
|
58
58
|
| `/hotkeys` | Show all keyboard shortcuts |
|
|
59
59
|
| `/changelog` | Display version history |
|
|
60
|
-
| `/quit` | Quit pi |
|
|
60
|
+
| `/quit`, `/exit` | Quit pi |
|
|
61
61
|
|
|
62
62
|
## Message Queue
|
|
63
63
|
|
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
### Breaking Changes
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
### Removed
|
|
14
|
+
|
|
15
|
+
## [2026.7.26] - 2026-07-26
|
|
16
|
+
|
|
17
|
+
### Breaking Changes
|
|
18
|
+
|
|
19
|
+
- Remove the separate GPT-only `exec`/`wait` runtime; GPT models now compose active tools through the persistent `eval` surface.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Detach interactive `eval` cells on timeout, inject completion notifications, and support `peek`/`stop` actions without blocking other language kernels.
|
|
24
|
+
- Report whether Python kernel state survived an interrupt or timeout, with a real-surface QA driver covering the contract.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- Bound each cell's retained status history and summarize omitted events ([#334](https://github.com/code-yeongyu/senpi/pull/334) by [@minpeter](https://github.com/minpeter)).
|
|
29
|
+
- Make task-output lookups non-blocking and document detached-cell state, output, and artifact behavior.
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- Preserve Python state when interruption succeeds, report truthful state when it does not, and tolerate kernels predating the interrupt-outcome contract.
|
|
34
|
+
- Stop normal bridge-request completion from aborting still-running host tool calls.
|
|
35
|
+
|
|
36
|
+
### Removed
|
|
37
|
+
|
|
3
38
|
## [2026.7.25-2] - 2026-07-25
|
|
4
39
|
|
|
5
40
|
### Breaking Changes
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
# @code-yeongyu/senpi-codemode
|
|
2
2
|
|
|
3
3
|
`@code-yeongyu/senpi-codemode` is Senpi's source-only Code Mode extension. It
|
|
4
|
-
registers persistent-kernel `eval` for every eligible
|
|
5
|
-
`
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
registers the persistent-kernel `eval` execution surface for every eligible
|
|
5
|
+
model. `eval` owns one persistent kernel per enabled language and re-registers
|
|
6
|
+
at session start after configuration, interpreter availability, and active
|
|
7
|
+
task-tool names are known.
|
|
8
8
|
|
|
9
9
|
## Capabilities
|
|
10
10
|
|
|
11
11
|
- Persistent JavaScript, Python, Ruby, and Julia cells. State survives later
|
|
12
12
|
cells in the same language until reset, restart, or session disposal.
|
|
13
|
+
- Timeout detachment for interactive `eval`: long pure-compute cells return a
|
|
14
|
+
handle and continue in their existing kernel. Completion is injected with the
|
|
15
|
+
final value/error and buffered output; use `eval({ action: "peek"|"stop",
|
|
16
|
+
cell_id })` to inspect or terminate a detached cell.
|
|
13
17
|
- Loopback, bearer-authenticated kernel bridge with bounded JSONL frames.
|
|
14
18
|
- Structured status events for file operations, environment access, phases,
|
|
15
19
|
bridge activity, and delegated task progress.
|
|
@@ -20,8 +24,8 @@ configuration, interpreter availability, and active task-tool names are known.
|
|
|
20
24
|
fallbacks.
|
|
21
25
|
- JavaScript import rewriting for supported local modules and package imports
|
|
22
26
|
in the persistent Node.js worker.
|
|
23
|
-
- GPT
|
|
24
|
-
active tools through `
|
|
27
|
+
- GPT models receive a terse `eval` prompt dialect that prioritizes composing
|
|
28
|
+
active tools through `tool.<name>(args)` and documents detach-on-timeout.
|
|
25
29
|
|
|
26
30
|
## Kernels
|
|
27
31
|
|
|
@@ -68,13 +72,13 @@ Configuration is loaded in this order:
|
|
|
68
72
|
| Key | Default | Effect |
|
|
69
73
|
| --- | --- | --- |
|
|
70
74
|
| `languages` | `py`/`js` enabled; `rb`/`jl` disabled | Selects desired languages before interpreter detection. |
|
|
71
|
-
| `cellTimeoutSeconds` | `30` | Idle timeout for one cell unless the call supplies `timeout
|
|
75
|
+
| `cellTimeoutSeconds` | `30` | Idle timeout for one cell unless the call supplies `timeout`; interactive calls detach by default and print/json calls error. |
|
|
72
76
|
| `parallelPoolWidth` | `4` | Maximum concurrent `parallel()` thunks. |
|
|
73
77
|
| `taskTools.task` | `"task"` | Registered tool name used by `agent()`. |
|
|
74
78
|
| `taskTools.output` | `"task_output"` | Registered tool name used by `output()`. |
|
|
75
79
|
| `outputSink.headBytes` | `20480` | Bytes retained from the beginning of a middle-truncated preview; `0` disables it. |
|
|
76
80
|
| `outputSink.maxColumns` | `768` | Maximum rendered output columns; `0` disables column clamping. |
|
|
77
|
-
| `statusEvents` | `true` | Enables kernel status-event forwarding and rendering. |
|
|
81
|
+
| `statusEvents` | `true` | Enables kernel status-event forwarding and rendering. Each cell retains at most 100 status rows; after overflow, one omitted-count row precedes the latest 99 events. |
|
|
78
82
|
|
|
79
83
|
`SENPI_CODEMODE_PY`, `SENPI_CODEMODE_JS`, `SENPI_CODEMODE_RB`, and
|
|
80
84
|
`SENPI_CODEMODE_JL` override the corresponding file setting. `1` or `true`
|
|
@@ -96,7 +100,7 @@ options object and asynchronous helpers are `await`-able.
|
|
|
96
100
|
| `read(path, offset?, limit?)` | Reads text with 1-indexed line slicing. `local://` paths resolve under the session artifact root. |
|
|
97
101
|
| `write(path, content)` | Creates parent directories and writes text. `local://` paths persist in the session artifact root. |
|
|
98
102
|
| `env(key?, value?)` | Reads all kernel environment values, one value, or sets one value. |
|
|
99
|
-
| `tool.<name>(args)`
|
|
103
|
+
| `tool.<name>(args)` | Invokes an active Senpi tool through the normal `pi.executeTool` pipeline. |
|
|
100
104
|
| `completion(prompt, model?, system?, schema?)` | Requests a one-shot host completion; `schema` asks the host to parse structured output. |
|
|
101
105
|
| `agent(prompt, ...)` | Delegates to the configured active `taskTools.task` tool. Supports background handles and structured JSON results. |
|
|
102
106
|
| `output(ids, format?, offset?, limit?)` | Delegates transcript retrieval to the configured active `taskTools.output` tool. |
|
|
@@ -105,13 +109,31 @@ options object and asynchronous helpers are `await`-able.
|
|
|
105
109
|
| `log(message)` / `phase(title)` | Emits progress text and starts a status phase. |
|
|
106
110
|
|
|
107
111
|
`agent()` is available only when the configured task tool is active in the
|
|
108
|
-
session. `output()` similarly requires the configured task-output tool
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
+
session. `output()` similarly requires the configured task-output tool and
|
|
113
|
+
returns immediately: a running task reports its current status, while completed
|
|
114
|
+
tasks return the requested transcript. Missing tools produce a clear
|
|
115
|
+
availability error instead of importing an orchestration package. `agent()`
|
|
116
|
+
delegates through the tool contract, so task-engine permissions, progress
|
|
117
|
+
updates, and transcripts remain owned by that engine.
|
|
112
118
|
`isolated`, `apply`, and `merge` are accepted for compatibility but emit a
|
|
113
119
|
warning because this task-engine integration has no isolation model.
|
|
114
120
|
|
|
121
|
+
## Detached cells
|
|
122
|
+
|
|
123
|
+
`eval` accepts `on_timeout: "detach"|"error"`. The default is `"detach"` in
|
|
124
|
+
interactive TUI, RPC, and app-server sessions; print and JSON one-shot runs
|
|
125
|
+
default to `"error"` so their result is never silently detached. A detached
|
|
126
|
+
cell keeps only its own language kernel busy. A new same-language call returns
|
|
127
|
+
a busy error with its cell id and output tail; calls in other languages continue
|
|
128
|
+
normally. Do not re-run the cell.
|
|
129
|
+
|
|
130
|
+
Use `eval({ action: "peek", cell_id })` for its state and buffered output, or
|
|
131
|
+
`eval({ action: "stop", cell_id })` to cancel it. Python stop interrupts the
|
|
132
|
+
existing kernel and preserves variables. JavaScript stop kills and restarts its
|
|
133
|
+
worker, so JavaScript VM state is lost. Detached completion messages state when
|
|
134
|
+
kernel variables are available to the next eval cell; oversized buffered output
|
|
135
|
+
is written under the session local root and referenced as `local://…`.
|
|
136
|
+
|
|
115
137
|
## Output and artifacts
|
|
116
138
|
|
|
117
139
|
Cell output is streamed while the cell runs. Large streams spill to an absolute
|
|
@@ -139,11 +161,9 @@ Session generations fence retired kernels and callbacks; each cell settles once
|
|
|
139
161
|
across completion, errors, cancellation, timeout, bridge failure, or a kernel
|
|
140
162
|
crash.
|
|
141
163
|
|
|
142
|
-
GPT
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
`eval` kernels. `eval`, `exec`, and `wait` are excluded from the nested tool
|
|
146
|
-
namespace to prevent recursive Code Mode execution.
|
|
164
|
+
GPT models use the same JavaScript `eval` worker trust boundary as other JavaScript cells;
|
|
165
|
+
there is no separate execution runtime. `eval` is excluded from the nested tool
|
|
166
|
+
namespace to prevent recursive execution.
|
|
147
167
|
|
|
148
168
|
## Validation
|
|
149
169
|
|
|
@@ -157,5 +177,5 @@ npm run check
|
|
|
157
177
|
|
|
158
178
|
Direct real-surface QA drivers live in `scripts/qa-*.ts`: kernel cells
|
|
159
179
|
(`qa-py-cell.ts`, `qa-js-cell.ts`, `qa-rb-cell.ts`, `qa-jl-cell.ts`), end-to-end
|
|
160
|
-
extension execution (`qa-e2e-eval.ts
|
|
180
|
+
extension execution (`qa-e2e-eval.ts`), and renderer output
|
|
161
181
|
(`qa-render-dump.ts`).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/senpi-codemode",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.26",
|
|
4
4
|
"description": "Source-only senpi extension package for codemode evaluation tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@babel/parser": "7.29.7",
|
|
33
|
-
"@earendil-works/pi-ai": "^2026.7.
|
|
33
|
+
"@earendil-works/pi-ai": "^2026.7.26",
|
|
34
34
|
"typebox": "1.1.38"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@code-yeongyu/senpi": "*"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@code-yeongyu/senpi": "2026.7.
|
|
40
|
+
"@code-yeongyu/senpi": "2026.7.26"
|
|
41
41
|
},
|
|
42
42
|
"keywords": [
|
|
43
43
|
"senpi",
|
|
@@ -75,7 +75,12 @@ async function handleRequest(
|
|
|
75
75
|
options: BridgeServerOptions,
|
|
76
76
|
): Promise<void> {
|
|
77
77
|
const abortController = new AbortController();
|
|
78
|
-
|
|
78
|
+
// IncomingMessage "close" fires on normal message completion in Node >= 16,
|
|
79
|
+
// so premature disconnect must be detected on the response side instead:
|
|
80
|
+
// its "close" without a finished response means the connection died mid-call.
|
|
81
|
+
response.on("close", () => {
|
|
82
|
+
if (!response.writableFinished) abortController.abort();
|
|
83
|
+
});
|
|
79
84
|
if (request.method !== "POST") {
|
|
80
85
|
sendJson(response, 404, { ok: false, error: transportError("not_found", "Bridge route was not found") });
|
|
81
86
|
return;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ExtensionContext } from "@code-yeongyu/senpi";
|
|
2
|
+
import type { EvalDetachedCellNotification, EvalDetachedCellNotifier } from "../tool/detached-cell-manager.ts";
|
|
3
|
+
|
|
4
|
+
const NON_INTERACTIVE_MODES = new Set(["print", "json"]);
|
|
5
|
+
|
|
6
|
+
export type EvalNotifyMode = "wake" | "next-turn" | "off";
|
|
7
|
+
|
|
8
|
+
export interface EvalNotifierDeps {
|
|
9
|
+
readonly sendUserMessage: (content: string, options?: { deliverAs?: "steer" | "followUp" }) => void;
|
|
10
|
+
readonly getContext: () => ExtensionContext | undefined;
|
|
11
|
+
readonly getMode: () => EvalNotifyMode;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Session-scoped completion injector with the same no-spin guards as terminal notifications. */
|
|
15
|
+
export class EvalNotifier implements EvalDetachedCellNotifier {
|
|
16
|
+
readonly #deps: EvalNotifierDeps;
|
|
17
|
+
readonly #notified = new Set<string>();
|
|
18
|
+
|
|
19
|
+
constructor(deps: EvalNotifierDeps) {
|
|
20
|
+
this.#deps = deps;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Starts a fresh session generation without suppressing reused tool-call ids. */
|
|
24
|
+
reset(): void {
|
|
25
|
+
this.#notified.clear();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
notify(cells: readonly EvalDetachedCellNotification[]): void {
|
|
29
|
+
const mode = this.#deps.getMode();
|
|
30
|
+
if (mode === "off") return;
|
|
31
|
+
const ctx = this.#deps.getContext();
|
|
32
|
+
if (ctx === undefined || NON_INTERACTIVE_MODES.has(ctx.mode) || ctx.model === undefined) return;
|
|
33
|
+
const pending = cells.filter((cell) => !this.#notified.has(cell.cellId));
|
|
34
|
+
if (pending.length === 0) return;
|
|
35
|
+
for (const cell of pending) this.#notified.add(cell.cellId);
|
|
36
|
+
this.#deps.sendUserMessage(pending.map((cell) => cell.content).join("\n\n"), {
|
|
37
|
+
deliverAs: mode === "wake" ? "steer" : "followUp",
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import * as os from "node:os";
|
|
2
2
|
import type { ExtensionContext } from "@code-yeongyu/senpi";
|
|
3
3
|
import type { AgentExecuteTool } from "./bridges/agent-bridge.ts";
|
|
4
|
-
import { CodeModeSessionRuntime } from "./codemode/runtime.ts";
|
|
5
|
-
import { type CodeModeTool, createCodeModeTools, isGptCodeModeModel } from "./codemode/tools.ts";
|
|
6
4
|
import { type CompletionRequest, type CompletionResult, createCompletionHandler } from "./completion/handler.ts";
|
|
7
5
|
import { defaultCodemodeSettings } from "./config/settings.ts";
|
|
6
|
+
import { EvalNotifier } from "./extension/eval-notifier.ts";
|
|
8
7
|
import {
|
|
9
8
|
createExecuteTool,
|
|
10
9
|
createRuntime,
|
|
@@ -13,6 +12,7 @@ import {
|
|
|
13
12
|
} from "./extension/runtime-factory.ts";
|
|
14
13
|
import type { CodemodeSessionManager, CreateCodemodeSessionManagerOptions } from "./extension/session-manager.ts";
|
|
15
14
|
import { SessionManagerProxy } from "./extension/session-manager-proxy.ts";
|
|
15
|
+
import { EvalDetachedCellManager } from "./tool/detached-cell-manager.ts";
|
|
16
16
|
import { createEvalTool } from "./tool/eval-tool.ts";
|
|
17
17
|
import { renderEvalCall, renderEvalResult } from "./tool/render.ts";
|
|
18
18
|
|
|
@@ -29,11 +29,11 @@ type CodemodeEvent = SessionLifecycleEvent | "model_select";
|
|
|
29
29
|
|
|
30
30
|
export interface CodemodeExtensionAPI {
|
|
31
31
|
registerTool(tool: ReturnType<typeof createEvalTool>): void;
|
|
32
|
+
registerRemovedToolHint(name: string, hint: string): void;
|
|
32
33
|
on(event: CodemodeEvent, handler: (event: unknown, ctx: ExtensionContext) => Promise<void> | void): void;
|
|
33
34
|
executeTool: AgentExecuteTool;
|
|
34
35
|
getActiveTools(): string[];
|
|
35
|
-
|
|
36
|
-
getAllTools?(): readonly { readonly name: string }[];
|
|
36
|
+
sendUserMessage(content: string, options?: { deliverAs?: "steer" | "followUp" }): void;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export interface SenpiCodemodeOptions {
|
|
@@ -43,19 +43,24 @@ export interface SenpiCodemodeOptions {
|
|
|
43
43
|
readonly complete?: (request: CompletionRequest, ctx: ExtensionContext) => Promise<CompletionResult>;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
type DynamicCodeModeExtensionAPI = CodemodeExtensionAPI & {
|
|
47
|
-
registerTool(tool: CodeModeTool): void;
|
|
48
|
-
setActiveTools(toolNames: string[]): void | Promise<void>;
|
|
49
|
-
getAllTools(): readonly { readonly name: string }[];
|
|
50
|
-
};
|
|
51
|
-
|
|
52
46
|
export default function senpiCodemode(pi: CodemodeExtensionAPI, options: SenpiCodemodeOptions = {}): void {
|
|
53
47
|
const manager = new SessionManagerProxy();
|
|
54
48
|
const complete = options.complete ?? ((request, ctx) => createCompletionHandler()(ctx)(request));
|
|
55
49
|
const renderers = { renderCall: renderEvalCall, renderResult: renderEvalResult };
|
|
56
|
-
let activeRuntime:
|
|
50
|
+
let activeRuntime: SessionRuntime | undefined;
|
|
57
51
|
let activeModelId: string | undefined;
|
|
58
|
-
|
|
52
|
+
let activeContext: ExtensionContext | undefined;
|
|
53
|
+
let activeCells: EvalDetachedCellManager | undefined;
|
|
54
|
+
const notifier = new EvalNotifier({
|
|
55
|
+
sendUserMessage: (content, notifyOptions) => pi.sendUserMessage(content, notifyOptions),
|
|
56
|
+
getContext: () => activeContext,
|
|
57
|
+
getMode: () => "wake",
|
|
58
|
+
});
|
|
59
|
+
const registerEvalForRuntime = (
|
|
60
|
+
runtime: SessionRuntime,
|
|
61
|
+
modelId: string | undefined,
|
|
62
|
+
cellManager: EvalDetachedCellManager,
|
|
63
|
+
): void => {
|
|
59
64
|
pi.registerTool(
|
|
60
65
|
createEvalTool({
|
|
61
66
|
enabledLanguages: runtime.enabledLanguages,
|
|
@@ -65,6 +70,7 @@ export default function senpiCodemode(pi: CodemodeExtensionAPI, options: SenpiCo
|
|
|
65
70
|
complete,
|
|
66
71
|
settings: runtime.settings,
|
|
67
72
|
artifactsDir: runtime.artifactsDir,
|
|
73
|
+
cellManager,
|
|
68
74
|
executionTracker: manager,
|
|
69
75
|
renderers,
|
|
70
76
|
spawns: runtime.spawns,
|
|
@@ -75,21 +81,13 @@ export default function senpiCodemode(pi: CodemodeExtensionAPI, options: SenpiCo
|
|
|
75
81
|
);
|
|
76
82
|
};
|
|
77
83
|
const dropRuntime = async (): Promise<void> => {
|
|
78
|
-
const
|
|
84
|
+
const cells = activeCells;
|
|
79
85
|
activeRuntime = undefined;
|
|
80
86
|
activeModelId = undefined;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const tools = createCodeModeTools({ runtime });
|
|
86
|
-
pi.registerTool(tools.exec);
|
|
87
|
-
pi.registerTool(tools.wait);
|
|
88
|
-
await pi.setActiveTools([...new Set([...pi.getActiveTools(), "exec", "wait"])]);
|
|
89
|
-
};
|
|
90
|
-
const deactivateCodeModeTools = async (): Promise<void> => {
|
|
91
|
-
if (!isDynamicCodeModeExtensionAPI(pi)) return;
|
|
92
|
-
await pi.setActiveTools(pi.getActiveTools().filter((name) => name !== "exec" && name !== "wait"));
|
|
87
|
+
activeCells = undefined;
|
|
88
|
+
await cells?.dispose();
|
|
89
|
+
activeContext = undefined;
|
|
90
|
+
await manager.dispose();
|
|
93
91
|
};
|
|
94
92
|
pi.registerTool(
|
|
95
93
|
createEvalTool({
|
|
@@ -99,71 +97,53 @@ export default function senpiCodemode(pi: CodemodeExtensionAPI, options: SenpiCo
|
|
|
99
97
|
executeTool: createExecuteTool(pi),
|
|
100
98
|
complete,
|
|
101
99
|
settings: defaultCodemodeSettings,
|
|
100
|
+
cellManager: new EvalDetachedCellManager({ notifier }),
|
|
102
101
|
executionTracker: manager,
|
|
103
102
|
renderers,
|
|
104
103
|
hostLine: hostLine(),
|
|
105
104
|
}),
|
|
106
105
|
);
|
|
106
|
+
pi.registerRemovedToolHint(
|
|
107
|
+
"exec",
|
|
108
|
+
'exec was removed; use eval({ language: "js", code }) instead. Long eval cells detach on timeout and notify when complete.',
|
|
109
|
+
);
|
|
110
|
+
pi.registerRemovedToolHint(
|
|
111
|
+
"wait",
|
|
112
|
+
'wait was removed; detached eval cells notify when complete. Use eval({ action: "peek"|"stop", cell_id }) to inspect or stop one.',
|
|
113
|
+
);
|
|
107
114
|
|
|
108
115
|
pi.on("session_start", async (event, ctx) => {
|
|
109
|
-
const
|
|
116
|
+
const previousCells = activeCells;
|
|
117
|
+
activeCells = undefined;
|
|
118
|
+
await previousCells?.dispose();
|
|
110
119
|
const generation = manager.beginReplacement();
|
|
111
120
|
const runtime = await createRuntime(pi, ctx, event, complete, options);
|
|
112
121
|
const replaced = await manager.replace(generation, runtime.manager);
|
|
113
122
|
if (!replaced) return;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
parallelPoolWidth: runtime.parallelPoolWidth,
|
|
120
|
-
executeTool: runtime.executeTool,
|
|
121
|
-
})
|
|
122
|
-
: undefined;
|
|
123
|
-
activeRuntime = { ...runtime, ...(codeMode === undefined ? {} : { codeMode }) };
|
|
123
|
+
notifier.reset();
|
|
124
|
+
activeContext = ctx;
|
|
125
|
+
const cellManager = new EvalDetachedCellManager({ artifactsDir: runtime.artifactsDir, notifier });
|
|
126
|
+
activeCells = cellManager;
|
|
127
|
+
activeRuntime = runtime;
|
|
124
128
|
activeModelId = ctx.model?.id;
|
|
125
|
-
registerEvalForRuntime(
|
|
126
|
-
if (codeMode) await activateCodeModeTools(codeMode);
|
|
127
|
-
else await deactivateCodeModeTools();
|
|
129
|
+
registerEvalForRuntime(runtime, activeModelId, cellManager);
|
|
128
130
|
});
|
|
129
131
|
pi.on("session_shutdown", async () => dropRuntime());
|
|
130
132
|
pi.on("session_before_switch", async () => dropRuntime());
|
|
131
133
|
pi.on("session_before_fork", async () => dropRuntime());
|
|
132
|
-
pi.on("model_select", async (event) => {
|
|
134
|
+
pi.on("model_select", async (event, ctx) => {
|
|
135
|
+
activeContext = ctx;
|
|
133
136
|
const runtime = activeRuntime;
|
|
134
137
|
if (runtime === undefined) return;
|
|
135
138
|
const modelId = modelIdFrom(event);
|
|
136
139
|
if (modelId === undefined || modelId === activeModelId) return;
|
|
137
140
|
activeModelId = modelId;
|
|
138
|
-
|
|
139
|
-
if (
|
|
140
|
-
|
|
141
|
-
await codeMode?.dispose();
|
|
142
|
-
activeRuntime = nextRuntime;
|
|
143
|
-
await deactivateCodeModeTools();
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
if (runtime.codeMode) {
|
|
147
|
-
if (isDynamicCodeModeExtensionAPI(pi)) {
|
|
148
|
-
await pi.setActiveTools([...new Set([...pi.getActiveTools(), "exec", "wait"])]);
|
|
149
|
-
}
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
const codeMode = new CodeModeSessionRuntime({
|
|
153
|
-
sessionId: runtime.sessionId,
|
|
154
|
-
cwd: runtime.cwd,
|
|
155
|
-
parallelPoolWidth: runtime.parallelPoolWidth,
|
|
156
|
-
executeTool: runtime.executeTool,
|
|
157
|
-
});
|
|
158
|
-
activeRuntime = { ...runtime, codeMode };
|
|
159
|
-
await activateCodeModeTools(codeMode);
|
|
141
|
+
const cellManager = activeCells;
|
|
142
|
+
if (cellManager === undefined) return;
|
|
143
|
+
registerEvalForRuntime(runtime, modelId, cellManager);
|
|
160
144
|
});
|
|
161
145
|
}
|
|
162
146
|
|
|
163
|
-
function isDynamicCodeModeExtensionAPI(pi: CodemodeExtensionAPI): pi is DynamicCodeModeExtensionAPI {
|
|
164
|
-
return typeof pi.setActiveTools === "function" && typeof pi.getAllTools === "function";
|
|
165
|
-
}
|
|
166
|
-
|
|
167
147
|
function hostLine(): string {
|
|
168
148
|
const cpu = os.cpus()[0]?.model?.trim();
|
|
169
149
|
return [`${os.platform()} ${os.arch()}`, cpu, `${os.availableParallelism()} cores`]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { HostToKernelMessage, KernelToHostMessage } from "../../bridge/protocol.ts";
|
|
2
|
+
import type { KernelInterruptHandle } from "../../tool/types.ts";
|
|
2
3
|
import { createInlineWorker, type WorkerLike } from "./inline-worker.ts";
|
|
3
4
|
import {
|
|
4
5
|
assertJavaScriptKernelOpen,
|
|
@@ -48,14 +49,16 @@ export class JavaScriptKernel {
|
|
|
48
49
|
return await promise;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
async interrupt(reason = "interrupted"): Promise<
|
|
52
|
+
async interrupt(reason = "interrupted"): Promise<KernelInterruptHandle> {
|
|
52
53
|
assertJavaScriptKernelOpen(this.#lifecycle, "interrupt");
|
|
53
54
|
const active = this.#runs.active;
|
|
54
55
|
const target = this.#runs.takeInterruptTarget();
|
|
55
|
-
if (!target) return;
|
|
56
|
+
if (!target) return { stateRetained: Promise.resolve(true) };
|
|
56
57
|
if (target === active) this.#clearTimeout();
|
|
57
58
|
this.#runs.settle(target, stoppedResult(target.input.cellId, `JS cell interrupted: ${reason}`));
|
|
58
59
|
await this.#restartAfterStop();
|
|
60
|
+
// A restart always replaces the worker VM, so no user global survives.
|
|
61
|
+
return { stateRetained: Promise.resolve(false) };
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
async reset(): Promise<void> {
|
|
@@ -29,4 +29,6 @@ export interface PendingRun {
|
|
|
29
29
|
timeoutTimer: NodeJS.Timeout | null;
|
|
30
30
|
escalationTimer?: NodeJS.Timeout;
|
|
31
31
|
interruptReason?: string;
|
|
32
|
+
/** Set while an interrupt outcome is pending; resolved once the kernel knows whether state survived. */
|
|
33
|
+
resolveStateRetained?: (retained: boolean) => void;
|
|
32
34
|
}
|