Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e774587
fix(onboard): use Nemotron endpoint probe parameters
apurvvkumaria Sep 2, 2026
b57cdd5
refactor(inference): inline Nemotron probe match
apurvvkumaria Sep 2, 2026
0bb7a0c
merge(main): integrate required base fixes
apurvvkumaria Sep 2, 2026
75795cd
test(inference): describe Nemotron probe behavior
apurvvkumaria Sep 3, 2026
907848a
test(inference): verify serialized Nemotron probe
apurvvkumaria Sep 3, 2026
4a6693c
test(inference): name serialized Nemotron probe
apurvvkumaria Sep 3, 2026
c806515
Merge remote-tracking branch 'origin/main' into codex/fix-nvidia-endp…
apurvvkumaria Sep 3, 2026
87f6641
Merge branch 'main' into codex/fix-nvidia-endpoints-validation
apurvvkumaria Sep 3, 2026
0489382
fix(onboard): scope Nemotron probe parameters
apurvvkumaria Sep 3, 2026
8e2acae
fix(inference): handle legacy NVIDIA endpoint provider
apurvvkumaria Sep 3, 2026
3ba03ed
merge(main): refresh NVIDIA endpoint validation
prekshivyas Sep 3, 2026
80db299
fix(inference): preserve NVIDIA payload on build validation
prekshivyas Sep 3, 2026
76a0b18
fix(onboard): preserve Nemotron build validation payload
prekshivyas Sep 3, 2026
d250e68
test(inference): align NVIDIA validation evidence
prekshivyas Sep 3, 2026
be54607
merge: refresh NVIDIA endpoint validation
prekshivyas Sep 3, 2026
f60d9f0
merge: reconcile concurrent NVIDIA endpoint fixes
prekshivyas Sep 3, 2026
c84b203
Merge branch 'main' into codex/fix-nvidia-endpoints-validation
prekshivyas Sep 3, 2026
f21a656
merge: reconcile concurrent upstream refresh
prekshivyas Sep 3, 2026
1e4ee7a
Merge branch 'main' into codex/fix-nvidia-endpoints-validation
prekshivyas Sep 3, 2026
088bdc3
Merge branch 'main' into codex/fix-nvidia-endpoints-validation
prekshivyas Sep 4, 2026
5bc5899
Merge branch 'main' into codex/fix-nvidia-endpoints-validation
prekshivyas Sep 4, 2026
39a83d5
Merge branch 'main' into codex/fix-nvidia-endpoints-validation
ericksoa Sep 4, 2026
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
22 changes: 22 additions & 0 deletions src/lib/inference/health.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,28 @@ describe("inference health", () => {
expect(payload.model).toBe("meta/llama-3.3-70b-instruct");
});

it.each(["nvidia-prod", "nvidia-nim"])(
"uses the NVIDIA Endpoints request shape for Nemotron 3 Super health through %s (#10880)",
(provider) => {
let capturedArgv: string[] = [];
const result = probeRemoteProviderHealth(provider, {
model: "nvidia/nemotron-3-super-120b-a12b",
getCredentialImpl: () => "nvapi-test",
runCurlProbeImpl: (argv) => {
capturedArgv = argv;
return httpOk();
},
});

expect(result?.ok).toBe(true);
expect(JSON.parse(capturedArgv[capturedArgv.indexOf("-d") + 1])).toMatchObject({
temperature: 1,
top_p: 0.95,
chat_template_kwargs: { enable_thinking: false },
});
},
);

it("always resolves NVIDIA credentials from NVIDIA_INFERENCE_API_KEY, not the route's default credential env", () => {
let resolvedEnvNames: string[] = [];
const result = probeRemoteProviderHealth("nvidia-nim", {
Expand Down
16 changes: 13 additions & 3 deletions src/lib/inference/health.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type { LocalProviderHealthProbeOptions } from "./local";
import { probeLocalProviderHealth } from "./local";
import { MIN_PROBE_REPLY_TOKENS } from "./max-tokens-field";
import { getChatCompletionsProbeCurlArgs } from "./onboard-probes";
import { usesNvidiaEndpointProbePayload } from "./openai-probe-models";
import { BUILD_ENDPOINT_URL } from "./provider-models";

export interface ProviderHealthStatus {
Expand Down Expand Up @@ -55,7 +56,6 @@ export interface ProviderHealthProbeOptions {
}

const COMPATIBLE_PROVIDERS = new Set(["compatible-endpoint", "compatible-anthropic-endpoint"]);
const NVIDIA_MANAGED_PROVIDERS = new Set(["nvidia-prod", "nvidia-nim"]);
const NVIDIA_HEALTH_CREDENTIAL_ENV = "NVIDIA_INFERENCE_API_KEY";
const HEALTH_PROBE_CONNECT_TIMEOUT_SECONDS = "3";
const HEALTH_PROBE_MAX_TIME_SECONDS = "5";
Expand Down Expand Up @@ -125,6 +125,7 @@ function buildChatCompletionsStatusProbeCurlArgs(
endpoint: string,
authArgs: readonly string[],
isWsl?: boolean,
useNvidiaEndpointProbePayload = false,
): string[] {
const args = capStatusProbeOutput(
useStatusProbeTiming(
Expand All @@ -133,6 +134,7 @@ function buildChatCompletionsStatusProbeCurlArgs(
model,
url: endpoint,
isWsl,
useNvidiaEndpointProbePayload,
}),
),
);
Expand Down Expand Up @@ -500,6 +502,7 @@ function probeChatCompletionsProviderHealth(
credentialEnv: string,
endpoint: string,
options: ProviderHealthProbeOptions,
useNvidiaEndpointProbePayload = false,
): ProviderHealthStatus {
let apiKey = "";
try {
Expand All @@ -523,7 +526,13 @@ function probeChatCompletionsProviderHealth(
const rawResult = (() => {
try {
return runCurlProbeImpl(
buildChatCompletionsStatusProbeCurlArgs(model, endpoint, authConfig.args, options.isWsl),
buildChatCompletionsStatusProbeCurlArgs(
model,
endpoint,
authConfig.args,
options.isWsl,
useNvidiaEndpointProbePayload,
),
{ trustedConfigFiles: authConfig.trustedConfigFiles },
);
} finally {
Expand Down Expand Up @@ -652,13 +661,14 @@ export function probeRemoteProviderHealth(

if (!config?.model) return null;

if (NVIDIA_MANAGED_PROVIDERS.has(provider)) {
if (usesNvidiaEndpointProbePayload(provider)) {
return probeChatCompletionsProviderHealth(
providerLabel,
config.model,
NVIDIA_HEALTH_CREDENTIAL_ENV,
`${BUILD_ENDPOINT_URL}/chat/completions`,
options,
true,
);
}

Expand Down
50 changes: 39 additions & 11 deletions src/lib/inference/onboard-probes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,35 @@ describe("OpenAI-compatible inference probes", () => {
});
});

it("keeps the default chat-completions probe bounded for other models", () => {
expect(getChatCompletionsProbePayload("nvidia/nemotron-3-super-120b-a12b")).toEqual({
it("serializes the Nemotron 3 Super validation request parameters (#10880)", () => {
const args = getChatCompletionsProbeCurlArgs({
credentialArgs: FAKE_CREDENTIAL_ARGS,
model: "nvidia/nemotron-3-super-120b-a12b",
url: "https://integrate.api.nvidia.com/v1/chat/completions",
isWsl: false,
useNvidiaEndpointProbePayload: true,
});

expect(args).toContain("-d");
expect(JSON.parse(args[args.indexOf("-d") + 1])).toEqual({
model: "nvidia/nemotron-3-super-120b-a12b",
messages: [{ role: "user", content: "Reply with exactly: OK" }],
max_tokens: 16,
temperature: 1,
top_p: 0.95,
chat_template_kwargs: { enable_thinking: false },
});
});

it("keeps compatible endpoints on the generic request shape for the same Nemotron model (#10880)", () => {
const args = getChatCompletionsProbeCurlArgs({
credentialArgs: FAKE_CREDENTIAL_ARGS,
model: "nvidia/nemotron-3-super-120b-a12b",
url: "https://compatible.example.test/v1/chat/completions",
isWsl: false,
});

expect(JSON.parse(args[args.indexOf("-d") + 1])).toEqual({
model: "nvidia/nemotron-3-super-120b-a12b",
messages: [{ role: "user", content: "Reply with exactly: OK" }],
max_tokens: 16,
Expand Down Expand Up @@ -905,7 +932,7 @@ exit 0
});

it("retries chat-completions when /responses errors then chat-completions times out", () => {
const script = `#!/usr/bin/env bash
const script = `#!/usr/bin/env bash
outfile=""
url=""
while [ "$#" -gt 0 ]; do
Expand Down Expand Up @@ -954,7 +981,7 @@ exit 0
});

it("preserves query-param auth on doubled-timeout chat-completions retry", () => {
const script = `#!/usr/bin/env bash
const script = `#!/usr/bin/env bash
outfile=""
n=$(cat "${HARNESS_COUNTER}")
n=$((n + 1))
Expand Down Expand Up @@ -1417,7 +1444,8 @@ exit 0
});

describe("onboard inference smoke abort cleanup", () => {
it("tears down the orphan managed gateway before exiting after a failed smoke", async () => {
it("uses the legacy NVIDIA Endpoints payload before cleaning up a failed smoke (#10880)", async () => {
const optimizedProbe = vi.fn().mockResolvedValue({ ok: false, message: "smoke failed" });
const teardownOrphanManagedGatewayOnAbort = vi.fn();
const exit = vi.spyOn(process, "exit").mockImplementation((() => undefined) as never);
const error = vi.spyOn(console, "error").mockImplementation(() => undefined);
Expand All @@ -1428,18 +1456,18 @@ describe("onboard inference smoke abort cleanup", () => {
{
endpointUrl: "https://inference.example.com/v1",
forceOpenAiLike: true,
model: "example/model",
provider: "example-provider",
model: "nvidia/nemotron-3-super-120b-a12b",
provider: "nvidia-nim",
},
{
probeOpenAiLikeEndpointOptimized: vi.fn().mockResolvedValue({
ok: false,
message: "smoke failed",
}),
probeOpenAiLikeEndpointOptimized: optimizedProbe,
teardownOrphanManagedGatewayOnAbort,
},
);

expect(optimizedProbe.mock.calls[0]?.[3]).toMatchObject({
useNvidiaEndpointProbePayload: true,
});
expect(teardownOrphanManagedGatewayOnAbort).toHaveBeenCalledOnce();
expect(exit).toHaveBeenCalledWith(1);
expect(teardownOrphanManagedGatewayOnAbort.mock.invocationCallOrder[0]).toBeLessThan(
Expand Down
32 changes: 29 additions & 3 deletions src/lib/inference/onboard-probes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ const {
getHostDockerInternalProbeFailure,
isHijackedDockerInternalUrl,
} = require("./onboard-host-docker-internal");
const { isNvcfFunctionNotFoundForAccount, nvcfFunctionNotFoundMessage } = require("../validation");
const {
isNvcfFunctionNotFoundForAccount,
nvcfFunctionNotFoundMessage,
shouldSkipResponsesProbe,
} = require("../validation");
const { isPrivateHostname, isPrivateIp, isLoopbackHostname } = require("../private-networks");
const { buildResolvePinArgs, isOperatorTrustablePrivateIp } = require("./endpoint-ssrf-preflight");
const {
Expand All @@ -57,6 +61,7 @@ const {
STRICT_TOOL_PROBE_INITIAL_TOKENS,
STRICT_TOOL_PROBE_RETRY_TOKEN_LADDER,
strictToolProbeReasoningRetryMessage,
usesNvidiaEndpointProbePayload,
vllmProbePolicyForModel,
} = require("./openai-probe-models");
const {
Expand Down Expand Up @@ -261,6 +266,16 @@ function getProbeAuthMode(_provider) {
return undefined;
}

function getOpenAiSelectionProbeOptions(provider) {
return {
provider,
useNvidiaEndpointProbePayload: usesNvidiaEndpointProbePayload(provider),
requireResponsesToolCalling: shouldRequireResponsesToolCalling(provider),
skipResponsesProbe: shouldSkipResponsesProbe(provider),
authMode: getProbeAuthMode(provider),
};
}

export function getProbeExtraHeaders(provider) {
if (provider === openrouter.OPENROUTER_PROVIDER_NAME) {
return openrouter.getOpenRouterCurlHeaders();
Expand Down Expand Up @@ -535,6 +550,7 @@ export function getChatCompletionsProbeCurlArgs(opts: {
isWsl?: boolean;
pinnedAddresses?: readonly string[];
validationTiming?: unknown;
useNvidiaEndpointProbePayload?: boolean;
}) {
const {
credentialArgs,
Expand All @@ -544,6 +560,7 @@ export function getChatCompletionsProbeCurlArgs(opts: {
isWsl: isWslOverride,
pinnedAddresses,
validationTiming,
useNvidiaEndpointProbePayload,
} = opts;
const platformOptions = getProbeTimingOptions({
...(typeof isWslOverride === "boolean" ? { isWsl: isWslOverride } : {}),
Expand All @@ -559,7 +576,7 @@ export function getChatCompletionsProbeCurlArgs(opts: {
"Content-Type: application/json",
...credSlice,
"-d",
JSON.stringify(getChatCompletionsProbePayload(model)),
JSON.stringify(getChatCompletionsProbePayload(model, { useNvidiaEndpointProbePayload })),
url,
];
}
Expand All @@ -573,6 +590,7 @@ function runChatCompletionsProbe({
pinnedAddresses,
trustedPrivateCapability,
validationTiming,
useNvidiaEndpointProbePayload,
spawnSyncImpl,
}) {
const args = getChatCompletionsProbeCurlArgs({
Expand All @@ -582,6 +600,7 @@ function runChatCompletionsProbe({
isWsl: isWslOverride,
pinnedAddresses,
validationTiming,
useNvidiaEndpointProbePayload,
});
const probeOpts = {
timeoutMs: getProbeProcessTimeoutMs(args),
Expand Down Expand Up @@ -621,7 +640,11 @@ function runDoubledTimeoutChatCompletionsRetry({
"Content-Type: application/json",
...authConfig.args,
"-d",
JSON.stringify(getChatCompletionsProbePayload(model)),
JSON.stringify(
getChatCompletionsProbePayload(model, {
useNvidiaEndpointProbePayload: options.useNvidiaEndpointProbePayload,
}),
),
`${baseUrl}/chat/completions`,
];
const runRetryProbe = () =>
Expand Down Expand Up @@ -879,6 +902,7 @@ function probeOpenAiLikeEndpoint(endpointUrl, model, apiKey, options = {}) {
pinnedAddresses,
trustedPrivateCapability: options.trustedPrivateCapability,
validationTiming,
useNvidiaEndpointProbePayload: options.useNvidiaEndpointProbePayload,
spawnSyncImpl: options.spawnSyncImpl,
}),
};
Expand Down Expand Up @@ -1121,6 +1145,7 @@ module.exports = {
hasChatCompletionsToolCallLeak,
shouldRequireResponsesToolCalling,
getProbeAuthMode,
getOpenAiSelectionProbeOptions,
getProbeExtraHeaders,
getValidationProbeCurlArgs,
getDeepSeekV4ProValidationProbeCurlArgs,
Expand Down Expand Up @@ -1197,6 +1222,7 @@ export async function verifyOnboardInferenceSmoke(options: any, dependencies: an
authMode: getProbeAuthMode(options.provider),
extraHeaders: getProbeExtraHeaders(options.provider),
skipResponsesProbe: true,
useNvidiaEndpointProbePayload: usesNvidiaEndpointProbePayload(options.provider),
pinnedAddresses: options.pinnedAddresses,
trustedPrivateCapability: options.trustedPrivateCapability,
});
Expand Down
23 changes: 22 additions & 1 deletion src/lib/inference/openai-probe-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ export const STANDARD_NVIDIA_ENDPOINT_PROBE_POLICY =
export const EXTENDED_NVIDIA_ENDPOINT_PROBE_POLICY =
"nvidia.endpoint-validation.extended/v1";

const NVIDIA_ENDPOINT_PROVIDERS = new Set(["nvidia-prod", "nvidia-nim"]);

export function usesNvidiaEndpointProbePayload(provider: unknown): boolean {
return typeof provider === "string" && NVIDIA_ENDPOINT_PROVIDERS.has(provider);
}

export function vllmProbePolicyForModel(model: string): string {
const normalized = model.trim().toLowerCase();
const matches = loadManagedInferenceCatalog().models.filter(({ spec }) =>
Expand Down Expand Up @@ -47,7 +53,10 @@ export function isKimiK26Model(model: unknown): boolean {
return String(model || "").toLowerCase() === "moonshotai/kimi-k2.6";
}

export function getChatCompletionsProbePayload(model: string): Record<string, unknown> {
export function getChatCompletionsProbePayload(
model: string,
options: { useNvidiaEndpointProbePayload?: boolean } = {},
): Record<string, unknown> {
const maxTokensField = resolveMaxTokensField(model);
const payload = {
model,
Expand All @@ -74,6 +83,18 @@ export function getChatCompletionsProbePayload(model: string): Record<string, un
};
}

if (
options.useNvidiaEndpointProbePayload === true &&
model.toLowerCase() === "nvidia/nemotron-3-super-120b-a12b"
) {
return {
...payload,
temperature: 1,
top_p: 0.95,
chat_template_kwargs: { enable_thinking: false },
};
}

return payload;
}

Expand Down
Loading
Loading