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
This commit is contained in:
Agustin Rivera
2026-07-09 13:09:38 -07:00
committed by GitHub
parent bf84515463
commit 47ec6237ff
8 changed files with 418 additions and 145 deletions
+23 -15
View File
@@ -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.
<Accordion title="Catalog and pricing">
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.
</Accordion>
<Accordion title="OpenAI-compatible endpoint">
+21 -21
View File
@@ -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",
]);
});
+5 -3
View File
@@ -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: {
+32 -9
View File
@@ -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",
]);
});
});
+2 -2
View File
@@ -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",
+115 -26
View File
@@ -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"
}
]
}
+199 -65
View File
@@ -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,
+21 -4
View File
@@ -39,6 +39,11 @@ const NVIDIA_ULTRA_DEFAULT_PARAMS = {
force_nonempty_content: true,
},
} as const;
const DEPRECATED_NVIDIA_MODEL_IDS = new Set<string>(
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<ModelProviderConfig> {
export function buildSelectableNvidiaProvider(): ModelProviderConfig {
const provider = buildNvidiaProvider();
return {
...provider,
models: filterSelectableNvidiaModels(provider.models ?? []),
};
}
export async function buildLiveNvidiaProvider(): Promise<ModelProviderConfig> {
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<ModelProviderConfig> {
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<ModelProvider
}
return {
...provider,
models: applyNvidiaModelDefaults(featuredModels),
models: applyNvidiaModelDefaults(filterSelectableNvidiaModels(featuredModels)),
};
}
@@ -166,6 +179,10 @@ function applyNvidiaModelDefaults(models: ModelDefinitionConfig[]): ModelDefinit
);
}
function filterSelectableNvidiaModels(models: ModelDefinitionConfig[]): ModelDefinitionConfig[] {
return models.filter((model) => !DEPRECATED_NVIDIA_MODEL_IDS.has(model.id));
}
function parseNvidiaFeaturedModel(row: unknown): ModelDefinitionConfig | null {
if (!row || typeof row !== "object") {
return null;