Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f81e586
Add rebrand for welcome UI, include launch.sh script
liveaverage Mar 11, 2026
53258bc
Remove BASH_SOURCE dependency
liveaverage Mar 11, 2026
9842d40
Address silent fail on launch.sh
liveaverage Mar 12, 2026
eb74ff4
Add favicon, handle ghcr.io login if params present, fix logo
liveaverage Mar 12, 2026
485a94e
Init LiteLLM implementation
nv-kasikritc Mar 12, 2026
754c756
LiteLLM working
nv-kasikritc Mar 12, 2026
dc1d7ac
Update welcome UI icon assets
liveaverage Mar 12, 2026
ce8197a
Add on-demand nemoclaw build; improve auto-pair
liveaverage Mar 12, 2026
6c319fa
Logo fixup, improve auto-approve cycle, NO_PROXY for localhost
liveaverage Mar 12, 2026
536e63c
Bump defualt context window, set NO_PROXY widely
liveaverage Mar 13, 2026
ec48954
Extend timer for device auto approval, minimize wait
liveaverage Mar 13, 2026
7d6355f
Reload dashboard once after pairing approval
liveaverage Mar 13, 2026
e512644
Revert nemoclaw runtime back to inference.local
liveaverage Mar 13, 2026
10d871a
Keep pairing watcher alive until approval
liveaverage Mar 13, 2026
9483694
Add proxy request tracing for sandbox launch
liveaverage Mar 13, 2026
b2f361c
Add override to skip nemoclaw image build
liveaverage Mar 13, 2026
6784eae
Add revised policy and NO_PROXY
liveaverage Mar 13, 2026
29720c9
Fix unconditional chown
liveaverage Mar 14, 2026
61e84fa
Added guarded reload for pairing; ensure custom policy.yaml bake-in
liveaverage Mar 14, 2026
93436b0
Add console logging for device pairing; extend NO_PROXY
liveaverage Mar 14, 2026
59b4389
Handle context mod for inference.local
liveaverage Mar 14, 2026
c35e759
Fix k3s image import on build; force reload on first pass timeout
liveaverage Mar 14, 2026
9ef9e78
Revise Brev README
liveaverage Mar 14, 2026
efeb9aa
Cleanup Brev section
liveaverage Mar 14, 2026
7aa8d18
Revert policy.yaml to orig
liveaverage Mar 14, 2026
77dd5cd
Merge origin/main into fix/branch-consolidation
Mar 15, 2026
3e100b0
Added policy recommender
Mar 15, 2026
2dda533
nemoclaw: inference UX overhaul, inline API keys, partner logos, deni…
Mar 15, 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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
node_modules/
AGENTS.md
AGENTS.md
10 changes: 2 additions & 8 deletions brev/launch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -568,12 +568,12 @@
set_inference_route() {
log "Configuring inference route..."

if "$CLI_BIN" inference set --provider nvidia-endpoints --model qwen/qwen3.5-397b-a17b >/dev/null 2>&1; then
if "$CLI_BIN" inference set --provider nvidia-endpoints --model minimaxai/minimax-m2.5 >/dev/null 2>&1; then
log "Configured inference via '$CLI_BIN inference set'."
return
fi

if "$CLI_BIN" cluster inference set --provider nvidia-endpoints --model qwen/qwen3.5-397b-a17b >/dev/null 2>&1; then
if "$CLI_BIN" cluster inference set --provider nvidia-endpoints --model minimaxai/minimax-m2.5 >/dev/null 2>&1; then
log "Configured inference via legacy '$CLI_BIN cluster inference set'."
return
fi
Expand Down Expand Up @@ -706,12 +706,6 @@
import_nemoclaw_image_into_cluster_if_needed

step "Configuring providers"
run_provider_create_or_replace \
nvidia-inference \
--type openai \
--credential OPENAI_API_KEY=unused \
--config OPENAI_BASE_URL=https://inference-api.nvidia.com/v1

run_provider_create_or_replace \
nvidia-endpoints \
--type nvidia \
Expand Down
44 changes: 21 additions & 23 deletions brev/welcome-ui/SERVER_ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ main()
├── 1. _bootstrap_config_cache()
│ If /tmp/nemoclaw-provider-config-cache.json does NOT exist:
│ Write defaults for:
│ - nvidia-inference → OPENAI_BASE_URL=https://inference-api.nvidia.com/v1
│ - nvidia-endpoints → NVIDIA_BASE_URL=https://integrate.api.nvidia.com/v1
│ If it already exists: skip (no-op)
Expand Down Expand Up @@ -436,13 +435,12 @@ Step 10: Cleanup temp policy file
```
Step 1: Log receipt (hash prefix)
Step 2: Run CLI command:
nemoclaw provider update nvidia-inference \
--type openai \
--credential OPENAI_API_KEY=<key> \
--config OPENAI_BASE_URL=https://inference-api.nvidia.com/v1
nemoclaw provider update nvidia-endpoints \
--credential NVIDIA_API_KEY=<key> \
--config NVIDIA_BASE_URL=https://integrate.api.nvidia.com/v1
Timeout: 120s
Step 3: If success:
- Cache config {"OPENAI_BASE_URL": "https://inference-api.nvidia.com/v1"} under name "nvidia-inference"
- Cache config under name "nvidia-endpoints"
- State → "done"
If failure:
- State → "error" with stderr/stdout message
Expand Down Expand Up @@ -537,10 +535,10 @@ Step 3: Merge with config cache values
The CLI outputs text like:
```
Id: abc-123
Name: nvidia-inference
Type: openai
Credential keys: OPENAI_API_KEY
Config keys: OPENAI_BASE_URL
Name: nvidia-endpoints
Type: nvidia
Credential keys: NVIDIA_API_KEY
Config keys: NVIDIA_BASE_URL
```

Parsing rules:
Expand All @@ -560,11 +558,11 @@ After parsing, if the provider name has an entry in the config cache, a `configV
"providers": [
{
"id": "abc-123",
"name": "nvidia-inference",
"type": "openai",
"credentialKeys": ["OPENAI_API_KEY"],
"configKeys": ["OPENAI_BASE_URL"],
"configValues": {"OPENAI_BASE_URL": "https://inference-api.nvidia.com/v1"}
"name": "nvidia-endpoints",
"type": "nvidia",
"credentialKeys": ["NVIDIA_API_KEY"],
"configKeys": ["NVIDIA_BASE_URL"],
"configValues": {"NVIDIA_BASE_URL": "https://integrate.api.nvidia.com/v1"}
}
]
}
Expand Down Expand Up @@ -671,7 +669,7 @@ nemoclaw cluster inference get

**Output Parsing (`_parse_cluster_inference`):**
```
Provider: nvidia-inference
Provider: nvidia-endpoints
Model: meta/llama-3.1-70b-instruct
Version: 2
```
Expand All @@ -688,7 +686,7 @@ Version: 2
```json
{
"ok": true,
"providerName": "nvidia-inference",
"providerName": "nvidia-endpoints",
"modelId": "meta/llama-3.1-70b-instruct",
"version": 2
}
Expand All @@ -703,7 +701,7 @@ Version: 2
**Request Body:**
```json
{
"providerName": "nvidia-inference",
"providerName": "nvidia-endpoints",
"modelId": "meta/llama-3.1-70b-instruct"
}
```
Expand All @@ -721,7 +719,7 @@ nemoclaw cluster inference set --provider <name> --model <model>
```json
{
"ok": true,
"providerName": "nvidia-inference",
"providerName": "nvidia-endpoints",
"modelId": "meta/llama-3.1-70b-instruct",
"version": 3
}
Expand Down Expand Up @@ -925,7 +923,7 @@ The `nemoclaw provider get` CLI only returns config **key names**, not their val
- Read on every `GET /api/providers` request
- Written on every `POST` (create) and `PUT` (update) that includes config values
- Cleaned up on `DELETE`
- Bootstrapped at server startup with a default for `nvidia-inference`
- Bootstrapped at server startup with a default for `nvidia-endpoints`

---

Expand All @@ -948,8 +946,8 @@ Output is parsed the same way as provider detail (line-by-line, prefix matching,
**Format:**
```json
{
"nvidia-inference": {
"OPENAI_BASE_URL": "https://inference-api.nvidia.com/v1"
"nvidia-endpoints": {
"NVIDIA_BASE_URL": "https://integrate.api.nvidia.com/v1"
},
"my-custom-provider": {
"CUSTOM_URL": "https://example.com"
Expand Down Expand Up @@ -1237,7 +1235,7 @@ This means it uses a local sandbox name rather than a container image reference.

### 18.10 Inject Key Hardcodes Provider Name

The `_run_inject_key` function hardcodes `nvidia-inference` as the provider name. This is not configurable via the API.
The `_run_inject_key` function hardcodes `nvidia-endpoints` as the provider name. This is not configurable via the API.

### 18.11 Error State Truncation

Expand Down
6 changes: 3 additions & 3 deletions brev/welcome-ui/__tests__/cli-parsing.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe("parseProviderDetail", () => {
const result = parseProviderDetail(FIXTURES.providerGetOutput);
expect(result).toEqual({
id: "abc-123",
name: "nvidia-inference",
name: "nvidia-endpoints",
type: "openai",
credentialKeys: ["OPENAI_API_KEY"],
configKeys: ["OPENAI_BASE_URL"],
Expand Down Expand Up @@ -63,7 +63,7 @@ describe("parseProviderDetail", () => {
it("TC-CL09: ANSI codes in output are stripped before parsing", () => {
const result = parseProviderDetail(FIXTURES.providerGetAnsi);
expect(result).not.toBeNull();
expect(result.name).toBe("nvidia-inference");
expect(result.name).toBe("nvidia-endpoints");
expect(result.type).toBe("openai");
});
});
Expand All @@ -72,7 +72,7 @@ describe("parseClusterInference", () => {
it("TC-CL10: parses Provider, Model, Version lines", () => {
const result = parseClusterInference(FIXTURES.clusterInferenceOutput);
expect(result).toEqual({
providerName: "nvidia-inference",
providerName: "nvidia-endpoints",
modelId: "meta/llama-3.1-70b-instruct",
version: 2,
});
Expand Down
4 changes: 2 additions & 2 deletions brev/welcome-ui/__tests__/cluster-inference.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe("GET /api/cluster-inference", () => {
const res = await request(server).get("/api/cluster-inference");
expect(res.status).toBe(200);
expect(res.body.ok).toBe(true);
expect(res.body.providerName).toBe("nvidia-inference");
expect(res.body.providerName).toBe("nvidia-endpoints");
expect(res.body.modelId).toBe("meta/llama-3.1-70b-instruct");
expect(res.body.version).toBe(2);
});
Expand Down Expand Up @@ -95,7 +95,7 @@ describe("GET /api/cluster-inference", () => {

const res = await request(server).get("/api/cluster-inference");
expect(res.status).toBe(200);
expect(res.body.providerName).toBe("nvidia-inference");
expect(res.body.providerName).toBe("nvidia-endpoints");
expect(res.body.modelId).toBe("meta/llama-3.1-70b-instruct");
});
});
Expand Down
7 changes: 2 additions & 5 deletions brev/welcome-ui/__tests__/config-cache.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe("config cache", () => {
bootstrapConfigCache();
const cache = readCacheFile();
expect(cache).not.toBeNull();
expect(cache["nvidia-inference"]).toBeDefined();
expect(cache["nvidia-endpoints"]).toBeDefined();
});

it("TC-CC02: bootstrapConfigCache is no-op when file already exists", () => {
Expand All @@ -29,13 +29,10 @@ describe("config cache", () => {
expect(cache).toEqual({ custom: { x: 1 } });
});

it("TC-CC03: default bootstrap content seeds both NVIDIA inference providers", () => {
it("TC-CC03: default bootstrap content seeds NVIDIA endpoints provider", () => {
bootstrapConfigCache();
const cache = readCacheFile();
expect(cache).toEqual({
"nvidia-inference": {
OPENAI_BASE_URL: "https://inference-api.nvidia.com/v1",
},
"nvidia-endpoints": {
NVIDIA_BASE_URL: "https://integrate.api.nvidia.com/v1",
},
Expand Down
13 changes: 3 additions & 10 deletions brev/welcome-ui/__tests__/inject-key.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ describe("inject-key background process", () => {
execFile.mockClear();
});

it("TC-K10: updates both default inference providers with the submitted key", async () => {
it("TC-K10: updates default NVIDIA endpoints provider with the submitted key", async () => {
execFile.mockImplementation((cmd, args, opts, cb) => {
if (typeof opts === "function") { cb = opts; opts = {}; }
cb(null, "", "");
Expand All @@ -161,15 +161,9 @@ describe("inject-key background process", () => {
const updateCalls = execFile.mock.calls.filter(
(c) => c[0] === "nemoclaw" && c[1]?.includes("update")
);
expect(updateCalls.length).toBeGreaterThanOrEqual(2);
expect(updateCalls.length).toBeGreaterThanOrEqual(1);

const inferenceArgs = updateCalls.find((c) => c[1].includes("nvidia-inference"))?.[1] || [];
const endpointsArgs = updateCalls.find((c) => c[1].includes("nvidia-endpoints"))?.[1] || [];

expect(inferenceArgs).toContain("nvidia-inference");
expect(inferenceArgs.some((a) => a.startsWith("OPENAI_API_KEY="))).toBe(true);
expect(inferenceArgs.some((a) => a.includes("inference-api.nvidia.com"))).toBe(true);

expect(endpointsArgs).toContain("nvidia-endpoints");
expect(endpointsArgs.some((a) => a.startsWith("NVIDIA_API_KEY="))).toBe(true);
expect(endpointsArgs.some((a) => a.includes("integrate.api.nvidia.com"))).toBe(true);
Expand Down Expand Up @@ -245,7 +239,7 @@ describe("key hashing", () => {
expect(hashKey("abc")).toBe(hashKey("abc"));
});

it("TC-K16: provider updates cover both nvidia-inference and nvidia-endpoints", async () => {
it("TC-K16: provider updates cover nvidia-endpoints", async () => {
execFile.mockImplementation((cmd, args, opts, cb) => {
if (typeof opts === "function") { cb = opts; opts = {}; }
cb(null, "", "");
Expand All @@ -260,7 +254,6 @@ describe("key hashing", () => {
const updateCalls = execFile.mock.calls.filter(
(c) => c[0] === "nemoclaw" && c[1]?.includes("update")
);
expect(updateCalls.some((c) => c[1].includes("nvidia-inference"))).toBe(true);
expect(updateCalls.some((c) => c[1].includes("nvidia-endpoints"))).toBe(true);
});
});
4 changes: 2 additions & 2 deletions brev/welcome-ui/__tests__/providers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe("GET /api/providers", () => {
execFile.mockImplementation((cmd, args, opts, cb) => {
if (typeof opts === "function") { cb = opts; opts = {}; }
if (args?.[1] === "list") {
return cb(null, "nvidia-inference\n", "");
return cb(null, "nvidia-endpoints\n", "");
}
if (args?.[1] === "get") {
return cb(null, FIXTURES.providerGetOutput, "");
Expand All @@ -54,7 +54,7 @@ describe("GET /api/providers", () => {
expect(res.body.ok).toBe(true);
expect(Array.isArray(res.body.providers)).toBe(true);
expect(res.body.providers.length).toBe(1);
expect(res.body.providers[0].name).toBe("nvidia-inference");
expect(res.body.providers[0].name).toBe("nvidia-endpoints");
});

it("TC-PR02: provider list CLI failure returns 502", async () => {
Expand Down
10 changes: 5 additions & 5 deletions brev/welcome-ui/__tests__/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ function readCacheFile() {
// CLI output fixtures matching the nemoclaw CLI text format

const FIXTURES = {
providerListOutput: "nvidia-inference\ncustom-provider\n",
providerListOutput: "nvidia-endpoints\ncustom-provider\n",

providerGetOutput: [
"Id: abc-123",
"Name: nvidia-inference",
"Name: nvidia-endpoints",
"Type: openai",
"Credential keys: OPENAI_API_KEY",
"Config keys: OPENAI_BASE_URL",
Expand All @@ -55,19 +55,19 @@ const FIXTURES = {

providerGetAnsi:
"\x1b[32mId:\x1b[0m abc-123\n" +
"\x1b[32mName:\x1b[0m nvidia-inference\n" +
"\x1b[32mName:\x1b[0m nvidia-endpoints\n" +
"\x1b[32mType:\x1b[0m openai\n" +
"\x1b[32mCredential keys:\x1b[0m OPENAI_API_KEY\n" +
"\x1b[32mConfig keys:\x1b[0m OPENAI_BASE_URL\n",

clusterInferenceOutput: [
"Provider: nvidia-inference",
"Provider: nvidia-endpoints",
"Model: meta/llama-3.1-70b-instruct",
"Version: 2",
].join("\n"),

clusterInferenceAnsi:
"\x1b[1;34mProvider:\x1b[0m nvidia-inference\n" +
"\x1b[1;34mProvider:\x1b[0m nvidia-endpoints\n" +
"\x1b[1;34mModel:\x1b[0m meta/llama-3.1-70b-instruct\n" +
"\x1b[1;34mVersion:\x1b[0m 2\n",

Expand Down
Loading
Loading