fix(onboard): decouple local inference providers from OPENAI_API_KEY#2580
Conversation
Local Ollama and local vLLM (incl. NIM) providers were capturing the host's OPENAI_API_KEY into onboard-session.json and credentials.json, then registering the gateway provider with credentialEnv=OPENAI_API_KEY. A stale or invalid host OPENAI_API_KEY would override the local proxy bearer at request time and surface as HTTP 401 on every prompt; an unset OPENAI_API_KEY would also block `nemoclaw rebuild --auto` preflight even though the sandbox never needed an OpenAI key. The wizard now records credentialEnv=null for ollama-local and vllm-local. setupInference registers the gateway under dedicated internal env names (NEMOCLAW_OLLAMA_PROXY_TOKEN / NEMOCLAW_VLLM_LOCAL_TOKEN) and prunes any pre-fix OPENAI_API_KEY entry from credentials.json so \`unset OPENAI_API_KEY; nemoclaw onboard\` behaves as expected. The rebuild preflight migrates legacy sandboxes that already recorded credentialEnv=OPENAI_API_KEY by printing a one-time notice and proceeding without demanding a host API key. Refs GH #2519 Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughLocal inference providers (Ollama, vLLM) are decoupled from the OpenAI key: new dedicated environment variables are introduced and used; onboarding and rebuild detect and migrate legacy sessions that recorded Changes
Sequence Diagram(s)sequenceDiagram
participant CLI as CLI
participant Onboard as OnboardLogic
participant Provider as ProviderRegistry
participant Env as Env (process)
participant Store as CredentialsStore
CLI->>Onboard: start setup or rebuild
Onboard->>Provider: select provider (ollama-local / vllm-local)
Provider->>Onboard: returns recorded credentialEnv
alt recorded credentialEnv == "OPENAI_API_KEY" for local provider
Onboard-->>CLI: log migration notice (GH `#2519`)
Onboard->>Provider: treat credentialEnv as null
end
Onboard->>Env: read dedicated env (OLLAMA_LOCAL_CREDENTIAL_ENV / VLLM_LOCAL_CREDENTIAL_ENV)
Onboard->>Provider: upsert provider with dedicated credentialEnv / internal token
Onboard->>Store: delete `OPENAI_API_KEY` if present
Onboard-->>CLI: continue (setup complete / rebuild proceeds)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/onboard.ts`:
- Around line 4752-4754: The call to deleteCredential("OPENAI_API_KEY") is
running too early and must be moved into the successful local-provider setup
path: only invoke deleteCredential after providerResult indicates registration
succeeded and after the local inference setup flow completes (the "inference
set" flow) so we don't remove a user key on failed onboarding; update the
instance where deleteCredential is called near the providerResult check (and the
duplicate at the other occurrence) to run in the success branch that confirms
provider registration and local configuration finished.
- Around line 4741-4751: The sandbox config still serializes legacy credential
envs for local providers; update setupOpenclaw() and
getProviderSelectionConfig(provider, model) so that when provider.id is
"vllm-local" or "ollama-local" (or when using
VLLM_LOCAL_CREDENTIAL_ENV/OLLAMA_LOCAL_CREDENTIAL_ENV), the returned provider
selection object sets credentialEnv (or credential_env) to null/undefined before
writing /sandbox/.nemoclaw/config.json; additionally update
src/lib/inference-config.ts to remove / stop mapping "vllm-local" and
"ollama-local" to OPENAI_API_KEY so consumers of the sandbox config cannot
resurrect the legacy OPENAI_API_KEY requirement.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 4ff7ecb8-e9cb-4cc3-b264-199c4bbb8289
📒 Files selected for processing (5)
src/lib/onboard-providers.tssrc/lib/onboard.tssrc/nemoclaw.tstest/onboard-selection.test.tstest/rebuild-credential-preflight.test.ts
CodeRabbit review on #2580 caught two issues: 1. getProviderSelectionConfig() in inference-config.ts still mapped ollama-local and vllm-local to OPENAI_API_KEY. That value flows into /sandbox/.nemoclaw/config.json via agent-onboard.ts, so the in-sandbox OpenClaw could resurrect the legacy credential requirement even after the gateway-side fix. 2. deleteCredential("OPENAI_API_KEY") ran before upsertProvider was verified and before `inference set` completed. A failed onboard would silently nuke a previously-saved OpenAI key the user may still need for a different provider. Move the credential env definitions to inference-config.ts so the sandbox-side and gateway-side paths share a single source of truth, and move both deleteCredential calls to run last in the success path. Refs GH #2519 Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/lib/onboard.ts (1)
4756-4771:⚠️ Potential issue | 🟠 MajorOnly prune
OPENAI_API_KEYafterinference setis actually confirmed.Line 4756 and Line 4814 ignore the result of
runOpenshell(["inference", "set", ...]), so Lines 4767-4771 and 4832-4839 can still delete a valid saved OpenAI key when the apply fails and the route never becomes ready. Move the prune until after theinference setresult is checked andverifyInferenceRoute(provider, model)has passed.Suggested fix
async function setupInference( sandboxName: string | null, model: string, provider: string, endpointUrl: string | null = null, credentialEnv: string | null = null, ): Promise<{ ok: true; retry?: undefined } | { retry: "selection" }> { step(4, 8, "Setting up inference provider"); runOpenshell(["gateway", "select", GATEWAY_NAME], { ignoreError: true }); + let shouldPruneLegacyOpenAiKey = false; if ( provider === "nvidia-prod" || @@ } else if (provider === "vllm-local") { @@ - runOpenshell([ + const applyResult = runOpenshell([ "inference", "set", "--no-verify", "--provider", "vllm-local", @@ "--timeout", String(LOCAL_INFERENCE_TIMEOUT_SECS), - ]); - // Prune any pre-fix OPENAI_API_KEY entry from credentials.json now that - // vllm-local is fully confirmed. Done last so a failed registration - // does not delete a credential the user may still need for a remote - // provider. - deleteCredential("OPENAI_API_KEY"); + ], { ignoreError: true }); + if (applyResult.status !== 0) { + process.exit(applyResult.status || 1); + } + shouldPruneLegacyOpenAiKey = true; } else if (provider === "ollama-local") { @@ - runOpenshell([ + const applyResult = runOpenshell([ "inference", "set", "--no-verify", "--provider", "ollama-local", @@ "--timeout", String(LOCAL_INFERENCE_TIMEOUT_SECS), - ]); + ], { ignoreError: true }); + if (applyResult.status !== 0) { + process.exit(applyResult.status || 1); + } @@ - deleteCredential("OPENAI_API_KEY"); + shouldPruneLegacyOpenAiKey = true; } verifyInferenceRoute(provider, model); + if (shouldPruneLegacyOpenAiKey) { + deleteCredential("OPENAI_API_KEY"); + }Also applies to: 4814-4839
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/onboard.ts` around lines 4756 - 4771, The code currently calls runOpenshell(["inference","set",...]) and then immediately calls deleteCredential("OPENAI_API_KEY"), which can remove a valid key even if the inference set fails; change the flow so you capture and check the result of runOpenshell (the same invocation used at lines around runOpenshell([...])) and only call deleteCredential("OPENAI_API_KEY") after verifyInferenceRoute(provider, model) returns success (i.e., the route is confirmed ready); update the control flow around runOpenshell, verifyInferenceRoute, and deleteCredential to bail on failure and log/propagate the error instead of pruning the credential.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/lib/onboard.ts`:
- Around line 4756-4771: The code currently calls
runOpenshell(["inference","set",...]) and then immediately calls
deleteCredential("OPENAI_API_KEY"), which can remove a valid key even if the
inference set fails; change the flow so you capture and check the result of
runOpenshell (the same invocation used at lines around runOpenshell([...])) and
only call deleteCredential("OPENAI_API_KEY") after
verifyInferenceRoute(provider, model) returns success (i.e., the route is
confirmed ready); update the control flow around runOpenshell,
verifyInferenceRoute, and deleteCredential to bail on failure and log/propagate
the error instead of pruning the credential.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 689cbbfe-dbe6-4563-95d4-87e299e00a87
📒 Files selected for processing (4)
src/lib/inference-config.test.tssrc/lib/inference-config.tssrc/lib/onboard-providers.tssrc/lib/onboard.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/onboard.ts`:
- Around line 4803-4807: The code is deleting the global OPENAI_API_KEY from
credentials.json via deleteCredential("OPENAI_API_KEY") during local sandbox
onboarding which mutates shared state; remove the two calls to
deleteCredential("OPENAI_API_KEY") in onboard.ts (the block around the
vllm-local confirmation and the later block referenced) so onboarding no longer
removes the global key, and also remove deleteCredential from the destructured
credentials import (so the symbol is not used); keep all other migration logic
(credentialEnv=null and rebuild preflight) intact.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 6bb3d687-606d-4ef9-8328-beb35ee15d68
📒 Files selected for processing (1)
src/lib/onboard.ts
…redential-decoupling # Conflicts: # src/lib/onboard.ts
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/lib/onboard.ts (1)
4998-5002:⚠️ Potential issue | 🟠 MajorDon't delete the shared
OPENAI_API_KEYhere.
deleteCredential()updates the global~/.nemoclaw/credentials.json, not sandbox-scoped state. A successful local-provider onboard can therefore remove the saved key for other OpenAI-backed sandboxes/users on the same host, even though rebuild already migrates legacy local sessions offOPENAI_API_KEY.Suggested fix
- // Prune any pre-fix OPENAI_API_KEY entry from credentials.json now that - // vllm-local is fully confirmed. Done last so a failed registration - // does not delete a credential the user may still need for a remote - // provider. - deleteCredential("OPENAI_API_KEY");- // Prune any pre-fix OPENAI_API_KEY entry from credentials.json now that - // ollama-local is fully confirmed (provider registered, inference set, - // model warm). Done last so a failed onboard does not delete a credential - // the user may still need for a remote provider. Without this, an - // invalid OpenAI key cached by an earlier onboard would still be hit by - // `getCredential` callers, and `unset OPENAI_API_KEY; nemoclaw onboard` - // would not clear it. - deleteCredential("OPENAI_API_KEY");Also applies to: 5063-5070
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/onboard.ts` around lines 4998 - 5002, The call to deleteCredential("OPENAI_API_KEY") is removing the global ~/.nemoclaw/credentials.json entry (affecting other sandboxes/users); remove that global deletion and instead clear the key only from the sandbox-scoped state—replace the deleteCredential("OPENAI_API_KEY") invocation with a sandbox-local update (e.g., call the sandbox credential API used elsewhere in this module such as updateSandboxCredentials/removeSandboxCredential or mutate the current sandbox's credentials object and persist it via the existing sandbox save function) so the global credentials.json is not modified; apply the same change at the duplicate spot that currently calls deleteCredential for OPENAI_API_KEY.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/lib/onboard.ts`:
- Around line 4998-5002: The call to deleteCredential("OPENAI_API_KEY") is
removing the global ~/.nemoclaw/credentials.json entry (affecting other
sandboxes/users); remove that global deletion and instead clear the key only
from the sandbox-scoped state—replace the deleteCredential("OPENAI_API_KEY")
invocation with a sandbox-local update (e.g., call the sandbox credential API
used elsewhere in this module such as
updateSandboxCredentials/removeSandboxCredential or mutate the current sandbox's
credentials object and persist it via the existing sandbox save function) so the
global credentials.json is not modified; apply the same change at the duplicate
spot that currently calls deleteCredential for OPENAI_API_KEY.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 6aa86b16-d46a-40b5-b192-07c6a4a14c40
📒 Files selected for processing (2)
src/lib/onboard.tssrc/nemoclaw.ts
✅ Files skipped from review due to trivial changes (1)
- src/nemoclaw.ts
cv
left a comment
There was a problem hiding this comment.
Security review PASS. I checked the local-inference credential path for #2519 and the CodeRabbit major finding: local Ollama/vLLM now register with dedicated internal env names instead of OPENAI_API_KEY, legacy rebuild preflight migrates old local sessions without requiring a host OpenAI key, and the salvage commit preserves any saved OPENAI_API_KEY for unrelated OpenAI-backed sandboxes. Tests cover the selection/session behavior, legacy rebuild migration, and the no-global-delete regression. CI is green; mergeable=MERGEABLE (mergeStateStatus is BLOCKED only because review was required).
## Summary Refreshes the 0.0.29 documentation for user-facing changes merged in the past 24 hours. Version metadata stays on `0.0.29`. ## Changes - `docs/get-started/quickstart.md`, `docs/reference/commands.md`, and `docs/reference/troubleshooting.md`: Document dashboard port auto-allocation, `--control-ui-port`, and `nemoclaw list` dashboard URL output from [#2411](#2411). - `docs/inference/inference-options.md` and `docs/inference/switch-inference-providers.md`: Document local Ollama and local vLLM credential isolation from `OPENAI_API_KEY` from [#2580](#2580). - `docs/inference/inference-options.md`: Document Local NVIDIA NIM validation behavior from [#2505](#2505). - `docs/reference/commands.md`: Document the cloud-only NIM status display behavior from [#2622](#2622). - `docs/deployment/deploy-to-remote-gpu.md`: Clarify runtime propagation for `NEMOCLAW_PROXY_HOST` and `NEMOCLAW_PROXY_PORT` from [#2581](#2581). - `docs/workspace/backup-restore.md`: Document snapshot restore symlink handling for sandbox data paths from [#2488](#2488). - `docs/reference/commands.md`: Document `skill install --help` and OpenClaw plugin-shaped directory guidance from [#2585](#2585). ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [x] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Verification - [x] `npx prek run --all-files` passes - [ ] `npm test` passes - [ ] Tests added or updated for new or changed behavior - [x] No secrets, API keys, or credentials committed - [x] Docs updated for user-facing behavior changes - [x] `make docs` builds without warnings (doc changes only) - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) ## AI Disclosure - [x] AI-assisted — tool: Codex --- Signed-off-by: Miyoung Choi <miyoungc@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added `--control-ui-port` flag for explicit dashboard port control * Implemented automatic port selection (18789–18799) when the default port is occupied * Clarified that local inference routes (Ollama, local vLLM) don't require `OPENAI_API_KEY` * Improved dashboard URL display in list and status commands * Enhanced symlink handling in workspace backup restoration * Updated multi-sandbox quickstart and troubleshooting guidance <!-- end of auto-generated comment: release notes by coderabbit.ai -->
…VIDIA#2580) ## Summary Local Ollama and local vLLM (incl. NIM) onboards were capturing the host's `OPENAI_API_KEY` and registering the gateway provider with `credentialEnv=OPENAI_API_KEY`. A stale or invalid host key would override the local proxy bearer at request time and surface as HTTP 401 on every prompt; an unset key would also block `nemoclaw rebuild --auto` preflight even though the sandbox never needed an OpenAI key. This PR decouples local inference from the user's OpenAI key entirely. ## Related Issue Refs NVIDIA#2519 ## Changes - Wizard now records `credentialEnv = null` for `ollama-local` and `vllm-local` (both NIM and vllm branches). The "Review configuration" line shows `(not required for ...)` and `onboard-session.json` no longer carries `OPENAI_API_KEY`. - `setupInference` registers the gateway under dedicated internal env names — `NEMOCLAW_OLLAMA_PROXY_TOKEN` for ollama-local, `NEMOCLAW_VLLM_LOCAL_TOKEN` for vllm-local — so the gateway never reads the user's host `OPENAI_API_KEY`. - After confirming a local inference provider, any pre-fix `OPENAI_API_KEY` entry is pruned from `~/.nemoclaw/credentials.json` so `unset OPENAI_API_KEY; nemoclaw onboard` clears the stale value. - Rebuild preflight in `nemoclaw.ts` migrates legacy sandboxes (where `onboard-session.json` already recorded `credentialEnv=OPENAI_API_KEY`) by printing a one-time migration notice and proceeding without demanding a host API key. - New `it.each` test in `test/rebuild-credential-preflight.test.ts` covers the legacy migration for both `ollama-local` and `vllm-local`. - Existing ollama validation test in `test/onboard-selection.test.ts` extended to assert `credentialEnv === null` and that the ollama-local path does not write `OPENAI_API_KEY` into `credentials.json`. ## Type of Change - [x] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Verification - [ ] `npx prek run --all-files` passes - [x] `npm test` passes for the affected suites (`test/rebuild-credential-preflight.test.ts`, `test/onboard-selection.test.ts`) — 41 tests green - [x] Tests added for the new behavior (legacy preflight migration; ollama-local credentialEnv=null) - [x] No secrets, API keys, or credentials committed - [ ] Docs updated for user-facing behavior changes - [ ] `make docs` builds without warnings (doc changes only) - [ ] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) Note on `npx prek run --all-files`: 4 unrelated tests in `test/onboard.test.ts` (5-second timeout on sandbox-build spawn cases) currently fail on `main` independent of this PR — verified by running the same isolated case on a clean checkout. Those flakes are out of scope for this fix. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Local inference providers (Ollama, vLLM) no longer rely on your OpenAI API key; they use dedicated local credentials, won’t prompt for or reuse the OpenAI key, and will remove stale OpenAI entries during setup or migration. * Rebuild/migration paths detect legacy sessions, show a migration notice, and avoid failing due to obsolete OpenAI credentials. * **Tests** * Added tests verifying credential isolation, deletion of stale OpenAI entries, and resilient rebuild/migration behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Aaron Erickson <aerickson@nvidia.com> Co-authored-by: Carlos Villela <cvillela@nvidia.com>
## Summary Refreshes the 0.0.29 documentation for user-facing changes merged in the past 24 hours. Version metadata stays on `0.0.29`. ## Changes - `docs/get-started/quickstart.md`, `docs/reference/commands.md`, and `docs/reference/troubleshooting.md`: Document dashboard port auto-allocation, `--control-ui-port`, and `nemoclaw list` dashboard URL output from [NVIDIA#2411](NVIDIA#2411). - `docs/inference/inference-options.md` and `docs/inference/switch-inference-providers.md`: Document local Ollama and local vLLM credential isolation from `OPENAI_API_KEY` from [NVIDIA#2580](NVIDIA#2580). - `docs/inference/inference-options.md`: Document Local NVIDIA NIM validation behavior from [NVIDIA#2505](NVIDIA#2505). - `docs/reference/commands.md`: Document the cloud-only NIM status display behavior from [NVIDIA#2622](NVIDIA#2622). - `docs/deployment/deploy-to-remote-gpu.md`: Clarify runtime propagation for `NEMOCLAW_PROXY_HOST` and `NEMOCLAW_PROXY_PORT` from [NVIDIA#2581](NVIDIA#2581). - `docs/workspace/backup-restore.md`: Document snapshot restore symlink handling for sandbox data paths from [NVIDIA#2488](NVIDIA#2488). - `docs/reference/commands.md`: Document `skill install --help` and OpenClaw plugin-shaped directory guidance from [NVIDIA#2585](NVIDIA#2585). ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [x] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Verification - [x] `npx prek run --all-files` passes - [ ] `npm test` passes - [ ] Tests added or updated for new or changed behavior - [x] No secrets, API keys, or credentials committed - [x] Docs updated for user-facing behavior changes - [x] `make docs` builds without warnings (doc changes only) - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) ## AI Disclosure - [x] AI-assisted — tool: Codex --- Signed-off-by: Miyoung Choi <miyoungc@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added `--control-ui-port` flag for explicit dashboard port control * Implemented automatic port selection (18789–18799) when the default port is occupied * Clarified that local inference routes (Ollama, local vLLM) don't require `OPENAI_API_KEY` * Improved dashboard URL display in list and status commands * Enhanced symlink handling in workspace backup restoration * Updated multi-sandbox quickstart and troubleshooting guidance <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Summary
Local Ollama and local vLLM (incl. NIM) onboards were capturing the host's
OPENAI_API_KEYand registering the gateway provider withcredentialEnv=OPENAI_API_KEY. A stale or invalid host key would override the local proxy bearer at request time and surface as HTTP 401 on every prompt; an unset key would also blocknemoclaw rebuild --autopreflight even though the sandbox never needed an OpenAI key. This PR decouples local inference from the user's OpenAI key entirely.Related Issue
Refs #2519
Changes
credentialEnv = nullforollama-localandvllm-local(both NIM and vllm branches). The "Review configuration" line shows(not required for ...)andonboard-session.jsonno longer carriesOPENAI_API_KEY.setupInferenceregisters the gateway under dedicated internal env names —NEMOCLAW_OLLAMA_PROXY_TOKENfor ollama-local,NEMOCLAW_VLLM_LOCAL_TOKENfor vllm-local — so the gateway never reads the user's hostOPENAI_API_KEY.OPENAI_API_KEYentry is pruned from~/.nemoclaw/credentials.jsonsounset OPENAI_API_KEY; nemoclaw onboardclears the stale value.nemoclaw.tsmigrates legacy sandboxes (whereonboard-session.jsonalready recordedcredentialEnv=OPENAI_API_KEY) by printing a one-time migration notice and proceeding without demanding a host API key.it.eachtest intest/rebuild-credential-preflight.test.tscovers the legacy migration for bothollama-localandvllm-local.test/onboard-selection.test.tsextended to assertcredentialEnv === nulland that the ollama-local path does not writeOPENAI_API_KEYintocredentials.json.Type of Change
Verification
npx prek run --all-filespassesnpm testpasses for the affected suites (test/rebuild-credential-preflight.test.ts,test/onboard-selection.test.ts) — 41 tests greenmake docsbuilds without warnings (doc changes only)Note on
npx prek run --all-files: 4 unrelated tests intest/onboard.test.ts(5-second timeout on sandbox-build spawn cases) currently fail onmainindependent of this PR — verified by running the same isolated case on a clean checkout. Those flakes are out of scope for this fix.Summary by CodeRabbit
Bug Fixes
Tests