Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions src/lib/onboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6124,8 +6124,7 @@ async function setupNim(
["curl", "-sf", ...localProbeCurlArgs, `http://127.0.0.1:${VLLM_PORT}/v1/models`],
{ ignoreError: true },
);
// Pick a vLLM install recipe for this host. Profiles live in inference/vllm.ts;
// null means "no supported platform" (vLLM stays behind EXPERIMENTAL).
// Pick a vLLM install recipe for this host. Profiles live in inference/vllm.ts.
const vllmProfile = detectVllmProfile(gpu);
// If the profile's image is already cached, the install path is really a
// "start" — docker pull is a no-op and the container can come up in seconds.
Expand Down Expand Up @@ -6237,6 +6236,7 @@ async function setupNim(
vllmRunning,
vllmProfile,
experimental: EXPERIMENTAL,
platform: gpu?.platform,
hasVllmImage,
}),
);
Expand Down
43 changes: 43 additions & 0 deletions src/lib/onboard/vllm-menu.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,49 @@ describe("buildVllmMenuEntries", () => {
assert.equal(entries[0].label, "Install vLLM (Linux NVIDIA)");
});

it("returns the install entry by default for DGX Spark", () => {
const entries = buildVllmMenuEntries({
vllmRunning: false,
vllmProfile: { name: "DGX Spark" },
experimental: false,
platform: "spark",
hasVllmImage: false,
env: {},
log: () => {},
});
assert.equal(entries.length, 1);
assert.equal(entries[0].key, "install-vllm");
assert.equal(entries[0].label, "Install vLLM (DGX Spark)");
});

it("returns the start entry by default for DGX Station when the image is already cached", () => {
const entries = buildVllmMenuEntries({
vllmRunning: false,
vllmProfile: { name: "DGX Station" },
experimental: false,
platform: "station",
hasVllmImage: true,
env: {},
log: () => {},
});
assert.equal(entries.length, 1);
assert.equal(entries[0].key, "install-vllm");
assert.equal(entries[0].label, "Start vLLM (DGX Station)");
});

it("keeps generic Linux managed vLLM behind EXPERIMENTAL", () => {
const entries = buildVllmMenuEntries({
vllmRunning: false,
vllmProfile: { name: "Linux NVIDIA" },
experimental: false,
platform: "linux",
hasVllmImage: false,
env: {},
log: () => {},
});
assert.deepEqual(entries, []);
});

it("uses Start verb when the image is already cached", () => {
const entries = buildVllmMenuEntries({
vllmRunning: false,
Expand Down
18 changes: 14 additions & 4 deletions src/lib/onboard/vllm-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,20 @@
* buildVllmMenuEntries always emits the install-vllm entry when the user
* explicitly opts in via NEMOCLAW_PROVIDER=install-vllm, even when the profile
* is null, so the dispatcher can emit the precise "No vLLM install profile
* available for this host." message. It also logs a note when running-vLLM
* takes precedence over the env-var opt-in.
* available for this host." message. It also lets the caller surface managed
* vLLM by default for known DGX platforms while generic Linux stays gated, and
* logs a note when running-vLLM takes precedence over the env-var opt-in.
*/

import { VLLM_PORT } from "../core/ports";
import type { NvidiaPlatform } from "../inference/nim";

interface VllmProfileShape {
name: string;
}

const MANAGED_VLLM_DEFAULT_PLATFORMS = new Set<NvidiaPlatform>(["spark", "station"]);

export interface VllmMenuEntry {
key: "vllm" | "install-vllm";
label: string;
Expand All @@ -37,6 +41,7 @@ export interface BuildVllmMenuOptions {
vllmRunning: boolean;
vllmProfile: VllmProfileShape | null | undefined;
experimental: boolean;
platform?: NvidiaPlatform;
hasVllmImage: boolean;
/** Defaults to process.env so tests can inject a clean environment. */
env?: NodeJS.ProcessEnv;
Expand All @@ -49,7 +54,8 @@ export function buildVllmMenuEntries(opts: BuildVllmMenuOptions): VllmMenuEntry[
// env-var opt-in surface the menu entry too — the non-interactive provider
// hint is null outside non-interactive mode.
const env = opts.env ?? process.env;
const userChoseManagedVllm = (env.NEMOCLAW_PROVIDER || "").trim().toLowerCase() === "install-vllm";
const userChoseManagedVllm =
(env.NEMOCLAW_PROVIDER || "").trim().toLowerCase() === "install-vllm";
if (opts.vllmRunning) {
if (userChoseManagedVllm) {
log(
Expand All @@ -63,7 +69,11 @@ export function buildVllmMenuEntries(opts: BuildVllmMenuOptions): VllmMenuEntry[
},
];
}
if (userChoseManagedVllm || (opts.vllmProfile && opts.experimental)) {
if (
userChoseManagedVllm ||
(opts.vllmProfile &&
(opts.experimental || MANAGED_VLLM_DEFAULT_PLATFORMS.has(opts.platform as NvidiaPlatform)))
) {
const verb = opts.hasVllmImage ? "Start" : "Install";
const profileLabel = opts.vllmProfile?.name ?? "no profile detected";
return [{ key: "install-vllm", label: `${verb} vLLM (${profileLabel})` }];
Expand Down
Loading