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
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
* Anthropic "effort" (extended-thinking budget) request parameter handling.
|
|
3
3
|
*/
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
CLAUDE_GENERATION_FLOOR,
|
|
6
|
+
claudeGenerationAtLeast,
|
|
6
7
|
emitsAnthropicProgressUpdates,
|
|
7
|
-
|
|
8
|
+
isAnthropicAdaptiveOnlyByGeneration,
|
|
8
9
|
normalizeClaudeModelId as normalizeModelId,
|
|
9
10
|
} from './anthropic-thinking-contract.mjs';
|
|
11
|
+
import { getModelMetadataSync } from './model-catalog.mjs';
|
|
10
12
|
|
|
11
13
|
const EFFORT_LEVELS = Object.freeze(['low', 'medium', 'high', 'xhigh', 'max']);
|
|
12
14
|
const THINKING_DISPLAYS = new Set(['summarized', 'omitted', 'updates']);
|
|
@@ -32,12 +34,47 @@ const CONTROL_EFFORT_KEYS = new Set(['supported', 'enabled', 'default']);
|
|
|
32
34
|
|
|
33
35
|
// ── Catalog-first capability index ───────────────────────────────────────
|
|
34
36
|
// The provider catalog already carries what each model advertises
|
|
35
|
-
// (capabilities.effort → reasoningOptions:[{type:'effort',values:[…]}]
|
|
36
|
-
//
|
|
37
|
-
// the
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
|
|
37
|
+
// (capabilities.effort → reasoningOptions:[{type:'effort',values:[…]}],
|
|
38
|
+
// capabilities.thinking.types → thinkingTypes), so it — not an id ladder — is
|
|
39
|
+
// the source of truth for what we put on the wire. Order for one model:
|
|
40
|
+
// 1. the live-roster index below (anthropic-model-resolve feeds it whenever
|
|
41
|
+
// the in-memory catalog moves),
|
|
42
|
+
// 2. the shared model catalog (cached roster / LiteLLM / models.dev),
|
|
43
|
+
// 3. a release-generation floor (anthropic-thinking-contract) for an id no
|
|
44
|
+
// catalog describes — a new release inherits it, no per-id entry.
|
|
45
|
+
const _catalogEntries = new Map();
|
|
46
|
+
|
|
47
|
+
/** `{adaptive?:boolean, enabled?:boolean}` a live /v1/models row declares under
|
|
48
|
+
* capabilities.thinking.types, or undefined when it declares neither. */
|
|
49
|
+
export function thinkingTypesFromCapabilities(capabilities) {
|
|
50
|
+
const types = capabilities?.thinking?.types;
|
|
51
|
+
if (!types || typeof types !== 'object') return undefined;
|
|
52
|
+
const out = {};
|
|
53
|
+
for (const key of ['adaptive', 'enabled']) {
|
|
54
|
+
const declared = types[key];
|
|
55
|
+
const supported = typeof declared === 'boolean' ? declared : declared?.supported;
|
|
56
|
+
if (typeof supported === 'boolean') out[key] = supported;
|
|
57
|
+
}
|
|
58
|
+
return Object.keys(out).length ? out : undefined;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function _effortLevelsOf(reasoningOptions) {
|
|
62
|
+
const option = (Array.isArray(reasoningOptions) ? reasoningOptions : []).find(
|
|
63
|
+
(entry) =>
|
|
64
|
+
String(entry?.type || '')
|
|
65
|
+
.trim()
|
|
66
|
+
.toLowerCase() === 'effort'
|
|
67
|
+
);
|
|
68
|
+
return new Set(
|
|
69
|
+
(Array.isArray(option?.values) ? option.values : [])
|
|
70
|
+
.map((value) =>
|
|
71
|
+
String(value || '')
|
|
72
|
+
.trim()
|
|
73
|
+
.toLowerCase()
|
|
74
|
+
)
|
|
75
|
+
.filter((value) => value && !CONTROL_EFFORT_KEYS.has(value))
|
|
76
|
+
);
|
|
77
|
+
}
|
|
41
78
|
|
|
42
79
|
function _catalogKeys(model) {
|
|
43
80
|
const id = normalizeModelId(model);
|
|
@@ -55,7 +92,7 @@ function _catalogKeys(model) {
|
|
|
55
92
|
* lists carry no capability data and must not disable effort.
|
|
56
93
|
*/
|
|
57
94
|
export function setModelEffortCapabilities(models) {
|
|
58
|
-
|
|
95
|
+
_catalogEntries.clear();
|
|
59
96
|
if (!Array.isArray(models)) return;
|
|
60
97
|
for (const model of models) {
|
|
61
98
|
if (!model?.id || !Array.isArray(model.reasoningOptions)) continue;
|
|
@@ -63,37 +100,82 @@ export function setModelEffortCapabilities(models) {
|
|
|
63
100
|
// (custom-reasoning.mjs); a same-id custom model must never reshape the
|
|
64
101
|
// first-party index.
|
|
65
102
|
if (String(model.provider || '').startsWith('custom-')) continue;
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
.trim()
|
|
70
|
-
.toLowerCase() === 'effort'
|
|
71
|
-
);
|
|
72
|
-
const levels = new Set(
|
|
73
|
-
(Array.isArray(option?.values) ? option.values : [])
|
|
74
|
-
.map((value) =>
|
|
75
|
-
String(value || '')
|
|
76
|
-
.trim()
|
|
77
|
-
.toLowerCase()
|
|
78
|
-
)
|
|
79
|
-
.filter((value) => value && !CONTROL_EFFORT_KEYS.has(value))
|
|
80
|
-
);
|
|
103
|
+
const levels = _effortLevelsOf(model.reasoningOptions);
|
|
104
|
+
const manual = typeof model.thinkingTypes?.enabled === 'boolean' ? model.thinkingTypes.enabled : undefined;
|
|
105
|
+
const adaptive = typeof model.thinkingTypes?.adaptive === 'boolean' ? model.thinkingTypes.adaptive : undefined;
|
|
81
106
|
for (const key of _catalogKeys(model.id)) {
|
|
82
|
-
const existing =
|
|
107
|
+
const existing = _catalogEntries.get(key);
|
|
83
108
|
// A bare alias shared by several records keeps the richer entry.
|
|
84
|
-
if (existing?.size && levels.size === 0) continue;
|
|
85
|
-
|
|
109
|
+
if (existing?.levels.size && levels.size === 0) continue;
|
|
110
|
+
_catalogEntries.set(key, { levels, manual, adaptive });
|
|
86
111
|
}
|
|
87
112
|
}
|
|
88
113
|
}
|
|
89
114
|
|
|
90
|
-
|
|
91
|
-
|
|
115
|
+
// Shared-catalog tier (cached roster rows, LiteLLM, models.dev) for an id the
|
|
116
|
+
// live index does not hold. Only an actual effort ladder counts; silence
|
|
117
|
+
// returns null so the generation floor decides.
|
|
118
|
+
function _sharedCatalogEntry(model) {
|
|
119
|
+
const id = normalizeModelId(model);
|
|
120
|
+
if (!id) return null;
|
|
121
|
+
const levels = _effortLevelsOf(getModelMetadataSync(id, 'anthropic')?.reasoningOptions);
|
|
122
|
+
return levels.size ? { levels, manual: undefined, adaptive: undefined } : null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** `{levels: Set, manual?: boolean, adaptive?: boolean}` for `model`, or null when no catalog describes it. */
|
|
126
|
+
function _catalogEntry(model) {
|
|
92
127
|
for (const key of _catalogKeys(model)) {
|
|
93
|
-
const
|
|
94
|
-
if (
|
|
128
|
+
const entry = _catalogEntries.get(key);
|
|
129
|
+
if (entry) return entry;
|
|
130
|
+
}
|
|
131
|
+
return _sharedCatalogEntry(model);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Advertised levels for `model`, or null when the catalog has no ladder for it. */
|
|
135
|
+
function _catalogLevels(model) {
|
|
136
|
+
return _catalogEntry(model)?.levels ?? null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* True when the model's thinking contract rejects a manual
|
|
141
|
+
* `thinking:{type:"enabled",budget_tokens}` request: the catalog's declared
|
|
142
|
+
* thinking types decide, the release-generation floor covers an undescribed id.
|
|
143
|
+
*/
|
|
144
|
+
export function isAnthropicAdaptiveOnlyModel(model) {
|
|
145
|
+
const manual = _catalogEntry(model)?.manual;
|
|
146
|
+
return typeof manual === 'boolean' ? !manual : isAnthropicAdaptiveOnlyByGeneration(model);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// The thinking type is resolved apart from the effort ladder: a catalog can
|
|
150
|
+
// advertise effort levels for a model that still takes the manual budget shape
|
|
151
|
+
// (effort is not adaptive-thinking support). A declared `adaptive` flag decides;
|
|
152
|
+
// otherwise the release-generation floor does, whatever ladder the catalog holds.
|
|
153
|
+
function _usesAdaptiveThinking(model) {
|
|
154
|
+
if (isEnvTruthy(process.env.MIXDOG_ANTHROPIC_ALWAYS_ENABLE_EFFORT)) return true;
|
|
155
|
+
const adaptive = _catalogEntry(model)?.adaptive;
|
|
156
|
+
return typeof adaptive === 'boolean' ? adaptive : _floorSupportsEffort(model);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function assertAnthropicManualBudgetSupported(model) {
|
|
160
|
+
if (isAnthropicAdaptiveOnlyModel(model)) {
|
|
161
|
+
throw new TypeError(`${model} does not support thinkingBudgetTokens; use effort with adaptive thinking instead.`);
|
|
95
162
|
}
|
|
96
|
-
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Effort levels the wire builder sends unchanged for `model` (reserved `max`
|
|
167
|
+
* excluded), from the same capability gates normalizeAnthropicEffortInput and
|
|
168
|
+
* applyAnthropicEffortToBody use: catalog record first, generation floor for
|
|
169
|
+
* an absent record. A model without effort support, or whose catalog record
|
|
170
|
+
* declares none, accepts none.
|
|
171
|
+
*/
|
|
172
|
+
export function anthropicEffortLevelsFor(model) {
|
|
173
|
+
// Only the adaptive path sends output_config effort; a manual-thinking model
|
|
174
|
+
// takes none, whatever ladder a catalog holds for it.
|
|
175
|
+
if (!modelSupportsEffort(model) || !_usesAdaptiveThinking(model)) return [];
|
|
176
|
+
const levels = ['low', 'medium', 'high'];
|
|
177
|
+
if (modelSupportsXhighEffort(model)) levels.push('xhigh');
|
|
178
|
+
return levels;
|
|
97
179
|
}
|
|
98
180
|
|
|
99
181
|
export const EFFORT_BETA_HEADER = 'effort-2025-11-24';
|
|
@@ -109,121 +191,41 @@ const _LOGGED_EFFORT_NORMALIZATION = new Set();
|
|
|
109
191
|
const _LOGGED_UNKNOWN_EFFORT = new Set();
|
|
110
192
|
const MAX_LOGGED_UNKNOWN_EFFORTS = 100;
|
|
111
193
|
|
|
112
|
-
function parseClaudeVersion(model) {
|
|
113
|
-
const m = normalizeModelId(model);
|
|
114
|
-
const triple = m.match(/^claude-(haiku|sonnet|opus|fable)-(\d+)-(\d+)/);
|
|
115
|
-
if (triple) {
|
|
116
|
-
return { family: triple[1], major: Number(triple[2]), minor: Number(triple[3]) };
|
|
117
|
-
}
|
|
118
|
-
// Bare version ids carry family + major only (claude-opus-5). opus/haiku
|
|
119
|
-
// were missing here, so `claude-opus-5` parsed to null and fell through
|
|
120
|
-
// every capability check as an unknown shape.
|
|
121
|
-
const pair = m.match(/^claude-(sonnet|fable|opus|haiku)-(\d+)(?:$|[-@])/);
|
|
122
|
-
if (pair) {
|
|
123
|
-
return { family: pair[1], major: Number(pair[2]), minor: null };
|
|
124
|
-
}
|
|
125
|
-
// Legacy naming: version comes BEFORE the family (claude-3-7-sonnet,
|
|
126
|
-
// claude-3-5-sonnet, claude-3-opus). These are manual-thinking models —
|
|
127
|
-
// parse them so isLegacyAnthropicReasoningModel excludes them instead of
|
|
128
|
-
// letting modelSupportsEffort's `startsWith('claude-')` fallthrough grant
|
|
129
|
-
// them adaptive thinking + the effort beta (a hard 400).
|
|
130
|
-
const legacy = m.match(/^claude-(\d+)-(\d+)-(haiku|sonnet|opus)/);
|
|
131
|
-
if (legacy) {
|
|
132
|
-
return { family: legacy[3], major: Number(legacy[1]), minor: Number(legacy[2]) };
|
|
133
|
-
}
|
|
134
|
-
return null;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function isLegacyAnthropicReasoningModel(model) {
|
|
138
|
-
const parsed = parseClaudeVersion(model);
|
|
139
|
-
if (!parsed) return false;
|
|
140
|
-
if (parsed.family === 'haiku') return true;
|
|
141
|
-
if (parsed.family === 'fable') return false;
|
|
142
|
-
if (parsed.family === 'sonnet' || parsed.family === 'opus') {
|
|
143
|
-
if (parsed.major < 4) return true;
|
|
144
|
-
if (parsed.major === 4 && parsed.minor !== null && parsed.minor < 6) return true;
|
|
145
|
-
// Bare major, no minor (claude-opus-4 / claude-sonnet-4): adaptive
|
|
146
|
-
// effort only ships from 5 up, so 4.x aliases stay manual-thinking.
|
|
147
|
-
if (parsed.minor === null && parsed.major < 5) return true;
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
return false;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// @[MODEL LAUNCH]: extend allowlist when new Claude models ship with effort support.
|
|
154
194
|
export function modelSupportsEffort(model) {
|
|
155
195
|
if (isEnvTruthy(process.env.MIXDOG_ANTHROPIC_ALWAYS_ENABLE_EFFORT)) return true;
|
|
156
196
|
const advertised = _catalogLevels(model);
|
|
157
197
|
if (advertised) return advertised.size > 0;
|
|
158
|
-
return
|
|
198
|
+
return _floorSupportsEffort(model);
|
|
159
199
|
}
|
|
160
200
|
|
|
161
|
-
//
|
|
162
|
-
// effortValuesForModel, which BUILDS the catalog records and therefore must
|
|
163
|
-
// never consult the index it feeds.
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
if (isAnthropicAdaptiveOnlyModel(model)) return true;
|
|
169
|
-
if (m.includes('opus-4-6') || m.includes('sonnet-4-6')) return true;
|
|
170
|
-
if (m.includes('sonnet-5') || m.includes('fable-5')) return true;
|
|
171
|
-
if (/^claude-mythos-5-1(?:-\d{8})?$/.test(m)) return true;
|
|
172
|
-
if (/^claude-opus-4-(6|7|8)(?:$|[-@])/.test(m)) return true;
|
|
173
|
-
if (/^claude-opus-5(?:$|[-@])/.test(m)) return true;
|
|
174
|
-
// Fallthrough for not-yet-enumerated modern models: only grant effort when
|
|
175
|
-
// parseClaudeVersion resolves a family with major>=4 (and not a manual-
|
|
176
|
-
// thinking legacy already excluded above). A bare `startsWith('claude-')`
|
|
177
|
-
// here would hand thinking:adaptive + the effort beta to legacy/unknown
|
|
178
|
-
// IDs (e.g. claude-3-7-sonnet) → hard 400. Unknown-shape IDs (no version
|
|
179
|
-
// parsed) fall through to false: no effort, no adaptive thinking.
|
|
180
|
-
const parsed = parseClaudeVersion(model);
|
|
181
|
-
if (
|
|
182
|
-
parsed &&
|
|
183
|
-
(parsed.family === 'sonnet' || parsed.family === 'opus' || parsed.family === 'fable') &&
|
|
184
|
-
parsed.major >= 4
|
|
185
|
-
) {
|
|
186
|
-
return true;
|
|
187
|
-
}
|
|
188
|
-
return false;
|
|
201
|
+
// Generation-floor fallbacks for ids the catalog does not describe. Also used
|
|
202
|
+
// by effortValuesForModel, which BUILDS the catalog records and therefore must
|
|
203
|
+
// never consult the index it feeds. Legacy manual-thinking generations
|
|
204
|
+
// (claude-3-7-sonnet, claude-sonnet-4-5, claude-haiku-4-5) sit below the
|
|
205
|
+
// floor; non-claude ids have no generation and get nothing.
|
|
206
|
+
function _floorSupportsEffort(model) {
|
|
207
|
+
return claudeGenerationAtLeast(model, CLAUDE_GENERATION_FLOOR.adaptiveEffort);
|
|
189
208
|
}
|
|
190
209
|
|
|
191
|
-
// @[MODEL LAUNCH]: extend when new models support xhigh effort.
|
|
192
|
-
// Per platform.claude.com/docs/en/build-with-claude/effort — xhigh is
|
|
193
|
-
// supported by: Fable 5, Mythos 5, Opus 4.8, Opus 4.7, Sonnet 5.
|
|
194
|
-
// NOT Opus 4.6 / Sonnet 4.6 (those support max but not xhigh).
|
|
195
210
|
export function modelSupportsXhighEffort(model) {
|
|
196
211
|
const advertised = _catalogLevels(model);
|
|
197
212
|
if (advertised) return advertised.has('xhigh');
|
|
198
|
-
return
|
|
213
|
+
return _floorSupportsXhighEffort(model);
|
|
199
214
|
}
|
|
200
215
|
|
|
201
|
-
function
|
|
202
|
-
|
|
203
|
-
if (/^claude-opus-4-(7|8)(?:$|[-@])/.test(m)) return true;
|
|
204
|
-
if (/^claude-opus-5(?:$|[-@])/.test(m)) return true;
|
|
205
|
-
if (/^claude-sonnet-5(?:$|[-@])/.test(m)) return true;
|
|
206
|
-
if (/^claude-fable-5(?:$|[-@])/.test(m)) return true;
|
|
207
|
-
if (/^claude-mythos-5(?:$|[-@])/.test(m)) return true;
|
|
208
|
-
if (/^claude-mythos-preview(?:$|[-@])/.test(m)) return true;
|
|
209
|
-
return false;
|
|
216
|
+
function _floorSupportsXhighEffort(model) {
|
|
217
|
+
return claudeGenerationAtLeast(model, CLAUDE_GENERATION_FLOOR.xhighEffort);
|
|
210
218
|
}
|
|
211
219
|
|
|
212
|
-
// @[MODEL LAUNCH]: extend when new Opus models support max effort.
|
|
213
|
-
// Max list = xhigh list PLUS Opus 4.6, Sonnet 4.6, Opus 4.5.
|
|
214
220
|
export function modelSupportsMaxEffort(model) {
|
|
215
221
|
const advertised = _catalogLevels(model);
|
|
216
|
-
// xhigh support implies max support
|
|
222
|
+
// xhigh support implies max support.
|
|
217
223
|
if (advertised) return advertised.has('max') || advertised.has('xhigh');
|
|
218
|
-
return
|
|
224
|
+
return _floorSupportsMaxEffort(model);
|
|
219
225
|
}
|
|
220
226
|
|
|
221
|
-
function
|
|
222
|
-
|
|
223
|
-
const m = normalizeModelId(model);
|
|
224
|
-
if (/^claude-opus-4-(5|6)(?:$|[-@])/.test(m)) return true;
|
|
225
|
-
if (/^claude-sonnet-4-6(?:$|[-@])/.test(m)) return true;
|
|
226
|
-
return false;
|
|
227
|
+
function _floorSupportsMaxEffort(model) {
|
|
228
|
+
return claudeGenerationAtLeast(model, CLAUDE_GENERATION_FLOOR.maxEffort);
|
|
227
229
|
}
|
|
228
230
|
|
|
229
231
|
function isEnvTruthy(value) {
|
|
@@ -276,7 +278,8 @@ export function normalizeAnthropicEffortInput(raw, model, logTag = 'anthropic')
|
|
|
276
278
|
export function shouldIncludeEffortBeta(model, opts = {}) {
|
|
277
279
|
const thinkingBudgetTokens = Number(opts.thinkingBudgetTokens);
|
|
278
280
|
if (Number.isFinite(thinkingBudgetTokens) && thinkingBudgetTokens > 0) return false;
|
|
279
|
-
|
|
281
|
+
// Only requests that carry output_config effort (adaptive path) need the beta.
|
|
282
|
+
return modelSupportsEffort(model) && _usesAdaptiveThinking(model);
|
|
280
283
|
}
|
|
281
284
|
|
|
282
285
|
/**
|
|
@@ -300,7 +303,7 @@ export function applyAnthropicEffortToBody(
|
|
|
300
303
|
|
|
301
304
|
const normalized = normalizeAnthropicEffortInput(opts.effort, model, logTag);
|
|
302
305
|
|
|
303
|
-
if (modelSupportsEffort(model)) {
|
|
306
|
+
if (modelSupportsEffort(model) && _usesAdaptiveThinking(model)) {
|
|
304
307
|
if (normalized) {
|
|
305
308
|
const existing = body.output_config && typeof body.output_config === 'object' ? body.output_config : {};
|
|
306
309
|
body.output_config = { ...existing, effort: normalized };
|
|
@@ -372,10 +375,10 @@ export function effortValuesForModel(capabilities, modelId) {
|
|
|
372
375
|
// the model supports effort but doesn't enumerate levels, so derive the
|
|
373
376
|
// set from the known level ladder, gated by the top-tier model check.
|
|
374
377
|
let levels = [...EFFORT_LEVELS];
|
|
375
|
-
if (!
|
|
378
|
+
if (!_floorSupportsMaxEffort(modelId)) {
|
|
376
379
|
levels = levels.filter((level) => level !== 'max');
|
|
377
380
|
}
|
|
378
|
-
if (!
|
|
381
|
+
if (!_floorSupportsXhighEffort(modelId)) {
|
|
379
382
|
levels = levels.filter((level) => level !== 'xhigh');
|
|
380
383
|
}
|
|
381
384
|
return levels;
|
|
@@ -5,25 +5,61 @@ export function normalizeClaudeModelId(model) {
|
|
|
5
5
|
.replace(/\./g, '-');
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
// Version token after the family (claude-opus-4-8, claude-nova-9-1-20270101)
|
|
9
|
+
// or before it (claude-3-5-sonnet). Minor is one or two digits and never
|
|
10
|
+
// followed by another digit, so a release date (claude-opus-4-20250514) is
|
|
11
|
+
// not read as a minor version.
|
|
12
|
+
const FAMILY_FIRST_VERSION = /^claude-[a-z][a-z0-9]*-(\d+)(?:-(\d{1,2})(?!\d))?(?:[-@]|$)/;
|
|
13
|
+
const VERSION_FIRST_VERSION = /^claude-(\d+)(?:-(\d{1,2})(?!\d))?(?:[-@]|$)/;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Release generation of a Claude id as major*100 + minor (4.8 → 408), derived
|
|
17
|
+
* from the version token alone — no family names. A claude-* id without a
|
|
18
|
+
* version token is a not-yet-numbered release and ranks as the newest
|
|
19
|
+
* (Infinity); a non-claude id has no generation (null). A route prefix before
|
|
20
|
+
* the claude token (anthropic/claude-…, us.anthropic.claude-…) is skipped.
|
|
21
|
+
*/
|
|
22
|
+
export function claudeGeneration(model) {
|
|
23
|
+
const normalized = normalizeClaudeModelId(model);
|
|
24
|
+
const at = normalized.indexOf('claude-');
|
|
25
|
+
if (at < 0) return null;
|
|
26
|
+
const id = normalized.slice(at);
|
|
27
|
+
const m = id.match(FAMILY_FIRST_VERSION) || id.match(VERSION_FIRST_VERSION);
|
|
28
|
+
return m ? Number(m[1]) * 100 + Number(m[2] || 0) : Infinity;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Offline floors, used only for an id no catalog record describes. Each is the
|
|
32
|
+
// first generation whose documented API contract has the capability; later
|
|
33
|
+
// generations inherit it, so a new release needs no entry here.
|
|
34
|
+
export const CLAUDE_GENERATION_FLOOR = Object.freeze({
|
|
35
|
+
// adaptive thinking + output_config.effort
|
|
36
|
+
adaptiveEffort: 406,
|
|
37
|
+
// thinking:{type:"enabled",budget_tokens} is rejected from here on
|
|
38
|
+
manualThinkingRejected: 407,
|
|
39
|
+
// effort tier "xhigh"
|
|
40
|
+
xhighEffort: 407,
|
|
41
|
+
// effort tier "max"
|
|
42
|
+
maxEffort: 405,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
/** Generation at/above `floor`; ids with no generation (non-claude) never qualify. */
|
|
46
|
+
export function claudeGenerationAtLeast(model, floor) {
|
|
47
|
+
const generation = claudeGeneration(model);
|
|
48
|
+
return generation !== null && generation >= floor;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Offline classification for an id the catalog does not describe (catalog
|
|
52
|
+
// lookup lives in anthropic-effort.mjs: isAnthropicAdaptiveOnlyModel).
|
|
53
|
+
export function isAnthropicAdaptiveOnlyByGeneration(model) {
|
|
54
|
+
return claudeGenerationAtLeast(model, CLAUDE_GENERATION_FLOOR.manualThinkingRejected);
|
|
16
55
|
}
|
|
17
56
|
|
|
18
57
|
// Models that write their user-facing notes between tool calls (tool
|
|
19
58
|
// preambles) as progress-update thinking blocks instead of text blocks.
|
|
59
|
+
// Kept as an id list: no catalog field carries it, the display value rides a
|
|
60
|
+
// beta-gated parameter that other models reject (a wrong "yes" is a 400), and
|
|
61
|
+
// a wrong "no" only leaves preambles as text — so unknown ids stay off.
|
|
20
62
|
export function emitsAnthropicProgressUpdates(model) {
|
|
21
63
|
const id = normalizeClaudeModelId(model);
|
|
22
64
|
return /^claude-(?:opus-5-5|sonnet-5-5|fable-5-1|mythos-5-1|fable-5)(?:-\d{8})?$/.test(id);
|
|
23
65
|
}
|
|
24
|
-
|
|
25
|
-
export function assertAnthropicManualBudgetSupported(model) {
|
|
26
|
-
if (isAnthropicAdaptiveOnlyModel(model)) {
|
|
27
|
-
throw new TypeError(`${model} does not support thinkingBudgetTokens; use effort with adaptive thinking instead.`);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
} from './provider-catalog-cache.mjs';
|
|
30
30
|
import {
|
|
31
31
|
modelsDevProviderId,
|
|
32
|
+
firstPartyModelsDevIds,
|
|
32
33
|
providerCatalogEntry,
|
|
33
34
|
providerMetadataCorrection,
|
|
34
35
|
providerSeedRow,
|
|
@@ -60,35 +61,35 @@ const PRICING_CATALOG_RETRY_MS = 60_000;
|
|
|
60
61
|
// name, so a provider-keyed lookup can find nothing and the route silently
|
|
61
62
|
// prices at zero — indistinguishable from a genuinely free local model.
|
|
62
63
|
|
|
63
|
-
// Which vendor actually served a relayed model, read off the
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
[
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
function _relayedModelVendor(id) {
|
|
86
|
-
const model = String(id || '').toLowerCase();
|
|
87
|
-
if (!model) return null;
|
|
88
|
-
for (const [pattern, vendor] of _RELAYED_MODEL_VENDORS) {
|
|
89
|
-
if (pattern.test(model)) return vendor;
|
|
64
|
+
// Which vendor actually served a relayed model, read off the catalogs, in
|
|
65
|
+
// order of provenance that does not depend on catalog entry order:
|
|
66
|
+
// 1. the vendor LiteLLM lists the id under (fixed key order);
|
|
67
|
+
// 2. registered first-party vendors that list it in models.dev (sorted);
|
|
68
|
+
// 3. an unregistered models.dev provider, only when it is the sole such
|
|
69
|
+
// candidate — aggregators list many vendors' SKUs, so when several
|
|
70
|
+
// disagree there is no provenance and nothing is borrowed.
|
|
71
|
+
// Only a guess: its row fills capabilities and the effort ladder the route's
|
|
72
|
+
// own sources left undeclared, and prices a model only when the
|
|
73
|
+
// provider-keyed lookup found no rates, so a route with real catalog coverage
|
|
74
|
+
// is never repriced by it. A model no catalog lists has no vendor row to
|
|
75
|
+
// lend, so there is nothing to guess and no id pattern is used.
|
|
76
|
+
function _relayedModelVendors(id, catalog, modelsDevCatalog) {
|
|
77
|
+
// A vendor serves its own models: a relay or a user-defined provider listed
|
|
78
|
+
// in a catalog is never the vendor (and resolving it would guess again).
|
|
79
|
+
const isVendor = (vendor) =>
|
|
80
|
+
Boolean(vendor) && !String(vendor).startsWith('custom-') && !providerCatalogEntry(vendor)?.relay;
|
|
81
|
+
const vendors = new Set();
|
|
82
|
+
for (const key of [id, ..._CATALOG_SIMPLE_PREFIXES.map((prefix) => prefix + id)]) {
|
|
83
|
+
const vendor = modelsDevProviderId(catalog?.[key]?.litellm_provider);
|
|
84
|
+
if (isVendor(vendor)) vendors.add(vendor);
|
|
90
85
|
}
|
|
91
|
-
|
|
86
|
+
const firstParty = new Set(firstPartyModelsDevIds());
|
|
87
|
+
for (const vendor of firstParty) if (modelsDevCatalog?.[vendor]?.models?.[id]) vendors.add(vendor);
|
|
88
|
+
const unregistered = Object.entries(modelsDevCatalog || {})
|
|
89
|
+
.filter(([vendor, entry]) => entry?.models?.[id] && !firstParty.has(vendor) && isVendor(vendor))
|
|
90
|
+
.map(([vendor]) => vendor);
|
|
91
|
+
if (unregistered.length === 1) vendors.add(unregistered[0]);
|
|
92
|
+
return vendors;
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
// Provider prefix variants used by the shared catalog resolver.
|
|
@@ -523,10 +524,15 @@ const effortEntry = (options) => (Array.isArray(options) ? options.find((o) => o
|
|
|
523
524
|
// A vendor row is a first guess for a route it does not describe (relay,
|
|
524
525
|
// same-vendor other endpoint, custom provider): it fills only the capabilities
|
|
525
526
|
// and effort ladder the route's own sources left undeclared. Never limits.
|
|
526
|
-
|
|
527
|
+
// A relay serves the model through its own hosted tools, so the serving
|
|
528
|
+
// vendor's web-search flag says nothing about the relay endpoint.
|
|
529
|
+
function withVendorGuess(meta, guess, { ladder = true, relay = false } = {}) {
|
|
527
530
|
if (!guess) return meta;
|
|
528
531
|
const out = { ...(meta || _normalize({})) };
|
|
529
|
-
for (const key of GUESSED_FLAGS)
|
|
532
|
+
for (const key of GUESSED_FLAGS) {
|
|
533
|
+
if (relay && key === 'supportsWebSearch') continue;
|
|
534
|
+
out[key] ??= guess[key];
|
|
535
|
+
}
|
|
530
536
|
const effort = effortEntry(guess.reasoningOptions);
|
|
531
537
|
if (ladder && effort && out.supportsReasoning !== false && !effortEntry(out.reasoningOptions)) {
|
|
532
538
|
out.reasoningOptions = [...(out.reasoningOptions || []), effort];
|
|
@@ -602,11 +608,16 @@ function catalogMetadata(id, mappedProvider, catalog, modelsDevCatalog) {
|
|
|
602
608
|
|
|
603
609
|
// The row of the vendor serving a relayed or custom model id (no vendor: a
|
|
604
610
|
// bare-id catalog lookup).
|
|
605
|
-
function servingVendorMetadata(id,
|
|
606
|
-
//
|
|
607
|
-
//
|
|
608
|
-
const
|
|
609
|
-
|
|
611
|
+
function servingVendorMetadata(id, catalog, modelsDevCatalog) {
|
|
612
|
+
// Some vendors spell versions with hyphens (claude-opus-5-5) where relays
|
|
613
|
+
// list the same SKU with dots (claude-opus-5.5); the catalog decides which.
|
|
614
|
+
for (const candidate of new Set([id, id.replace(/(\d)\.(\d)/g, '$1-$2')])) {
|
|
615
|
+
for (const vendor of _relayedModelVendors(candidate, catalog, modelsDevCatalog)) {
|
|
616
|
+
const row = lookupModelMetadata(candidate, vendor, catalog, modelsDevCatalog);
|
|
617
|
+
if (row) return row;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
return null;
|
|
610
621
|
}
|
|
611
622
|
|
|
612
623
|
// Both list enrichment and synchronous accounting use this exact resolver;
|
|
@@ -631,9 +642,9 @@ function lookupModelMetadata(originalId, provider, catalog, modelsDevCatalog, li
|
|
|
631
642
|
const correction = source ? providerMetadataCorrection(provider, id) : null;
|
|
632
643
|
if (meta && correction) meta = { ...meta, ...correction };
|
|
633
644
|
let guess = null;
|
|
634
|
-
const
|
|
645
|
+
const relayGuess = source?.relay ? servingVendorMetadata(id, catalog, modelsDevCatalog) : null;
|
|
635
646
|
if (custom) guess = customVendorMetadata(originalId, catalog, modelsDevCatalog);
|
|
636
|
-
else if (
|
|
647
|
+
else if (relayGuess) guess = relayGuess;
|
|
637
648
|
else if (source && !source.sameEndpoint) guess = mapped;
|
|
638
649
|
if (source?.relay && !hasRates(meta) && hasRates(guess)) {
|
|
639
650
|
meta = meta ? { ...meta, ...pricingFields(guess) } : pricingOnly(guess);
|
|
@@ -686,7 +697,10 @@ function lookupModelMetadata(originalId, provider, catalog, modelsDevCatalog, li
|
|
|
686
697
|
const rosterLadders = [cached?.rawProviderModel, listedRow].filter(
|
|
687
698
|
(row) => Array.isArray(row?.reasoningLevels) || Array.isArray(row?.reasoningOptions)
|
|
688
699
|
);
|
|
689
|
-
meta = withVendorGuess(meta, guess, {
|
|
700
|
+
meta = withVendorGuess(meta, guess, {
|
|
701
|
+
ladder: !(source?.rosterLadderFinal && rosterLadders.length),
|
|
702
|
+
relay: Boolean(relayGuess),
|
|
703
|
+
});
|
|
690
704
|
return meta
|
|
691
705
|
? {
|
|
692
706
|
...meta,
|
|
@@ -706,8 +720,7 @@ function customVendorMetadata(originalId, catalog, modelsDevCatalog) {
|
|
|
706
720
|
const listedId = String(originalId || '');
|
|
707
721
|
for (const id of new Set([listedId, listedId.slice(listedId.lastIndexOf('/') + 1)])) {
|
|
708
722
|
if (!id) continue;
|
|
709
|
-
const
|
|
710
|
-
const guess = servingVendorMetadata(id, vendor, catalog, modelsDevCatalog);
|
|
723
|
+
const guess = servingVendorMetadata(id, catalog, modelsDevCatalog);
|
|
711
724
|
if (guess) return guess;
|
|
712
725
|
}
|
|
713
726
|
return null;
|
|
@@ -904,7 +917,6 @@ export function pricingCatalogRevisionSync() {
|
|
|
904
917
|
}
|
|
905
918
|
|
|
906
919
|
let lastAuditedRevision = null;
|
|
907
|
-
let lastAudit = null;
|
|
908
920
|
function auditCachedModelPricing() {
|
|
909
921
|
const revision = pricingCatalogRevisionSync();
|
|
910
922
|
const rows = Object.entries(cachedProviderModelListsSync()).flatMap(([provider, models]) =>
|
|
@@ -919,17 +931,6 @@ function auditCachedModelPricing() {
|
|
|
919
931
|
);
|
|
920
932
|
}
|
|
921
933
|
lastAuditedRevision = revision;
|
|
922
|
-
lastAudit = { revision, rows, unpriced };
|
|
923
|
-
return lastAudit;
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
/** Catalog routes without a complete list price, from the latest audit (run on demand when none is cached). */
|
|
927
|
-
export function unpricedModelsSync() {
|
|
928
|
-
return (lastAudit ?? auditCachedModelPricing()).unpriced.map(({ provider, model, missingRates }) => ({
|
|
929
|
-
provider,
|
|
930
|
-
model,
|
|
931
|
-
missingRates: [...missingRates],
|
|
932
|
-
}));
|
|
933
934
|
}
|
|
934
935
|
|
|
935
936
|
/**
|
|
@@ -13,17 +13,6 @@ export const DAYBREAK_OFF = 'off';
|
|
|
13
13
|
export const DAYBREAK_BLUE_PROGRAM = 'daybreak_blue';
|
|
14
14
|
const STANDARD_PROGRAM = 'standard';
|
|
15
15
|
|
|
16
|
-
// Static fallback, used ONLY when a catalog row carries no access-program
|
|
17
|
-
// list at all (an older cache or a catalog without the field). Any list the
|
|
18
|
-
// catalog does send — empty included — decides on its own.
|
|
19
|
-
const FALLBACK_DAYBREAK_BLUE_MODELS = new Set([
|
|
20
|
-
'gpt-6-sol',
|
|
21
|
-
'gpt-6-luna',
|
|
22
|
-
'gpt-5.6-sol',
|
|
23
|
-
'gpt-5.6-terra',
|
|
24
|
-
'gpt-5.6-luna',
|
|
25
|
-
]);
|
|
26
|
-
|
|
27
16
|
export const DAYBREAK_PARAMETER_OPTION = Object.freeze({
|
|
28
17
|
id: DAYBREAK_PARAMETER_ID,
|
|
29
18
|
label: 'Daybreak Blue',
|
|
@@ -43,13 +32,12 @@ export function catalogAccessPrograms(raw) {
|
|
|
43
32
|
}
|
|
44
33
|
|
|
45
34
|
/**
|
|
46
|
-
* Whether a model
|
|
47
|
-
*
|
|
35
|
+
* Whether a model accepts Blue: only when the catalog's access-program list
|
|
36
|
+
* for it names the program. A row with no list (or a bare id) is not offered
|
|
37
|
+
* the toggle; the server's catalog is the only source of this entitlement.
|
|
48
38
|
*/
|
|
49
39
|
export function daybreakBlueSupported(model) {
|
|
50
|
-
|
|
51
|
-
const id = clean(typeof model === 'string' ? model : model?.id).toLowerCase();
|
|
52
|
-
return FALLBACK_DAYBREAK_BLUE_MODELS.has(id);
|
|
40
|
+
return Array.isArray(model?.accessPrograms) && model.accessPrograms.includes(DAYBREAK_BLUE_PROGRAM);
|
|
53
41
|
}
|
|
54
42
|
|
|
55
43
|
/**
|