mixdog 1.2.1 → 1.2.3
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 +18 -0
- package/package.json +2 -1
- package/scripts/gate-local.mjs +19 -3
- package/scripts/model-catalog-audit.mjs +1 -15
- package/scripts/provider-pingpong-live.mjs +509 -0
- package/src/agents/advisor/AGENT.md +1 -1
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/reviewer/AGENT.md +3 -3
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +6 -0
- package/src/defaults/skills/setup/SKILL.md +6 -1
- package/src/defaults/skills/setup/references/actions.md +44 -22
- package/src/defaults/skills/setup/references/surfaces.md +10 -8
- package/src/headless-exec.mjs +15 -8
- package/src/lib/keychain-cjs.cjs +7 -4
- package/src/output-styles/common.md +11 -10
- package/src/repl/slash-commands.mjs +16 -1
- package/src/rules/agent/AGENT.md +5 -5
- package/src/rules/lead/LEAD.md +5 -5
- 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/agent-trace-io.mjs +92 -61
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
- package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
- package/src/runtime/agent/orchestrator/config.mjs +5 -0
- package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +36 -7
- package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +49 -10
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +40 -3
- package/src/runtime/agent/orchestrator/mcp/client.mjs +230 -96
- 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/providers/account-pool.mjs +188 -29
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +94 -31
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +98 -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 +48 -37
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +10 -7
- 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 +102 -45
- 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-turn/turn-blocks.mjs +20 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +10 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +40 -7
- 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 +88 -21
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +30 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +106 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +10 -61
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +94 -15
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +117 -72
- package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +75 -10
- 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 +103 -23
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +43 -2
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +103 -33
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +32 -6
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +27 -3
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +64 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +70 -6
- package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
- package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
- package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +80 -18
- package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +46 -8
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +273 -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-request-body.mjs +41 -5
- 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 +369 -112
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +140 -35
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +70 -24
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +80 -29
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +69 -19
- package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +246 -42
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
- package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +388 -0
- package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
- package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
- package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +48 -22
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +119 -18
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
- 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-channel.d.mts +1 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +33 -1
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +4 -9
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +123 -61
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +27 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +37 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
- 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 +47 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +151 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +64 -23
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +79 -33
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +172 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-state.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +144 -15
- 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 +9 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +109 -26
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +27 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +34 -20
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +23 -4
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +37 -28
- 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/output-items.mjs +23 -10
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +43 -15
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +5 -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 +7 -3
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
- 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-model-capabilities.mjs +80 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +37 -4
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +12 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +22 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +12 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +76 -33
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +44 -16
- package/src/runtime/agent/orchestrator/providers/openai-retry-policy.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -16
- package/src/runtime/agent/orchestrator/providers/openai-ws-handshake.mjs +16 -8
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -35
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
- 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-stream/event-switch.mjs +12 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
- package/src/runtime/agent/orchestrator/providers/openai-ws-terminal.mjs +18 -11
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +41 -22
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +170 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +75 -70
- package/src/runtime/agent/orchestrator/providers/openrouter.mjs +75 -0
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +720 -0
- package/src/runtime/agent/orchestrator/providers/registry.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/retry-backoff.mjs +46 -7
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +123 -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/providers/transport-scope.d.mts +6 -0
- package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +157 -0
- package/src/runtime/agent/orchestrator/providers/wire-route.mjs +512 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +183 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +100 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +21 -0
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
- 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 +1 -97
- package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
- package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +14 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +176 -71
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +62 -10
- package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +14 -93
- package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +120 -0
- package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
- package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +91 -1
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
- package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +21 -10
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +132 -0
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +30 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +104 -19
- package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +150 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +30 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +57 -21
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +5 -10
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +208 -14
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +16 -4
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +25 -3
- package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +19 -2
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +18 -7
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +168 -29
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
- package/src/runtime/agent/orchestrator/session/side-question.mjs +192 -0
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +17 -3
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +58 -2
- package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +41 -28
- package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +12 -1
- package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +3 -1
- 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-archived-agent.mjs +34 -15
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/store.mjs +19 -3
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +77 -0
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +20 -1
- package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +12 -15
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +14 -10
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +49 -34
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
- package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
- package/src/runtime/computer-bridge/action-schema.mjs +44 -21
- package/src/runtime/github/tool.mjs +92 -2
- package/src/runtime/memory/index.mjs +1 -0
- package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
- package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
- package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
- package/src/runtime/memory/lib/pg/process.mjs +65 -50
- package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
- package/src/runtime/memory/lib/pg/supervisor.mjs +124 -16
- package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
- package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
- package/src/runtime/office/README.md +2 -2
- package/src/runtime/office/authoring/html-document-author.mjs +2 -0
- package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
- package/src/runtime/office/authoring/pptx-html-measure.mjs +2 -0
- package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +2 -0
- package/src/runtime/office/core/office-actions-read.mjs +3 -0
- package/src/runtime/office/core/office-render-preview.mjs +2 -0
- package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
- package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
- package/src/runtime/office/core/office-sessions.mjs +5 -0
- package/src/runtime/office/core/office-transactions.mjs +3 -0
- package/src/runtime/office/core/office-write-ledger.mjs +98 -0
- package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
- package/src/runtime/office/index.mjs +30 -0
- package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
- package/src/runtime/office/pdf/pdf-render.mjs +23 -7
- package/src/runtime/office/pdf/pdf-security.mjs +2 -0
- package/src/runtime/office/portable/portable-opc.mjs +4 -1
- package/src/runtime/office/quality/visual-diff.mjs +2 -0
- package/src/runtime/office/shared/values.mjs +0 -5
- package/src/runtime/shared/background-tasks.mjs +92 -14
- package/src/runtime/shared/bounded-file-read.mjs +13 -0
- package/src/runtime/shared/bounded-line-diff.mjs +182 -0
- package/src/runtime/shared/buffered-appender.mjs +18 -0
- package/src/runtime/shared/config.mjs +78 -18
- package/src/runtime/shared/err-text.mjs +31 -0
- package/src/runtime/shared/error-presentation.mjs +159 -19
- package/src/runtime/shared/file-permissions.d.mts +6 -1
- package/src/runtime/shared/file-permissions.mjs +54 -6
- package/src/runtime/shared/llm/anthropic-betas.mjs +4 -3
- package/src/runtime/shared/llm/anthropic-effort.mjs +129 -134
- package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +50 -14
- package/src/runtime/shared/llm/model-catalog.mjs +53 -40
- package/src/runtime/shared/llm/openai-daybreak.mjs +4 -16
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +11 -0
- package/src/runtime/shared/llm/provider-model-identities.mjs +13 -4
- package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
- package/src/runtime/shared/llm/usage-rollup.mjs +0 -1
- package/src/runtime/shared/loopback-listener.mjs +9 -0
- package/src/runtime/shared/model-display.mjs +13 -0
- package/src/runtime/shared/provider-api-key.mjs +2 -0
- package/src/runtime/shared/quota-resume-store.mjs +11 -0
- package/src/runtime/shared/review-diff.mjs +52 -0
- package/src/runtime/shared/session-baseline-store.mjs +960 -0
- package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
- package/src/runtime/shared/session-sidebar-host.mjs +38 -0
- package/src/runtime/shared/slow-span.mjs +114 -0
- package/src/runtime/shared/statusline/statusline-format.mjs +4 -4
- package/src/runtime/shared/statusline/statusline-segments.mjs +28 -4
- package/src/runtime/shared/task-notification-envelope.mjs +2 -2
- package/src/runtime/shared/tool-card-model/card-header.mjs +6 -1
- package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
- package/src/runtime/shared/tool-card-model.mjs +5 -2
- package/src/runtime/shared/tool-output-limit.mjs +4 -0
- package/src/runtime/shared/tool-primitives.mjs +13 -0
- package/src/runtime/shared/tool-result-summary.mjs +8 -1
- package/src/runtime/shared/tool-surface.mjs +18 -3
- package/src/runtime/shared/tool-work-units.mjs +40 -4
- package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
- package/src/runtime/shared/transcript-writer.mjs +10 -2
- package/src/runtime/shared/turn-changes.mjs +670 -274
- package/src/runtime/shared/turn-review-reply.mjs +8 -39
- package/src/runtime/shared/turn-snapshot-store.mjs +94 -2
- package/src/runtime/shared/turn-snapshot.mjs +986 -690
- package/src/runtime/shared/turn-worktree-snapshot.mjs +279 -262
- package/src/runtime/shared/user-data-guard.mjs +262 -49
- package/src/runtime/shared/worktrees/carry.mjs +531 -0
- package/src/runtime/shared/worktrees/contract.mjs +34 -24
- package/src/runtime/shared/worktrees/file-recovery.mjs +68 -0
- package/src/runtime/shared/worktrees/git-head.mjs +205 -0
- package/src/runtime/shared/worktrees/git.mjs +8 -3
- package/src/runtime/shared/worktrees/maintenance.mjs +1 -1
- package/src/runtime/shared/worktrees/manager.mjs +156 -8
- package/src/runtime/shared/worktrees/merge.mjs +31 -21
- package/src/runtime/shared/worktrees/paths.d.mts +6 -0
- package/src/runtime/shared/worktrees/test-support.mjs +19 -4
- package/src/runtime/terminal-bridge/client.mjs +44 -11
- package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
- package/src/runtime/tidy/apply.mjs +47 -2
- package/src/runtime/tidy/run-engines.mjs +11 -5
- package/src/session-runtime/agent-tool-routing.mjs +19 -13
- package/src/session-runtime/boot/apis.mjs +19 -5
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/infrastructure.mjs +12 -1
- package/src/session-runtime/boot/session.mjs +0 -1
- package/src/session-runtime/boot/tools.mjs +4 -1
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +65 -0
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +11 -4
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +115 -18
- package/src/session-runtime/internal-tool-executor.mjs +6 -2
- package/src/session-runtime/lifecycle/cold-heir.mjs +188 -0
- package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
- package/src/session-runtime/lifecycle/session-catalog.mjs +14 -3
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +29 -6
- package/src/session-runtime/lifecycle/teardown.mjs +73 -8
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/connect.mjs +46 -14
- package/src/session-runtime/mcp-glue/server-catalog.mjs +20 -3
- package/src/session-runtime/mcp-glue.mjs +3 -0
- 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 +85 -17
- 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/native-web-search-usage.mjs +51 -0
- package/src/session-runtime/native-web-search.mjs +10 -1
- package/src/session-runtime/new-session-config.mjs +4 -2
- package/src/session-runtime/provider-auth/login.mjs +4 -0
- package/src/session-runtime/provider-models/model-meta.mjs +12 -3
- 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 +4 -0
- package/src/session-runtime/resource-mcp-api.mjs +98 -2
- package/src/session-runtime/resource-scope-decorate.mjs +10 -3
- package/src/session-runtime/runtime-review-api.mjs +21 -2
- package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
- 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/lead-worker-index/forgotten-leads.mjs +29 -0
- package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +73 -7
- 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/tag-registry.mjs +15 -1
- 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-index/row-store.mjs +10 -1
- package/src/session-runtime/services/agent-tool/worker-index.mjs +46 -7
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +17 -0
- package/src/session-runtime/services/agent-tool.mjs +3 -0
- package/src/session-runtime/services/channel-admin.mjs +19 -3
- package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
- package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
- package/src/session-runtime/services/provider-admin.mjs +81 -15
- package/src/session-runtime/session-transcript-purge.mjs +32 -0
- package/src/session-runtime/session-turn-api.mjs +14 -5
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -0
- package/src/session-runtime/settings-compaction-api.mjs +1 -0
- package/src/session-runtime/setup-tool/executor.mjs +36 -6
- package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +13 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +13 -4
- package/src/session-runtime/skills-api.mjs +3 -5
- package/src/session-runtime/tool-surface.mjs +5 -1
- package/src/session-runtime/turn/compaction-gate.mjs +25 -0
- package/src/session-runtime/turn/session-ops.mjs +7 -5
- package/src/session-runtime/turn/side-question-ops.mjs +22 -0
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +5 -1
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +8 -3
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +10 -0
- package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
- package/src/session-runtime/turn/turn-run.mjs +25 -9
- package/src/session-runtime/usage-stats-api.mjs +43 -11
- package/src/session-runtime/workspace/project-branches.mjs +7 -5
- package/src/session-runtime/workspace/transition-steps.mjs +129 -31
- package/src/session-runtime/workspace/transitions.mjs +190 -15
- package/src/standalone/daemon-agent-control.mjs +9 -1
- package/src/standalone/daemon-drain-policy.mjs +8 -0
- package/src/standalone/daemon-local-session-bridge.mjs +14 -1
- package/src/standalone/daemon-owner.mjs +17 -4
- package/src/standalone/daemon-pg-stop.mjs +51 -0
- package/src/standalone/daemon-stop-budget.d.mts +2 -0
- package/src/standalone/daemon-stop-budget.mjs +18 -0
- package/src/standalone/daemon-stored-session-views.mjs +2 -0
- package/src/standalone/daemon-telemetry.mjs +74 -0
- package/src/standalone/daemon.mjs +64 -8
- package/src/standalone/desktop-service-registry.mjs +5 -0
- package/src/standalone/local-session-runtime.mjs +70 -19
- package/src/standalone/session-client.mjs +42 -0
- package/src/standalone/session-protocol.mjs +14 -0
- package/src/standalone/session-proxy/projection.mjs +41 -4
- package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
- package/src/standalone/session-runtime-inline-host.mjs +1 -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 +18 -3
- package/src/standalone/session-service-api.mjs +11 -1
- package/src/standalone/session-service.mjs +1 -0
- package/src/standalone/session-state-patch.d.mts +2 -1
- package/src/standalone/session-state-patch.mjs +41 -1
- package/src/tui/App.jsx +25 -0
- package/src/tui/app/app-view/floating-panel.jsx +26 -1
- package/src/tui/app/app-view.jsx +1 -0
- package/src/tui/app/btw-controller.mjs +118 -0
- package/src/tui/app/create-app-pickers.mjs +6 -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.mjs +2 -1
- package/src/tui/app/model-options.mjs +11 -16
- package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
- package/src/tui/app/shell-layout/surfaces.mjs +3 -1
- package/src/tui/app/slash-commands.mjs +20 -5
- package/src/tui/app/slash-dispatch/panel-commands.mjs +16 -1
- package/src/tui/app/slash-dispatch/session-commands.mjs +19 -6
- package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
- package/src/tui/app/use-global-key-input.mjs +5 -12
- package/src/tui/app/use-prompt-handlers.mjs +11 -0
- package/src/tui/components/BtwPanel.jsx +53 -0
- package/src/tui/components/QuestionPanel.jsx +275 -0
- package/src/tui/components/StatusLine.jsx +2 -0
- package/src/tui/components/question-panel-model.mjs +156 -0
- 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/dist/index.mjs +3221 -1500
- package/src/tui/session/context-state.mjs +4 -2
- package/src/tui/session/quota-resume.mjs +46 -14
- package/src/tui/session/session-api/commands.mjs +43 -24
- package/src/tui/session/session-api/controls.mjs +2 -2
- package/src/tui/session/session-api/extensions.mjs +22 -0
- package/src/tui/session/session-api/integrations.mjs +16 -2
- package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
- package/src/tui/session/session-api/lifecycle.mjs +7 -2
- package/src/tui/session/session-api/routes.mjs +71 -7
- package/src/tui/session/session-api/settings.mjs +11 -14
- package/src/tui/session/session-api.mjs +1 -0
- package/src/tui/session/session-flow/drain.mjs +7 -1
- package/src/tui/session/session-flow/failed-turn-rewind.mjs +10 -4
- package/src/tui/session/tool-approval.mjs +10 -7
- package/src/tui/session/transcript-spill.mjs +14 -7
- package/src/tui/session/turn-stream.mjs +174 -31
- package/src/tui/session/turn.mjs +46 -16
- 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/workflows/default/WORKFLOW.md +3 -1
- package/src/runtime/memory/lib/memory-session-merge.mjs +0 -32
- package/src/runtime/shared/llm/usage-session-history.mjs +0 -266
|
@@ -14,13 +14,16 @@ import {
|
|
|
14
14
|
ANTHROPIC_RETRY_JITTER_RATIO,
|
|
15
15
|
anthropicMaxAttempts,
|
|
16
16
|
anthropicRequestTimeoutMs,
|
|
17
|
+
AnthropicFallbackTriggeredError,
|
|
17
18
|
emitProviderRetryStage,
|
|
18
19
|
withRetry,
|
|
19
|
-
retryAfterMsFromError,
|
|
20
20
|
retryDelayLabel,
|
|
21
21
|
} from './retry-classifier.mjs';
|
|
22
|
+
import { ANTHROPIC_MAX_CONSECUTIVE_529 } from './retry-backoff.mjs';
|
|
22
23
|
import { PROVIDER_FIRST_BYTE_TIMEOUT_MS, createTimeoutSignal } from '../stall-policy.mjs';
|
|
23
|
-
import { noteFastModeCapacityError } from './anthropic-fast-mode.mjs';
|
|
24
|
+
import { fastModeDowngraded, noteFastModeCapacityError } from './anthropic-fast-mode.mjs';
|
|
25
|
+
import { adjustMaxTokensForContextOverflow } from './anthropic-max-tokens-recovery.mjs';
|
|
26
|
+
import { applyAnthropicErrorContract, retryAfterMsFromHeaders } from './anthropic-error-contract.mjs';
|
|
24
27
|
import { noteRequestServiceTier } from '../../../shared/llm/usage-context.mjs';
|
|
25
28
|
import { notifyCurrentAnthropicRateLimit } from './admission-scheduler.mjs';
|
|
26
29
|
|
|
@@ -78,12 +81,61 @@ export function armFirstByteWatchdog(streamController, midState) {
|
|
|
78
81
|
* @param {object} deps.params the streaming request body (mutated on fast-pool de-latch)
|
|
79
82
|
* @param {object|null} deps.requestHeaders per-call beta/extra headers
|
|
80
83
|
* @param {AbortSignal|null} deps.totalSignal session-lifetime pass-through
|
|
84
|
+
* @param {{ state: { consecutive529Errors: number } }|null} [deps.overload] the send's shared overload counter
|
|
81
85
|
*/
|
|
82
|
-
export function createAnthropicApiTransport({
|
|
86
|
+
export function createAnthropicApiTransport({
|
|
87
|
+
client,
|
|
88
|
+
label,
|
|
89
|
+
opts,
|
|
90
|
+
useModel,
|
|
91
|
+
params,
|
|
92
|
+
requestHeaders,
|
|
93
|
+
totalSignal,
|
|
94
|
+
overload = null,
|
|
95
|
+
}) {
|
|
83
96
|
const requestOptions = (attemptSignal) => ({
|
|
84
97
|
signal: attemptSignal,
|
|
85
98
|
...(requestHeaders ? { headers: requestHeaders } : {}),
|
|
86
99
|
});
|
|
100
|
+
// The SDK throws a non-2xx before `.asResponse()` resolves, so an HTTP
|
|
101
|
+
// failure arrives as an APIError rather than a Response. Stamp the
|
|
102
|
+
// provider-boundary error contract on it (status, lowercased error type as
|
|
103
|
+
// `code`, preserved headers, uncapped retryAfterMs / resetAt).
|
|
104
|
+
const annotateHttpFailure = (err) => {
|
|
105
|
+
if (err && typeof err === 'object' && Number(err.status || err.httpStatus || 0) > 0) {
|
|
106
|
+
applyAnthropicErrorContract(err, { status: err.status || err.httpStatus, headers: err.headers });
|
|
107
|
+
}
|
|
108
|
+
return err;
|
|
109
|
+
};
|
|
110
|
+
// A fast-pool refusal (or a "Fast mode is not enabled" 400) says nothing
|
|
111
|
+
// about standard-speed capacity: drop `speed` and let the caller replay at
|
|
112
|
+
// once instead of waiting out a window that only the fast pool owns.
|
|
113
|
+
const dropFastSpeedAfter = (body, err) => {
|
|
114
|
+
if (body.speed !== 'fast') return false;
|
|
115
|
+
if (!fastModeDowngraded(noteFastModeCapacityError(err, { fast: true }))) return false;
|
|
116
|
+
delete body.speed;
|
|
117
|
+
return true;
|
|
118
|
+
};
|
|
119
|
+
// In-attempt body repairs, each replayed once: drop speed after a fast-pool
|
|
120
|
+
// refusal, and shrink max_tokens after the "input length and max_tokens
|
|
121
|
+
// exceed context limit" 400.
|
|
122
|
+
const withBodyRecovery = (body, attempt) => async (ctx) => {
|
|
123
|
+
let speedDropped = false;
|
|
124
|
+
let tokensAdjusted = false;
|
|
125
|
+
for (;;) {
|
|
126
|
+
try {
|
|
127
|
+
return await attempt(ctx);
|
|
128
|
+
} catch (err) {
|
|
129
|
+
if (!speedDropped && dropFastSpeedAfter(body, err)) {
|
|
130
|
+
speedDropped = true;
|
|
131
|
+
} else if (!tokensAdjusted && adjustMaxTokensForContextOverflow(body, err?.status, err?.message)) {
|
|
132
|
+
tokensAdjusted = true;
|
|
133
|
+
} else {
|
|
134
|
+
throw err;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
87
139
|
// Initial-response retry policy shared by the streaming request and the
|
|
88
140
|
// non-streaming fallback.
|
|
89
141
|
const retryPolicy = (signal, perAttemptLabel, recoveryOwner) => ({
|
|
@@ -95,23 +147,27 @@ export function createAnthropicApiTransport({ client, label, opts, useModel, par
|
|
|
95
147
|
perAttemptTimeoutMs: anthropicRequestTimeoutMs(),
|
|
96
148
|
perAttemptLabel,
|
|
97
149
|
provider: 'anthropic',
|
|
150
|
+
// This transport honors the positive x-should-retry override.
|
|
151
|
+
honorShouldRetryTrue: true,
|
|
98
152
|
recoveryOwner,
|
|
99
153
|
retry529: opts.retry529,
|
|
100
154
|
model: useModel,
|
|
101
155
|
fallbackModel: opts._fallbackTriggered ? undefined : opts.fallbackModel,
|
|
156
|
+
// One overload counter for the send: SSE overloads count toward the same
|
|
157
|
+
// limit as request-loop 529s.
|
|
158
|
+
overloadState: overload?.state,
|
|
159
|
+
overloadFallbackAfter: ANTHROPIC_MAX_CONSECUTIVE_529,
|
|
160
|
+
stopAfterRepeated529: overload?.stopAfterRepeated529 === true,
|
|
102
161
|
});
|
|
103
162
|
|
|
104
|
-
const requestStreamingResponse = () =>
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
163
|
+
const requestStreamingResponse = async () => {
|
|
164
|
+
const attempt = async ({ signal: attemptSignal }) => {
|
|
165
|
+
noteRequestServiceTier(params.speed);
|
|
166
|
+
try {
|
|
108
167
|
const res = await client.messages.create(params, requestOptions(attemptSignal)).asResponse();
|
|
109
168
|
if (!res.ok) {
|
|
110
169
|
const text = await res.text().catch(() => '');
|
|
111
170
|
const err = new Error(`Anthropic API ${res.status}: ${text.slice(0, 200)}`);
|
|
112
|
-
err.status = res.status;
|
|
113
|
-
err.httpStatus = res.status;
|
|
114
|
-
err.initialResponseError = true;
|
|
115
171
|
// Carry response headers so withRetry can honor a
|
|
116
172
|
// short Retry-After and upstream can read quota hints.
|
|
117
173
|
err.headers = res.headers;
|
|
@@ -120,48 +176,55 @@ export function createAnthropicApiTransport({ client, label, opts, useModel, par
|
|
|
120
176
|
// output/tool exposure, so the request-local
|
|
121
177
|
// withRetry loop may retry it with jitter.
|
|
122
178
|
if (res.status === 429) {
|
|
123
|
-
const retryAfterMs = retryAfterMsFromError({
|
|
124
|
-
headers: res.headers,
|
|
125
|
-
response: { headers: res.headers },
|
|
126
|
-
});
|
|
127
179
|
err.name = 'ProviderQuotaError';
|
|
128
|
-
err.
|
|
129
|
-
err.retryAfterMs = retryAfterMs;
|
|
180
|
+
err.retryAfterMs = retryAfterMsFromHeaders(res.headers);
|
|
130
181
|
err.providerQuota = true;
|
|
131
182
|
err.quotaExceeded = true;
|
|
132
183
|
}
|
|
133
|
-
throw err;
|
|
184
|
+
throw applyAnthropicErrorContract(err, { status: res.status, headers: res.headers, bodyText: text });
|
|
134
185
|
}
|
|
135
186
|
if (!res.body) {
|
|
136
187
|
throw new Error('Anthropic streaming response has no body');
|
|
137
188
|
}
|
|
138
189
|
return res;
|
|
139
|
-
}
|
|
140
|
-
|
|
190
|
+
} catch (err) {
|
|
191
|
+
throw annotateHttpFailure(err);
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
try {
|
|
195
|
+
return await withRetry(withBodyRecovery(params, attempt), {
|
|
141
196
|
...retryPolicy(totalSignal, `${label} Anthropic streaming response`, `${label}-initial-response`),
|
|
142
|
-
onRetry: ({ attempt, maxAttempts, lastErr, delayMs, delayReason }) => {
|
|
143
|
-
emitProviderRetryStage(opts.onStageChange, { attempt:
|
|
144
|
-
// Long/unknown fast-pool window: replay at
|
|
145
|
-
// standard speed rather than waiting it out.
|
|
146
|
-
if (params?.speed === 'fast' && noteFastModeCapacityError(lastErr, { fast: true }) !== 'retry-fast') {
|
|
147
|
-
delete params.speed;
|
|
148
|
-
}
|
|
197
|
+
onRetry: ({ attempt: retryNo, maxAttempts, lastErr, delayMs, delayReason }) => {
|
|
198
|
+
emitProviderRetryStage(opts.onStageChange, { attempt: retryNo + 1, maxAttempts, lastErr, delayMs });
|
|
149
199
|
const status = Number(lastErr?.httpStatus || lastErr?.status || lastErr?.response?.status || 0);
|
|
150
200
|
if (status === 429) notifyCurrentAnthropicRateLimit(lastErr);
|
|
151
201
|
const delayLabel = retryDelayLabel(delayMs, delayReason);
|
|
152
202
|
process.stderr.write(
|
|
153
|
-
`[${label}] retry attempt ${
|
|
203
|
+
`[${label}] retry attempt ${retryNo + 1} after ${lastErr?.message || lastErr?.code || 'transient error'}${delayLabel}\n`
|
|
154
204
|
);
|
|
155
205
|
},
|
|
206
|
+
});
|
|
207
|
+
} catch (err) {
|
|
208
|
+
// Whatever escapes withRetry failed before any stream existed and has
|
|
209
|
+
// already spent the request-level budget: mark it so mid-stream
|
|
210
|
+
// recovery never grants it a second, SSE-sized retry budget.
|
|
211
|
+
if (err && typeof err === 'object' && !(err instanceof AnthropicFallbackTriggeredError)) {
|
|
212
|
+
err.initialResponseError = true;
|
|
156
213
|
}
|
|
157
|
-
|
|
214
|
+
throw err;
|
|
215
|
+
}
|
|
216
|
+
};
|
|
158
217
|
|
|
159
218
|
const requestNonStreamingMessage = (nonStreamingParams, signal) =>
|
|
160
219
|
withRetry(
|
|
161
|
-
async ({ signal: attemptSignal }) => {
|
|
220
|
+
withBodyRecovery(nonStreamingParams, async ({ signal: attemptSignal }) => {
|
|
162
221
|
noteRequestServiceTier(nonStreamingParams.speed);
|
|
163
|
-
|
|
164
|
-
|
|
222
|
+
try {
|
|
223
|
+
return await client.messages.create(nonStreamingParams, requestOptions(attemptSignal));
|
|
224
|
+
} catch (err) {
|
|
225
|
+
throw annotateHttpFailure(err);
|
|
226
|
+
}
|
|
227
|
+
}),
|
|
165
228
|
{
|
|
166
229
|
...retryPolicy(signal, `${label} Anthropic non-streaming fallback`, `${label}-nonstreaming-request`),
|
|
167
230
|
onRetry: ({ attempt, maxAttempts, lastErr, delayMs }) =>
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* anthropic-error-contract.mjs — the fields every error thrown at an Anthropic
|
|
3
|
+
* provider boundary carries, so the shared core never has to re-derive them
|
|
4
|
+
* from message text:
|
|
5
|
+
*
|
|
6
|
+
* status / httpStatus the HTTP status
|
|
7
|
+
* code the lowercased Anthropic error type (`rate_limit_error`,
|
|
8
|
+
* `overloaded_error`, ...); a 413 is always
|
|
9
|
+
* `request_too_large` (a byte/media size refusal), which
|
|
10
|
+
* stays distinct from a 400 `invalid_request_error`
|
|
11
|
+
* "prompt is too long" (a token-count refusal)
|
|
12
|
+
* headers the response headers, preserved as received
|
|
13
|
+
* retryAfterMs the server's Retry-After / retry-after-ms window, uncapped
|
|
14
|
+
* resetAt epoch ms of anthropic-ratelimit-unified-reset, uncapped
|
|
15
|
+
*/
|
|
16
|
+
import { headerValue, retryAfterMsFromError } from './retry-classification.mjs';
|
|
17
|
+
|
|
18
|
+
const RESET_HEADER = 'anthropic-ratelimit-unified-reset';
|
|
19
|
+
const REQUEST_TOO_LARGE = 'request_too_large';
|
|
20
|
+
|
|
21
|
+
// Anthropic's documented error-type enumeration by status, used only when the
|
|
22
|
+
// body names no type of its own.
|
|
23
|
+
const STATUS_ERROR_TYPE = new Map([
|
|
24
|
+
[400, 'invalid_request_error'],
|
|
25
|
+
[401, 'authentication_error'],
|
|
26
|
+
[403, 'permission_error'],
|
|
27
|
+
[404, 'not_found_error'],
|
|
28
|
+
[409, 'conflict_error'],
|
|
29
|
+
[413, REQUEST_TOO_LARGE],
|
|
30
|
+
[429, 'rate_limit_error'],
|
|
31
|
+
[500, 'api_error'],
|
|
32
|
+
[504, 'timeout_error'],
|
|
33
|
+
[529, 'overloaded_error'],
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
const BODY_TYPE_RE = /"error"\s*:\s*\{\s*"type"\s*:\s*"([A-Za-z_]+)"/;
|
|
37
|
+
|
|
38
|
+
function present(value) {
|
|
39
|
+
return value != null && value !== '';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function lowered(value) {
|
|
43
|
+
return typeof value === 'string' && value.trim() && value.trim() !== 'error' ? value.trim().toLowerCase() : '';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** The lowercased error type named by an Anthropic error body (JSON text or parsed object). */
|
|
47
|
+
export function anthropicErrorTypeFromBody(body) {
|
|
48
|
+
if (body && typeof body === 'object') return lowered((body.error && body.error.type) || body.type);
|
|
49
|
+
const match = BODY_TYPE_RE.exec(String(body || ''));
|
|
50
|
+
return match ? lowered(match[1]) : '';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Retry-After / retry-after-ms in ms, uncapped; null when the server sent neither. */
|
|
54
|
+
export function retryAfterMsFromHeaders(headers) {
|
|
55
|
+
if (!present(headerValue(headers, 'retry-after-ms')) && !present(headerValue(headers, 'retry-after'))) return null;
|
|
56
|
+
return retryAfterMsFromError({ headers });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Epoch ms of the unified rate-limit reset header, uncapped; null when absent or past. */
|
|
60
|
+
export function resetAtFromHeaders(headers) {
|
|
61
|
+
const raw = headerValue(headers, RESET_HEADER);
|
|
62
|
+
if (!present(raw)) return null;
|
|
63
|
+
const seconds = Number(raw);
|
|
64
|
+
return Number.isFinite(seconds) && seconds > 0 ? Math.ceil(seconds * 1000) : null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Stamp the contract onto `err`. Existing `headers` and a finite
|
|
69
|
+
* `retryAfterMs` are preserved. `type` is the wire error type when the caller
|
|
70
|
+
* already parsed one; otherwise it is read from `bodyText` (or err.error, the
|
|
71
|
+
* SDK's parsed body, or err.message) and finally from the status.
|
|
72
|
+
*/
|
|
73
|
+
export function applyAnthropicErrorContract(err, { status, headers, type = '', bodyText = '' } = {}) {
|
|
74
|
+
if (!err || typeof err !== 'object') return err;
|
|
75
|
+
const httpStatus = Number(status || err.httpStatus || err.status || 0) || 0;
|
|
76
|
+
if (httpStatus) {
|
|
77
|
+
err.status = httpStatus;
|
|
78
|
+
err.httpStatus = httpStatus;
|
|
79
|
+
const wireType =
|
|
80
|
+
lowered(type) ||
|
|
81
|
+
anthropicErrorTypeFromBody(bodyText) ||
|
|
82
|
+
anthropicErrorTypeFromBody(err.error) ||
|
|
83
|
+
anthropicErrorTypeFromBody(err.message) ||
|
|
84
|
+
STATUS_ERROR_TYPE.get(httpStatus) ||
|
|
85
|
+
'';
|
|
86
|
+
const code = httpStatus === 413 ? REQUEST_TOO_LARGE : wireType;
|
|
87
|
+
if (code) err.code = code;
|
|
88
|
+
}
|
|
89
|
+
if (!err.headers && headers) err.headers = headers;
|
|
90
|
+
const effectiveHeaders = err.headers || headers || null;
|
|
91
|
+
if (!(err.retryAfterMs != null && Number.isFinite(Number(err.retryAfterMs)))) {
|
|
92
|
+
const retryAfterMs = retryAfterMsFromHeaders(effectiveHeaders);
|
|
93
|
+
if (retryAfterMs != null) err.retryAfterMs = retryAfterMs;
|
|
94
|
+
}
|
|
95
|
+
const resetAt = resetAtFromHeaders(effectiveHeaders);
|
|
96
|
+
if (resetAt != null) err.resetAt = resetAt;
|
|
97
|
+
return err;
|
|
98
|
+
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// cache, because the retry after the wait carries a different speed anyway.
|
|
7
7
|
// The reference client's rule: a SHORT server window is worth waiting for at
|
|
8
8
|
// fast speed (the cache prefix survives), anything longer drops to standard
|
|
9
|
-
// speed for a cooldown. An explicit "overage billing unavailable" header is
|
|
9
|
+
// speed for a cooldown (reference thresholds: <20s keeps fast; otherwise\n// max(Retry-After ?? 30min, 10min)). An explicit "overage billing unavailable" header is
|
|
10
10
|
// terminal for the process — no cooldown can make paid overage appear.
|
|
11
11
|
//
|
|
12
12
|
// State is process-wide because the capacity pool is per-account, not per
|
|
@@ -14,23 +14,28 @@
|
|
|
14
14
|
// sessions hammering it.
|
|
15
15
|
|
|
16
16
|
import { headerValue } from './retry-classification.mjs';
|
|
17
|
+
import { retryAfterMsFromHeaders } from './anthropic-error-contract.mjs';
|
|
17
18
|
|
|
18
19
|
// Server-declared reason header for a fast-mode rejection caused by missing
|
|
19
20
|
// overage billing (matches the reference client's header name).
|
|
20
21
|
const OVERAGE_DISABLED_HEADER = 'anthropic-ratelimit-unified-overage-disabled-reason';
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
const
|
|
22
|
+
// Reasons that mean the wallet is empty / capped for now rather than that
|
|
23
|
+
// overage can never exist: the request drops to standard speed, but fast mode
|
|
24
|
+
// is not switched off (the reference client keeps its setting for these).
|
|
25
|
+
const TRANSIENT_OVERAGE_REASONS = new Set(['org_level_disabled_until', 'out_of_credits']);
|
|
26
|
+
// A 400 from an account/endpoint that cannot serve fast mode at all. The same
|
|
27
|
+
// request succeeds at standard speed, and no cooldown makes it succeed fast.
|
|
28
|
+
const NOT_ENABLED_PATTERN = /fast mode is not enabled/i;
|
|
29
|
+
const NOT_ENABLED_REASON = 'fast_mode_not_enabled';
|
|
25
30
|
|
|
26
31
|
// A Retry-After under this bound is short enough that waiting keeps fast mode
|
|
27
32
|
// (and its cache prefix) worthwhile.
|
|
28
|
-
const SHORT_RETRY_THRESHOLD_MS =
|
|
33
|
+
const SHORT_RETRY_THRESHOLD_MS = 20_000;
|
|
29
34
|
// Cooldown floor: without it a 1s window would flip fast mode on and off every
|
|
30
35
|
// turn, which costs more in cache misses than the downgrade saves.
|
|
31
|
-
const MIN_COOLDOWN_MS =
|
|
36
|
+
const MIN_COOLDOWN_MS = 600_000;
|
|
32
37
|
// Applied when the server gives no window at all.
|
|
33
|
-
const DEFAULT_COOLDOWN_MS =
|
|
38
|
+
const DEFAULT_COOLDOWN_MS = 1_800_000;
|
|
34
39
|
|
|
35
40
|
let _cooldownUntilMs = 0;
|
|
36
41
|
let _disabledReason = null;
|
|
@@ -62,23 +67,23 @@ export function fastModeDisabledReason() {
|
|
|
62
67
|
export function noteFastModeCapacityError(err, { fast = false, now = Date.now() } = {}) {
|
|
63
68
|
if (!fast) return 'ignored';
|
|
64
69
|
const status = Number(err?.httpStatus || err?.status || err?.response?.status || 0);
|
|
70
|
+
if (status === 400 && NOT_ENABLED_PATTERN.test(String(err?.message || ''))) {
|
|
71
|
+
_disabledReason = NOT_ENABLED_REASON;
|
|
72
|
+
return 'disabled';
|
|
73
|
+
}
|
|
65
74
|
if (status !== 429 && status !== 529) return 'ignored';
|
|
66
75
|
|
|
67
76
|
const headers = err?.headers || err?.response?.headers || err?.data?.responseHeaders || null;
|
|
68
77
|
const overageReason = headerValue(headers, OVERAGE_DISABLED_HEADER);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return '
|
|
72
|
-
|
|
73
|
-
// Same terminal condition reported only in the error body: the account has
|
|
74
|
-
// no usage credits for fast mode, so no cooldown can make it succeed.
|
|
75
|
-
if (CREDITS_REQUIRED_PATTERN.test(String(err?.message || ''))) {
|
|
76
|
-
_disabledReason = CREDITS_REQUIRED_REASON;
|
|
78
|
+
// The header's presence (even empty) is the signal, as in the reference client.
|
|
79
|
+
if (overageReason != null) {
|
|
80
|
+
if (TRANSIENT_OVERAGE_REASONS.has(String(overageReason))) return 'downgrade';
|
|
81
|
+
_disabledReason = String(overageReason) || 'overage_unavailable';
|
|
77
82
|
return 'disabled';
|
|
78
83
|
}
|
|
79
84
|
|
|
80
|
-
const retryAfterMs =
|
|
81
|
-
const hasWindow =
|
|
85
|
+
const retryAfterMs = serverWindowMs(err);
|
|
86
|
+
const hasWindow = retryAfterMs != null;
|
|
82
87
|
if (hasWindow && retryAfterMs < SHORT_RETRY_THRESHOLD_MS) return 'retry-fast';
|
|
83
88
|
|
|
84
89
|
const cooldownMs = Math.max(hasWindow ? retryAfterMs : DEFAULT_COOLDOWN_MS, MIN_COOLDOWN_MS);
|
|
@@ -86,6 +91,22 @@ export function noteFastModeCapacityError(err, { fast = false, now = Date.now()
|
|
|
86
91
|
return 'downgrade';
|
|
87
92
|
}
|
|
88
93
|
|
|
94
|
+
/** True when the decision means the caller must drop `speed` before replaying. */
|
|
95
|
+
export function fastModeDowngraded(decision) {
|
|
96
|
+
return decision === 'downgrade' || decision === 'disabled';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// The server's Retry-After window: an explicit err.retryAfterMs, else the
|
|
100
|
+
// Retry-After headers. The unified-reset header is deliberately not a window
|
|
101
|
+
// here (the reference client reads Retry-After only). null when none.
|
|
102
|
+
function serverWindowMs(err) {
|
|
103
|
+
const explicit = err?.retryAfterMs;
|
|
104
|
+
if (explicit != null && explicit !== '' && Number.isFinite(Number(explicit)) && Number(explicit) >= 0) {
|
|
105
|
+
return Number(explicit);
|
|
106
|
+
}
|
|
107
|
+
return retryAfterMsFromHeaders(err?.headers || err?.response?.headers || err?.data?.responseHeaders || null);
|
|
108
|
+
}
|
|
109
|
+
|
|
89
110
|
/** Manual re-enable (user action) and test seam. */
|
|
90
111
|
export function clearFastModeCooldown() {
|
|
91
112
|
_cooldownUntilMs = 0;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* anthropic-max-tokens-recovery.mjs — the two max_tokens adjustments the
|
|
3
|
+
* reference client makes (withRetry.ts / claude.ts):
|
|
4
|
+
*
|
|
5
|
+
* - a 400 "input length and `max_tokens` exceed context limit: A + B > C" is
|
|
6
|
+
* answered by shrinking max_tokens to what the context still has room for
|
|
7
|
+
* (1000-token safety buffer, 3000-token floor, thinking budget + 1 minimum)
|
|
8
|
+
* and replaying; with less than the floor available the error surfaces.
|
|
9
|
+
* - the non-streaming replay caps max_tokens at 64000 (the API's long-request
|
|
10
|
+
* boundary) and keeps thinking.budget_tokens below it.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export const FLOOR_OUTPUT_TOKENS = 3000;
|
|
14
|
+
export const CONTEXT_SAFETY_BUFFER_TOKENS = 1000;
|
|
15
|
+
export const MAX_NON_STREAMING_TOKENS = 64_000;
|
|
16
|
+
|
|
17
|
+
const OVERFLOW_RE = /input length and `max_tokens` exceed context limit: (\d+) \+ (\d+) > (\d+)/;
|
|
18
|
+
|
|
19
|
+
/** `{ inputTokens, maxTokens, contextLimit }` for the exact 400, else null. */
|
|
20
|
+
export function parseMaxTokensContextOverflow(status, message) {
|
|
21
|
+
if (Number(status) !== 400) return null;
|
|
22
|
+
const match = OVERFLOW_RE.exec(String(message || ''));
|
|
23
|
+
if (!match) return null;
|
|
24
|
+
const [inputTokens, maxTokens, contextLimit] = match.slice(1).map((value) => Number.parseInt(value, 10));
|
|
25
|
+
return [inputTokens, maxTokens, contextLimit].every(Number.isFinite) ? { inputTokens, maxTokens, contextLimit } : null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const thinkingBudget = (body) =>
|
|
29
|
+
body?.thinking?.type === 'enabled' && Number(body.thinking.budget_tokens) > 0 ? Number(body.thinking.budget_tokens) : 0;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Shrink `body.max_tokens` to fit the reported context. Returns true when the
|
|
33
|
+
* body was adjusted and is worth replaying.
|
|
34
|
+
*/
|
|
35
|
+
export function adjustMaxTokensForContextOverflow(body, status, message) {
|
|
36
|
+
const overflow = parseMaxTokensContextOverflow(status, message);
|
|
37
|
+
if (!overflow || !body) return false;
|
|
38
|
+
const available = Math.max(0, overflow.contextLimit - overflow.inputTokens - CONTEXT_SAFETY_BUFFER_TOKENS);
|
|
39
|
+
if (available < FLOOR_OUTPUT_TOKENS) return false;
|
|
40
|
+
body.max_tokens = Math.max(FLOOR_OUTPUT_TOKENS, available, thinkingBudget(body) + 1);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Cap a non-streaming body in place (max_tokens and the thinking budget). */
|
|
45
|
+
export function capForNonStreaming(body) {
|
|
46
|
+
if (!body || !(Number(body.max_tokens) > MAX_NON_STREAMING_TOKENS)) return body;
|
|
47
|
+
body.max_tokens = MAX_NON_STREAMING_TOKENS;
|
|
48
|
+
if (thinkingBudget(body)) {
|
|
49
|
+
body.thinking = {
|
|
50
|
+
...body.thinking,
|
|
51
|
+
budget_tokens: Math.min(body.thinking.budget_tokens, MAX_NON_STREAMING_TOKENS - 1),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return body;
|
|
55
|
+
}
|
|
@@ -4,29 +4,21 @@
|
|
|
4
4
|
//
|
|
5
5
|
// Resolution order:
|
|
6
6
|
// 1. MIXDOG_ANTHROPIC_MAX_OUTPUT_TOKENS env override, if set to a positive
|
|
7
|
-
// int, wins
|
|
7
|
+
// int, wins, capped by the known model maximum when there is one.
|
|
8
8
|
// 2. Catalog outputTokens for the model id (trusted over hardcoded
|
|
9
9
|
// heuristics when present — the API reports real per-model limits),
|
|
10
|
-
// clamped to
|
|
11
|
-
// 3.
|
|
12
|
-
//
|
|
10
|
+
// clamped to safetyCap (never raised: a declared limit is a ceiling).
|
|
11
|
+
// 3. The shared model catalog's outputTokens for the model (cached roster /
|
|
12
|
+
// LiteLLM / models.dev), same clamp.
|
|
13
|
+
// 4. The pre-catalog family limits for a model no catalog describes, else
|
|
14
|
+
// the floor.
|
|
15
|
+
|
|
16
|
+
import { getModelMetadataSync } from './model-catalog.mjs';
|
|
13
17
|
|
|
14
18
|
const MAX_TOKENS_FLOOR = 8192;
|
|
15
19
|
const DEFAULT_SAFETY_CAP = 65536;
|
|
16
20
|
const ENV_VAR = 'MIXDOG_ANTHROPIC_MAX_OUTPUT_TOKENS';
|
|
17
21
|
|
|
18
|
-
// Per-model max_tokens when the model id is explicitly listed. New models
|
|
19
|
-
// (e.g., Sonnet 4.7) won't match a specific entry and fall through to the
|
|
20
|
-
// family-based heuristic below. Conservative defaults — model may support
|
|
21
|
-
// more but we'd rather stay within safe bounds.
|
|
22
|
-
const MAX_TOKENS = {
|
|
23
|
-
'claude-opus-4-8': 65536,
|
|
24
|
-
'claude-opus-4-7': 65536,
|
|
25
|
-
'claude-opus-4-6': 65536,
|
|
26
|
-
'claude-sonnet-4-6': 16384,
|
|
27
|
-
'claude-haiku-4-5-20251001': 8192,
|
|
28
|
-
};
|
|
29
|
-
|
|
30
22
|
// Strict-positive env override parsing. Invalid values ("0", negatives,
|
|
31
23
|
// garbage, whitespace) are treated as UNSET — not as "use the default cap
|
|
32
24
|
// outright" — so catalog/fallback still decide for low-cap models. Raw env
|
|
@@ -39,11 +31,18 @@ function envAnthropicMaxOutputOverride() {
|
|
|
39
31
|
return Math.floor(n);
|
|
40
32
|
}
|
|
41
33
|
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
|
|
34
|
+
// Last resort when no catalog describes the model: the limits known before
|
|
35
|
+
// the catalogs existed. Sonnet 5+ ships a much larger output budget than the
|
|
36
|
+
// legacy 4.x line (16384 starved visible output once extended thinking ate
|
|
37
|
+
// into the same hard cap). Unknown families stay at the floor.
|
|
38
|
+
const MAX_TOKENS = {
|
|
39
|
+
'claude-opus-4-8': 65536,
|
|
40
|
+
'claude-opus-4-7': 65536,
|
|
41
|
+
'claude-opus-4-6': 65536,
|
|
42
|
+
'claude-sonnet-4-6': 16384,
|
|
43
|
+
'claude-haiku-4-5-20251001': 8192,
|
|
44
|
+
};
|
|
45
|
+
|
|
47
46
|
function fallbackAnthropicMaxTokens(model) {
|
|
48
47
|
if (MAX_TOKENS[model]) return MAX_TOKENS[model];
|
|
49
48
|
const id = String(model || '').toLowerCase();
|
|
@@ -52,27 +51,39 @@ function fallbackAnthropicMaxTokens(model) {
|
|
|
52
51
|
const sonnetVersion = id.match(/^claude-sonnet-(\d+)/);
|
|
53
52
|
if (sonnetVersion) return Number(sonnetVersion[1]) >= 5 ? 65536 : 16384;
|
|
54
53
|
if (id.includes('sonnet')) return 16384;
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
return MAX_TOKENS_FLOOR;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function sharedCatalogOutputTokens(model) {
|
|
58
|
+
const declared = Number(getModelMetadataSync(String(model || ''), 'anthropic')?.outputTokens);
|
|
59
|
+
return Number.isFinite(declared) && declared > 0 ? declared : null;
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
// catalogLookup(model) -> number|null. Providers supply their own strategy
|
|
60
63
|
// for sourcing the catalog array (in-memory mirror + disk fallback for OAuth,
|
|
61
64
|
// plain disk read for the API-key twin — see anthropic.mjs).
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
//
|
|
66
|
+
// `modelMaxOutputTokens` (number|null): a gateway-supplied model limit. When
|
|
67
|
+
// positive it takes precedence over every catalog lookup. A declared model
|
|
68
|
+
// maximum is a ceiling: it is never raised to the floor, and the env override
|
|
69
|
+
// is capped by it.
|
|
70
|
+
export function resolveAnthropicMaxTokens(model, { catalogLookup, modelMaxOutputTokens = null } = {}) {
|
|
71
|
+
const isLimit = (value) => Number.isFinite(value) && value > 0;
|
|
72
|
+
let declared = Number(modelMaxOutputTokens);
|
|
73
|
+
if (!isLimit(declared)) {
|
|
74
|
+
declared = null;
|
|
75
|
+
if (typeof catalogLookup === 'function') {
|
|
76
|
+
try {
|
|
77
|
+
declared = catalogLookup(model);
|
|
78
|
+
} catch {
|
|
79
|
+
declared = null;
|
|
80
|
+
}
|
|
72
81
|
}
|
|
82
|
+
if (!isLimit(declared)) declared = sharedCatalogOutputTokens(model);
|
|
73
83
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return Math.min(
|
|
84
|
+
declared = isLimit(declared) ? Math.floor(declared) : null;
|
|
85
|
+
const envOverride = envAnthropicMaxOutputOverride();
|
|
86
|
+
if (envOverride != null) return declared == null ? envOverride : Math.min(envOverride, declared);
|
|
87
|
+
if (declared != null) return Math.min(declared, DEFAULT_SAFETY_CAP);
|
|
88
|
+
return Math.min(fallbackAnthropicMaxTokens(model), DEFAULT_SAFETY_CAP);
|
|
78
89
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Anthropic model catalog + message conversion helpers.
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { effortValuesForModel } from './anthropic-effort.mjs';
|
|
3
|
+
import { effortValuesForModel, thinkingTypesFromCapabilities } from './anthropic-effort.mjs';
|
|
4
4
|
import { makeModelCache } from './model-cache.mjs';
|
|
5
5
|
import { resolveAnthropicMaxTokens } from './anthropic-max-tokens.mjs';
|
|
6
6
|
import {
|
|
@@ -73,6 +73,7 @@ export function _normalizeAnthropicModel(raw, provider = 'anthropic') {
|
|
|
73
73
|
const dated = /-\d{8}$/.test(String(id));
|
|
74
74
|
const versioned = !dated && /^claude-[a-z]+-\d+(?:-\d+)?$/i.test(String(id));
|
|
75
75
|
const effortValues = effortValuesForModel(raw?.capabilities, id);
|
|
76
|
+
const thinkingTypes = thinkingTypesFromCapabilities(raw?.capabilities);
|
|
76
77
|
return {
|
|
77
78
|
id,
|
|
78
79
|
display: raw?.display_name || raw?.displayName || raw?.display || _prettyName(id, family),
|
|
@@ -90,6 +91,7 @@ export function _normalizeAnthropicModel(raw, provider = 'anthropic') {
|
|
|
90
91
|
latest: false,
|
|
91
92
|
supportsReasoning: effortValues.length > 0 || _capabilitySupported(raw?.capabilities?.thinking),
|
|
92
93
|
reasoningOptions: effortValues.length ? [{ type: 'effort', values: effortValues }] : [],
|
|
94
|
+
...(thinkingTypes ? { thinkingTypes } : {}),
|
|
93
95
|
};
|
|
94
96
|
}
|
|
95
97
|
// The API-key provider has no catalog cache of its own — it reads the same
|
|
@@ -129,8 +131,8 @@ function _catalogOutputTokensFromSharedCache(model) {
|
|
|
129
131
|
}
|
|
130
132
|
}
|
|
131
133
|
|
|
132
|
-
export function resolveMaxTokens(model) {
|
|
133
|
-
return resolveAnthropicMaxTokens(model, { catalogLookup: _catalogOutputTokensFromSharedCache });
|
|
134
|
+
export function resolveMaxTokens(model, { modelMaxOutputTokens = null } = {}) {
|
|
135
|
+
return resolveAnthropicMaxTokens(model, { catalogLookup: _catalogOutputTokensFromSharedCache, modelMaxOutputTokens });
|
|
134
136
|
}
|
|
135
137
|
|
|
136
138
|
// Test-only escape hatch for the provider contract scripts
|
|
@@ -142,11 +144,12 @@ export const _test = {
|
|
|
142
144
|
sanitizeInputSchema: (schema, toolName) => sanitizeAnthropicInputSchema(schema, toolName, 'anthropic'),
|
|
143
145
|
};
|
|
144
146
|
|
|
145
|
-
function deferredAnthropicTools(activeTools, messages, opts) {
|
|
146
|
-
return sharedDeferredAnthropicTools(activeTools, messages, opts,
|
|
147
|
+
function deferredAnthropicTools(activeTools, messages, opts, provider = 'anthropic') {
|
|
148
|
+
return sharedDeferredAnthropicTools(activeTools, messages, opts, provider);
|
|
147
149
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
+
// `provider`: the engine's name (a gateway Messages engine runs under its gateway's).
|
|
151
|
+
export function requestAnthropicTools(tools, messages, opts, provider = 'anthropic') {
|
|
152
|
+
return sharedRequestAnthropicTools(tools, messages, opts, provider);
|
|
150
153
|
}
|
|
151
154
|
// Test-only: expose the lowering so the steering-provenance test can assert
|
|
152
155
|
// the API-key provider keeps steering-tagged user turns distinct (mirrors
|