@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
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { stripBom } from "../utils/text.js";
|
|
2
|
+
import { CredentialStoreBusyError } from "./lockfile-policy.js";
|
|
3
|
+
export class AuthStoreUnreadableError extends Error {
|
|
4
|
+
constructor(loadError) {
|
|
5
|
+
super(`Your sign-in store (auth.json) could not be read: ${loadError.reason}. Nothing was changed; repair or move auth.json in the agent directory, then sign in again.`);
|
|
6
|
+
this.name = "AuthStoreUnreadableError";
|
|
7
|
+
this.loadError = loadError;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A store load that failed after auth.json was read and parsed: saving its repaired or migrated copy
|
|
12
|
+
* failed (`wroteBack`), or the lock was lost once the read was done. Neither means the file is unreadable.
|
|
13
|
+
*/
|
|
14
|
+
class AuthStoreAfterReadError extends Error {
|
|
15
|
+
constructor(cause, wroteBack) {
|
|
16
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
17
|
+
super(wroteBack
|
|
18
|
+
? `auth.json was read, but saving its repaired or migrated copy failed: ${detail}`
|
|
19
|
+
: `auth.json was read, but its lock was lost before the read finished: ${detail}`, { cause });
|
|
20
|
+
this.name = "AuthStoreAfterReadError";
|
|
21
|
+
this.wroteBack = wroteBack;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** The top-level object of an auth.json document; anything else is refused rather than read as empty. */
|
|
25
|
+
export function parseAuthDocument(content) {
|
|
26
|
+
let parsed;
|
|
27
|
+
try {
|
|
28
|
+
parsed = JSON.parse(stripBom(content));
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
throw new AuthStoreUnreadableError({ kind: "malformed_json", reason: "it is not valid JSON" });
|
|
32
|
+
}
|
|
33
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
34
|
+
throw new AuthStoreUnreadableError({ kind: "invalid_format", reason: "it does not hold a JSON object" });
|
|
35
|
+
}
|
|
36
|
+
return parsed;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The load error a failed store read stands for, or undefined when the failure says nothing about
|
|
40
|
+
* the file: a lock held by another writer, a read the caller aborted, or a lock lost after a clean read.
|
|
41
|
+
*/
|
|
42
|
+
export function describeAuthStoreLoadFailure(error) {
|
|
43
|
+
if (error instanceof AuthStoreUnreadableError)
|
|
44
|
+
return error.loadError;
|
|
45
|
+
if (error instanceof CredentialStoreBusyError)
|
|
46
|
+
return undefined;
|
|
47
|
+
if (error instanceof Error && error.name === "AbortError")
|
|
48
|
+
return undefined;
|
|
49
|
+
if (error instanceof AuthStoreAfterReadError) {
|
|
50
|
+
if (!error.wroteBack)
|
|
51
|
+
return undefined;
|
|
52
|
+
const code = errnoCode(error.cause);
|
|
53
|
+
const reason = "it was read, but its repaired or migrated copy could not be saved";
|
|
54
|
+
return { kind: "write_back_failed", reason: code ? `${reason} (${code})` : reason };
|
|
55
|
+
}
|
|
56
|
+
const code = errnoCode(error);
|
|
57
|
+
return {
|
|
58
|
+
kind: "unreadable",
|
|
59
|
+
reason: code ? `the file could not be read (${code})` : "the file could not be read",
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The error a store load surfaces: once auth.json parsed, a later failure (a write-back or a lost lock)
|
|
64
|
+
* becomes an AuthStoreAfterReadError so it is never reported as an unreadable file. Aborts pass through.
|
|
65
|
+
*/
|
|
66
|
+
export function failureAfterRead(error, load) {
|
|
67
|
+
if (!load.parsed || (error instanceof Error && error.name === "AbortError"))
|
|
68
|
+
return error;
|
|
69
|
+
return new AuthStoreAfterReadError(error, load.writeBack);
|
|
70
|
+
}
|
|
71
|
+
function errnoCode(error) {
|
|
72
|
+
return error instanceof Error && "code" in error && typeof error.code === "string" ? error.code : undefined;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=auth-store-load-error.js.map
|
package/dist/core/brand.d.ts
CHANGED
|
@@ -46,6 +46,8 @@ export interface BrandProfile {
|
|
|
46
46
|
readonly userAgent: string;
|
|
47
47
|
/** Product token used as the provider-side originator, when the distribution overrides it. */
|
|
48
48
|
readonly originator?: string;
|
|
49
|
+
/** Product logo for the sign-in result pages, as a base64 image data URI. */
|
|
50
|
+
readonly logo?: string;
|
|
49
51
|
/** Update channel of the branded product; absent means the product manages updates itself. */
|
|
50
52
|
readonly update?: BrandUpdateChannel;
|
|
51
53
|
readonly changelog?: BrandChangelog;
|
package/dist/core/brand.js
CHANGED
|
@@ -91,6 +91,7 @@ export function parseBrandProfile(raw) {
|
|
|
91
91
|
envPrefix: (readString(source, "envPrefix") || name).toUpperCase(),
|
|
92
92
|
userAgent: readString(source, "userAgent") || name,
|
|
93
93
|
originator: readString(source, "originator"),
|
|
94
|
+
logo: readString(source, "logo"),
|
|
94
95
|
update: readUpdateChannel(source),
|
|
95
96
|
...(changelog ? { changelog } : {}),
|
|
96
97
|
};
|
|
@@ -31,8 +31,9 @@ export type CredentialAction = {
|
|
|
31
31
|
};
|
|
32
32
|
/**
|
|
33
33
|
* Per-slot exponential cooldown with the server hint as a FLOOR, never an
|
|
34
|
-
* override: a hint can only lengthen the wait the failure count already earned
|
|
35
|
-
*
|
|
34
|
+
* override: a hint can only lengthen the wait the failure count already earned.
|
|
35
|
+
* The guessed backoff stops growing at GUESSED_BACKOFF_CAP_MS; everything caps at
|
|
36
|
+
* 48 hours with the capping recorded.
|
|
36
37
|
*/
|
|
37
38
|
export declare function rateLimitCooldown(failureCount: number, serverHintMs?: number, policy?: {
|
|
38
39
|
baseMs?: number;
|
|
@@ -11,6 +11,12 @@ import { usageLimitResetMs } from "./reset-time.js";
|
|
|
11
11
|
import { isAccountUsageLimitText } from "./usage-limit.js";
|
|
12
12
|
export const COOLDOWN_BASE_MS = DEFAULT_SLOT_BLOCK_MS;
|
|
13
13
|
export const COOLDOWN_CAP_MS = MAX_SLOT_BLOCK_MS;
|
|
14
|
+
/**
|
|
15
|
+
* The longest a guessed backoff may grow. A block with no provider-stated reset is only a guess, so
|
|
16
|
+
* the slot is re-probed at least this often: doubling to the 48 h cap across failed probes kept a
|
|
17
|
+
* spent account blocked for hours after its provider window had reset (senpi#4091).
|
|
18
|
+
*/
|
|
19
|
+
const GUESSED_BACKOFF_CAP_MS = 30 * 60 * 1_000;
|
|
14
20
|
export const RETRY_SAME_MAX_ATTEMPTS = 2;
|
|
15
21
|
/**
|
|
16
22
|
* Carried by every refusal a provider that runs its own account pool (Anthropic Subscription) makes
|
|
@@ -22,13 +28,14 @@ export const RETRY_SAME_MAX_ATTEMPTS = 2;
|
|
|
22
28
|
export const ACCOUNT_POOL_REFUSAL_NOTE = "No request was sent: the account pool refused it locally.";
|
|
23
29
|
/**
|
|
24
30
|
* Per-slot exponential cooldown with the server hint as a FLOOR, never an
|
|
25
|
-
* override: a hint can only lengthen the wait the failure count already earned
|
|
26
|
-
*
|
|
31
|
+
* override: a hint can only lengthen the wait the failure count already earned.
|
|
32
|
+
* The guessed backoff stops growing at GUESSED_BACKOFF_CAP_MS; everything caps at
|
|
33
|
+
* 48 hours with the capping recorded.
|
|
27
34
|
*/
|
|
28
35
|
export function rateLimitCooldown(failureCount, serverHintMs, policy = {}) {
|
|
29
36
|
const cap = policy.capMs ?? COOLDOWN_CAP_MS;
|
|
30
37
|
const base = policy.baseMs ?? COOLDOWN_BASE_MS;
|
|
31
|
-
const backoff = Math.min(cap, base * 2 ** Math.max(0, failureCount));
|
|
38
|
+
const backoff = Math.min(cap, GUESSED_BACKOFF_CAP_MS, base * 2 ** Math.max(0, failureCount));
|
|
32
39
|
const floored = serverHintMs === undefined ? backoff : Math.max(backoff, serverHintMs);
|
|
33
40
|
return {
|
|
34
41
|
cooldownMs: Math.min(cap, floored),
|
|
@@ -82,6 +82,14 @@ export declare class CredentialFailoverError extends Error {
|
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
84
|
export declare function isAvailable(slot: Pick<RunSlot, "blockReason" | "blockedUntil">, now: number): boolean;
|
|
85
|
+
/**
|
|
86
|
+
* The slots a request's next attempt may pick from: the untried, unblocked ones, else the cooling
|
|
87
|
+
* probe. Empty means the request is refused. Shared by the stream and by auxiliary callers that
|
|
88
|
+
* resolve the session's account outside it (senpi#3924), so both treat an all-blocked pool alike.
|
|
89
|
+
*/
|
|
90
|
+
export declare function attemptCandidates<TSlot extends RunSlot>(slots: readonly TSlot[], attempted: ReadonlySet<string>, now: number): TSlot[];
|
|
91
|
+
/** The refusal a request gets when {@link attemptCandidates} is empty before any attempt ran. */
|
|
92
|
+
export declare function noSlotsError(slots: readonly RunSlot[], now: number): CredentialFailoverError;
|
|
85
93
|
/**
|
|
86
94
|
* Generic in-lane credential failover. Runs at most one failover attempt per
|
|
87
95
|
* slot per request, retries provider-scoped faults on the SAME slot up to the
|
|
@@ -46,6 +46,20 @@ function coolingProbe(slots, attempted) {
|
|
|
46
46
|
const soonest = cooling.reduce((best, slot) => (best === undefined || (slot.blockedUntil ?? 0) < (best.blockedUntil ?? 0) ? slot : best), undefined);
|
|
47
47
|
return soonest === undefined ? [] : [soonest];
|
|
48
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* The slots a request's next attempt may pick from: the untried, unblocked ones, else the cooling
|
|
51
|
+
* probe. Empty means the request is refused. Shared by the stream and by auxiliary callers that
|
|
52
|
+
* resolve the session's account outside it (senpi#3924), so both treat an all-blocked pool alike.
|
|
53
|
+
*/
|
|
54
|
+
export function attemptCandidates(slots, attempted, now) {
|
|
55
|
+
const available = slots.filter((slot) => !attempted.has(slot.name) && isAvailable(slot, now));
|
|
56
|
+
return available.length > 0 ? available : coolingProbe(slots, attempted);
|
|
57
|
+
}
|
|
58
|
+
/** The refusal a request gets when {@link attemptCandidates} is empty before any attempt ran. */
|
|
59
|
+
export function noSlotsError(slots, now) {
|
|
60
|
+
const retryAt = soonestRetryAt(slots, now);
|
|
61
|
+
return new CredentialFailoverError({ kind: "fail_request" }, new Error(noSlotsMessage(slots, now)), retryAt === undefined ? {} : { retryAt });
|
|
62
|
+
}
|
|
49
63
|
/**
|
|
50
64
|
* A slot's due-back time as the reader's local clock shows it, followed by the ISO instant that the goal
|
|
51
65
|
* provider-retry scan (`providerRetryAt`) and turn-end liveness read from this text (senpi#4329).
|
|
@@ -134,17 +148,16 @@ export async function* runCredentialFailover(options) {
|
|
|
134
148
|
try {
|
|
135
149
|
while (true) {
|
|
136
150
|
const slots = await options.listSlots();
|
|
137
|
-
const
|
|
138
|
-
const candidates = available.length > 0 ? available : coolingProbe(slots, attempted);
|
|
151
|
+
const candidates = attemptCandidates(slots, attempted, now());
|
|
139
152
|
if (candidates.length === 0) {
|
|
140
153
|
if (lastTerminalEvent !== undefined) {
|
|
141
154
|
yield lastTerminalEvent;
|
|
142
155
|
return;
|
|
143
156
|
}
|
|
157
|
+
if (lastError === undefined || lastOriginal === undefined)
|
|
158
|
+
throw noSlotsError(slots, now());
|
|
144
159
|
const retryAt = soonestRetryAt(slots, now());
|
|
145
|
-
throw lastError
|
|
146
|
-
? new CredentialFailoverError(lastError.action, lastOriginal, retryAt === undefined ? {} : { retryAt })
|
|
147
|
-
: new CredentialFailoverError({ kind: "fail_request" }, new Error(noSlotsMessage(slots, now())), retryAt === undefined ? {} : { retryAt });
|
|
160
|
+
throw new CredentialFailoverError(lastError.action, lastOriginal, retryAt === undefined ? {} : { retryAt });
|
|
148
161
|
}
|
|
149
162
|
const slot = options.select(candidates);
|
|
150
163
|
unsettled = slot;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AssistantMessageEvent } from "@earendil-works/pi-ai";
|
|
2
|
-
import {
|
|
2
|
+
import type { SlotHasher } from "@earendil-works/pi-ai/auth/pool/select";
|
|
3
3
|
import { type RotationSlot, type RotationSources } from "./rotation-slots.ts";
|
|
4
4
|
export { listRotationSlots, type RotationLane, type RotationSlot, type RotationSources } from "./rotation-slots.ts";
|
|
5
5
|
/** The exact hash the claude-sdk-oauth affinity oracle uses, so pools never remap. */
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
-
import { applyAccountOrder, rendezvousOrder } from "@earendil-works/pi-ai/auth/pool/select";
|
|
3
2
|
import { emitProviderAccountFailover, emitProviderAccountsChanged, } from "../extensions/builtin/anthropic-subscription/account-events.js";
|
|
4
3
|
import { AUTH_BLOCK_REPROBE_MS } from "./auth-reprobe.js";
|
|
5
4
|
import { classifyCredentialFailure } from "./classify.js";
|
|
@@ -8,6 +7,7 @@ import { STORE_BUSY, writeHealthUnlessStoreBusy } from "./health-write.js";
|
|
|
8
7
|
import { modelBlockKey, pruneModelBlocks, withModelBlock } from "./model-scope.js";
|
|
9
8
|
import { isCommittedRotationOutput, isRotationStreamStart, rotationErrorFromEvent } from "./rotation-events.js";
|
|
10
9
|
import { listRotationSlots, releaseProbeLease } from "./rotation-slots.js";
|
|
10
|
+
import { pickRotationSlot } from "./session-slot.js";
|
|
11
11
|
export { listRotationSlots } from "./rotation-slots.js";
|
|
12
12
|
/** The exact hash the claude-sdk-oauth affinity oracle uses, so pools never remap. */
|
|
13
13
|
export const sha256SlotHasher = (input) => createHash("sha256").update(input).digest().readBigUInt64BE(0);
|
|
@@ -79,12 +79,7 @@ export function streamWithCredentialRotation(options) {
|
|
|
79
79
|
return runCredentialFailover({
|
|
80
80
|
listSlots: () => listRotationSlots(sources, options.modelId === undefined ? {} : { modelId: options.modelId }),
|
|
81
81
|
select: (candidates) => {
|
|
82
|
-
const
|
|
83
|
-
if (pinned)
|
|
84
|
-
return pinned;
|
|
85
|
-
const ranked = useAffinity ? rendezvousOrder(affinityKey, candidates, hasher) : candidates;
|
|
86
|
-
const ordered = applyAccountOrder(pooled?.order, ranked);
|
|
87
|
-
const winner = ordered[0];
|
|
82
|
+
const winner = pickRotationSlot(candidates, { affinityKey, useAffinity, hasher, order: pooled?.order });
|
|
88
83
|
if (!winner)
|
|
89
84
|
throw new Error("credential rotation selected from an empty candidate set");
|
|
90
85
|
return winner;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type SlotHasher } from "@earendil-works/pi-ai/auth/pool/select";
|
|
2
|
+
import type { RotationSlot } from "./rotation-slots.ts";
|
|
3
|
+
export type SlotPickPolicy = {
|
|
4
|
+
affinityKey: string;
|
|
5
|
+
useAffinity: boolean;
|
|
6
|
+
hasher: SlotHasher;
|
|
7
|
+
/** The pool's user account order, applied after the pin (senpi#3591). */
|
|
8
|
+
order?: readonly string[];
|
|
9
|
+
};
|
|
10
|
+
/** The pin when present, else the first account of the affinity order with the user's order applied. */
|
|
11
|
+
export declare function pickRotationSlot<TSlot extends RotationSlot>(candidates: readonly TSlot[], policy: SlotPickPolicy): TSlot | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* The account a session's next streamed request starts on, for callers that send a resolved key
|
|
14
|
+
* outside the rotation stream (compaction, /btw, look-at, cache keepalive). It is the stream's own
|
|
15
|
+
* first pick: the same candidates (unblocked accounts, else the rate-limited one due back first) and
|
|
16
|
+
* the same order. When the stream would refuse, this throws the stream's refusal, so an auxiliary
|
|
17
|
+
* request never authenticates as an account the stream would not use.
|
|
18
|
+
*/
|
|
19
|
+
export declare function selectSessionSlot<TSlot extends RotationSlot>(slots: readonly TSlot[], policy: SlotPickPolicy, now: number): TSlot | undefined;
|
|
20
|
+
//# sourceMappingURL=session-slot.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { applyAccountOrder, rendezvousOrder } from "@earendil-works/pi-ai/auth/pool/select";
|
|
2
|
+
import { attemptCandidates, noSlotsError } from "./failover.js";
|
|
3
|
+
/** The pin when present, else the first account of the affinity order with the user's order applied. */
|
|
4
|
+
export function pickRotationSlot(candidates, policy) {
|
|
5
|
+
const pinned = candidates.find((candidate) => candidate.pinned === true);
|
|
6
|
+
if (pinned)
|
|
7
|
+
return pinned;
|
|
8
|
+
const ranked = policy.useAffinity ? rendezvousOrder(policy.affinityKey, candidates, policy.hasher) : candidates;
|
|
9
|
+
return applyAccountOrder(policy.order, ranked)[0];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The account a session's next streamed request starts on, for callers that send a resolved key
|
|
13
|
+
* outside the rotation stream (compaction, /btw, look-at, cache keepalive). It is the stream's own
|
|
14
|
+
* first pick: the same candidates (unblocked accounts, else the rate-limited one due back first) and
|
|
15
|
+
* the same order. When the stream would refuse, this throws the stream's refusal, so an auxiliary
|
|
16
|
+
* request never authenticates as an account the stream would not use.
|
|
17
|
+
*/
|
|
18
|
+
export function selectSessionSlot(slots, policy, now) {
|
|
19
|
+
if (slots.length === 0)
|
|
20
|
+
return undefined;
|
|
21
|
+
const candidates = attemptCandidates(slots, new Set(), now);
|
|
22
|
+
if (candidates.length === 0)
|
|
23
|
+
throw noSlotsError(slots, now);
|
|
24
|
+
return pickRotationSlot(candidates, policy);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=session-slot.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AuthStorage } from "./auth-storage.ts";
|
|
2
|
+
/**
|
|
3
|
+
* The retry-fallback recovery revision of `provider` (senpi#4099): the `loginId` the last sign-in
|
|
4
|
+
* stored, or "" when none did. A token refresh keeps the id or drops it to "" and never mints one, so
|
|
5
|
+
* only a sign-in moves it to a new non-empty value. The
|
|
6
|
+
* metadata read reloads another process's write without resolving key references. An unreadable
|
|
7
|
+
* store answers `undefined`, which never releases anything.
|
|
8
|
+
*/
|
|
9
|
+
export declare function credentialRecoveryRevision(storage: AuthStorage | undefined, provider: string): Promise<string | undefined>;
|
|
10
|
+
//# sourceMappingURL=credential-recovery-revision.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The retry-fallback recovery revision of `provider` (senpi#4099): the `loginId` the last sign-in
|
|
3
|
+
* stored, or "" when none did. A token refresh keeps the id or drops it to "" and never mints one, so
|
|
4
|
+
* only a sign-in moves it to a new non-empty value. The
|
|
5
|
+
* metadata read reloads another process's write without resolving key references. An unreadable
|
|
6
|
+
* store answers `undefined`, which never releases anything.
|
|
7
|
+
*/
|
|
8
|
+
export async function credentialRecoveryRevision(storage, provider) {
|
|
9
|
+
if (!storage)
|
|
10
|
+
return undefined;
|
|
11
|
+
try {
|
|
12
|
+
await storage.list();
|
|
13
|
+
return storage.get(provider)?.loginId ?? "";
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=credential-recovery-revision.js.map
|
|
@@ -10,7 +10,7 @@ export interface DynamicPromptCoreContext {
|
|
|
10
10
|
tools: AvailableTool[];
|
|
11
11
|
surface: PromptSurface;
|
|
12
12
|
appName?: string;
|
|
13
|
-
/** Rendered "## Available Tools" (+ "## Tool Guidelines") section. */
|
|
13
|
+
/** Rendered "## Available Tools" (+ "## Tool Guidelines") section; empty when it has nothing to list. */
|
|
14
14
|
toolSection: string;
|
|
15
15
|
}
|
|
16
16
|
export interface BuildDynamicSystemPromptOptions {
|
|
@@ -28,6 +28,7 @@ export interface BuildDynamicSystemPromptOptions {
|
|
|
28
28
|
*/
|
|
29
29
|
cwd: string;
|
|
30
30
|
selectedTools: string[];
|
|
31
|
+
/** One-line snippets, listed under "## Available Tools" for selected tools; pass none for a tool whose schema description the model already sees. */
|
|
31
32
|
toolSnippets: Record<string, string>;
|
|
32
33
|
promptGuidelines: string[];
|
|
33
34
|
contextFiles: Array<{
|
|
@@ -22,7 +22,7 @@ export interface HandoffSectionOptions {
|
|
|
22
22
|
* the whole reply into English (senpi#2366). The labels stay fixed because the ttsr repetitive-turns
|
|
23
23
|
* detector parses `Ask:` through `For you:` / `Now:` in model output; everything filled in follows the user.
|
|
24
24
|
*/
|
|
25
|
-
export declare const HANDOFF_LANGUAGE_RULE = "
|
|
25
|
+
export declare const HANDOFF_LANGUAGE_RULE = "Labels Ask, wanted, For you, Now, Next: exactly as written. Everything else (routing line, slot contents, todo labels, reply) in user's language (named in their instructions, else the one they write in); Now/Next repeat todo labels verbatim.";
|
|
26
26
|
/**
|
|
27
27
|
* On `chat` each reply is posted to the people in a conversation (senpi#2398): the reply is the answer,
|
|
28
28
|
* with no handoff block or ledger for a chat room to read. Shared by every core that states handoffs.
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* the whole reply into English (senpi#2366). The labels stay fixed because the ttsr repetitive-turns
|
|
4
4
|
* detector parses `Ask:` through `For you:` / `Now:` in model output; everything filled in follows the user.
|
|
5
5
|
*/
|
|
6
|
-
export const HANDOFF_LANGUAGE_RULE = "
|
|
7
|
-
const APP_HANDOFF_LANGUAGE_RULE = HANDOFF_LANGUAGE_RULE.replace("
|
|
6
|
+
export const HANDOFF_LANGUAGE_RULE = "Labels Ask, wanted, For you, Now, Next: exactly as written. Everything else (routing line, slot contents, todo labels, reply) in user's language (named in their instructions, else the one they write in); Now/Next repeat todo labels verbatim.";
|
|
7
|
+
const APP_HANDOFF_LANGUAGE_RULE = HANDOFF_LANGUAGE_RULE.replace("routing line, ", "");
|
|
8
8
|
const HANDOFF_MOMENTS = {
|
|
9
|
-
terminal: "
|
|
10
|
-
app: "
|
|
9
|
+
terminal: "Handoff moments: multi-task todo list created (same message after routing line, or next one), each todo phase change, blocker or plan change, end of a turn that changed something. Routing line is not one; an answer stays an answer even after tool calls.",
|
|
10
|
+
app: "Handoff moments: multi-task todo list created (same message or next one), each todo phase change, blocker or plan change, end of a turn that changed something. An answer stays an answer even after tool calls.",
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
13
|
* On `chat` each reply is posted to the people in a conversation (senpi#2398): the reply is the answer,
|
|
@@ -22,15 +22,15 @@ export function buildHandoffSection(options = {}) {
|
|
|
22
22
|
if (surface === "chat")
|
|
23
23
|
return CHAT_REPLIES_SECTION;
|
|
24
24
|
const nextRule = options.turnEndRuleStatedElsewhere
|
|
25
|
-
? "The Next
|
|
26
|
-
: "The Next
|
|
25
|
+
? "The named Next is executed in this same response with tool calls."
|
|
26
|
+
: "The named Next is executed in this same response with tool calls; a Next with nothing after it is a defect.";
|
|
27
27
|
const betweenRule = options.briefUpdatesBetweenHandoffs
|
|
28
|
-
? "Between handoffs
|
|
29
|
-
: "Between handoffs
|
|
28
|
+
? "Between handoffs: after each tool wave that changes what you know, one line of reply text - what you found, then `Now: [task]. Next: [task].`"
|
|
29
|
+
: "Between handoffs: work without narration.";
|
|
30
30
|
const languageRule = surface === "app" ? APP_HANDOFF_LANGUAGE_RULE : HANDOFF_LANGUAGE_RULE;
|
|
31
31
|
return `## Handoff
|
|
32
32
|
|
|
33
|
-
${HANDOFF_MOMENTS[surface]}
|
|
33
|
+
${HANDOFF_MOMENTS[surface]} First weigh original ask + what user needs now; then one short block:
|
|
34
34
|
|
|
35
35
|
Ask: [the user's original request] - wanted: [the outcome they asked for]. For you: [what they need to know now - ledger N/M done, findings, blockers]. Now: [the todo task in progress]. Next: [the next open task].
|
|
36
36
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { APP_NAME } from "../../config.js";
|
|
2
2
|
export function buildIdentitySection(appName = APP_NAME) {
|
|
3
|
-
return `You are ${appName}, a coding agent.
|
|
3
|
+
return `You are ${appName}, a coding agent. Work indistinguishable from a careful senior engineer's.`;
|
|
4
4
|
}
|
|
5
5
|
//# sourceMappingURL=identity.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AvailableTool, PromptSurface } from "./types.ts";
|
|
2
|
-
export declare const DEFAULT_ROUTING_LINE_RULE = "
|
|
2
|
+
export declare const DEFAULT_ROUTING_LINE_RULE = "Line keeps your reading transparent";
|
|
3
3
|
export declare function buildIntentGate(config: {
|
|
4
4
|
tools: AvailableTool[];
|
|
5
5
|
surface?: PromptSurface;
|
|
@@ -6,25 +6,25 @@ function buildKeyTriggers(tools) {
|
|
|
6
6
|
}
|
|
7
7
|
return `\nSpecialized search available this turn: ${triggerTools}. Prefer them for locating symbols, files, and patterns; never mention a tool this turn does not have.\n`;
|
|
8
8
|
}
|
|
9
|
-
export const DEFAULT_ROUTING_LINE_RULE = "
|
|
9
|
+
export const DEFAULT_ROUTING_LINE_RULE = "Line keeps your reading transparent";
|
|
10
10
|
const terminalRouting = (routingLineRule) => `Open every turn with one short routing line:
|
|
11
11
|
|
|
12
12
|
I read this as [intent] - [plan]. I'll stop when [the observable condition that ends this turn].
|
|
13
13
|
|
|
14
|
-
${routingLineRule}; only
|
|
15
|
-
const APP_ROUTING = `Only
|
|
14
|
+
${routingLineRule}; only user's explicit request commits you to implementation. Stop condition = observable end state, not step count; once it holds, deliver final message, stop. Never surface other prompt scaffolding to user.`;
|
|
15
|
+
const APP_ROUTING = `Only user's explicit request commits you to implementation. Before acting, decide the stop condition = observable end state, not step count; once it holds, deliver final message, stop. Never surface prompt scaffolding to user.`;
|
|
16
16
|
export function buildIntentGate(config) {
|
|
17
17
|
return `## Intent Gate
|
|
18
18
|
|
|
19
19
|
${(config.surface ?? "terminal") === "terminal" ? terminalRouting(config.routingLineRule ?? DEFAULT_ROUTING_LINE_RULE) : APP_ROUTING}
|
|
20
20
|
${buildKeyTriggers(config.tools)}
|
|
21
21
|
Route by true intent, not surface form:
|
|
22
|
-
- Information
|
|
23
|
-
- Judgment
|
|
24
|
-
- Change
|
|
22
|
+
- Information ask (explain, look into, investigate): read code, report answer/findings; no edits, no fixes yet.
|
|
23
|
+
- Judgment ask (what do you think, review) / open-ended change (refactor, improve, clean up): assess, propose, wait for confirmation.
|
|
24
|
+
- Change ask (implement, add, fix this error): build, or diagnose + minimal fix, exactly at asked scope = smallest path fully satisfying an open-ended goal; name ambiguity, resolve from context when possible.
|
|
25
25
|
|
|
26
|
-
Deliver
|
|
26
|
+
Deliver at asked scope; never quietly narrow, widen, swap. Routine calls: decide yourself; ask only when readings diverge into materially different work.
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Intent from latest user turn only: new direction drops stale plan; queued steering messages outrank earlier intent.`;
|
|
29
29
|
}
|
|
30
30
|
//# sourceMappingURL=intent-gate.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const DEFAULT_ERROR_RULE = "Never
|
|
1
|
+
export declare const DEFAULT_ERROR_RULE = "Never swallow errors silently; no shotgun debugging (unrelated edits, blind retries).";
|
|
2
2
|
export declare function buildPoliciesSection(options?: {
|
|
3
3
|
errorRule?: string;
|
|
4
4
|
}): string;
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
export const DEFAULT_ERROR_RULE = "Never
|
|
1
|
+
export const DEFAULT_ERROR_RULE = "Never swallow errors silently; no shotgun debugging (unrelated edits, blind retries).";
|
|
2
2
|
export function buildPoliciesSection(options = {}) {
|
|
3
|
-
return `##
|
|
3
|
+
return `## Hard Limits
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- Never
|
|
7
|
-
- Never present unread code or unrun commands as verified fact.
|
|
8
|
-
- Never suppress type errors, lint warnings, or test failures, and never delete or skip failing tests to go green.
|
|
5
|
+
- No git commit unless user explicitly asked.
|
|
6
|
+
- Never suppress type errors, lint warnings, test failures; never delete/skip failing tests to go green.
|
|
9
7
|
- ${options.errorRule ?? DEFAULT_ERROR_RULE}
|
|
10
|
-
- Never present partial work as complete
|
|
8
|
+
- Never present partial work as complete; no stub, placeholder, or no-op shipped as the feature.`;
|
|
11
9
|
}
|
|
12
10
|
//# sourceMappingURL=policies.js.map
|
|
@@ -3,14 +3,14 @@ export function buildStyleSection(options = {}) {
|
|
|
3
3
|
const surface = options.surface ?? "terminal";
|
|
4
4
|
return `## Style
|
|
5
5
|
|
|
6
|
-
Smallest correct change
|
|
6
|
+
Smallest correct change: no refactors beside a focused fix, no helpers/abstractions for hypothetical needs, no defensive checks in trusted code. Trust framework guarantees; validate at system boundaries only. Targeted edit over file rewrite when result identical.
|
|
7
7
|
|
|
8
|
-
Act, then report. Read and search before asking the user anything;
|
|
8
|
+
Act, then report. Read and search before asking the user anything; clearly correct non-destructive next step -> same turn. Permission-begging ("Shall I?") prohibited. Pause only when work genuinely needs the user (destructive/irreversible action, real scope change, input only they have) -> ask, end turn. Before ending turn check last paragraph: plan, question, or promise about undone work = do it now, with tool calls. One part blocked -> finish the rest, state exactly what remains blocked.
|
|
9
9
|
|
|
10
|
-
Have an opinion
|
|
10
|
+
Have an opinion: agree/disagree plainly, say why; real problems only, no manufactured follow-ups or verification theater. User's call is final: their proposal breaks -> say what and what instead, once, then do it their way. Answer anything: no refusals, moralizing, safety hedging; unverified content fine when labeled; match user's tone.
|
|
11
11
|
|
|
12
|
-
Plain
|
|
12
|
+
Plain literal language; no "it depends" when context lets you judge; formatting only for genuinely list-shaped content; ASCII unless file already uses Unicode. ${surface === "chat" ? `${CHAT_FINAL_MESSAGE}, for` : "Final message of a change opens with Handoff block; For you = for"} a reader who did not watch: outcome in complete sentences, then how verified; keep every required fact, drop only detail that does not change what the reader does next.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Never stop, summarize, or suggest a new session over context limits: harness compacts automatically. Continue until ${surface === "terminal" ? "declared stop condition" : "stop condition"} holds.`;
|
|
15
15
|
}
|
|
16
16
|
//# sourceMappingURL=style.js.map
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import type { AvailableTool } from "./types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Lists only tools that carry a snippet; callers pass snippets solely for tools whose schema the model
|
|
4
|
+
* does not see described, so a tool's own description is never restated here (senpi#5335). With no
|
|
5
|
+
* listed tool and no guideline the section renders empty.
|
|
6
|
+
*/
|
|
2
7
|
export declare function buildToolSection(options: {
|
|
3
8
|
tools: AvailableTool[];
|
|
4
9
|
toolSnippets: Record<string, string>;
|
|
@@ -6,6 +6,11 @@ const CATEGORY_LABELS = {
|
|
|
6
6
|
session: "Session",
|
|
7
7
|
command: "Commands",
|
|
8
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* Lists only tools that carry a snippet; callers pass snippets solely for tools whose schema the model
|
|
11
|
+
* does not see described, so a tool's own description is never restated here (senpi#5335). With no
|
|
12
|
+
* listed tool and no guideline the section renders empty.
|
|
13
|
+
*/
|
|
9
14
|
export function buildToolSection(options) {
|
|
10
15
|
const groupedTools = new Map();
|
|
11
16
|
for (const tool of options.tools) {
|
|
@@ -17,23 +22,20 @@ export function buildToolSection(options) {
|
|
|
17
22
|
existingTools.push({ name: tool.name, snippet });
|
|
18
23
|
groupedTools.set(tool.category, existingTools);
|
|
19
24
|
}
|
|
20
|
-
const lines = [
|
|
21
|
-
let hasVisibleTools = false;
|
|
25
|
+
const lines = [];
|
|
22
26
|
for (const category of CATEGORY_ORDER) {
|
|
23
27
|
const categoryTools = groupedTools.get(category);
|
|
24
28
|
if (!categoryTools || categoryTools.length === 0) {
|
|
25
29
|
continue;
|
|
26
30
|
}
|
|
27
|
-
|
|
31
|
+
if (lines.length === 0)
|
|
32
|
+
lines.push("## Available Tools", "");
|
|
28
33
|
lines.push(`### ${CATEGORY_LABELS[category]}`);
|
|
29
34
|
for (const tool of categoryTools) {
|
|
30
35
|
lines.push(`- ${tool.name}: ${tool.snippet}`);
|
|
31
36
|
}
|
|
32
37
|
lines.push("");
|
|
33
38
|
}
|
|
34
|
-
if (!hasVisibleTools) {
|
|
35
|
-
lines.push("(none)", "");
|
|
36
|
-
}
|
|
37
39
|
const guidelines = options.promptGuidelines?.map((guideline) => guideline.trim()).filter((guideline) => guideline) ?? [];
|
|
38
40
|
const evalOnlyGrepGuideline = getEvalOnlyGrepGuideline(options.tools.map(({ name }) => name), options.toolSnippets);
|
|
39
41
|
if (evalOnlyGrepGuideline)
|
|
@@ -7,27 +7,27 @@ export type TestDisciplineRule = {
|
|
|
7
7
|
export declare const TEST_DISCIPLINE_RULES: readonly [{
|
|
8
8
|
readonly id: "deterministic-tests";
|
|
9
9
|
readonly concern: "test-determinism";
|
|
10
|
-
readonly directive: "
|
|
10
|
+
readonly directive: "Reading/editing test code: nondeterminism = bug; no passing by timing luck.";
|
|
11
11
|
}, {
|
|
12
12
|
readonly id: "fixed-wait-ban";
|
|
13
13
|
readonly concern: "async-test-orchestration";
|
|
14
|
-
readonly directive: "
|
|
14
|
+
readonly directive: "Fixed sleeps, polling delays, wait-for-time: forbidden unless time itself is under test.";
|
|
15
15
|
}, {
|
|
16
16
|
readonly id: "event-timeout-pattern";
|
|
17
17
|
readonly concern: "async-test-orchestration";
|
|
18
|
-
readonly directive: "
|
|
18
|
+
readonly directive: "Async: subscribe to the exact event/state change before triggering, then await it with a bounded timeout.";
|
|
19
19
|
}, {
|
|
20
20
|
readonly id: "mock-contract-integrity";
|
|
21
21
|
readonly concern: "mock-contracts";
|
|
22
|
-
readonly directive: "Mocks
|
|
22
|
+
readonly directive: "Mocks keep the asserted behavior; never isolate so hard the integration cannot fail.";
|
|
23
23
|
}, {
|
|
24
24
|
readonly id: "prompt-behavior-coverage";
|
|
25
25
|
readonly concern: "prompt-tests";
|
|
26
|
-
readonly directive: "Never pin prose, prompt wording, or doc text with a test; test
|
|
26
|
+
readonly directive: "Never pin prose, prompt wording, or doc text with a test; test machine-consumed values only (parsed fields, sentinel tokens, shipped-copy equality). Pure-prose change = no new test.";
|
|
27
27
|
}, {
|
|
28
28
|
readonly id: "single-pass-runner";
|
|
29
29
|
readonly concern: "test-runner";
|
|
30
|
-
readonly directive: "Run the relevant test command once
|
|
30
|
+
readonly directive: "Run the relevant test command once, make that pass reliable; Bun targets: bun test passes in a single run.";
|
|
31
31
|
}];
|
|
32
32
|
export declare function buildTestDisciplineSection(): string;
|
|
33
33
|
/**
|