From 47ec6237ffbc28b9fa711799357d9745f47ad6ab Mon Sep 17 00:00:00 2001
From: Agustin Rivera <31522568+eleqtrizit@users.noreply.github.com>
Date: Thu, 9 Jul 2026 13:09:38 -0700
Subject: [PATCH] fix(nvidia): sync recommended models with featured catalog
(#99242)
* fix(nvidia): refresh bundled featured models
* fix(nvidia): match featured model feed exactly
* fix(nvidia): remove transient feed detail
* fix(nvidia): correct super context window
* fix(nvidia): align auth choice expectation
* fix(nvidia): hide deprecated models from selection
Refresh the bundled featured catalog while retaining deprecated model metadata for exact-reference compatibility. Route NVIDIA onboarding and catalog picker surfaces through selectable-only provider builders.
* fix(nvidia): simplify featured model table
* fix(nvidia): restore shipped compatibility rows
---
docs/providers/nvidia.md | 38 +--
extensions/nvidia/index.test.ts | 42 ++--
extensions/nvidia/index.ts | 8 +-
extensions/nvidia/onboard.test.ts | 41 +++-
extensions/nvidia/onboard.ts | 4 +-
extensions/nvidia/openclaw.plugin.json | 141 +++++++++--
extensions/nvidia/provider-catalog.test.ts | 264 ++++++++++++++++-----
extensions/nvidia/provider-catalog.ts | 25 +-
8 files changed, 418 insertions(+), 145 deletions(-)
diff --git a/docs/providers/nvidia.md b/docs/providers/nvidia.md
index 1056e8c4e58e..0f3a1f3103c9 100644
--- a/docs/providers/nvidia.md
+++ b/docs/providers/nvidia.md
@@ -84,8 +84,6 @@ OpenClaw falls back to the bundled catalog and bundled default below.
Nemotron 3 Ultra is the default NVIDIA model in OpenClaw. NVIDIA's build page for
[`nvidia/nemotron-3-ultra-550b-a55b`](https://build.nvidia.com/nvidia/nemotron-3-ultra-550b-a55b)
lists it as an available free endpoint with a 1M-token context specification.
-The bundled catalog records a 16,384-token max output to match NVIDIA's current
-OpenAI-compatible sample request for the hosted endpoint.
The bundled Ultra row sends
`chat_template_kwargs: { enable_thinking: false, force_nonempty_content: true }`
@@ -98,15 +96,25 @@ hosted in NVIDIA's catalog when their context, latency, or behavior fits better.
## Bundled fallback catalog
-| Model ref | Name | Context | Max output | Notes |
-| ------------------------------------------ | ---------------------------- | --------- | ---------- | ---------------------------------------- |
-| `nvidia/nvidia/nemotron-3-ultra-550b-a55b` | NVIDIA Nemotron 3 Ultra 550B | 1,000,000 | 16,384 | Default |
-| `nvidia/nvidia/nemotron-3-super-120b-a12b` | NVIDIA Nemotron 3 Super 120B | 1,048,576 | 8,192 | |
-| `nvidia/moonshotai/kimi-k2.5` | Kimi K2.5 | 262,144 | 8,192 | |
-| `nvidia/minimaxai/minimax-m2.7` | Minimax M2.7 | 196,608 | 8,192 | |
-| `nvidia/z-ai/glm-5.1` | GLM 5.1 | 202,752 | 8,192 | |
-| `nvidia/minimaxai/minimax-m2.5` | MiniMax M2.5 | 196,608 | 8,192 | Deprecated; use `minimaxai/minimax-m2.7` |
-| `nvidia/z-ai/glm5` | GLM-5 | 202,752 | 8,192 | Deprecated; use `z-ai/glm-5.1` |
+The selectable bundled rows snapshot NVIDIA's featured-model catalog. Deprecated
+compatibility rows remain resolvable by exact reference but stay out of model
+pickers.
+
+| Model ref | Name | Context | Max output |
+| ------------------------------------------ | --------------------- | --------- | ---------- |
+| `nvidia/nvidia/nemotron-3-ultra-550b-a55b` | Nemotron 3 Ultra 550B | 1,048,576 | 8,192 |
+| `nvidia/nvidia/nemotron-3-super-120b-a12b` | Nemotron 3 Super 120B | 1,000,000 | 8,192 |
+| `nvidia/z-ai/glm-5.2` | GLM 5.2 | 202,752 | 8,192 |
+| `nvidia/moonshotai/kimi-k2.6` | Kimi K2.6 | 262,144 | 8,192 |
+| `nvidia/minimaxai/minimax-m3` | Minimax M3 | 196,608 | 8,192 |
+| `nvidia/deepseek-ai/deepseek-v4-pro` | DeepSeek V4 Pro | 262,144 | 16,384 |
+| `nvidia/qwen/qwen3.5-397b-a17b` | Qwen3.5 397B A17B | 262,144 | 16,384 |
+
+The full compatibility catalog also retains these shipped refs for existing
+configurations: `nvidia/moonshotai/kimi-k2.5`, `nvidia/z-ai/glm-5.1`,
+`nvidia/minimaxai/minimax-m2.5`, `nvidia/z-ai/glm5`, and
+`nvidia/minimaxai/minimax-m2.7`. They remain available by exact reference but
+never appear in onboarding or model pickers.
## Advanced configuration
@@ -119,10 +127,10 @@ hosted in NVIDIA's catalog when their context, latency, or behavior fits better.
OpenClaw prefers NVIDIA's public featured-model catalog when NVIDIA auth is
- configured and caches it for 24 hours. The bundled fallback catalog is static
- and keeps deprecated shipped refs for upgrade compatibility. Costs default
- to `0` in source since NVIDIA currently offers free API access for the
- listed models.
+ configured and caches it for 24 hours. The bundled selectable fallback is a
+ static snapshot of NVIDIA's featured-model catalog; deprecated exact-reference
+ compatibility rows are hidden from model pickers. Costs default to `0` in
+ source since NVIDIA currently offers free API access for the listed models.
diff --git a/extensions/nvidia/index.test.ts b/extensions/nvidia/index.test.ts
index 09379a916e70..828a0290cbe7 100644
--- a/extensions/nvidia/index.test.ts
+++ b/extensions/nvidia/index.test.ts
@@ -209,11 +209,11 @@ describe("nvidia provider hooks", () => {
expect(entries?.map((entry) => entry.id)).toEqual([
"nvidia/nemotron-3-ultra-550b-a55b",
"nvidia/nemotron-3-super-120b-a12b",
- "moonshotai/kimi-k2.5",
- "minimaxai/minimax-m2.7",
- "z-ai/glm-5.1",
- "minimaxai/minimax-m2.5",
- "z-ai/glm5",
+ "z-ai/glm-5.2",
+ "moonshotai/kimi-k2.6",
+ "minimaxai/minimax-m3",
+ "deepseek-ai/deepseek-v4-pro",
+ "qwen/qwen3.5-397b-a17b",
]);
expect(entries?.every((entry) => entry.provider === "nvidia")).toBe(true);
expect(ssrfRuntimeMocks.fetchWithSsrFGuard).not.toHaveBeenCalled();
@@ -228,11 +228,11 @@ describe("nvidia provider hooks", () => {
expect(entries?.map((entry) => entry.id)).toEqual([
"nvidia/nemotron-3-ultra-550b-a55b",
"nvidia/nemotron-3-super-120b-a12b",
- "moonshotai/kimi-k2.5",
- "minimaxai/minimax-m2.7",
- "z-ai/glm-5.1",
- "minimaxai/minimax-m2.5",
- "z-ai/glm5",
+ "z-ai/glm-5.2",
+ "moonshotai/kimi-k2.6",
+ "minimaxai/minimax-m3",
+ "deepseek-ai/deepseek-v4-pro",
+ "qwen/qwen3.5-397b-a17b",
]);
expect(entries?.every((entry) => entry.provider === "nvidia")).toBe(true);
expect(ssrfRuntimeMocks.fetchWithSsrFGuard).toHaveBeenCalledTimes(1);
@@ -242,8 +242,8 @@ describe("nvidia provider hooks", () => {
mockFeaturedCatalogResponse({
"featured-models": [
{
- model: "minimaxai/minimax-m2.7",
- "model-name": "Minimax M2.7",
+ model: "minimaxai/minimax-m3",
+ "model-name": "Minimax M3",
context: 196608,
"max-output": 8192,
},
@@ -253,7 +253,7 @@ describe("nvidia provider hooks", () => {
const entries = await provider.augmentModelCatalog?.(buildAugmentCatalogContext("nvapi-test"));
- expect(entries?.map((entry) => entry.id)).toEqual(["minimaxai/minimax-m2.7"]);
+ expect(entries?.map((entry) => entry.id)).toEqual(["minimaxai/minimax-m3"]);
});
it("opts into literal provider-prefix preservation", async () => {
@@ -280,8 +280,8 @@ describe("nvidia provider hooks", () => {
mockFeaturedCatalogResponse({
"featured-models": [
{
- model: "minimaxai/minimax-m2.7",
- "model-name": "Minimax M2.7",
+ model: "minimaxai/minimax-m3",
+ "model-name": "Minimax M3",
context: 196608,
"max-output": 8192,
},
@@ -297,18 +297,18 @@ describe("nvidia provider hooks", () => {
expect(staticRows?.map((entry) => `${entry.source}:${entry.provider}/${entry.model}`)).toEqual([
"static:nvidia/nvidia/nemotron-3-ultra-550b-a55b",
"static:nvidia/nvidia/nemotron-3-super-120b-a12b",
- "static:nvidia/moonshotai/kimi-k2.5",
- "static:nvidia/minimaxai/minimax-m2.7",
- "static:nvidia/z-ai/glm-5.1",
- "static:nvidia/minimaxai/minimax-m2.5",
- "static:nvidia/z-ai/glm5",
+ "static:nvidia/z-ai/glm-5.2",
+ "static:nvidia/moonshotai/kimi-k2.6",
+ "static:nvidia/minimaxai/minimax-m3",
+ "static:nvidia/deepseek-ai/deepseek-v4-pro",
+ "static:nvidia/qwen/qwen3.5-397b-a17b",
]);
await expect(catalogProvider?.liveCatalog?.(buildCatalogContext())).resolves.toEqual([]);
const liveRows = await catalogProvider?.liveCatalog?.(buildCatalogContext("nvapi-test"));
expect(liveRows?.map((entry) => `${entry.source}:${entry.provider}/${entry.model}`)).toEqual([
- "live:nvidia/minimaxai/minimax-m2.7",
+ "live:nvidia/minimaxai/minimax-m3",
]);
});
diff --git a/extensions/nvidia/index.ts b/extensions/nvidia/index.ts
index 9bcac3aaa048..e49cb70241fb 100644
--- a/extensions/nvidia/index.ts
+++ b/extensions/nvidia/index.ts
@@ -3,7 +3,7 @@ import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-en
import { applyNvidiaConfig, NVIDIA_DEFAULT_MODEL_REF } from "./onboard.js";
import {
buildLiveNvidiaProvider,
- buildNvidiaProvider,
+ buildSelectableNvidiaProvider,
buildSelectableLiveNvidiaProvider,
} from "./provider-catalog.js";
@@ -22,7 +22,9 @@ async function buildNvidiaCatalogModels(ctx: {
env: NodeJS.ProcessEnv;
resolveProviderApiKey?: (providerId?: string) => { apiKey: string | undefined };
}) {
- const provider = hasNvidiaApiToken(ctx) ? await buildLiveNvidiaProvider() : buildNvidiaProvider();
+ const provider = hasNvidiaApiToken(ctx)
+ ? await buildLiveNvidiaProvider()
+ : buildSelectableNvidiaProvider();
return provider.models.map((model) => ({
provider: PROVIDER_ID,
id: model.id,
@@ -57,7 +59,7 @@ export default defineSingleProviderPluginEntry({
],
catalog: {
buildProvider: buildSelectableLiveNvidiaProvider,
- buildStaticProvider: buildNvidiaProvider,
+ buildStaticProvider: buildSelectableNvidiaProvider,
},
augmentModelCatalog: buildNvidiaCatalogModels,
wizard: {
diff --git a/extensions/nvidia/onboard.test.ts b/extensions/nvidia/onboard.test.ts
index c320391dc8cd..172ebc065816 100644
--- a/extensions/nvidia/onboard.test.ts
+++ b/extensions/nvidia/onboard.test.ts
@@ -18,11 +18,11 @@ describe("nvidia onboard", () => {
expect(provider.models.map((model) => model.id)).toEqual([
"nvidia/nemotron-3-ultra-550b-a55b",
"nvidia/nemotron-3-super-120b-a12b",
- "moonshotai/kimi-k2.5",
- "minimaxai/minimax-m2.7",
- "z-ai/glm-5.1",
- "minimaxai/minimax-m2.5",
- "z-ai/glm5",
+ "z-ai/glm-5.2",
+ "moonshotai/kimi-k2.6",
+ "minimaxai/minimax-m3",
+ "deepseek-ai/deepseek-v4-pro",
+ "qwen/qwen3.5-397b-a17b",
]);
// Config stores the canonical form; the picker label shows the literal
// form via preserveLiteralProviderPrefix.
@@ -46,11 +46,34 @@ describe("nvidia onboard", () => {
"nvidia/custom-model",
"nvidia/nemotron-3-ultra-550b-a55b",
"nvidia/nemotron-3-super-120b-a12b",
+ "z-ai/glm-5.2",
+ "moonshotai/kimi-k2.6",
+ "minimaxai/minimax-m3",
+ "deepseek-ai/deepseek-v4-pro",
+ "qwen/qwen3.5-397b-a17b",
+ ]);
+ });
+
+ it("preserves an existing deprecated exact-reference model", () => {
+ const provider = expectProviderOnboardMergedLegacyConfig({
+ applyProviderConfig: applyNvidiaProviderConfig,
+ providerId: "nvidia",
+ providerApi: "openai-completions",
+ baseUrl: "https://integrate.api.nvidia.com/v1",
+ legacyApi: "openai-completions",
+ legacyModelId: "moonshotai/kimi-k2.5",
+ legacyModelName: "Kimi K2.5",
+ });
+
+ expect(provider?.models.map((model) => model.id)).toEqual([
"moonshotai/kimi-k2.5",
- "minimaxai/minimax-m2.7",
- "z-ai/glm-5.1",
- "minimaxai/minimax-m2.5",
- "z-ai/glm5",
+ "nvidia/nemotron-3-ultra-550b-a55b",
+ "nvidia/nemotron-3-super-120b-a12b",
+ "z-ai/glm-5.2",
+ "moonshotai/kimi-k2.6",
+ "minimaxai/minimax-m3",
+ "deepseek-ai/deepseek-v4-pro",
+ "qwen/qwen3.5-397b-a17b",
]);
});
});
diff --git a/extensions/nvidia/onboard.ts b/extensions/nvidia/onboard.ts
index ca5276654733..7a9c977663dc 100644
--- a/extensions/nvidia/onboard.ts
+++ b/extensions/nvidia/onboard.ts
@@ -3,14 +3,14 @@ import {
createDefaultModelsPresetAppliers,
type OpenClawConfig,
} from "openclaw/plugin-sdk/provider-onboard";
-import { buildNvidiaProvider, NVIDIA_DEFAULT_MODEL_ID } from "./provider-catalog.js";
+import { buildSelectableNvidiaProvider, NVIDIA_DEFAULT_MODEL_ID } from "./provider-catalog.js";
export const NVIDIA_DEFAULT_MODEL_REF = NVIDIA_DEFAULT_MODEL_ID;
const nvidiaPresetAppliers = createDefaultModelsPresetAppliers({
primaryModelRef: NVIDIA_DEFAULT_MODEL_REF,
resolveParams: (_cfg: OpenClawConfig) => {
- const defaultProvider = buildNvidiaProvider();
+ const defaultProvider = buildSelectableNvidiaProvider();
return {
providerId: "nvidia",
api: defaultProvider.api ?? "openai-completions",
diff --git a/extensions/nvidia/openclaw.plugin.json b/extensions/nvidia/openclaw.plugin.json
index 4b7c5fdffe4f..7fe523d1f200 100644
--- a/extensions/nvidia/openclaw.plugin.json
+++ b/extensions/nvidia/openclaw.plugin.json
@@ -28,10 +28,10 @@
"models": [
{
"id": "nvidia/nemotron-3-ultra-550b-a55b",
- "name": "NVIDIA Nemotron 3 Ultra 550B",
+ "name": "Nemotron 3 Ultra 550B",
"input": ["text"],
- "contextWindow": 1000000,
- "maxTokens": 16384,
+ "contextWindow": 1048576,
+ "maxTokens": 8192,
"cost": {
"input": 0,
"output": 0,
@@ -44,9 +44,9 @@
},
{
"id": "nvidia/nemotron-3-super-120b-a12b",
- "name": "NVIDIA Nemotron 3 Super 120B",
+ "name": "Nemotron 3 Super 120B",
"input": ["text"],
- "contextWindow": 1048576,
+ "contextWindow": 1000000,
"maxTokens": 8192,
"cost": {
"input": 0,
@@ -58,6 +58,86 @@
"requiresStringContent": true
}
},
+ {
+ "id": "z-ai/glm-5.2",
+ "name": "GLM 5.2",
+ "input": ["text"],
+ "contextWindow": 202752,
+ "maxTokens": 8192,
+ "cost": {
+ "input": 0,
+ "output": 0,
+ "cacheRead": 0,
+ "cacheWrite": 0
+ },
+ "compat": {
+ "requiresStringContent": true
+ }
+ },
+ {
+ "id": "moonshotai/kimi-k2.6",
+ "name": "Kimi K2.6",
+ "input": ["text"],
+ "contextWindow": 262144,
+ "maxTokens": 8192,
+ "cost": {
+ "input": 0,
+ "output": 0,
+ "cacheRead": 0,
+ "cacheWrite": 0
+ },
+ "compat": {
+ "requiresStringContent": true
+ }
+ },
+ {
+ "id": "minimaxai/minimax-m3",
+ "name": "Minimax M3",
+ "input": ["text"],
+ "contextWindow": 196608,
+ "maxTokens": 8192,
+ "cost": {
+ "input": 0,
+ "output": 0,
+ "cacheRead": 0,
+ "cacheWrite": 0
+ },
+ "compat": {
+ "requiresStringContent": true
+ }
+ },
+ {
+ "id": "deepseek-ai/deepseek-v4-pro",
+ "name": "DeepSeek V4 Pro",
+ "input": ["text"],
+ "contextWindow": 262144,
+ "maxTokens": 16384,
+ "cost": {
+ "input": 0,
+ "output": 0,
+ "cacheRead": 0,
+ "cacheWrite": 0
+ },
+ "compat": {
+ "requiresStringContent": true
+ }
+ },
+ {
+ "id": "qwen/qwen3.5-397b-a17b",
+ "name": "Qwen3.5 397B A17B",
+ "input": ["text"],
+ "contextWindow": 262144,
+ "maxTokens": 16384,
+ "cost": {
+ "input": 0,
+ "output": 0,
+ "cacheRead": 0,
+ "cacheWrite": 0
+ },
+ "compat": {
+ "requiresStringContent": true
+ }
+ },
{
"id": "moonshotai/kimi-k2.5",
"name": "Kimi K2.5",
@@ -72,23 +152,10 @@
},
"compat": {
"requiresStringContent": true
- }
- },
- {
- "id": "minimaxai/minimax-m2.7",
- "name": "Minimax M2.7",
- "input": ["text"],
- "contextWindow": 196608,
- "maxTokens": 8192,
- "cost": {
- "input": 0,
- "output": 0,
- "cacheRead": 0,
- "cacheWrite": 0
},
- "compat": {
- "requiresStringContent": true
- }
+ "status": "deprecated",
+ "statusReason": "Still available by exact reference; use moonshotai/kimi-k2.6 for new NVIDIA setups.",
+ "replacedBy": "moonshotai/kimi-k2.6"
},
{
"id": "z-ai/glm-5.1",
@@ -104,7 +171,10 @@
},
"compat": {
"requiresStringContent": true
- }
+ },
+ "status": "deprecated",
+ "statusReason": "Still available by exact reference; use z-ai/glm-5.2 for new NVIDIA setups.",
+ "replacedBy": "z-ai/glm-5.2"
},
{
"id": "minimaxai/minimax-m2.5",
@@ -122,8 +192,8 @@
"requiresStringContent": true
},
"status": "deprecated",
- "statusReason": "Shipped compatibility row; use minimaxai/minimax-m2.7 for new NVIDIA setups.",
- "replacedBy": "minimaxai/minimax-m2.7"
+ "statusReason": "Still available by exact reference; use minimaxai/minimax-m3 for new NVIDIA setups.",
+ "replacedBy": "minimaxai/minimax-m3"
},
{
"id": "z-ai/glm5",
@@ -141,8 +211,27 @@
"requiresStringContent": true
},
"status": "deprecated",
- "statusReason": "Shipped compatibility row; use z-ai/glm-5.1 for new NVIDIA setups.",
- "replacedBy": "z-ai/glm-5.1"
+ "statusReason": "Still available by exact reference; use z-ai/glm-5.2 for new NVIDIA setups.",
+ "replacedBy": "z-ai/glm-5.2"
+ },
+ {
+ "id": "minimaxai/minimax-m2.7",
+ "name": "Minimax M2.7",
+ "input": ["text"],
+ "contextWindow": 196608,
+ "maxTokens": 8192,
+ "cost": {
+ "input": 0,
+ "output": 0,
+ "cacheRead": 0,
+ "cacheWrite": 0
+ },
+ "compat": {
+ "requiresStringContent": true
+ },
+ "status": "deprecated",
+ "statusReason": "Still available by exact reference; use minimaxai/minimax-m3 for new NVIDIA setups.",
+ "replacedBy": "minimaxai/minimax-m3"
}
]
}
diff --git a/extensions/nvidia/provider-catalog.test.ts b/extensions/nvidia/provider-catalog.test.ts
index bce32fb1f2d3..5c1e511e343d 100644
--- a/extensions/nvidia/provider-catalog.test.ts
+++ b/extensions/nvidia/provider-catalog.test.ts
@@ -1,13 +1,88 @@
// Nvidia tests cover provider catalog plugin behavior.
import { afterEach, describe, expect, it, vi } from "vitest";
+import manifest from "./openclaw.plugin.json" with { type: "json" };
import {
buildLiveNvidiaProvider,
buildNvidiaProvider,
+ buildSelectableNvidiaProvider,
buildSelectableLiveNvidiaProvider,
clearNvidiaFeaturedModelCacheForTests,
NVIDIA_FEATURED_MODELS_URL,
} from "./provider-catalog.js";
+const EXPECTED_FEATURED_MODELS = [
+ {
+ id: "nvidia/nemotron-3-ultra-550b-a55b",
+ name: "Nemotron 3 Ultra 550B",
+ contextWindow: 1_048_576,
+ maxTokens: 8_192,
+ },
+ {
+ id: "nvidia/nemotron-3-super-120b-a12b",
+ name: "Nemotron 3 Super 120B",
+ contextWindow: 1_000_000,
+ maxTokens: 8_192,
+ },
+ { id: "z-ai/glm-5.2", name: "GLM 5.2", contextWindow: 202_752, maxTokens: 8_192 },
+ {
+ id: "moonshotai/kimi-k2.6",
+ name: "Kimi K2.6",
+ contextWindow: 262_144,
+ maxTokens: 8_192,
+ },
+ {
+ id: "minimaxai/minimax-m3",
+ name: "Minimax M3",
+ contextWindow: 196_608,
+ maxTokens: 8_192,
+ },
+ {
+ id: "deepseek-ai/deepseek-v4-pro",
+ name: "DeepSeek V4 Pro",
+ contextWindow: 262_144,
+ maxTokens: 16_384,
+ },
+ {
+ id: "qwen/qwen3.5-397b-a17b",
+ name: "Qwen3.5 397B A17B",
+ contextWindow: 262_144,
+ maxTokens: 16_384,
+ },
+] as const;
+
+const EXPECTED_DEPRECATED_MODELS = [
+ {
+ id: "moonshotai/kimi-k2.5",
+ name: "Kimi K2.5",
+ contextWindow: 262_144,
+ maxTokens: 8_192,
+ },
+ {
+ id: "z-ai/glm-5.1",
+ name: "GLM 5.1",
+ contextWindow: 202_752,
+ maxTokens: 8_192,
+ },
+ {
+ id: "minimaxai/minimax-m2.5",
+ name: "MiniMax M2.5",
+ contextWindow: 196_608,
+ maxTokens: 8_192,
+ },
+ { id: "z-ai/glm5", name: "GLM-5", contextWindow: 202_752, maxTokens: 8_192 },
+ {
+ id: "minimaxai/minimax-m2.7",
+ name: "Minimax M2.7",
+ contextWindow: 196_608,
+ maxTokens: 8_192,
+ },
+] as const;
+
+const EXPECTED_BUNDLED_MODELS = [
+ ...EXPECTED_FEATURED_MODELS,
+ ...EXPECTED_DEPRECATED_MODELS,
+] as const;
+
const ssrfRuntimeMocks = vi.hoisted(() => ({
fetchWithSsrFGuard: vi.fn(),
ssrfPolicyFromHttpBaseUrlAllowedHostname: vi.fn((baseUrl: string) => ({
@@ -41,21 +116,20 @@ describe("nvidia provider catalog", () => {
expect(provider.baseUrl).toBe("https://integrate.api.nvidia.com/v1");
expect(provider.api).toBe("openai-completions");
expect(provider.apiKey).toBe("NVIDIA_API_KEY");
- expect(provider.models.map((model) => model.id)).toEqual([
- "nvidia/nemotron-3-ultra-550b-a55b",
- "nvidia/nemotron-3-super-120b-a12b",
- "moonshotai/kimi-k2.5",
- "minimaxai/minimax-m2.7",
- "z-ai/glm-5.1",
- "minimaxai/minimax-m2.5",
- "z-ai/glm5",
- ]);
+ expect(
+ provider.models.map(({ id, name, contextWindow, maxTokens }) => ({
+ id,
+ name,
+ contextWindow,
+ maxTokens,
+ })),
+ ).toEqual(EXPECTED_BUNDLED_MODELS);
expect(provider.models.filter((model) => model.compat?.requiresStringContent !== true)).toEqual(
[],
);
expect(provider.models[0]).toMatchObject({
- contextWindow: 1_000_000,
- maxTokens: 16_384,
+ contextWindow: 1_048_576,
+ maxTokens: 8_192,
params: {
chat_template_kwargs: {
enable_thinking: false,
@@ -65,16 +139,35 @@ describe("nvidia provider catalog", () => {
});
expect(provider.models[1]).toMatchObject({
id: "nvidia/nemotron-3-super-120b-a12b",
- contextWindow: 1_048_576,
+ contextWindow: 1_000_000,
});
+ expect(
+ manifest.modelCatalog.providers.nvidia.models
+ .filter((model) => "status" in model && model.status === "deprecated")
+ .map((model) => ({ id: model.id, replacedBy: model.replacedBy })),
+ ).toEqual([
+ { id: "moonshotai/kimi-k2.5", replacedBy: "moonshotai/kimi-k2.6" },
+ { id: "z-ai/glm-5.1", replacedBy: "z-ai/glm-5.2" },
+ { id: "minimaxai/minimax-m2.5", replacedBy: "minimaxai/minimax-m3" },
+ { id: "z-ai/glm5", replacedBy: "z-ai/glm-5.2" },
+ { id: "minimaxai/minimax-m2.7", replacedBy: "minimaxai/minimax-m3" },
+ ]);
+ });
+
+ it("keeps deprecated exact-reference rows out of the selectable catalog", () => {
+ const provider = buildSelectableNvidiaProvider();
+
+ expect(provider.models.map((model) => model.id)).toEqual(
+ EXPECTED_FEATURED_MODELS.map((model) => model.id),
+ );
});
it("promotes ranked models from NVIDIA's featured catalog", async () => {
const release = mockFeaturedCatalogResponse({
"featured-models": [
{
- model: "z-ai/glm-5.1",
- "model-name": "GLM 5.1",
+ model: "z-ai/glm-5.2",
+ "model-name": "GLM 5.2",
context: 202752,
"max-output": 8192,
},
@@ -90,11 +183,11 @@ describe("nvidia provider catalog", () => {
const provider = await buildLiveNvidiaProvider();
expect(provider.models.map((model) => model.id)).toEqual([
- "z-ai/glm-5.1",
+ "z-ai/glm-5.2",
"nvidia/nemotron-3-super-120b-a12b",
]);
expect(provider.models[0]).toMatchObject({
- name: "GLM 5.1",
+ name: "GLM 5.2",
contextWindow: 202752,
maxTokens: 8192,
compat: { requiresStringContent: true },
@@ -117,22 +210,8 @@ describe("nvidia provider catalog", () => {
const provider = await buildLiveNvidiaProvider();
- expect(provider.models.map((model) => model.id)).toEqual([
- "nvidia/nemotron-3-ultra-550b-a55b",
- "nvidia/nemotron-3-super-120b-a12b",
- "moonshotai/kimi-k2.5",
- "minimaxai/minimax-m2.7",
- "z-ai/glm-5.1",
- "minimaxai/minimax-m2.5",
- "z-ai/glm5",
- ]);
- });
-
- it("retains shipped NVIDIA model refs as bundled fallback compatibility rows", () => {
- const provider = buildNvidiaProvider();
-
expect(provider.models.map((model) => model.id)).toEqual(
- expect.arrayContaining(["minimaxai/minimax-m2.5", "z-ai/glm5"]),
+ EXPECTED_FEATURED_MODELS.map((model) => model.id),
);
});
@@ -140,8 +219,8 @@ describe("nvidia provider catalog", () => {
mockFeaturedCatalogResponse({
"featured-models": [
{
- model: "z-ai/glm-5.1",
- "model-name": "GLM 5.1",
+ model: "z-ai/glm-5.2",
+ "model-name": "GLM 5.2",
context: 202752,
"max-output": 8192,
},
@@ -157,11 +236,75 @@ describe("nvidia provider catalog", () => {
const provider = await buildSelectableLiveNvidiaProvider();
expect(provider.models.map((model) => model.id)).toEqual([
- "z-ai/glm-5.1",
+ "z-ai/glm-5.2",
"nvidia/nemotron-3-super-120b-a12b",
]);
});
+ it("keeps every deprecated exact-reference row out of live catalogs", async () => {
+ mockFeaturedCatalogResponse({
+ "featured-models": [
+ {
+ model: "minimaxai/minimax-m3",
+ "model-name": "Minimax M3",
+ context: 196608,
+ "max-output": 8192,
+ },
+ ...EXPECTED_DEPRECATED_MODELS.map((model) => ({
+ model: model.id,
+ "model-name": model.name,
+ context: model.contextWindow,
+ "max-output": model.maxTokens,
+ })),
+ ],
+ });
+
+ const live = await buildLiveNvidiaProvider();
+ const selectableLive = await buildSelectableLiveNvidiaProvider();
+
+ expect(live.models.map((model) => model.id)).toEqual(["minimaxai/minimax-m3"]);
+ expect(selectableLive.models.map((model) => model.id)).toEqual(["minimaxai/minimax-m3"]);
+ });
+
+ it("maps current featured feed metadata for MiniMax, DeepSeek, and Qwen", async () => {
+ mockFeaturedCatalogResponse({
+ "featured-models": [
+ {
+ model: "minimaxai/minimax-m3",
+ "model-name": "Minimax M3",
+ context: 196608,
+ "max-output": 8192,
+ },
+ {
+ model: "deepseek-ai/deepseek-v4-pro",
+ "model-name": "DeepSeek V4 Pro",
+ context: 262144,
+ "max-output": 16384,
+ },
+ {
+ model: "qwen/qwen3.5-397b-a17b",
+ "model-name": "Qwen3.5 397B A17B",
+ context: 262144,
+ "max-output": 16384,
+ },
+ ],
+ });
+
+ const provider = await buildLiveNvidiaProvider();
+
+ expect(
+ provider.models.map(({ id, contextWindow, maxTokens }) => ({
+ id,
+ contextWindow,
+ maxTokens,
+ })),
+ ).toEqual([
+ { id: "minimaxai/minimax-m3", contextWindow: 196_608, maxTokens: 8_192 },
+ { id: "deepseek-ai/deepseek-v4-pro", contextWindow: 262_144, maxTokens: 16_384 },
+ { id: "qwen/qwen3.5-397b-a17b", contextWindow: 262_144, maxTokens: 16_384 },
+ ]);
+ });
+
it("returns no selectable live rows when the featured catalog is unavailable", async () => {
mockFeaturedCatalogResponse({ error: "unavailable" }, 503);
@@ -180,8 +323,8 @@ describe("nvidia provider catalog", () => {
"max-output": 1000,
},
{
- model: "minimaxai/minimax-m2.7",
- "model-name": "Minimax M2.7",
+ model: "minimaxai/minimax-m3",
+ "model-name": "Minimax M3",
context: 196608,
"max-output": 8192,
},
@@ -196,15 +339,15 @@ describe("nvidia provider catalog", () => {
const provider = await buildLiveNvidiaProvider();
- expect(provider.models.map((model) => model.id)).toEqual(["minimaxai/minimax-m2.7"]);
+ expect(provider.models.map((model) => model.id)).toEqual(["minimaxai/minimax-m3"]);
});
it("caches the featured catalog for repeated provider builds", async () => {
mockFeaturedCatalogResponse({
"featured-models": [
{
- model: "minimaxai/minimax-m2.7",
- "model-name": "Minimax M2.7",
+ model: "minimaxai/minimax-m3",
+ "model-name": "Minimax M3",
context: 196608,
"max-output": 8192,
},
@@ -222,8 +365,8 @@ describe("nvidia provider catalog", () => {
mockFeaturedCatalogResponse({
"featured-models": [
{
- model: "minimaxai/minimax-m2.7",
- "model-name": "Minimax M2.7",
+ model: "minimaxai/minimax-m3",
+ "model-name": "Minimax M3",
context: 196608,
"max-output": 8192,
},
@@ -232,8 +375,8 @@ describe("nvidia provider catalog", () => {
mockFeaturedCatalogResponse({
"featured-models": [
{
- model: "z-ai/glm-5.1",
- "model-name": "GLM 5.1",
+ model: "z-ai/glm-5.2",
+ "model-name": "GLM 5.2",
context: 202752,
"max-output": 8192,
},
@@ -243,8 +386,8 @@ describe("nvidia provider catalog", () => {
const first = await buildLiveNvidiaProvider();
const second = await buildLiveNvidiaProvider();
- expect(first.models.map((model) => model.id)).toEqual(["minimaxai/minimax-m2.7"]);
- expect(second.models.map((model) => model.id)).toEqual(["z-ai/glm-5.1"]);
+ expect(first.models.map((model) => model.id)).toEqual(["minimaxai/minimax-m3"]);
+ expect(second.models.map((model) => model.id)).toEqual(["z-ai/glm-5.2"]);
expect(ssrfRuntimeMocks.fetchWithSsrFGuard).toHaveBeenCalledTimes(2);
});
@@ -262,8 +405,8 @@ describe("nvidia provider catalog", () => {
mockFeaturedCatalogResponse({
"featured-models": [
{
- model: "z-ai/glm-5.1",
- "model-name": "GLM 5.1",
+ model: "z-ai/glm-5.2",
+ "model-name": "GLM 5.2",
context: 202752,
"max-output": 8192,
},
@@ -273,16 +416,10 @@ describe("nvidia provider catalog", () => {
const first = await buildLiveNvidiaProvider();
const second = await buildLiveNvidiaProvider();
- expect(first.models.map((model) => model.id)).toEqual([
- "nvidia/nemotron-3-ultra-550b-a55b",
- "nvidia/nemotron-3-super-120b-a12b",
- "moonshotai/kimi-k2.5",
- "minimaxai/minimax-m2.7",
- "z-ai/glm-5.1",
- "minimaxai/minimax-m2.5",
- "z-ai/glm5",
- ]);
- expect(second.models.map((model) => model.id)).toEqual(["z-ai/glm-5.1"]);
+ expect(first.models.map((model) => model.id)).toEqual(
+ EXPECTED_FEATURED_MODELS.map((model) => model.id),
+ );
+ expect(second.models.map((model) => model.id)).toEqual(["z-ai/glm-5.2"]);
expect(ssrfRuntimeMocks.fetchWithSsrFGuard).toHaveBeenCalledTimes(2);
});
@@ -292,8 +429,8 @@ describe("nvidia provider catalog", () => {
{
model: "nemotron-3-ultra-550b-a55b",
"model-name": "Nemotron 3 Ultra 550B",
- context: 1000000,
- "max-output": 16384,
+ context: 1048576,
+ "max-output": 8192,
},
{
model: "minimaxai/minimax-m2.7",
@@ -306,14 +443,11 @@ describe("nvidia provider catalog", () => {
const provider = await buildLiveNvidiaProvider();
- expect(provider.models.map((model) => model.id)).toEqual([
- "nvidia/nemotron-3-ultra-550b-a55b",
- "minimaxai/minimax-m2.7",
- ]);
+ expect(provider.models.map((model) => model.id)).toEqual(["nvidia/nemotron-3-ultra-550b-a55b"]);
expect(provider.models[0]).toMatchObject({
name: "Nemotron 3 Ultra 550B",
- contextWindow: 1_000_000,
- maxTokens: 16_384,
+ contextWindow: 1_048_576,
+ maxTokens: 8_192,
params: {
chat_template_kwargs: {
enable_thinking: false,
diff --git a/extensions/nvidia/provider-catalog.ts b/extensions/nvidia/provider-catalog.ts
index 163e4cec35de..85d4efec6751 100644
--- a/extensions/nvidia/provider-catalog.ts
+++ b/extensions/nvidia/provider-catalog.ts
@@ -39,6 +39,11 @@ const NVIDIA_ULTRA_DEFAULT_PARAMS = {
force_nonempty_content: true,
},
} as const;
+const DEPRECATED_NVIDIA_MODEL_IDS = new Set(
+ manifest.modelCatalog.providers.nvidia.models
+ .filter((model) => "status" in model && model.status === "deprecated")
+ .map((model) => model.id),
+);
type NvidiaFeaturedModel = {
model: string;
@@ -79,20 +84,28 @@ export function buildNvidiaProvider(): ModelProviderConfig {
};
}
-export async function buildLiveNvidiaProvider(): Promise {
+export function buildSelectableNvidiaProvider(): ModelProviderConfig {
const provider = buildNvidiaProvider();
+ return {
+ ...provider,
+ models: filterSelectableNvidiaModels(provider.models ?? []),
+ };
+}
+
+export async function buildLiveNvidiaProvider(): Promise {
+ const provider = buildSelectableNvidiaProvider();
const featuredModels = await loadNvidiaFeaturedModels();
if (!featuredModels || featuredModels.length === 0) {
return provider;
}
return {
...provider,
- models: applyNvidiaModelDefaults(featuredModels),
+ models: applyNvidiaModelDefaults(filterSelectableNvidiaModels(featuredModels)),
};
}
export async function buildSelectableLiveNvidiaProvider(): Promise {
- const provider = buildNvidiaProvider();
+ const provider = buildSelectableNvidiaProvider();
const featuredModels = await loadNvidiaFeaturedModels();
if (!featuredModels || featuredModels.length === 0) {
return {
@@ -102,7 +115,7 @@ export async function buildSelectableLiveNvidiaProvider(): Promise !DEPRECATED_NVIDIA_MODEL_IDS.has(model.id));
+}
+
function parseNvidiaFeaturedModel(row: unknown): ModelDefinitionConfig | null {
if (!row || typeof row !== "object") {
return null;