From cdd07df700e2e1fea1fb0f866787b1d451bec762 Mon Sep 17 00:00:00 2001 From: backryun Date: Thu, 3 Sep 2026 19:50:02 +0900 Subject: [PATCH] feat(providers): refresh NVIDIA hosted models (#12538) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validado em lote numa worktree combinada com #12524, #12538, #12277 e #12367 sobre o tip de release/v3.8.51: os quatro boardaram sem conflito (áreas disjuntas — zai-web, nvidia, clova, cursor/devin/fable). typecheck:core limpo, check:provider-consistency OK (272 entradas REGISTRY, 355 providers canônicos), check:known-symbols OK, e 305/305 nos testes tocados pelos quatro PRs. Os IDs de modelo adicionados foram conferidos individualmente. Obrigado, @backryun. --- README.md | 8 +- docs/diagrams/free-tier-budget.svg | 4 +- open-sse/config/freeModelCatalog.data.ts | 11 +- .../config/nvidiaHostedModels.snapshot.json | 24 ++-- .../config/providers/registry/nvidia/index.ts | 127 +++--------------- src/lib/providers/nvidiaValidationModel.ts | 9 +- tests/integration/freeModelBenchmarkShared.ts | 4 +- tests/unit/catalog-updates-v3x.test.ts | 17 ++- tests/unit/clinepass-thinking-budget.test.ts | 4 +- tests/unit/free-models.test.ts | 24 ++-- .../combo-vision-provider-id-12112.test.ts | 20 ++- .../unit/model-capabilities-registry.test.ts | 2 +- tests/unit/nvidia-410-model-scope.test.ts | 2 +- tests/unit/nvidia-eol-catalog.test.ts | 40 ++---- .../nvidia-minimax-m3-removed-3329.test.ts | 14 +- .../nvidia-nim-catalog-expansion-2373.test.ts | 81 ----------- tests/unit/nvidia-nim-registry-6108.test.ts | 50 +++++-- tests/unit/nvidia-nim-validator.test.ts | 2 +- .../nvidia-passthrough-models-6773.test.ts | 14 +- .../unit/nvidia-validation-model-3116.test.ts | 15 ++- .../opencode-go-effort-aliases-8353.test.ts | 9 -- 21 files changed, 156 insertions(+), 325 deletions(-) delete mode 100644 tests/unit/nvidia-nim-catalog-expansion-2373.test.ts diff --git a/README.md b/README.md index 60d5827d99..a026f9c9c3 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,9 @@ -> Stacking free tiers by hand is painful — dozens of SDKs, dozens of rate limits, and no idea how much you actually have. OmniRoute catalogs **446 free-tier entries across 38 recurring pool keys** and computes the token headline from the **20 pools with a published positive monthly budget**, deduplicated by shared pool. The result stays visible on the dashboard (`/dashboard/free-tiers`). +> Stacking free tiers by hand is painful — dozens of SDKs, dozens of rate limits, and no idea how much you actually have. OmniRoute catalogs **437 free-tier entries across 38 recurring pool keys** and computes the token headline from the **20 pools with a published positive monthly budget**, deduplicated by shared pool. The result stays visible on the dashboard (`/dashboard/free-tiers`). -OmniRoute free-tier budget card: ~1.51B free tokens per month steady, up to ~2.13B in the first month with signup credits, from 38 documented recurring pool keys covering 446 cataloged free-tier entries behind one endpoint. Honest pool-deduped math — each shared pool counted once, including 20 recurring pools with a published positive monthly token budget; 13 providers are marked avoid in the terms-risk catalog so you decide. Budget bar includes Mistral 1B, LLM7 150M, Nara 150M, Gemini 60M and smaller pools, plus first-month signup credits and permanently-free no-token-cap providers surfaced separately so they never inflate the headline. Live used/remaining on /dashboard/free-tiers. +OmniRoute free-tier budget card: ~1.51B free tokens per month steady, up to ~2.13B in the first month with signup credits, from 38 documented recurring pool keys covering 437 cataloged free-tier entries behind one endpoint. Honest pool-deduped math — each shared pool counted once, including 20 recurring pools with a published positive monthly token budget; 13 providers are marked avoid in the terms-risk catalog so you decide. Budget bar includes Mistral 1B, LLM7 150M, Nara 150M, Gemini 60M and smaller pools, plus first-month signup credits and permanently-free no-token-cap providers surfaced separately so they never inflate the headline. Live used/remaining on /dashboard/free-tiers. > Animated summary of the live `/dashboard/free-tiers` page. Full methodology (pool dedupe, credit tiers, provider terms): **[docs/reference/FREE_TIERS.md](docs/reference/FREE_TIERS.md)**. > @@ -648,7 +648,7 @@ of your shell history. → [CLI Integrations](docs/guides/CLI-INTEGRATIONS.md) -> **352 registered providers** across the canonical chat, media, search, local, cloud-agent and system collections, including **152 carrying `hasFree: true` discovery metadata**. The chat model registry covers **229 providers / 2,554 distinct provider-model pairs / 1,283 raw model IDs**; the separate free-budget catalog has **446 per-model rows**, **38 recurring pools** and **53 recurring/keyless free-forever providers**. These are different denominators by design; definitions and pool-deduped calculations live in the [Provider Reference](docs/reference/PROVIDER_REFERENCE.md) and [Free Tiers](docs/reference/FREE_TIERS.md). +> **352 registered providers** across the canonical chat, media, search, local, cloud-agent and system collections, including **152 carrying `hasFree: true` discovery metadata**. The chat model registry covers **229 providers / 2,554 distinct provider-model pairs / 1,283 raw model IDs**; the separate free-budget catalog has **437 per-model rows**, **38 recurring pools** and **53 recurring/keyless free-forever providers**. These are different denominators by design; definitions and pool-deduped calculations live in the [Provider Reference](docs/reference/PROVIDER_REFERENCE.md) and [Free Tiers](docs/reference/FREE_TIERS.md).
@@ -1270,7 +1270,7 @@ Métricas canônicas em 2026-08-24: **1.029 vídeos únicos** · **11.132.922 vi Resilience GuideCircuit breakers, cooldowns, queue, anti-thundering herd, TLS spoofing Auto-Combo Engine16-factor scoring, mode packs, self-healing Proxy Guide3-level proxy system, 1proxy marketplace, registry CRUD - Free TiersConsolidated directory: 38 documented recurring pools / 446 cataloged free-tier entries + Free TiersConsolidated directory: 38 documented recurring pools / 437 cataloged free-tier entries Features GalleryVisual dashboard tour with screenshots Codebase DocumentationBeginner-friendly codebase walkthrough diff --git a/docs/diagrams/free-tier-budget.svg b/docs/diagrams/free-tier-budget.svg index 51267b3ae2..72d1219cb2 100644 --- a/docs/diagrams/free-tier-budget.svg +++ b/docs/diagrams/free-tier-budget.svg @@ -1,4 +1,4 @@ - + Pool-deduplicated chart of the 20 recurring free-token pools with positive published budgets, plus signup credits and uncapped providers shown separately. @@ -64,7 +64,7 @@ ~1.51B FREE TOKENS / MONTH · STEADY up to ~2.13B in your first month — signup credits - documented free tiers · 38 recurring pools · 446 catalog entries · one endpoint + documented free tiers · 38 recurring pools · 437 catalog entries · one endpoint diff --git a/open-sse/config/freeModelCatalog.data.ts b/open-sse/config/freeModelCatalog.data.ts index 2d82b69382..f107d7fef4 100644 --- a/open-sse/config/freeModelCatalog.data.ts +++ b/open-sse/config/freeModelCatalog.data.ts @@ -277,18 +277,9 @@ export const FREE_MODEL_BUDGETS: FreeModelBudget[] = [ { provider: "nscale", modelId: "openai/gpt-oss-20b", displayName: "openai/gpt-oss-20b", monthlyTokens: 0, creditTokens: 5000000, freeType: "one-time-initial", poolKey: "nscale", tos: "caution" }, { provider: "nscale", modelId: "meta-llama/Llama-4-Scout-17B-16E-Instruct", displayName: "meta-llama/Llama-4-Scout-17B-16E-Instruct", monthlyTokens: 0, creditTokens: 5000000, freeType: "one-time-initial", poolKey: "nscale", tos: "caution" }, { provider: "nscale", modelId: "meta-llama/Llama-3.3-70B-Instruct", displayName: "meta-llama/Llama-3.3-70B-Instruct", monthlyTokens: 0, creditTokens: 5000000, freeType: "one-time-initial", poolKey: "nscale", tos: "caution" }, - { provider: "nvidia", modelId: "z-ai/glm-5.2", displayName: "GLM 5.2", monthlyTokens: 0, creditTokens: 0, freeType: "one-time-initial", poolKey: "nvidia", tos: "caution" }, - { provider: "nvidia", modelId: "minimaxai/minimax-m2.7", displayName: "MiniMax M2.7", monthlyTokens: 0, creditTokens: 0, freeType: "one-time-initial", poolKey: "nvidia", tos: "caution" }, { provider: "nvidia", modelId: "google/gemma-4-31b-it", displayName: "Gemma 4 31B", monthlyTokens: 0, creditTokens: 0, freeType: "one-time-initial", poolKey: "nvidia", tos: "caution" }, - { provider: "nvidia", modelId: "mistralai/mistral-small-4-119b-2603", displayName: "Mistral Small 4 2603", monthlyTokens: 0, creditTokens: 0, freeType: "one-time-initial", poolKey: "nvidia", tos: "caution" }, - { provider: "nvidia", modelId: "mistralai/mistral-large-3-675b-instruct-2512", displayName: "Mistral Large 3 675B", monthlyTokens: 0, creditTokens: 0, freeType: "one-time-initial", poolKey: "nvidia", tos: "caution" }, - { provider: "nvidia", modelId: "mistralai/devstral-2-123b-instruct-2512", displayName: "Devstral 2 123B", monthlyTokens: 0, creditTokens: 0, freeType: "one-time-initial", poolKey: "nvidia", tos: "caution" }, - { provider: "nvidia", modelId: "qwen/qwen3.5-397b-a17b", displayName: "Qwen3.5-397B-A17B", monthlyTokens: 0, creditTokens: 0, freeType: "one-time-initial", poolKey: "nvidia", tos: "caution" }, - { provider: "nvidia", modelId: "qwen/qwen3.5-122b-a10b", displayName: "Qwen3.5-122B-A10B", monthlyTokens: 0, creditTokens: 0, freeType: "one-time-initial", poolKey: "nvidia", tos: "caution" }, - { provider: "nvidia", modelId: "stepfun-ai/step-3.5-flash", displayName: "Step 3.5 Flash", monthlyTokens: 0, creditTokens: 0, freeType: "one-time-initial", poolKey: "nvidia", tos: "caution" }, - { provider: "nvidia", modelId: "openai/gpt-oss-120b", displayName: "GPT OSS 120B", monthlyTokens: 0, creditTokens: 0, freeType: "one-time-initial", poolKey: "nvidia", tos: "caution" }, - { provider: "nvidia", modelId: "openai/gpt-oss-20b", displayName: "GPT OSS 20B", monthlyTokens: 0, creditTokens: 0, freeType: "one-time-initial", poolKey: "nvidia", tos: "caution" }, { provider: "nvidia", modelId: "nvidia/nemotron-3-super-120b-a12b", displayName: "Nemotron 3 Super 120B A12B", monthlyTokens: 0, creditTokens: 0, freeType: "one-time-initial", poolKey: "nvidia", tos: "caution" }, + { provider: "nvidia", modelId: "openai/gpt-oss-120b", displayName: "GPT OSS 120B", monthlyTokens: 0, creditTokens: 0, freeType: "one-time-initial", poolKey: "nvidia", tos: "caution" }, { provider: "ollama-cloud", modelId: "deepseek-v4-pro", displayName: "DeepSeek V4 Pro", monthlyTokens: 20000000, creditTokens: 0, freeType: "recurring-monthly", poolKey: "ollama-cloud", tos: "ambiguous" }, { provider: "ollama-cloud", modelId: "deepseek-v4-flash", displayName: "DeepSeek V4 Flash", monthlyTokens: 20000000, creditTokens: 0, freeType: "recurring-monthly", poolKey: "ollama-cloud", tos: "ambiguous" }, { provider: "ollama-cloud", modelId: "kimi-k2.6", displayName: "Kimi K2.6", monthlyTokens: 20000000, creditTokens: 0, freeType: "recurring-monthly", poolKey: "ollama-cloud", tos: "ambiguous" }, diff --git a/open-sse/config/nvidiaHostedModels.snapshot.json b/open-sse/config/nvidiaHostedModels.snapshot.json index 60d2f2e76d..fa94a6a4a7 100644 --- a/open-sse/config/nvidiaHostedModels.snapshot.json +++ b/open-sse/config/nvidiaHostedModels.snapshot.json @@ -1,16 +1,14 @@ [ - "google/gemma-4-31b-it", - "minimaxai/minimax-m2.7", - "mistralai/devstral-2-123b-instruct-2512", - "mistralai/mistral-large-3-675b-instruct-2512", - "mistralai/mistral-small-4-119b-2603", - "nvidia/nemotron-3-super-120b-a12b", - "openai/gpt-oss-120b", - "openai/gpt-oss-20b", + "moonshotai/kimi-k3", + "deepseek-ai/deepseek-v4-pro-0813", + "deepseek-ai/deepseek-v4-flash-0731", + "meta/muse-glimmer-30b", "poolside/laguna-xs-2.1", - "qwen/qwen3.5-122b-a10b", - "qwen/qwen3.5-397b-a17b", - "stepfun-ai/step-3.5-flash", - "thinkingmachines/inkling", - "z-ai/glm-5.2" + "google/gemma-4-31b-it", + "google/diffusiongemma-26b-a4b-it", + "nvidia/nemotron-3-ultra-550b-a55b", + "nvidia/nemotron-3-super-120b-a12b", + "nvidia/nemotron-3.5-lightning-30b-a3b", + "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning", + "openai/gpt-oss-120b" ] diff --git a/open-sse/config/providers/registry/nvidia/index.ts b/open-sse/config/providers/registry/nvidia/index.ts index 0966fa5941..dab45294d3 100644 --- a/open-sse/config/providers/registry/nvidia/index.ts +++ b/open-sse/config/providers/registry/nvidia/index.ts @@ -9,104 +9,34 @@ export const nvidiaProvider: RegistryEntry = { authType: "apikey", authHeader: "bearer", toolNameMaxLength: 64, - // #6773: nvidia multiplexes 17 models from 9 different upstream vendors - // (z-ai/, minimaxai/, deepseek-ai/, qwen/, mistralai/, stepfun-ai/, - // moonshotai/, openai/, nvidia/) behind ONE connection — mark it passthrough + // #6773: NVIDIA multiplexes models from multiple upstream vendors + // (moonshotai/, deepseek-ai/, nvidia/, meta/, poolside/, google/, openai/) + // behind ONE connection — mark it passthrough // so a single stale/renamed model's 404 locks out only that model instead // of cooling down the whole connection (see accountFallback.ts // hasPerModelQuota doc comment; matches modelscope/synthetic/kilo-gateway). passthroughModels: true, models: [ - // #6108: z-ai/glm-5.1 EOL'd 2026-07-02 (direct probe returns 410) — dropped. - // #10788: NVIDIA's hosted GLM-5.2 exposes a BINARY thinking switch - // (chat_template_kwargs.enable_thinking), not effort tiers — see - // mapNvidiaGlm52ReasoningParams. Declaring an empty tier list keeps the - // catalog from synthesizing unresolvable -low/-high/-max variant ids while - // still marking the model reasoning-capable. + { id: "moonshotai/kimi-k3", name: "Kimi K3" }, { - id: "z-ai/glm-5.2", - name: "GLM 5.2", + id: "deepseek-ai/deepseek-v4-pro-0813", + name: "DeepSeek V4 Pro 0813", supportsReasoning: true, - supportedThinkingEfforts: [], }, - // #3329/#6108: minimaxai/minimax-m3 stays excluded from the nvidia tier — it - // still 404s here for most callers; the single 200 probe in #6108 was not - // reproducible enough to override the #3329 guard. Re-add only once NVIDIA - // reliably serves it (and flip nvidia-minimax-m3-removed-3329.test.ts then). - { id: "minimaxai/minimax-m2.7", name: "MiniMax M2.7" }, + { + id: "deepseek-ai/deepseek-v4-flash-0731", + name: "DeepSeek V4 Flash 0731", + supportsReasoning: true, + }, + { id: "meta/muse-glimmer-30b", name: "Muse Glimmer 30B" }, + { id: "poolside/laguna-xs-2.1", name: "Laguna XS 2.1" }, { id: "google/gemma-4-31b-it", name: "Gemma 4 31B" }, - { id: "mistralai/mistral-small-4-119b-2603", name: "Mistral Small 4 2603" }, - { id: "mistralai/mistral-large-3-675b-instruct-2512", name: "Mistral Large 3 675B" }, - { id: "mistralai/devstral-2-123b-instruct-2512", name: "Devstral 2 123B" }, - { id: "qwen/qwen3.5-397b-a17b", name: "Qwen3.5-397B-A17B" }, - { id: "qwen/qwen3.5-122b-a10b", name: "Qwen3.5-122B-A10B" }, - { id: "stepfun-ai/step-3.5-flash", name: "Step 3.5 Flash" }, - { id: "stepfun-ai/step-3.7-flash", name: "Step 3.7 Flash" }, - // Sweep 2026-06-19: verified present in the live NVIDIA NIM /v1/models catalog. - { id: "moonshotai/kimi-k2.6", name: "Kimi K2.6" }, - { id: "openai/gpt-oss-120b", name: "GPT OSS 120B", toolCalling: false }, - { id: "openai/gpt-oss-20b", name: "GPT OSS 20B", toolCalling: false }, + { id: "google/diffusiongemma-26b-a4b-it", name: "DiffusionGemma 26B A4B IT" }, + { id: "nvidia/nemotron-3-ultra-550b-a55b", name: "Nemotron 3 Ultra 550B A55B" }, { id: "nvidia/nemotron-3-super-120b-a12b", name: "Nemotron 3 Super 120B A12B" }, - { id: "nvidia/nemotron-3-ultra-550b-a55b", name: "Nemotron 3 Ultra 550B" }, - // Port of decolua/9router#2373 ("fix(nvidia): expand NIM chat model catalog"): - // additional live-catalog models observed to serve /v1/chat/completions. - // `minimaxai/minimax-m3` from that PR is intentionally NOT re-added — it stays - // excluded per the #3329 guard (nvidia-minimax-m3-removed-3329.test.ts). - // Non-chat entries from the same PR (nvidia/gliner-pii — NER tagger, not a chat - // model; google/diffusiongemma-26b-a4b-it — diffusion model) are dropped for the - // same reason: this registry only models the /v1/chat/completions surface. - { id: "abacusai/dracarys-llama-3.1-70b-instruct", name: "Dracarys Llama 3.1 70B Instruct" }, - { id: "google/gemma-2-2b-it", name: "Gemma 2 2B IT" }, - { id: "google/gemma-3n-e2b-it", name: "Gemma 3n E2B IT" }, - { id: "meta/llama-3.1-8b-instruct", name: "Llama 3.1 8B Instruct", toolCalling: false }, { - id: "meta/llama-3.2-11b-vision-instruct", - name: "Llama 3.2 11B Vision Instruct", - supportsVision: true, - }, - { id: "meta/llama-3.2-1b-instruct", name: "Llama 3.2 1B Instruct" }, - { id: "meta/llama-3.2-3b-instruct", name: "Llama 3.2 3B Instruct", toolCalling: false }, - { - id: "meta/llama-3.2-90b-vision-instruct", - name: "Llama 3.2 90B Vision Instruct", - supportsVision: true, - }, - { id: "meta/llama-4-maverick-17b-128e-instruct", name: "Llama 4 Maverick 17B 128E Instruct" }, - { id: "meta/llama-guard-4-12b", name: "Llama Guard 4 12B", toolCalling: false }, - { id: "mistralai/ministral-14b-instruct-2512", name: "Ministral 14B Instruct 2512" }, - { id: "mistralai/mistral-medium-3.5-128b", name: "Mistral Medium 3.5 128B" }, - { id: "mistralai/mistral-nemotron", name: "Mistral Nemotron" }, - { id: "mistralai/mixtral-8x7b-instruct-v0.1", name: "Mixtral 8x7B Instruct v0.1" }, - { - id: "nvidia/ising-calibration-1-35b-a3b", - name: "Ising Calibration 1 35B A3B", - supportsReasoning: true, - }, - { - id: "nvidia/llama-3.1-nemoguard-8b-content-safety", - name: "Llama 3.1 Nemoguard 8B Content Safety", - }, - { - id: "nvidia/llama-3.1-nemoguard-8b-topic-control", - name: "Llama 3.1 Nemoguard 8B Topic Control", - }, - { id: "nvidia/llama-3.1-nemotron-nano-8b-v1", name: "Llama 3.1 Nemotron Nano 8B v1" }, - { - id: "nvidia/llama-3.1-nemotron-nano-vl-8b-v1", - name: "Llama 3.1 Nemotron Nano VL 8B v1", - supportsVision: true, - }, - { - id: "nvidia/llama-3.1-nemotron-safety-guard-8b-v3", - name: "Llama 3.1 Nemotron Safety Guard 8B v3", - }, - { id: "nvidia/llama-3.3-nemotron-super-49b-v1", name: "Llama 3.3 Nemotron Super 49B v1" }, - { id: "nvidia/llama-3.3-nemotron-super-49b-v1.5", name: "Llama 3.3 Nemotron Super 49B v1.5" }, - { id: "nvidia/nemotron-3-content-safety", name: "Nemotron 3 Content Safety" }, - { - id: "nvidia/nemotron-3-nano-30b-a3b", - name: "Nemotron 3 Nano 30B A3B", - supportsReasoning: true, + id: "nvidia/nemotron-3.5-lightning-30b-a3b", + name: "Nemotron 3.5 Lightning 30B A3B", }, { id: "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning", @@ -114,27 +44,6 @@ export const nvidiaProvider: RegistryEntry = { supportsReasoning: true, supportsVision: true, }, - { id: "nvidia/nemotron-3.5-content-safety", name: "Nemotron 3.5 Content Safety" }, - { id: "nvidia/nemotron-mini-4b-instruct", name: "Nemotron Mini 4B Instruct" }, - { - id: "nvidia/nemotron-nano-12b-v2-vl", - name: "Nemotron Nano 12B v2 VL", - supportsReasoning: true, - supportsVision: true, - }, - { - id: "nvidia/nvidia-nemotron-nano-9b-v2", - name: "NVIDIA Nemotron Nano 9B v2", - supportsReasoning: true, - }, - { id: "nvidia/riva-translate-4b-instruct-v1.1", name: "Riva Translate 4B Instruct v1.1" }, - { - id: "qwen/qwen3-next-80b-a3b-instruct", - name: "Qwen3 Next 80B A3B Instruct", - supportsReasoning: true, - }, - { id: "sarvamai/sarvam-m", name: "Sarvam M" }, - { id: "stockmark/stockmark-2-100b-instruct", name: "Stockmark 2 100B Instruct" }, - { id: "upstage/solar-10.7b-instruct", name: "Solar 10.7B Instruct" }, + { id: "openai/gpt-oss-120b", name: "GPT OSS 120B", toolCalling: false }, ], }; diff --git a/src/lib/providers/nvidiaValidationModel.ts b/src/lib/providers/nvidiaValidationModel.ts index bde123944b..07ef6291b4 100644 --- a/src/lib/providers/nvidiaValidationModel.ts +++ b/src/lib/providers/nvidiaValidationModel.ts @@ -9,11 +9,12 @@ * probe HANG until the validation timeout, which surfaces as a misleading "Upstream * Error" on an otherwise-valid key. * - * `meta/llama-3.1-8b-instruct` is a long-lived, universally-available NIM model (no - * special permission), so it is a far more reliable auth probe. A connection may still - * override it via `providerSpecificData.validationModelId`. + * The default must stay inside the current NVIDIA hosted-model catalog. Nemotron 3.5 + * Lightning is the smallest retained general chat model, which keeps the auth probe + * lightweight. A connection may still override it via + * `providerSpecificData.validationModelId`. */ -export const NVIDIA_DEFAULT_VALIDATION_MODEL = "meta/llama-3.1-8b-instruct"; +export const NVIDIA_DEFAULT_VALIDATION_MODEL = "nvidia/nemotron-3.5-lightning-30b-a3b"; export function resolveNvidiaValidationModel(providerSpecificData?: { validationModelId?: unknown; diff --git a/tests/integration/freeModelBenchmarkShared.ts b/tests/integration/freeModelBenchmarkShared.ts index caf5cd8e78..e732c6e0b6 100644 --- a/tests/integration/freeModelBenchmarkShared.ts +++ b/tests/integration/freeModelBenchmarkShared.ts @@ -56,8 +56,8 @@ export const FREE_MODELS: FreeModelSpec[] = [ displayName: "Gemini 3.1 Flash-Lite", }, { provider: "gemini", model: "gemini/gemma-4-31b-it", displayName: "Gemma 4 31B (Gemini)" }, - { provider: "nvidia", model: "nvidia/openai/gpt-oss-20b", displayName: "GPT OSS 20B (NVIDIA)" }, - { provider: "nvidia", model: "nvidia/z-ai/glm-5.1", displayName: "GLM 5.1 (NVIDIA)" }, + { provider: "nvidia", model: "nvidia/openai/gpt-oss-120b", displayName: "GPT OSS 120B (NVIDIA)" }, + { provider: "nvidia", model: "nvidia/moonshotai/kimi-k3", displayName: "Kimi K3 (NVIDIA)" }, { provider: "nvidia", model: "nvidia/google/gemma-4-31b-it", diff --git a/tests/unit/catalog-updates-v3x.test.ts b/tests/unit/catalog-updates-v3x.test.ts index e95132bec6..e233380490 100644 --- a/tests/unit/catalog-updates-v3x.test.ts +++ b/tests/unit/catalog-updates-v3x.test.ts @@ -23,18 +23,21 @@ test("Pollinations catalog mirrors the current public text model lineup", () => ); }); -test("NVIDIA catalog includes the verified 2026 additions and GPT OSS 20B alias resolution", () => { +test("NVIDIA catalog includes the current hosted models and GPT OSS 120B alias resolution", () => { const ids = new Set(getModelsByProviderId("nvidia").map((model) => model.id)); - assert.ok(ids.has("openai/gpt-oss-20b")); + assert.ok(ids.has("moonshotai/kimi-k3")); + assert.ok(ids.has("deepseek-ai/deepseek-v4-pro-0813")); + assert.ok(ids.has("deepseek-ai/deepseek-v4-flash-0731")); + assert.ok(ids.has("nvidia/nemotron-3.5-lightning-30b-a3b")); + assert.ok(ids.has("meta/muse-glimmer-30b")); + assert.ok(ids.has("google/diffusiongemma-26b-a4b-it")); + assert.ok(ids.has("openai/gpt-oss-120b")); assert.ok(ids.has("nvidia/nemotron-3-super-120b-a12b")); - assert.ok(ids.has("mistralai/mistral-large-3-675b-instruct-2512")); - assert.ok(ids.has("qwen/qwen3.5-397b-a17b")); - assert.ok(ids.has("mistralai/devstral-2-123b-instruct-2512")); - assert.deepEqual(resolveCanonicalProviderModel("nvidia", "gpt-oss-20b"), { + assert.deepEqual(resolveCanonicalProviderModel("nvidia", "gpt-oss-120b"), { provider: "nvidia", - model: "openai/gpt-oss-20b", + model: "openai/gpt-oss-120b", }); }); diff --git a/tests/unit/clinepass-thinking-budget.test.ts b/tests/unit/clinepass-thinking-budget.test.ts index b1452aedaa..7883294d0d 100644 --- a/tests/unit/clinepass-thinking-budget.test.ts +++ b/tests/unit/clinepass-thinking-budget.test.ts @@ -83,11 +83,11 @@ test("bumps undersized max_tokens for a non-clinepass reasoning provider (gate r // Nemotron Nano with supportsReasoning in the NVIDIA registry. const executor = new DefaultExecutor("nvidia"); const body = { - model: "nvidia/nvidia-nemotron-nano-9b-v2", + model: "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning", reasoning_effort: "high", max_tokens: 100, } as Record; - executor.ensureThinkingBudget(body, "nvidia/nvidia-nemotron-nano-9b-v2"); + executor.ensureThinkingBudget(body, "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning"); assert.equal(body.max_tokens, 4096); }); diff --git a/tests/unit/free-models.test.ts b/tests/unit/free-models.test.ts index e857db1bdf..0d4ae6a566 100644 --- a/tests/unit/free-models.test.ts +++ b/tests/unit/free-models.test.ts @@ -57,15 +57,12 @@ test("isFreeModel: a model id listed in the free catalog for that provider is fr assert.equal(isFreeModel(sample.provider, { id: sample.modelId }), true); }); -test("isFreeModel: NVIDIA GLM 5.2 is included in the reviewed trial catalog", () => { - assert.equal(isFreeModel("nvidia", { id: "z-ai/glm-5.2" }), true); +test("isFreeModel: NVIDIA GPT OSS 120B remains in the reviewed trial catalog", () => { + assert.equal(isFreeModel("nvidia", { id: "openai/gpt-oss-120b" }), true); }); test("selectModelsForImport: passthrough when importFreeOnly is false", () => { - const models = [ - { id: "a:free" }, - { id: "b", pricing: { prompt: "0.01", completion: "0.02" } }, - ]; + const models = [{ id: "a:free" }, { id: "b", pricing: { prompt: "0.01", completion: "0.02" } }]; const result = selectModelsForImport("openrouter", models, false); assert.equal(result.models.length, 2); assert.equal(result.freeFilterEmpty, false); @@ -130,8 +127,14 @@ test("sortModelsFreeFirst: deterministic (alphabetical) within each group, regar ], { isFree: (m) => m.isFree, key: (m) => m.id } ); - assert.deepEqual(a.map((m) => m.id), ["a", "b", "c"]); - assert.deepEqual(b.map((m) => m.id), ["a", "b", "c"]); + assert.deepEqual( + a.map((m) => m.id), + ["a", "b", "c"] + ); + assert.deepEqual( + b.map((m) => m.id), + ["a", "b", "c"] + ); }); test("sortModelsFreeFirst: does not mutate the input array", () => { @@ -141,5 +144,8 @@ test("sortModelsFreeFirst: does not mutate the input array", () => { ]; const before = items.map((m) => m.id); sortModelsFreeFirst(items, { isFree: (m) => m.isFree, key: (m) => m.id }); - assert.deepEqual(items.map((m) => m.id), before); + assert.deepEqual( + items.map((m) => m.id), + before + ); }); diff --git a/tests/unit/guardrails/combo-vision-provider-id-12112.test.ts b/tests/unit/guardrails/combo-vision-provider-id-12112.test.ts index 734e13e2fe..c4ddaf6fe9 100644 --- a/tests/unit/guardrails/combo-vision-provider-id-12112.test.ts +++ b/tests/unit/guardrails/combo-vision-provider-id-12112.test.ts @@ -3,29 +3,27 @@ import assert from "node:assert/strict"; process.env.DATA_DIR = `/tmp/omniroute-test-12112-${Date.now()}`; -const { getComboVisionBridgeDecision } = await import( - "../../../src/lib/guardrails/visionBridge.ts" -); +const { getComboVisionBridgeDecision } = + await import("../../../src/lib/guardrails/visionBridge.ts"); const combosDb = await import("../../../src/lib/db/combos.ts"); const core = await import("../../../src/lib/db/core.ts"); -const { isVisionIncompatibleTarget } = await import( - "../../../open-sse/services/combo/comboStructure.ts" -); +const { isVisionIncompatibleTarget } = + await import("../../../open-sse/services/combo/comboStructure.ts"); import type { ResolvedComboTarget } from "../../../open-sse/services/combo/types.ts"; test.after(() => { core.resetDbInstance(); }); -test("#12112: checkComboVision respects providerId for namespaced vision models (e.g. nvidia/nemotron-nano-12b-v2-vl)", async () => { - // Model 'nvidia/nemotron-nano-12b-v2-vl' is declared with supportsVision: true in nvidia provider registry. +test("#12112: checkComboVision respects providerId for namespaced vision models (e.g. nvidia/nemotron-3-nano-omni-30b-a3b-reasoning)", async () => { + // Model 'nvidia/nemotron-3-nano-omni-30b-a3b-reasoning' is declared with supportsVision: true in nvidia provider registry. // It has a slash in model id and requires providerId="nvidia" to resolve capabilities. await combosDb.createCombo({ name: "nvidia-vision-combo-12112", models: [ { providerId: "nvidia", - model: "nvidia/nemotron-nano-12b-v2-vl", + model: "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning", weight: 1, }, ], @@ -44,7 +42,7 @@ test("#12112: isVisionIncompatibleTarget passes providerId to resolve vision cap kind: "model", stepId: "step-1", executionKey: "step-1", - modelStr: "nvidia/nemotron-nano-12b-v2-vl", + modelStr: "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning", provider: "nvidia", providerId: "nvidia", connectionId: "conn-1", @@ -64,6 +62,6 @@ test("#12112: isVisionIncompatibleTarget passes providerId to resolve vision cap assert.equal( incompatible, false, - "Target with providerId='nvidia' and model='nvidia/nemotron-nano-12b-v2-vl' must be vision-compatible" + "Target with providerId='nvidia' and model='nvidia/nemotron-3-nano-omni-30b-a3b-reasoning' must be vision-compatible" ); }); diff --git a/tests/unit/model-capabilities-registry.test.ts b/tests/unit/model-capabilities-registry.test.ts index 7bb82681db..98adbbf21a 100644 --- a/tests/unit/model-capabilities-registry.test.ts +++ b/tests/unit/model-capabilities-registry.test.ts @@ -203,7 +203,7 @@ test("GPT OSS and DeepSeek Reasoner models support tool calling", () => { // GPT OSS models should not be blocked by the heuristic assert.equal(modelCapabilities.supportsToolCalling("fake-provider/gpt-oss-120b"), true); assert.equal(modelCapabilities.supportsToolCalling("gpt-oss-120b"), true); - assert.equal(modelCapabilities.supportsToolCalling("nvidia/openai/gpt-oss-20b"), false); // in registry + assert.equal(modelCapabilities.supportsToolCalling("nvidia/openai/gpt-oss-120b"), false); // in registry // DeepSeek Reasoner supports tool calling assert.equal(modelCapabilities.supportsToolCalling("deepseek-reasoner"), true); diff --git a/tests/unit/nvidia-410-model-scope.test.ts b/tests/unit/nvidia-410-model-scope.test.ts index 0d72fe1345..9865e1f5f8 100644 --- a/tests/unit/nvidia-410-model-scope.test.ts +++ b/tests/unit/nvidia-410-model-scope.test.ts @@ -15,7 +15,7 @@ const auth = await import("../../src/sse/services/auth.ts"); const fallback = await import("../../open-sse/services/accountFallback.ts"); const DEAD_MODEL = "deepseek-ai/deepseek-v4-pro"; -const HEALTHY_MODEL = "z-ai/glm-5.2"; +const HEALTHY_MODEL = "nvidia/nemotron-3.5-lightning-30b-a3b"; const GONE_BODY = JSON.stringify({ type: "about:blank", diff --git a/tests/unit/nvidia-eol-catalog.test.ts b/tests/unit/nvidia-eol-catalog.test.ts index ea8708d19e..f5319d08e0 100644 --- a/tests/unit/nvidia-eol-catalog.test.ts +++ b/tests/unit/nvidia-eol-catalog.test.ts @@ -13,20 +13,15 @@ const documentedFreeIds = new Set( const reviewedIds = new Set(reviewedLiveIds); -test("NVIDIA registry excludes retired DeepSeek V4 models", () => { - assert.ok( - !registryIds.has("deepseek-ai/deepseek-v4-pro"), - "retired deepseek-ai/deepseek-v4-pro must not be advertised" - ); - - assert.ok( - !registryIds.has("deepseek-ai/deepseek-v4-flash"), - "retired deepseek-ai/deepseek-v4-flash must not be advertised" - ); -}); - -test("NVIDIA static lifecycle metadata excludes known EOL models", () => { - for (const modelId of ["z-ai/glm-5.1", "deepseek-ai/deepseek-v4-pro"]) { +test("NVIDIA static catalog metadata excludes superseded model ids", () => { + for (const modelId of [ + "z-ai/glm-5.1", + "z-ai/glm-5.2", + "deepseek-ai/deepseek-v4-pro", + "deepseek-ai/deepseek-v4-flash", + "minimaxai/minimax-m2.7", + ]) { + assert.ok(!registryIds.has(modelId), `${modelId} must not remain in the NVIDIA registry`); assert.ok( !reviewedIds.has(modelId), `${modelId} must not remain in the reviewed NVIDIA hosted-model snapshot` @@ -39,16 +34,9 @@ test("NVIDIA static lifecycle metadata excludes known EOL models", () => { } }); -test("NVIDIA cleanup preserves the healthy GLM replacement", () => { - assert.ok(registryIds.has("z-ai/glm-5.2"), "z-ai/glm-5.2 must remain in the NVIDIA registry"); - - assert.ok( - reviewedIds.has("z-ai/glm-5.2"), - "z-ai/glm-5.2 must remain in the reviewed NVIDIA hosted-model snapshot" - ); - - assert.ok( - documentedFreeIds.has("z-ai/glm-5.2"), - "z-ai/glm-5.2 must remain in the NVIDIA free-model catalog" - ); +test("NVIDIA reviewed snapshot matches the registry and trial entries remain valid", () => { + assert.deepEqual([...reviewedIds], [...registryIds]); + for (const modelId of documentedFreeIds) { + assert.ok(registryIds.has(modelId), `${modelId} must exist in the NVIDIA hosted catalog`); + } }); diff --git a/tests/unit/nvidia-minimax-m3-removed-3329.test.ts b/tests/unit/nvidia-minimax-m3-removed-3329.test.ts index 77e0ce4822..f0c8b6d502 100644 --- a/tests/unit/nvidia-minimax-m3-removed-3329.test.ts +++ b/tests/unit/nvidia-minimax-m3-removed-3329.test.ts @@ -4,16 +4,16 @@ import assert from "node:assert/strict"; const { getRegistryEntry } = await import("../../open-sse/config/providerRegistry.ts"); // #3329: `minimaxai/minimax-m3` was registered in the nvidia (NVIDIA NIM) tier, -// but NVIDIA NIM does not host it — every request returns `404 page not found`, -// while sibling models on the same provider (e.g. `minimaxai/minimax-m2.7`) -// work. Advertising a model that 404s is a catalog bug; it is removed from the -// nvidia tier until NVIDIA actually serves it. It remains on the tiers that do -// (minimax / minimax-cn / opencode / etc.). +// but NVIDIA NIM does not host it — every request returns `404 page not found`. +// Advertising a model that 404s is a catalog bug; it stays absent from the +// NVIDIA tier while remaining available from providers that actually serve it. test("nvidia tier does not advertise minimaxai/minimax-m3 (404 upstream) (#3329)", () => { const nvidia = getRegistryEntry("nvidia"); assert.ok(nvidia, "nvidia registry entry must exist"); const ids = (nvidia.models ?? []).map((m) => m.id); assert.ok(!ids.includes("minimaxai/minimax-m3"), "minimaxai/minimax-m3 must not be in nvidia"); - // sanity: the working sibling stays listed - assert.ok(ids.includes("minimaxai/minimax-m2.7"), "minimaxai/minimax-m2.7 stays available"); + assert.ok( + !ids.includes("minimaxai/minimax-m2.7"), + "removed minimaxai/minimax-m2.7 must stay out" + ); }); diff --git a/tests/unit/nvidia-nim-catalog-expansion-2373.test.ts b/tests/unit/nvidia-nim-catalog-expansion-2373.test.ts deleted file mode 100644 index 32d14a8a00..0000000000 --- a/tests/unit/nvidia-nim-catalog-expansion-2373.test.ts +++ /dev/null @@ -1,81 +0,0 @@ -import test from "node:test"; -import assert from "node:assert/strict"; - -import { nvidiaProvider } from "../../open-sse/config/providers/registry/nvidia/index.ts"; - -// Port of decolua/9router#2373 ("fix(nvidia): expand NIM chat model catalog"). Upstream's -// PR also added a per-model `thinkingFormat`/`kind` capability shape in a legacy -// open-sse/providers/capabilities.js file that has no equivalent in OmniRoute — reasoning -// translation here is per-PROVIDER (open-sse/translator/paramSupport.ts, -// executors/default.ts, both gated on `this.provider === "nvidia"`), not per-model, so -// only the catalog (RegistryModel.supportsReasoning/supportsVision) needed porting. -// Embedding/ASR/TTS entries from the same upstream PR are already covered by -// open-sse/config/embeddingRegistry.ts and audioRegistry.ts, so they are not duplicated -// here. `minimaxai/minimax-m3` is intentionally excluded — see the #3329 guard -// (nvidia-minimax-m3-removed-3329.test.ts). -const modelIds = new Set(nvidiaProvider.models.map((m) => m.id)); - -test("#2373: NVIDIA NIM registry gains the newly-observed chat-completions models", () => { - for (const id of [ - "abacusai/dracarys-llama-3.1-70b-instruct", - "google/gemma-2-2b-it", - "google/gemma-3n-e2b-it", - "meta/llama-3.1-8b-instruct", - "meta/llama-3.2-11b-vision-instruct", - "meta/llama-4-maverick-17b-128e-instruct", - "meta/llama-guard-4-12b", - "mistralai/ministral-14b-instruct-2512", - "mistralai/mistral-medium-3.5-128b", - "mistralai/mistral-nemotron", - "mistralai/mixtral-8x7b-instruct-v0.1", - "nvidia/ising-calibration-1-35b-a3b", - "nvidia/llama-3.1-nemoguard-8b-content-safety", - "nvidia/llama-3.3-nemotron-super-49b-v1.5", - "nvidia/nemotron-3-nano-30b-a3b", - "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning", - "nvidia/nemotron-nano-12b-v2-vl", - "nvidia/nvidia-nemotron-nano-9b-v2", - "qwen/qwen3-next-80b-a3b-instruct", - "sarvamai/sarvam-m", - "stockmark/stockmark-2-100b-instruct", - "upstage/solar-10.7b-instruct", - ]) { - assert.ok(modelIds.has(id), `expected nvidia registry to include ${id}`); - } -}); - -test("#2373: reasoning-capable NVIDIA-hosted models are flagged supportsReasoning", () => { - const reasoningIds = [ - "nvidia/ising-calibration-1-35b-a3b", - "nvidia/nemotron-3-nano-30b-a3b", - "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning", - "nvidia/nemotron-nano-12b-v2-vl", - "nvidia/nvidia-nemotron-nano-9b-v2", - "qwen/qwen3-next-80b-a3b-instruct", - ]; - for (const id of reasoningIds) { - const model = nvidiaProvider.models.find((m) => m.id === id); - assert.ok(model, `model ${id} must exist`); - assert.equal(model?.supportsReasoning, true, `${id} must be supportsReasoning: true`); - } -}); - -test("#2373/#3329: minimaxai/minimax-m3 stays excluded from the nvidia tier", () => { - assert.ok( - !modelIds.has("minimaxai/minimax-m3"), - "minimaxai/minimax-m3 must not be re-added to the nvidia registry (404 upstream, #3329)" - ); - // sanity: the working sibling stays listed - assert.ok(modelIds.has("minimaxai/minimax-m2.7"), "minimaxai/minimax-m2.7 stays available"); -}); - -test("#2373: non-chat model kinds (NER/diffusion) from the upstream PR are not ported into the chat registry", () => { - assert.ok( - !modelIds.has("nvidia/gliner-pii"), - "nvidia/gliner-pii is an NER/PII tagger, not a chat-completions model" - ); - assert.ok( - !modelIds.has("google/diffusiongemma-26b-a4b-it"), - "google/diffusiongemma-26b-a4b-it is a diffusion model, not a chat-completions model" - ); -}); diff --git a/tests/unit/nvidia-nim-registry-6108.test.ts b/tests/unit/nvidia-nim-registry-6108.test.ts index b9c12d9992..702747656d 100644 --- a/tests/unit/nvidia-nim-registry-6108.test.ts +++ b/tests/unit/nvidia-nim-registry-6108.test.ts @@ -3,21 +3,45 @@ import assert from "node:assert/strict"; import { nvidiaProvider } from "../../open-sse/config/providers/registry/nvidia/index.ts"; -// Regression guard for #6108: the static NVIDIA NIM model registry had gone -// stale — z-ai/glm-5.1 was EOL'd (410) 2026-07-02, while glm-5.2 and -// nvidia/nemotron-3-ultra-550b-a55b were absent. minimaxai/minimax-m3 stays -// excluded per the #3329 guard (nvidia-minimax-m3-removed-3329.test.ts) — the -// single 200 probe in #6108 wasn't reproducible enough to override it. -const modelIds = new Set(nvidiaProvider.models.map((m) => m.id)); +const EXPECTED_MODEL_IDS = [ + "moonshotai/kimi-k3", + "deepseek-ai/deepseek-v4-pro-0813", + "deepseek-ai/deepseek-v4-flash-0731", + "meta/muse-glimmer-30b", + "poolside/laguna-xs-2.1", + "google/gemma-4-31b-it", + "google/diffusiongemma-26b-a4b-it", + "nvidia/nemotron-3-ultra-550b-a55b", + "nvidia/nemotron-3-super-120b-a12b", + "nvidia/nemotron-3.5-lightning-30b-a3b", + "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning", + "openai/gpt-oss-120b", +] as const; -test("#6108: NVIDIA NIM registry contains the refreshed live models", () => { - assert.ok(modelIds.has("z-ai/glm-5.2"), "z-ai/glm-5.2 must be present"); - assert.ok( - modelIds.has("nvidia/nemotron-3-ultra-550b-a55b"), - "nvidia/nemotron-3-ultra-550b-a55b must be present" +test("NVIDIA NIM registry exactly matches the current hosted-model catalog", () => { + assert.deepEqual( + nvidiaProvider.models.map((model) => model.id), + EXPECTED_MODEL_IDS ); }); -test("#6108: NVIDIA NIM registry no longer lists EOL z-ai/glm-5.1", () => { - assert.ok(!modelIds.has("z-ai/glm-5.1"), "EOL z-ai/glm-5.1 must be removed"); +test("NVIDIA NIM registry preserves known model capabilities", () => { + const byId = new Map(nvidiaProvider.models.map((model) => [model.id, model])); + + for (const id of [ + "deepseek-ai/deepseek-v4-pro-0813", + "deepseek-ai/deepseek-v4-flash-0731", + "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning", + ]) { + assert.equal(byId.get(id)?.supportsReasoning, true, `${id} must support reasoning`); + } + + const omni = byId.get("nvidia/nemotron-3-nano-omni-30b-a3b-reasoning"); + assert.equal(omni?.supportsVision, true, "Nemotron 3 Nano Omni must support vision"); + + assert.equal( + byId.get("openai/gpt-oss-120b")?.toolCalling, + false, + "openai/gpt-oss-120b must keep tool calling disabled" + ); }); diff --git a/tests/unit/nvidia-nim-validator.test.ts b/tests/unit/nvidia-nim-validator.test.ts index f6f82e44f6..b6c2c5518d 100644 --- a/tests/unit/nvidia-nim-validator.test.ts +++ b/tests/unit/nvidia-nim-validator.test.ts @@ -135,7 +135,7 @@ test("nvidia specialty validator falls back to stable chat validation model", as calls.some((u) => u.endsWith("/chat/completions")), `should fall back to /chat/completions, called: ${JSON.stringify(calls)}` ); - assert.equal(payload?.model, "meta/llama-3.1-8b-instruct"); + assert.equal(payload?.model, "nvidia/nemotron-3.5-lightning-30b-a3b"); } ); }); diff --git a/tests/unit/nvidia-passthrough-models-6773.test.ts b/tests/unit/nvidia-passthrough-models-6773.test.ts index 915b541413..9275367845 100644 --- a/tests/unit/nvidia-passthrough-models-6773.test.ts +++ b/tests/unit/nvidia-passthrough-models-6773.test.ts @@ -2,8 +2,8 @@ * Regression test for #6773 — NVIDIA NIM models listed available:true but 404 at router. * * Root cause: the `nvidia` provider registry entry multiplexes many distinct - * third-party vendor models (z-ai/, minimaxai/, deepseek-ai/, qwen/, - * mistralai/, stepfun-ai/, moonshotai/, openai/, nvidia/) behind ONE base URL + * third-party vendor models (moonshotai/, deepseek-ai/, nvidia/, meta/, + * poolside/, google/, openai/) behind ONE base URL * and ONE API key connection — architecturally identical to `modelscope`, * `synthetic`, and `kilo-gateway`, which all set `passthroughModels: true` so * that a single model's 404/429 stays scoped to that model instead of cooling @@ -24,8 +24,8 @@ test("#6773: nvidia registry entry sets passthroughModels", () => { entry?.passthroughModels, true, "nvidia multiplexes many third-party vendor models behind one connection " + - "(z-ai/, minimaxai/, deepseek-ai/, qwen/, mistralai/, stepfun-ai/, " + - "moonshotai/, openai/, nvidia/) — it should set passthroughModels: true " + + "(moonshotai/, deepseek-ai/, nvidia/, meta/, poolside/, google/, " + + "openai/) — it should set passthroughModels: true " + "like modelscope/synthetic/kilo-gateway, so a single stale model 404 " + "does not cool down the whole connection for all other models" ); @@ -33,7 +33,7 @@ test("#6773: nvidia registry entry sets passthroughModels", () => { test("#6773: hasPerModelQuota('nvidia') is true, so a 404 on one nvidia model is model-scoped", () => { assert.equal( - accountFallback.hasPerModelQuota("nvidia", "z-ai/glm-5.2"), + accountFallback.hasPerModelQuota("nvidia", "nvidia/nemotron-3.5-lightning-30b-a3b"), true, "expected nvidia to use per-model lockout (like gemini/github/codex/compatible " + "providers) so a 404 on one model doesn't cool down the other nvidia models" @@ -50,7 +50,7 @@ test("#6773: checkFallbackError + lockModelIfPerModelQuota scope a single-model 404, "Not Found", 0, - "z-ai/glm-5.2", + "nvidia/nemotron-3.5-lightning-30b-a3b", "nvidia", null, null, @@ -66,7 +66,7 @@ test("#6773: checkFallbackError + lockModelIfPerModelQuota scope a single-model const locked = accountFallback.lockModelIfPerModelQuota( "nvidia", "conn-6773", - "z-ai/glm-5.2", + "nvidia/nemotron-3.5-lightning-30b-a3b", "unknown", result.cooldownMs ?? 30_000 ); diff --git a/tests/unit/nvidia-validation-model-3116.test.ts b/tests/unit/nvidia-validation-model-3116.test.ts index 1d52f68059..da7e541fd2 100644 --- a/tests/unit/nvidia-validation-model-3116.test.ts +++ b/tests/unit/nvidia-validation-model-3116.test.ts @@ -2,7 +2,7 @@ * #3116 — NVIDIA key validation probed the first catalog model (`z-ai/glm-5.1`), which * requires the "Public API Endpoints" account permission and can hang/be DEGRADED, * making a *valid* key fail with a misleading "Upstream Error". The probe now defaults to - * the universally-available `meta/llama-3.1-8b-instruct`, with a per-connection override. + * a lightweight model from the current hosted catalog, with a per-connection override. */ import test from "node:test"; import assert from "node:assert/strict"; @@ -12,10 +12,10 @@ import { resolveNvidiaValidationModel, } from "../../src/lib/providers/nvidiaValidationModel.ts"; -test("defaults to a stable, permission-free NVIDIA model (not the gated glm-5.1)", () => { - assert.equal(NVIDIA_DEFAULT_VALIDATION_MODEL, "meta/llama-3.1-8b-instruct"); - assert.equal(resolveNvidiaValidationModel(), "meta/llama-3.1-8b-instruct"); - assert.equal(resolveNvidiaValidationModel({}), "meta/llama-3.1-8b-instruct"); +test("defaults to a lightweight model in the current NVIDIA catalog", () => { + assert.equal(NVIDIA_DEFAULT_VALIDATION_MODEL, "nvidia/nemotron-3.5-lightning-30b-a3b"); + assert.equal(resolveNvidiaValidationModel(), "nvidia/nemotron-3.5-lightning-30b-a3b"); + assert.equal(resolveNvidiaValidationModel({}), "nvidia/nemotron-3.5-lightning-30b-a3b"); assert.notEqual(resolveNvidiaValidationModel(undefined), "z-ai/glm-5.1"); }); @@ -25,5 +25,8 @@ test("honors a per-connection validationModelId override", () => { "nvidia/llama-3.3-nemotron-super-49b" ); // blank/whitespace override falls back to the default - assert.equal(resolveNvidiaValidationModel({ validationModelId: " " }), NVIDIA_DEFAULT_VALIDATION_MODEL); + assert.equal( + resolveNvidiaValidationModel({ validationModelId: " " }), + NVIDIA_DEFAULT_VALIDATION_MODEL + ); }); diff --git a/tests/unit/opencode-go-effort-aliases-8353.test.ts b/tests/unit/opencode-go-effort-aliases-8353.test.ts index 762de5fcd2..c743623f93 100644 --- a/tests/unit/opencode-go-effort-aliases-8353.test.ts +++ b/tests/unit/opencode-go-effort-aliases-8353.test.ts @@ -283,12 +283,3 @@ test("#10788 registry base rows declare the same tiers EFFORT_TIERS parses", () } } }); - -test("#10788 nvidia z-ai/glm-5.2 declares reasoning with an empty tier list (binary switch)", () => { - const entry = REGISTRY["nvidia"]; - assert.ok(entry?.models, "nvidia must expose models"); - const row = entry.models.find((m) => m.id === "z-ai/glm-5.2"); - assert.ok(row, "nvidia z-ai/glm-5.2 must exist"); - assert.equal(row.supportsReasoning, true); - assert.deepEqual(row.supportedThinkingEfforts, []); -});