@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
|
@@ -93,6 +93,7 @@ Configuration is loaded in this order:
|
|
|
93
93
|
"foregroundWindowSeconds": 60,
|
|
94
94
|
"runBudgetSeconds": 300,
|
|
95
95
|
"hardLimitSeconds": 1800,
|
|
96
|
+
"maxDetachedCells": 15,
|
|
96
97
|
"parallelPoolWidth": 4,
|
|
97
98
|
"taskTools": {
|
|
98
99
|
"task": "task",
|
|
@@ -110,9 +111,10 @@ Configuration is loaded in this order:
|
|
|
110
111
|
| --- | --- | --- |
|
|
111
112
|
| `languages` | `py`/`js` enabled; `rb`/`jl` disabled | Selects desired languages before interpreter detection. |
|
|
112
113
|
| `cellTimeoutSeconds` | `30` | Idle time an interactive call blocks the turn before the cell detaches. Print/json calls never detach. |
|
|
113
|
-
| `foregroundWindowSeconds` | `60` |
|
|
114
|
-
| `runBudgetSeconds` | `300` | Kill deadline for a cell's own execution time - child processes, network, timers, CPU. Time parked in host tool calls (`agent()`, `tool.*`) is not charged, and the budget keeps counting after the cell detaches. A per-call `timeout` replaces it for that cell. Env override: `SENPI_CODEMODE_RUN_BUDGET_SECONDS`. |
|
|
115
|
-
| `hardLimitSeconds` | `1800` | Wall-clock kill deadline
|
|
114
|
+
| `foregroundWindowSeconds` | `60` | Submission-based foreground limit, including queue and bridge pauses. The cell detaches if capacity is available; otherwise it is cancelled with `eval_background_capacity_reached`. Env override: `SENPI_CODEMODE_FOREGROUND_SECONDS`. |
|
|
115
|
+
| `runBudgetSeconds` | `300` | Kill deadline for a cell's own execution time - child processes, network, timers, CPU. Time queued or parked in host tool calls (`agent()`, `tool.*`) is not charged, and the budget keeps counting after the cell detaches. A per-call `timeout` replaces it for that cell. Env override: `SENPI_CODEMODE_RUN_BUDGET_SECONDS`. |
|
|
116
|
+
| `hardLimitSeconds` | `1800` | Wall-clock kill deadline from submission, including queue and parked time; a per-call `timeout` above it raises it. Env override: `SENPI_CODEMODE_HARD_LIMIT_SECONDS`. |
|
|
117
|
+
| `maxDetachedCells` | `15` | Global detached-cell capacity across all kernels, including queued cells. At capacity, interactive cells stay foreground until completion or the foreground window elapses. Env override: `SENPI_CODEMODE_MAX_DETACHED_CELLS`. |
|
|
116
118
|
| `parallelPoolWidth` | `4` | Maximum concurrent `parallel()` thunks. |
|
|
117
119
|
| `taskTools.task` | `"task"` | Registered tool name used by `agent()`. |
|
|
118
120
|
| `taskTools.output` | `"task_output"` | Registered tool name used by `output()`. |
|
|
@@ -126,6 +128,9 @@ enables; `0` or `false` disables. Any other value leaves the file setting in
|
|
|
126
128
|
effect.
|
|
127
129
|
|
|
128
130
|
Malformed JSON or invalid settings fall back to defaults with a warning.
|
|
131
|
+
The detached-cell environment override uses the run-budget parser: a positive
|
|
132
|
+
base-10 integer wins over the file value; zero, negative, and malformed values
|
|
133
|
+
leave the file value in effect.
|
|
129
134
|
|
|
130
135
|
## Cell helpers
|
|
131
136
|
|
|
@@ -162,13 +167,25 @@ tasks return the requested transcript. Missing tools produce a clear
|
|
|
162
167
|
availability error instead of importing an orchestration package. `agent()`
|
|
163
168
|
delegates through the tool contract, so task-engine permissions, progress
|
|
164
169
|
updates, and transcripts remain owned by that engine.
|
|
165
|
-
`isolated
|
|
166
|
-
|
|
170
|
+
`isolated` and `apply` accept booleans; `merge` accepts `"patch"` or `"branch"`
|
|
171
|
+
(and `false`/`true` aliases respectively). The bridge checks the configured task
|
|
172
|
+
parameter schema once per bridge, using the same host catalog as `tool_schema()`.
|
|
173
|
+
If it advertises `isolated`, these options are forwarded; otherwise they are
|
|
174
|
+
omitted with the existing warning. Senpi does not implement isolation itself.
|
|
175
|
+
A foreground host result with `details.isolation.changes_applied === false`
|
|
176
|
+
raises `AgentIsolationNotAppliedError` (`isolation_not_applied`), including any
|
|
177
|
+
`patch_path`, `branch_name`, and `manual_command` recovery fields in its message.
|
|
178
|
+
The bridge retains host `details.isolation`; successful foreground helpers still
|
|
179
|
+
return text or parsed JSON.
|
|
167
180
|
|
|
168
181
|
Background `agent()` handles retain `id` and `agent://<id>` and include `run_epoch`.
|
|
169
182
|
The host must return structured `details.task_id` (`st_` plus lowercase hex) and
|
|
170
183
|
an integer `details.run_epoch >= 0`. Missing or malformed details raise
|
|
171
|
-
`invalid_task_handle`; prose IDs are never used.
|
|
184
|
+
`invalid_task_handle`; prose IDs are never used. Handles return immediately,
|
|
185
|
+
so final isolation results are not available on the initial handle: await the
|
|
186
|
+
completion notification or read `task_output` (via `output()`) after completion.
|
|
187
|
+
Any isolation metadata supplied by the host on a handle is preserved as
|
|
188
|
+
`details.isolation`, not interpreted as a foreground apply failure.
|
|
172
189
|
|
|
173
190
|
`workpool` takes exactly one of `{category, prompt, model?}` or
|
|
174
191
|
`{subagent_type, prompt, model?}` as its plain-data agent spec. Mode is `fresh`
|
|
@@ -203,22 +220,28 @@ without a `summary` fails with a teaching error.
|
|
|
203
220
|
`eval` accepts `on_timeout: "detach"|"error"`. The default is `"detach"` in
|
|
204
221
|
interactive TUI, RPC, and app-server sessions; print and JSON one-shot runs
|
|
205
222
|
default to `"error"` so their result is never silently detached. A detached
|
|
206
|
-
cell keeps only its own language kernel busy.
|
|
207
|
-
|
|
208
|
-
|
|
223
|
+
cell keeps only its own language kernel busy. New same-language cells are admitted
|
|
224
|
+
into its FIFO queue; calls in other languages continue normally. Queued cells may
|
|
225
|
+
also detach, within the global `maxDetachedCells` cap. At capacity, the first idle
|
|
226
|
+
detach attempt leaves the cell foreground and re-arms one wait for the remaining
|
|
227
|
+
submission-based foreground window. At the window, it detaches if a slot is now
|
|
228
|
+
free; otherwise it settles `cancelled` with `eval_background_capacity_reached`,
|
|
229
|
+
listing the live cells and a stop-or-wait remedy. Cells that complete inside the
|
|
230
|
+
window return normally. Cancelling a queued cell never interrupts its predecessor.
|
|
231
|
+
Do not re-run a detached or queued cell; each detached cell completes as one notification.
|
|
209
232
|
|
|
210
233
|
Queued steering also detaches an eligible interactive foreground call, including
|
|
211
234
|
one paused in a host tool bridge, without cancelling its computation. If the
|
|
212
|
-
|
|
235
|
+
global detached cap is reached, steering leaves the call waiting. Follow-up
|
|
213
236
|
messages, explicit `on_timeout: "error"`, and print/JSON calls do not trigger this
|
|
214
237
|
transition; caller abort and existing deadlines retain their cancellation behavior.
|
|
215
238
|
|
|
216
239
|
Every cell, detached or not, is bounded by two kill deadlines. The run budget
|
|
217
240
|
(`runBudgetSeconds`, or the call's `timeout`) charges only the cell's own
|
|
218
|
-
execution time and is paused while a host tool call is in flight, so a cell
|
|
241
|
+
execution time and is paused while queued or while a host tool call is in flight, so a cell
|
|
219
242
|
waiting on `agent()` survives while a runaway child process or loop does not.
|
|
220
243
|
The hard limit (`hardLimitSeconds`, raised by a larger `timeout`) is wall-clock
|
|
221
|
-
and bounds parked cells too. A cell killed by either deadline reports which one
|
|
244
|
+
from submission and bounds queued and parked cells too. A cell killed by either deadline reports which one
|
|
222
245
|
in its result or completion notification, together with whether kernel state
|
|
223
246
|
survived; the tool schema states the configured numbers. The `timeout` value
|
|
224
247
|
never changes the idle detach deadline: that is `cellTimeoutSeconds` capped by
|
|
@@ -227,9 +250,24 @@ never changes the idle detach deadline: that is `cellTimeoutSeconds` capped by
|
|
|
227
250
|
While any cell is detached, the interactive footer shows a highlighted
|
|
228
251
|
`↗ <language> · <summary>` status on the extension status line (the cell id
|
|
229
252
|
when the call had no summary), clearing as soon as the last detached cell settles.
|
|
253
|
+
Queued entries are labelled `queued`; an all-queued footer shows `(queued)` instead
|
|
254
|
+
of an elapsed duration. Elapsed time counts only from execution start.
|
|
255
|
+
|
|
256
|
+
Use `eval({ action: "list" })` without a language or cell id to see live and
|
|
257
|
+
recently settled cells across languages. Each line includes the id, language,
|
|
258
|
+
state, elapsed execution seconds, queue predecessors, and summary (or a short code
|
|
259
|
+
preview); `details.cells` carries the typed cell metadata. Listing never consumes
|
|
260
|
+
completion notifications.
|
|
261
|
+
|
|
262
|
+
A run with `reset: true` resets only its selected language and is refused with
|
|
263
|
+
`eval_kernel_busy_reset_refused` while any other cell in that language is live,
|
|
264
|
+
including queued cells. The requesting cell fails without changing the kernel or
|
|
265
|
+
cancelling existing work. Stop those cells explicitly or wait for their completion
|
|
266
|
+
notifications before resetting; live cells in other languages do not block reset.
|
|
230
267
|
|
|
231
268
|
Use `eval({ action: "peek", cell_id })` for its state and buffered output, or
|
|
232
|
-
`eval({ action: "stop", cell_id })` to cancel it.
|
|
269
|
+
`eval({ action: "stop", cell_id })` to cancel it. Stopping a queued cell removes it
|
|
270
|
+
without interrupting the active cell; kernel state is retained. Python running-cell stop interrupts the
|
|
233
271
|
existing kernel and preserves variables. JavaScript stop is cooperative first:
|
|
234
272
|
the worker rejects the cell's pending bridge `tool.*` calls and kills the
|
|
235
273
|
`Bun.spawn` children it started, and a cell that settles within the 2 s grace
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/senpi-codemode",
|
|
3
|
-
"version": "2026.9.
|
|
3
|
+
"version": "2026.9.22-2",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Source-only senpi extension package for codemode evaluation tools",
|
|
6
6
|
"type": "module",
|
|
@@ -31,14 +31,14 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@babel/parser": "8.0.4",
|
|
34
|
-
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.
|
|
34
|
+
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.22-2",
|
|
35
35
|
"typebox": "1.3.34"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@code-yeongyu/senpi": "2026.9.
|
|
38
|
+
"@code-yeongyu/senpi": "2026.9.22-2"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@code-yeongyu/senpi": "2026.9.
|
|
41
|
+
"@code-yeongyu/senpi": "2026.9.22-2"
|
|
42
42
|
},
|
|
43
43
|
"keywords": [
|
|
44
44
|
"senpi",
|
|
@@ -2,6 +2,7 @@ import type { AgentToolResult } from "@code-yeongyu/senpi";
|
|
|
2
2
|
import { type Static, Type } from "typebox";
|
|
3
3
|
import { Check, Errors } from "typebox/value";
|
|
4
4
|
import type { EvalStatusEvent, ExecuteTool } from "../tool/types.ts";
|
|
5
|
+
import type { EvalSchemaToolInfo } from "./schema-bridge.ts";
|
|
5
6
|
|
|
6
7
|
const agentArgsSchema = Type.Object(
|
|
7
8
|
{
|
|
@@ -14,7 +15,7 @@ const agentArgsSchema = Type.Object(
|
|
|
14
15
|
tools: Type.Optional(Type.Array(Type.String({ minLength: 1 }))),
|
|
15
16
|
isolated: Type.Optional(Type.Boolean()),
|
|
16
17
|
apply: Type.Optional(Type.Boolean()),
|
|
17
|
-
merge: Type.Optional(Type.Boolean()),
|
|
18
|
+
merge: Type.Optional(Type.Union([Type.Boolean(), Type.Literal("patch"), Type.Literal("branch")])),
|
|
18
19
|
},
|
|
19
20
|
{ additionalProperties: false },
|
|
20
21
|
);
|
|
@@ -43,6 +44,9 @@ type TaskParams = {
|
|
|
43
44
|
readonly name?: string;
|
|
44
45
|
readonly run_in_background: boolean;
|
|
45
46
|
readonly tools?: readonly string[];
|
|
47
|
+
readonly isolated?: boolean;
|
|
48
|
+
readonly apply?: boolean;
|
|
49
|
+
readonly merge?: "patch" | "branch";
|
|
46
50
|
};
|
|
47
51
|
type ProgressContext = { readonly fallbackId: string; readonly warning?: string };
|
|
48
52
|
|
|
@@ -54,15 +58,32 @@ export interface RunEvalAgentOptions {
|
|
|
54
58
|
readonly callId: string;
|
|
55
59
|
readonly taskToolName: string;
|
|
56
60
|
readonly executeTool: AgentExecuteTool;
|
|
61
|
+
readonly listTools?: () => readonly EvalSchemaToolInfo[];
|
|
57
62
|
readonly signal?: AbortSignal;
|
|
58
63
|
readonly emitStatus?: (event: EvalStatusEvent) => void;
|
|
59
64
|
}
|
|
60
65
|
|
|
61
|
-
export type EvalAgentResult =
|
|
66
|
+
export type EvalAgentResult = (
|
|
62
67
|
| { readonly text: string }
|
|
63
68
|
| { readonly text: string; readonly data: unknown }
|
|
64
69
|
| { readonly text: string; readonly parseError: string }
|
|
65
|
-
| { readonly text: string; readonly id: string; readonly handle: string; readonly run_epoch: number }
|
|
70
|
+
| { readonly text: string; readonly id: string; readonly handle: string; readonly run_epoch: number }
|
|
71
|
+
) & { readonly details?: { readonly isolation: Readonly<Record<string, unknown>> } };
|
|
72
|
+
|
|
73
|
+
// The session-owned executor identifies a bridge across JS and HTTP calls; do not retain retired sessions.
|
|
74
|
+
const isolationCapabilities = new WeakMap<AgentExecuteTool, Map<string, boolean>>();
|
|
75
|
+
|
|
76
|
+
export class AgentIsolationNotAppliedError extends Error {
|
|
77
|
+
readonly name = "AgentIsolationNotAppliedError";
|
|
78
|
+
readonly code = "isolation_not_applied";
|
|
79
|
+
|
|
80
|
+
constructor(isolation: Readonly<Record<string, unknown>>) {
|
|
81
|
+
const recovery = ["patch_path", "branch_name", "manual_command"]
|
|
82
|
+
.flatMap((key) => (typeof isolation[key] === "string" ? [`${key}: ${isolation[key]}`] : []))
|
|
83
|
+
.join("; ");
|
|
84
|
+
super(`agent() isolated changes were not applied${recovery ? `; ${recovery}` : ""}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
66
87
|
|
|
67
88
|
class AgentArgumentsError extends Error {
|
|
68
89
|
readonly name = "AgentArgumentsError";
|
|
@@ -92,7 +113,8 @@ class AgentHandleError extends Error {
|
|
|
92
113
|
export async function runEvalAgent(args: unknown, options: RunEvalAgentOptions): Promise<EvalAgentResult> {
|
|
93
114
|
const parsed = parseAgentArgs(args);
|
|
94
115
|
const structured = Object.hasOwn(parsed, "schema");
|
|
95
|
-
const
|
|
116
|
+
const supportsIsolation = taskSupportsIsolation(options);
|
|
117
|
+
const warning = supportsIsolation ? undefined : droppedOptionsWarning(parsed);
|
|
96
118
|
const fallbackId = parsed.label ?? options.callId;
|
|
97
119
|
if (warning) options.emitStatus?.({ op: "agent", id: fallbackId, status: "running", warning });
|
|
98
120
|
|
|
@@ -104,7 +126,7 @@ export async function runEvalAgent(args: unknown, options: RunEvalAgentOptions):
|
|
|
104
126
|
|
|
105
127
|
let result: AgentToolResult<unknown>;
|
|
106
128
|
try {
|
|
107
|
-
result = await options.executeTool(options.taskToolName, toTaskParams(parsed, structured), {
|
|
129
|
+
result = await options.executeTool(options.taskToolName, toTaskParams(parsed, structured, supportsIsolation), {
|
|
108
130
|
...(options.signal ? { signal: options.signal } : {}),
|
|
109
131
|
...(options.emitStatus
|
|
110
132
|
? {
|
|
@@ -119,12 +141,15 @@ export async function runEvalAgent(args: unknown, options: RunEvalAgentOptions):
|
|
|
119
141
|
}
|
|
120
142
|
|
|
121
143
|
const text = resultText(result);
|
|
144
|
+
const isolation =
|
|
145
|
+
isRecord(result.details) && isRecord(result.details.isolation) ? result.details.isolation : undefined;
|
|
146
|
+
const metadata = isolation === undefined ? {} : { details: { isolation } };
|
|
122
147
|
if (parsed.handle === true) {
|
|
123
148
|
const { task_id: id, run_epoch } = resultTaskHandle(result);
|
|
124
|
-
return { text, id, handle: `agent://${id}`, run_epoch };
|
|
149
|
+
return { text, id, handle: `agent://${id}`, run_epoch, ...metadata };
|
|
125
150
|
}
|
|
126
|
-
if (
|
|
127
|
-
return parseStructuredText(text);
|
|
151
|
+
if (isolation?.changes_applied === false) throw new AgentIsolationNotAppliedError(isolation);
|
|
152
|
+
return { ...(structured ? parseStructuredText(text) : { text }), ...metadata };
|
|
128
153
|
}
|
|
129
154
|
|
|
130
155
|
function parseAgentArgs(value: unknown): AgentArgs {
|
|
@@ -135,7 +160,21 @@ function parseAgentArgs(value: unknown): AgentArgs {
|
|
|
135
160
|
throw new AgentArgumentsError(summary || "invalid value");
|
|
136
161
|
}
|
|
137
162
|
|
|
138
|
-
function
|
|
163
|
+
function taskSupportsIsolation(options: RunEvalAgentOptions): boolean {
|
|
164
|
+
let capabilities = isolationCapabilities.get(options.executeTool);
|
|
165
|
+
if (!capabilities) {
|
|
166
|
+
capabilities = new Map();
|
|
167
|
+
isolationCapabilities.set(options.executeTool, capabilities);
|
|
168
|
+
}
|
|
169
|
+
const cached = capabilities.get(options.taskToolName);
|
|
170
|
+
if (cached !== undefined) return cached;
|
|
171
|
+
const schema = options.listTools?.().find((tool) => tool.name === options.taskToolName)?.parameters;
|
|
172
|
+
const supported = isRecord(schema) && isRecord(schema.properties) && schema.properties.isolated !== undefined;
|
|
173
|
+
capabilities.set(options.taskToolName, supported);
|
|
174
|
+
return supported;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function toTaskParams(args: AgentArgs, structured: boolean, supportsIsolation: boolean): TaskParams {
|
|
139
178
|
return {
|
|
140
179
|
prompt: structured
|
|
141
180
|
? `${args.prompt}\n\nRespond ONLY with JSON matching this JSON-Schema:\n${JSON.stringify(args.schema)}`
|
|
@@ -145,6 +184,11 @@ function toTaskParams(args: AgentArgs, structured: boolean): TaskParams {
|
|
|
145
184
|
...(args.label === undefined ? {} : { name: args.label }),
|
|
146
185
|
run_in_background: args.handle === true,
|
|
147
186
|
...(args.tools === undefined ? {} : { tools: args.tools }),
|
|
187
|
+
...(supportsIsolation && args.isolated !== undefined ? { isolated: args.isolated } : {}),
|
|
188
|
+
...(supportsIsolation && args.apply !== undefined ? { apply: args.apply } : {}),
|
|
189
|
+
...(supportsIsolation && args.merge !== undefined
|
|
190
|
+
? { merge: args.merge === true ? "branch" : args.merge === false ? "patch" : args.merge }
|
|
191
|
+
: {}),
|
|
148
192
|
};
|
|
149
193
|
}
|
|
150
194
|
|
|
@@ -35,6 +35,7 @@ export async function runReservedTool(toolName: string, context: ReservedDispatc
|
|
|
35
35
|
callId: context.callId,
|
|
36
36
|
taskToolName: context.taskToolName,
|
|
37
37
|
executeTool: context.executeTool,
|
|
38
|
+
...(context.listTools === undefined ? {} : { listTools: context.listTools }),
|
|
38
39
|
...(context.signal === undefined ? {} : { signal: context.signal }),
|
|
39
40
|
emitStatus: context.emitStatus,
|
|
40
41
|
});
|
|
@@ -22,6 +22,7 @@ export const codemodeSettingsSchema = Type.Object(
|
|
|
22
22
|
foregroundWindowSeconds: Type.Optional(Type.Number({ minimum: 1 })),
|
|
23
23
|
runBudgetSeconds: Type.Optional(Type.Number({ minimum: 1 })),
|
|
24
24
|
hardLimitSeconds: Type.Optional(Type.Number({ minimum: 1 })),
|
|
25
|
+
maxDetachedCells: Type.Optional(Type.Number({ minimum: 1 })),
|
|
25
26
|
parallelPoolWidth: Type.Optional(Type.Number({ minimum: 1 })),
|
|
26
27
|
taskTools: Type.Optional(
|
|
27
28
|
Type.Object(
|
|
@@ -80,6 +81,8 @@ export interface CodemodeSettings {
|
|
|
80
81
|
readonly runBudgetSeconds: number;
|
|
81
82
|
/** Wall-clock kill deadline for a single cell; bounds detached and bridge-parked cells too. */
|
|
82
83
|
readonly hardLimitSeconds: number;
|
|
84
|
+
/** Maximum detached cells across all language kernels. */
|
|
85
|
+
readonly maxDetachedCells?: number;
|
|
83
86
|
readonly parallelPoolWidth: number;
|
|
84
87
|
readonly taskTools?: CodemodeTaskTools;
|
|
85
88
|
readonly outputSink?: CodemodeOutputSink;
|
|
@@ -87,6 +90,7 @@ export interface CodemodeSettings {
|
|
|
87
90
|
}
|
|
88
91
|
|
|
89
92
|
export type ResolvedCodemodeSettings = CodemodeSettings & {
|
|
93
|
+
readonly maxDetachedCells: number;
|
|
90
94
|
readonly taskTools: CodemodeTaskTools;
|
|
91
95
|
readonly outputSink: CodemodeOutputSink;
|
|
92
96
|
readonly statusEvents: boolean;
|
|
@@ -129,7 +133,10 @@ export const FOREGROUND_WINDOW_ENVIRONMENT_FLAG = "SENPI_CODEMODE_FOREGROUND_SEC
|
|
|
129
133
|
*/
|
|
130
134
|
export const DEFAULT_RUN_BUDGET_SECONDS = 300;
|
|
131
135
|
|
|
136
|
+
export const DEFAULT_MAX_DETACHED_CELLS = 15;
|
|
137
|
+
|
|
132
138
|
export const RUN_BUDGET_ENVIRONMENT_FLAG = "SENPI_CODEMODE_RUN_BUDGET_SECONDS";
|
|
139
|
+
export const MAX_DETACHED_CELLS_ENVIRONMENT_FLAG = "SENPI_CODEMODE_MAX_DETACHED_CELLS";
|
|
133
140
|
|
|
134
141
|
// OMP settings-schema.ts:3211-3299 has language/path settings only; eval.ts:427
|
|
135
142
|
// defaults timeout to 30s, and codemode pins concurrency-bridge.ts:30 width to 4.
|
|
@@ -144,6 +151,7 @@ export const defaultCodemodeSettings: ResolvedCodemodeSettings = {
|
|
|
144
151
|
foregroundWindowSeconds: DEFAULT_FOREGROUND_WINDOW_SECONDS,
|
|
145
152
|
runBudgetSeconds: DEFAULT_RUN_BUDGET_SECONDS,
|
|
146
153
|
hardLimitSeconds: DEFAULT_HARD_LIMIT_SECONDS,
|
|
154
|
+
maxDetachedCells: DEFAULT_MAX_DETACHED_CELLS,
|
|
147
155
|
parallelPoolWidth: 4,
|
|
148
156
|
taskTools: {
|
|
149
157
|
task: "task",
|
|
@@ -207,6 +215,15 @@ export function resolveRunBudgetSeconds(settings: CodemodeSettings, env: Environ
|
|
|
207
215
|
return positiveSecondsOverride(env[RUN_BUDGET_ENVIRONMENT_FLAG]) ?? settings.runBudgetSeconds;
|
|
208
216
|
}
|
|
209
217
|
|
|
218
|
+
/** Uses the same positive-integer environment parsing as the run budget. */
|
|
219
|
+
export function resolveMaxDetachedCells(settings: CodemodeSettings, env: Environment = process.env): number {
|
|
220
|
+
return (
|
|
221
|
+
positiveSecondsOverride(env[MAX_DETACHED_CELLS_ENVIRONMENT_FLAG]) ??
|
|
222
|
+
settings.maxDetachedCells ??
|
|
223
|
+
DEFAULT_MAX_DETACHED_CELLS
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
210
227
|
function positiveSecondsOverride(value: string | undefined): number | undefined {
|
|
211
228
|
if (value === undefined) return undefined;
|
|
212
229
|
const parsed = Number.parseInt(value, 10);
|
|
@@ -250,6 +267,7 @@ function mergeSettings(input: CodemodeSettingsInput): ResolvedCodemodeSettings {
|
|
|
250
267
|
foregroundWindowSeconds: input.foregroundWindowSeconds ?? defaultCodemodeSettings.foregroundWindowSeconds,
|
|
251
268
|
runBudgetSeconds: input.runBudgetSeconds ?? defaultCodemodeSettings.runBudgetSeconds,
|
|
252
269
|
hardLimitSeconds: input.hardLimitSeconds ?? defaultCodemodeSettings.hardLimitSeconds,
|
|
270
|
+
maxDetachedCells: input.maxDetachedCells ?? DEFAULT_MAX_DETACHED_CELLS,
|
|
253
271
|
parallelPoolWidth: input.parallelPoolWidth ?? defaultCodemodeSettings.parallelPoolWidth,
|
|
254
272
|
taskTools: {
|
|
255
273
|
task: input.taskTools?.task ?? defaultCodemodeSettings.taskTools.task,
|
|
@@ -28,7 +28,8 @@ function packLabels(labels: readonly string[], budget: number): string {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
function labelOf(entry: EvalDetachedCellStatusEntry): string {
|
|
31
|
-
|
|
31
|
+
const label = entry.summary === undefined || entry.summary.length === 0 ? entry.cellId : entry.summary;
|
|
32
|
+
return entry.queuedBehind === undefined ? label : `queued ${label}`;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
/**
|
|
@@ -52,10 +53,12 @@ export function formatElapsedSeconds(value: number): string {
|
|
|
52
53
|
return `${hours}h ${remainingMinutes}m`;
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
/** Whole seconds since the oldest detached cell
|
|
56
|
+
/** Whole seconds since the oldest executing detached cell started; queued cells do not tick. */
|
|
56
57
|
export function evalCellElapsedSeconds(entries: readonly EvalDetachedCellStatusEntry[], nowMs: number): number {
|
|
57
58
|
let oldest = Number.POSITIVE_INFINITY;
|
|
58
|
-
for (const entry of entries)
|
|
59
|
+
for (const entry of entries) {
|
|
60
|
+
if (entry.queuedBehind === undefined) oldest = Math.min(oldest, entry.startedAtMs);
|
|
61
|
+
}
|
|
59
62
|
if (!Number.isFinite(oldest)) return 0;
|
|
60
63
|
return Math.max(0, Math.round((nowMs - oldest) / 1000));
|
|
61
64
|
}
|
|
@@ -67,7 +70,9 @@ export function formatEvalCellStatus(
|
|
|
67
70
|
): string | undefined {
|
|
68
71
|
const first = entries[0];
|
|
69
72
|
if (first === undefined) return undefined;
|
|
70
|
-
const suffix =
|
|
73
|
+
const suffix = entries.every((entry) => entry.queuedBehind !== undefined)
|
|
74
|
+
? " (queued)"
|
|
75
|
+
: ` (${formatElapsedSeconds(evalCellElapsedSeconds(entries, nowMs))})`;
|
|
71
76
|
if (entries.length === 1) {
|
|
72
77
|
const head = `${DETACHED_GLYPH} ${first.language} · `;
|
|
73
78
|
return head + truncateEnd(labelOf(first), MAX_STATUS_LENGTH - head.length - suffix.length) + suffix;
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
defaultCodemodeSettings,
|
|
8
8
|
resolveForegroundWindowSeconds,
|
|
9
9
|
resolveHardLimitSeconds,
|
|
10
|
+
resolveMaxDetachedCells,
|
|
10
11
|
resolveRunBudgetSeconds,
|
|
11
12
|
} from "./config/settings.ts";
|
|
12
13
|
import { EvalNotifier } from "./extension/eval-notifier.ts";
|
|
@@ -113,6 +114,9 @@ export default function senpiCodemode(pi: CodemodeExtensionAPI, options: SenpiCo
|
|
|
113
114
|
statusTicker.sync(entries);
|
|
114
115
|
};
|
|
115
116
|
const emitWakeSourceState = (state: WakeSourceState): void => {
|
|
117
|
+
// Same dual publication as the settle payload below: the in-process bus
|
|
118
|
+
// feeds the TUI footer, the rpc channel feeds out-of-process consumers.
|
|
119
|
+
pi.rpc?.emit(WAKE_SOURCE_STATE_EVENT, state);
|
|
116
120
|
pi.events?.emit(WAKE_SOURCE_STATE_EVENT, state);
|
|
117
121
|
};
|
|
118
122
|
const registerEvalForRuntime = (
|
|
@@ -181,6 +185,7 @@ export default function senpiCodemode(pi: CodemodeExtensionAPI, options: SenpiCo
|
|
|
181
185
|
settings: defaultCodemodeSettings,
|
|
182
186
|
cellManager: new EvalDetachedCellManager({
|
|
183
187
|
notifier,
|
|
188
|
+
maxDetachedCells: resolveMaxDetachedCells(defaultCodemodeSettings),
|
|
184
189
|
hardLimitSeconds: resolveHardLimitSeconds(defaultCodemodeSettings),
|
|
185
190
|
runBudgetSeconds: resolveRunBudgetSeconds(defaultCodemodeSettings),
|
|
186
191
|
onStatusChange: showDetachedCells,
|
|
@@ -219,6 +224,7 @@ export default function senpiCodemode(pi: CodemodeExtensionAPI, options: SenpiCo
|
|
|
219
224
|
const cellManager = new EvalDetachedCellManager({
|
|
220
225
|
artifactsDir: runtime.artifactsDir,
|
|
221
226
|
notifier,
|
|
227
|
+
maxDetachedCells: resolveMaxDetachedCells(runtime.settings),
|
|
222
228
|
hardLimitSeconds: resolveHardLimitSeconds(runtime.settings),
|
|
223
229
|
runBudgetSeconds: resolveRunBudgetSeconds(runtime.settings),
|
|
224
230
|
onStatusChange: showDetachedCells,
|
|
@@ -28,8 +28,8 @@ runner/prelude assets).
|
|
|
28
28
|
AST-parsed (Babel) and rewritten to bridge-compatible dynamic imports.
|
|
29
29
|
- JS runs on worker threads with an inline-worker fallback; py/rb/jl run as
|
|
30
30
|
framed subprocesses through `shared/`.
|
|
31
|
-
-
|
|
32
|
-
|
|
31
|
+
- Each language keeps one serial FIFO kernel. Queued cancellation removes only
|
|
32
|
+
that cell; active interruption and runtime recovery stay in the kernel layer.
|
|
33
33
|
- Every kernel exposes the active session's `PI_*` environment (`session-env.ts`):
|
|
34
34
|
inherited values are deleted before the session's values are applied, so any
|
|
35
35
|
child spawned from a cell sees the same session environment a bash-tool child
|
|
@@ -254,6 +254,12 @@ function output(ids...; format="raw", offset=nothing, limit=nothing)
|
|
|
254
254
|
senpi_with_bridge_timeout_pause(() -> senpi_call_tool("__output__", arguments))
|
|
255
255
|
end
|
|
256
256
|
|
|
257
|
+
"""
|
|
258
|
+
Delegate work with isolated/apply/merge; needs a host that supports isolation, otherwise a warning.
|
|
259
|
+
merge accepts "patch"/"branch" (false/true aliases). Unapplied foreground changes raise
|
|
260
|
+
an error with recovery instructions. Handles return immediately: await the completion
|
|
261
|
+
notification or read task_output for the isolation result.
|
|
262
|
+
"""
|
|
257
263
|
function agent(prompt::AbstractString; agent="task", model=nothing, label=nothing, schema=nothing, isolated=nothing, apply=nothing, merge=nothing, handle=false, kwargs...)
|
|
258
264
|
arguments = Dict{String, Any}("prompt" => string(prompt), "agent" => agent)
|
|
259
265
|
for (key, value) in (("model", model), ("label", label), ("schema", schema), ("isolated", isolated), ("apply", apply), ("merge", merge))
|
|
@@ -272,6 +278,10 @@ function agent(prompt::AbstractString; agent="task", model=nothing, label=nothin
|
|
|
272
278
|
result["handle"] = get(record, "handle", result["id"] === nothing ? nothing : "agent://" * string(result["id"]))
|
|
273
279
|
result["run_epoch"] = get(record, "run_epoch", nothing)
|
|
274
280
|
schema !== nothing && (result["data"] = parsed)
|
|
281
|
+
details = get(record, "details", nothing)
|
|
282
|
+
if details isa AbstractDict && haskey(details, "isolation")
|
|
283
|
+
result["details"] = Dict("isolation" => details["isolation"])
|
|
284
|
+
end
|
|
275
285
|
result
|
|
276
286
|
end
|
|
277
287
|
|
|
@@ -90,13 +90,26 @@ export class JavaScriptKernel {
|
|
|
90
90
|
return await promise;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
cancelQueued(cellId: string, reason: string): boolean {
|
|
94
|
+
return this.#runs.remove(cellId, reason);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
queueSnapshot(): { activeCellId: string | null; queuedCellIds: readonly string[] } {
|
|
98
|
+
return this.#runs.snapshot();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async interrupt(reason = "interrupted", cellId?: string): Promise<KernelInterruptHandle> {
|
|
94
102
|
assertJavaScriptKernelOpen(this.#lifecycle, "interrupt");
|
|
95
103
|
const active = this.#runs.active;
|
|
104
|
+
if (cellId !== undefined && active?.input.cellId !== cellId) {
|
|
105
|
+
const cancelled = this.cancelQueued(cellId, reason);
|
|
106
|
+
return { stateRetained: Promise.resolve(true), ...(cancelled ? {} : { note: "cell not found" }) };
|
|
107
|
+
}
|
|
96
108
|
if (!active) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
this.#runs.
|
|
109
|
+
// A worker still stuck in startup is not a healthy idle worker: retiring it is the only recovery.
|
|
110
|
+
const wedgedInStartup = this.#slot.startingUp;
|
|
111
|
+
this.#runs.settleAll(`JS cell interrupted: ${reason}`);
|
|
112
|
+
if (!wedgedInStartup) return { stateRetained: Promise.resolve(true) };
|
|
100
113
|
await this.#restartAfterStop();
|
|
101
114
|
return { stateRetained: Promise.resolve(false) };
|
|
102
115
|
}
|
|
@@ -262,8 +275,7 @@ export class JavaScriptKernel {
|
|
|
262
275
|
this.#trackChildEvent(message.event);
|
|
263
276
|
return;
|
|
264
277
|
}
|
|
265
|
-
this.#options.onMessage?.(message);
|
|
266
|
-
this.#runs.active?.input.onMessage?.(message);
|
|
278
|
+
(this.#runs.active?.input.onMessage ?? this.#options.onMessage)?.(message);
|
|
267
279
|
if (message.type === "tool-call") {
|
|
268
280
|
const waiter = this.#toolWaiters.shift();
|
|
269
281
|
if (waiter) waiter(message);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { KernelToHostMessage } from "../../bridge/protocol.ts";
|
|
2
|
+
import type { EvalKernelRunInput } from "../../tool/types.ts";
|
|
2
3
|
import type { SessionEnvironment } from "../session-env.ts";
|
|
3
4
|
|
|
4
5
|
export type ResultMessage = Extract<KernelToHostMessage, { type: "result" }>;
|
|
@@ -28,12 +29,7 @@ export interface JavaScriptKernelOptions {
|
|
|
28
29
|
readonly foreignLanguageNames?: KernelToolNameSource;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
export
|
|
32
|
-
readonly cellId: string;
|
|
33
|
-
readonly code: string;
|
|
34
|
-
readonly timeoutMs?: number;
|
|
35
|
-
readonly onMessage?: (message: KernelToHostMessage) => void;
|
|
36
|
-
}
|
|
32
|
+
export type JavaScriptRunInput = EvalKernelRunInput;
|
|
37
33
|
|
|
38
34
|
export type KernelOperation = "run" | "reset" | "interrupt";
|
|
39
35
|
export type LifecycleState = "open" | "closing" | "closed";
|
|
@@ -10,7 +10,7 @@ export const JAVASCRIPT_KERNEL_PRELUDE = [
|
|
|
10
10
|
"tool(fn, metadata?): register a named JavaScript function as a fenced kernel tool for in-process children.",
|
|
11
11
|
"completion(prompt, options?): request a host completion bridge call.",
|
|
12
12
|
"output(...ids, options?): retrieve task output through the reserved output bridge.",
|
|
13
|
-
|
|
13
|
+
'agent(prompt, options?): delegate work; isolated/apply/merge need a host that supports isolation, otherwise a warning. merge: "patch"/"branch" (false/true aliases). Unapplied foreground changes throw with recovery instructions. Handles return immediately; await the completion notification or read task_output for the isolation result.',
|
|
14
14
|
"workpool(agent, name, options?): await a host-owned pool adapter with pool_id, push, close, inspect, and cancel; options only accept mode.",
|
|
15
15
|
"parallel(thunks): run async thunks through the configured bounded pool; preserves order and rethrows the lowest-index error after all settle.",
|
|
16
16
|
"pipeline(items, ...stages): map items through staged async transforms with a barrier between stages.",
|
|
@@ -49,21 +49,31 @@ export class JavaScriptRunQueue {
|
|
|
49
49
|
const next = this.#queue.shift() ?? null;
|
|
50
50
|
if (next) next.startedAtMs = startedAtMs;
|
|
51
51
|
this.#active = next;
|
|
52
|
+
next?.input.onStarted?.();
|
|
52
53
|
return next;
|
|
53
54
|
}
|
|
54
55
|
|
|
56
|
+
remove(cellId: string, reason = "interrupted"): boolean {
|
|
57
|
+
const index = this.#queue.findIndex((run) => run.input.cellId === cellId);
|
|
58
|
+
if (index < 0) return false;
|
|
59
|
+
const [run] = this.#queue.splice(index, 1);
|
|
60
|
+
if (!run) return false;
|
|
61
|
+
this.settle(run, stoppedResult(cellId, reason));
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
snapshot(): { activeCellId: string | null; queuedCellIds: readonly string[] } {
|
|
66
|
+
return {
|
|
67
|
+
activeCellId: this.#active?.input.cellId ?? null,
|
|
68
|
+
queuedCellIds: this.#queue.map((run) => run.input.cellId),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
55
72
|
durationMs(run: PendingJavaScriptRun, finishedAtMs: number): number {
|
|
56
73
|
if (run.startedAtMs === null) return 0;
|
|
57
74
|
return Math.max(0, Math.round(finishedAtMs - run.startedAtMs));
|
|
58
75
|
}
|
|
59
76
|
|
|
60
|
-
takeInterruptTarget(): PendingJavaScriptRun | null {
|
|
61
|
-
if (!this.#active) return this.#queue.shift() ?? null;
|
|
62
|
-
const active = this.#active;
|
|
63
|
-
this.#active = null;
|
|
64
|
-
return active;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
77
|
releaseActive(run: PendingJavaScriptRun): boolean {
|
|
68
78
|
if (this.#active !== run) return false;
|
|
69
79
|
this.#active = null;
|
|
@@ -305,7 +305,9 @@ export class JsWorkerRuntime {
|
|
|
305
305
|
: JSON.parse(String(text))
|
|
306
306
|
: text;
|
|
307
307
|
if (!handle) return output;
|
|
308
|
-
const details =
|
|
308
|
+
const details = Object.hasOwn(responseRecord, "id")
|
|
309
|
+
? responseRecord
|
|
310
|
+
: isPlainObject(responseRecord.details) ? responseRecord.details : responseRecord;
|
|
309
311
|
const id = details.id;
|
|
310
312
|
if (id === undefined || id === null) return { text, output: text, handle: null, id: null, agent: null };
|
|
311
313
|
const node = {
|
|
@@ -317,6 +319,9 @@ export class JsWorkerRuntime {
|
|
|
317
319
|
agent: details.agent ?? callArgs.agent ?? null,
|
|
318
320
|
};
|
|
319
321
|
if (Object.hasOwn(callArgs, "schema")) node.data = output;
|
|
322
|
+
if (isPlainObject(responseRecord.details) && Object.hasOwn(responseRecord.details, "isolation")) {
|
|
323
|
+
node.details = { isolation: responseRecord.details.isolation };
|
|
324
|
+
}
|
|
320
325
|
for (const key of ["isolated", "patchPath", "branchName", "nestedPatches", "changesApplied", "isolationSummary"]) {
|
|
321
326
|
if (details[key] !== undefined) node[key] = details[key];
|
|
322
327
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BridgeConnectionConfig, KernelToHostMessage } from "../../bridge/protocol.ts";
|
|
2
|
+
import type { EvalKernelRunInput } from "../../tool/types.ts";
|
|
2
3
|
import type { SessionEnvironment } from "../session-env.ts";
|
|
3
4
|
import type { KernelSpawnProcess } from "./process.ts";
|
|
4
5
|
import type { PythonTransportResult } from "./transport.ts";
|
|
@@ -16,11 +17,7 @@ export interface PythonKernelStartOptions {
|
|
|
16
17
|
readonly spawnProcess?: KernelSpawnProcess;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
export
|
|
20
|
-
readonly cellId: string;
|
|
21
|
-
readonly code: string;
|
|
22
|
-
readonly timeoutMs?: number;
|
|
23
|
-
}
|
|
20
|
+
export type PythonKernelRunOptions = EvalKernelRunInput;
|
|
24
21
|
|
|
25
22
|
export type ResultMessage = PythonTransportResult;
|
|
26
23
|
|