mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-13 18:32:12 +03:00
feat(providers): refresh NVIDIA hosted models (#12538)
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.
This commit is contained in:
@@ -17,9 +17,9 @@
|
||||
|
||||
</div>
|
||||
|
||||
> 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`).
|
||||
|
||||
<img src="./docs/diagrams/free-tier-budget.svg" width="100%" alt="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."/>
|
||||
<img src="./docs/diagrams/free-tier-budget.svg" width="100%" alt="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)
|
||||
|
||||
</div>
|
||||
|
||||
> **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).
|
||||
|
||||
<div align="center">
|
||||
|
||||
@@ -1270,7 +1270,7 @@ Métricas canônicas em 2026-08-24: **1.029 vídeos únicos** · **11.132.922 vi
|
||||
<tr><td nowrap><b><a href="docs/architecture/RESILIENCE_GUIDE.md">Resilience Guide</a></b></td><td>Circuit breakers, cooldowns, queue, anti-thundering herd, TLS spoofing</td></tr>
|
||||
<tr><td nowrap><b><a href="docs/routing/AUTO-COMBO.md">Auto-Combo Engine</a></b></td><td>16-factor scoring, mode packs, self-healing</td></tr>
|
||||
<tr><td nowrap><b><a href="docs/ops/PROXY_GUIDE.md">Proxy Guide</a></b></td><td>3-level proxy system, 1proxy marketplace, registry CRUD</td></tr>
|
||||
<tr><td nowrap><b><a href="docs/reference/FREE_TIERS.md">Free Tiers</a></b></td><td>Consolidated directory: 38 documented recurring pools / 446 cataloged free-tier entries</td></tr>
|
||||
<tr><td nowrap><b><a href="docs/reference/FREE_TIERS.md">Free Tiers</a></b></td><td>Consolidated directory: 38 documented recurring pools / 437 cataloged free-tier entries</td></tr>
|
||||
<tr><td nowrap><b><a href="docs/guides/FEATURES.md">Features Gallery</a></b></td><td>Visual dashboard tour with screenshots</td></tr>
|
||||
<tr><td nowrap><b><a href="docs/architecture/CODEBASE_DOCUMENTATION.md">Codebase Documentation</a></b></td><td>Beginner-friendly codebase walkthrough</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<svg viewBox="0 0 1200 842" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="OmniRoute free-tier budget: about 1.51 billion free tokens per month steady, up to about 2.13 billion in the first month with signup credits. The catalog contains 446 rows, 439 active and 7 discontinued, grouped into 38 recurring pool keys; 20 pools have a published positive monthly token budget and 18 have a zero, uncapped, or keyless budget. Honest pool-deduped math counts each shared free pool once; 13 providers carry a terms-of-service avoid flag. The 20 quantified pools are Mistral 1 billion, LLM7 150 million, Nara 150 million, Gemini 60 million, Cerebras 30 million, Cloudflare AI 30 million, API Airforce 24 million, Ollama Cloud 20 million, Groq 15 million, Bluesminds 7.2 million, SambaNova 6 million, Arcee 4.8 million, Navy 4.5 million, BazaarLink 3.6 million, OpenRouter 1.2 million, Cohere 800 thousand, HuggingChat 500 thousand, Morph 400 thousand, Hugging Face 200 thousand, and Kiro 25 thousand. One-time signup credits add about 626 million. Uncapped providers and the OpenRouter top-up boost are shown separately so they do not inflate the headline. Live usage remains available at /dashboard/free-tiers.">
|
||||
<svg viewBox="0 0 1200 842" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="OmniRoute free-tier budget: about 1.51 billion free tokens per month steady, up to about 2.13 billion in the first month with signup credits. The catalog contains 437 rows, 430 active and 7 discontinued, grouped into 38 recurring pool keys; 20 pools have a published positive monthly token budget and 18 have a zero, uncapped, or keyless budget. Honest pool-deduped math counts each shared free pool once; 13 providers carry a terms-of-service avoid flag. The 20 quantified pools are Mistral 1 billion, LLM7 150 million, Nara 150 million, Gemini 60 million, Cerebras 30 million, Cloudflare AI 30 million, API Airforce 24 million, Ollama Cloud 20 million, Groq 15 million, Bluesminds 7.2 million, SambaNova 6 million, Arcee 4.8 million, Navy 4.5 million, BazaarLink 3.6 million, OpenRouter 1.2 million, Cohere 800 thousand, HuggingChat 500 thousand, Morph 400 thousand, Hugging Face 200 thousand, and Kiro 25 thousand. One-time signup credits add about 626 million. Uncapped providers and the OpenRouter top-up boost are shown separately so they do not inflate the headline. Live usage remains available at /dashboard/free-tiers.">
|
||||
<desc>Pool-deduplicated chart of the 20 recurring free-token pools with positive published budgets, plus signup credits and uncapped providers shown separately.</desc>
|
||||
<defs>
|
||||
<pattern id="gridPaperF" width="32" height="32" patternUnits="userSpaceOnUse">
|
||||
@@ -64,7 +64,7 @@
|
||||
<text x="60" y="228" font-family="Consolas, 'Courier New', monospace" font-size="104" font-weight="800" fill="url(#gradBrandF)">~1.51B</text>
|
||||
<text x="62" y="266" font-family="Consolas, 'Courier New', monospace" font-size="15" letter-spacing="3" font-weight="700" fill="#a1a1aa">FREE TOKENS / MONTH · <tspan fill="#22c55e">STEADY</tspan></text>
|
||||
<text x="62" y="298" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="16" fill="#F7F6FC">up to <tspan font-weight="800" fill="#22c55e">~2.13B</tspan> in your first month — signup credits</text>
|
||||
<text x="62" y="326" font-family="Consolas, 'Courier New', monospace" font-size="12" fill="#71717a">documented free tiers · <tspan fill="#8b5cf6">38 recurring pools</tspan> · <tspan fill="#8b5cf6">446 catalog entries</tspan> · one endpoint</text>
|
||||
<text x="62" y="326" font-family="Consolas, 'Courier New', monospace" font-size="12" fill="#71717a">documented free tiers · <tspan fill="#8b5cf6">38 recurring pools</tspan> · <tspan fill="#8b5cf6">437 catalog entries</tspan> · one endpoint</text>
|
||||
|
||||
<!-- ═══ Panel · The honest math ═══ -->
|
||||
<rect x="680" y="84" width="460" height="216" rx="14" fill="#161b22" stroke="#ffffff" stroke-opacity="0.08" stroke-width="1"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
@@ -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" },
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
|
||||
@@ -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 },
|
||||
],
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -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<string, unknown>;
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
@@ -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
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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`);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
});
|
||||
@@ -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"
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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, []);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user