@code-yeongyu/senpi 2026.11.2-3 → 2026.11.3-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 +55 -0
- package/dist/bundle/chunks/anthropic-messages-LJAKRKMX.js +11 -0
- package/dist/bundle/chunks/{args-AOI4NEA6.js → args-GQTXDYS3.js} +1 -1
- package/dist/bundle/chunks/{azure-openai-responses-YLBBQXI7.js → azure-openai-responses-HDEKTPMZ.js} +1 -1
- package/dist/bundle/chunks/chatgpt-subscription.js +10 -2
- package/dist/bundle/chunks/{chunk-ED7VJGL4.js → chunk-2PGSRQBF.js} +1 -1
- package/dist/bundle/chunks/{chunk-LMIETUPG.js → chunk-3LDASCJN.js} +1 -1
- package/dist/bundle/chunks/{chunk-PIAY636U.js → chunk-3QPE75AR.js} +1 -1
- package/dist/bundle/chunks/{chunk-FQZZGSYH.js → chunk-4ZGQUOBV.js} +1 -1
- package/dist/bundle/chunks/{chunk-S2M5D5GS.js → chunk-5BMIET5O.js} +2 -2
- package/dist/bundle/chunks/{chunk-XLLQJALL.js → chunk-67M7HKXO.js} +1 -1
- package/dist/bundle/chunks/chunk-6ISOXWH2.js +2 -0
- package/dist/bundle/chunks/{chunk-IWM5QRAE.js → chunk-6NPK2O3C.js} +2 -2
- package/dist/bundle/chunks/{chunk-FO56LSUK.js → chunk-7C4W5HMU.js} +1 -1
- package/dist/bundle/chunks/chunk-7KIHKE2T.js +2 -0
- package/dist/bundle/chunks/{chunk-BW4YXS7X.js → chunk-A4KOQUHT.js} +1 -1
- package/dist/bundle/chunks/{chunk-FJSJUVQQ.js → chunk-A5PZGQCP.js} +3 -3
- package/dist/bundle/chunks/{chunk-TBARMJ75.js → chunk-AVP6DDBF.js} +1 -1
- package/dist/bundle/chunks/{chunk-KVPRQ5KN.js → chunk-B3GTID4P.js} +1 -1
- package/dist/bundle/chunks/{chunk-2XBKE2BZ.js → chunk-BIWFWGUA.js} +1 -1
- package/dist/bundle/chunks/{chunk-6LDUM5CL.js → chunk-DCI4QOUX.js} +1 -1
- package/dist/bundle/chunks/{chunk-2YFPDNNP.js → chunk-DNZKKG4V.js} +1 -1
- package/dist/bundle/chunks/{chunk-W2V7RIBF.js → chunk-E7SA75PP.js} +1 -1
- package/dist/bundle/chunks/{chunk-YWD54RHU.js → chunk-EBZ6IP4V.js} +1 -1
- package/dist/bundle/chunks/{chunk-N4TSAHRL.js → chunk-EVTTLPIY.js} +1 -1
- package/dist/bundle/chunks/{chunk-J2OBN7TI.js → chunk-G5XUGK4B.js} +1 -1
- package/dist/bundle/chunks/{chunk-IHOQR7TU.js → chunk-GKP34H3C.js} +2 -2
- package/dist/bundle/chunks/{chunk-PP52OWBB.js → chunk-GLTOBXZY.js} +1 -1
- package/dist/bundle/chunks/{chunk-ZSVWKOAJ.js → chunk-IJGXAACA.js} +263 -237
- package/dist/bundle/chunks/{chunk-LGO25HPL.js → chunk-JCTODLUP.js} +1 -1
- package/dist/bundle/chunks/{chunk-3ESZE3DG.js → chunk-KHBCZ6TR.js} +1 -1
- package/dist/bundle/chunks/chunk-KJR3XXMI.js +2 -0
- package/dist/bundle/chunks/{chunk-TVMW2SUP.js → chunk-KY4V3TSO.js} +2 -2
- package/dist/bundle/chunks/{chunk-T5ZJ2Q4O.js → chunk-MCXOJHN2.js} +1 -1
- package/dist/bundle/chunks/{chunk-GIY7PGOH.js → chunk-NKI7L5UM.js} +3 -3
- package/dist/bundle/chunks/{chunk-L3V65XW7.js → chunk-OD7RT7G7.js} +1 -1
- package/dist/bundle/chunks/{chunk-NYXXKS6D.js → chunk-OOU3BRUY.js} +3 -2
- package/dist/bundle/chunks/{chunk-LPHUMR6R.js → chunk-OT6ALXSJ.js} +1 -1
- package/dist/bundle/chunks/{chunk-XGBRBCIQ.js → chunk-Q5CKFBQT.js} +1 -1
- package/dist/bundle/chunks/{chunk-F7GBSQRV.js → chunk-QPYDQ4QK.js} +1 -1
- package/dist/bundle/chunks/{chunk-7FUO655J.js → chunk-QSMT5KVJ.js} +1 -1
- package/dist/bundle/chunks/{chunk-SAZ6E74O.js → chunk-RUOTFZQR.js} +1 -1
- package/dist/bundle/chunks/chunk-RWF6IJQL.js +448 -0
- package/dist/bundle/chunks/{chunk-P4AT7SBE.js → chunk-S5Y7NEHB.js} +1 -1
- package/dist/bundle/chunks/{chunk-QLTQ3UUI.js → chunk-SCBTASM4.js} +1 -1
- package/dist/bundle/chunks/chunk-SJWTZ3Z2.js +2 -0
- package/dist/bundle/chunks/{chunk-ISZ4EWIS.js → chunk-SODMQEHO.js} +1 -1
- package/dist/bundle/chunks/{chunk-WEGTCUO3.js → chunk-SQAQEITV.js} +1 -1
- package/dist/bundle/chunks/{chunk-UFVZTQKN.js → chunk-TQQG5L4D.js} +1 -1
- package/dist/bundle/chunks/{chunk-662SCMTH.js → chunk-U6A4X3FV.js} +1 -1
- package/dist/bundle/chunks/{chunk-ACIFXWJ6.js → chunk-UHUM55TR.js} +1 -1
- package/dist/bundle/chunks/{chunk-L5OFGHDA.js → chunk-USKWGPA6.js} +1 -1
- package/dist/bundle/chunks/{chunk-7ORS33CE.js → chunk-VDDJADPV.js} +1 -1
- package/dist/bundle/chunks/{chunk-R65P6LAT.js → chunk-VIHXG53S.js} +1 -1
- package/dist/bundle/chunks/{chunk-SGS76663.js → chunk-VPVD5G32.js} +1 -1
- package/dist/bundle/chunks/chunk-WO6I5PRF.js +3 -0
- package/dist/bundle/chunks/{chunk-ETCYVVVO.js → chunk-WVEIJ437.js} +1 -1
- package/dist/bundle/chunks/{chunk-VRWJJMHO.js → chunk-XKFG4N3Z.js} +1 -1
- package/dist/bundle/chunks/{chunk-57MRFI6E.js → chunk-XMWPCJU6.js} +1 -1
- package/dist/bundle/chunks/{chunk-GDPWQJDQ.js → chunk-XPSXUKSD.js} +1 -1
- package/dist/bundle/chunks/{chunk-FNBEICAA.js → chunk-YI6KRJDC.js} +1 -1
- package/dist/bundle/chunks/{chunk-UURGXV5B.js → chunk-YP47G4YP.js} +1 -1
- package/dist/bundle/chunks/{chunk-TXOR5BQL.js → chunk-YRYDCKUI.js} +1 -1
- package/dist/bundle/chunks/{chunk-QAM6AXA2.js → chunk-YTKZSGMQ.js} +12 -9
- package/dist/bundle/chunks/{chunk-V36CXIIB.js → chunk-YXL3PNTL.js} +1 -1
- package/dist/bundle/chunks/chunk-Z7HTHT6K.js +2 -0
- package/dist/bundle/chunks/{chunk-27XEDYQA.js → chunk-ZTPG27EJ.js} +1 -1
- package/dist/bundle/chunks/{cli-main-534A3WSC.js → cli-main-RN7YB427.js} +1 -1
- package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-FC7QLRU2.js → cloudflare-workers-ai-system-one-N5KFNKK4.js} +1 -1
- package/dist/bundle/chunks/credential-accounts-BJX55MTT.js +2 -0
- package/dist/bundle/chunks/devin.js +10 -2
- package/dist/bundle/chunks/{dispatch-UY6LBJJE.js → dispatch-M7UAPGVY.js} +1 -1
- package/dist/bundle/chunks/{google-generative-ai-7PQ4QRHJ.js → google-generative-ai-2TZSCSIS.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-DY7EO4EJ.js → google-vertex-7NJJOI7V.js} +1 -1
- package/dist/bundle/chunks/{health-write-EB4CPHXN.js → health-write-YUSPVH7U.js} +1 -1
- package/dist/bundle/chunks/{help-fast-path-U2PSNNWO.js → help-fast-path-DWCA77QP.js} +1 -1
- package/dist/bundle/chunks/host-command-KJXUTSQ7.js +2 -0
- package/dist/bundle/chunks/{host-lifecycle-TGG7KGQH.js → host-lifecycle-QHIJ4G2K.js} +1 -1
- package/dist/bundle/chunks/host-lifecycle.js +1 -1
- package/dist/bundle/chunks/{host-session-command-PWVPQ2OV.js → host-session-command-IPH3WXSG.js} +1 -1
- package/dist/bundle/chunks/{host-socket-request-F2R5P34M.js → host-socket-request-XPXJV3CS.js} +1 -1
- package/dist/bundle/chunks/interactive-mode-XUXMDYLA.js +2 -0
- package/dist/bundle/chunks/{list-tips-3D3A6GFK.js → list-tips-XJY7EL5S.js} +1 -1
- package/dist/bundle/chunks/{login-health-7G2DZVOV.js → login-health-226NO44U.js} +1 -1
- package/dist/bundle/chunks/main-P7PKMJUG.js +2 -0
- package/dist/bundle/chunks/{mistral-conversations-6F2RAIB2.js → mistral-conversations-QMHMHSUF.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-7E26R5JF.js → multi-session-host-ZQY4AN46.js} +4 -4
- package/dist/bundle/chunks/{native-loader-NMDTMHMA.js → native-loader-A6DNMGCK.js} +1 -1
- package/dist/bundle/chunks/openai-chatgpt.js +11 -3
- package/dist/bundle/chunks/{openai-codex-responses-VNBMMIL3.js → openai-codex-responses-GUAHKQE2.js} +1 -1
- package/dist/bundle/chunks/{openai-completions-JLR32APM.js → openai-completions-UPRTFM54.js} +1 -1
- package/dist/bundle/chunks/{openai-images-LEBNERSM.js → openai-images-IKWNS6VB.js} +1 -1
- package/dist/bundle/chunks/{openai-responses-JCDUNMHA.js → openai-responses-AXN5NUHH.js} +1 -1
- package/dist/bundle/chunks/openrouter.js +10 -2
- package/dist/bundle/chunks/{package-manager-cli-CBSDV36M.js → package-manager-cli-PP7L2Q5M.js} +1 -1
- package/dist/bundle/chunks/radius.js +10 -2
- package/dist/bundle/chunks/{rg-engine-JDUYBM6L.js → rg-engine-VRSXT6HG.js} +1 -1
- package/dist/bundle/chunks/{role-LP6LVNCY.js → role-L5J7ZPCF.js} +1 -1
- package/dist/bundle/chunks/rotation-stream-6INZXQFC.js +2 -0
- package/dist/bundle/chunks/rpc-mode-W4UATRAT.js +2 -0
- package/dist/bundle/chunks/{rpc-monitor-source-5TUR27NY.js → rpc-monitor-source-RMMUPBMS.js} +1 -1
- package/dist/bundle/chunks/{run-attached-tui-PVLUHHJX.js → run-attached-tui-RLXFGCEP.js} +1 -1
- package/dist/bundle/chunks/{schedule-command-W45NYTTK.js → schedule-command-ZNFEJNTT.js} +1 -1
- package/dist/bundle/chunks/{session-control-endpoint-LFLUNALC.js → session-control-endpoint-TWTONJWF.js} +1 -1
- package/dist/bundle/chunks/{session-picker-OZUINLD7.js → session-picker-KRUVCHOV.js} +1 -1
- package/dist/bundle/chunks/session-slot-NJOZCOHQ.js +2 -0
- package/dist/bundle/chunks/session-worker.js +492 -461
- package/dist/bundle/chunks/{state-store-SZARKD36.js → state-store-ZAFZ4JOM.js} +1 -1
- package/dist/bundle/chunks/{typesafe-system-one-5JYDJK6S.js → typesafe-system-one-CICIRAYN.js} +1 -1
- package/dist/bundle/cli.js +2 -2
- package/dist/bundle/host-supervisor.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/bundle/runtime-manifest.json +1 -1
- package/dist/core/agent-session.d.ts +8 -0
- package/dist/core/agent-session.js +73 -63
- package/dist/core/auth-storage.d.ts +19 -0
- package/dist/core/auth-storage.js +99 -24
- package/dist/core/auth-store-load-error.d.ts +29 -0
- package/dist/core/auth-store-load-error.js +74 -0
- package/dist/core/brand.d.ts +2 -0
- package/dist/core/brand.js +1 -0
- package/dist/core/credential-pool/classify.d.ts +3 -2
- package/dist/core/credential-pool/classify.js +10 -3
- package/dist/core/credential-pool/failover.d.ts +8 -0
- package/dist/core/credential-pool/failover.js +18 -5
- package/dist/core/credential-pool/rotation-stream.d.ts +1 -1
- package/dist/core/credential-pool/rotation-stream.js +2 -7
- package/dist/core/credential-pool/session-slot.d.ts +20 -0
- package/dist/core/credential-pool/session-slot.js +26 -0
- package/dist/core/credential-recovery-revision.d.ts +10 -0
- package/dist/core/credential-recovery-revision.js +19 -0
- package/dist/core/dynamic-prompt/build.d.ts +2 -1
- package/dist/core/dynamic-prompt/build.js +1 -2
- package/dist/core/dynamic-prompt/handoff.d.ts +1 -1
- package/dist/core/dynamic-prompt/handoff.js +9 -9
- package/dist/core/dynamic-prompt/identity.js +1 -1
- package/dist/core/dynamic-prompt/intent-gate.d.ts +1 -1
- package/dist/core/dynamic-prompt/intent-gate.js +8 -8
- package/dist/core/dynamic-prompt/policies.d.ts +1 -1
- package/dist/core/dynamic-prompt/policies.js +5 -7
- package/dist/core/dynamic-prompt/style.js +5 -5
- package/dist/core/dynamic-prompt/tool-section.d.ts +5 -0
- package/dist/core/dynamic-prompt/tool-section.js +8 -6
- package/dist/core/dynamic-prompt/verification.d.ts +6 -6
- package/dist/core/dynamic-prompt/verification.js +12 -12
- package/dist/core/dynamic-prompt/working-task.d.ts +1 -1
- package/dist/core/dynamic-prompt/working-task.js +3 -3
- package/dist/core/dynamic-prompt/workstation.js +1 -1
- package/dist/core/execution/executor-body.d.ts +22 -0
- package/dist/core/execution/executor-body.js +73 -0
- package/dist/core/execution/executor-freeze.d.ts +17 -0
- package/dist/core/execution/executor-freeze.js +53 -0
- package/dist/core/execution/executor-pipeline.d.ts +9 -0
- package/dist/core/execution/executor-pipeline.js +25 -0
- package/dist/core/execution/executor-types.d.ts +82 -0
- package/dist/core/execution/executor-types.js +2 -0
- package/dist/core/execution/executor.d.ts +8 -0
- package/dist/core/execution/executor.js +216 -0
- package/dist/core/extensions/builtin/anthropic-subscription/account-block-log.d.ts +15 -0
- package/dist/core/extensions/builtin/anthropic-subscription/account-block-log.js +18 -0
- package/dist/core/extensions/builtin/anthropic-subscription/affinity.d.ts +9 -1
- package/dist/core/extensions/builtin/anthropic-subscription/affinity.js +15 -4
- package/dist/core/extensions/builtin/anthropic-subscription/failover.d.ts +7 -1
- package/dist/core/extensions/builtin/anthropic-subscription/failover.js +19 -2
- package/dist/core/extensions/builtin/anthropic-subscription/guidance.d.ts +8 -2
- package/dist/core/extensions/builtin/anthropic-subscription/guidance.js +25 -1
- package/dist/core/extensions/builtin/anthropic-subscription/provider-diagnostic.d.ts +9 -0
- package/dist/core/extensions/builtin/anthropic-subscription/provider-diagnostic.js +59 -0
- package/dist/core/extensions/builtin/anthropic-subscription/session-registry-pump.d.ts +13 -0
- package/dist/core/extensions/builtin/anthropic-subscription/session-registry-pump.js +64 -2
- package/dist/core/extensions/builtin/anthropic-subscription/session-registry-wiring.js +7 -0
- package/dist/core/extensions/builtin/anthropic-subscription/session-stream.js +5 -1
- package/dist/core/extensions/builtin/anthropic-subscription/session-turn-attempt.d.ts +7 -0
- package/dist/core/extensions/builtin/anthropic-subscription/session-turn-attempt.js +28 -1
- package/dist/core/extensions/builtin/anthropic-subscription/session-turn-types.d.ts +2 -0
- package/dist/core/extensions/builtin/anthropic-subscription/stream-guidance.js +5 -3
- package/dist/core/extensions/builtin/anthropic-subscription/stream.js +4 -0
- package/dist/core/extensions/builtin/bash-timeout/index.d.ts +1 -1
- package/dist/core/extensions/builtin/bash-timeout/index.js +3 -28
- package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts +0 -11
- package/dist/core/extensions/builtin/bash-timeout/timeout.js +0 -11
- package/dist/core/extensions/builtin/btw/index.js +3 -1
- package/dist/core/extensions/builtin/cache-keepalive/index.js +3 -1
- package/dist/core/extensions/builtin/compaction/index.js +1 -1
- package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +3 -1
- package/dist/core/extensions/builtin/compaction/openai-remote.js +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.js +3 -2
- package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.js +3 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/native-bootstrap.js +3 -1
- package/dist/core/extensions/builtin/imagegen/index.d.ts +0 -1
- package/dist/core/extensions/builtin/imagegen/index.js +0 -11
- package/dist/core/extensions/builtin/look-at/runner.js +3 -1
- package/dist/core/extensions/builtin/mcp/auth/callback.js +3 -4
- package/dist/core/extensions/builtin/mcp/auth/oauth-provider.js +2 -1
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts +5 -5
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js +5 -5
- package/dist/core/extensions/builtin/prompt-preset/glm-5.d.ts +1 -1
- package/dist/core/extensions/builtin/prompt-preset/glm-5.js +1 -1
- package/dist/core/extensions/builtin/terminal/extension.js +8 -1
- package/dist/core/extensions/builtin/terminal/notify.js +9 -3
- package/dist/core/extensions/builtin/terminal/prompt.d.ts +7 -1
- package/dist/core/extensions/builtin/terminal/prompt.js +27 -60
- package/dist/core/extensions/builtin/terminal/tools/bash.js +10 -2
- package/dist/core/extensions/builtin/todotools/normalize.d.ts +20 -3
- package/dist/core/extensions/builtin/todotools/normalize.js +251 -5
- package/dist/core/extensions/builtin/todotools/prompt.d.ts +2 -2
- package/dist/core/extensions/builtin/todotools/prompt.js +5 -5
- package/dist/core/extensions/builtin/todotools/tools/todo.js +9 -8
- package/dist/core/extensions/builtin/webfetch/webfetch/tool.js +0 -5
- package/dist/core/extensions/builtin/websearch/index.js +9 -4
- package/dist/core/extensions/builtin/websearch/websearch/tool.d.ts +2 -0
- package/dist/core/extensions/builtin/websearch/websearch/tool.js +3 -1
- package/dist/core/model-registry.d.ts +10 -2
- package/dist/core/model-registry.js +12 -4
- package/dist/core/model-runtime.d.ts +8 -0
- package/dist/core/model-runtime.js +39 -1
- package/dist/core/provider-failure.d.ts +6 -0
- package/dist/core/provider-failure.js +6 -2
- package/dist/core/retry-fallback/controller-types.d.ts +7 -0
- package/dist/core/retry-fallback/controller.d.ts +2 -0
- package/dist/core/retry-fallback/controller.js +13 -4
- package/dist/core/retry-fallback/credential-recovery.d.ts +18 -0
- package/dist/core/retry-fallback/credential-recovery.js +32 -0
- package/dist/core/retry-fallback/exhaustion.d.ts +18 -0
- package/dist/core/retry-fallback/exhaustion.js +20 -0
- package/dist/core/retry-fallback/settings.d.ts +8 -1
- package/dist/core/retry-fallback/settings.js +12 -6
- package/dist/core/session-log.js +1 -1
- package/dist/core/settings-manager.js +4 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/tools/bash.d.ts +3 -1
- package/dist/core/tools/bash.js +14 -4
- package/dist/core/tools/edit.d.ts +1 -1
- package/dist/core/tools/edit.js +1 -6
- package/dist/core/tools/grep/index.js +2 -3
- package/dist/core/tools/powershell.d.ts +1 -1
- package/dist/core/tools/powershell.js +1 -1
- package/dist/core/tools/read.d.ts +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/write.d.ts +1 -1
- package/dist/core/tools/write.js +1 -1
- package/dist/engine-trust/shell-trust.d.ts +36 -0
- package/dist/engine-trust/shell-trust.js +44 -0
- package/dist/engine-trust/transport-failure.d.ts +12 -0
- package/dist/engine-trust/transport-failure.js +48 -0
- package/dist/modes/interactive/interactive-mode.js +9 -3
- package/dist/modes/print-mode.js +2 -1
- package/dist/modes/rpc/compact-catalog-families.d.ts +5 -2
- package/dist/modes/rpc/compact-catalog-families.js +5 -2
- package/dist/modes/rpc/compact-catalog-registry.d.ts +9 -1
- package/dist/modes/rpc/compact-catalog-registry.js +9 -2
- package/dist/modes/rpc/compact-recovery-manifest-kinds.d.ts +17 -0
- package/dist/modes/rpc/compact-recovery-manifest-kinds.js +21 -0
- package/dist/modes/rpc/compact-recovery-manifest-shape.d.ts +7 -0
- package/dist/modes/rpc/compact-recovery-manifest.js +11 -3
- package/dist/modes/rpc/compact-socket-commands.js +6 -0
- package/dist/modes/rpc/connection-handler.js +24 -6
- package/dist/modes/rpc/connection-question-bridge.d.ts +3 -1
- package/dist/modes/rpc/connection-question-bridge.js +4 -1
- package/dist/modes/rpc/connection-roles.d.ts +8 -0
- package/dist/modes/rpc/connection-roles.js +18 -0
- package/dist/modes/rpc/effect-commands.d.ts +1 -0
- package/dist/modes/rpc/loopless-execute-grant.d.ts +20 -0
- package/dist/modes/rpc/loopless-execute-grant.js +26 -0
- package/dist/modes/rpc/loopless-runtime-settings.d.ts +30 -0
- package/dist/modes/rpc/loopless-runtime-settings.js +69 -0
- package/dist/modes/rpc/loopless-tool-call.d.ts +12 -0
- package/dist/modes/rpc/loopless-tool-call.js +22 -0
- package/dist/modes/rpc/method-classes-schema-session.d.ts +4 -0
- package/dist/modes/rpc/method-classes-schema-session.js +1 -0
- package/dist/modes/rpc/method-classes-schema.d.ts +4 -0
- package/dist/modes/rpc/protocol-identity.js +2 -0
- package/dist/modes/rpc/remote-origin.d.ts +31 -0
- package/dist/modes/rpc/remote-origin.js +58 -0
- package/dist/modes/rpc/rpc-protocol-info-types.d.ts +8 -0
- package/dist/modes/rpc/rpc-question-types.d.ts +7 -0
- package/dist/modes/rpc/rpc-question-types.js +0 -3
- package/dist/modes/rpc/rpc-read-response-types.d.ts +2 -1
- package/dist/modes/rpc/rpc-session-command-types.d.ts +3 -0
- package/dist/modes/rpc/rpc-session-state-types.d.ts +10 -0
- package/dist/modes/rpc/rpc-types.d.ts +1 -1
- package/dist/modes/rpc/runtime-factory-loopless.d.ts +57 -0
- package/dist/modes/rpc/runtime-factory-loopless.js +131 -0
- package/dist/modes/rpc/session-registry.js +12 -3
- package/dist/modes/rpc/session-worker-client.js +2 -0
- package/dist/modes/rpc/session-worker-protocol.d.ts +3 -0
- package/dist/modes/rpc/session-worker.js +2 -0
- package/docs/development.md +1 -1
- package/docs/engine-socket/fixtures/admission-routes/c-baseline.json +3 -3
- package/docs/engine-socket/fixtures/admission-routes/h-legacy.json +1 -1
- package/docs/engine-socket/fixtures/admission-routes/i-reset-stream.json +3 -3
- package/docs/engine-socket/fixtures/recovery-manifest/index.json +32 -0
- package/docs/engine-socket/fixtures/recovery-manifest/one-partial-family.json +118 -0
- package/docs/rpc.md +95 -3
- package/package.json +6 -6
- package/dist/bundle/chunks/anthropic-messages-WUPLDYD6.js +0 -10
- package/dist/bundle/chunks/chunk-7UC4W2T2.js +0 -2
- package/dist/bundle/chunks/chunk-O4GRBX4R.js +0 -3
- package/dist/bundle/chunks/chunk-R23WXN4L.js +0 -448
- package/dist/bundle/chunks/chunk-W5NLCRB3.js +0 -2
- package/dist/bundle/chunks/credential-accounts-OAK2E5O2.js +0 -2
- package/dist/bundle/chunks/host-command-WJIMRBGN.js +0 -2
- package/dist/bundle/chunks/interactive-mode-NPHFDPGH.js +0 -2
- package/dist/bundle/chunks/main-I6FJAFUP.js +0 -2
- package/dist/bundle/chunks/rotation-stream-ZDCNHIBE.js +0 -2
- package/dist/bundle/chunks/rpc-mode-GBBTN2WP.js +0 -2
|
@@ -923,6 +923,10 @@ export declare const SESSION_RECORD_SCHEMAS: {
|
|
|
923
923
|
} & {
|
|
924
924
|
readonly width: Type.TInteger;
|
|
925
925
|
readonly capabilities: Type.TOptional<Type.TArray<Type.TString>>;
|
|
926
|
+
readonly remoteOrigin: Type.TOptional<Type.TObject<{
|
|
927
|
+
deviceId: Type.TString;
|
|
928
|
+
deviceName: Type.TOptional<Type.TString>;
|
|
929
|
+
}>>;
|
|
926
930
|
}>;
|
|
927
931
|
};
|
|
928
932
|
//# sourceMappingURL=method-classes-schema-session.d.ts.map
|
|
@@ -198,6 +198,7 @@ const SURFACE_AND_ACCOUNT_SCHEMAS = {
|
|
|
198
198
|
set_client_info: session("set_client_info", {
|
|
199
199
|
width: Type.Integer({ minimum: 1, maximum: 100_000 }),
|
|
200
200
|
capabilities: Opt(Strings),
|
|
201
|
+
remoteOrigin: Opt(Type.Object({ deviceId: Id, deviceName: OptId }, { additionalProperties: false })),
|
|
201
202
|
}),
|
|
202
203
|
};
|
|
203
204
|
export const SESSION_RECORD_SCHEMAS = {
|
|
@@ -1268,6 +1268,10 @@ export declare const RPC_INBOUND_SCHEMAS: {
|
|
|
1268
1268
|
} & {
|
|
1269
1269
|
readonly width: import("typebox").TInteger;
|
|
1270
1270
|
readonly capabilities: import("typebox").TOptional<import("typebox").TArray<import("typebox").TString>>;
|
|
1271
|
+
readonly remoteOrigin: import("typebox").TOptional<import("typebox").TObject<{
|
|
1272
|
+
deviceId: import("typebox").TString;
|
|
1273
|
+
deviceName: import("typebox").TOptional<import("typebox").TString>;
|
|
1274
|
+
}>>;
|
|
1271
1275
|
}>;
|
|
1272
1276
|
};
|
|
1273
1277
|
export type RpcInboundValidation = {
|
|
@@ -19,6 +19,7 @@ import { parseArgs, resolveSessionRuntime } from "../../cli/args.js";
|
|
|
19
19
|
import { getAgentDir } from "../../config.js";
|
|
20
20
|
import { engineBuildIdentity } from "../../core/engine-build-identity.js";
|
|
21
21
|
import { HOST_GENERATION_ENV, HOST_INSTANCE_ID_ENV } from "./host-identity-env.js";
|
|
22
|
+
import { RPC_METHOD_CLASSES_DIGEST, RPC_METHOD_CLASSES_VERSION } from "./method-classes.js";
|
|
22
23
|
export { HOST_GENERATION_ENV, HOST_INSTANCE_ID_ENV };
|
|
23
24
|
/** Identity of THIS host process, fixed for its lifetime. */
|
|
24
25
|
const INSTANCE_ID = resolveInstanceId(process.env[HOST_INSTANCE_ID_ENV]);
|
|
@@ -69,6 +70,7 @@ export function protocolIdentity(agentDir = resolve(getAgentDir())) {
|
|
|
69
70
|
engineOrdinal: build.ordinal,
|
|
70
71
|
launch_profile: cachedProfile,
|
|
71
72
|
agentDir,
|
|
73
|
+
method_classes: { version: RPC_METHOD_CLASSES_VERSION, digest: RPC_METHOD_CLASSES_DIGEST },
|
|
72
74
|
};
|
|
73
75
|
}
|
|
74
76
|
//# sourceMappingURL=protocol-identity.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The remote device a connection speaks for (senpi#5475, omo-relay-daemon#184 P5).
|
|
3
|
+
*
|
|
4
|
+
* A relay forwarder opens one engine connection per remote sender and declares, through its own
|
|
5
|
+
* `set_client_info`, which device that connection speaks for. Every dialog a command of that connection raises
|
|
6
|
+
* then carries the value as `remoteOrigin`, so the host's desktop and TUI can label it "Requested from <device>".
|
|
7
|
+
* A connection that never declared one is local, and its dialogs carry no `remoteOrigin`. The engine copies only
|
|
8
|
+
* this declared value, never a free-form client name. `set_client_info` is `connection_local` in the method-class
|
|
9
|
+
* table, so a forwarded record can never set or change it.
|
|
10
|
+
*/
|
|
11
|
+
export interface RpcRemoteOrigin {
|
|
12
|
+
readonly deviceId: string;
|
|
13
|
+
readonly deviceName?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Validates a `set_client_info.remoteOrigin` against what the connection already declared, before anything of the
|
|
17
|
+
* declaration is committed: the origin to record (none when the field is absent), or the refusal to answer.
|
|
18
|
+
*/
|
|
19
|
+
export declare function remoteOriginDeclaration(value: unknown, accepts: (origin: RpcRemoteOrigin) => boolean): {
|
|
20
|
+
readonly origin: RpcRemoteOrigin | undefined;
|
|
21
|
+
} | {
|
|
22
|
+
readonly refusal: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function sameRemoteOrigin(a: RpcRemoteOrigin, b: RpcRemoteOrigin): boolean;
|
|
25
|
+
export declare function remoteOriginField(origin: RpcRemoteOrigin | undefined): {
|
|
26
|
+
remoteOrigin?: RpcRemoteOrigin;
|
|
27
|
+
};
|
|
28
|
+
export declare function originField(origin: RpcRemoteOrigin | undefined): {
|
|
29
|
+
origin?: RpcRemoteOrigin;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=remote-origin.d.ts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The remote device a connection speaks for (senpi#5475, omo-relay-daemon#184 P5).
|
|
3
|
+
*
|
|
4
|
+
* A relay forwarder opens one engine connection per remote sender and declares, through its own
|
|
5
|
+
* `set_client_info`, which device that connection speaks for. Every dialog a command of that connection raises
|
|
6
|
+
* then carries the value as `remoteOrigin`, so the host's desktop and TUI can label it "Requested from <device>".
|
|
7
|
+
* A connection that never declared one is local, and its dialogs carry no `remoteOrigin`. The engine copies only
|
|
8
|
+
* this declared value, never a free-form client name. `set_client_info` is `connection_local` in the method-class
|
|
9
|
+
* table, so a forwarded record can never set or change it.
|
|
10
|
+
*/
|
|
11
|
+
const MAX_DEVICE_ID_CHARACTERS = 256;
|
|
12
|
+
const MAX_DEVICE_NAME_CHARACTERS = 256;
|
|
13
|
+
const REMOTE_ORIGIN_INVALID = "remote_origin_invalid: remoteOrigin must be { deviceId: non-empty string, deviceName?: non-empty string }";
|
|
14
|
+
const REMOTE_ORIGIN_FIXED = "remote_origin_fixed: a connection's remoteOrigin cannot change after it is declared";
|
|
15
|
+
function boundedText(value, max) {
|
|
16
|
+
return typeof value === "string" && value.length > 0 && value.length <= max;
|
|
17
|
+
}
|
|
18
|
+
/** The declared origin, `undefined` when the field is absent, or `"invalid"` for any other shape. */
|
|
19
|
+
function parseRemoteOrigin(value) {
|
|
20
|
+
if (value === undefined)
|
|
21
|
+
return undefined;
|
|
22
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
23
|
+
return "invalid";
|
|
24
|
+
const deviceId = Reflect.get(value, "deviceId");
|
|
25
|
+
const deviceName = Reflect.get(value, "deviceName");
|
|
26
|
+
const keys = Object.keys(value);
|
|
27
|
+
if (keys.some((key) => key !== "deviceId" && key !== "deviceName"))
|
|
28
|
+
return "invalid";
|
|
29
|
+
if (!boundedText(deviceId, MAX_DEVICE_ID_CHARACTERS))
|
|
30
|
+
return "invalid";
|
|
31
|
+
if (deviceName === undefined)
|
|
32
|
+
return { deviceId };
|
|
33
|
+
if (!boundedText(deviceName, MAX_DEVICE_NAME_CHARACTERS))
|
|
34
|
+
return "invalid";
|
|
35
|
+
return { deviceId, deviceName };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Validates a `set_client_info.remoteOrigin` against what the connection already declared, before anything of the
|
|
39
|
+
* declaration is committed: the origin to record (none when the field is absent), or the refusal to answer.
|
|
40
|
+
*/
|
|
41
|
+
export function remoteOriginDeclaration(value, accepts) {
|
|
42
|
+
const origin = parseRemoteOrigin(value);
|
|
43
|
+
if (origin === "invalid")
|
|
44
|
+
return { refusal: REMOTE_ORIGIN_INVALID };
|
|
45
|
+
if (origin !== undefined && !accepts(origin))
|
|
46
|
+
return { refusal: REMOTE_ORIGIN_FIXED };
|
|
47
|
+
return { origin };
|
|
48
|
+
}
|
|
49
|
+
export function sameRemoteOrigin(a, b) {
|
|
50
|
+
return a.deviceId === b.deviceId && a.deviceName === b.deviceName;
|
|
51
|
+
}
|
|
52
|
+
export function remoteOriginField(origin) {
|
|
53
|
+
return origin === undefined ? {} : { remoteOrigin: origin };
|
|
54
|
+
}
|
|
55
|
+
export function originField(origin) {
|
|
56
|
+
return origin === undefined ? {} : { origin };
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=remote-origin.js.map
|
|
@@ -33,6 +33,14 @@ export interface RpcProtocolIdentity {
|
|
|
33
33
|
readonly launch_profile: RpcLaunchProfile;
|
|
34
34
|
/** Absolute agent directory this host reads and writes; a handoff from another agent dir is refused. */
|
|
35
35
|
readonly agentDir: string;
|
|
36
|
+
/**
|
|
37
|
+
* The inbound method-class table this engine runs (`method-classes.ts`): a remote forwarder classifies with its
|
|
38
|
+
* own copy only while that copy's digest equals `digest`.
|
|
39
|
+
*/
|
|
40
|
+
readonly method_classes: {
|
|
41
|
+
readonly version: number;
|
|
42
|
+
readonly digest: string;
|
|
43
|
+
};
|
|
36
44
|
}
|
|
37
45
|
export interface RpcProtocolInfo extends RpcProtocolIdentity {
|
|
38
46
|
/** Present only on a public POSIX endpoint's answer to a challenge (wire contract v1.1). */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RpcRemoteOrigin } from "./remote-origin.ts";
|
|
1
2
|
/** One question in an RPC `question` UI request. Matches canonical QuestionRequest.questions. */
|
|
2
3
|
export type RpcQuestionSpec = {
|
|
3
4
|
id: string;
|
|
@@ -25,6 +26,8 @@ export type RpcQuestionUiRequest = {
|
|
|
25
26
|
questions: RpcQuestionSpec[];
|
|
26
27
|
/** The connection whose command raised the question, or `"agent"` when no connection's command was dispatching. */
|
|
27
28
|
raisedBy?: string;
|
|
29
|
+
/** The remote device the raising connection speaks for (senpi#5475); absent for a local connection. */
|
|
30
|
+
remoteOrigin?: RpcRemoteOrigin;
|
|
28
31
|
timeout: number;
|
|
29
32
|
askedAtMs: number;
|
|
30
33
|
deadlineAtMs: number;
|
|
@@ -35,6 +38,7 @@ export type RpcExtensionUIRequest = {
|
|
|
35
38
|
type: "extension_ui_request";
|
|
36
39
|
id: string;
|
|
37
40
|
method: "select";
|
|
41
|
+
remoteOrigin?: RpcRemoteOrigin;
|
|
38
42
|
/** Permanent MCP env grant; only a grant_select presentation may answer. */
|
|
39
43
|
grantSelect?: boolean;
|
|
40
44
|
title: string;
|
|
@@ -50,10 +54,12 @@ export type RpcExtensionUIRequest = {
|
|
|
50
54
|
title: string;
|
|
51
55
|
message: string;
|
|
52
56
|
timeout?: number;
|
|
57
|
+
remoteOrigin?: RpcRemoteOrigin;
|
|
53
58
|
} | {
|
|
54
59
|
type: "extension_ui_request";
|
|
55
60
|
id: string;
|
|
56
61
|
method: "input";
|
|
62
|
+
remoteOrigin?: RpcRemoteOrigin;
|
|
57
63
|
secret?: boolean;
|
|
58
64
|
deadlineAtMs?: number;
|
|
59
65
|
title: string;
|
|
@@ -67,6 +73,7 @@ export type RpcExtensionUIRequest = {
|
|
|
67
73
|
method: "editor";
|
|
68
74
|
title: string;
|
|
69
75
|
prefill?: string;
|
|
76
|
+
remoteOrigin?: RpcRemoteOrigin;
|
|
70
77
|
} | {
|
|
71
78
|
type: "extension_ui_request";
|
|
72
79
|
id: string;
|
|
@@ -11,7 +11,7 @@ import type { ThinkingLevelSource } from "../../core/session-thinking-memory.ts"
|
|
|
11
11
|
import type { EffectStatus } from "./effect-record.ts";
|
|
12
12
|
import type { RpcSlashCommand } from "./rpc-command-surface.ts";
|
|
13
13
|
import type { RpcEvalCell, RpcEvalCellSnapshot } from "./rpc-result-types.ts";
|
|
14
|
-
import type { RpcAuthProvider, RpcLoadedExtension, RpcLoadedMcpServer, RpcProviderAccount, RpcSessionState } from "./rpc-session-state-types.ts";
|
|
14
|
+
import type { RpcAuthProvider, RpcAuthStoreError, RpcLoadedExtension, RpcLoadedMcpServer, RpcProviderAccount, RpcSessionState } from "./rpc-session-state-types.ts";
|
|
15
15
|
import type { RpcSnapshot } from "./snapshot-types.ts";
|
|
16
16
|
export type RpcReadResponse = {
|
|
17
17
|
id?: string;
|
|
@@ -215,6 +215,7 @@ export type RpcReadResponse = {
|
|
|
215
215
|
success: true;
|
|
216
216
|
data: {
|
|
217
217
|
providers: RpcAuthProvider[];
|
|
218
|
+
storeError?: RpcAuthStoreError;
|
|
218
219
|
};
|
|
219
220
|
} | {
|
|
220
221
|
id?: string;
|
|
@@ -6,6 +6,7 @@ import type { ClientMessageIdentity } from "../../core/client-message-identity.t
|
|
|
6
6
|
import type { SessionEntry } from "../../core/session-manager.ts";
|
|
7
7
|
import type { ToolBarrierSpec } from "../../core/tool-barrier.ts";
|
|
8
8
|
import type { RpcRecoveryCommand } from "./rpc-recovery-command-types.ts";
|
|
9
|
+
import type { RpcRemoteOrigin } from "./remote-origin.ts";
|
|
9
10
|
import type { RpcSessionModelEntry } from "./rpc-session-state-types.ts";
|
|
10
11
|
export type RpcSessionCommand = {
|
|
11
12
|
id?: string;
|
|
@@ -521,6 +522,8 @@ export type RpcSessionCommand = {
|
|
|
521
522
|
type: "set_client_info";
|
|
522
523
|
width: number;
|
|
523
524
|
capabilities?: string[];
|
|
525
|
+
/** Declared by a relay forwarder for the remote device this connection speaks for (senpi#5475). */
|
|
526
|
+
remoteOrigin?: RpcRemoteOrigin;
|
|
524
527
|
};
|
|
525
528
|
/** What `steer`/`follow_up` do on an idle session: queue (default) or start a turn. */
|
|
526
529
|
export type RpcWhenIdle = "queue" | "start";
|
|
@@ -27,6 +27,16 @@ export interface RpcAuthProvider {
|
|
|
27
27
|
/** Where the provider is defined, so a client can name the file or extension to edit (senpi#4328). */
|
|
28
28
|
origin?: ProviderOrigin;
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* `get_auth_providers` `storeError`: auth.json exists but could not be loaded, so stored sign-ins read
|
|
32
|
+
* as unconfigured and every write is refused until it is repaired. `write_back_failed` is the exception:
|
|
33
|
+
* the file was read, so its sign-ins stay configured and writes are not refused (senpi#4413).
|
|
34
|
+
* Never a path or contents.
|
|
35
|
+
*/
|
|
36
|
+
export interface RpcAuthStoreError {
|
|
37
|
+
kind: "malformed_json" | "invalid_format" | "unreadable" | "write_back_failed";
|
|
38
|
+
reason: string;
|
|
39
|
+
}
|
|
30
40
|
/** Auth status mirror (no credential values), from getProviderAuthStatus. */
|
|
31
41
|
export interface RpcAuthStatus {
|
|
32
42
|
configured: boolean;
|
|
@@ -16,7 +16,7 @@ export type { EditAssistantMessageResult, EditUserMessageResult, NavigateTreeRes
|
|
|
16
16
|
export type { RpcWhenIdle } from "./rpc-session-command-types.ts";
|
|
17
17
|
export { STEER_WHEN_IDLE_CAPABILITY, USER_ACTIVITY_CAPABILITY } from "./rpc-session-command-types.ts";
|
|
18
18
|
export type { RpcAccountFailoverEvent, RpcAuthAccountsChangedEvent, RpcExtensionEvent, RpcHighReasoningWarningEvent, RpcLoadedSurfacesChangedEvent, RpcModelChangedEvent, RpcOpenQueuedEvent, RpcPendingInputUpdateEvent, RpcServiceTierChangedEvent, RpcSessionClosedEvent, RpcSessionClosedReason, RpcSessionOpenedEvent, RpcSessionParkedEvent, RpcSessionReplacedEvent, RpcSettingsSourceSelectedEvent, RpcSkillInvocationEvent, RpcThinkingLevelChangedEvent, } from "./rpc-session-event-types.ts";
|
|
19
|
-
export type { RpcAuthProvider, RpcAuthStatus, RpcLoadedExtension, RpcLoadedMcpServer, RpcMcpServerStatus, RpcProviderAccount, RpcSessionModelEntry, RpcSessionState, } from "./rpc-session-state-types.ts";
|
|
19
|
+
export type { RpcAuthProvider, RpcAuthStatus, RpcAuthStoreError, RpcLoadedExtension, RpcLoadedMcpServer, RpcMcpServerStatus, RpcProviderAccount, RpcSessionModelEntry, RpcSessionState, } from "./rpc-session-state-types.ts";
|
|
20
20
|
export type { SessionEffectStatusRecord as RpcEffectStatusEvent } from "./session-effect-status.ts";
|
|
21
21
|
export type { SessionStatusRecord as RpcSessionStatusEvent } from "./session-status.ts";
|
|
22
22
|
//# sourceMappingURL=rpc-types.d.ts.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
2
|
+
import type { AgentSessionLaunchProfile } from "../../core/agent-session-runtime.ts";
|
|
3
|
+
import { type AgentSessionRuntimeDiagnostic } from "../../core/agent-session-services.ts";
|
|
4
|
+
import type { InlineExtension } from "../../core/extensions/types.ts";
|
|
5
|
+
import { type ToolDefinitionEntry } from "../../core/runtime/bootstrap.ts";
|
|
6
|
+
import { SettingsManager } from "../../core/settings-manager.ts";
|
|
7
|
+
import type { CliRuntimeConfiguration } from "../../main.ts";
|
|
8
|
+
import { type LooplessExecuteGrant } from "./loopless-execute-grant.ts";
|
|
9
|
+
/**
|
|
10
|
+
* A session worker's runtime with the agent loop removed (brain/hand split, senpi#5413): the same
|
|
11
|
+
* built-in and extension tools a full session serves, executed one call at a time, with no agent loop,
|
|
12
|
+
* no model binding and no transcript. Its extension runtime is never bound to a loop, so an extension
|
|
13
|
+
* that tries to drive one (`pi.sendUserMessage`, `pi.setModel`, ...) is refused.
|
|
14
|
+
*/
|
|
15
|
+
export interface LooplessRuntime {
|
|
16
|
+
readonly cwd: string;
|
|
17
|
+
/** Every tool this runtime serves: built-ins first, then extension tools, a later name replacing an earlier one. */
|
|
18
|
+
readonly definitions: ReadonlyMap<string, ToolDefinitionEntry>;
|
|
19
|
+
/** What building the runtime reported: settings, extension load and `project_trust` handler diagnostics. */
|
|
20
|
+
readonly diagnostics: readonly AgentSessionRuntimeDiagnostic[];
|
|
21
|
+
/**
|
|
22
|
+
* Runs one tool call: argument preparation and schema validation as the loop does, then the tool. An unknown
|
|
23
|
+
* name is refused before anything runs; invalid arguments and a failing tool come back as an `isError` result.
|
|
24
|
+
*
|
|
25
|
+
* It does NOT run the extensions' `tool_call`/`tool_result` handlers (permission checks among them): where those
|
|
26
|
+
* run for a call that reaches a tool-execution-only process is decided by the remote tool executor that calls
|
|
27
|
+
* this runtime, including forwarding a two-sided extension's handlers to the process that owns the session.
|
|
28
|
+
* Until that executor exists, a runtime refuses every call unless it was built with a grant from the closed
|
|
29
|
+
* allowlist in `loopless-execute-grant.ts` (the in-process test harness only).
|
|
30
|
+
*/
|
|
31
|
+
execute(name: string, toolCallId: string, params: unknown, signal?: AbortSignal): Promise<AgentToolResult<unknown>>;
|
|
32
|
+
/** Marks its extension contexts stale, then closes the tool work and the tool child it still runs. */
|
|
33
|
+
dispose(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
export interface LooplessRuntimeProfile {
|
|
36
|
+
cwd: string;
|
|
37
|
+
launchProfile?: Readonly<AgentSessionLaunchProfile>;
|
|
38
|
+
}
|
|
39
|
+
export type LooplessRuntimeFactory = (profile: LooplessRuntimeProfile) => Promise<LooplessRuntime>;
|
|
40
|
+
export declare class LooplessToolNotFoundError extends Error {
|
|
41
|
+
readonly toolName: string;
|
|
42
|
+
constructor(toolName: string);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Builds loopless runtimes from the same launch configuration as `createCliRuntimeFactory`: the same
|
|
46
|
+
* cwd-bound services (settings, project trust, model registry, extensions and their flags), then the tool
|
|
47
|
+
* registry through `bootstrapRuntime()` / `buildToolRegistry()` (senpi#5222) on a runner without a session
|
|
48
|
+
* (senpi#5223), so nothing is ever written to a session file. Tools are placed by the same tool-child runtime
|
|
49
|
+
* a session builds (senpi#5227), so `--tool-runtime child` runs child-placed work on this runtime's own child.
|
|
50
|
+
*/
|
|
51
|
+
export declare function createLooplessRuntimeFactory(configuration: CliRuntimeConfiguration, local?: {
|
|
52
|
+
extensionFactories?: InlineExtension[];
|
|
53
|
+
startupSettingsManager?: SettingsManager;
|
|
54
|
+
/** Required for `execute`; see `loopless-execute-grant.ts`. */
|
|
55
|
+
executeGrant?: LooplessExecuteGrant;
|
|
56
|
+
}): LooplessRuntimeFactory;
|
|
57
|
+
//# sourceMappingURL=runtime-factory-loopless.d.ts.map
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { createAgentSessionServices } from "../../core/agent-session-services.js";
|
|
3
|
+
import { bootstrapRuntime, buildToolRegistry } from "../../core/runtime/bootstrap.js";
|
|
4
|
+
import { SettingsManager } from "../../core/settings-manager.js";
|
|
5
|
+
import { childModuleRoots } from "../../core/tool-dispatch/offload.js";
|
|
6
|
+
import { createToolChildRuntime } from "../../core/tool-dispatch/tool-child-runtime.js";
|
|
7
|
+
import { builtInExtensions } from "../../extensions/index.js";
|
|
8
|
+
import { looplessToolFilters, resolveCliPaths, resolveLooplessSettings } from "./loopless-runtime-settings.js";
|
|
9
|
+
import { isLooplessExecuteGranted, LooplessExecuteRefusedError, } from "./loopless-execute-grant.js";
|
|
10
|
+
import { runLooplessToolCall } from "./loopless-tool-call.js";
|
|
11
|
+
import { toolChildModuleRoots } from "./tool-child/session-child.js";
|
|
12
|
+
export class LooplessToolNotFoundError extends Error {
|
|
13
|
+
constructor(toolName) {
|
|
14
|
+
super(`loopless_tool_not_found: ${toolName}`);
|
|
15
|
+
this.toolName = toolName;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Builds loopless runtimes from the same launch configuration as `createCliRuntimeFactory`: the same
|
|
20
|
+
* cwd-bound services (settings, project trust, model registry, extensions and their flags), then the tool
|
|
21
|
+
* registry through `bootstrapRuntime()` / `buildToolRegistry()` (senpi#5222) on a runner without a session
|
|
22
|
+
* (senpi#5223), so nothing is ever written to a session file. Tools are placed by the same tool-child runtime
|
|
23
|
+
* a session builds (senpi#5227), so `--tool-runtime child` runs child-placed work on this runtime's own child.
|
|
24
|
+
*/
|
|
25
|
+
export function createLooplessRuntimeFactory(configuration, local = {}) {
|
|
26
|
+
const { parsed, agentDir, toolRuntime } = configuration;
|
|
27
|
+
const extensionFactories = local.extensionFactories ?? builtInExtensions;
|
|
28
|
+
const startupSettingsManager = local.startupSettingsManager ?? SettingsManager.create(configuration.cwd, configuration.agentDir);
|
|
29
|
+
return async (profile) => {
|
|
30
|
+
const { cwd } = profile;
|
|
31
|
+
const diagnostics = [];
|
|
32
|
+
const { settingsManager, flagValues, reloadOptions } = await resolveLooplessSettings(configuration, startupSettingsManager, profile, diagnostics);
|
|
33
|
+
const services = await createAgentSessionServices({
|
|
34
|
+
cwd,
|
|
35
|
+
agentDir,
|
|
36
|
+
settingsManager,
|
|
37
|
+
modelRuntimeSignal: AbortSignal.timeout(15_000),
|
|
38
|
+
extensionFlagValues: flagValues,
|
|
39
|
+
...(reloadOptions ? { resourceLoaderReloadOptions: reloadOptions } : {}),
|
|
40
|
+
resourceLoaderOptions: {
|
|
41
|
+
sessionKind: profile.launchProfile?.sessionKind,
|
|
42
|
+
sessionContext: profile.launchProfile?.sessionContext,
|
|
43
|
+
additionalExtensionPaths: resolveCliPaths(cwd, parsed.extensions),
|
|
44
|
+
additionalSkillPaths: resolveCliPaths(cwd, parsed.skills),
|
|
45
|
+
additionalPromptTemplatePaths: resolveCliPaths(cwd, parsed.promptTemplates),
|
|
46
|
+
additionalThemePaths: resolveCliPaths(cwd, parsed.themes),
|
|
47
|
+
noExtensions: parsed.noExtensions,
|
|
48
|
+
noSkills: parsed.noSkills,
|
|
49
|
+
noPromptTemplates: parsed.noPromptTemplates,
|
|
50
|
+
noThemes: parsed.noThemes,
|
|
51
|
+
noContextFiles: parsed.noContextFiles,
|
|
52
|
+
extensionFactories,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
const extensionsResult = services.resourceLoader.getExtensions();
|
|
56
|
+
diagnostics.push(...services.diagnostics, ...extensionsResult.errors.map(({ path, error }) => ({
|
|
57
|
+
type: "warning",
|
|
58
|
+
message: `Failed to load extension "${path}": ${error}`,
|
|
59
|
+
})), ...(extensionsResult.warnings ?? []).map(({ path, warning }) => ({
|
|
60
|
+
type: "warning",
|
|
61
|
+
message: `Extension package "${path}": ${warning}`,
|
|
62
|
+
})));
|
|
63
|
+
let execute = () => Promise.reject(new Error("Loopless runtime is not ready"));
|
|
64
|
+
let toolNames = () => [];
|
|
65
|
+
const toolChildRuntime = createToolChildRuntime({
|
|
66
|
+
toolRuntime: toolRuntime ?? "in-process",
|
|
67
|
+
agentDir,
|
|
68
|
+
scopeId: `loopless-${randomUUID()}`,
|
|
69
|
+
cwd: services.cwd,
|
|
70
|
+
moduleRoots: () => [
|
|
71
|
+
...toolChildModuleRoots(runtime.extensionRunner.getAllRegisteredTools()),
|
|
72
|
+
...childModuleRoots(runtime.extensionRunner.getAllChildModules()),
|
|
73
|
+
],
|
|
74
|
+
hostCallDeps: {
|
|
75
|
+
cwd: services.cwd,
|
|
76
|
+
executeNested: async (_parentToolCallId, name, args, signal) => {
|
|
77
|
+
const toolCall = { type: "toolCall", id: `nested-${randomUUID()}`, name, arguments: {} };
|
|
78
|
+
const result = await execute(name, toolCall.id, args, signal);
|
|
79
|
+
return { toolCall, result, isError: result.isError === true };
|
|
80
|
+
},
|
|
81
|
+
callableToolNames: () => toolNames(),
|
|
82
|
+
target: () => undefined,
|
|
83
|
+
filesystemPolicy: () => runtime.filesystemPolicy,
|
|
84
|
+
},
|
|
85
|
+
onRecord: () => { },
|
|
86
|
+
});
|
|
87
|
+
const { dispatcher, toolChild } = toolChildRuntime;
|
|
88
|
+
const runtime = bootstrapRuntime({
|
|
89
|
+
cwd: services.cwd,
|
|
90
|
+
settingsManager: services.settingsManager,
|
|
91
|
+
extensionsResult,
|
|
92
|
+
modelRegistry: services.modelRegistry,
|
|
93
|
+
toolDispatcher: dispatcher,
|
|
94
|
+
});
|
|
95
|
+
const registry = buildToolRegistry({
|
|
96
|
+
baseToolDefinitions: runtime.baseToolDefinitions,
|
|
97
|
+
runner: runtime.extensionRunner,
|
|
98
|
+
dispatcher,
|
|
99
|
+
...looplessToolFilters(parsed, services.settingsManager),
|
|
100
|
+
});
|
|
101
|
+
toolNames = () => [...registry.toolRegistry.keys()];
|
|
102
|
+
execute = (name, toolCallId, params, signal) => {
|
|
103
|
+
if (!isLooplessExecuteGranted(local.executeGrant))
|
|
104
|
+
return Promise.reject(new LooplessExecuteRefusedError("no executor runs the tool_call/tool_result handlers for this runtime yet"));
|
|
105
|
+
const tool = registry.toolRegistry.get(name);
|
|
106
|
+
if (tool === undefined)
|
|
107
|
+
return Promise.reject(new LooplessToolNotFoundError(name));
|
|
108
|
+
return runLooplessToolCall(tool, {
|
|
109
|
+
toolCallId,
|
|
110
|
+
params,
|
|
111
|
+
...(signal ? { signal } : {}),
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
return {
|
|
115
|
+
cwd: services.cwd,
|
|
116
|
+
definitions: registry.definitions,
|
|
117
|
+
diagnostics,
|
|
118
|
+
execute: (name, toolCallId, params, signal) => execute(name, toolCallId, params, signal),
|
|
119
|
+
dispose: async () => {
|
|
120
|
+
// Stale first, as a session disposes: a close that fails must not leave the contexts usable.
|
|
121
|
+
runtime.extensionRunner.invalidate("This loopless runtime was disposed.");
|
|
122
|
+
// Both closes run to the end; the first failure is then reported to the caller.
|
|
123
|
+
const closed = await Promise.allSettled([dispatcher.dispose(), toolChild?.close()]);
|
|
124
|
+
const failure = closed.find((outcome) => outcome.status === "rejected");
|
|
125
|
+
if (failure !== undefined)
|
|
126
|
+
throw failure.reason;
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=runtime-factory-loopless.js.map
|
|
@@ -4,7 +4,7 @@ import { createRegistryWarm } from "./host-warm.js";
|
|
|
4
4
|
import { refreshesSessionActivity } from "./session-command-activity.js";
|
|
5
5
|
import { publishedSessionContext } from "./session-context-patch.js";
|
|
6
6
|
import { attachLiveSession, markPathAttached } from "./session-live-attachment.js";
|
|
7
|
-
import { syncRuntimeMetadata } from "./session-registry-claims.js";
|
|
7
|
+
import { beginPendingClaim, syncRuntimeMetadata } from "./session-registry-claims.js";
|
|
8
8
|
import { openRegistrySession } from "./session-registry-open.js";
|
|
9
9
|
import { RpcSessionRegistryError, } from "./session-registry-types.js";
|
|
10
10
|
import { beginSessionClose, closeMarkedSession, closeSession } from "./session-teardown.js";
|
|
@@ -44,8 +44,17 @@ export class RpcSessionRegistry {
|
|
|
44
44
|
return deleted;
|
|
45
45
|
},
|
|
46
46
|
releaseReservation: async (key) => {
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
// Close may finish at its grace deadline before removal settles. Keep
|
|
48
|
+
// that work visible to reopen even after the closing entry is gone. A failed removal
|
|
49
|
+
// still gives the path back: no entry is left to ever release it later.
|
|
50
|
+
const settle = beginPendingClaim(this.pendingClaims, key);
|
|
51
|
+
try {
|
|
52
|
+
await this.options.pathReservations?.release(key);
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
this.reservations.delete(key);
|
|
56
|
+
settle();
|
|
57
|
+
}
|
|
49
58
|
},
|
|
50
59
|
markDetached: (key) => this.options.pathReservations?.setAttached(key, false),
|
|
51
60
|
now: () => this.now(),
|
|
@@ -5,6 +5,7 @@ import { createWebViewBroker } from "../../core/webview/webview-broker.js";
|
|
|
5
5
|
import { workerCapabilities } from "./worker-client-capabilities.js";
|
|
6
6
|
import { captureAdmissionReply, withAdmissionReply } from "./compact-admission-reply.js";
|
|
7
7
|
import { roleConnection } from "./connection-roles.js";
|
|
8
|
+
import { originField } from "./remote-origin.js";
|
|
8
9
|
import { answeredUiRequestId, isGrantSelectRequest, refusedExtensionUiResponse } from "./extension-ui-response.js";
|
|
9
10
|
import { enqueueLegacyRecord } from "./legacy-record-depth.js";
|
|
10
11
|
import { SessionAcceptanceLane } from "./session-acceptance-lane.js";
|
|
@@ -199,6 +200,7 @@ export class SessionWorkerClient {
|
|
|
199
200
|
command,
|
|
200
201
|
connection,
|
|
201
202
|
roles: options.connectionRoles?.rolesOf(roleConnection(connection)),
|
|
203
|
+
...originField(options.connectionRoles?.originOf(connection)),
|
|
202
204
|
...(owner === undefined ? {} : { owner }),
|
|
203
205
|
});
|
|
204
206
|
},
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RpcRemoteOrigin } from "./remote-origin.ts";
|
|
1
2
|
import type { BrowserEngine } from "../../core/browser-engine.ts";
|
|
2
3
|
import type { McpFormInput, McpFormOutcome } from "../../core/mcp-form-types.ts";
|
|
3
4
|
import type { RecoveryCarrier } from "../../core/session-recovery-identity.ts";
|
|
@@ -96,6 +97,8 @@ export type HostToSessionWorker = {
|
|
|
96
97
|
command: object;
|
|
97
98
|
connection?: string;
|
|
98
99
|
roles?: readonly string[];
|
|
100
|
+
/** The remote device the connection declared on the host (senpi#5475); the isolate adopts it. */
|
|
101
|
+
origin?: RpcRemoteOrigin;
|
|
99
102
|
/** The gate the host captured at ingress, before its first await (#4728). */
|
|
100
103
|
owner?: ExtensionOwnerWire;
|
|
101
104
|
}
|
|
@@ -338,6 +338,8 @@ async function handle(message) {
|
|
|
338
338
|
throw new Error("session_closing");
|
|
339
339
|
if (message.roles !== undefined)
|
|
340
340
|
connectionRoles.adopt(roleConnection(message.connection), message.roles);
|
|
341
|
+
if (message.origin !== undefined)
|
|
342
|
+
connectionRoles.declareOrigin(roleConnection(message.connection), message.origin);
|
|
341
343
|
const activeBinding = binding;
|
|
342
344
|
const run = () => activeBinding.handle(message.command);
|
|
343
345
|
await workerAdmissionCommand(message, writer, issuedOwners, run);
|
package/docs/development.md
CHANGED
|
@@ -70,7 +70,7 @@ Never use `__dirname` directly for package assets.
|
|
|
70
70
|
```bash
|
|
71
71
|
bun run test # Vitest across workspaces (skips live-API; default test runner)
|
|
72
72
|
./pi-test.sh # Launch the CLI from source via tsx for manual testing (--no-env unsets API keys)
|
|
73
|
-
bun run check # oxlint +
|
|
73
|
+
bun run check # oxlint + bun fmt + lint ratchet + tsc + browser-smoke check (pre-commit equivalent)
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
Live-API tests are env-gated vitest tests. Set `PI_ENABLE_LIVE_API_TESTS=1` (or a per-provider flag from `packages/ai/test/live-api-gates.ts`) plus the provider API keys, then run `bun run test`.
|
|
@@ -43,9 +43,9 @@
|
|
|
43
43
|
"hint": "restart_from_catalog",
|
|
44
44
|
"retryAfterMs": 0
|
|
45
45
|
},
|
|
46
|
-
"length":
|
|
47
|
-
"digest": "
|
|
48
|
-
"bytes": "
|
|
46
|
+
"length": 1230,
|
|
47
|
+
"digest": "afc0506ef0b5e09ae70818c0b435b2fa633d3536d44f6e357950aad78d0102f9",
|
|
48
|
+
"bytes": "ewAiAGYAbwByAG0AYQB0ACIAOgAiAHMAZQBuAHAAaQAtAHIAZQBjAG8AdgBlAHIAeQAtAG0AYQBuAGkAZgBlAHMAdAAiACwAIgB2AGUAcgBzAGkAbwBuACIAOgAxACwAIgBzAG8AYwBrAGUAdABFAHAAbwBjAGgAIgA6AHsAIgBpAGQAIgA6ACIAcwBvAGMAawBlAHQALQAxACIAfQAsACIAYQBkAG0AaQBzAHMAaQBvAG4ASQBkACIAOgB7ACIAaQBkACIAOgAiAGcAbwBsAGQAZQBuAC0AYQAiAH0ALAAiAHIAbwB1AHQAZQBLAGkAbgBkACIAOgAiAG8AcgBkAGkAbgBhAHIAeQAiACwAIgBzAGUAcwBzAGkAbwBuACIAOgB7ACIAaQBkACIAOgAiAHIAcABjAC0AMQAiAH0ALAAiAHMAZQBzAHMAaQBvAG4ARQBwAG8AYwBoACIAOgB7ACIAaQBkACIAOgAiADAAMAAwADAAMAAwADAAMAAtADAAMAAwADAALQA0ADAAMAAwAC0AOAAwADAAMAAtADAAMAAwADAAMAAwADAAMAAwADAAMAAxACIAfQAsACIAZwBlAG4AZQByAGEAdABpAG8AbgAiADoAMQAsACIAcwBlAHEAdQBlAG4AYwBlACIAOgAwACwAIgBoAGkAcwB0AG8AcgB5AFYAZQByAHMAaQBvAG4AIgA6ADUALAAiAHQAbwBrAGUAbgAiADoAewAiAGkAZAAiADoAIgBzAG8AYwBrAGUAdAAtADEAOgAxACIAfQAsACIAbABlAGEAZgAiADoAewAiAGkAZAAiADoAIgAwADAAMAAwADAAMAAwADEAIgB9ACwAIgBhAGMAdABpAHYAZQBNAGUAcwBzAGEAZwBlACIAOgBuAHUAbABsACwAIgB0AHUAcgBuACIAOgBuAHUAbABsACwAIgBjAGgAZQBjAGsAcABvAGkAbgB0AEQAaQBnAGUAcwB0ACIAOgAiADEAYgBiAGMAYQBkADIAOQAzADIAMABmADIAMAA4ADQANwBhADUAMQA1AGMAYwA4ADUANAAwADYAMwBjAGQAYQAwAGQAZABhAGUAYQAyADAAYwBkAGMAZgBmADQANQBlAGIANgBiADUAZQAwAGUAOQBlAGUAMQA1AGYAYgBkADQAIgAsACIAYwBhAHQAYQBsAG8AZwBSAG8AbwB0ACIAOgAiAGMALQAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAxACIALAAiAGMAYQB0AGEAbABvAGcAUgBvAG8AdABMAGUAbgBnAHQAaAAiADoAMwA5ADQANgAsACIAcgBlAHEAdQBpAHIAZQBkAEsAaQBuAGQAcwAiADoAWwAiAGEAYwB0AGkAdgBlACIALAAiAGMAYQBsAGwAcwAiACwAIgBkAGkAYQBsAG8AZwBzACIALAAiAGkAZABlAG4AdABpAHQAeQAiACwAIgBsAGkAZgBlAGMAeQBjAGwAZQAiACwAIgBvAHAAYQBxAHUAZQAiACwAIgByAHUAbgAiACwAIgBzAGUAdAB0AGwAZQBkACIALAAiAHMAbwB1AHIAYwBlACIALAAiAHQAcgBhAG4AcwBjAHIAaQBwAHQAIgBdAH0A"
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
}
|