diff --git a/.github/workflows/e2e-script.yaml b/.github/workflows/e2e-script.yaml index a7c6bb6dee7..177e30ff954 100644 --- a/.github/workflows/e2e-script.yaml +++ b/.github/workflows/e2e-script.yaml @@ -229,8 +229,8 @@ jobs: printf 'NEMOCLAW_E2E_USE_HOSTED_INFERENCE=1\n' printf 'NEMOCLAW_PROVIDER=custom\n' printf 'NEMOCLAW_ENDPOINT_URL=https://inference-api.nvidia.com/v1\n' - printf 'NEMOCLAW_MODEL=nvidia/nemotron-3-ultra\n' - printf 'NEMOCLAW_COMPAT_MODEL=nvidia/nemotron-3-ultra\n' + printf 'NEMOCLAW_MODEL=nvidia/nvidia/nemotron-3-ultra\n' + printf 'NEMOCLAW_COMPAT_MODEL=nvidia/nvidia/nemotron-3-ultra\n' printf 'NEMOCLAW_PREFERRED_API=openai-completions\n' printf 'COMPATIBLE_API_KEY=%s\n' "${NVIDIA_INFERENCE_API_KEY}" } >> "$GITHUB_ENV" diff --git a/.github/workflows/e2e-vitest-scenarios.yaml b/.github/workflows/e2e-vitest-scenarios.yaml index 2ec40bd9539..04415d83873 100644 --- a/.github/workflows/e2e-vitest-scenarios.yaml +++ b/.github/workflows/e2e-vitest-scenarios.yaml @@ -1415,8 +1415,8 @@ jobs: NVIDIA_INFERENCE_API_KEY: ${{ secrets.NVIDIA_INFERENCE_API_KEY }} NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions run: | set -euo pipefail @@ -2135,8 +2135,8 @@ jobs: NEMOCLAW_NON_INTERACTIVE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions NEMOCLAW_SANDBOX_NAME: e2e-rebuild-hermes OPENSHELL_GATEWAY: nemoclaw @@ -2218,8 +2218,8 @@ jobs: NEMOCLAW_NON_INTERACTIVE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions NEMOCLAW_SANDBOX_NAME: e2e-rebuild-hermes-base OPENSHELL_GATEWAY: nemoclaw @@ -2970,8 +2970,8 @@ jobs: NEMOCLAW_SANDBOX_NAME: "e2e-resume" NEMOCLAW_PROVIDER: "custom" NEMOCLAW_ENDPOINT_URL: "https://inference-api.nvidia.com/v1" - NEMOCLAW_MODEL: "nvidia/nemotron-3-ultra" - NEMOCLAW_COMPAT_MODEL: "nvidia/nemotron-3-ultra" + NEMOCLAW_MODEL: "nvidia/nvidia/nemotron-3-ultra" + NEMOCLAW_COMPAT_MODEL: "nvidia/nvidia/nemotron-3-ultra" steps: - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: diff --git a/.github/workflows/nightly-e2e.yaml b/.github/workflows/nightly-e2e.yaml index a8893d37f57..b47644dff88 100644 --- a/.github/workflows/nightly-e2e.yaml +++ b/.github/workflows/nightly-e2e.yaml @@ -468,8 +468,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" @@ -544,8 +544,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_ISSUE_4434_LIVE: "1" @@ -1003,8 +1003,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" @@ -1301,8 +1301,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" @@ -1608,8 +1608,8 @@ jobs: NVIDIA_INFERENCE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} E2E_ARTIFACT_DIR: ${{ github.workspace }}/e2e-artifacts/vitest/credential-migration @@ -1834,8 +1834,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" @@ -1847,8 +1847,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" @@ -1886,8 +1886,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" @@ -1899,8 +1899,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" @@ -1938,8 +1938,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" @@ -1951,8 +1951,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" @@ -1991,8 +1991,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" @@ -2004,8 +2004,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" @@ -2044,8 +2044,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" @@ -2058,8 +2058,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" @@ -2100,8 +2100,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" @@ -2114,8 +2114,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" @@ -2194,8 +2194,8 @@ jobs: NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1" NEMOCLAW_PROVIDER: custom NEMOCLAW_ENDPOINT_URL: https://inference-api.nvidia.com/v1 - NEMOCLAW_MODEL: nvidia/nemotron-3-ultra - NEMOCLAW_COMPAT_MODEL: nvidia/nemotron-3-ultra + NEMOCLAW_MODEL: nvidia/nvidia/nemotron-3-ultra + NEMOCLAW_COMPAT_MODEL: nvidia/nvidia/nemotron-3-ultra NEMOCLAW_PREFERRED_API: openai-completions COMPATIBLE_API_KEY: ${{ (github.event_name != 'workflow_dispatch' || inputs.target_ref == '') && secrets.NVIDIA_INFERENCE_API_KEY || '' }} NEMOCLAW_NON_INTERACTIVE: "1" diff --git a/src/lib/inference/onboard-probes.test.ts b/src/lib/inference/onboard-probes.test.ts index 555ccca6ea6..14e00c29c22 100644 --- a/src/lib/inference/onboard-probes.test.ts +++ b/src/lib/inference/onboard-probes.test.ts @@ -293,8 +293,8 @@ describe("OpenAI-compatible inference probes", () => { }); it("bounds the hosted compatible inference probe for the served Nemotron model", () => { - expect(getChatCompletionsProbePayload("nvidia/nemotron-3-ultra")).toEqual({ - model: "nvidia/nemotron-3-ultra", + expect(getChatCompletionsProbePayload("nvidia/nvidia/nemotron-3-ultra")).toEqual({ + model: "nvidia/nvidia/nemotron-3-ultra", messages: [{ role: "user", content: "Reply with exactly: OK" }], max_tokens: 8, }); diff --git a/src/lib/onboard/providers.ts b/src/lib/onboard/providers.ts index a91f435aa84..77a5eaceed0 100644 --- a/src/lib/onboard/providers.ts +++ b/src/lib/onboard/providers.ts @@ -27,7 +27,10 @@ const HOSTED_INFERENCE_SOURCE_ENV = "NVIDIA_INFERENCE_API_KEY"; const HOSTED_INFERENCE_PROVIDER_KEY_ENV = "NEMOCLAW_PROVIDER_KEY"; const HOSTED_INFERENCE_CREDENTIAL_ENV = "COMPATIBLE_API_KEY"; const HOSTED_INFERENCE_ENDPOINT_URL = "https://inference-api.nvidia.com/v1"; -const HOSTED_INFERENCE_MODEL = "nvidia/nemotron-3-ultra"; +// Private CI-compatible Inference Hub endpoint model IDs use the +// provider/namespace/model convention. This endpoint is staged as a custom +// OpenAI-compatible provider, not as the public build.nvidia.com provider. +const HOSTED_INFERENCE_MODEL = "nvidia/nvidia/nemotron-3-ultra"; const NON_INTERACTIVE_PROVIDER_ALIASES = { cloud: "build", nim: "nim-local", diff --git a/test/e2e-scenario/fixtures/hosted-inference.ts b/test/e2e-scenario/fixtures/hosted-inference.ts index bb37f8858fa..4efcbbddbd5 100644 --- a/test/e2e-scenario/fixtures/hosted-inference.ts +++ b/test/e2e-scenario/fixtures/hosted-inference.ts @@ -6,7 +6,7 @@ const HOSTED_INFERENCE_CREDENTIAL_ENV = "COMPATIBLE_API_KEY"; const HOSTED_INFERENCE_PROVIDER = "custom"; const HOSTED_INFERENCE_PROVIDER_NAME = "compatible-endpoint"; const DEFAULT_HOSTED_INFERENCE_BASE_URL = "https://inference-api.nvidia.com/v1"; -const DEFAULT_HOSTED_INFERENCE_MODEL = "nvidia/nemotron-3-ultra"; +const DEFAULT_HOSTED_INFERENCE_MODEL = "nvidia/nvidia/nemotron-3-ultra"; export interface HostedInferenceSecrets { required(name: string): string; diff --git a/test/e2e-scenario/live/agent-turn-latency-helpers.ts b/test/e2e-scenario/live/agent-turn-latency-helpers.ts index 9f33e39d673..327ebdfdc44 100644 --- a/test/e2e-scenario/live/agent-turn-latency-helpers.ts +++ b/test/e2e-scenario/live/agent-turn-latency-helpers.ts @@ -23,7 +23,7 @@ export const HERMES_SANDBOX = validateSandboxName(OPENCLAW_SANDBOX); validateSandboxName(HERMES_SANDBOX); const DEFAULT_NVIDIA_MODEL = "nvidia/nemotron-3-super-120b-a12b"; -const DEFAULT_COMPAT_MODEL = "nvidia/nemotron-3-ultra"; +const DEFAULT_COMPAT_MODEL = "nvidia/nvidia/nemotron-3-ultra"; const USE_COMPATIBLE_HOSTED = process.env.NEMOCLAW_E2E_USE_HOSTED_INFERENCE === "1"; export const MODEL = process.env.NEMOCLAW_TURN_LATENCY_MODEL ?? diff --git a/test/e2e-scenario/live/hermes-discord.test.ts b/test/e2e-scenario/live/hermes-discord.test.ts index 3926fab3254..d6ad565b889 100644 --- a/test/e2e-scenario/live/hermes-discord.test.ts +++ b/test/e2e-scenario/live/hermes-discord.test.ts @@ -47,11 +47,11 @@ function commandEnv(apiKey?: string, extra: NodeJS.ProcessEnv = {}): NodeJS.Proc NEMOCLAW_PROVIDER: process.env.NEMOCLAW_PROVIDER ?? "custom", NEMOCLAW_ENDPOINT_URL: process.env.NEMOCLAW_ENDPOINT_URL ?? "https://inference-api.nvidia.com/v1", - NEMOCLAW_MODEL: process.env.NEMOCLAW_MODEL ?? "nvidia/nemotron-3-ultra", + NEMOCLAW_MODEL: process.env.NEMOCLAW_MODEL ?? "nvidia/nvidia/nemotron-3-ultra", NEMOCLAW_COMPAT_MODEL: process.env.NEMOCLAW_COMPAT_MODEL ?? process.env.NEMOCLAW_MODEL ?? - "nvidia/nemotron-3-ultra", + "nvidia/nvidia/nemotron-3-ultra", NEMOCLAW_PREFERRED_API: process.env.NEMOCLAW_PREFERRED_API ?? "openai-completions", DISCORD_BOT_TOKEN: DISCORD_TOKEN, DISCORD_SERVER_IDS, diff --git a/test/e2e-scenario/live/hermes-slack-e2e-helpers.ts b/test/e2e-scenario/live/hermes-slack-e2e-helpers.ts index 8530f91519f..adf999f6d94 100644 --- a/test/e2e-scenario/live/hermes-slack-e2e-helpers.ts +++ b/test/e2e-scenario/live/hermes-slack-e2e-helpers.ts @@ -40,11 +40,11 @@ function hermesSlackEnv(apiKey?: string): NodeJS.ProcessEnv { apiKey, extra: { ...(apiKey ? { COMPATIBLE_API_KEY: apiKey } : {}), - NEMOCLAW_COMPAT_MODEL: process.env.NEMOCLAW_COMPAT_MODEL ?? "nvidia/nemotron-3-ultra", + NEMOCLAW_COMPAT_MODEL: process.env.NEMOCLAW_COMPAT_MODEL ?? "nvidia/nvidia/nemotron-3-ultra", NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1", NEMOCLAW_ENDPOINT_URL: process.env.NEMOCLAW_ENDPOINT_URL ?? "https://inference-api.nvidia.com/v1", - NEMOCLAW_MODEL: process.env.NEMOCLAW_MODEL ?? "nvidia/nemotron-3-ultra", + NEMOCLAW_MODEL: process.env.NEMOCLAW_MODEL ?? "nvidia/nvidia/nemotron-3-ultra", NEMOCLAW_POLICY_TIER: process.env.NEMOCLAW_POLICY_TIER ?? "open", NEMOCLAW_PREFERRED_API: process.env.NEMOCLAW_PREFERRED_API ?? "openai-completions", NEMOCLAW_PROVIDER: process.env.NEMOCLAW_PROVIDER ?? "custom", diff --git a/test/e2e-scenario/live/rebuild-hermes.test.ts b/test/e2e-scenario/live/rebuild-hermes.test.ts index 2127093379b..2df0fe7b052 100644 --- a/test/e2e-scenario/live/rebuild-hermes.test.ts +++ b/test/e2e-scenario/live/rebuild-hermes.test.ts @@ -54,7 +54,9 @@ const BACKUP_ROOT = path.join(os.homedir(), ".nemoclaw", "rebuild-backups"); const HOSTED_ENDPOINT_URL = process.env.NEMOCLAW_ENDPOINT_URL ?? "https://inference-api.nvidia.com/v1"; const HOSTED_MODEL = - process.env.NEMOCLAW_MODEL ?? process.env.NEMOCLAW_COMPAT_MODEL ?? "nvidia/nemotron-3-ultra"; + process.env.NEMOCLAW_MODEL ?? + process.env.NEMOCLAW_COMPAT_MODEL ?? + "nvidia/nvidia/nemotron-3-ultra"; const OLD_BASE_TAG = `nemoclaw-hermes-old-base:${SANDBOX_NAME.toLowerCase().replace(/[^a-z0-9_.-]+/g, "-")}`; const CURRENT_BASE_TAG = "ghcr.io/nvidia/nemoclaw/hermes-sandbox-base:latest"; diff --git a/test/e2e-scenario/live/upgrade-stale-sandbox-helpers.ts b/test/e2e-scenario/live/upgrade-stale-sandbox-helpers.ts index 0b64cfd3a40..8b6fecc2ffb 100644 --- a/test/e2e-scenario/live/upgrade-stale-sandbox-helpers.ts +++ b/test/e2e-scenario/live/upgrade-stale-sandbox-helpers.ts @@ -122,7 +122,7 @@ export function writeStaleRegistryEntry(): void { (typeof session.model === "string" && session.model) || process.env.NEMOCLAW_MODEL || process.env.NEMOCLAW_COMPAT_MODEL || - "nvidia/nemotron-3-ultra"; + "nvidia/nvidia/nemotron-3-ultra"; const registry = readJsonFile<{ sandboxes?: Record>; defaultSandbox?: string; diff --git a/test/e2e-script-workflow.test.ts b/test/e2e-script-workflow.test.ts index 4b204933b18..f966b53f988 100644 --- a/test/e2e-script-workflow.test.ts +++ b/test/e2e-script-workflow.test.ts @@ -546,8 +546,8 @@ describe("E2E reusable workflow contract", () => { expect(runStep?.env?.NVIDIA_INFERENCE_API_KEY).toBe(GUARDED_HOSTED_INFERENCE_SECRET); expect(runStep?.env?.NEMOCLAW_PROVIDER).toBe("custom"); expect(runStep?.env?.NEMOCLAW_ENDPOINT_URL).toBe("https://inference-api.nvidia.com/v1"); - expect(runStep?.env?.NEMOCLAW_MODEL).toBe("nvidia/nemotron-3-ultra"); - expect(runStep?.env?.NEMOCLAW_COMPAT_MODEL).toBe("nvidia/nemotron-3-ultra"); + expect(runStep?.env?.NEMOCLAW_MODEL).toBe("nvidia/nvidia/nemotron-3-ultra"); + expect(runStep?.env?.NEMOCLAW_COMPAT_MODEL).toBe("nvidia/nvidia/nemotron-3-ultra"); expect(runStep?.env?.NEMOCLAW_PREFERRED_API).toBe("openai-completions"); expect(runStep?.env?.COMPATIBLE_API_KEY).toBe(GUARDED_HOSTED_INFERENCE_SECRET); expect(runStep?.env?.GITHUB_TOKEN).toBeUndefined(); @@ -926,8 +926,8 @@ describe("E2E reusable workflow contract", () => { expect(exportStep?.run).toContain("NEMOCLAW_E2E_USE_HOSTED_INFERENCE=1"); expect(exportStep?.run).toContain("NEMOCLAW_PROVIDER=custom"); expect(exportStep?.run).toContain("NEMOCLAW_ENDPOINT_URL=https://inference-api.nvidia.com/v1"); - expect(exportStep?.run).toContain("NEMOCLAW_MODEL=nvidia/nemotron-3-ultra"); - expect(exportStep?.run).toContain("NEMOCLAW_COMPAT_MODEL=nvidia/nemotron-3-ultra"); + expect(exportStep?.run).toContain("NEMOCLAW_MODEL=nvidia/nvidia/nemotron-3-ultra"); + expect(exportStep?.run).toContain("NEMOCLAW_COMPAT_MODEL=nvidia/nvidia/nemotron-3-ultra"); expect(exportStep?.run).toContain("NEMOCLAW_PREFERRED_API=openai-completions"); expect(exportStep?.run).toContain("COMPATIBLE_API_KEY=%s"); @@ -950,7 +950,7 @@ describe("E2E reusable workflow contract", () => { expect(body, fixture).toContain("if env_provider == 'custom'"); expect(body, fixture).toContain("'provider': provider"); expect(body, fixture).toContain("'model': model"); - expect(body, fixture).toContain("nvidia/nemotron-3-ultra"); + expect(body, fixture).toContain("nvidia/nvidia/nemotron-3-ultra"); expect(body, fixture).not.toContain("'provider': 'nvidia-prod'"); expect(body, fixture).not.toContain("'model': 'nvidia/nemotron-3-super-120b-a12b'"); } @@ -1003,8 +1003,8 @@ describe("E2E reusable workflow contract", () => { } expect(step.env?.NEMOCLAW_PROVIDER, jobName).toBe("custom"); expect(step.env?.NEMOCLAW_ENDPOINT_URL, jobName).toBe("https://inference-api.nvidia.com/v1"); - expect(step.env?.NEMOCLAW_MODEL, jobName).toBe("nvidia/nemotron-3-ultra"); - expect(step.env?.NEMOCLAW_COMPAT_MODEL, jobName).toBe("nvidia/nemotron-3-ultra"); + expect(step.env?.NEMOCLAW_MODEL, jobName).toBe("nvidia/nvidia/nemotron-3-ultra"); + expect(step.env?.NEMOCLAW_COMPAT_MODEL, jobName).toBe("nvidia/nvidia/nemotron-3-ultra"); expect(step.env?.NEMOCLAW_PREFERRED_API, jobName).toBe("openai-completions"); expect(step.env?.COMPATIBLE_API_KEY, jobName).toBe(GUARDED_HOSTED_INFERENCE_SECRET); } diff --git a/test/e2e/lib/ci-compatible-inference.sh b/test/e2e/lib/ci-compatible-inference.sh index 285da0389f7..12cdb94bcb1 100755 --- a/test/e2e/lib/ci-compatible-inference.sh +++ b/test/e2e/lib/ci-compatible-inference.sh @@ -7,7 +7,7 @@ # at inference-api.nvidia.com. Keep this helper in test/e2e so the # product-facing provider/default endpoint remain unchanged. -NEMOCLAW_E2E_COMPATIBLE_INFERENCE_MODEL_DEFAULT="nvidia/nemotron-3-ultra" +NEMOCLAW_E2E_COMPATIBLE_INFERENCE_MODEL_DEFAULT="nvidia/nvidia/nemotron-3-ultra" NEMOCLAW_E2E_HOSTED_INFERENCE_PROVIDER_DEFAULT="compatible-endpoint" NEMOCLAW_E2E_NVIDIA_INFERENCE_MODEL_DEFAULT="nvidia/nemotron-3-super-120b-a12b" diff --git a/test/e2e/test-rebuild-hermes.sh b/test/e2e/test-rebuild-hermes.sh index 8183955dc05..f5d83266e91 100755 --- a/test/e2e/test-rebuild-hermes.sh +++ b/test/e2e/test-rebuild-hermes.sh @@ -261,7 +261,7 @@ model = ( sess.get('model') or os.environ.get('NEMOCLAW_MODEL') or os.environ.get('NEMOCLAW_COMPAT_MODEL') - or 'nvidia/nemotron-3-ultra' + or 'nvidia/nvidia/nemotron-3-ultra' ) credential_hash = hashlib.sha256('${DISCORD_FAKE_TOKEN}'.encode()).hexdigest() plan = { @@ -397,7 +397,7 @@ fi # Inference works after rebuild (proves credential chain is intact) info "Verifying inference after rebuild..." -POST_REBUILD_INFERENCE_MODEL="${NEMOCLAW_MODEL:-${NEMOCLAW_COMPAT_MODEL:-nvidia/nemotron-3-ultra}}" +POST_REBUILD_INFERENCE_MODEL="${NEMOCLAW_MODEL:-${NEMOCLAW_COMPAT_MODEL:-nvidia/nvidia/nemotron-3-ultra}}" INFERENCE_RESPONSE=$(openshell sandbox exec --name "${SANDBOX_NAME}" -- \ curl -s --max-time 60 https://inference.local/v1/chat/completions \ -H 'Content-Type: application/json' \ diff --git a/test/e2e/test-rebuild-openclaw.sh b/test/e2e/test-rebuild-openclaw.sh index 8aab09c93a0..7535602b3f9 100755 --- a/test/e2e/test-rebuild-openclaw.sh +++ b/test/e2e/test-rebuild-openclaw.sh @@ -230,7 +230,7 @@ model = ( sess.get('model') or os.environ.get('NEMOCLAW_MODEL') or os.environ.get('NEMOCLAW_COMPAT_MODEL') - or 'nvidia/nemotron-3-ultra' + or 'nvidia/nvidia/nemotron-3-ultra' ) reg = {'sandboxes': {'${SANDBOX_NAME}': { 'name': '${SANDBOX_NAME}', @@ -446,7 +446,7 @@ fi # Inference works after rebuild (proves credential chain is intact) info "Verifying inference after rebuild..." -POST_REBUILD_INFERENCE_MODEL="${NEMOCLAW_MODEL:-${NEMOCLAW_COMPAT_MODEL:-nvidia/nemotron-3-ultra}}" +POST_REBUILD_INFERENCE_MODEL="${NEMOCLAW_MODEL:-${NEMOCLAW_COMPAT_MODEL:-nvidia/nvidia/nemotron-3-ultra}}" INFERENCE_RESPONSE=$(openshell sandbox exec --name "${SANDBOX_NAME}" -- \ curl -s --max-time 60 https://inference.local/v1/chat/completions \ -H 'Content-Type: application/json' \ diff --git a/test/e2e/test-upgrade-stale-sandbox.sh b/test/e2e/test-upgrade-stale-sandbox.sh index feb1bf6ab5a..e06c03d53b7 100755 --- a/test/e2e/test-upgrade-stale-sandbox.sh +++ b/test/e2e/test-upgrade-stale-sandbox.sh @@ -170,7 +170,7 @@ model = ( sess.get('model') or os.environ.get('NEMOCLAW_MODEL') or os.environ.get('NEMOCLAW_COMPAT_MODEL') - or 'nvidia/nemotron-3-ultra' + or 'nvidia/nvidia/nemotron-3-ultra' ) reg = {'sandboxes': {'${SANDBOX_NAME}': { 'name': '${SANDBOX_NAME}', diff --git a/test/issue-5667-hosted-inference-model-namespace.test.ts b/test/issue-5667-hosted-inference-model-namespace.test.ts index 088d9cdac1b..a65cb025b70 100644 --- a/test/issue-5667-hosted-inference-model-namespace.test.ts +++ b/test/issue-5667-hosted-inference-model-namespace.test.ts @@ -1,12 +1,13 @@ // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 // -// Regression test for issue #5667: onboarding a Deep Agents / OpenAI-compatible -// sandbox without an explicit NEMOCLAW_MODEL recorded the default model id as -// "nvidia/nvidia/nemotron-3-ultra" — a doubled "nvidia/" namespace prefix. -// Standard NIM model ids carry exactly one namespace segment, so the default -// fallback must be the canonical single-prefix id and the staged onboarding env -// must never contain "nvidia/nvidia/". +// Regression coverage for the hosted Inference Hub compatible-endpoint default. +// The repo-secret endpoint at https://inference-api.nvidia.com/v1 is staged as +// a custom OpenAI-compatible provider and expects provider/namespace/model IDs. +// For NVIDIA-hosted models that means nvidia/nvidia/, which is distinct +// from the official NVIDIA provider catalog IDs used for build.nvidia.com. +// NemoClaw must preserve the provider-accepted ID end-to-end instead of +// normalizing away the leading provider segment. import assert from "node:assert/strict"; import { spawnSync } from "node:child_process"; @@ -141,12 +142,12 @@ describe("issue #5667: hosted inference default model namespace", () => { Object.assign(process.env, envSnapshot); }); - it("default hosted inference model has a single nvidia/ namespace segment", () => { - expect(providers.HOSTED_INFERENCE_MODEL).not.toContain("nvidia/nvidia/"); - expect(providers.HOSTED_INFERENCE_MODEL).toBe("nvidia/nemotron-3-ultra"); + it("default hosted inference model uses the provider/namespace/model convention", () => { + expect(providers.HOSTED_INFERENCE_MODEL).toBe("nvidia/nvidia/nemotron-3-ultra"); + expect(providers.HOSTED_INFERENCE_MODEL).not.toContain("nvidia/nvidia/nvidia/"); }); - it("staging the hosted inference secret without NEMOCLAW_MODEL records a single-prefix model", () => { + it("staging the hosted inference secret without NEMOCLAW_MODEL records the provider-convention model", () => { // Reproduce the reported flow: an Inference Hub OpenAI-compatible key with no // explicit NEMOCLAW_MODEL, so onboarding falls back to the default model id. process.env.NVIDIA_INFERENCE_API_KEY = "sk-test-inference-hub-key"; @@ -155,12 +156,12 @@ describe("issue #5667: hosted inference default model namespace", () => { const staged = providers.stageHostedInferenceSourceSecretEnv(); expect(staged).toBe(true); - expect(process.env.NEMOCLAW_MODEL).not.toContain("nvidia/nvidia/"); - expect(process.env.NEMOCLAW_MODEL).toBe("nvidia/nemotron-3-ultra"); - expect(process.env.NEMOCLAW_COMPAT_MODEL).toBe("nvidia/nemotron-3-ultra"); + expect(process.env.NEMOCLAW_MODEL).toBe("nvidia/nvidia/nemotron-3-ultra"); + expect(process.env.NEMOCLAW_MODEL).not.toContain("nvidia/nvidia/nvidia/"); + expect(process.env.NEMOCLAW_COMPAT_MODEL).toBe("nvidia/nvidia/nemotron-3-ultra"); }); - it("stages the Deep Agents NEMOCLAW_PROVIDER_KEY path with a single-prefix model", () => { + it("stages the Deep Agents NEMOCLAW_PROVIDER_KEY path with the provider-convention model", () => { // Reproduce the issue command: a Deep Agents compatible endpoint key is // supplied via the generic provider-key hint, with no explicit model. process.env.NEMOCLAW_AGENT = "langchain-deepagents-code"; @@ -171,12 +172,12 @@ describe("issue #5667: hosted inference default model namespace", () => { expect(staged).toBe(true); expect(process.env.NEMOCLAW_PROVIDER).toBe("custom"); expect(process.env.COMPATIBLE_API_KEY).toBe("sk-test-inference-hub-key"); - expect(process.env.NEMOCLAW_MODEL).not.toContain("nvidia/nvidia/"); - expect(process.env.NEMOCLAW_MODEL).toBe("nvidia/nemotron-3-ultra"); - expect(process.env.NEMOCLAW_COMPAT_MODEL).toBe("nvidia/nemotron-3-ultra"); + expect(process.env.NEMOCLAW_MODEL).toBe("nvidia/nvidia/nemotron-3-ultra"); + expect(process.env.NEMOCLAW_MODEL).not.toContain("nvidia/nvidia/nvidia/"); + expect(process.env.NEMOCLAW_COMPAT_MODEL).toBe("nvidia/nvidia/nemotron-3-ultra"); }); - it("drives setupNim and downstream Deep Agents surfaces with a single-prefix model", async () => { + it("drives setupNim and downstream Deep Agents surfaces with the provider-convention model", async () => { const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-issue-5667-")); const fakeBin = path.join(tmpDir, "bin"); const home = path.join(tmpDir, "home"); @@ -253,16 +254,16 @@ const { setupNim } = require(${onboardPath}); expect(payload.result.provider).toBe("compatible-endpoint"); expect(payload.result.credentialEnv).toBe("COMPATIBLE_API_KEY"); - expect(payload.result.model).toBe("nvidia/nemotron-3-ultra"); + expect(payload.result.model).toBe("nvidia/nvidia/nemotron-3-ultra"); expect(payload.result.preferredInferenceApi).toBe("openai-completions"); expect(payload.env).toMatchObject({ provider: "custom", - model: "nvidia/nemotron-3-ultra", - compatModel: "nvidia/nemotron-3-ultra", + model: "nvidia/nvidia/nemotron-3-ultra", + compatModel: "nvidia/nvidia/nemotron-3-ultra", compatibleKey: "sk-test-inference-hub-key", preferredApi: "openai-completions", }); - expect(output).not.toContain("nvidia/nvidia/"); + expect(output).not.toContain("nvidia/nvidia/nvidia/"); const statusSnapshot = await collectSandboxStatusSnapshot("dcode-test", { deps: { @@ -278,15 +279,20 @@ const { setupNim } = require(${onboardPath}); }); const statusModelLine = ` Model: ${statusSnapshot.currentModel}`; expect(statusSnapshot.currentProvider).toBe("compatible-endpoint"); - expect(statusSnapshot.currentModel).toBe("nvidia/nemotron-3-ultra"); - expect(statusModelLine).toBe(" Model: nvidia/nemotron-3-ultra"); - expect(statusModelLine).not.toContain("nvidia/nvidia/"); + expect(statusSnapshot.currentModel).toBe("nvidia/nvidia/nemotron-3-ultra"); + expect(statusModelLine).toBe(" Model: nvidia/nvidia/nemotron-3-ultra"); + expect(statusModelLine).not.toContain("nvidia/nvidia/nvidia/"); const dockerfilePath = path.join(tmpDir, "Dockerfile"); fs.writeFileSync(dockerfilePath, "FROM scratch\nARG NEMOCLAW_MODEL=old\n"); - patchStagedDockerfile(dockerfilePath, payload.result.model, null, "issue-5667-single-prefix"); + patchStagedDockerfile( + dockerfilePath, + payload.result.model, + null, + "issue-5667-provider-convention", + ); expect(fs.readFileSync(dockerfilePath, "utf8")).toContain( - "ARG NEMOCLAW_MODEL=nvidia/nemotron-3-ultra", + "ARG NEMOCLAW_MODEL=nvidia/nvidia/nemotron-3-ultra", ); const configResult = spawnSync( @@ -312,8 +318,8 @@ const { setupNim } = require(${onboardPath}); ); assert.equal(configResult.status, 0, `${configResult.stdout}\n${configResult.stderr}`); const config = fs.readFileSync(path.join(home, ".deepagents", "config.toml"), "utf8"); - expect(config).toContain('default = "openai:nvidia/nemotron-3-ultra"'); - expect(config).not.toContain("nvidia/nvidia/"); + expect(config).toContain('default = "openai:nvidia/nvidia/nemotron-3-ultra"'); + expect(config).not.toContain("nvidia/nvidia/nvidia/"); const dcodeWrapperPath = writeDcodeWrapperFixture(tmpDir, home); const fakePythonPath = writeFakeDeepAgentsCodeModule(tmpDir); @@ -329,10 +335,10 @@ const { setupNim } = require(${onboardPath}); const dcodeOutput = `${dcodeResult.stdout}\n${dcodeResult.stderr}`; assert.equal(dcodeResult.status, 0, dcodeOutput); expect(dcodeOutput).toContain( - "App: v0.1.12 | Agent: agent (default) | Model: nvidia/nemotron-3-ultra", + "App: v0.1.12 | Agent: agent (default) | Model: nvidia/nvidia/nemotron-3-ultra", ); expect(dcodeOutput).toContain("ARGS:--sandbox none --no-mcp -n ping"); - expect(dcodeOutput).not.toContain("nvidia/nvidia/"); + expect(dcodeOutput).not.toContain("nvidia/nvidia/nvidia/"); } finally { fs.rmSync(tmpDir, { recursive: true, force: true }); } diff --git a/tools/e2e-scenarios/workflow-boundary.mts b/tools/e2e-scenarios/workflow-boundary.mts index 71d1ac85a28..6811e3bb65a 100644 --- a/tools/e2e-scenarios/workflow-boundary.mts +++ b/tools/e2e-scenarios/workflow-boundary.mts @@ -1771,10 +1771,10 @@ function validateRebuildHermesVitestJob( if (jobEnv.NEMOCLAW_ENDPOINT_URL !== "https://inference-api.nvidia.com/v1") { errors.push(`${jobName} job must target hosted CI inference endpoint`); } - if (jobEnv.NEMOCLAW_MODEL !== "nvidia/nemotron-3-ultra") { + if (jobEnv.NEMOCLAW_MODEL !== "nvidia/nvidia/nemotron-3-ultra") { errors.push(`${jobName} job must pin the CI-safe Hermes rebuild model`); } - if (jobEnv.NEMOCLAW_COMPAT_MODEL !== "nvidia/nemotron-3-ultra") { + if (jobEnv.NEMOCLAW_COMPAT_MODEL !== "nvidia/nvidia/nemotron-3-ultra") { errors.push(`${jobName} job must pin the CI-safe compatible model`); } if (jobEnv.OPENSHELL_GATEWAY !== "nemoclaw") {