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
|
@@ -0,0 +1,96 @@
|
|
|
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
|
+
[413, REQUEST_TOO_LARGE],
|
|
29
|
+
[429, 'rate_limit_error'],
|
|
30
|
+
[500, 'api_error'],
|
|
31
|
+
[529, 'overloaded_error'],
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
const BODY_TYPE_RE = /"error"\s*:\s*\{\s*"type"\s*:\s*"([A-Za-z_]+)"/;
|
|
35
|
+
|
|
36
|
+
function present(value) {
|
|
37
|
+
return value != null && value !== '';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function lowered(value) {
|
|
41
|
+
return typeof value === 'string' && value.trim() && value.trim() !== 'error' ? value.trim().toLowerCase() : '';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** The lowercased error type named by an Anthropic error body (JSON text or parsed object). */
|
|
45
|
+
export function anthropicErrorTypeFromBody(body) {
|
|
46
|
+
if (body && typeof body === 'object') return lowered((body.error && body.error.type) || body.type);
|
|
47
|
+
const match = BODY_TYPE_RE.exec(String(body || ''));
|
|
48
|
+
return match ? lowered(match[1]) : '';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Retry-After / retry-after-ms in ms, uncapped; null when the server sent neither. */
|
|
52
|
+
export function retryAfterMsFromHeaders(headers) {
|
|
53
|
+
if (!present(headerValue(headers, 'retry-after-ms')) && !present(headerValue(headers, 'retry-after'))) return null;
|
|
54
|
+
return retryAfterMsFromError({ headers });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Epoch ms of the unified rate-limit reset header, uncapped; null when absent or past. */
|
|
58
|
+
export function resetAtFromHeaders(headers) {
|
|
59
|
+
const raw = headerValue(headers, RESET_HEADER);
|
|
60
|
+
if (!present(raw)) return null;
|
|
61
|
+
const seconds = Number(raw);
|
|
62
|
+
return Number.isFinite(seconds) && seconds > 0 ? Math.ceil(seconds * 1000) : null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Stamp the contract onto `err`. Existing `headers` and a finite
|
|
67
|
+
* `retryAfterMs` are preserved. `type` is the wire error type when the caller
|
|
68
|
+
* already parsed one; otherwise it is read from `bodyText` (or err.error, the
|
|
69
|
+
* SDK's parsed body, or err.message) and finally from the status.
|
|
70
|
+
*/
|
|
71
|
+
export function applyAnthropicErrorContract(err, { status, headers, type = '', bodyText = '' } = {}) {
|
|
72
|
+
if (!err || typeof err !== 'object') return err;
|
|
73
|
+
const httpStatus = Number(status || err.httpStatus || err.status || 0) || 0;
|
|
74
|
+
if (httpStatus) {
|
|
75
|
+
err.status = httpStatus;
|
|
76
|
+
err.httpStatus = httpStatus;
|
|
77
|
+
const wireType =
|
|
78
|
+
lowered(type) ||
|
|
79
|
+
anthropicErrorTypeFromBody(bodyText) ||
|
|
80
|
+
anthropicErrorTypeFromBody(err.error) ||
|
|
81
|
+
anthropicErrorTypeFromBody(err.message) ||
|
|
82
|
+
STATUS_ERROR_TYPE.get(httpStatus) ||
|
|
83
|
+
'';
|
|
84
|
+
const code = httpStatus === 413 ? REQUEST_TOO_LARGE : wireType;
|
|
85
|
+
if (code) err.code = code;
|
|
86
|
+
}
|
|
87
|
+
if (!err.headers && headers) err.headers = headers;
|
|
88
|
+
const effectiveHeaders = err.headers || headers || null;
|
|
89
|
+
if (!(err.retryAfterMs != null && Number.isFinite(Number(err.retryAfterMs)))) {
|
|
90
|
+
const retryAfterMs = retryAfterMsFromHeaders(effectiveHeaders);
|
|
91
|
+
if (retryAfterMs != null) err.retryAfterMs = retryAfterMs;
|
|
92
|
+
}
|
|
93
|
+
const resetAt = resetAtFromHeaders(effectiveHeaders);
|
|
94
|
+
if (resetAt != null) err.resetAt = resetAt;
|
|
95
|
+
return err;
|
|
96
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -8,25 +8,17 @@
|
|
|
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
10
|
// clamped to [MAX_TOKENS_FLOOR, safetyCap].
|
|
11
|
-
// 3.
|
|
12
|
-
//
|
|
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,8 +51,12 @@ 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
|
|
@@ -71,6 +74,7 @@ export function resolveAnthropicMaxTokens(model, { catalogLookup } = {}) {
|
|
|
71
74
|
catalogValue = null;
|
|
72
75
|
}
|
|
73
76
|
}
|
|
77
|
+
if (!(Number.isFinite(catalogValue) && catalogValue > 0)) catalogValue = sharedCatalogOutputTokens(model);
|
|
74
78
|
if (Number.isFinite(catalogValue) && catalogValue > 0) {
|
|
75
79
|
return Math.max(MAX_TOKENS_FLOOR, Math.min(catalogValue, safetyCap));
|
|
76
80
|
}
|
|
@@ -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
|
|
@@ -24,6 +24,8 @@ import {
|
|
|
24
24
|
} from './retry-classifier.mjs';
|
|
25
25
|
import { _classifyMidstreamError, _midstreamSleepWithAbort, stampAnthropicStreamOutcome } from './anthropic-sse.mjs';
|
|
26
26
|
import { notifyCurrentAnthropicRateLimit } from './admission-scheduler.mjs';
|
|
27
|
+
import { applyAnthropicErrorContract } from './anthropic-error-contract.mjs';
|
|
28
|
+
import { isAnthropicOverloadError } from './anthropic-overload-fallback.mjs';
|
|
27
29
|
import { noteAbandonedUsage } from '../../../shared/llm/usage-context.mjs';
|
|
28
30
|
|
|
29
31
|
export function createAnthropicMidState(attemptIndex) {
|
|
@@ -88,6 +90,8 @@ export function assertAnthropicStreamNotEmpty(midState, result, label) {
|
|
|
88
90
|
* @param {{ recoverNonStreaming: Function, issueNonStreamingFallback: Function, requireTransportRecoveryBudget: Function }} deps.recovery
|
|
89
91
|
* @param {Function|null} [deps.onStageChange] receives the display-only 'reconnecting' stage per retry
|
|
90
92
|
* @param {boolean} [deps.retry529] false for a background call: an overload mid-stream is not retried
|
|
93
|
+
* @param {ReturnType<typeof import('./anthropic-overload-fallback.mjs').createAnthropicOverloadTracker>|null} [deps.overload]
|
|
94
|
+
* the send's shared overload counter (SSE overloads feed it)
|
|
91
95
|
*/
|
|
92
96
|
export function createAnthropicMidstreamRecovery({
|
|
93
97
|
label,
|
|
@@ -101,6 +105,7 @@ export function createAnthropicMidstreamRecovery({
|
|
|
101
105
|
recovery,
|
|
102
106
|
onStageChange = null,
|
|
103
107
|
retry529 = true,
|
|
108
|
+
overload = null,
|
|
104
109
|
}) {
|
|
105
110
|
const log = (line) => {
|
|
106
111
|
try {
|
|
@@ -128,7 +133,7 @@ export function createAnthropicMidstreamRecovery({
|
|
|
128
133
|
firstAttemptClassifier = classifier;
|
|
129
134
|
abortStream(controller, err);
|
|
130
135
|
log(message);
|
|
131
|
-
const waitMs = delayMs ?? midstreamBackoffFor(attemptIndex + 1);
|
|
136
|
+
const waitMs = delayMs ?? midstreamBackoffFor(attemptIndex + 1, undefined, err);
|
|
132
137
|
emitProviderRetryStage(onStageChange, {
|
|
133
138
|
attempt: attemptIndex + 1,
|
|
134
139
|
maxAttempts: maxRetries,
|
|
@@ -192,6 +197,16 @@ export function createAnthropicMidstreamRecovery({
|
|
|
192
197
|
abortStream(controller, err);
|
|
193
198
|
throw err;
|
|
194
199
|
}
|
|
200
|
+
// An SSE overload counts toward the same limit as a request-loop 529; at
|
|
201
|
+
// the limit the configured fallback model takes over (the provider's
|
|
202
|
+
// send loop catches the trigger around this whole recovery).
|
|
203
|
+
if (overload && isAnthropicOverloadError(err)) {
|
|
204
|
+
const trigger = overload.noteStreamOverload(err);
|
|
205
|
+
if (trigger) {
|
|
206
|
+
abortStream(controller, err);
|
|
207
|
+
throw trigger;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
195
210
|
const canRetry = attemptIndex < maxRetries;
|
|
196
211
|
const attemptLabel = `${attemptIndex + 1}/${maxRetries}`;
|
|
197
212
|
// Empty/dropped stream (no message_start): safe to retry once —
|
|
@@ -270,10 +285,9 @@ export function createAnthropicMidstreamRecovery({
|
|
|
270
285
|
const status = Number(err?.httpStatus || err?.status || 0);
|
|
271
286
|
let retryDelayMs = null;
|
|
272
287
|
if (status === 429) {
|
|
273
|
-
if (!err.headers && response?.headers) err.headers = response.headers;
|
|
274
288
|
if (!err.response && response) err.response = { status, headers: response.headers };
|
|
289
|
+
applyAnthropicErrorContract(err, { status, headers: response?.headers });
|
|
275
290
|
retryDelayMs = retryAfterMsFromError(err);
|
|
276
|
-
if (retryDelayMs != null) err.retryAfterMs = retryDelayMs;
|
|
277
291
|
notifyCurrentAnthropicRateLimit(err);
|
|
278
292
|
}
|
|
279
293
|
try {
|
|
@@ -283,7 +297,7 @@ export function createAnthropicMidstreamRecovery({
|
|
|
283
297
|
log(`abort on stream error failed: ${abortErr?.message ?? String(abortErr)}`);
|
|
284
298
|
}
|
|
285
299
|
log(`mid-stream recovered: retry ${attemptLabel} (cause: ${classifier})`);
|
|
286
|
-
const waitMs = retryDelayMs ?? midstreamBackoffFor(attemptIndex + 1);
|
|
300
|
+
const waitMs = retryDelayMs ?? midstreamBackoffFor(attemptIndex + 1, undefined, err);
|
|
287
301
|
emitProviderRetryStage(onStageChange, {
|
|
288
302
|
attempt: attemptIndex + 1,
|
|
289
303
|
maxAttempts: maxRetries,
|
|
@@ -8,7 +8,12 @@
|
|
|
8
8
|
import { enrichModels } from './model-catalog.mjs';
|
|
9
9
|
import { sanitizeModelList } from './model-list-sanitize.mjs';
|
|
10
10
|
import { makeModelCache } from './model-cache.mjs';
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
effortValuesForModel,
|
|
13
|
+
setModelEffortCapabilities,
|
|
14
|
+
thinkingTypesFromCapabilities,
|
|
15
|
+
} from './anthropic-effort.mjs';
|
|
16
|
+
import { getModelMetadataSync } from './model-catalog.mjs';
|
|
12
17
|
|
|
13
18
|
// Disk-backed cache so repeated process starts (cron, tool calls) don't
|
|
14
19
|
// hammer /v1/models. 24h TTL matches the upstream client cadence.
|
|
@@ -85,6 +90,7 @@ export function _normalizeAnthropicModel(raw) {
|
|
|
85
90
|
const tier = modelTier(dated, versioned);
|
|
86
91
|
const releaseDate = dated ? id.match(/-(\d{4})(\d{2})(\d{2})$/) : null;
|
|
87
92
|
const effortValues = effortValuesForModel(raw?.capabilities, id);
|
|
93
|
+
const thinkingTypes = thinkingTypesFromCapabilities(raw?.capabilities);
|
|
88
94
|
return {
|
|
89
95
|
id,
|
|
90
96
|
display: raw?.display_name || _prettyName(id, family),
|
|
@@ -98,6 +104,7 @@ export function _normalizeAnthropicModel(raw) {
|
|
|
98
104
|
releaseDate: releaseDate ? `${releaseDate[1]}-${releaseDate[2]}-${releaseDate[3]}` : null,
|
|
99
105
|
supportsReasoning: effortValues.length > 0 || _capabilitySupported(raw?.capabilities?.thinking),
|
|
100
106
|
reasoningOptions: effortValues.length ? [{ type: 'effort', values: effortValues }] : [],
|
|
107
|
+
...(thinkingTypes ? { thinkingTypes } : {}),
|
|
101
108
|
};
|
|
102
109
|
}
|
|
103
110
|
|
|
@@ -115,7 +122,12 @@ export function _prettyName(id, family) {
|
|
|
115
122
|
return `${base} ${v[1]}${minor}`;
|
|
116
123
|
}
|
|
117
124
|
|
|
125
|
+
// Context window for a roster row that reports none: the shared model catalog
|
|
126
|
+
// (cached roster / LiteLLM / models.dev) first, else the pre-catalog family
|
|
127
|
+
// windows.
|
|
118
128
|
export function _defaultContextForModel(id) {
|
|
129
|
+
const declared = Number(getModelMetadataSync(id, 'anthropic')?.contextWindow);
|
|
130
|
+
if (Number.isFinite(declared) && declared > 0) return declared;
|
|
119
131
|
const text = String(id || '');
|
|
120
132
|
const version = text.match(/^claude-[a-z]+-(\d+)(?:-(\d+))?/i);
|
|
121
133
|
if (Number(version?.[1] || 0) >= 5) return 1000000;
|
|
@@ -10,7 +10,7 @@ import { createNpmVersionSource, maxSemver } from './npm-cli-version.mjs';
|
|
|
10
10
|
// source release just to advance the user-agent version.
|
|
11
11
|
// Claude Opus 5.5 requires 2.1.280 or newer. The release workflow raises this
|
|
12
12
|
// to the published CLI version (scripts/sync-client-version-floors.mjs).
|
|
13
|
-
export const DEFAULT_CLI_VERSION = '2.1.
|
|
13
|
+
export const DEFAULT_CLI_VERSION = '2.1.300';
|
|
14
14
|
export const CLAUDE_CLI_NPM_PACKAGE = '@anthropic-ai/claude-code';
|
|
15
15
|
|
|
16
16
|
const CACHE_SCHEMA_VERSION = 1;
|
|
@@ -21,8 +21,16 @@ export function createMidState(attemptIndex) {
|
|
|
21
21
|
* @param {ReturnType<import('./anthropic-oauth-recovery.mjs').createAnthropicOAuthRecovery>} deps.recovery
|
|
22
22
|
* @param {Function|null} [deps.onStageChange]
|
|
23
23
|
* @param {boolean} [deps.retry529]
|
|
24
|
+
* @param {object|null} [deps.overload] the send's shared overload counter
|
|
24
25
|
*/
|
|
25
|
-
export function createMidstreamRecovery({
|
|
26
|
+
export function createMidstreamRecovery({
|
|
27
|
+
maxRetries,
|
|
28
|
+
totalSignal,
|
|
29
|
+
recovery,
|
|
30
|
+
onStageChange = null,
|
|
31
|
+
retry529 = true,
|
|
32
|
+
overload = null,
|
|
33
|
+
}) {
|
|
26
34
|
return createAnthropicMidstreamRecovery({
|
|
27
35
|
label: 'anthropic-oauth',
|
|
28
36
|
outcomeProvider: 'anthropic-oauth',
|
|
@@ -33,5 +41,6 @@ export function createMidstreamRecovery({ maxRetries, totalSignal, recovery, onS
|
|
|
33
41
|
recovery,
|
|
34
42
|
onStageChange,
|
|
35
43
|
retry529,
|
|
44
|
+
overload,
|
|
36
45
|
});
|
|
37
46
|
}
|
|
@@ -8,7 +8,10 @@ import { PROVIDER_NONSTREAM_TOTAL_TIMEOUT_MS, createTimeoutSignal } from '../sta
|
|
|
8
8
|
import { AnthropicFallbackTriggeredError, markProviderRecoveryExhausted } from './retry-classifier.mjs';
|
|
9
9
|
import { cloneAnthropicEffortBody } from './effort-configuration.mjs';
|
|
10
10
|
import { normalizeAnthropicNonStreamingResponse } from './lib/anthropic-request-utils.mjs';
|
|
11
|
+
import { capForNonStreaming } from './anthropic-max-tokens-recovery.mjs';
|
|
11
12
|
import { createAnthropicRecoveryGuards } from './anthropic-recovery-guards.mjs';
|
|
13
|
+
import { applyAnthropicErrorContract } from './anthropic-error-contract.mjs';
|
|
14
|
+
import { isRefreshableAuthRejection } from './anthropic-oauth-request/initial-status.mjs';
|
|
12
15
|
|
|
13
16
|
/**
|
|
14
17
|
* @param {object} deps
|
|
@@ -70,7 +73,7 @@ export function createAnthropicOAuthRecovery({
|
|
|
70
73
|
const requestFallback = async (accessToken) => {
|
|
71
74
|
const result = await requestWithRetry(
|
|
72
75
|
accessToken,
|
|
73
|
-
cloneAnthropicEffortBody(body, { stream: false }),
|
|
76
|
+
capForNonStreaming(cloneAnthropicEffortBody(body, { stream: false })),
|
|
74
77
|
lifetime.signal
|
|
75
78
|
);
|
|
76
79
|
fallback = result;
|
|
@@ -89,19 +92,30 @@ export function createAnthropicOAuthRecovery({
|
|
|
89
92
|
};
|
|
90
93
|
try {
|
|
91
94
|
fallback = await requestFallback(auth.creds.accessToken);
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
// Same refresh rule as the streaming request: every 401 and only the
|
|
96
|
+
// exact revoked-token 403 are refreshed and replayed once; an ordinary
|
|
97
|
+
// 403 stays terminal. A rejected body is drained once and reused below.
|
|
98
|
+
let rejectedBody = null;
|
|
99
|
+
if (fallback.response.status === 401 || fallback.response.status === 403) {
|
|
100
|
+
rejectedBody = await fallback.response.text().catch(() => '');
|
|
101
|
+
if (isRefreshableAuthRejection(fallback.response.status, rejectedBody)) {
|
|
102
|
+
const rejectedStatus = fallback.response.status;
|
|
103
|
+
releaseFallback('Anthropic OAuth non-streaming fallback refreshing auth');
|
|
104
|
+
auth.creds = await provider.ensureAuth({ forceRefresh: true, reason: String(rejectedStatus) });
|
|
105
|
+
fallback = await requestFallback(auth.creds.accessToken);
|
|
106
|
+
rejectedBody = null;
|
|
107
|
+
}
|
|
96
108
|
}
|
|
97
109
|
if (!fallback.response.ok) {
|
|
98
|
-
const text = await fallback.response.text().catch(() => '');
|
|
110
|
+
const text = rejectedBody ?? (await fallback.response.text().catch(() => ''));
|
|
99
111
|
const fallbackError = new Error(
|
|
100
112
|
`Anthropic OAuth API ${fallback.response.status}: ${provider.scrubTokens(text).slice(0, 200)}`
|
|
101
113
|
);
|
|
102
|
-
fallbackError
|
|
103
|
-
|
|
104
|
-
|
|
114
|
+
throw applyAnthropicErrorContract(fallbackError, {
|
|
115
|
+
status: fallback.response.status,
|
|
116
|
+
headers: fallback.response.headers,
|
|
117
|
+
bodyText: provider.scrubTokens(text),
|
|
118
|
+
});
|
|
105
119
|
}
|
|
106
120
|
const message = await fallback.response.json();
|
|
107
121
|
return normalizeAnthropicNonStreamingResponse(message, useModel);
|