Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/lib/inference/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,10 +342,14 @@ describe("getSandboxInferenceConfig", () => {

it("maps NVIDIA Endpoints to the routed inference provider", () => {
expect(
getSandboxInferenceConfig("qwen/qwen3.5-397b-a17b", "nvidia-prod", "openai-completions"),
getSandboxInferenceConfig(
"nvidia/nemotron-3-super-120b-a12b",
"nvidia-prod",
"openai-completions",
),
).toEqual({
providerKey: MANAGED_PROVIDER_ID,
primaryModelRef: `${MANAGED_PROVIDER_ID}/qwen/qwen3.5-397b-a17b`,
primaryModelRef: `${MANAGED_PROVIDER_ID}/nvidia/nemotron-3-super-120b-a12b`,
inferenceBaseUrl: INFERENCE_ROUTE_URL,
inferenceApi: "openai-completions",
inferenceCompat: null,
Expand Down
1 change: 0 additions & 1 deletion src/lib/inference/health.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,6 @@ describe("inference health", () => {

it.each([
"deepseek-ai/deepseek-v4-pro",
"qwen/qwen3.5-397b-a17b",
"deepseek-ai/deepseek-v4-flash",
])("reports the short status timeout as unverified for slow model %s", (model) => {
const result = probeRemoteProviderHealth("nvidia-prod", {
Expand Down
13 changes: 0 additions & 13 deletions src/lib/inference/nvidia-featured-models.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,6 @@ describe("NVIDIA featured model catalog", () => {
).toEqual([{ id: "nvidia/nemotron-3-super-120b-a12b", label: "Nemotron 3 Super 120B" }]);
});

it("rewrites stale Minimax M2.7 catalog IDs and labels to M3 (#5827)", () => {
expect(
parseNvidiaFeaturedModels(
JSON.stringify({
"featured-models": [
{ model: "minimaxai/minimax-m2.7", "model-name": "Minimax M2.7" },
{ model: "minimaxai/minimax-m3", "model-name": "Minimax M3 duplicate" },
],
}),
),
).toEqual([{ id: "minimaxai/minimax-m3", label: "Minimax M3" }]);
});

it("filters models whose catalogs outlive their NVIDIA Endpoints routes", () => {
expect(
parseNvidiaFeaturedModels(
Expand Down
20 changes: 1 addition & 19 deletions src/lib/inference/nvidia-featured-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,6 @@ export type FeaturedModelFetchResult =
/** Normalizes NVIDIA featured-model catalog IDs into endpoint model IDs. */
function normalizeFeaturedModelId(model: string): string {
const trimmed = model.trim();
// Minimax rollout contract (#5827): the external feed has emitted the stale
// M2.7 ID/label while CLOUD_MODEL_OPTIONS and the task-fit docs define M3 as
// the NVIDIA Endpoints choice. This is an upstream-lag bridge; remove this ID
// rewrite together with the label rewrite and fixture only once the feed no
// longer emits M2.7 and publishes M3 directly.
if (trimmed === "minimaxai/minimax-m2.7") {
return "minimaxai/minimax-m3";
}
// Nemotron namespace contract (#5827): the external feed has emitted bare
// nemotron-3-* IDs, while CLOUD_MODEL_OPTIONS and the matching OpenClaw
// model-specific setup manifest use the canonical nvidia/ endpoint namespace.
Expand All @@ -94,16 +86,6 @@ function sanitizeFeaturedCatalogText(value: string, maxLength: number): string {
.slice(0, maxLength);
}

/** Normalizes NVIDIA featured-model labels for known catalog lag cases. */
function normalizeFeaturedModelLabel(id: string, label: string): string {
const sanitized = sanitizeFeaturedCatalogText(label, MAX_NVIDIA_FEATURED_MODEL_LABEL_LENGTH);
// Keep the display label coupled to the Minimax rollout contract above.
if (id === "minimaxai/minimax-m3" && /^minimax m2\.7$/i.test(sanitized)) {
return "Minimax M3";
}
return sanitized;
}

function isRetiredFeaturedModelId(
idKey: string,
retiredModelIds: RetiredFeaturedModelIds,
Expand Down Expand Up @@ -136,7 +118,7 @@ export function parseNvidiaFeaturedModels(
const idKey = id.toLowerCase();
const label =
typeof item?.["model-name"] === "string"
? normalizeFeaturedModelLabel(id, item["model-name"])
? sanitizeFeaturedCatalogText(item["model-name"], MAX_NVIDIA_FEATURED_MODEL_LABEL_LENGTH)
: "";
if (
!id ||
Expand Down
22 changes: 10 additions & 12 deletions src/lib/inference/onboard-probes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,21 +332,19 @@ describe("OpenAI-compatible inference probes", () => {
}
});

it("uses an extended validation budget for slow NVIDIA Build models", () => {
for (const model of ["qwen/qwen3.5-397b-a17b", "deepseek-ai/deepseek-v4-flash"]) {
const args = getChatCompletionsProbeCurlArgs({
credentialArgs: FAKE_CREDENTIAL_ARGS,
model,
url: "https://integrate.api.nvidia.com/v1/chat/completions",
isWsl: false,
});
expect(args[args.indexOf("--connect-timeout") + 1]).toBe("10");
expect(args[args.indexOf("--max-time") + 1]).toBe("300");
}
it("uses an extended validation budget for DeepSeek V4 Flash", () => {
const args = getChatCompletionsProbeCurlArgs({
credentialArgs: FAKE_CREDENTIAL_ARGS,
model: "deepseek-ai/deepseek-v4-flash",
url: "https://integrate.api.nvidia.com/v1/chat/completions",
isWsl: false,
});
expect(args[args.indexOf("--connect-timeout") + 1]).toBe("10");
expect(args[args.indexOf("--max-time") + 1]).toBe("300");

const wslArgs = getChatCompletionsProbeCurlArgs({
credentialArgs: FAKE_CREDENTIAL_ARGS,
model: "qwen/qwen3.5-397b-a17b",
model: "deepseek-ai/deepseek-v4-flash",
url: "https://integrate.api.nvidia.com/v1/chat/completions",
isWsl: true,
});
Expand Down
5 changes: 1 addition & 4 deletions src/lib/inference/onboard-probes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,7 @@ function openAiLikeFailureFromError(error) {

// ── Helpers ──────────────────────────────────────────────────────

const EXTENDED_NVIDIA_ENDPOINT_VALIDATION_MODELS = new Set([
"qwen/qwen3.5-397b-a17b",
"deepseek-ai/deepseek-v4-flash",
]);
const EXTENDED_NVIDIA_ENDPOINT_VALIDATION_MODELS = new Set(["deepseek-ai/deepseek-v4-flash"]);

// Hostnames that are normally meant for the sandbox/container host boundary.
// host.openshell.internal only resolves inside the OpenShell sandbox network,
Expand Down
8 changes: 4 additions & 4 deletions src/lib/inventory/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ describe("inventory commands", () => {
],
defaultSandbox: "alpha",
}),
getLiveInference: () => ({ provider: "nvidia-prod", model: "minimaxai/minimax-m2.7" }),
getLiveInference: () => ({ provider: "nvidia-prod", model: "provider/runtime-model" }),
showServiceStatus,
log: (message = "") => lines.push(message),
});
Expand All @@ -858,7 +858,7 @@ describe("inventory commands", () => {
expect(lines).toContain(" Sandboxes:");
// Default sandbox shows the live gateway model (#2369), annotated with
// the onboarded model when they differ.
expect(lines).toContain(" alpha * (minimaxai/minimax-m2.7)");
expect(lines).toContain(" alpha * (provider/runtime-model)");
expect(lines).toContain(" (onboarded: nvidia/nemotron-3-super-120b-a12b)");
// Non-default sandbox keeps its stored model — the gateway only applies
// to whichever sandbox is currently connected.
Expand Down Expand Up @@ -1040,12 +1040,12 @@ describe("inventory commands", () => {
sandboxes: [{ name: "alpha" }],
defaultSandbox: "alpha",
}),
getLiveInference: () => ({ provider: "nvidia-prod", model: "minimaxai/minimax-m2.7" }),
getLiveInference: () => ({ provider: "nvidia-prod", model: "provider/runtime-model" }),
showServiceStatus: vi.fn(),
log: (message = "") => lines.push(message),
});

expect(lines).toContain(" alpha * (minimaxai/minimax-m2.7)");
expect(lines).toContain(" alpha * (provider/runtime-model)");
expect(lines).toContain(" (onboarded: unknown)");
});

Expand Down
4 changes: 2 additions & 2 deletions src/lib/onboard/compatible-endpoint-smoke.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ describe("compatible endpoint sandbox smoke helpers", () => {

it("retries a reasoning-only length response before failing the sandbox smoke", () => {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-compat-smoke-reasoning-"));
const model = "minimaxai/minimax-m2.7";
const model = "provider/reasoning-model";
const configPath = writeSmokeConfig(tmpDir, model);
const { binDir, callFile } = writeFakeCurl(
tmpDir,
Expand Down Expand Up @@ -355,7 +355,7 @@ printf '%s\n' '{"choices":[{"message":{"content":"PONG"},"finish_reason":"stop"}

it("reports a model-output budget problem when the retry also has no assistant content", () => {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-compat-smoke-no-content-"));
const model = "minimaxai/minimax-m2.7";
const model = "provider/reasoning-model";
const configPath = writeSmokeConfig(tmpDir, model);
const { binDir, callFile } = writeFakeCurl(
tmpDir,
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/support/hermes-workflow-boundary.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ describe("Hermes GPU boundary", () => {

it("rejects broad drift", () => {
const errors = wfErrors((workflow) => {
workflow.jobs["hermes-e2e"].env.NEMOCLAW_MODEL = "minimaxai/minimax-m2.7";
workflow.jobs["hermes-e2e"].env.NEMOCLAW_MODEL = "provider/unexpected-model";
const job = workflow.jobs[GPU];
job["runs-on"] = "ubuntu-latest";
job.if = "${{ always() }}";
Expand Down
2 changes: 1 addition & 1 deletion test/onboard-selection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ const TEST_NVIDIA_FEATURED_MODELS = parseNvidiaFeaturedModels(
},
{ model: "z-ai/glm-5.1", "model-name": "GLM 5.1" },
{ model: "moonshotai/kimi-k2.6", "model-name": "Kimi K2.6" },
{ model: "minimaxai/minimax-m2.7", "model-name": "Minimax M2.7" },
{ model: "minimaxai/minimax-m3", "model-name": "Minimax M3" },
],
}),
);
Expand Down
Loading