mixdog 1.1.2 → 1.2.1
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 +8 -5
- package/package.json +2 -1
- package/scripts/lib/run-node-tests.mjs +9 -0
- package/scripts/prune-desktop-runtime.mjs +3 -0
- package/scripts/test-direct.mjs +4 -2
- package/src/defaults/shipped-history.json +10 -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 +18 -5
- package/src/defaults/skills/visualize/SKILL.md +160 -0
- package/src/defaults/skills/visualize/references/craft.md +88 -0
- package/src/headless-command.mjs +56 -3
- package/src/headless-exec.mjs +17 -1
- package/src/help.mjs +2 -0
- 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-dispatch/preset.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +2 -0
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +26 -5
- package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
- package/src/runtime/agent/orchestrator/config-providers-merge.mjs +17 -11
- package/src/runtime/agent/orchestrator/config-storage.mjs +1 -0
- package/src/runtime/agent/orchestrator/config.mjs +19 -5
- 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 +133 -15
- package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +55 -8
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +86 -8
- package/src/runtime/agent/orchestrator/mcp/client.mjs +474 -164
- package/src/runtime/agent/orchestrator/mcp/lazy-output-validator.mjs +25 -0
- package/src/runtime/agent/orchestrator/mcp/plugin-placeholders.mjs +54 -0
- package/src/runtime/agent/orchestrator/mcp/reconnect-singleflight.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +108 -17
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +15 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +32 -12
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -0
- 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 +444 -0
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -4
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +21 -6
- package/src/runtime/agent/orchestrator/providers/effort-rejection.mjs +244 -0
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +41 -28
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/lib/gemini-model-catalog.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +8 -40
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +51 -12
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +37 -2
- package/src/runtime/agent/orchestrator/providers/model-proxy-bridge.mjs +1080 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +82 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +556 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +251 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +69 -102
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +15 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +6 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -1
- 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-xai-send.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +15 -4
- package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog-store.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/registry.mjs +47 -7
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +10 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +36 -3
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -11
- 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/model-capabilities.mjs +16 -1
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +278 -84
- 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/runtime-core/tool-defs.mjs +10 -3
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +9 -5
- package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +284 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +268 -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/execution-tail.mjs +10 -3
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +24 -13
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +362 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +253 -0
- 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/continuation.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/diagnostic.mjs +1 -7
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/refusal.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +7 -4
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +21 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +15 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +22 -12
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +9 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +9 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +37 -16
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +17 -4
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +90 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +22 -12
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +32 -3
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/message-ids.mjs +123 -0
- package/src/runtime/agent/orchestrator/session/message-ids.test-support.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +33 -22
- package/src/runtime/agent/orchestrator/session/store/listing.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +10 -3
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +11 -0
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +817 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +36 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +23 -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 +202 -374
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +20 -3
- 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 +48 -9
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +161 -0
- 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/cache-layers.mjs +52 -2
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +32 -22
- package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +10 -3
- 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-cache-policy.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +203 -33
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +32 -35
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-guards.mjs +8 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +11 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +9 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +83 -68
- package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +8 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +20 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +16 -7
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +137 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +11 -10
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +21 -11
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +12 -1
- 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/builtin/task-tool.mjs +56 -13
- package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +58 -0
- 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/code-graph/trusted-roots.mjs +25 -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/patch/ui-diff.mjs +78 -5
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -0
- package/src/runtime/attachments/store.d.mts +3 -0
- package/src/runtime/attachments/store.mjs +38 -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/session-ingest.mjs +2 -2
- package/src/runtime/shared/atomic-file.mjs +33 -6
- package/src/runtime/shared/best-effort-stderr.mjs +8 -0
- package/src/runtime/shared/code-graph-state.mjs +12 -0
- package/src/runtime/shared/defaults-separation.mjs +2 -0
- package/src/runtime/shared/extension-scopes.mjs +5 -3
- package/src/runtime/shared/file-lock.mjs +37 -11
- package/src/runtime/shared/git-runner-worker.mjs +3 -2
- package/src/runtime/shared/git-runner.mjs +4 -3
- package/src/runtime/shared/llm/anthropic-effort.mjs +14 -0
- package/src/runtime/shared/llm/default-context-window.mjs +6 -0
- package/src/runtime/shared/llm/model-catalog-projection.mjs +5 -4
- package/src/runtime/shared/llm/model-catalog.mjs +240 -130
- package/src/runtime/shared/llm/provider-catalog-cache.mjs +36 -28
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +162 -0
- package/src/runtime/shared/llm/provider-seed-rosters.mjs +130 -0
- package/src/runtime/shared/model-proxy-mode.d.mts +3 -0
- package/src/runtime/shared/model-proxy-mode.mjs +19 -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 +125 -21
- package/src/runtime/shared/provider-api-key.mjs +33 -1
- package/src/runtime/shared/schedule-model-ref.mjs +11 -2
- package/src/runtime/shared/session-usage-totals.mjs +19 -0
- package/src/runtime/shared/sharp-electron-linux.mjs +25 -0
- package/src/runtime/shared/shell-display.mjs +9 -3
- package/src/runtime/shared/singleton-owner.mjs +36 -6
- 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-segments.mjs +68 -14
- package/src/runtime/shared/tool-primitives.mjs +35 -2
- package/src/runtime/shared/tool-surface.mjs +7 -0
- package/src/runtime/shared/tool-work-units.mjs +14 -0
- package/src/runtime/shared/transcript-metadata.mjs +17 -1
- package/src/runtime/shared/turn-changes.mjs +791 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +346 -12
- package/src/runtime/shared/turn-snapshot.mjs +690 -81
- package/src/runtime/shared/turn-worktree-snapshot.mjs +185 -15
- package/src/runtime/shared/worker-requests.mjs +15 -2
- package/src/runtime/shared/worktrees/cache-cleanups.mjs +52 -0
- package/src/runtime/shared/worktrees/contract.mjs +551 -0
- package/src/runtime/shared/worktrees/disk.mjs +57 -0
- package/src/runtime/shared/worktrees/git.mjs +247 -0
- package/src/runtime/shared/worktrees/include.mjs +480 -0
- package/src/runtime/shared/worktrees/lock.mjs +46 -0
- package/src/runtime/shared/worktrees/maintenance.mjs +96 -0
- package/src/runtime/shared/worktrees/manager.mjs +1215 -0
- package/src/runtime/shared/worktrees/merge.mjs +182 -0
- package/src/runtime/shared/worktrees/owner.mjs +46 -0
- package/src/runtime/shared/worktrees/paths.mjs +62 -0
- package/src/runtime/shared/worktrees/registry.mjs +110 -0
- package/src/runtime/shared/worktrees/settings.mjs +84 -0
- package/src/runtime/shared/worktrees/slug.mjs +62 -0
- package/src/runtime/shared/worktrees/test-support.mjs +96 -0
- package/src/runtime/visualize-bridge/client.mjs +181 -0
- package/src/runtime/visualize-bridge/tool-defs.mjs +97 -0
- package/src/session-runtime/automation-agents.mjs +8 -2
- package/src/session-runtime/boot/apis.mjs +90 -0
- package/src/session-runtime/boot/config.mjs +7 -2
- package/src/session-runtime/boot/facade.mjs +21 -0
- package/src/session-runtime/boot/infrastructure.mjs +30 -18
- package/src/session-runtime/boot/session.mjs +1 -0
- package/src/session-runtime/boot/tools.mjs +4 -0
- package/src/session-runtime/config-lifecycle.mjs +10 -1
- 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 +21 -6
- package/src/session-runtime/cwd-plugins/plugin-status.mjs +47 -42
- package/src/session-runtime/global-extensions.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +27 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +32 -1
- package/src/session-runtime/internal-tool-executor.mjs +9 -1
- package/src/session-runtime/lifecycle/session-catalog.mjs +8 -1
- package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +5 -0
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +21 -3
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +16 -0
- package/src/session-runtime/mcp-glue/connect.mjs +68 -16
- package/src/session-runtime/mcp-glue/plugin-servers.mjs +499 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +122 -33
- package/src/session-runtime/mcp-glue/server-input.mjs +29 -0
- package/src/session-runtime/mcp-glue.mjs +22 -2
- package/src/session-runtime/model-route/route-persist.mjs +3 -0
- package/src/session-runtime/model-route/set-route.mjs +15 -2
- package/src/session-runtime/new-session-config.mjs +3 -2
- package/src/session-runtime/notification-bus.mjs +18 -3
- package/src/session-runtime/provider-auth/accounts.mjs +33 -15
- package/src/session-runtime/provider-models/row-hydration.mjs +2 -0
- 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/resource-extension-sync.mjs +45 -7
- package/src/session-runtime/resource-mcp-api.mjs +121 -84
- 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/route-resolution.mjs +10 -1
- package/src/session-runtime/route-state.mjs +16 -2
- package/src/session-runtime/runtime-core.mjs +5 -0
- package/src/session-runtime/runtime-facade.mjs +8 -0
- package/src/session-runtime/runtime-review-api.mjs +9 -0
- package/src/session-runtime/schedule-session-run.mjs +1 -1
- package/src/session-runtime/services/agent-tool/helpers.mjs +5 -0
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +3 -0
- package/src/session-runtime/services/agent-tool/job-views/job-lookup.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-views/spawn-meta.mjs +1 -0
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +15 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +1 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +10 -2
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -7
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +2 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -0
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +1 -0
- package/src/session-runtime/services/agent-tool.mjs +1 -0
- package/src/session-runtime/services/channel-session-router.mjs +4 -1
- package/src/session-runtime/services/daemon-candidate.mjs +3 -2
- package/src/session-runtime/services/daemon-crash-capture/spawn-capture.mjs +55 -0
- 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/session-create/session-options.mjs +10 -1
- package/src/session-runtime/session-turn-api.mjs +1 -0
- package/src/session-runtime/settings-api.mjs +4 -2
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -2
- package/src/session-runtime/settings-worktree-api.mjs +17 -0
- package/src/session-runtime/setup-tool/executor.mjs +23 -5
- package/src/session-runtime/setup-tool/extended-actions.mjs +1 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +4 -1
- package/src/session-runtime/setup-tool/tool-defs.mjs +38 -4
- package/src/session-runtime/skills-api.mjs +7 -3
- package/src/session-runtime/turn/agent-ops.mjs +12 -1
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +14 -3
- package/src/session-runtime/turn/turn-run/snapshot-tracker.mjs +20 -15
- package/src/session-runtime/turn/turn-run/turn-open.mjs +4 -5
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +29 -1
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +6 -1
- package/src/session-runtime/turn/turn-run.mjs +6 -7
- package/src/session-runtime/webhook-session-run.mjs +16 -4
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -3
- package/src/session-runtime/workspace/admission-gate.mjs +197 -0
- package/src/session-runtime/workspace/project-branches.mjs +136 -0
- package/src/session-runtime/workspace/transition-steps.mjs +364 -0
- package/src/session-runtime/workspace/transitions.mjs +651 -0
- package/src/session-runtime/workspace/workspace-state.mjs +112 -0
- package/src/skill-script-entry.mjs +36 -0
- package/src/standalone/channel-transport/http-routes.mjs +17 -0
- package/src/standalone/channel-transport.mjs +13 -1
- package/src/standalone/daemon-desktop-runtime.mjs +1 -0
- package/src/standalone/daemon-owner.mjs +372 -0
- package/src/standalone/daemon-stored-session-views.mjs +15 -4
- package/src/standalone/daemon.mjs +179 -8
- package/src/standalone/desktop-service-registry.mjs +20 -0
- package/src/standalone/local-session-runtime.mjs +11 -0
- package/src/standalone/session-client/attachment-calls.mjs +3 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +62 -0
- package/src/standalone/session-client/lease-heartbeat.mjs +47 -0
- package/src/standalone/session-client.mjs +104 -13
- package/src/standalone/session-protocol.mjs +21 -0
- package/src/standalone/session-proxy.mjs +3 -0
- package/src/standalone/session-service/agent-tree/agent-child.mjs +4 -0
- package/src/standalone/session-service/agent-tree/agent-rehydrate.mjs +1 -0
- package/src/standalone/session-service/entries/lifecycle.mjs +6 -0
- package/src/standalone/session-service/projection/revisions.mjs +2 -0
- package/src/standalone/session-service/projection/transcript-window.mjs +149 -19
- package/src/standalone/session-service/projection/workspace.mjs +14 -0
- package/src/standalone/session-service/session-calls/session-action.mjs +17 -4
- package/src/standalone/session-transport/call-route.mjs +13 -0
- package/src/standalone/session-transport/client-registry/client-grace.mjs +45 -3
- package/src/standalone/session-transport/client-registry/registration-replays.mjs +1 -0
- package/src/standalone/session-transport/client-registry.mjs +20 -3
- package/src/standalone/session-transport/routes.mjs +79 -2
- package/src/standalone/session-transport/stack.mjs +2 -0
- package/src/standalone/session-transport.mjs +24 -1
- 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 +6 -0
- package/src/tui/app/extension-pickers/plugins-pickers.mjs +35 -16
- package/src/tui/app/message-selector.mjs +2 -1
- package/src/tui/app/model-options.mjs +37 -5
- package/src/tui/app/model-picker/provider-models-list.mjs +2 -2
- package/src/tui/app/model-picker.mjs +4 -2
- package/src/tui/app/skill-mention-palette.mjs +88 -0
- 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/TranscriptItem.jsx +9 -1
- package/src/tui/components/prompt-input/key-handler.mjs +21 -8
- package/src/tui/components/user-message-skills.mjs +38 -0
- package/src/tui/dist/index.mjs +839 -207
- package/src/tui/index.jsx +10 -2
- package/src/tui/session/compaction-view.mjs +147 -0
- package/src/tui/session/context-state.mjs +6 -0
- package/src/tui/session/initial-state.mjs +3 -0
- package/src/tui/session/queue-helpers.mjs +7 -2
- package/src/tui/session/quota-resume.mjs +2 -1
- package/src/tui/session/session-api/commands.mjs +10 -2
- package/src/tui/session/session-api/controls.mjs +4 -0
- package/src/tui/session/session-api/extensions.mjs +4 -2
- package/src/tui/session/session-api/intake/rewind.mjs +2 -1
- package/src/tui/session/session-api/integrations.mjs +17 -0
- package/src/tui/session/session-api/lifecycle/dispose.mjs +6 -1
- package/src/tui/session/session-api/lifecycle/inheritance.mjs +2 -0
- package/src/tui/session/session-api/lifecycle/resume.mjs +3 -0
- package/src/tui/session/session-api/routes.mjs +10 -1
- package/src/tui/session/session-api/settings.mjs +9 -0
- package/src/tui/session/session-api/worktree.mjs +60 -0
- package/src/tui/session/session-api.mjs +2 -0
- package/src/tui/session/session-flow/auto-clear.mjs +31 -12
- package/src/tui/session/session-flow/drain.mjs +27 -3
- package/src/tui/session/session-flow/session-reset.mjs +4 -3
- package/src/tui/session/session-flow.mjs +2 -0
- package/src/tui/session/transcript-intake.mjs +14 -5
- package/src/tui/session/tui-steering-persist.mjs +25 -9
- package/src/tui/session/turn-stream.mjs +32 -4
- package/src/tui/session/turn-tool-cards.mjs +10 -2
- package/src/tui/session/turn.mjs +56 -10
- package/src/runtime/effort-judge/previous-human-request.mjs +0 -162
- package/src/runtime/effort-judge/verified-context-input.mjs +0 -10
|
@@ -20,12 +20,19 @@ import { createHash } from 'node:crypto';
|
|
|
20
20
|
import { resolvePluginData } from '../plugin-paths.mjs';
|
|
21
21
|
import { writeJsonAtomicSync } from '../atomic-file.mjs';
|
|
22
22
|
import {
|
|
23
|
+
capabilityFlag,
|
|
24
|
+
rosterRowMetadata,
|
|
23
25
|
providerCachedModelMetadataSync,
|
|
24
|
-
providerUsesEndpointScopedLimits,
|
|
25
26
|
providerPricingModelSync,
|
|
26
27
|
cachedProviderModelListsSync,
|
|
27
28
|
providerCachedModelsSync,
|
|
28
29
|
} from './provider-catalog-cache.mjs';
|
|
30
|
+
import {
|
|
31
|
+
modelsDevProviderId,
|
|
32
|
+
providerCatalogEntry,
|
|
33
|
+
providerMetadataCorrection,
|
|
34
|
+
providerSeedRow,
|
|
35
|
+
} from './provider-catalog-registry.mjs';
|
|
29
36
|
import { litellmMediaPricing, litellmPricing, modelsDevPricing, PRICING_RATE_KEYS } from './model-pricing-rates.mjs';
|
|
30
37
|
// Both overlays are narrowed to their read surface before becoming resident;
|
|
31
38
|
// the disk caches below still receive the full payload.
|
|
@@ -45,34 +52,21 @@ const MODELSDEV_CACHE_FILE = 'modelsdev-catalog.json';
|
|
|
45
52
|
export const PRICING_CATALOG_REFRESH_MS = 6 * 60 * 60 * 1000;
|
|
46
53
|
const PRICING_CATALOG_RETRY_MS = 60_000;
|
|
47
54
|
|
|
48
|
-
// mixdog provider
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
const _MODELSDEV_PROVIDER_ALIAS = {
|
|
52
|
-
'anthropic-oauth': 'anthropic',
|
|
53
|
-
'openai-oauth': 'openai',
|
|
54
|
-
'grok-oauth': 'xai',
|
|
55
|
-
'mimo-oauth': 'xiaomi',
|
|
56
|
-
gemini: 'google',
|
|
57
|
-
};
|
|
58
|
-
function _modelsDevProviderId(provider) {
|
|
59
|
-
if (!provider) return null;
|
|
60
|
-
const p = String(provider).toLowerCase();
|
|
61
|
-
return _MODELSDEV_PROVIDER_ALIAS[p] || p;
|
|
62
|
-
}
|
|
63
|
-
|
|
55
|
+
// The mixdog provider → models.dev provider mapping, relay flags, live-roster
|
|
56
|
+
// files and seeds live in provider-catalog-registry.mjs.
|
|
57
|
+
//
|
|
64
58
|
// Relays sell access, not models: one subscription fronts Anthropic, Google,
|
|
65
|
-
// OpenAI and xAI SKUs at once.
|
|
66
|
-
// name, so a provider-keyed lookup
|
|
67
|
-
// at zero — indistinguishable from a genuinely free local model.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
// name guess. Ids are matched on their leading family token
|
|
74
|
-
// substring, so an unrelated model that merely mentions a
|
|
75
|
-
// adopted by it.
|
|
59
|
+
// OpenAI and xAI SKUs at once. Few catalogs list them under the relay's own
|
|
60
|
+
// name, so a provider-keyed lookup can find nothing and the route silently
|
|
61
|
+
// prices at zero — indistinguishable from a genuinely free local model.
|
|
62
|
+
|
|
63
|
+
// Which vendor actually served a relayed model, read off the model id. Only a
|
|
64
|
+
// guess: its row fills capabilities and the effort ladder the route's own
|
|
65
|
+
// sources left undeclared, and prices a model only when the provider-keyed
|
|
66
|
+
// lookup found no rates, so a route with real catalog coverage is never
|
|
67
|
+
// repriced by a name guess. Ids are matched on their leading family token
|
|
68
|
+
// rather than a bare substring, so an unrelated model that merely mentions a
|
|
69
|
+
// vendor is not adopted by it.
|
|
76
70
|
const _RELAYED_MODEL_VENDORS = [
|
|
77
71
|
[/^claude[-.]/, 'anthropic'],
|
|
78
72
|
[/^(gpt|o[1-9]|codex)[-.]/, 'openai'],
|
|
@@ -82,6 +76,10 @@ const _RELAYED_MODEL_VENDORS = [
|
|
|
82
76
|
[/^kimi[-.]/, 'moonshotai'],
|
|
83
77
|
[/^glm[-.]/, 'zai'],
|
|
84
78
|
[/^muse[-.]/, 'meta'],
|
|
79
|
+
[/^qwen(?:\d|[-.])/, 'alibaba'],
|
|
80
|
+
[/^minimax[-.]/, 'minimax'],
|
|
81
|
+
[/^mimo[-.]/, 'xiaomi'],
|
|
82
|
+
[/^longcat[-.]/, 'longcat'],
|
|
85
83
|
];
|
|
86
84
|
|
|
87
85
|
function _relayedModelVendor(id) {
|
|
@@ -93,12 +91,6 @@ function _relayedModelVendor(id) {
|
|
|
93
91
|
return null;
|
|
94
92
|
}
|
|
95
93
|
|
|
96
|
-
/** The vendor to reprice a relayed model under, or null to leave it alone. */
|
|
97
|
-
function _relayPricingProvider(provider, id) {
|
|
98
|
-
if (!provider || !_RELAY_PROVIDERS.has(String(provider).toLowerCase())) return null;
|
|
99
|
-
return _relayedModelVendor(id);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
94
|
// Provider prefix variants used by the shared catalog resolver.
|
|
103
95
|
// A provider needing a new prefix adds it here.
|
|
104
96
|
// Source: LiteLLM catalog key conventions (see CATALOG_URL above).
|
|
@@ -118,7 +110,7 @@ const _CATALOG_BEDROCK_PREFIXES = ['anthropic.', 'bedrock/anthropic.'];
|
|
|
118
110
|
|
|
119
111
|
// Provider hint → catalog prefixes to try (subset of _CATALOG_SIMPLE_PREFIXES).
|
|
120
112
|
// Keyed by the *mapped* models.dev provider id
|
|
121
|
-
// (see
|
|
113
|
+
// (see modelsDevProviderId), so anthropic-oauth and anthropic share one
|
|
122
114
|
// entry, likewise grok-oauth/xai and gemini/google. A provider missing here
|
|
123
115
|
// (unknown/custom) gets bare-id lookup only — no prefix guessing across
|
|
124
116
|
// unrelated providers. No provider hint at all (mappedProvider null) keeps
|
|
@@ -366,12 +358,13 @@ function _modelsDevMetadata(row) {
|
|
|
366
358
|
max_input_tokens: row?.limit?.context,
|
|
367
359
|
max_output_tokens: row?.limit?.output,
|
|
368
360
|
mode: 'chat',
|
|
369
|
-
|
|
361
|
+
// Undeclared capabilities stay undefined (see capabilityFlag).
|
|
362
|
+
supports_reasoning: capabilityFlag(row?.reasoning),
|
|
370
363
|
reasoning_options: Array.isArray(row?.reasoning_options) ? row.reasoning_options : [],
|
|
371
364
|
reasoning_content_field: row?.interleaved?.field || null,
|
|
372
|
-
supports_function_calling: row?.tool_call
|
|
373
|
-
supports_vision: Array.isArray(row?.modalities?.input)
|
|
374
|
-
supports_prompt_caching: c.cache_read != null,
|
|
365
|
+
supports_function_calling: capabilityFlag(row?.tool_call),
|
|
366
|
+
supports_vision: Array.isArray(row?.modalities?.input) ? row.modalities.input.includes('image') : undefined,
|
|
367
|
+
supports_prompt_caching: c.cache_read != null ? true : undefined,
|
|
375
368
|
};
|
|
376
369
|
return { ..._normalize(out), ...modelsDevPricing(c), pricingSource: row?.cost ? 'models.dev' : null };
|
|
377
370
|
}
|
|
@@ -387,7 +380,7 @@ export function getModelsDevRowSync(id, provider, _test) {
|
|
|
387
380
|
if (!_test) warmModelsDevFromDiskSync();
|
|
388
381
|
const cat = _test || modelsDevSource.cache;
|
|
389
382
|
if (!cat) return null;
|
|
390
|
-
const pid =
|
|
383
|
+
const pid = modelsDevProviderId(provider);
|
|
391
384
|
if (!pid) return null;
|
|
392
385
|
const row = cat?.[pid]?.models?.[id];
|
|
393
386
|
return row || null;
|
|
@@ -400,7 +393,7 @@ export function getModelsDevProviderModelsSync(provider, _test) {
|
|
|
400
393
|
if (!_test) warmModelsDevFromDiskSync();
|
|
401
394
|
const cat = _test || modelsDevSource.cache;
|
|
402
395
|
if (!cat) return null;
|
|
403
|
-
const pid =
|
|
396
|
+
const pid = modelsDevProviderId(provider);
|
|
404
397
|
if (!pid) return null;
|
|
405
398
|
const models = cat?.[pid]?.models;
|
|
406
399
|
return models && typeof models === 'object' ? models : null;
|
|
@@ -486,11 +479,85 @@ function scaledRates(row, factor) {
|
|
|
486
479
|
return Object.fromEntries(PRICING_RATE_KEYS.map((key) => [key, row?.[key] == null ? null : row[key] * factor]));
|
|
487
480
|
}
|
|
488
481
|
|
|
489
|
-
//
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
482
|
+
// Pricing a catalog row can lend to a route it does not describe.
|
|
483
|
+
const PRICING_FIELDS = Object.freeze([
|
|
484
|
+
...PRICING_RATE_KEYS,
|
|
485
|
+
'pricingTiers',
|
|
486
|
+
'fastPricing',
|
|
487
|
+
'ultrafastPricing',
|
|
488
|
+
'offPeakMultiplier',
|
|
489
|
+
'outputImageCostPerM',
|
|
490
|
+
'outputVideoCostPerM',
|
|
491
|
+
'outputCostPerImage',
|
|
492
|
+
'outputCostPerSecond',
|
|
493
|
+
'outputCostPerSecondByResolution',
|
|
494
|
+
'pricingSource',
|
|
495
|
+
'pricingProvider',
|
|
496
|
+
// Decides whether a cache-read rate is required, so it travels with prices.
|
|
497
|
+
'supportsPromptCaching',
|
|
498
|
+
]);
|
|
499
|
+
const hasRates = (meta) => PRICING_RATE_KEYS.some((key) => meta?.[key] != null);
|
|
500
|
+
|
|
501
|
+
function pricingFields(meta) {
|
|
502
|
+
return Object.fromEntries(PRICING_FIELDS.filter((key) => meta?.[key] !== undefined).map((key) => [key, meta[key]]));
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// A vendor row describes the vendor's own endpoint. Elsewhere it prices the
|
|
506
|
+
// model and lends its label; capabilities and the effort ladder come back
|
|
507
|
+
// only as a guess (withVendorGuess), its limits never.
|
|
508
|
+
function pricingOnly(meta) {
|
|
509
|
+
if (!meta) return null;
|
|
510
|
+
return { ..._normalize({}), ...pricingFields(meta), displayName: meta.displayName || null };
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// Capabilities a vendor row may lend; fast mode is an endpoint feature.
|
|
514
|
+
const GUESSED_FLAGS = Object.freeze([
|
|
515
|
+
'supportsVision',
|
|
516
|
+
'supportsFunctionCalling',
|
|
517
|
+
'supportsWebSearch',
|
|
518
|
+
'supportsPromptCaching',
|
|
519
|
+
'supportsReasoning',
|
|
520
|
+
]);
|
|
521
|
+
const effortEntry = (options) => (Array.isArray(options) ? options.find((o) => o?.type === 'effort') : null) || null;
|
|
522
|
+
|
|
523
|
+
// A vendor row is a first guess for a route it does not describe (relay,
|
|
524
|
+
// same-vendor other endpoint, custom provider): it fills only the capabilities
|
|
525
|
+
// and effort ladder the route's own sources left undeclared. Never limits.
|
|
526
|
+
function withVendorGuess(meta, guess, { ladder = true } = {}) {
|
|
527
|
+
if (!guess) return meta;
|
|
528
|
+
const out = { ...(meta || _normalize({})) };
|
|
529
|
+
for (const key of GUESSED_FLAGS) out[key] ??= guess[key];
|
|
530
|
+
const effort = effortEntry(guess.reasoningOptions);
|
|
531
|
+
if (ladder && effort && out.supportsReasoning !== false && !effortEntry(out.reasoningOptions)) {
|
|
532
|
+
out.reasoningOptions = [...(out.reasoningOptions || []), effort];
|
|
533
|
+
}
|
|
534
|
+
return out;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// Offline seed: fills only what no fetched source supplied.
|
|
538
|
+
function withSeedFallback(meta, seed, provider) {
|
|
539
|
+
if (!seed) return meta;
|
|
540
|
+
// A capability any fetched layer declared (false included) stands; the seed
|
|
541
|
+
// fills only undeclared ones, and never gives a non-reasoning model a ladder.
|
|
542
|
+
const out = { ...(meta || _normalize({})) };
|
|
543
|
+
for (const key of CAPABILITY_FLAGS) out[key] ??= capabilityFlag(seed[key]);
|
|
544
|
+
if (!out.displayName && seed.name) out.displayName = seed.name;
|
|
545
|
+
if (!out.contextWindow && seed.contextWindow) out.contextWindow = seed.contextWindow;
|
|
546
|
+
if (!out.outputTokens && seed.outputTokens) out.outputTokens = seed.outputTokens;
|
|
547
|
+
if (!out.reasoningOptions?.length && seed.reasoningOptions?.length && out.supportsReasoning !== false) {
|
|
548
|
+
out.reasoningOptions = seed.reasoningOptions;
|
|
549
|
+
}
|
|
550
|
+
if (!hasRates(out) && hasRates(seed)) {
|
|
551
|
+
for (const key of PRICING_RATE_KEYS) out[key] = seed[key] ?? null;
|
|
552
|
+
out.pricingTiers = [];
|
|
553
|
+
out.pricingSource = 'seed';
|
|
554
|
+
out.pricingProvider = provider;
|
|
555
|
+
}
|
|
556
|
+
return out;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// Override → LiteLLM → models.dev rows under one catalog provider id.
|
|
560
|
+
function catalogMetadata(id, mappedProvider, catalog, modelsDevCatalog) {
|
|
494
561
|
let meta = null;
|
|
495
562
|
// 1. Manual overrides — authoritative + offline. Provider-guarded: when a
|
|
496
563
|
// provider hint is given, an override is only honoured if it belongs to
|
|
@@ -498,13 +565,13 @@ function lookupModelMetadata(originalId, provider, catalog, modelsDevCatalog) {
|
|
|
498
565
|
// deepseek-v4-pro under `deepseek` vs `opencode-go`) never leaks the
|
|
499
566
|
// wrong provider's rate. Bare-id callers keep the legacy behaviour.
|
|
500
567
|
const ov = PRICING_OVERRIDES[id];
|
|
501
|
-
if (ov && (!mappedProvider ||
|
|
568
|
+
if (ov && (!mappedProvider || modelsDevProviderId(ov.litellm_provider) === mappedProvider)) {
|
|
502
569
|
meta = { ..._normalize(ov), pricingSource: 'override' };
|
|
503
570
|
}
|
|
504
571
|
const metaFromPricingOverride = meta !== null;
|
|
505
572
|
// 2. LiteLLM community catalog (broad mainstream coverage).
|
|
506
573
|
if (!meta) {
|
|
507
|
-
if (catalog[id] && (!mappedProvider ||
|
|
574
|
+
if (catalog[id] && (!mappedProvider || modelsDevProviderId(catalog[id].litellm_provider) === mappedProvider)) {
|
|
508
575
|
meta = { ..._normalize(catalog[id]), pricingSource: 'litellm' };
|
|
509
576
|
}
|
|
510
577
|
for (const prefix of _prefixesForProvider(mappedProvider, _CATALOG_SIMPLE_PREFIXES)) {
|
|
@@ -530,16 +597,49 @@ function lookupModelMetadata(originalId, provider, catalog, modelsDevCatalog) {
|
|
|
530
597
|
});
|
|
531
598
|
if (row) meta = { ...meta, displayName: modelsDevDisplayName(row) };
|
|
532
599
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
600
|
+
return meta;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// The row of the vendor serving a relayed or custom model id (no vendor: a
|
|
604
|
+
// bare-id catalog lookup).
|
|
605
|
+
function servingVendorMetadata(id, vendor, catalog, modelsDevCatalog) {
|
|
606
|
+
// Anthropic SKUs spell versions with hyphens (claude-opus-5-5); relays
|
|
607
|
+
// may list the same SKU with dots (claude-opus-5.5).
|
|
608
|
+
const vendorId = vendor === 'anthropic' ? id.replace(/(\d)\.(\d)/g, '$1-$2') : id;
|
|
609
|
+
return lookupModelMetadata(vendorId, vendor, catalog, modelsDevCatalog);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// Both list enrichment and synchronous accounting use this exact resolver;
|
|
613
|
+
// enrichment passes the listed row, which is the live roster just fetched.
|
|
614
|
+
// Precedence, for every provider (see provider-catalog-registry.mjs):
|
|
615
|
+
// (a) the provider's own live roster (cached row, then the listed row);
|
|
616
|
+
// (b) catalog rows under its models.dev id — in full when that entry is the
|
|
617
|
+
// same endpoint, otherwise pricing only;
|
|
618
|
+
// (c) verified corrections for confirmed upstream catalog gaps;
|
|
619
|
+
// (d) offline seed rows fill whatever nothing above supplied;
|
|
620
|
+
// (e) relays, same-vendor providers on another endpoint and custom
|
|
621
|
+
// providers take the vendor row as a first guess for capabilities and
|
|
622
|
+
// the effort ladder still undeclared — never its limits;
|
|
623
|
+
// (f) a relay model with no rates of its own borrows the vendor's pricing.
|
|
624
|
+
function lookupModelMetadata(originalId, provider, catalog, modelsDevCatalog, listedRow = null) {
|
|
625
|
+
const custom = String(provider || '').startsWith('custom-');
|
|
626
|
+
const id = providerPricingModelSync(provider, originalId);
|
|
627
|
+
const source = provider ? providerCatalogEntry(provider) : null;
|
|
628
|
+
const mappedProvider = source?.modelsDev || null;
|
|
629
|
+
const mapped = catalogMetadata(id, mappedProvider, catalog, modelsDevCatalog);
|
|
630
|
+
let meta = source && !source.sameEndpoint ? pricingOnly(mapped) : mapped;
|
|
631
|
+
const correction = source ? providerMetadataCorrection(provider, id) : null;
|
|
632
|
+
if (meta && correction) meta = { ...meta, ...correction };
|
|
633
|
+
let guess = null;
|
|
634
|
+
const relayVendor = source?.relay ? _relayedModelVendor(id) : null;
|
|
635
|
+
if (custom) guess = customVendorMetadata(originalId, catalog, modelsDevCatalog);
|
|
636
|
+
else if (relayVendor) guess = servingVendorMetadata(id, relayVendor, catalog, modelsDevCatalog);
|
|
637
|
+
else if (source && !source.sameEndpoint) guess = mapped;
|
|
638
|
+
if (source?.relay && !hasRates(meta) && hasRates(guess)) {
|
|
639
|
+
meta = meta ? { ...meta, ...pricingFields(guess) } : pricingOnly(guess);
|
|
540
640
|
}
|
|
541
|
-
const variant = PRICED_VARIANTS[
|
|
542
|
-
if (variant && !
|
|
641
|
+
const variant = PRICED_VARIANTS[source?.provider || '']?.[id];
|
|
642
|
+
if (variant && !hasRates(meta)) {
|
|
543
643
|
const base = lookupModelMetadata(variant.base, provider, catalog, modelsDevCatalog);
|
|
544
644
|
if (base && PRICING_RATE_KEYS.some((key) => base[key] != null)) {
|
|
545
645
|
meta = {
|
|
@@ -554,38 +654,39 @@ function lookupModelMetadata(originalId, provider, catalog, modelsDevCatalog) {
|
|
|
554
654
|
};
|
|
555
655
|
}
|
|
556
656
|
}
|
|
557
|
-
const cursorRow = /^cursor-(?:oauth|api)$/.test(
|
|
657
|
+
const cursorRow = /^cursor-(?:oauth|api)$/.test(source?.provider || '') ? CURSOR_PRICING[id] : null;
|
|
558
658
|
if (cursorRow) {
|
|
559
|
-
if (!
|
|
659
|
+
if (!hasRates(meta)) {
|
|
560
660
|
meta = { ...meta, ...listedRates(cursorRow), pricingSource: 'override' };
|
|
561
661
|
}
|
|
562
662
|
if (cursorRow.fast) meta = { ...meta, fastPricing: listedRates(cursorRow.fast) };
|
|
563
663
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
//
|
|
574
|
-
//
|
|
575
|
-
//
|
|
576
|
-
//
|
|
577
|
-
//
|
|
578
|
-
//
|
|
579
|
-
//
|
|
580
|
-
|
|
581
|
-
const nativeLimitsAuthoritative = providerUsesEndpointScopedLimits(provider);
|
|
582
|
-
meta = mergeModelMetadata(meta, providerNative, {
|
|
664
|
+
const cached = provider ? providerCachedModelMetadataSync(provider, originalId) : null;
|
|
665
|
+
const seed = source ? providerSeedRow(provider, originalId) : null;
|
|
666
|
+
// A listed row alone is no metadata: enrichment then keeps it as listed.
|
|
667
|
+
if (!meta && !cached && !seed && !guess) return null;
|
|
668
|
+
const listed = listedRow ? rosterRowMetadata(provider, listedRow) : null;
|
|
669
|
+
// A custom model known only through its vendor gets the guess alone.
|
|
670
|
+
if (custom && !meta && !cached) return customCatalogDefaults(withVendorGuess(listed, guess), guess);
|
|
671
|
+
for (const roster of [cached, listed]) {
|
|
672
|
+
if (!roster) continue;
|
|
673
|
+
// The live roster's effort ladder and capabilities win. Its limits beat
|
|
674
|
+
// catalog limits only where the registry marks them authoritative (the
|
|
675
|
+
// row reflects the live account/backend window). Elsewhere the cache is
|
|
676
|
+
// a best-effort snapshot that can go stale, so it must NOT override the
|
|
677
|
+
// catalog limits — otherwise downstream catalog-vs-cache staleness checks
|
|
678
|
+
// (context-meta, statusline route-meta) compare stale-vs-stale and can
|
|
679
|
+
// never correct an outdated cached window; it still fills missing limits.
|
|
680
|
+
meta = mergeModelMetadata(meta, roster, {
|
|
583
681
|
preserveBaseCosts: true,
|
|
584
|
-
preserveBaseLimits: !
|
|
682
|
+
preserveBaseLimits: !source?.rosterLimitsAuthoritative,
|
|
585
683
|
});
|
|
586
684
|
}
|
|
587
|
-
|
|
588
|
-
|
|
685
|
+
meta = withSeedFallback(meta, seed, source?.provider);
|
|
686
|
+
const rosterLadders = [cached?.rawProviderModel, listedRow].filter(
|
|
687
|
+
(row) => Array.isArray(row?.reasoningLevels) || Array.isArray(row?.reasoningOptions)
|
|
688
|
+
);
|
|
689
|
+
meta = withVendorGuess(meta, guess, { ladder: !(source?.rosterLadderFinal && rosterLadders.length) });
|
|
589
690
|
return meta
|
|
590
691
|
? {
|
|
591
692
|
...meta,
|
|
@@ -595,27 +696,32 @@ function lookupModelMetadata(originalId, provider, catalog, modelsDevCatalog) {
|
|
|
595
696
|
: null;
|
|
596
697
|
}
|
|
597
698
|
|
|
598
|
-
// A user-defined (`custom-*`) provider is in
|
|
599
|
-
// its discovered models match by bare model id (as listed, then without
|
|
600
|
-
// `vendor/` route prefix) under the vendor the id names.
|
|
601
|
-
//
|
|
602
|
-
//
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
699
|
+
// A user-defined (`custom-*`) provider is rarely in a catalog under its own
|
|
700
|
+
// id, so its discovered models match by bare model id (as listed, then without
|
|
701
|
+
// a `vendor/` route prefix) under the vendor the id names. That vendor row is a
|
|
702
|
+
// first guess for the capabilities and effort ladder the custom route leaves
|
|
703
|
+
// undeclared (the row's customReasoning overrides still win); prices and
|
|
704
|
+
// limits describe the vendor's own API, not the custom endpoint.
|
|
705
|
+
function customVendorMetadata(originalId, catalog, modelsDevCatalog) {
|
|
706
|
+
const listedId = String(originalId || '');
|
|
707
|
+
for (const id of new Set([listedId, listedId.slice(listedId.lastIndexOf('/') + 1)])) {
|
|
606
708
|
if (!id) continue;
|
|
607
|
-
const vendor = _relayedModelVendor(id) ||
|
|
608
|
-
const
|
|
609
|
-
if (
|
|
610
|
-
return {
|
|
611
|
-
supportsReasoning: meta.supportsReasoning === true,
|
|
612
|
-
reasoningOptions: Array.isArray(meta.reasoningOptions) ? meta.reasoningOptions : [],
|
|
613
|
-
reasoningContentField: meta.reasoningContentField || null,
|
|
614
|
-
};
|
|
709
|
+
const vendor = _relayedModelVendor(id) || modelsDevProviderId(catalog[id]?.litellm_provider);
|
|
710
|
+
const guess = servingVendorMetadata(id, vendor, catalog, modelsDevCatalog);
|
|
711
|
+
if (guess) return guess;
|
|
615
712
|
}
|
|
616
713
|
return null;
|
|
617
714
|
}
|
|
618
715
|
|
|
716
|
+
// The defaults a vendor guess gives a custom row: capabilities and reasoning only.
|
|
717
|
+
function customCatalogDefaults(meta, guess) {
|
|
718
|
+
return {
|
|
719
|
+
...Object.fromEntries(GUESSED_FLAGS.map((key) => [key, meta[key]])),
|
|
720
|
+
reasoningOptions: meta.reasoningOptions || [],
|
|
721
|
+
reasoningContentField: meta.reasoningContentField || guess.reasoningContentField || null,
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
|
|
619
725
|
function _normalize(entry) {
|
|
620
726
|
if (!entry || typeof entry !== 'object') return null;
|
|
621
727
|
// OpenAI's Priority processing (since renamed Fast mode) columns.
|
|
@@ -629,18 +735,39 @@ function _normalize(entry) {
|
|
|
629
735
|
...(PRICING_RATE_KEYS.some((key) => fastPricing[key] != null) ? { fastPricing } : {}),
|
|
630
736
|
...(PRICING_RATE_KEYS.some((key) => ultrafastPricing[key] != null) ? { ultrafastPricing } : {}),
|
|
631
737
|
...(entry.off_peak_multiplier ? { offPeakMultiplier: entry.off_peak_multiplier } : {}),
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
738
|
+
// Tri-state: true/false as declared, undefined when the row is silent.
|
|
739
|
+
supportsVision: capabilityFlag(entry.supports_vision),
|
|
740
|
+
supportsFunctionCalling: capabilityFlag(entry.supports_function_calling),
|
|
741
|
+
supportsWebSearch:
|
|
742
|
+
entry.supports_web_search === true || entry.supports_websearch === true
|
|
743
|
+
? true
|
|
744
|
+
: (capabilityFlag(entry.supports_web_search) ?? capabilityFlag(entry.supports_websearch)),
|
|
745
|
+
supportsPromptCaching: capabilityFlag(entry.supports_prompt_caching),
|
|
746
|
+
supportsFastMode: capabilityFlag(entry.supports_fast_mode),
|
|
747
|
+
supportsReasoning: capabilityFlag(entry.supports_reasoning),
|
|
638
748
|
reasoningOptions: Array.isArray(entry.reasoning_options) ? entry.reasoning_options : [],
|
|
639
749
|
reasoningContentField: entry.reasoning_content_field || null,
|
|
640
750
|
mode: entry.mode || null,
|
|
641
751
|
};
|
|
642
752
|
}
|
|
643
753
|
|
|
754
|
+
const CAPABILITY_FLAGS = Object.freeze([
|
|
755
|
+
'supportsVision',
|
|
756
|
+
'supportsFunctionCalling',
|
|
757
|
+
'supportsWebSearch',
|
|
758
|
+
'supportsPromptCaching',
|
|
759
|
+
'supportsFastMode',
|
|
760
|
+
'supportsReasoning',
|
|
761
|
+
]);
|
|
762
|
+
|
|
763
|
+
// A layer's own ladder wins; a lower layer's ladder never reaches a model the
|
|
764
|
+
// higher layer declares non-reasoning.
|
|
765
|
+
function mergedReasoningOptions(base, overlay) {
|
|
766
|
+
if (overlay.reasoningOptions?.length) return overlay.reasoningOptions;
|
|
767
|
+
if ((overlay.supportsReasoning ?? base.supportsReasoning) === false) return [];
|
|
768
|
+
return base.reasoningOptions || [];
|
|
769
|
+
}
|
|
770
|
+
|
|
644
771
|
function mergeModelMetadata(base, overlay, opts = {}) {
|
|
645
772
|
if (!base) return overlay || null;
|
|
646
773
|
if (!overlay) return base;
|
|
@@ -674,13 +801,10 @@ function mergeModelMetadata(base, overlay, opts = {}) {
|
|
|
674
801
|
!opts.preserveBaseCosts && PRICING_RATE_KEYS.some((key) => overlay[key] != null)
|
|
675
802
|
? overlay.pricingSource
|
|
676
803
|
: base.pricingSource,
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
supportsFastMode: base.supportsFastMode || overlay.supportsFastMode,
|
|
682
|
-
supportsReasoning: base.supportsReasoning || overlay.supportsReasoning,
|
|
683
|
-
reasoningOptions: overlay.reasoningOptions?.length ? overlay.reasoningOptions : base.reasoningOptions || [],
|
|
804
|
+
// The overlay is the higher layer: a capability it declares (false
|
|
805
|
+
// included) wins; the base fills only what the overlay leaves undeclared.
|
|
806
|
+
...Object.fromEntries(CAPABILITY_FLAGS.map((key) => [key, overlay[key] ?? base[key]])),
|
|
807
|
+
reasoningOptions: mergedReasoningOptions(base, overlay),
|
|
684
808
|
reasoningContentField: overlay.reasoningContentField || base.reasoningContentField || null,
|
|
685
809
|
mode: base.mode || overlay.mode || null,
|
|
686
810
|
};
|
|
@@ -695,7 +819,7 @@ export async function enrichModels(models, { fetchFn, force = false } = {}) {
|
|
|
695
819
|
if (!Array.isArray(models)) return models;
|
|
696
820
|
const catalog = await loadCatalog({ fetchFn, force });
|
|
697
821
|
let modelsDevCatalog = modelsDevSource.cache;
|
|
698
|
-
if (models.some((m) =>
|
|
822
|
+
if (models.some((m) => modelsDevProviderId(m?.provider))) {
|
|
699
823
|
try {
|
|
700
824
|
modelsDevCatalog = await loadModelsDevCatalog({ fetchFn, force });
|
|
701
825
|
} catch {
|
|
@@ -705,7 +829,7 @@ export async function enrichModels(models, { fetchFn, force = false } = {}) {
|
|
|
705
829
|
return models.map((m) => {
|
|
706
830
|
const id = m.id || m.name;
|
|
707
831
|
if (!id) return m;
|
|
708
|
-
const meta = lookupModelMetadata(id, m.provider, catalog, modelsDevCatalog || {});
|
|
832
|
+
const meta = lookupModelMetadata(id, m.provider, catalog, modelsDevCatalog || {}, m);
|
|
709
833
|
if (!meta) return m;
|
|
710
834
|
const catalogDisplay = meta.displayName;
|
|
711
835
|
return {
|
|
@@ -726,12 +850,10 @@ export async function enrichModels(models, { fetchFn, force = false } = {}) {
|
|
|
726
850
|
pricingModel: meta.pricingModel,
|
|
727
851
|
pricingProvider: meta.pricingProvider,
|
|
728
852
|
pricingSource: meta.pricingSource,
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
supportsReasoning: m.supportsReasoning === true || meta.supportsReasoning,
|
|
734
|
-
reasoningOptions: m.reasoningOptions?.length ? m.reasoningOptions : meta.reasoningOptions || [],
|
|
853
|
+
// The lookup already layered the listed row as the live roster, with
|
|
854
|
+
// the same roster semantics as the sync path.
|
|
855
|
+
...Object.fromEntries(GUESSED_FLAGS.map((key) => [key, meta[key]])),
|
|
856
|
+
reasoningOptions: meta.reasoningOptions || [],
|
|
735
857
|
reasoningContentField: meta.reasoningContentField || m.reasoningContentField || null,
|
|
736
858
|
mode: meta.mode || m.mode || null,
|
|
737
859
|
};
|
|
@@ -782,7 +904,6 @@ export function pricingCatalogRevisionSync() {
|
|
|
782
904
|
}
|
|
783
905
|
|
|
784
906
|
let lastAuditedRevision = null;
|
|
785
|
-
let lastAudit = null;
|
|
786
907
|
function auditCachedModelPricing() {
|
|
787
908
|
const revision = pricingCatalogRevisionSync();
|
|
788
909
|
const rows = Object.entries(cachedProviderModelListsSync()).flatMap(([provider, models]) =>
|
|
@@ -797,17 +918,6 @@ function auditCachedModelPricing() {
|
|
|
797
918
|
);
|
|
798
919
|
}
|
|
799
920
|
lastAuditedRevision = revision;
|
|
800
|
-
lastAudit = { revision, rows, unpriced };
|
|
801
|
-
return lastAudit;
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
/** Catalog routes without a complete list price, from the latest audit (run on demand when none is cached). */
|
|
805
|
-
export function unpricedModelsSync() {
|
|
806
|
-
return (lastAudit ?? auditCachedModelPricing()).unpriced.map(({ provider, model, missingRates }) => ({
|
|
807
|
-
provider,
|
|
808
|
-
model,
|
|
809
|
-
missingRates: [...missingRates],
|
|
810
|
-
}));
|
|
811
921
|
}
|
|
812
922
|
|
|
813
923
|
/**
|
|
@@ -2,19 +2,29 @@ import { existsSync, readFileSync } from 'node:fs';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { resolvePluginData } from '../plugin-paths.mjs';
|
|
4
4
|
import { ANTIGRAVITY_MODELS, ANTIGRAVITY_PRICING_ALIASES, normalizeGrokModelId } from './provider-model-identities.mjs';
|
|
5
|
+
import { providerRosterFiles, rosterProviders } from './provider-catalog-registry.mjs';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
'grok-oauth': ['grok-oauth-models.json'],
|
|
12
|
-
'antigravity-oauth': ['antigravity-oauth-models.json'],
|
|
13
|
-
});
|
|
7
|
+
/** A declared capability keeps its boolean; an undeclared one stays undefined,
|
|
8
|
+
* so lower layers (catalogs, seeds) fill only what no source stated. */
|
|
9
|
+
export function capabilityFlag(value) {
|
|
10
|
+
return typeof value === 'boolean' ? value : undefined;
|
|
11
|
+
}
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
/** Provider roster rows coerce "unknown" to `false` (`x === true`), so only a
|
|
14
|
+
* `true` there is a declaration; `false` leaves the field to catalogs/seeds. */
|
|
15
|
+
export function rosterCapabilityFlag(value) {
|
|
16
|
+
return value === true ? true : undefined;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** A roster row's effort ladder: `reasoningOptions` when it carries an effort
|
|
20
|
+
* entry, else the flat `reasoningLevels` some rosters store (Antigravity). */
|
|
21
|
+
export function rosterReasoningOptions(row) {
|
|
22
|
+
const options = Array.isArray(row?.reasoningOptions) ? row.reasoningOptions : [];
|
|
23
|
+
// An effort entry with no values declares nothing.
|
|
24
|
+
const usable = options.filter((o) => o?.type !== 'effort' || (Array.isArray(o.values) && o.values.length > 0));
|
|
25
|
+
if (usable.some((o) => o?.type === 'effort')) return usable;
|
|
26
|
+
const levels = Array.isArray(row?.reasoningLevels) ? row.reasoningLevels.filter((v) => typeof v === 'string') : [];
|
|
27
|
+
return levels.length ? [...usable, { type: 'effort', values: levels }] : usable;
|
|
18
28
|
}
|
|
19
29
|
|
|
20
30
|
function num(value) {
|
|
@@ -34,8 +44,7 @@ function readModelsFromCacheFile(fileName) {
|
|
|
34
44
|
}
|
|
35
45
|
|
|
36
46
|
export function providerCachedModelsSync(provider) {
|
|
37
|
-
const
|
|
38
|
-
const files = PROVIDER_CACHE_FILES[p] || [];
|
|
47
|
+
const files = providerRosterFiles(provider);
|
|
39
48
|
const rows = [];
|
|
40
49
|
const seen = new Set();
|
|
41
50
|
for (const fileName of files) {
|
|
@@ -50,11 +59,7 @@ export function providerCachedModelsSync(provider) {
|
|
|
50
59
|
}
|
|
51
60
|
|
|
52
61
|
export function cachedProviderModelListsSync() {
|
|
53
|
-
return Object.fromEntries(
|
|
54
|
-
Object.keys(PROVIDER_CACHE_FILES)
|
|
55
|
-
.filter((provider) => provider !== 'anthropic')
|
|
56
|
-
.map((provider) => [provider, providerCachedModelsSync(provider)])
|
|
57
|
-
);
|
|
62
|
+
return Object.fromEntries(rosterProviders().map((provider) => [provider, providerCachedModelsSync(provider)]));
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
/** Only explicit catalog wire mappings establish an alias. Never strip an
|
|
@@ -86,8 +91,7 @@ function rowId(row) {
|
|
|
86
91
|
}
|
|
87
92
|
|
|
88
93
|
function getProviderCachedModelSync(provider, model) {
|
|
89
|
-
const
|
|
90
|
-
const files = PROVIDER_CACHE_FILES[p] || [];
|
|
94
|
+
const files = providerRosterFiles(provider);
|
|
91
95
|
if (!files.length || !model) return null;
|
|
92
96
|
const aliases = new Set(modelAliases(model));
|
|
93
97
|
for (const fileName of files) {
|
|
@@ -101,9 +105,13 @@ function getProviderCachedModelSync(provider, model) {
|
|
|
101
105
|
}
|
|
102
106
|
|
|
103
107
|
export function providerCachedModelMetadataSync(provider, model) {
|
|
104
|
-
const p = String(provider || '').toLowerCase();
|
|
105
108
|
const row = getProviderCachedModelSync(provider, model);
|
|
106
|
-
|
|
109
|
+
return row ? rosterRowMetadata(provider, row) : null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Metadata layer of one live-roster row (cached or just listed). */
|
|
113
|
+
export function rosterRowMetadata(provider, row) {
|
|
114
|
+
const p = String(provider || '').toLowerCase();
|
|
107
115
|
return {
|
|
108
116
|
contextWindow: num(
|
|
109
117
|
row.contextWindow ?? row.context_window ?? row.maxContextWindow ?? row.max_context_window ?? row.max_input_tokens
|
|
@@ -115,12 +123,12 @@ export function providerCachedModelMetadataSync(provider, model) {
|
|
|
115
123
|
p === 'grok-oauth'
|
|
116
124
|
? null
|
|
117
125
|
: num(row.outputTokens ?? row.maxOutputTokens ?? row.max_output_tokens ?? row.output_token_limit),
|
|
118
|
-
supportsVision: row.supportsVision
|
|
119
|
-
supportsFunctionCalling: row.supportsFunctionCalling
|
|
120
|
-
supportsWebSearch: row.supportsWebSearch
|
|
121
|
-
supportsPromptCaching: row.supportsPromptCaching
|
|
122
|
-
supportsReasoning: row.supportsReasoning
|
|
123
|
-
reasoningOptions:
|
|
126
|
+
supportsVision: rosterCapabilityFlag(row.supportsVision),
|
|
127
|
+
supportsFunctionCalling: rosterCapabilityFlag(row.supportsFunctionCalling),
|
|
128
|
+
supportsWebSearch: rosterCapabilityFlag(row.supportsWebSearch),
|
|
129
|
+
supportsPromptCaching: rosterCapabilityFlag(row.supportsPromptCaching),
|
|
130
|
+
supportsReasoning: rosterCapabilityFlag(row.supportsReasoning),
|
|
131
|
+
reasoningOptions: rosterReasoningOptions(row),
|
|
124
132
|
reasoningContentField: row.reasoningContentField || null,
|
|
125
133
|
mode: row.mode || null,
|
|
126
134
|
displayName: row.displayName || row.display || row.name || null,
|