Skip to content

fix(onboard): front Ollama with the auth proxy on WSL native Docker too#3732

Merged
ericksoa merged 7 commits into
mainfrom
fix/ollama-wsl-host-binding
May 19, 2026
Merged

fix(onboard): front Ollama with the auth proxy on WSL native Docker too#3732
ericksoa merged 7 commits into
mainfrom
fix/ollama-wsl-host-binding

Conversation

@laitingsheng

@laitingsheng laitingsheng commented May 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes a long-standing assumption that WSL2 sandboxes always reach the host's loopback directly. That's only true under Docker Desktop; with native dockerd installed inside the WSL distro the sandbox container goes through the Docker bridge gateway (typically 172.17.0.1), which can't see Ollama bound to 127.0.0.1. Front Ollama with the existing auth proxy in that topology, and harden the systemd loopback override so legacy 0.0.0.0:11434 drop-ins are removed rather than just shadowed by an appended 127.0.0.1:11434 line.

Related Issue

Fixes #3695
Fixes #3342

Changes

  • New containerCanReachHostLoopback(runtime, opts) predicate in src/lib/platform.ts. Returns true only when WSL detection is positive and docker info reports docker-desktop (the only topology where container-to-host loopback works without a proxy).
  • src/lib/onboard.ts: replace the four isWsl() gates in the plain-Ollama and install-ollama branches with containerCanReachHostLoopback(getContainerRuntime()). The manual OLLAMA_HOST=127.0.0.1:<port> fallback launch is now unconditional (loopback is the right policy everywhere); the auth proxy starts in every topology except Docker Desktop on WSL.
  • src/lib/onboard/ollama-systemd.ts:
    • Drop the WSL bail-out in ensureOllamaLoopbackSystemdOverride. The function now also runs on WSL systemd-backed Ollama (Win11 22H2+ enables systemd in WSL by default).
    • Harden mergeOllamaLoopbackSystemdOverride to strip any existing non-comment OLLAMA_HOST= line in [Service] before re-appending the loopback line. systemd's "last value wins" rule for repeated Environment= would usually pick the appended override, but legacy 0.0.0.0 drop-ins from older NemoClaw versions occasionally survived the restart on some hosts. Removing the stale line keeps the policy unambiguous and addresses [DGX Spark][Onboard] Re-onboard does not repair legacy 0.0.0.0 Ollama systemd override to loopback-only #3342 even on the resume / non-interactive fast-paths that skip setupNim.
  • Tests:
    • test/platform.test.ts covers all four (isWsl × runtime) cells plus non-Docker runtimes.
    • test/onboard-selection.test.ts fixture had a String.raw escape bug (join("\\n") produced literal backslash-n instead of newlines) that silently masked the merge behaviour for the past few releases. Fixture corrected; the assertion now requires the legacy OLLAMA_HOST=0.0.0.0:11434 to be removed, with adjacent settings (OLLAMA_MODELS, HTTPS_PROXY) preserved.

Type of Change

  • 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
  • npm test passes
  • Tests added or updated for new or changed behavior
  • 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 (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Tinson Lai tinsonl@nvidia.com

Summary by CodeRabbit

  • Bug Fixes

    • Improved loopback handling: local service now binds to 127.0.0.1 and onboarding repairs legacy loopback overrides on Linux (including WSL). Installer/start paths reset managed systemd launches to the loopback binding.
  • New Features

    • Runtime-aware decision to front the local service with a token-gated reverse proxy when containers can’t reach host loopback.
    • Dynamic selection of the container-facing port based on actual reachability; proxy port surfaced in success logs when used.
  • Documentation

    • Clarified proxy behavior and WSL/Docker Desktop distinctions.
  • Tests

    • Updated/added tests for port selection, proxy lifecycle, and loopback repair.

Review Change Stack

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 0c4e03dd-01e8-4d8b-bed7-1e72a2aa379c

📥 Commits

Reviewing files that changed from the base of the PR and between 1e665ab and 04bd603.

📒 Files selected for processing (1)
  • test/onboard.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/onboard.test.ts

📝 Walkthrough

Walkthrough

Detects whether sandbox containers can reach host loopback, centralizes topology decisions, chooses Ollama container ports and proxy gating by capability, always binds Ollama to 127.0.0.1 on start, and repairs systemd loopback overrides on Linux.

Changes

Ollama Loopback Networking

Layer / File(s) Summary
Container loopback reachability detection
src/lib/platform.ts, test/platform.test.ts, docs/inference/use-local-inference.md
Adds containerCanReachHostLoopback(runtime, opts) (true only for Docker Desktop on WSL); tests verify behavior across runtimes/WSL states; docs clarify proxy startup conditions.
Local inference topology helpers
src/lib/onboard/local-inference-topology.ts, src/lib/onboard.ts
New getContainerRuntime(), shouldFrontOllamaWithProxy(), and repairLocalInferenceSystemdOverrideOrExit() centralize runtime detection, proxy gating, and systemd-repair-on-resume.
Dynamic Ollama container port & tests
src/lib/inference/local.ts, src/lib/inference/local.test.ts, test/*
Replaces static OLLAMA_CONTAINER_PORT with memoized getOllamaContainerPort() and resetOllamaContainerPortCache(); updates URL construction, reachability probes, diagnostics, and tests to use the dynamic port.
Onboard: Ollama startup and proxy gating
src/lib/onboard.ts
Always starts Ollama with OLLAMA_HOST=127.0.0.1:${OLLAMA_PORT}; decides whether to start the authenticated proxy via shouldFrontOllamaWithProxy(); invokes systemd override repair when resuming onboarding.
Systemd loopback override management & tests
src/lib/onboard/ollama-systemd.ts, test/onboard-selection.test.ts
ensureOllamaLoopbackSystemdOverride() now applies on all Linux; mergeOllamaLoopbackSystemdOverride() removes legacy non-comment OLLAMA_HOST entries and enforces a single loopback Environment= assignment; tests adjusted for newline handling and repaired assertions.

Sequence Diagram

sequenceDiagram
  participant Onboard as Onboard
  participant Topology as local_inference_topology
  participant Platform as platform.containerCanReachHostLoopback
  participant Systemd as ensure/mergeOllamaLoopbackSystemdOverride
  participant OllamaDaemon as OllamaService
  participant AuthProxy as AuthenticatedProxy

  Onboard->>Topology: getContainerRuntime()
  Topology->>Platform: containerCanReachHostLoopback(runtime, opts)
  Platform-->>Topology: canReachLoopback (bool)
  Topology-->>Onboard: shouldFrontOllamaWithProxy()
  Onboard->>Systemd: repairLocalInferenceSystemdOverrideOrExit(provider)
  Systemd-->>OllamaDaemon: ensure loopback binding and restart
  Onboard->>OllamaDaemon: start `ollama serve` with OLLAMA_HOST=127.0.0.1:PORT
  Onboard->>AuthProxy: start/configure (only if shouldFrontOllamaWithProxy() == true)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

Local Models, Provider: Ollama, Docker, Sandbox

Suggested reviewers

  • ericksoa
  • cv
  • prekshivyas

"I sniff the loopback, hop through ports with glee,
If containers can't reach, I front a proxy key.
I patch systemd, bind Ollama tight,
I mock the tests and set them right.
— 🐇"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: enabling Ollama auth proxy fronting for WSL native Docker setups, moving beyond the Docker Desktop assumption.
Linked Issues check ✅ Passed All coding objectives from issue #3695 and #3342 are met: containerCanReachHostLoopback() detects Docker Desktop on WSL, auth proxy fronting gates on this predicate, systemd override handling applies unconditionally to WSL, and legacy 0.0.0.0 overrides are repaired on re-onboard.
Out of Scope Changes check ✅ Passed All changes directly address the linked issues: platform detection, systemd override handling, proxy fronting logic, and re-onboard repair flow. No unrelated refactoring or scope creep detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/ollama-wsl-host-binding

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Comment @coderabbitai help to get the list of available commands and usage tips.

@laitingsheng laitingsheng marked this pull request as draft May 18, 2026 14:32
@copy-pr-bot

copy-pr-bot Bot commented May 18, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@github-actions

github-actions Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: ollama-proxy-e2e, gpu-e2e, gpu-double-onboard-e2e, wsl-e2e
Optional E2E: onboard-resume-e2e, inference-routing-e2e, macos-e2e

Dispatch hint: gpu-e2e,gpu-double-onboard-e2e,onboard-resume-e2e,inference-routing-e2e

Auto-dispatched E2E: gpu-e2e, gpu-double-onboard-e2e via nightly-e2e.yaml at 04bd6034df9e658449af85ef0209302ddf227b40nightly run

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • ollama-proxy-e2e (medium): Directly validates the real Ollama auth proxy security boundary: localhost-only Ollama, proxy token enforcement, token persistence/recovery, inference through the proxy, and container reachability to the proxy rather than raw Ollama.
  • gpu-e2e (high): Exercises the real user flow changed by this PR: install/onboard with NEMOCLAW_PROVIDER=ollama, start or install Ollama, apply loopback/proxy topology, create sandbox, and verify local Ollama inference through the sandbox.
  • gpu-double-onboard-e2e (high): Covers repeated Ollama onboarding with the auth proxy and persisted token after topology changes. This is high-signal for regressions in proxy startup/reuse and local Ollama route consistency across re-onboard.
  • wsl-e2e (high): The PR changes WSL/container-runtime detection and WSL handling for local inference topology. Existing WSL E2E should run to catch platform regressions in WSL install/onboard/sandbox behavior, even though it does not fully cover local Ollama.

Optional E2E

  • onboard-resume-e2e (medium): Useful adjacent coverage because onboard resume now calls the new local-inference systemd repair hook. The existing test uses cloud inference, so it mainly verifies no resume regression outside the Ollama branch.
  • inference-routing-e2e (medium): Provides additional confidence that inference.local routing and provider configuration still work after changes in local provider URL construction, though it does not specifically exercise Ollama topology.
  • macos-e2e (medium): macOS remains on the proxy-required side of the new topology decision. Existing macOS E2E is mostly build/cloud-onboard coverage, so it is useful but not targeted local-Ollama coverage.

New E2E recommendations

  • wsl-local-ollama-topology (high): Existing WSL E2E does not exercise NEMOCLAW_PROVIDER=ollama. Add scenario coverage that runs local Ollama onboarding inside WSL with native Docker-in-WSL and verifies the auth proxy is used and reachable from the sandbox.
    • Suggested test: Add a wsl-repo-local-ollama-openclaw scenario or workflow job that runs nemoclaw onboard with NEMOCLAW_PROVIDER=ollama under native Docker in WSL and validates inference-local /api/tags through the proxy.
  • docker-desktop-wsl-direct-loopback (medium): The new decision allows direct Ollama port 11434 only for Docker Desktop on WSL. There is no existing E2E that proves this exception continues to work or avoids starting an unnecessary proxy.
    • Suggested test: Add WSL Docker Desktop local-Ollama E2E coverage that asserts getLocalProviderBaseUrl uses port 11434 and sandbox inference succeeds without the auth proxy path.
  • ollama-systemd-resume-repair (high): The code repairs legacy 0.0.0.0 Ollama systemd drop-ins during ollama-local resume, but existing resume E2E uses cloud inference and does not cover this security repair path.
    • Suggested test: Add an ollama-local resume E2E that seeds a legacy systemd override with OLLAMA_HOST=0.0.0.0:11434, resumes onboarding, and verifies the override is rewritten to 127.0.0.1 with sandbox inference still working.

Dispatch hint

  • Workflow: .github/workflows/nightly-e2e.yaml
  • jobs input: gpu-e2e,gpu-double-onboard-e2e,onboard-resume-e2e,inference-routing-e2e

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ⚠️ No requested jobs ran

Run: 26040074432
Target ref: d1d2939ec1017ab3a5d696f497148d28b1ac05a4
Workflow ref: main
Requested jobs: gpu-e2e,gpu-double-onboard-e2e
Summary: 0 passed, 0 failed, 2 skipped

Job Result
gpu-double-onboard-e2e ⏭️ skipped
gpu-e2e ⏭️ skipped

@laitingsheng laitingsheng added fix and removed v0.0.45 labels May 18, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/onboard.ts`:
- Around line 7017-7020: The setupInference flow still gates proxy credential
wiring on isWsl(), causing credentials to be set incorrectly when proxy startup
moved to reachability-based logic; update setupInference to use the same
reachability check (containerCanReachHostLoopback(getContainerRuntime()))
instead of isWsl() when deciding whether to wire proxy tokens/credentials for
the provider (the proxy-token wiring logic inside setupInference should follow
the reachability gate used where proxy startup is decided, not the old isWsl()
gate). Ensure references to containerCanReachHostLoopback, getContainerRuntime,
setupInference, and any existing proxy token/credential variables are updated so
the provider receives proxy credentials whenever the reachability check
indicates the proxy will be used.
- Around line 7003-7006: Two identical explanatory comment blocks about the
Ollama loopback / Docker Desktop-on-WSL behavior are duplicated and inflate the
onboard entrypoint file; collapse them into a single short comment mentioning
that Ollama is loopback-only and reachable via the authenticated proxy on
OLLAMA_PROXY_PORT except for Docker Desktop on WSL, remove the duplicated
paragraph at the second occurrence (the other similar block around the later
Ollama proxy usage), and leave all surrounding code and behavior (proxy ports
and authentication) unchanged.
🪄 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: 2ec86a76-f847-4be8-950d-d176a2898416

📥 Commits

Reviewing files that changed from the base of the PR and between d7bae57 and d1d2939.

📒 Files selected for processing (5)
  • src/lib/onboard.ts
  • src/lib/onboard/ollama-systemd.ts
  • src/lib/platform.ts
  • test/onboard-selection.test.ts
  • test/platform.test.ts

Comment thread src/lib/onboard.ts Outdated
Comment thread src/lib/onboard.ts Outdated
Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Docs preview ready!

https://NVIDIA.github.io/NemoClaw/pr-preview/pr-3732/

@laitingsheng laitingsheng marked this pull request as ready for review May 18, 2026 15:51

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/lib/onboard.ts (1)

7606-7606: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use the same reachability gate for the fallback proxy recovery.

This hunk switches credential wiring to shouldFrontOllamaWithProxy(), but Lines 7578-7581 still decide whether to start the recovery proxy with !isWsl(). On native dockerd-on-WSL, that means validation can fail and exit before the proxy is ever started, even though this branch now expects the proxy path.

Suggested fix
-      if (!isWsl()) {
+      if (shouldFrontOllamaWithProxy()) {
         ensureOllamaAuthProxy();
         proxyReady = isProxyHealthy();
       }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/onboard.ts` at line 7606, The reachability gate for starting the
fallback recovery proxy must match the new credential branch: replace the legacy
check that uses !isWsl() (the condition that decides whether to start/skip the
recovery proxy and whether to run validation) with shouldFrontOllamaWithProxy()
so the code that starts the recovery proxy and the validation path use the same
predicate; update the logic around the recovery proxy startup and any early-exit
validation that currently runs under !isWsl() to instead use
shouldFrontOllamaWithProxy() (referencing the existing
shouldFrontOllamaWithProxy() call and the recovery proxy start/validation code
paths) so validation won’t fail/exit before the proxy is started.
🧹 Nitpick comments (1)
docs/inference/use-local-inference.md (1)

99-99: ⚡ Quick win

Remove unnecessary bold (LLM pattern detected).

The bold on **not** is emphatic emphasis rather than a UI label, parameter name, or genuine warning. This is a common LLM-generated pattern that should be avoided.

Suggested fix
-**Native Docker installed inside a WSL distro** (the more common WSL2 setup with `docker-ce`) does **not** see the host's loopback from its bridge network, so the proxy runs there too.
+Native Docker installed inside a WSL distro (the more common WSL2 setup with `docker-ce`) does not see the host's loopback from its bridge network, so the proxy runs there too.

As per coding guidelines: Bold is reserved for UI labels, parameter names, and genuine warnings.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/inference/use-local-inference.md` at line 99, In the sentence containing
"Native Docker installed inside a WSL distro (the more common WSL2 setup with
`docker-ce`) does **not** see the host's loopback from its bridge network, so
the proxy runs there too.", remove the unnecessary bold markup around "not" so
it reads "...does not see the host's loopback...", preserving the inline code
span for `docker-ce` and leaving the rest of the sentence unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/inference/use-local-inference.md`:
- Line 98: The sentence "The proxy is skipped only when Docker Desktop on WSL
bridges the host's loopback into containers via `host.docker.internal`" uses
passive voice; change it to active voice by naming the actor (e.g., "NemoClaw
skips the proxy only when Docker Desktop on WSL bridges the host's loopback into
containers via `host.docker.internal`, because raw Ollama on `127.0.0.1:11434`
is directly reachable and the auth proxy adds no value.") Replace the passive
sentence in use-local-inference.md with a similar active-voice construction that
identifies the actor (NemoClaw or the application) and preserves the existing
technical details.

In `@src/lib/onboard.ts`:
- Around line 9765-9771: The resume fast-path currently calls
ensureOllamaLoopbackSystemdOverride({ isNonInteractive }) for provider ===
"ollama-local" but ignores a failure result; update the block to check the
return value and abort the resume when ensureOllamaLoopbackSystemdOverride
returns "failed" (match the fatal behavior used in the other Ollama paths) by
propagating the error/returning failure or throwing so re-onboard stops if the
loopback repair did not succeed.

---

Duplicate comments:
In `@src/lib/onboard.ts`:
- Line 7606: The reachability gate for starting the fallback recovery proxy must
match the new credential branch: replace the legacy check that uses !isWsl()
(the condition that decides whether to start/skip the recovery proxy and whether
to run validation) with shouldFrontOllamaWithProxy() so the code that starts the
recovery proxy and the validation path use the same predicate; update the logic
around the recovery proxy startup and any early-exit validation that currently
runs under !isWsl() to instead use shouldFrontOllamaWithProxy() (referencing the
existing shouldFrontOllamaWithProxy() call and the recovery proxy
start/validation code paths) so validation won’t fail/exit before the proxy is
started.

---

Nitpick comments:
In `@docs/inference/use-local-inference.md`:
- Line 99: In the sentence containing "Native Docker installed inside a WSL
distro (the more common WSL2 setup with `docker-ce`) does **not** see the host's
loopback from its bridge network, so the proxy runs there too.", remove the
unnecessary bold markup around "not" so it reads "...does not see the host's
loopback...", preserving the inline code span for `docker-ce` and leaving the
rest of the sentence unchanged.
🪄 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: cb8b00e8-7933-4c46-9b55-21b78e2a5433

📥 Commits

Reviewing files that changed from the base of the PR and between d1d2939 and 2606fb7.

📒 Files selected for processing (6)
  • docs/inference/use-local-inference.md
  • src/lib/inference/local.test.ts
  • src/lib/inference/local.ts
  • src/lib/onboard.ts
  • src/lib/onboard/local-inference-topology.ts
  • src/lib/onboard/ollama-systemd.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/onboard/ollama-systemd.ts

Comment thread docs/inference/use-local-inference.md Outdated
Comment thread src/lib/onboard.ts Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26044567282
Target ref: 2606fb72dba67c3da0930b567bc896fd34a1a815
Workflow ref: main
Requested jobs: gpu-e2e,gpu-double-onboard-e2e,onboard-resume-e2e
Summary: 1 passed, 0 failed, 2 skipped

Job Result
gpu-double-onboard-e2e ⏭️ skipped
gpu-e2e ⏭️ skipped
onboard-resume-e2e ✅ success

…doc to active voice

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/lib/onboard.ts (1)

7609-7623: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use the same reachability gate for proxy recovery and token wiring.

Line 7609 now keys proxy credentials off shouldFrontOllamaWithProxy(), but Line 7581 still only probes/starts the proxy behind !isWsl(). On native dockerd-in-WSL that leaves the recovery path on the old heuristic, so local validation can fail and abort before the proxy path is ever considered.

Suggested fix
   if (!validation.ok) {
     // The container reachability check uses Docker's --add-host host-gateway,
     // which may not work on all Docker configurations (e.g., Brev, rootless).
     // The real sandbox uses k3s CoreDNS + NodeHosts — a different path.
     // Try to start/restart the auth proxy before probing — this recovers
     // from stale or missing proxy processes before we decide to abort.
-    if (!isWsl()) {
+    if (shouldFrontOllamaWithProxy()) {
       ensureOllamaAuthProxy();
       proxyReady = isProxyHealthy();
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/onboard.ts` around lines 7609 - 7623, The proxy recovery probe is
gated by the old isWsl() heuristic while token wiring uses
shouldFrontOllamaWithProxy(), causing mismatched behavior; change the
recovery/start condition to use shouldFrontOllamaWithProxy() so both paths
align: where the code currently checks !isWsl() before calling
ensureOllamaAuthProxy()/probing the proxy (the block that sets proxyReady),
update that condition to shouldFrontOllamaWithProxy(), ensure proxyReady is set
the same way, and keep the later token wiring logic that calls
getOllamaProxyToken(), ensureOllamaAuthProxy(), and persistAndProbeOllamaProxy()
unchanged so both recovery and token wiring use the same reachability gate.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@src/lib/onboard.ts`:
- Around line 7609-7623: The proxy recovery probe is gated by the old isWsl()
heuristic while token wiring uses shouldFrontOllamaWithProxy(), causing
mismatched behavior; change the recovery/start condition to use
shouldFrontOllamaWithProxy() so both paths align: where the code currently
checks !isWsl() before calling ensureOllamaAuthProxy()/probing the proxy (the
block that sets proxyReady), update that condition to
shouldFrontOllamaWithProxy(), ensure proxyReady is set the same way, and keep
the later token wiring logic that calls getOllamaProxyToken(),
ensureOllamaAuthProxy(), and persistAndProbeOllamaProxy() unchanged so both
recovery and token wiring use the same reachability gate.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e9d229bf-d4dc-48a5-a10b-c9de0647da19

📥 Commits

Reviewing files that changed from the base of the PR and between 2606fb7 and 832f53f.

📒 Files selected for processing (3)
  • docs/inference/use-local-inference.md
  • src/lib/onboard.ts
  • src/lib/onboard/local-inference-topology.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/inference/use-local-inference.md

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ⚠️ No requested jobs ran

Run: 26046456468
Target ref: 832f53fe655276ba248bd32c9ff41d8fef53b561
Workflow ref: main
Requested jobs: gpu-e2e,gpu-double-onboard-e2e
Summary: 0 passed, 0 failed, 2 skipped

Job Result
gpu-double-onboard-e2e ⏭️ skipped
gpu-e2e ⏭️ skipped

@ericksoa ericksoa added v0.0.46 Release target and removed v0.0.45 labels May 18, 2026
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ⚠️ No requested jobs ran

Run: 26071976537
Target ref: c15a5e3808bf74e501522b7482c58f78f274d2df
Workflow ref: main
Requested jobs: gpu-e2e,gpu-double-onboard-e2e
Summary: 0 passed, 0 failed, 2 skipped

Job Result
gpu-double-onboard-e2e ⏭️ skipped
gpu-e2e ⏭️ skipped

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26074876520
Target ref: 08b5fe3aa132c186da20f2ae535a371a90597aa1
Workflow ref: main
Requested jobs: gpu-e2e,gpu-double-onboard-e2e,onboard-resume-e2e
Summary: 1 passed, 0 failed, 2 skipped

Job Result
gpu-double-onboard-e2e ⏭️ skipped
gpu-e2e ⏭️ skipped
onboard-resume-e2e ✅ success

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ⚠️ No requested jobs ran

Run: 26075418483
Target ref: 1e665abc734069de66c99c39e905edb2227be4cf
Workflow ref: main
Requested jobs: gpu-e2e,gpu-double-onboard-e2e
Summary: 0 passed, 0 failed, 2 skipped

Job Result
gpu-double-onboard-e2e ⏭️ skipped
gpu-e2e ⏭️ skipped

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
test/onboard.test.ts (1)

925-927: ⚡ Quick win

Add an explicit assertion that the proxy token never appears in argv.

This test already validates credential-name wiring, but it should also fail if the literal token is accidentally embedded in the command string.

Suggested test hardening
     assert.match(providerCommand.command, /--credential NEMOCLAW_OLLAMA_PROXY_TOKEN/);
     assert.equal(providerCommand.env?.NEMOCLAW_OLLAMA_PROXY_TOKEN, "proxy-token");
+    assert.doesNotMatch(providerCommand.command, /proxy-token/);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/onboard.test.ts` around lines 925 - 927, Add an assertion ensuring the
literal proxy token never appears in the generated command argv; specifically,
after the existing checks on providerCommand.command and providerCommand.env
(references: providerCommand.command and providerCommand.env), add a negative
assertion that providerCommand.command (or providerCommand.argv if present) does
not include the string "proxy-token" (e.g., assert.doesNotMatch or
assert.ok(!...includes("proxy-token"))), so the test fails if the secret token
is accidentally embedded into the command line.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/onboard.test.ts`:
- Around line 925-927: Add an assertion ensuring the literal proxy token never
appears in the generated command argv; specifically, after the existing checks
on providerCommand.command and providerCommand.env (references:
providerCommand.command and providerCommand.env), add a negative assertion that
providerCommand.command (or providerCommand.argv if present) does not include
the string "proxy-token" (e.g., assert.doesNotMatch or
assert.ok(!...includes("proxy-token"))), so the test fails if the secret token
is accidentally embedded into the command line.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 1c29666b-ed56-4e04-8663-a2947b1e0070

📥 Commits

Reviewing files that changed from the base of the PR and between c15a5e3 and 1e665ab.

📒 Files selected for processing (2)
  • src/lib/onboard.ts
  • test/onboard.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/onboard.ts

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ⚠️ No requested jobs ran

Run: 26075804049
Target ref: 04bd6034df9e658449af85ef0209302ddf227b40
Workflow ref: main
Requested jobs: gpu-e2e,gpu-double-onboard-e2e
Summary: 0 passed, 0 failed, 2 skipped

Job Result
gpu-double-onboard-e2e ⏭️ skipped
gpu-e2e ⏭️ skipped

@ericksoa ericksoa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved after adversarial review and follow-up fixes. The WSL native Docker Ollama proxy recovery path now uses the same topology predicate as token wiring, and the regression test covers proxy recovery without leaking the proxy token into argv. CI and CodeRabbit are green on head 04bd603.

@ericksoa ericksoa merged commit 9418d49 into main May 19, 2026
30 checks passed
@miyoungc miyoungc mentioned this pull request May 20, 2026
12 tasks
miyoungc added a commit that referenced this pull request May 20, 2026
## Summary
Refreshes the NemoClaw docs for v0.0.46 by updating version metadata,
release notes, and generated user skills. The refresh also keeps public
docs aligned with the docs skip list by removing non-public experimental
references from the generated output.

## Related Issue
None.

## Changes
- #3744 and #3824 -> `docs/about/release-notes.mdx`: Added Windows
bootstrap and WSL express install coverage for v0.0.46.
- #3392 -> `docs/manage-sandboxes/messaging-channels.mdx`,
`docs/reference/commands.mdx`, `docs/reference/network-policies.mdx`,
and policy examples: Refreshed public messaging channel docs around
WhatsApp and matching policy presets.
- #3742, #3767, #3732, #3786, #3777, and #3808 ->
`docs/about/release-notes.mdx`: Added release-note coverage for Hermes
managed tools, Bedrock Runtime endpoint detection, WSL Ollama proxying,
Model Router Python fallback, plugin command registration, and
tool-catalog latency improvements.
- #3124 -> `docs/about/release-notes.mdx`: Added release-note coverage
for hosted uninstall flag guidance.
- Generated `nemoclaw-user-*` skills from the updated MDX docs for the
v0.0.46 release.

## 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
- [ ] `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
- [ ] `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)

Verification notes:
- Commit hooks passed, including markdownlint, gitleaks, docs-to-skills
verification, env-var docs, and skills YAML checks.
- `python3 scripts/docs-to-skills.py docs/ .agents/skills/ --prefix
nemoclaw-user --doc-platform fern-mdx` passed.
- `bash test/e2e/e2e-cloud-experimental/check-docs.sh --only-links
--local-only --with-skills` passed.
- `git diff --check` passed.
- `make docs` was attempted but blocked before MDX validation because
`npx` received HTTP 403 fetching `fern-api` from npm.

---
Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Released v0.0.46: improved Windows setup, WhatsApp messaging support,
Hermes sandbox/tool routing, Anthropic endpoint compatibility, Ollama
proxy routing, model-router fallback, OpenClaw plugin/backup
compatibility, sandbox build tooling fixes, and updated uninstall flag
behavior.

* **Documentation**
* Removed WeChat from messaging flows and presets across guides and CLI
docs; clarified onboarding and channel setup for WhatsApp. Clarified
runtime mutability and filesystem (Landlock) behavior — some changes
require sandbox rebuilds; prefer host-side commands for durable config.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/NVIDIA/NemoClaw/pull/3911?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@wscurran wscurran added bug-fix PR fixes a bug or regression and removed fix labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug-fix PR fixes a bug or regression v0.0.46 Release target

Projects

None yet

3 participants