@code-yeongyu/senpi 2026.9.21-2 → 2026.9.22-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 +56 -0
- package/dist/bundle/chunks/{anthropic-messages-C3ZY2ANT.js → anthropic-messages-2P7APOOQ.js} +1 -1
- package/dist/bundle/chunks/{app-server-command-HSX5RFAP.js → app-server-command-PRNA6QQU.js} +1 -1
- package/dist/bundle/chunks/{azure-openai-responses-7TAGS2VU.js → azure-openai-responses-3AH7MJWF.js} +1 -1
- package/dist/bundle/chunks/{bun-extension-importer-UO7V2MZ7.js → bun-extension-importer-H4IJCWWQ.js} +1 -1
- package/dist/bundle/chunks/{chunk-OSDJ2SYO.js → chunk-5XC2FNJ5.js} +1 -1
- package/dist/bundle/chunks/{chunk-D5CL7PPD.js → chunk-64JQFFHH.js} +2 -2
- package/dist/bundle/chunks/{chunk-Z3KQB2R3.js → chunk-6OD4TT33.js} +95 -39
- package/dist/bundle/chunks/{chunk-NEEAKXDT.js → chunk-7EH64T6E.js} +2 -2
- package/dist/bundle/chunks/{chunk-MIVOQT3Q.js → chunk-ARJJU3MS.js} +1 -1
- package/dist/bundle/chunks/chunk-BOZ37BOT.js +14 -0
- package/dist/bundle/chunks/{chunk-POMPEGWQ.js → chunk-F3DXL5MX.js} +1 -1
- package/dist/bundle/chunks/{chunk-GLKVDRNP.js → chunk-GXUYWMN2.js} +1 -1
- package/dist/bundle/chunks/chunk-HH3KJDWA.js +2 -0
- package/dist/bundle/chunks/{chunk-B7W62BM7.js → chunk-IPRJIKLL.js} +1 -1
- package/dist/bundle/chunks/chunk-JEFYJDHP.js +8 -0
- package/dist/bundle/chunks/{chunk-T6XA2IZR.js → chunk-JR4X6ECO.js} +1 -1
- package/dist/bundle/chunks/{chunk-I425CMTO.js → chunk-JZ6YQU3A.js} +4 -4
- package/dist/bundle/chunks/{chunk-KNM6SRPE.js → chunk-K3HEWWSS.js} +1 -1
- package/dist/bundle/chunks/{chunk-M2XAY6I7.js → chunk-M2HSO7MH.js} +1 -1
- package/dist/bundle/chunks/{chunk-UYVPLEOL.js → chunk-NK2RNX25.js} +1 -1
- package/dist/bundle/chunks/chunk-NMB4C6ZZ.js +2 -0
- package/dist/bundle/chunks/{chunk-VEO3ABZR.js → chunk-OLJ7LQJY.js} +1 -1
- package/dist/bundle/chunks/{chunk-GVI2HP7N.js → chunk-OPNVT7BU.js} +1 -1
- package/dist/bundle/chunks/{chunk-XHMOFY4T.js → chunk-R6LVC7SP.js} +4 -4
- package/dist/bundle/chunks/{chunk-3SLCHXZO.js → chunk-UCPWK6TZ.js} +2 -2
- package/dist/bundle/chunks/{chunk-B2IM56LB.js → chunk-VYIJQQ5I.js} +1 -1
- package/dist/bundle/chunks/{chunk-47GF6XYZ.js → chunk-YT2ZSZOY.js} +1 -1
- package/dist/bundle/chunks/{cli-main-GQTEEZ2V.js → cli-main-AFJNXUSL.js} +1 -1
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/{google-generative-ai-JWIH75VF.js → google-generative-ai-Y2IYMUVC.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-IRGAY5XR.js → google-vertex-TKBBMPHV.js} +1 -1
- package/dist/bundle/chunks/{host-command-KOEKIHIZ.js → host-command-OVA6GEWC.js} +1 -1
- package/dist/bundle/chunks/host-lifecycle-IDQPLYEA.js +3 -0
- package/dist/bundle/chunks/host-lifecycle.js +10 -6
- package/dist/bundle/chunks/{interactive-host-runtime-2KTFEW7O.js → interactive-host-runtime-F5L4USLR.js} +1 -1
- package/dist/bundle/chunks/{interactive-mode-I3ILWXQB.js → interactive-mode-UFBSCOP7.js} +1 -1
- package/dist/bundle/chunks/kimi-coding.js +2 -2
- package/dist/bundle/chunks/{list-tips-2KX65NWZ.js → list-tips-2QG7ASHS.js} +1 -1
- package/dist/bundle/chunks/{mistral-conversations-VOBYATVJ.js → mistral-conversations-ZYDVFRYF.js} +1 -1
- package/dist/bundle/chunks/multi-session-host-EUTEGVLS.js +21 -0
- package/dist/bundle/chunks/openai-codex-responses-MEIUNROM.js +10 -0
- package/dist/bundle/chunks/{openai-completions-YK6QTYOH.js → openai-completions-4V76L5ZJ.js} +1 -1
- package/dist/bundle/chunks/openai-responses-YR7WRBG3.js +2 -0
- package/dist/bundle/chunks/{package-manager-cli-HOL6CAI6.js → package-manager-cli-JPUWMUEJ.js} +1 -1
- package/dist/bundle/chunks/rotation-stream-S56Y7WMM.js +2 -0
- package/dist/bundle/chunks/{rpc-mode-L3DSGTVM.js → rpc-mode-JDVHUBZY.js} +1 -1
- package/dist/bundle/chunks/{session-picker-L3FYEQBL.js → session-picker-PFPJVVIC.js} +1 -1
- package/dist/bundle/chunks/session-worker.js +225 -164
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/core/agent-session.d.ts +6 -4
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +9 -7
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/credential-pool/classify.d.ts.map +1 -1
- package/dist/core/credential-pool/classify.js +12 -0
- package/dist/core/credential-pool/classify.js.map +1 -1
- package/dist/core/credential-pool/failover.d.ts +37 -5
- package/dist/core/credential-pool/failover.d.ts.map +1 -1
- package/dist/core/credential-pool/failover.js +60 -24
- package/dist/core/credential-pool/failover.js.map +1 -1
- package/dist/core/credential-pool/rotation-events.d.ts +5 -0
- package/dist/core/credential-pool/rotation-events.d.ts.map +1 -0
- package/dist/core/credential-pool/rotation-events.js +25 -0
- package/dist/core/credential-pool/rotation-events.js.map +1 -0
- package/dist/core/credential-pool/rotation-stream.d.ts +4 -3
- package/dist/core/credential-pool/rotation-stream.d.ts.map +1 -1
- package/dist/core/credential-pool/rotation-stream.js +8 -11
- package/dist/core/credential-pool/rotation-stream.js.map +1 -1
- package/dist/core/extensions/builtin/ask-user/schema.d.ts +2 -25
- package/dist/core/extensions/builtin/ask-user/schema.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ask-user/schema.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/api-id.d.ts +7 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/api-id.d.ts.map +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/api-id.js +7 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/api-id.js.map +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/index.js +3 -2
- package/dist/core/extensions/builtin/claude-sdk-oauth/index.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js +22 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.d.ts +2 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.js +4 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js +18 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js +18 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +2 -7
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +2 -8
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/extension.js +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/extension.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/naming.d.ts +0 -1
- package/dist/core/extensions/builtin/mcp/expose/naming.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/naming.js +0 -3
- package/dist/core/extensions/builtin/mcp/expose/naming.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/register.d.ts +1 -2
- package/dist/core/extensions/builtin/mcp/expose/register.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/register.js +0 -21
- package/dist/core/extensions/builtin/mcp/expose/register.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/schema-compat.d.ts +2 -2
- package/dist/core/extensions/builtin/mcp/expose/schema-compat.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/schema-compat.js +2 -2
- package/dist/core/extensions/builtin/mcp/expose/schema-compat.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/file-operations.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/file-operations.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/grok-4.7.d.ts +3 -0
- package/dist/core/extensions/builtin/prompt-preset/grok-4.7.d.ts.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/grok-4.7.js +105 -0
- package/dist/core/extensions/builtin/prompt-preset/grok-4.7.js.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.js +14 -0
- package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
- package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
- package/dist/core/extensions/bun-extension-importer.d.ts +1 -0
- package/dist/core/extensions/bun-extension-importer.d.ts.map +1 -1
- package/dist/core/extensions/bun-extension-importer.js +4 -0
- package/dist/core/extensions/bun-extension-importer.js.map +1 -1
- package/dist/core/extensions/extension-module-cache.d.ts +48 -0
- package/dist/core/extensions/extension-module-cache.d.ts.map +1 -0
- package/dist/core/extensions/extension-module-cache.js +111 -0
- package/dist/core/extensions/extension-module-cache.js.map +1 -0
- package/dist/core/extensions/loader.d.ts +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +14 -56
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts +29 -0
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +30 -3
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/model-resolver.js +1 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/retry-fallback/billing.d.ts.map +1 -1
- package/dist/core/retry-fallback/billing.js +20 -1
- package/dist/core/retry-fallback/billing.js.map +1 -1
- package/dist/core/session-manager.d.ts +3 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +12 -6
- package/dist/core/session-manager.js.map +1 -1
- package/dist/modes/interactive/components/assistant-render-descriptors.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-render-descriptors.js +8 -7
- package/dist/modes/interactive/components/assistant-render-descriptors.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +7 -5
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/custom-capability.d.ts +7 -0
- package/dist/modes/rpc/custom-capability.d.ts.map +1 -1
- package/dist/modes/rpc/custom-capability.js +7 -0
- package/dist/modes/rpc/custom-capability.js.map +1 -1
- package/dist/modes/rpc/handoff-activity.d.ts +4 -0
- package/dist/modes/rpc/handoff-activity.d.ts.map +1 -0
- package/dist/modes/rpc/handoff-activity.js +6 -0
- package/dist/modes/rpc/handoff-activity.js.map +1 -0
- package/dist/modes/rpc/host-child-exit.d.ts +19 -0
- package/dist/modes/rpc/host-child-exit.d.ts.map +1 -0
- package/dist/modes/rpc/host-child-exit.js +35 -0
- package/dist/modes/rpc/host-child-exit.js.map +1 -0
- package/dist/modes/rpc/host-crash-record.d.ts +24 -0
- package/dist/modes/rpc/host-crash-record.d.ts.map +1 -0
- package/dist/modes/rpc/host-crash-record.js +75 -0
- package/dist/modes/rpc/host-crash-record.js.map +1 -0
- package/dist/modes/rpc/host-crash-record.test.d.ts +2 -0
- package/dist/modes/rpc/host-crash-record.test.d.ts.map +1 -0
- package/dist/modes/rpc/host-crash-record.test.js +91 -0
- package/dist/modes/rpc/host-crash-record.test.js.map +1 -0
- package/dist/modes/rpc/host-ensure.d.ts.map +1 -1
- package/dist/modes/rpc/host-ensure.js +60 -17
- package/dist/modes/rpc/host-ensure.js.map +1 -1
- package/dist/modes/rpc/host-lifecycle.d.ts +4 -10
- package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
- package/dist/modes/rpc/host-lifecycle.js +83 -51
- package/dist/modes/rpc/host-lifecycle.js.map +1 -1
- package/dist/modes/rpc/host-supersession.d.ts +13 -2
- package/dist/modes/rpc/host-supersession.d.ts.map +1 -1
- package/dist/modes/rpc/host-supersession.js +40 -7
- package/dist/modes/rpc/host-supersession.js.map +1 -1
- package/dist/modes/rpc/multi-session-host.d.ts +1 -0
- package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
- package/dist/modes/rpc/multi-session-host.js +40 -7
- package/dist/modes/rpc/multi-session-host.js.map +1 -1
- package/dist/modes/rpc/observer-link.d.ts +48 -0
- package/dist/modes/rpc/observer-link.d.ts.map +1 -0
- package/dist/modes/rpc/observer-link.js +56 -0
- package/dist/modes/rpc/observer-link.js.map +1 -0
- package/dist/modes/rpc/rpc-mode.d.ts +12 -2
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +12 -2
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +36 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js +8 -0
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/rpc/session-command-router.d.ts +10 -4
- package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
- package/dist/modes/rpc/session-command-router.js +95 -19
- package/dist/modes/rpc/session-command-router.js.map +1 -1
- package/dist/modes/rpc/session-event-writer.d.ts +5 -3
- package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
- package/dist/modes/rpc/session-event-writer.js +21 -2
- package/dist/modes/rpc/session-event-writer.js.map +1 -1
- package/dist/modes/rpc/session-registry.d.ts +6 -1
- package/dist/modes/rpc/session-registry.d.ts.map +1 -1
- package/dist/modes/rpc/session-registry.js +34 -3
- package/dist/modes/rpc/session-registry.js.map +1 -1
- package/dist/modes/rpc/session-worker-client.d.ts +1 -0
- package/dist/modes/rpc/session-worker-client.d.ts.map +1 -1
- package/dist/modes/rpc/session-worker-client.js +3 -0
- package/dist/modes/rpc/session-worker-client.js.map +1 -1
- package/dist/modes/rpc/session-worker-protocol.d.ts +3 -1
- package/dist/modes/rpc/session-worker-protocol.d.ts.map +1 -1
- package/dist/modes/rpc/session-worker-protocol.js.map +1 -1
- package/dist/modes/rpc/session-worker.js +7 -1
- package/dist/modes/rpc/session-worker.js.map +1 -1
- package/dist/modes/rpc/socket-ownership.d.ts +16 -0
- package/dist/modes/rpc/socket-ownership.d.ts.map +1 -1
- package/dist/modes/rpc/socket-ownership.js +28 -4
- package/dist/modes/rpc/socket-ownership.js.map +1 -1
- package/dist/modes/rpc/worker-session-registry.d.ts +12 -5
- package/dist/modes/rpc/worker-session-registry.d.ts.map +1 -1
- package/dist/modes/rpc/worker-session-registry.js +10 -2
- package/dist/modes/rpc/worker-session-registry.js.map +1 -1
- package/docs/providers.md +9 -1
- package/docs/rpc.md +72 -10
- package/docs/settings.md +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +29 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +51 -13
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/agent-bridge.ts +53 -9
- package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/reserved-dispatch.ts +1 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/config/settings.ts +18 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/eval-status.ts +9 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +6 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/AGENTS.md +2 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/prelude.jl +10 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +18 -6
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-contract.ts +2 -6
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/prelude.ts +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/run-queue.ts +17 -7
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-runtime.js +6 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel-contract.ts +2 -5
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel.ts +37 -5
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/prelude.py +11 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/prelude.rb +6 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-contract.ts +2 -5
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +14 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-queue.ts +18 -5
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt-template.ts +3 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +4 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/timeouts/idle-timeout.ts +9 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/AGENTS.md +2 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-execution.ts +19 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-runtime.ts +11 -3
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-contract.ts +6 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +72 -20
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-snapshot.ts +28 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-state.ts +5 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-status.ts +5 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-eval-result.ts +76 -25
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-execution-event.ts +4 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-kernel-reset-refused-error.ts +12 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-request.ts +2 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool-options.ts +3 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +58 -37
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/managed-cell.ts +15 -8
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +32 -8
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/run-eval-cell.ts +89 -25
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/terminal-snapshot-store.ts +4 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +51 -10
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts +2 -1
- 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 +2 -13
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.js +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/tool-arguments.d.ts +5 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/tool-arguments.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/tool-arguments.js +20 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/tool-arguments.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/README.md +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +14 -56
- 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.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +18 -27
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/websocket-transport-failure.d.ts +40 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/websocket-transport-failure.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/websocket-transport-failure.js +102 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/websocket-transport-failure.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-coding.d.ts +4 -3
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-coding.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-coding.js +28 -14
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-coding.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-region.d.ts +44 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-region.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-region.js +120 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-region.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.d.ts +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.js +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js +21 -15
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/compat.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/compat.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +2 -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 +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/legacy-provider-ids.d.ts +8 -0
- package/node_modules/@earendil-works/pi-ai/dist/legacy-provider-ids.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/legacy-provider-ids.js +26 -0
- package/node_modules/@earendil-works/pi-ai/dist/legacy-provider-ids.js.map +1 -0
- 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/github-copilot.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.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/venice.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/xai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/xiaomi.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding-auth.d.ts +9 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding-auth.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding-auth.js +43 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding-auth.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.js +3 -2
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/provider-failure-description.d.ts +19 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/provider-failure-description.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/provider-failure-description.js +63 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/provider-failure-description.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/classifiers.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/classifiers.js +5 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/classifiers.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts +17 -0
- 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 +22 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +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/tui.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.js +12 -2
- package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
- package/dist/bundle/chunks/chunk-5J5R5AMP.js +0 -8
- package/dist/bundle/chunks/chunk-I3F6VZZF.js +0 -2
- package/dist/bundle/chunks/chunk-IDTLJYJ5.js +0 -10
- package/dist/bundle/chunks/chunk-U6Z6OBX4.js +0 -2
- package/dist/bundle/chunks/host-lifecycle-DGZJTBDJ.js +0 -3
- package/dist/bundle/chunks/multi-session-host-S5FWCIWE.js +0 -20
- package/dist/bundle/chunks/openai-codex-responses-L2PO2D6F.js +0 -10
- package/dist/bundle/chunks/openai-responses-YDUBVF4S.js +0 -2
- package/dist/bundle/chunks/rotation-stream-Y4YU6HV4.js +0 -2
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { AgentToolResult } from "@code-yeongyu/senpi";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_HARD_LIMIT_SECONDS,
|
|
4
|
+
DEFAULT_MAX_DETACHED_CELLS,
|
|
5
|
+
DEFAULT_RUN_BUDGET_SECONDS,
|
|
6
|
+
} from "../config/settings.ts";
|
|
3
7
|
import type { WakeSourceState } from "../extension/wake-source-state.ts";
|
|
4
8
|
import type { CellDeadlineExpiry } from "./cell-deadlines.ts";
|
|
5
9
|
import type {
|
|
@@ -33,12 +37,13 @@ export class EvalDetachedCellManager {
|
|
|
33
37
|
readonly #onStatusChange: ((entries: readonly EvalDetachedCellStatusEntry[]) => void) | undefined;
|
|
34
38
|
readonly #onWakeSourceState: ((state: WakeSourceState) => void) | undefined;
|
|
35
39
|
readonly #cells = new Map<string, ManagedCell>();
|
|
36
|
-
readonly #
|
|
40
|
+
readonly #detached = new Map<string, ManagedCell>();
|
|
37
41
|
readonly #terminalSnapshots = new TerminalSnapshotStore();
|
|
38
42
|
readonly #notificationQueue: DetachedNotificationQueue;
|
|
39
43
|
readonly #now: () => number;
|
|
40
44
|
readonly #hardLimitSeconds: number;
|
|
41
45
|
readonly #runBudgetSeconds: number;
|
|
46
|
+
readonly #maxDetachedCells: number;
|
|
42
47
|
|
|
43
48
|
constructor(options: EvalDetachedCellManagerOptions = {}) {
|
|
44
49
|
this.#artifactsDir = options.artifactsDir;
|
|
@@ -48,6 +53,11 @@ export class EvalDetachedCellManager {
|
|
|
48
53
|
this.#now = options.now ?? Date.now;
|
|
49
54
|
this.#hardLimitSeconds = options.hardLimitSeconds ?? DEFAULT_HARD_LIMIT_SECONDS;
|
|
50
55
|
this.#runBudgetSeconds = options.runBudgetSeconds ?? DEFAULT_RUN_BUDGET_SECONDS;
|
|
56
|
+
this.#maxDetachedCells = options.maxDetachedCells ?? DEFAULT_MAX_DETACHED_CELLS;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
get maxDetachedCells(): number {
|
|
60
|
+
return this.#maxDetachedCells;
|
|
51
61
|
}
|
|
52
62
|
|
|
53
63
|
create(cellId: string, input: EvalToolInput, onKill?: (error: Error) => void): ManagedCell {
|
|
@@ -74,19 +84,27 @@ export class EvalDetachedCellManager {
|
|
|
74
84
|
return cell;
|
|
75
85
|
}
|
|
76
86
|
|
|
77
|
-
|
|
87
|
+
bindKernel(
|
|
78
88
|
cell: ManagedCell,
|
|
79
89
|
kernel: EvalKernel,
|
|
80
90
|
liveResult: LiveResultProvider,
|
|
81
91
|
onKill?: (error: Error) => void,
|
|
82
92
|
): void {
|
|
83
|
-
if (cell.state
|
|
93
|
+
if (!detachedCellIsActive(cell.state)) return;
|
|
84
94
|
cell.onKill = onKill ?? cell.onKill;
|
|
85
95
|
cell.kernel = kernel;
|
|
86
96
|
cell.liveResult = liveResult;
|
|
87
97
|
cell.canDetach = true;
|
|
88
98
|
}
|
|
89
99
|
|
|
100
|
+
markRunning(cell: ManagedCell): void {
|
|
101
|
+
if (!allowsDetachedCellTransition(cell.state, "running")) return;
|
|
102
|
+
cell.state = "running";
|
|
103
|
+
cell.runStartedAtMs = this.#now();
|
|
104
|
+
cell.deadlines.resume();
|
|
105
|
+
if (cell.detached) this.#emitStatus();
|
|
106
|
+
}
|
|
107
|
+
|
|
90
108
|
/** A host bridge call is in flight for this cell; its run budget stops charging until {@link resume}. */
|
|
91
109
|
pause(cell: ManagedCell): void {
|
|
92
110
|
cell.deadlines.pause();
|
|
@@ -99,19 +117,26 @@ export class EvalDetachedCellManager {
|
|
|
99
117
|
detach(cell: ManagedCell): boolean {
|
|
100
118
|
if (
|
|
101
119
|
!cell.canDetach ||
|
|
102
|
-
!
|
|
103
|
-
|
|
120
|
+
!detachedCellIsActive(cell.state) ||
|
|
121
|
+
cell.detached ||
|
|
122
|
+
!(this.#detached.size < this.#maxDetachedCells)
|
|
104
123
|
)
|
|
105
124
|
return false;
|
|
106
|
-
cell.
|
|
125
|
+
cell.detached = true;
|
|
107
126
|
cell.wasDetached = true;
|
|
108
|
-
this.#
|
|
127
|
+
this.#detached.set(cell.cellId, cell);
|
|
109
128
|
this.#emitStatus();
|
|
110
129
|
return true;
|
|
111
130
|
}
|
|
112
131
|
|
|
113
132
|
complete(cell: ManagedCell, result: AgentToolResult<EvalToolDetails>): boolean {
|
|
114
|
-
|
|
133
|
+
const state =
|
|
134
|
+
result.details.cells?.[0]?.status === "cancelled"
|
|
135
|
+
? "cancelled"
|
|
136
|
+
: result.details.isError === true
|
|
137
|
+
? "failed"
|
|
138
|
+
: "completed";
|
|
139
|
+
return this.#settle(cell, state, result);
|
|
115
140
|
}
|
|
116
141
|
|
|
117
142
|
fail(cell: ManagedCell, error: Error): boolean {
|
|
@@ -121,7 +146,8 @@ export class EvalDetachedCellManager {
|
|
|
121
146
|
async stop(cellId: string, reason = "Stopped detached eval cell"): Promise<EvalDetachedCellSnapshot> {
|
|
122
147
|
const live = this.#cells.get(cellId);
|
|
123
148
|
if (live === undefined) return this.#terminal(cellId);
|
|
124
|
-
if (live.state === "
|
|
149
|
+
if (live.state === "queued") this.#cancelQueued(live, reason);
|
|
150
|
+
else if (live.detached) await this.#cancel(live, reason);
|
|
125
151
|
return this.#snapshot(live);
|
|
126
152
|
}
|
|
127
153
|
|
|
@@ -130,9 +156,20 @@ export class EvalDetachedCellManager {
|
|
|
130
156
|
return live === undefined ? this.#terminal(cellId) : this.#snapshot(live);
|
|
131
157
|
}
|
|
132
158
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
159
|
+
liveCells(language?: EvalLanguage, opts?: { except?: string }): readonly EvalDetachedCellSnapshot[] {
|
|
160
|
+
return [...this.#cells.values()]
|
|
161
|
+
.filter(
|
|
162
|
+
(cell) =>
|
|
163
|
+
detachedCellIsActive(cell.state) &&
|
|
164
|
+
(language === undefined || cell.input.language === language) &&
|
|
165
|
+
cell.cellId !== opts?.except,
|
|
166
|
+
)
|
|
167
|
+
.sort((a, b) => a.startedAtMs - b.startedAtMs)
|
|
168
|
+
.map((cell) => this.#snapshot(cell));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
list(): { live: readonly EvalDetachedCellSnapshot[]; recent: readonly EvalDetachedCellSnapshot[] } {
|
|
172
|
+
return { live: this.liveCells(), recent: this.#terminalSnapshots.list() };
|
|
136
173
|
}
|
|
137
174
|
|
|
138
175
|
async waitForTerminal(cellId: string): Promise<EvalDetachedCellSnapshot> {
|
|
@@ -141,7 +178,11 @@ export class EvalDetachedCellManager {
|
|
|
141
178
|
}
|
|
142
179
|
|
|
143
180
|
async dispose(): Promise<void> {
|
|
144
|
-
const detached = [...this.#
|
|
181
|
+
const detached = [...this.#detached.values()];
|
|
182
|
+
// Dequeue first: interrupting an active run can synchronously start its next waiter.
|
|
183
|
+
for (const cell of detached) {
|
|
184
|
+
if (cell.state === "queued") this.#cancelQueued(cell, "Session ended; detached eval cell cancelled");
|
|
185
|
+
}
|
|
145
186
|
await Promise.allSettled(
|
|
146
187
|
detached.map(async (cell) => await this.stop(cell.cellId, "Session ended; detached eval cell cancelled")),
|
|
147
188
|
);
|
|
@@ -157,7 +198,7 @@ export class EvalDetachedCellManager {
|
|
|
157
198
|
|
|
158
199
|
/** Re-publish the current snapshot; consumers reset their per-source counts at session_start. */
|
|
159
200
|
publishWakeSourceState(): void {
|
|
160
|
-
this.#emitWakeSourceState([...this.#
|
|
201
|
+
this.#emitWakeSourceState([...this.#detached.values()]);
|
|
161
202
|
}
|
|
162
203
|
|
|
163
204
|
#settle(
|
|
@@ -174,8 +215,7 @@ export class EvalDetachedCellManager {
|
|
|
174
215
|
this.#cells.delete(cell.cellId);
|
|
175
216
|
this.#refreshTerminalSnapshot(cell);
|
|
176
217
|
if (cell.wasDetached) {
|
|
177
|
-
|
|
178
|
-
this.#detachedByLanguage.delete(cell.input.language);
|
|
218
|
+
this.#detached.delete(cell.cellId);
|
|
179
219
|
this.#emitStatus();
|
|
180
220
|
if (!cell.notificationQueued) {
|
|
181
221
|
cell.notificationQueued = true;
|
|
@@ -197,9 +237,13 @@ export class EvalDetachedCellManager {
|
|
|
197
237
|
*/
|
|
198
238
|
async #expireDeadline(cell: ManagedCell, expiry: CellDeadlineExpiry): Promise<void> {
|
|
199
239
|
if (!detachedCellIsActive(cell.state)) return;
|
|
200
|
-
const foreground = cell.
|
|
240
|
+
const foreground = !cell.detached && cell.onKill !== undefined;
|
|
201
241
|
cell.hardLimited = expiry.kind === "hard-limit";
|
|
202
242
|
cell.runBudgetExhausted = expiry.kind === "run-budget";
|
|
243
|
+
if (cell.state === "queued") {
|
|
244
|
+
this.#cancelQueued(cell, expiry.error.message, expiry.error);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
203
247
|
if (foreground) {
|
|
204
248
|
if (this.#settle(cell, "cancelled", currentDetachedResult(cell))) cell.onKill?.(expiry.error);
|
|
205
249
|
return;
|
|
@@ -207,12 +251,20 @@ export class EvalDetachedCellManager {
|
|
|
207
251
|
await this.#cancel(cell, expiry.error.message);
|
|
208
252
|
}
|
|
209
253
|
|
|
254
|
+
#cancelQueued(cell: ManagedCell, reason: string, error = new Error(reason)): void {
|
|
255
|
+
const dequeued = cell.kernel?.cancelQueued(cell.cellId, reason) ?? false;
|
|
256
|
+
cell.stateRetained = true;
|
|
257
|
+
this.#settle(cell, "cancelled", currentDetachedResult(cell));
|
|
258
|
+
// Acquisition/reset has no queue promise yet; its execution has no interrupt target either.
|
|
259
|
+
if (!dequeued) cell.onKill?.(error);
|
|
260
|
+
}
|
|
261
|
+
|
|
210
262
|
async #cancel(cell: ManagedCell, reason: string): Promise<void> {
|
|
211
263
|
const outcome = Promise.withResolvers<void>();
|
|
212
264
|
cell.interruptOutcome = outcome;
|
|
213
265
|
try {
|
|
214
266
|
if (!this.#settle(cell, "cancelled", currentDetachedResult(cell)) || cell.kernel === undefined) return;
|
|
215
|
-
const handle = await cell.kernel.interrupt(reason);
|
|
267
|
+
const handle = await cell.kernel.interrupt(reason, cell.cellId);
|
|
216
268
|
cell.interruptNote = handle.note;
|
|
217
269
|
cell.stateRetained = await handle.stateRetained;
|
|
218
270
|
} finally {
|
|
@@ -226,7 +278,7 @@ export class EvalDetachedCellManager {
|
|
|
226
278
|
}
|
|
227
279
|
|
|
228
280
|
#emitStatus(): void {
|
|
229
|
-
const liveCells = [...this.#
|
|
281
|
+
const liveCells = [...this.#detached.values()];
|
|
230
282
|
this.#onStatusChange?.(detachedStatusEntries(liveCells));
|
|
231
283
|
this.#emitWakeSourceState(liveCells);
|
|
232
284
|
}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import type { AgentToolResult } from "@code-yeongyu/senpi";
|
|
2
2
|
import type { EvalDetachedCellSnapshot, EvalDetachedCellState } from "./detached-cell-manager.ts";
|
|
3
3
|
import { resultForDetachedState } from "./detached-eval-result.ts";
|
|
4
|
+
import { EvalKernelResetRefusedError } from "./eval-kernel-reset-refused-error.ts";
|
|
4
5
|
import type { EvalKernel, EvalToolDetails, EvalToolInput } from "./types.ts";
|
|
5
6
|
|
|
6
7
|
export interface DetachedCellResultSource {
|
|
7
8
|
readonly cellId: string;
|
|
8
9
|
readonly input: EvalToolInput;
|
|
9
10
|
readonly startedAtMs: number;
|
|
11
|
+
readonly runStartedAtMs?: number | undefined;
|
|
12
|
+
readonly detached?: boolean;
|
|
10
13
|
state: EvalDetachedCellState;
|
|
11
14
|
kernel: EvalKernel | undefined;
|
|
12
15
|
stateRetained: boolean | undefined;
|
|
@@ -20,12 +23,16 @@ export interface DetachedCellResultSource {
|
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
export function snapshotDetachedCell(cell: DetachedCellResultSource, nowMs: number): EvalDetachedCellSnapshot {
|
|
23
|
-
const durationMs = Math.max(0, nowMs - cell.
|
|
24
|
-
const
|
|
26
|
+
const durationMs = cell.runStartedAtMs === undefined ? 0 : Math.max(0, nowMs - cell.runStartedAtMs);
|
|
27
|
+
const state = cell.detached && (cell.state === "queued" || cell.state === "running") ? "detached" : cell.state;
|
|
28
|
+
const queuedBehind = queuedBehindCell(cell);
|
|
29
|
+
const result = resultForDetachedState(currentDetachedResult(cell), state, durationMs, queuedBehind);
|
|
25
30
|
return {
|
|
26
31
|
cellId: cell.cellId,
|
|
27
32
|
language: cell.input.language,
|
|
28
|
-
|
|
33
|
+
startedAtMs: cell.startedAtMs,
|
|
34
|
+
state,
|
|
35
|
+
...(queuedBehind === undefined ? {} : { queuedBehind }),
|
|
29
36
|
outputTail: detachedOutputTail(result),
|
|
30
37
|
result,
|
|
31
38
|
stateRetained: cell.stateRetained,
|
|
@@ -39,6 +46,19 @@ export function snapshotDetachedCell(cell: DetachedCellResultSource, nowMs: numb
|
|
|
39
46
|
};
|
|
40
47
|
}
|
|
41
48
|
|
|
49
|
+
export function queuedBehindCell(
|
|
50
|
+
cell: Pick<DetachedCellResultSource, "state" | "kernel" | "cellId">,
|
|
51
|
+
): readonly string[] | undefined {
|
|
52
|
+
if (cell.state !== "queued") return undefined;
|
|
53
|
+
const queue = cell.kernel?.queueSnapshot();
|
|
54
|
+
if (queue === undefined) return [];
|
|
55
|
+
const index = queue.queuedCellIds.indexOf(cell.cellId);
|
|
56
|
+
return [
|
|
57
|
+
...(queue.activeCellId === null || queue.activeCellId === cell.cellId ? [] : [queue.activeCellId]),
|
|
58
|
+
...queue.queuedCellIds.slice(0, index < 0 ? undefined : index),
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
|
|
42
62
|
export function currentDetachedResult(cell: DetachedCellResultSource): AgentToolResult<EvalToolDetails> {
|
|
43
63
|
return cell.terminalResult ?? cell.liveResult?.() ?? fallbackResult(cell.input);
|
|
44
64
|
}
|
|
@@ -54,7 +74,11 @@ export function detachedErrorResult(cell: DetachedCellResultSource, error: Error
|
|
|
54
74
|
},
|
|
55
75
|
...current.content.filter((part) => part.type === "image"),
|
|
56
76
|
],
|
|
57
|
-
details: {
|
|
77
|
+
details: {
|
|
78
|
+
...current.details,
|
|
79
|
+
isError: true,
|
|
80
|
+
...(error instanceof EvalKernelResetRefusedError ? { code: error.code } : {}),
|
|
81
|
+
},
|
|
58
82
|
};
|
|
59
83
|
}
|
|
60
84
|
|
|
@@ -5,20 +5,21 @@ interface DetachedCellIdentity {
|
|
|
5
5
|
readonly cellId: string;
|
|
6
6
|
readonly input: EvalToolInput;
|
|
7
7
|
readonly state: EvalDetachedCellState;
|
|
8
|
+
readonly detached?: boolean;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export function activeDetachedCellReuseError(cell: DetachedCellIdentity): Error {
|
|
11
12
|
return new Error(
|
|
12
|
-
`Eval cell ${cell.cellId} from a previous call is still ${cell.state} in the ${cell.input.language} kernel. Use eval({ action: "peek", cell_id: "${cell.cellId}" }) to read it or eval({ action: "stop", cell_id: "${cell.cellId}" }) to end it before its id can be reused.`,
|
|
13
|
+
`Eval cell ${cell.cellId} from a previous call is still ${cell.detached ? "detached" : cell.state} in the ${cell.input.language} kernel. Use eval({ action: "peek", cell_id: "${cell.cellId}" }) to read it or eval({ action: "stop", cell_id: "${cell.cellId}" }) to end it before its id can be reused.`,
|
|
13
14
|
);
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
export function allowsDetachedCellTransition(from: EvalDetachedCellState, to: EvalDetachedCellState): boolean {
|
|
17
|
-
if (from === "
|
|
18
|
-
if (from === "
|
|
18
|
+
if (from === "queued") return to === "running" || to === "failed" || to === "cancelled";
|
|
19
|
+
if (from === "running") return to === "completed" || to === "failed" || to === "cancelled";
|
|
19
20
|
return false;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export function detachedCellIsActive(state: EvalDetachedCellState): boolean {
|
|
23
|
-
return state === "running" || state === "detached";
|
|
24
|
+
return state === "queued" || state === "running" || state === "detached";
|
|
24
25
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { SENPI_CODEMODE_WAKE_SOURCE, type WakeSourceState } from "../extension/wake-source-state.ts";
|
|
2
2
|
import type { EvalDetachedCellStatusEntry } from "./detached-cell-manager.ts";
|
|
3
|
+
import { queuedBehindCell } from "./detached-cell-snapshot.ts";
|
|
4
|
+
import type { ManagedCell } from "./managed-cell.ts";
|
|
3
5
|
|
|
4
6
|
export interface LiveDetachedCell {
|
|
5
7
|
readonly cellId: string;
|
|
@@ -7,11 +9,12 @@ export interface LiveDetachedCell {
|
|
|
7
9
|
readonly input: { readonly language: EvalDetachedCellStatusEntry["language"]; readonly summary?: string };
|
|
8
10
|
}
|
|
9
11
|
|
|
10
|
-
export function detachedStatusEntries(liveCells: readonly
|
|
12
|
+
export function detachedStatusEntries(liveCells: readonly ManagedCell[]): EvalDetachedCellStatusEntry[] {
|
|
11
13
|
return liveCells.map((cell) => ({
|
|
12
14
|
cellId: cell.cellId,
|
|
13
15
|
language: cell.input.language,
|
|
14
|
-
startedAtMs: cell.startedAtMs,
|
|
16
|
+
startedAtMs: cell.runStartedAtMs ?? cell.startedAtMs,
|
|
17
|
+
...(cell.state === "queued" ? { queuedBehind: queuedBehindCell(cell) } : {}),
|
|
15
18
|
...(cell.input.summary === undefined ? {} : { summary: cell.input.summary }),
|
|
16
19
|
}));
|
|
17
20
|
}
|
|
@@ -5,27 +5,87 @@ import type {
|
|
|
5
5
|
EvalDetachedCellState,
|
|
6
6
|
} from "./detached-cell-manager.ts";
|
|
7
7
|
import { interruptionStateNote } from "./interrupt-note.ts";
|
|
8
|
-
import type {
|
|
8
|
+
import type {
|
|
9
|
+
EvalCellResult,
|
|
10
|
+
EvalControlInput,
|
|
11
|
+
EvalListDetails,
|
|
12
|
+
EvalListedCell,
|
|
13
|
+
EvalResultDetails,
|
|
14
|
+
EvalToolDetails,
|
|
15
|
+
EvalToolInput,
|
|
16
|
+
} from "./types.ts";
|
|
17
|
+
|
|
18
|
+
export class EvalBackgroundCapacityError extends Error {
|
|
19
|
+
readonly code = "eval_background_capacity_reached";
|
|
20
|
+
readonly name = "EvalBackgroundCapacityError";
|
|
21
|
+
|
|
22
|
+
constructor(cap: number, cellId: string, foregroundMs: number, liveCellIds: readonly string[]) {
|
|
23
|
+
super(
|
|
24
|
+
`Background capacity (${cap}) reached: cell ${cellId} ran ${Math.floor(foregroundMs / 1_000)}s in the foreground and was cancelled when the foreground window elapsed. Live cells: ${liveCellIds.join(", ")}. Stop one with eval({ action: "stop", cell_id }) or wait for a notification, then re-run this step.`,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
9
28
|
|
|
10
29
|
export async function executeEvalControl(
|
|
11
30
|
cellManager: EvalDetachedCellManager,
|
|
12
31
|
request: EvalControlInput,
|
|
13
|
-
): Promise<AgentToolResult<
|
|
32
|
+
): Promise<AgentToolResult<EvalResultDetails>> {
|
|
33
|
+
if (request.action === "list") return createEvalListResult(cellManager);
|
|
14
34
|
const snapshot =
|
|
15
35
|
request.action === "stop" ? await cellManager.stop(request.cell_id) : cellManager.peek(request.cell_id);
|
|
16
36
|
return createDetachedControlResult(snapshot);
|
|
17
37
|
}
|
|
18
38
|
|
|
39
|
+
function createEvalListResult(cellManager: EvalDetachedCellManager): AgentToolResult<EvalListDetails> {
|
|
40
|
+
const { live, recent } = cellManager.list();
|
|
41
|
+
const snapshots = [...live, ...recent];
|
|
42
|
+
const cells: EvalListedCell[] = snapshots.map((snapshot) => {
|
|
43
|
+
const summary = snapshot.result.details.summary;
|
|
44
|
+
return {
|
|
45
|
+
cellId: snapshot.cellId,
|
|
46
|
+
language: snapshot.language,
|
|
47
|
+
state: snapshot.state,
|
|
48
|
+
startedAtMs: snapshot.startedAtMs,
|
|
49
|
+
...(snapshot.queuedBehind === undefined || snapshot.queuedBehind.length === 0
|
|
50
|
+
? {}
|
|
51
|
+
: { queuedBehind: [...snapshot.queuedBehind] }),
|
|
52
|
+
...(summary ? { summary } : {}),
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
const text = snapshots
|
|
56
|
+
.map((snapshot, index) => {
|
|
57
|
+
const cell = cells[index];
|
|
58
|
+
const preview = (cell.summary || snapshot.result.details.cells?.[0]?.code?.slice(0, 60) || "").replace(
|
|
59
|
+
/\s+/gu,
|
|
60
|
+
" ",
|
|
61
|
+
);
|
|
62
|
+
const elapsed = Math.floor(snapshot.result.details.durationMs / 1000);
|
|
63
|
+
const queued = cell.queuedBehind === undefined ? "" : ` queued behind ${cell.queuedBehind.join(", ")}`;
|
|
64
|
+
return `${cell.cellId} ${cell.language} ${cell.state} ${elapsed}s${queued} - ${preview}`;
|
|
65
|
+
})
|
|
66
|
+
.join("\n");
|
|
67
|
+
return {
|
|
68
|
+
content: [{ type: "text", text: text || "No eval cells are live; recent: none" }],
|
|
69
|
+
details: { action: "list", cells },
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
19
73
|
export function resultAfterDetach(
|
|
20
74
|
snapshot: EvalDetachedCellSnapshot,
|
|
21
75
|
input: EvalToolInput,
|
|
76
|
+
otherLiveCells: number,
|
|
22
77
|
): AgentToolResult<EvalToolDetails> {
|
|
23
78
|
if (snapshot.state !== "detached" && snapshot.state !== "running") return createDetachedControlResult(snapshot);
|
|
79
|
+
const predecessors = snapshot.queuedBehind?.join(", ");
|
|
80
|
+
const text =
|
|
81
|
+
predecessors === undefined
|
|
82
|
+
? `Eval cell ${snapshot.cellId} detached and is running in the ${input.language} kernel (${otherLiveCells} other live cells). Completion arrives as a notification; do not re-run it. eval({ action: "peek" | "stop", cell_id }) or eval({ action: "list" }).`
|
|
83
|
+
: `Eval cell ${snapshot.cellId} is queued behind ${predecessors} in the ${input.language} kernel and detached; it runs after ${predecessors} and completes as one notification. peek/stop/list with eval({ action, cell_id })`;
|
|
24
84
|
return {
|
|
25
85
|
content: [
|
|
26
86
|
{
|
|
27
87
|
type: "text",
|
|
28
|
-
text
|
|
88
|
+
text,
|
|
29
89
|
},
|
|
30
90
|
],
|
|
31
91
|
details: snapshot.result.details,
|
|
@@ -55,21 +115,23 @@ export function resultForDetachedState(
|
|
|
55
115
|
result: AgentToolResult<EvalToolDetails>,
|
|
56
116
|
state: EvalDetachedCellState,
|
|
57
117
|
durationMs: number,
|
|
118
|
+
queuedBehind?: readonly string[],
|
|
58
119
|
): AgentToolResult<EvalToolDetails> {
|
|
59
120
|
const details = result.details;
|
|
60
121
|
const cells = details.cells ?? [];
|
|
61
122
|
const nextCells =
|
|
62
123
|
cells.length === 0
|
|
63
124
|
? []
|
|
64
|
-
: cells.map((cell, index) =>
|
|
65
|
-
index
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
: {
|
|
72
|
-
|
|
125
|
+
: cells.map((cell, index) => {
|
|
126
|
+
if (index !== 0) return { ...cell };
|
|
127
|
+
const { queuedBehind: _previousQueue, ...current } = cell;
|
|
128
|
+
return {
|
|
129
|
+
...current,
|
|
130
|
+
durationMs: terminalDuration(cell, state, durationMs),
|
|
131
|
+
status: state === "detached" && queuedBehind !== undefined ? "queued" : cellStatus(state),
|
|
132
|
+
...(queuedBehind === undefined ? {} : { queuedBehind }),
|
|
133
|
+
};
|
|
134
|
+
});
|
|
73
135
|
return {
|
|
74
136
|
content: result.content.map((part) => ({ ...part })),
|
|
75
137
|
details: {
|
|
@@ -102,19 +164,6 @@ export function resultForDetachedState(
|
|
|
102
164
|
};
|
|
103
165
|
}
|
|
104
166
|
|
|
105
|
-
export function detachedKernelBusyError(
|
|
106
|
-
snapshot: EvalDetachedCellSnapshot,
|
|
107
|
-
idleLanguages: readonly EvalLanguage[] = [],
|
|
108
|
-
): Error {
|
|
109
|
-
const tail = snapshot.outputTail.length === 0 ? "(no output yet)" : snapshot.outputTail;
|
|
110
|
-
const peek = `eval({ action: "peek", cell_id: "${snapshot.cellId}" })`;
|
|
111
|
-
const idleHint =
|
|
112
|
-
idleLanguages.length === 0 ? "" : ` or continue this step in an idle kernel: ${idleLanguages.join(", ")}`;
|
|
113
|
-
return new Error(
|
|
114
|
-
`The ${snapshot.language} eval kernel is busy running detached cell ${snapshot.cellId} - peek with ${peek}${idleHint}. Do not re-run the busy cell. Current output tail:\n${tail}`,
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
167
|
function textContent(result: AgentToolResult<EvalToolDetails>): string {
|
|
119
168
|
return result.content
|
|
120
169
|
.filter((part) => part.type === "text")
|
|
@@ -133,6 +182,8 @@ function terminalDuration(
|
|
|
133
182
|
|
|
134
183
|
function cellStatus(state: EvalDetachedCellState): EvalCellResult["status"] {
|
|
135
184
|
switch (state) {
|
|
185
|
+
case "queued":
|
|
186
|
+
return "queued";
|
|
136
187
|
case "running":
|
|
137
188
|
return "running";
|
|
138
189
|
case "detached":
|
|
@@ -30,6 +30,7 @@ interface EvalExecutionBasePayload {
|
|
|
30
30
|
readonly completedAt: number;
|
|
31
31
|
readonly durationMs: number;
|
|
32
32
|
readonly kernelDurationMs?: number;
|
|
33
|
+
readonly queued_ms: number;
|
|
33
34
|
readonly detached: boolean;
|
|
34
35
|
readonly toolCallCount: number;
|
|
35
36
|
readonly pendingToolCallCount: number;
|
|
@@ -66,6 +67,7 @@ export interface BuildEvalExecutionEventPayloadOptions {
|
|
|
66
67
|
readonly state: CellState;
|
|
67
68
|
readonly outcome: EvalExecutionSettleOutcome;
|
|
68
69
|
readonly completedAt: number;
|
|
70
|
+
readonly queuedMs?: number;
|
|
69
71
|
readonly detached: boolean;
|
|
70
72
|
}
|
|
71
73
|
|
|
@@ -87,6 +89,7 @@ export function buildEvalExecutionEventPayload(
|
|
|
87
89
|
startedAt: state.startedAt,
|
|
88
90
|
completedAt,
|
|
89
91
|
durationMs: Math.max(0, completedAt - state.startedAt),
|
|
92
|
+
queued_ms: options.queuedMs ?? 0,
|
|
90
93
|
...(result === undefined ? {} : { kernelDurationMs: result.details.durationMs }),
|
|
91
94
|
detached,
|
|
92
95
|
toolCallCount: state.toolCallMetrics.length,
|
|
@@ -110,6 +113,7 @@ export function toEvalExecutionRpcPayload(payload: EvalExecutionEventPayload): E
|
|
|
110
113
|
startedAt: payload.startedAt,
|
|
111
114
|
completedAt: payload.completedAt,
|
|
112
115
|
durationMs: payload.durationMs,
|
|
116
|
+
queued_ms: payload.queued_ms,
|
|
113
117
|
...(payload.kernelDurationMs === undefined ? {} : { kernelDurationMs: payload.kernelDurationMs }),
|
|
114
118
|
detached: payload.detached,
|
|
115
119
|
toolCallCount: payload.toolCallCount,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { EvalLanguage } from "./types.ts";
|
|
2
|
+
|
|
3
|
+
export class EvalKernelResetRefusedError extends Error {
|
|
4
|
+
readonly name = "EvalKernelResetRefusedError";
|
|
5
|
+
readonly code = "eval_kernel_busy_reset_refused";
|
|
6
|
+
|
|
7
|
+
constructor(language: EvalLanguage, liveCellIds: readonly string[]) {
|
|
8
|
+
super(
|
|
9
|
+
`eval_kernel_busy_reset_refused: Cannot reset the ${language} kernel: live cells ${liveCellIds.join(", ")}. Stop them with eval({ action: "stop", cell_id }) or wait for their notifications, then reset.`,
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -18,6 +18,7 @@ export function clampEvalSummary(value: unknown): string | undefined {
|
|
|
18
18
|
|
|
19
19
|
export function parseEvalRequest(params: unknown): EvalToolRequest {
|
|
20
20
|
if (!isRecord(params)) throw new TypeError("eval parameters must be an object");
|
|
21
|
+
if (params.action === "list") return { action: "list" };
|
|
21
22
|
if (params.action === "peek" || params.action === "stop") {
|
|
22
23
|
if (typeof params.cell_id !== "string" || params.cell_id.length === 0)
|
|
23
24
|
throw new TypeError(`eval action "${params.action}" requires cell_id`);
|
|
@@ -46,7 +47,7 @@ export function parseEvalRequest(params: unknown): EvalToolRequest {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
export function isEvalControlRequest(request: EvalToolRequest): request is EvalControlInput {
|
|
49
|
-
return request.action === "peek" || request.action === "stop";
|
|
50
|
+
return request.action === "peek" || request.action === "stop" || request.action === "list";
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
export function evalTimeoutBehavior(input: EvalToolInput, ctx: ExtensionContext): "detach" | "error" {
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
EnabledEvalLanguages,
|
|
12
12
|
EvalInputSchema,
|
|
13
13
|
EvalKernelManager,
|
|
14
|
+
EvalResultDetails,
|
|
14
15
|
EvalRuntimes,
|
|
15
16
|
EvalToolDetails,
|
|
16
17
|
EvalToolInput,
|
|
@@ -34,6 +35,7 @@ export interface CreateEvalToolOptions {
|
|
|
34
35
|
* replaces it. Rendered into the tool schema and description; also seeds a self-created manager.
|
|
35
36
|
*/
|
|
36
37
|
readonly runBudgetSeconds?: number;
|
|
38
|
+
readonly maxDetachedCells?: number;
|
|
37
39
|
readonly executeTool: ExecuteTool;
|
|
38
40
|
readonly listTools?: () => readonly EvalSchemaToolInfo[];
|
|
39
41
|
readonly complete?: (request: CompletionRequest, ctx: ExtensionContext) => Promise<CompletionResult>;
|
|
@@ -45,7 +47,7 @@ export interface CreateEvalToolOptions {
|
|
|
45
47
|
readonly onCellSettled?: (payload: EvalExecutionEventPayload) => void;
|
|
46
48
|
readonly timeoutFactory?: EvalTimeoutFactory;
|
|
47
49
|
readonly proxyExecutor?: (params: EvalToolInput, signal?: AbortSignal) => Promise<AgentToolResult<EvalToolDetails>>;
|
|
48
|
-
readonly renderers?: Pick<ToolDefinition<EvalInputSchema,
|
|
50
|
+
readonly renderers?: Pick<ToolDefinition<EvalInputSchema, EvalResultDetails>, "renderCall" | "renderResult">;
|
|
49
51
|
readonly spawns?: boolean;
|
|
50
52
|
/** Whether the session registry exposes the monitor tool through eval. */
|
|
51
53
|
readonly monitor?: boolean;
|