mixdog 1.2.0 → 1.2.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/README.md +7 -5
- package/package.json +1 -1
- package/scripts/gate-local.mjs +19 -3
- package/scripts/model-catalog-audit.mjs +1 -15
- package/src/agents/reviewer/AGENT.md +3 -3
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +5 -0
- package/src/defaults/skills/pptx/SKILL.md +6 -6
- package/src/defaults/skills/pptx/references/review.md +6 -4
- package/src/defaults/skills/pptx/scripts/source-extract.mjs +1 -1
- package/src/defaults/skills/setup/references/actions.md +13 -3
- package/src/defaults/skills/visualize/SKILL.md +12 -9
- package/src/repl/slash-commands.mjs +16 -1
- package/src/rules/shared/60-verification.md +3 -1
- package/src/rules/shared/70-delivery.md +4 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -4
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +10 -0
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +26 -5
- package/src/runtime/agent/orchestrator/config.mjs +10 -4
- package/src/runtime/agent/orchestrator/context/collect.mjs +2 -1
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +11 -5
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +74 -21
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +122 -15
- package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +54 -11
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +104 -9
- package/src/runtime/agent/orchestrator/mcp/client.mjs +358 -140
- package/src/runtime/agent/orchestrator/mcp/lazy-output-validator.mjs +25 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +103 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +150 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +111 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +87 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +95 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-request.mjs +122 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +9 -0
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +229 -0
- package/src/runtime/agent/orchestrator/mcp/plugin-placeholders.mjs +54 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +294 -44
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +94 -31
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +96 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.mjs +39 -18
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +55 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +25 -21
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-midstream-recovery.mjs +18 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +13 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-midstream.mjs +10 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-recovery.mjs +23 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +46 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request.mjs +14 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +73 -35
- package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +69 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +8 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +53 -18
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +30 -9
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +30 -14
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +93 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +82 -9
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +337 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-tokens.mjs +159 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +447 -0
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +38 -5
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire-guards.mjs +97 -2
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +102 -23
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +103 -33
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +29 -6
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +18 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -4
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +86 -19
- package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +29 -8
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +191 -0
- package/src/runtime/agent/orchestrator/providers/gemini-family.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/gemini-history-signatures.mjs +9 -4
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +180 -0
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +21 -82
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +71 -12
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +21 -20
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +97 -51
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +68 -19
- package/src/runtime/agent/orchestrator/providers/lib/gemini-model-catalog.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-bridge.mjs +1080 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +15 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +35 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +4 -9
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +12 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +6 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +5 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +22 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +50 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +23 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +16 -8
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-state.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +94 -13
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +193 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +66 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +6 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +6 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +23 -14
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +26 -6
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +42 -25
- package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +274 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +72 -32
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +18 -11
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-stamps.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +2 -3
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +1 -3
- package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +34 -3
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +22 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +5 -9
- package/src/runtime/agent/orchestrator/providers/openai-retry-policy.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-handshake.mjs +16 -8
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/policy.mjs +25 -14
- package/src/runtime/agent/orchestrator/providers/openai-ws-terminal.mjs +18 -11
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +35 -24
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +581 -0
- package/src/runtime/agent/orchestrator/providers/registry.mjs +35 -9
- package/src/runtime/agent/orchestrator/providers/retry-backoff.mjs +46 -7
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +118 -219
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +148 -45
- package/src/runtime/agent/orchestrator/providers/retry-midstream.mjs +81 -16
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +15 -55
- package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +15 -2
- package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +0 -18
- package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +57 -28
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +19 -16
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +268 -181
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +21 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +54 -3
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +284 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +270 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/sqlite-gate.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +628 -0
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +184 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +136 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +128 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +127 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +101 -0
- package/src/runtime/agent/orchestrator/session/explicit-skills.mjs +83 -5
- package/src/runtime/agent/orchestrator/session/imported-message.mjs +11 -0
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -4
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +102 -18
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +42 -5
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +14 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +20 -12
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +50 -23
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +22 -14
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +18 -7
- package/src/runtime/agent/orchestrator/session/manager.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +155 -29
- package/src/runtime/agent/orchestrator/session/store/listing.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/store/write-guards.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +22 -10
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +819 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +22 -12
- package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +158 -0
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +183 -374
- package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +41 -3
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +38 -17
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +12 -15
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +17 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -0
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +173 -22
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-guards.mjs +8 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +5 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +15 -2
- package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +13 -10
- package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +17 -12
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/apply-patch/codex-batch.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/patch/apply-patch/route.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/read-redirects.mjs +34 -30
- package/src/runtime/agent/orchestrator/tools/patch/sequence/units.mjs +7 -7
- package/src/runtime/agent/orchestrator/tools/patch/sequence.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -0
- package/src/runtime/attachments/store.d.mts +3 -0
- package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +1 -1
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +16 -4
- package/src/runtime/channels/lib/worker-main.mjs +17 -14
- package/src/runtime/computer-bridge/linux-readiness.mjs +0 -2
- package/src/runtime/effort-judge/judge-client.mjs +56 -18
- package/src/runtime/memory/lib/memory.mjs +1 -1
- package/src/runtime/memory/lib/pg/process.mjs +34 -24
- package/src/runtime/memory/lib/pg/supervisor.mjs +16 -13
- package/src/runtime/memory/lib/session-ingest.mjs +2 -2
- package/src/runtime/office/README.md +1 -1
- package/src/runtime/office/shared/values.mjs +0 -5
- package/src/runtime/shared/atomic-file.mjs +25 -4
- package/src/runtime/shared/background-tasks.mjs +92 -14
- package/src/runtime/shared/err-text.mjs +25 -0
- package/src/runtime/shared/error-presentation.mjs +159 -19
- package/src/runtime/shared/extension-scopes.mjs +5 -3
- package/src/runtime/shared/file-lock.mjs +37 -11
- package/src/runtime/shared/llm/anthropic-betas.mjs +4 -3
- package/src/runtime/shared/llm/anthropic-effort.mjs +134 -131
- package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +50 -14
- package/src/runtime/shared/llm/model-catalog.mjs +53 -52
- package/src/runtime/shared/llm/openai-daybreak.mjs +4 -16
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +17 -0
- package/src/runtime/shared/llm/provider-model-identities.mjs +13 -4
- package/src/runtime/shared/llm/usage-rollup.mjs +0 -1
- package/src/runtime/shared/model-display.mjs +13 -0
- package/src/runtime/shared/plugin-manifest.mjs +18 -9
- package/src/runtime/shared/pristine-execution-contract.json +9 -2
- package/src/runtime/shared/pristine-execution.mjs +28 -4
- package/src/runtime/shared/provider-accounts.mjs +124 -20
- package/src/runtime/shared/provider-api-key.mjs +12 -0
- package/src/runtime/shared/quota-resume-store.mjs +11 -0
- package/src/runtime/shared/session-baseline-store.mjs +960 -0
- package/src/runtime/shared/shell-display.mjs +9 -3
- package/src/runtime/shared/skill-mentions.d.mts +10 -0
- package/src/runtime/shared/skill-mentions.mjs +133 -0
- package/src/runtime/shared/skill-script-runtime.mjs +264 -0
- package/src/runtime/shared/statusline/statusline-format.mjs +4 -4
- package/src/runtime/shared/task-notification-envelope.mjs +2 -2
- package/src/runtime/shared/tool-primitives.mjs +35 -2
- package/src/runtime/shared/turn-changes.mjs +447 -219
- package/src/runtime/shared/turn-snapshot-store.mjs +182 -1
- package/src/runtime/shared/turn-snapshot.mjs +170 -48
- package/src/runtime/shared/turn-worktree-snapshot.mjs +160 -51
- package/src/runtime/shared/worker-requests.mjs +15 -2
- package/src/runtime/shared/worktrees/contract.mjs +0 -24
- package/src/runtime/shared/worktrees/test-support.mjs +19 -4
- package/src/session-runtime/automation-agents.mjs +8 -2
- package/src/session-runtime/boot/apis.mjs +61 -0
- package/src/session-runtime/boot/config.mjs +5 -2
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/infrastructure.mjs +35 -18
- package/src/session-runtime/conversation-import/discovery.mjs +698 -0
- package/src/session-runtime/conversation-import/service.mjs +369 -0
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +10 -5
- package/src/session-runtime/cwd-plugins/plugin-status.mjs +47 -42
- package/src/session-runtime/lifecycle/session-catalog.mjs +2 -0
- package/src/session-runtime/lifecycle/teardown.mjs +1 -1
- package/src/session-runtime/mcp-glue/connect.mjs +83 -16
- package/src/session-runtime/mcp-glue/plugin-servers.mjs +499 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +135 -33
- package/src/session-runtime/mcp-glue.mjs +25 -2
- package/src/session-runtime/mcp-oauth-login.mjs +174 -0
- package/src/session-runtime/model-route/model-switch-target.mjs +34 -0
- package/src/session-runtime/model-route/set-route.mjs +83 -15
- package/src/session-runtime/model-route/web-search-route.mjs +1 -1
- package/src/session-runtime/native-web-search/routes.mjs +22 -3
- package/src/session-runtime/new-session-config.mjs +3 -2
- package/src/session-runtime/notification-bus.mjs +9 -2
- package/src/session-runtime/provider-auth/accounts.mjs +33 -15
- package/src/session-runtime/provider-models/model-meta.mjs +12 -3
- package/src/session-runtime/provider-models/web-search-catalog.mjs +5 -1
- package/src/session-runtime/provider-readiness.mjs +16 -10
- package/src/session-runtime/quick-model-rows/web-search-rows.mjs +13 -8
- package/src/session-runtime/quick-web-search-models.mjs +13 -38
- package/src/session-runtime/resource-extension-sync.mjs +24 -5
- package/src/session-runtime/resource-mcp-api.mjs +198 -78
- package/src/session-runtime/resource-plugins-api.mjs +29 -41
- package/src/session-runtime/resource-scope-decorate.mjs +6 -8
- package/src/session-runtime/resource-skills-api.mjs +23 -2
- package/src/session-runtime/runtime-review-api.mjs +13 -0
- package/src/session-runtime/schedule-session-run.mjs +1 -1
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +13 -1
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +7 -2
- package/src/session-runtime/services/agent-tool/send-flow.mjs +22 -4
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +2 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +22 -5
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +8 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -2
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +17 -0
- package/src/session-runtime/services/channel-session-router.mjs +4 -1
- package/src/session-runtime/services/hook-bus/command-handler.mjs +4 -1
- package/src/session-runtime/services/hook-bus/handlers.mjs +7 -3
- package/src/session-runtime/services/provider-admin.mjs +64 -18
- package/src/session-runtime/services/usage-dashboard-model.mjs +3 -0
- package/src/session-runtime/settings-compaction-api.mjs +1 -0
- package/src/session-runtime/setup-tool/executor.mjs +12 -1
- package/src/session-runtime/setup-tool/extended-actions.mjs +1 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +1 -0
- package/src/session-runtime/setup-tool/tool-defs.mjs +7 -1
- package/src/session-runtime/skills-api.mjs +7 -3
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/webhook-session-run.mjs +16 -4
- package/src/skill-script-entry.mjs +36 -0
- package/src/standalone/daemon-drain-policy.mjs +8 -0
- package/src/standalone/daemon-stored-session-views.mjs +11 -3
- package/src/standalone/daemon-telemetry.mjs +55 -0
- package/src/standalone/daemon.mjs +44 -11
- package/src/standalone/session-protocol.mjs +12 -0
- package/src/standalone/session-service/agent-tree/agent-cancel.mjs +33 -2
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +26 -10
- package/src/standalone/session-service/agent-tree.mjs +12 -0
- package/src/standalone/session-service/quota-resume.mjs +8 -0
- package/src/standalone/session-service/retention/busy.mjs +15 -1
- package/src/standalone/session-service/session-calls/session-action.mjs +6 -1
- package/src/standalone/session-service-api.mjs +5 -0
- package/src/standalone/session-service.mjs +1 -0
- package/src/tui/App.jsx +9 -1
- package/src/tui/app/app-view/floating-panel.jsx +9 -1
- package/src/tui/app/app-view.jsx +7 -0
- package/src/tui/app/create-app-pickers.mjs +4 -0
- package/src/tui/app/extension-pickers/mcp-login.mjs +107 -0
- package/src/tui/app/extension-pickers/mcp-servers-picker.mjs +2 -1
- package/src/tui/app/extension-pickers/plugins-pickers.mjs +35 -16
- package/src/tui/app/extension-pickers.mjs +2 -1
- package/src/tui/app/model-options.mjs +13 -16
- package/src/tui/app/skill-mention-palette.mjs +88 -0
- package/src/tui/app/slash-commands.mjs +7 -2
- package/src/tui/app/slash-dispatch/panel-commands.mjs +16 -1
- package/src/tui/app/slash-palette.mjs +23 -7
- package/src/tui/app/transcript-row-estimate.mjs +11 -3
- package/src/tui/app/use-prompt-draft-flow.mjs +7 -2
- package/src/tui/app/use-prompt-state.mjs +5 -0
- package/src/tui/components/Message.jsx +22 -1
- package/src/tui/components/PromptInput.jsx +21 -3
- package/src/tui/components/SlashCommandPalette.jsx +12 -3
- package/src/tui/components/StatusLine.jsx +2 -0
- package/src/tui/components/TranscriptItem.jsx +9 -1
- package/src/tui/components/prompt-input/key-handler.mjs +21 -8
- package/src/tui/components/status-line/local-line.mjs +5 -2
- package/src/tui/components/status-line/use-statusline-text.mjs +7 -1
- package/src/tui/components/user-message-skills.mjs +38 -0
- package/src/tui/dist/index.mjs +1323 -214
- package/src/tui/session/queue-helpers.mjs +7 -2
- package/src/tui/session/quota-resume.mjs +46 -14
- package/src/tui/session/session-api/commands.mjs +33 -24
- package/src/tui/session/session-api/extensions.mjs +26 -2
- package/src/tui/session/session-api/integrations.mjs +7 -0
- package/src/tui/session/session-api/lifecycle.mjs +5 -1
- package/src/tui/session/session-api/routes.mjs +71 -7
- package/src/tui/session/session-api/settings.mjs +12 -14
- package/src/tui/session/session-flow/drain.mjs +21 -5
- package/src/tui/session/session-flow/failed-turn-rewind.mjs +10 -4
- package/src/tui/session/tui-steering-persist.mjs +25 -9
- package/src/tui/session/turn.mjs +55 -15
- package/src/tui/statusline-ansi-bridge.mjs +1 -1
- package/src/ui/statusline-agents.mjs +15 -4
- package/src/ui/statusline.mjs +7 -3
- package/src/ui/streaming-markdown-heal.mjs +34 -3
- package/src/vendor/statusline/src/gateway/claude-current.mjs +14 -4
- package/src/runtime/effort-judge/previous-human-request.mjs +0 -162
- package/src/runtime/effort-judge/verified-context-input.mjs +0 -10
- package/src/runtime/memory/lib/memory-session-merge.mjs +0 -32
- package/src/runtime/shared/llm/usage-session-history.mjs +0 -266
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
// Structural error classification: typed status, transience, auth, context
|
|
2
2
|
// overflow, retry-after and stream-close verdicts shared by every provider.
|
|
3
3
|
import { readStreamOutcome } from './lib/stream-outcome.mjs';
|
|
4
|
+
import {
|
|
5
|
+
BARE_FETCH_TRANSPORT_MESSAGE_RE,
|
|
6
|
+
DETERMINISTIC_KINDS,
|
|
7
|
+
QUOTA_KINDS,
|
|
8
|
+
REQUEST_SIZE_PATTERNS,
|
|
9
|
+
TLS_RECORD_FAILURE_RE,
|
|
10
|
+
TOKEN_CONTEXT_OVERFLOW_PATTERNS,
|
|
11
|
+
TRANSIENT_SDK_NAMES,
|
|
12
|
+
boundedCauseChain,
|
|
13
|
+
isTransientErrorCode,
|
|
14
|
+
providerErrorKind,
|
|
15
|
+
typedCodeKind,
|
|
16
|
+
typedErrorCode,
|
|
17
|
+
} from './provider-error-kind.mjs';
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
boundedCauseChain,
|
|
21
|
+
errorHeaderValue,
|
|
22
|
+
headerValue,
|
|
23
|
+
isTransientErrorCode,
|
|
24
|
+
providerErrorKind,
|
|
25
|
+
retryAfterMsFromError,
|
|
26
|
+
typedErrorCode,
|
|
27
|
+
} from './provider-error-kind.mjs';
|
|
4
28
|
|
|
5
29
|
// HTTP statuses considered transient — safe to retry with backoff.
|
|
6
30
|
// 408 — request timeout
|
|
@@ -15,22 +39,18 @@ export const TRANSIENT_STATUSES = new Set([408, 409, 425]);
|
|
|
15
39
|
// 400/422 — bad request (deterministic)
|
|
16
40
|
const AUTH_STATUSES = new Set([401, 403]);
|
|
17
41
|
const PERMANENT_STATUSES = new Set([400, 404, 405, 410, 415, 422]);
|
|
18
|
-
// Cloudflare origin-TLS pages never clear on retry
|
|
42
|
+
// Cloudflare origin-TLS pages never clear on retry.
|
|
19
43
|
export const TERMINAL_EDGE_STATUSES = new Set([525, 526]);
|
|
20
44
|
const GEMINI_TRANSIENT_RPC_CODES = new Set(['UNAVAILABLE', 'DEADLINE_EXCEEDED', 'ABORTED', 'INTERNAL']);
|
|
21
45
|
const PREVIOUS_RESPONSE_NOT_FOUND = 'previous_response_not_found';
|
|
22
46
|
export const WEBSOCKET_CONNECTION_LIMIT = 'websocket_connection_limit_reached';
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
'
|
|
27
|
-
'
|
|
28
|
-
'
|
|
29
|
-
'HeadersTimeoutError',
|
|
30
|
-
'BodyTimeoutError',
|
|
47
|
+
// Token-context codes only: a byte-size `request_too_large` is not cured by
|
|
48
|
+
// compaction (see isContextOverflowError).
|
|
49
|
+
const CONTEXT_OVERFLOW_CODES = new Set([
|
|
50
|
+
'context_length_exceeded',
|
|
51
|
+
'context_window_exceeded',
|
|
52
|
+
'model_context_window_exceeded',
|
|
31
53
|
]);
|
|
32
|
-
const ANTHROPIC_RESET_HEADER = 'anthropic-ratelimit-unified-reset';
|
|
33
|
-
const ANTHROPIC_RESET_CAP_MS = 300_000;
|
|
34
54
|
|
|
35
55
|
// Structured status fields a provider error / wire event may carry. A value is
|
|
36
56
|
// accepted only when it is a real numeric HTTP status; string codes
|
|
@@ -59,8 +79,11 @@ const statusOfError = (err) => Number(err?.httpStatus || err?.status || err?.res
|
|
|
59
79
|
|
|
60
80
|
// The verdict a typed HTTP status (or a typed stream shape) gives, in
|
|
61
81
|
// precedence order; null when the status decides nothing.
|
|
62
|
-
function classifyByStatus(err, status) {
|
|
82
|
+
function classifyByStatus(err, status, options = {}) {
|
|
63
83
|
if (AUTH_STATUSES.has(status)) return 'auth';
|
|
84
|
+
// Opt-in: 499 "client closed request" from Google
|
|
85
|
+
// frontends is retried; others keep it a deterministic 4xx.
|
|
86
|
+
if (status === 499 && options.retry499 === true) return 'transient';
|
|
64
87
|
// Stale previous_response_id is recoverable by dropping the chain and
|
|
65
88
|
// re-issuing a full frame, which is the retryable path. A typed
|
|
66
89
|
// 400 here is not a deterministic payload refusal.
|
|
@@ -90,7 +113,7 @@ function classifyByStatus(err, status) {
|
|
|
90
113
|
* 'unknown' — neither; default to permanent in safety-critical paths,
|
|
91
114
|
* or retry once in best-effort paths.
|
|
92
115
|
*/
|
|
93
|
-
export function classifyError(err) {
|
|
116
|
+
export function classifyError(err, options = {}) {
|
|
94
117
|
if (!err) return 'unknown';
|
|
95
118
|
// Canonical stream-outcome contract owns replay safety: exposed
|
|
96
119
|
// text/reasoning or a dispatched/ambiguous complete tool call makes
|
|
@@ -105,14 +128,34 @@ export function classifyError(err) {
|
|
|
105
128
|
// across the bounded chain before considering stale connection causes.
|
|
106
129
|
const chain = boundedCauseChain(err);
|
|
107
130
|
if (chain.some(isExplicitUserAbortError)) return 'permanent';
|
|
108
|
-
//
|
|
131
|
+
// A typed provider code outranks the HTTP status (429+server_is_overloaded
|
|
132
|
+
// is an overload, 403+cyber_policy a policy refusal, 5xx+insufficient_quota
|
|
133
|
+
// a billing refusal).
|
|
134
|
+
// Typed evidence only: message wording never synthesizes a verdict here.
|
|
135
|
+
const { kind } = providerErrorKind(err, { text: false });
|
|
109
136
|
const status = statusOfError(err);
|
|
110
|
-
|
|
137
|
+
// Opt-in: a status-only 499 "client closed request" is retried instead of
|
|
138
|
+
// read as a 4xx; a typed code on it decides as usual.
|
|
139
|
+
if (status === 499 && options.retry499 === true && kind === 'invalid_request' && !typedCodeKind(err)) {
|
|
140
|
+
return 'transient';
|
|
141
|
+
}
|
|
142
|
+
if (kind === 'auth' || kind === 'permission') return 'auth';
|
|
143
|
+
if (DETERMINISTIC_KINDS.has(kind)) return 'permanent';
|
|
144
|
+
// An origin-TLS edge failure is final whatever code accompanies it.
|
|
145
|
+
if (TERMINAL_EDGE_STATUSES.has(status)) return 'permanent';
|
|
146
|
+
// A deterministic wire code outranks a numeric 5xx on the same event.
|
|
147
|
+
if (classifyWireErrorEvent(err) === 'permanent') return 'permanent';
|
|
148
|
+
if (kind === 'overloaded') return 'transient';
|
|
149
|
+
// A typed transient kind decides whatever status accompanies it (401 +
|
|
150
|
+
// server_error is a server fault).
|
|
151
|
+
if (kind === 'transient') return 'transient';
|
|
152
|
+
// Current typed HTTP status outranks stale stream/connection annotations.
|
|
153
|
+
return classifyByStatus(err, status, options) || classifyByTransport(err, chain, status) || 'unknown';
|
|
111
154
|
}
|
|
112
155
|
|
|
113
156
|
// A turn that ended on a malformed or unexpected tool call produced no usable
|
|
114
|
-
// call at all (the typed finish reason says so); the
|
|
115
|
-
//
|
|
157
|
+
// call at all (the typed finish reason says so); the same request is re-asked,
|
|
158
|
+
// bounded, instead of failing the turn.
|
|
116
159
|
const INVALID_TOOL_CALL_FINISH_REASONS = new Set(['MALFORMED_FUNCTION_CALL', 'UNEXPECTED_TOOL_CALL']);
|
|
117
160
|
|
|
118
161
|
function isInvalidToolCallFinish(err) {
|
|
@@ -132,9 +175,9 @@ function classifyByTransport(err, chain, status) {
|
|
|
132
175
|
// so without this it classified as 'unknown' and no loop-level replay was
|
|
133
176
|
// ever attempted (observed live: pooled WS retired by the server between
|
|
134
177
|
// turns → close 1000 before response.created → the whole turn failed).
|
|
135
|
-
//
|
|
136
|
-
//
|
|
137
|
-
//
|
|
178
|
+
// The same disconnect is retryable (a stream fallback/retry applies); the
|
|
179
|
+
// exposure deny above still fails closed for anything already relayed or
|
|
180
|
+
// dispatched.
|
|
138
181
|
if (isNonTerminalStreamClose(err)) return 'transient';
|
|
139
182
|
|
|
140
183
|
// Cursor's resumed tool-result stream cannot safely reopen the same wire
|
|
@@ -172,58 +215,6 @@ function classifyByTransport(err, chain, status) {
|
|
|
172
215
|
return classifyWireErrorEvent(err) || null;
|
|
173
216
|
}
|
|
174
217
|
|
|
175
|
-
const MAX_CAUSE_CHAIN_DEPTH = 8;
|
|
176
|
-
// 'terminated' / 'other side closed' / 'socket hang up' are the body-read
|
|
177
|
-
// forms of the same disconnect (undici aborts the response body when the peer
|
|
178
|
-
// closes mid-stream and may not attach a cause).
|
|
179
|
-
const BARE_FETCH_TRANSPORT_MESSAGE_RE =
|
|
180
|
-
/^(?:fetch failed|failed to fetch|couldn'?t fetch\.?|load failed|network error|terminated|other side closed|socket hang up)$/i;
|
|
181
|
-
const TRANSIENT_ERROR_CODES = new Set([
|
|
182
|
-
'ECONNRESET',
|
|
183
|
-
'ETIMEDOUT',
|
|
184
|
-
'ESOCKETTIMEDOUT',
|
|
185
|
-
'EAI_AGAIN',
|
|
186
|
-
'ENOTFOUND',
|
|
187
|
-
'EAI_NODATA',
|
|
188
|
-
'ECONNREFUSED',
|
|
189
|
-
'ENETUNREACH',
|
|
190
|
-
'EHOSTUNREACH',
|
|
191
|
-
'EPIPE',
|
|
192
|
-
'EPROVIDERTIMEOUT',
|
|
193
|
-
'EGEMINITIMEOUT',
|
|
194
|
-
'ESTREAMSTALL',
|
|
195
|
-
'EWSACQUIRETIMEOUT',
|
|
196
|
-
'UND_ERR_SOCKET',
|
|
197
|
-
'UND_ERR_CONNECT_TIMEOUT',
|
|
198
|
-
'UND_ERR_HEADERS_TIMEOUT',
|
|
199
|
-
'UND_ERR_BODY_TIMEOUT',
|
|
200
|
-
'UND_ERR_CONNECT',
|
|
201
|
-
'EPROTO',
|
|
202
|
-
'UND_ERR_DESTROYED',
|
|
203
|
-
'UND_ERR_CLOSED',
|
|
204
|
-
'ECONNABORTED',
|
|
205
|
-
'ENETRESET',
|
|
206
|
-
'ERR_STREAM_DESTROYED',
|
|
207
|
-
'ERR_HTTP2_STREAM_ERROR',
|
|
208
|
-
'ERR_HTTP2_SESSION_ERROR',
|
|
209
|
-
'ERR_HTTP2_INVALID_SESSION',
|
|
210
|
-
'ERR_SOCKET_CONNECTION_TIMEOUT',
|
|
211
|
-
'ERR_SSL_WRONG_VERSION_NUMBER',
|
|
212
|
-
'ERR_STREAM_PREMATURE_CLOSE',
|
|
213
|
-
]);
|
|
214
|
-
|
|
215
|
-
// TLS record corruption on a flaky link or a meddling proxy. Node builds the
|
|
216
|
-
// ERR_SSL_* code from the OpenSSL reason string, which differs across OpenSSL
|
|
217
|
-
// versions (…SSLV3_ALERT_BAD_RECORD_MAC, …SSL/TLS_ALERT_BAD_RECORD_MAC,
|
|
218
|
-
// …DECRYPTION_FAILED_OR_BAD_RECORD_MAC), so the stable suffix names the class.
|
|
219
|
-
const TLS_RECORD_FAILURE_RE = /^ERR_SSL_[A-Z0-9_/]*BAD_RECORD_MAC$/i;
|
|
220
|
-
|
|
221
|
-
/** True for a socket/TLS errno that describes a transient transport fault. */
|
|
222
|
-
export function isTransientErrorCode(code) {
|
|
223
|
-
const value = String(code || '');
|
|
224
|
-
return TRANSIENT_ERROR_CODES.has(value) || TLS_RECORD_FAILURE_RE.test(value);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
218
|
// Cursor's HTTP/2 bridge preserves provider-specific codes in `cursorCode`.
|
|
228
219
|
// These codes all describe an incomplete transport turn, not a model verdict.
|
|
229
220
|
// Replay permission remains fail-closed in the stream-outcome gate above.
|
|
@@ -342,9 +333,8 @@ export function isToolInputCut(err) {
|
|
|
342
333
|
// The provider was never reached: name resolution, routing, refusal or the
|
|
343
334
|
// connect handshake failed, so nothing was sent or received. Only this class
|
|
344
335
|
// is worth waiting out for minutes — the identical request succeeds once the
|
|
345
|
-
// network is back (a lift, a sleeping laptop, a router reboot),
|
|
346
|
-
//
|
|
347
|
-
// recovers. A stream that dropped mid-response is not this class: it keeps
|
|
336
|
+
// network is back (a lift, a sleeping laptop, a router reboot), so a sampling
|
|
337
|
+
// turn is kept alive until such a connection recovers. A stream that dropped mid-response is not this class: it keeps
|
|
348
338
|
// the short, bounded retry budget.
|
|
349
339
|
const CONNECT_FAILURE_CODES = new Set([
|
|
350
340
|
'ENOTFOUND',
|
|
@@ -382,9 +372,14 @@ export function isServerUnavailable(err) {
|
|
|
382
372
|
if (!err || (typeof err !== 'object' && typeof err !== 'function')) return false;
|
|
383
373
|
const chain = boundedCauseChain(err);
|
|
384
374
|
if (chain.some(isExplicitUserAbortError)) return false;
|
|
375
|
+
// Typed kind first: an overload (any status) is this class; quota, billing,
|
|
376
|
+
// policy, auth, request refusals and rate limits never are.
|
|
377
|
+
const { kind } = providerErrorKind(err);
|
|
378
|
+
if (kind === 'overloaded') return true;
|
|
379
|
+
if (kind !== 'transient' && kind !== 'unknown') return false;
|
|
385
380
|
const status = statusOfError(err);
|
|
386
381
|
if (status) return status === 408 || (status >= 500 && status < 600 && !TERMINAL_EDGE_STATUSES.has(status));
|
|
387
|
-
if (isRetryableWireErrorEvent(err)) return
|
|
382
|
+
if (isRetryableWireErrorEvent(err)) return true;
|
|
388
383
|
return chain.some((item) => {
|
|
389
384
|
const rpc = [item?.geminiStatus, item?.error?.status, typeof item?.status === 'string' ? item.status : ''];
|
|
390
385
|
if (rpc.some((field) => GEMINI_TRANSIENT_RPC_CODES.has(String(field || '').toUpperCase()))) return true;
|
|
@@ -414,21 +409,11 @@ export function canFallbackNonStreaming(err, { signal } = {}) {
|
|
|
414
409
|
// A cut mid tool-argument stream is replayed by the loop with a split-call
|
|
415
410
|
// notice, never re-issued unchanged here.
|
|
416
411
|
if (isToolInputCut(err)) return false;
|
|
412
|
+
// A provider-terminal verdict ends recovery; no re-issue of any shape.
|
|
413
|
+
if (boundedCauseChain(err).some((item) => item?.providerRecoveryTerminal === true)) return false;
|
|
417
414
|
return classifyError(err) === 'transient' || outcome.stallObserved === true || outcome.truncatedStream === true;
|
|
418
415
|
}
|
|
419
416
|
|
|
420
|
-
export function boundedCauseChain(err) {
|
|
421
|
-
const chain = [];
|
|
422
|
-
const seen = new Set();
|
|
423
|
-
let cursor = err;
|
|
424
|
-
while (cursor && chain.length < MAX_CAUSE_CHAIN_DEPTH && !seen.has(cursor)) {
|
|
425
|
-
chain.push(cursor);
|
|
426
|
-
seen.add(cursor);
|
|
427
|
-
cursor = cursor?.cause;
|
|
428
|
-
}
|
|
429
|
-
return chain;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
417
|
export function isExplicitUserAbortError(err) {
|
|
433
418
|
if (!err || (typeof err !== 'object' && typeof err !== 'function')) return false;
|
|
434
419
|
if (err.name === 'AbortError' || err.name === 'APIUserAbortError' || err.code === 'ABORT_ERR') return true;
|
|
@@ -462,34 +447,10 @@ export function isCursorTransientTransportError(err) {
|
|
|
462
447
|
// Patterns cover OpenAI ("maximum context length", "reduce the length"),
|
|
463
448
|
// Anthropic ("prompt is too long"), and generic "input exceeds the context
|
|
464
449
|
// window" phrasing. Match is case-insensitive over err.message.
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
/context[_ ]length[_ ]exceeded/i,
|
|
470
|
-
/prompt is too long/i,
|
|
471
|
-
/reduce the length of (?:the )?(?:messages|input|prompt)/i,
|
|
472
|
-
// Wordings other backends use for the same refusal, each tied to a context
|
|
473
|
-
// or input-length noun so a tokens-per-minute rate limit never matches.
|
|
474
|
-
/prompt too long/i, // z.ai, Ollama
|
|
475
|
-
/prompt exceeds max length/i, // z.ai CN endpoint
|
|
476
|
-
/input is too long for requested model/i, // Amazon Bedrock
|
|
477
|
-
/input token count.*exceeds the maximum/i, // Google
|
|
478
|
-
/request payload size exceeds the limit/i, // Google (400, byte-size limit)
|
|
479
|
-
// A 413 re-wrapped by a proxy or aggregator without its status.
|
|
480
|
-
/request entity too large/i,
|
|
481
|
-
/request exceeds the maximum size/i,
|
|
482
|
-
/maximum prompt length is \d+/i, // xAI
|
|
483
|
-
/exceeds (?:the )?maximum allowed input length/i, // OpenRouter relays
|
|
484
|
-
/is longer than the model'?s context length/i, // Together AI
|
|
485
|
-
/exceeds the available context size/i, // llama.cpp server
|
|
486
|
-
/greater than the context length/i, // LM Studio
|
|
487
|
-
/context window exceeds limit/i, // MiniMax
|
|
488
|
-
/exceeded model token limit/i, // Kimi
|
|
489
|
-
/too large for model with \d+ maximum context length/i, // Mistral
|
|
490
|
-
/range of input length should be/i, // DashScope / Qwen
|
|
491
|
-
/model_context_window_exceeded/i, // z.ai finish reason surfaced as text
|
|
492
|
-
];
|
|
450
|
+
// Untyped byte-size wordings (no status, no code) keep routing here: an
|
|
451
|
+
// unlabelled proxy refusal is most often an oversized history.
|
|
452
|
+
const CONTEXT_OVERFLOW_PATTERNS = [...TOKEN_CONTEXT_OVERFLOW_PATTERNS, ...REQUEST_SIZE_PATTERNS];
|
|
453
|
+
const REQUEST_TOO_LARGE_KIND = 'request_too_large';
|
|
493
454
|
|
|
494
455
|
/**
|
|
495
456
|
* True when `err` is a context-window-exceeded provider rejection. Walks
|
|
@@ -502,89 +463,33 @@ const CONTEXT_OVERFLOW_PATTERNS = [
|
|
|
502
463
|
*/
|
|
503
464
|
export function isContextOverflowError(err, _depth = 0) {
|
|
504
465
|
if (!err || _depth > 2) return false;
|
|
505
|
-
if (statusOfError(err) === 413) return true;
|
|
506
466
|
const code = typedErrorCode(err);
|
|
507
467
|
if (code && CONTEXT_OVERFLOW_CODES.has(code)) return true;
|
|
468
|
+
// A typed byte/media-size refusal (a size code, or HTTP 413 without a
|
|
469
|
+
// token-context code) is not a token-context overflow: compaction cannot
|
|
470
|
+
// shrink it, so only token-context wording may still qualify it.
|
|
471
|
+
const sizeTyped =
|
|
472
|
+
typeof err === 'object' &&
|
|
473
|
+
boundedCauseChain(err).some(
|
|
474
|
+
(item) => item && typeof item === 'object' && providerErrorKind(item, { text: false }).kind === REQUEST_TOO_LARGE_KIND
|
|
475
|
+
);
|
|
476
|
+
const patterns = sizeTyped ? TOKEN_CONTEXT_OVERFLOW_PATTERNS : CONTEXT_OVERFLOW_PATTERNS;
|
|
508
477
|
const msg = (typeof err === 'string' ? err : err?.message) || '';
|
|
509
|
-
if (msg &&
|
|
478
|
+
if (msg && patterns.some((re) => re.test(msg))) return true;
|
|
510
479
|
if (err.cause != null && err.cause !== err) return isContextOverflowError(err.cause, _depth + 1);
|
|
511
480
|
if (err.response?.data != null) return isContextOverflowError(err.response.data, _depth + 1);
|
|
512
481
|
return false;
|
|
513
482
|
}
|
|
514
483
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
return null;
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
export function retryAfterMsFromError(err) {
|
|
526
|
-
const headers = err?.headers || err?.response?.headers || err?.data?.responseHeaders || null;
|
|
527
|
-
const retryAfterMs = headerValue(headers, 'retry-after-ms');
|
|
528
|
-
if (retryAfterMs != null && retryAfterMs !== '') {
|
|
529
|
-
const n = Number(retryAfterMs);
|
|
530
|
-
if (Number.isFinite(n) && n >= 0) return n;
|
|
531
|
-
}
|
|
532
|
-
const retryAfter = headerValue(headers, 'retry-after');
|
|
533
|
-
if (retryAfter != null && retryAfter !== '') {
|
|
534
|
-
const seconds = Number(retryAfter);
|
|
535
|
-
if (Number.isFinite(seconds) && seconds >= 0) return Math.ceil(seconds * 1000);
|
|
536
|
-
const dateMs = Date.parse(String(retryAfter));
|
|
537
|
-
if (!Number.isNaN(dateMs)) return Math.max(0, dateMs - Date.now());
|
|
538
|
-
}
|
|
539
|
-
// Google RPC RetryInfo encodes retryDelay as a protobuf Duration. Preserve
|
|
540
|
-
// the same precedence as Retry-After: a server-provided retry window means
|
|
541
|
-
// RESOURCE_EXHAUSTED is request-local, not a permanent quota refusal.
|
|
542
|
-
const detailLists = [err?.details, err?.error?.details, err?.data?.error?.details];
|
|
543
|
-
for (const details of detailLists) {
|
|
544
|
-
if (!Array.isArray(details)) continue;
|
|
545
|
-
for (const detail of details) {
|
|
546
|
-
const delay = detail?.retryDelay;
|
|
547
|
-
if (typeof delay === 'string') {
|
|
548
|
-
const match = delay.trim().match(/^(\d+(?:\.\d+)?)s$/);
|
|
549
|
-
if (match) return Math.ceil(Number(match[1]) * 1000);
|
|
550
|
-
} else if (delay && typeof delay === 'object') {
|
|
551
|
-
const seconds = Number(delay.seconds || 0);
|
|
552
|
-
const nanos = Number(delay.nanos || 0);
|
|
553
|
-
const ms = seconds * 1000 + nanos / 1_000_000;
|
|
554
|
-
if (Number.isFinite(ms) && ms >= 0) return Math.ceil(ms);
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
const resetHeader = headerValue(headers, ANTHROPIC_RESET_HEADER);
|
|
559
|
-
if (resetHeader != null && resetHeader !== '') {
|
|
560
|
-
const resetUnixSec = Number(resetHeader);
|
|
561
|
-
if (Number.isFinite(resetUnixSec) && resetUnixSec > 0) {
|
|
562
|
-
const delayMs = Math.ceil(resetUnixSec * 1000 - Date.now());
|
|
563
|
-
if (delayMs > 0) return Math.min(delayMs, ANTHROPIC_RESET_CAP_MS);
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
// Codex parses the server-supplied window from a TYPED rate_limit_exceeded
|
|
567
|
-
// payload. Message text never decides whether to retry — only how long to
|
|
568
|
-
// wait after the typed code is already in hand. Headers / RetryInfo win.
|
|
569
|
-
if (typedErrorCode(err) === RATE_LIMIT_EXCEEDED) {
|
|
570
|
-
const delay = rateLimitRetryAfterMsFromMessage(err);
|
|
571
|
-
if (delay != null) return delay;
|
|
572
|
-
}
|
|
573
|
-
return null;
|
|
574
|
-
}
|
|
575
|
-
|
|
484
|
+
/**
|
|
485
|
+
* True for an explicit quota / plan / billing refusal (providerErrorKind
|
|
486
|
+
* quota_exhausted, entitlement or billing). No wait recovers it, so retry
|
|
487
|
+
* layers never replay it, even when the server attached a Retry-After.
|
|
488
|
+
* RESOURCE_EXHAUSTED with a 429, retry advice or a per-minute scope is a
|
|
489
|
+
* request-local rate limit instead.
|
|
490
|
+
*/
|
|
576
491
|
export function isPermanentQuotaError(err) {
|
|
577
|
-
|
|
578
|
-
// Gemini uses RESOURCE_EXHAUSTED for both daily quota and per-minute
|
|
579
|
-
// rate limits. A 429 is request-local (Google/LiteLLM retry); without a
|
|
580
|
-
// 429 the same code stays a deterministic quota refusal.
|
|
581
|
-
const permanentCodes = new Set(['insufficient_quota', 'quota_exceeded']);
|
|
582
|
-
if (status !== 429) permanentCodes.add('resource_exhausted');
|
|
583
|
-
for (const item of boundedCauseChain(err)) {
|
|
584
|
-
const codes = [item?.code, item?.error?.code];
|
|
585
|
-
if (codes.some((code) => permanentCodes.has(String(code || '').toLowerCase()))) return true;
|
|
586
|
-
}
|
|
587
|
-
return false;
|
|
492
|
+
return QUOTA_KINDS.has(providerErrorKind(err).kind);
|
|
588
493
|
}
|
|
589
494
|
|
|
590
495
|
// ── Wire error events: default-retry with a fatal-code deny-list ────────────
|
|
@@ -595,7 +500,7 @@ export function isPermanentQuotaError(err) {
|
|
|
595
500
|
// server_error, server_is_overloaded, slow_down, or an event with no code at
|
|
596
501
|
// all — is a server-side fault and is retried under the bounded budgets
|
|
597
502
|
// (observed live 2026-08-11: two turns failed on typed `server_error`
|
|
598
|
-
// response.failed events that
|
|
503
|
+
// response.failed events that are server-side faults).
|
|
599
504
|
export const WIRE_ERROR_FATAL_CODES = new Set([
|
|
600
505
|
'context_length_exceeded',
|
|
601
506
|
'context_window_exceeded',
|
|
@@ -614,17 +519,26 @@ export const WIRE_ERROR_FATAL_CODES = new Set([
|
|
|
614
519
|
'permission_error',
|
|
615
520
|
'permission_denied',
|
|
616
521
|
'billing_not_active',
|
|
522
|
+
// Billing / spend refusals.
|
|
523
|
+
'credit_balance_exhausted',
|
|
524
|
+
'organization_spend_limit_exceeded',
|
|
525
|
+
'project_spend_limit_exceeded',
|
|
526
|
+
'organization_usage_limit_exceeded',
|
|
527
|
+
'billing_hard_limit_reached',
|
|
528
|
+
'payment_required',
|
|
529
|
+
// Policy refusals.
|
|
530
|
+
'cyber_policy_violation',
|
|
531
|
+
'bio_policy_violation',
|
|
532
|
+
'misalignment_policy_violation',
|
|
533
|
+
'content_policy_violation',
|
|
534
|
+
'content_filter',
|
|
535
|
+
// Flex tier capacity: the same request at the same tier is refused again.
|
|
536
|
+
'flex_unavailable',
|
|
537
|
+
// Byte/media size and token context.
|
|
538
|
+
'request_too_large',
|
|
539
|
+
'model_context_window_exceeded',
|
|
617
540
|
]);
|
|
618
541
|
|
|
619
|
-
export function typedErrorCode(err) {
|
|
620
|
-
const failed = err?.responseFailed;
|
|
621
|
-
const detail = failed?.response?.error || failed?.error || err?.providerError || failed || null;
|
|
622
|
-
for (const field of [detail?.code, detail?.type, err?.providerErrorCode, err?.code, err?.error?.code]) {
|
|
623
|
-
if (typeof field === 'string' && field.trim()) return field.trim().toLowerCase();
|
|
624
|
-
}
|
|
625
|
-
return '';
|
|
626
|
-
}
|
|
627
|
-
|
|
628
542
|
/**
|
|
629
543
|
* True when the typed wire/SDK code is previous_response_not_found.
|
|
630
544
|
* Callers drop lastResponseId / previous_response_id and re-issue a full frame.
|
|
@@ -657,30 +571,15 @@ export function isStaleKeepAliveError(err) {
|
|
|
657
571
|
});
|
|
658
572
|
}
|
|
659
573
|
|
|
660
|
-
const RATE_LIMIT_RETRY_AFTER_RE = /try again in\s*(\d+(?:\.\d+)?)\s*(ms|s|seconds?)\b/i;
|
|
661
|
-
|
|
662
|
-
function rateLimitRetryAfterMsFromMessage(err) {
|
|
663
|
-
const failed = err?.responseFailed;
|
|
664
|
-
const detail = failed?.response?.error || failed?.error || err?.providerError || err?.error || null;
|
|
665
|
-
const messages = [detail?.message, err?.message];
|
|
666
|
-
for (const message of messages) {
|
|
667
|
-
if (typeof message !== 'string' || !message) continue;
|
|
668
|
-
const match = message.match(RATE_LIMIT_RETRY_AFTER_RE);
|
|
669
|
-
if (!match) continue;
|
|
670
|
-
const value = Number(match[1]);
|
|
671
|
-
if (!Number.isFinite(value) || value < 0) continue;
|
|
672
|
-
const unit = String(match[2] || '').toLowerCase();
|
|
673
|
-
return unit === 'ms' ? Math.ceil(value) : Math.ceil(value * 1000);
|
|
674
|
-
}
|
|
675
|
-
return null;
|
|
676
|
-
}
|
|
677
|
-
|
|
678
574
|
// 'transient' | 'permanent' for errors born from a provider wire error event;
|
|
679
575
|
// null for everything else (no blanket retry for untyped local failures).
|
|
576
|
+
// A fatal code or a deterministic kind (quota, billing, plan, policy, auth,
|
|
577
|
+
// permission, context, size) outranks any numeric 5xx the event carries.
|
|
680
578
|
function classifyWireErrorEvent(err) {
|
|
681
579
|
if (!err || (err.responseFailed == null && err.providerWireError !== true)) return null;
|
|
682
580
|
const code = typedErrorCode(err);
|
|
683
581
|
if (code && WIRE_ERROR_FATAL_CODES.has(code)) return 'permanent';
|
|
582
|
+
if (DETERMINISTIC_KINDS.has(providerErrorKind(err, { text: false }).kind)) return 'permanent';
|
|
684
583
|
return 'transient';
|
|
685
584
|
}
|
|
686
585
|
|
|
@@ -696,7 +595,7 @@ export function isRetryableWireErrorEvent(err) {
|
|
|
696
595
|
}
|
|
697
596
|
|
|
698
597
|
/**
|
|
699
|
-
*
|
|
598
|
+
* Mid-stream wire error event: a mid-stream wire fault is retryable even when the
|
|
700
599
|
* envelope type is invalid_request_error, unless a typed 4xx status or a
|
|
701
600
|
* deterministic refusal code (quota/context/auth) is present.
|
|
702
601
|
*/
|
|
@@ -50,6 +50,7 @@ export {
|
|
|
50
50
|
ANTHROPIC_RETRY_BACKOFF_MS,
|
|
51
51
|
ANTHROPIC_RETRY_JITTER_RATIO,
|
|
52
52
|
AnthropicFallbackTriggeredError,
|
|
53
|
+
ModelFallbackTriggeredError,
|
|
53
54
|
STREAM_STALL_RETRY_BUDGET_MS,
|
|
54
55
|
anthropicMaxAttempts,
|
|
55
56
|
anthropicRequestTimeoutMs,
|
|
@@ -71,6 +72,7 @@ export {
|
|
|
71
72
|
createStreamSafetyStamps,
|
|
72
73
|
emitProviderRetryStage,
|
|
73
74
|
isProviderRecoveryExhausted,
|
|
75
|
+
isProviderRecoveryTerminal,
|
|
74
76
|
markProviderRecoveryExhausted,
|
|
75
77
|
retryDelayLabel,
|
|
76
78
|
withRetry,
|