Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,46 @@ When you select it, NemoClaw starts the router proxy on the host, waits for its
The sandbox does not call the router port directly.

The router model pool lives in `nemoclaw-blueprint/router/pool-config.yaml`.
Edit that file to define which models the router can choose from.
The default pool routes between NVIDIA-hosted Nemotron models and uses the `tolerance` value to choose the lowest-cost model whose predicted quality stays within the configured threshold.

```yaml
routing:
method: prefill
checkpoint: llm-router/checkpoints/prefill_router_qwen08b.pt
tolerance: 0.20
encoder: Qwen/Qwen3.5-0.8B

models:
- name: nano
litellm_model: "openai/nvidia/nvidia/Nemotron-3-Nano-30B-A3B"
cost_per_m_input_tokens: 0.05
api_base: "https://inference-api.nvidia.com"

- name: super
litellm_model: "openai/nvidia/nvidia/nemotron-3-super-v3"
cost_per_m_input_tokens: 0.10
api_base: "https://inference-api.nvidia.com"
Comment on lines +91 to +96

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

For NVIDIA-hosted NemoClaw/OpenAI-compatible inference, what is the correct base URL to configure in router/provider examples: https://integrate.api.nvidia.com/v1 or https://inference-api.nvidia.com ?

💡 Result:

Correct base URL for NVIDIA-hosted NemoClaw/OpenAI-compatible inference: https://integrate.api.nvidia.com/v1. NVIDIA’s NemoClaw inference documentation states that for hosted models on integrate.api.nvidia.com, NemoClaw sets the base URL to https://integrate.api.nvidia.com/v1 (and the APIs are OpenAI-compatible under the /v1/chat/completions route). [1][2] The alternative base URL you mentioned (https://inference-api.nvidia.com) is not what NemoClaw’s official docs specify for hosted NVIDIA inference. [1][2]

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE=".agents/skills/nemoclaw-user-configure-inference/references/inference-options.md"

# Show the NVIDIA endpoint documentation section (around the cited Line 62)
echo "---- around line 55-70 ----"
nl -ba "$FILE" | sed -n '55,75p'

echo "---- around line 85-105 ----"
nl -ba "$FILE" | sed -n '85,105p'

Repository: NVIDIA/NemoClaw

Length of output: 148


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE=".agents/skills/nemoclaw-user-configure-inference/references/inference-options.md"

echo "---- around line 55-75 ----"
cat -n "$FILE" | sed -n '55,75p'

echo "---- around line 85-105 ----"
cat -n "$FILE" | sed -n '85,105p'

Repository: NVIDIA/NemoClaw

Length of output: 3001


Fix api_base mismatch in Model Router example (NVIDIA-hosted endpoints)

The doc states NVIDIA-hosted endpoints use https://integrate.api.nvidia.com/v1 (Line 62), but the router example uses https://inference-api.nvidia.com for both nano and super (Lines 91-96), which will break copy/paste setup.

Proposed doc fix
 models:
   - name: nano
     litellm_model: "openai/nvidia/nvidia/Nemotron-3-Nano-30B-A3B"
     cost_per_m_input_tokens: 0.05
-    api_base: "https://inference-api.nvidia.com"
+    api_base: "https://integrate.api.nvidia.com/v1"

   - name: super
     litellm_model: "openai/nvidia/nvidia/nemotron-3-super-v3"
     cost_per_m_input_tokens: 0.10
-    api_base: "https://inference-api.nvidia.com"
+    api_base: "https://integrate.api.nvidia.com/v1"
🤖 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
@.agents/skills/nemoclaw-user-configure-inference/references/inference-options.md
around lines 91 - 96, The example model router entries for models named "nano"
and "super" have an incorrect api_base ("https://inference-api.nvidia.com");
update their api_base values to match the documented NVIDIA-hosted endpoint
"https://integrate.api.nvidia.com/v1" so copied router configs use the correct
NVIDIA inference URL; locate the entries by the litellm_model names
"openai/nvidia/nvidia/nemotron-3-nano-v3" and
"openai/nvidia/nvidia/nemotron-3-super-v3" and replace the api_base fields
accordingly.

```

The `tolerance` parameter controls the accuracy-cost tradeoff.

| Value | Behavior |
|-------|----------|
| `0.0` | Always pick the most accurate model. |
| `0.20` | Allow up to 20 percentage points below the best for a cheaper model (default). |
| `1.0` | Always pick the cheapest model. |

The router runs on the host, not inside the sandbox.

```text
Sandbox (agent) ──> OpenShell Gateway (L7 proxy) ──> Model Router (:4000) ──> NVIDIA API
└── PrefillRouter selects model
```

Credentials flow through the OpenShell provider system.
The sandbox never sees raw API keys.

To use the router in scripted setup, set:

```console
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,15 @@ For sensitive workloads, use a reviewed host-side immutability workflow after in

- **DAC permissions (default).** The sandbox user owns `/sandbox/.openclaw` with mode `2770` (setgid `sandbox:sandbox`) and `openclaw.json` with mode `660`, so the agent and its group can read and write config directly. A reviewed host-side immutability workflow should compare the intended ownership and mode with the live sandbox filesystem before treating the config tree as locked.
- **Config integrity hash.** The image includes a SHA256 hash of `openclaw.json`. In the default mutable state, `.config-hash` is sandbox-owned and is not a tamper-proof trust anchor, so startup does not fail closed on that hash. When the hash is root-owned and read-only, startup enforces it and refuses to start if the hash does not match.
- **Content seal under shields up.**
When `nemoclaw <name> shields up` runs against a clean lock, it captures a SHA-256 seal of `openclaw.json` and any other locked files into the host-side shields state file.
On sealed sandboxes, every `shields status` call recomputes the hash inside the sandbox and surfaces drift on any mismatch, so a host-root tamper that flips perms back to `444 root:root` after rewriting the file is still flagged.
Sandboxes locked before this seal landed have no recorded hash; perm-only verification cannot prove their bytes match the image-original, so the seal is **not** a retroactive proof of integrity for legacy state.
The same refusal applies to partial seals where the locked file set grew after the existing seal was captured (some entries sealed, some missing).
By default, `shields up` refuses to seal in either case and asks you to rebuild the sandbox first for a known-good baseline.
`shields status` on a legacy lockdown surfaces `UP (UNSEALED — content integrity unknown for legacy lockdown)` and exits with status 2 so scripts treat it as a failure until the operator seals an explicit baseline.
If you explicitly trust the current bytes, opt in via `NEMOCLAW_SHIELDS_ACCEPT_LEGACY_BASELINE=1`, which captures a seal over the current files and is acknowledged in the log line.
Once a sandbox is sealed, `shields up` refuses to re-seal a tampered baseline; restore the original file or rebuild the sandbox before re-running.
- **Gateway token environment.** The gateway exports `OPENCLAW_GATEWAY_TOKEN` and writes it to `/tmp/nemoclaw-proxy-env.sh` for interactive sandbox sessions. Keep this in mind when deciding whether a workload should run with mutable config or an immutable config posture.

| Aspect | Detail |
Expand Down
1 change: 1 addition & 0 deletions .agents/skills/nemoclaw-user-get-started/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ $ curl -fsSL https://www.nvidia.com/nemoclaw.sh | bash
On DGX Spark, DGX Station, and Windows WSL, an interactive installer offers express install after you accept the third-party software notice.
Express install switches onboarding to non-interactive mode, allows `sudo` password prompts for required host changes, and selects the managed local inference path for that platform.
Unless `NEMOCLAW_POLICY_TIER` is set, it applies sandbox policy in `suggested` mode with the `balanced` tier by default, using the base sandbox policy plus supported package, model, web-search, and local-inference presets.
On DGX Spark, express install uses `my-spark-assistant` as the sandbox name unless `NEMOCLAW_SANDBOX_NAME` is already set.
On WSL, express install selects the Windows-host Ollama setup path.
Set `NEMOCLAW_NO_EXPRESS=1` to skip the express prompt, or set `NEMOCLAW_PROVIDER` before launching the installer when you want to choose a provider yourself.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@
Use NemoHermes when you want NemoClaw to create an OpenShell sandbox that runs Hermes instead of the default OpenClaw agent.
The `nemohermes` command is an alias for `nemoclaw` with the Hermes agent pre-selected.

**Experimental Feature:**

The Hermes agent option is experimental.
Interfaces, defaults, and supported features may change without notice, and it is not recommended for production use.

Review the [Prerequisites](prerequisites.md) before starting.
Docker must be installed, running, and reachable from the current shell before Hermes onboarding can build the sandbox image.
On Linux, the installer can install Docker, start the service, and add your user to the `docker` group.
Expand Down
57 changes: 56 additions & 1 deletion .agents/skills/nemoclaw-user-manage-sandboxes/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ Check a specific sandbox's health, inference route, active connections, live pol
$ nemoclaw my-assistant status
```

Run the per-sandbox doctor when you need a readiness gate for automation or a deeper diagnostic bundle for one sandbox:

```console
$ nemoclaw my-assistant doctor
$ nemoclaw my-assistant doctor --json
```

`doctor` checks the host, gateway, sandbox, inference route, messaging channels, and local services.
Failed checks exit non-zero.

Use the host-level status command when you want the sandbox inventory plus host auxiliary service state, such as cloudflared:

```console
Expand All @@ -56,8 +66,27 @@ Stream logs while you reproduce a problem:
$ nemoclaw my-assistant logs --follow
```

Limit the history window with `--tail` (or `-n`) and `--since`:

```console
$ nemoclaw my-assistant logs --tail 100
$ nemoclaw my-assistant logs --since 10m
```

The log command reads both OpenClaw gateway output and OpenShell audit events, so policy denials appear beside gateway logs.

## Retrieve Gateway Token

Print the OpenClaw gateway auth token when an in-container client or debug script needs to call the gateway directly:

```console
$ nemoclaw my-assistant gateway-token
$ TOKEN=$(nemoclaw my-assistant gateway-token --quiet)
```

Use `--quiet` when the command is part of shell substitution and you want only the token on stdout.
Treat the token as a secret.

## Collect Diagnostics

Collect diagnostics for bug reports or support handoff:
Expand All @@ -73,6 +102,7 @@ $ nemoclaw debug --quick --sandbox my-assistant
```

The debug command gathers system information, Docker state, gateway logs, and sandbox status.
The debug command auto-redacts known secrets before writing files, but review the tarball before sharing it outside your trusted support path.

## Manage Dashboard Ports

Expand Down Expand Up @@ -116,15 +146,20 @@ For full details on port conflicts and overrides, refer to Port already in use (
## Reconfigure or Recover

Recover from a misconfigured sandbox without re-running the full onboard wizard or destroying workspace state.
Use `recover` when the sandbox container is still healthy but gateway or dashboard forwarding needs repair.
Use `rebuild` when the sandbox image, agent runtime, provider bake-in, or container state needs to be recreated while preserving workspace state.

### Change Inference Model or API

Change the active model or provider at runtime without rebuilding the sandbox:

```console
$ nemoclaw inference get
$ nemoclaw inference get --json
$ nemoclaw inference set --model <model> --provider <provider>
```

`inference get` is the read-only companion for checking the current route before you change it.
Refer to Switch Inference Providers (use the `nemoclaw-user-configure-inference` skill) for provider-specific model IDs and API compatibility notes.

### Restart the Gateway and Port Forward
Expand Down Expand Up @@ -187,7 +222,7 @@ Re-run the installer.
Before it onboards anything, the installer calls `nemoclaw backup-all` (use the `nemoclaw-user-reference` skill) automatically, storing a snapshot of each running sandbox in `~/.nemoclaw/rebuild-backups/` as a safety net.
If your existing gateway is from OpenShell earlier than `0.0.37`, the installer prompts before it runs the new automatic gateway upgrade path.
The automatic path is offered only when the existing `nemoclaw` CLI supports `backup-all`; older installs must preserve sandbox state manually before retiring the gateway.
For unattended installs, set `NEMOCLAW_ACCEPT_EXPERIMENTAL_OPENSHELL_UPGRADE=1`, or manually run `nemoclaw backup-all` and `openshell gateway destroy -g nemoclaw || openshell gateway destroy` before rerunning the installer as `curl -fsSL https://www.nvidia.com/nemoclaw.sh | NEMOCLAW_OPENSHELL_UPGRADE_PREPARED=1 bash`.
For unattended installs, set `NEMOCLAW_ACCEPT_EXPERIMENTAL_OPENSHELL_UPGRADE=1`, or manually run `nemoclaw backup-all`, `openshell gateway remove nemoclaw || openshell gateway destroy -g nemoclaw || openshell gateway destroy` (both verbs are tried so the right one runs on either OpenShell release), and `sudo pkill -f openshell-gateway` if a privileged host gateway remains before rerunning the installer as `curl -fsSL https://www.nvidia.com/nemoclaw.sh | NEMOCLAW_OPENSHELL_UPGRADE_PREPARED=1 bash`.

```console
$ curl -fsSL https://www.nvidia.com/nemoclaw.sh | bash
Expand Down Expand Up @@ -243,6 +278,18 @@ Your existing container keeps serving traffic until the new image is ready.

## Uninstall

### Garbage Collect Orphan Images

After destroying or rebuilding older sandboxes, remove Docker images that are no longer referenced by registered sandboxes:

```console
$ nemoclaw gc --dry-run
$ nemoclaw gc --yes
```

Use `--dry-run` first to preview deletions.
Use `--force` only when you intentionally want to remove images referenced by stopped containers.

To remove NemoClaw and all resources created during setup, run the CLI's built-in uninstall command:

```bash
Expand All @@ -255,6 +302,14 @@ nemoclaw uninstall
| `--keep-openshell` | Leave OpenShell binaries installed. |
| `--delete-models` | Also remove NemoClaw-pulled Ollama models. |

**Note:**

`nemoclaw uninstall` preserves `~/.nemoclaw/rebuild-backups/` (host-side snapshots that `nemoclaw <name> snapshot create` and `nemoclaw backup-all` write), `~/.nemoclaw/backups/` (workspace backups that `scripts/backup-workspace.sh` writes), and `~/.nemoclaw/sandboxes.json` (the sandbox registry) by default.
Uninstall removes every other entry under `~/.nemoclaw/`.
Interactive runs prompt before they remove the preserved entries; the default answer keeps them.
For non-interactive runs (`--yes`, `NEMOCLAW_NON_INTERACTIVE=1`, or a non-TTY shell), set `NEMOCLAW_UNINSTALL_DESTROY_USER_DATA=1` to acknowledge data loss and remove the preserved entries as well.
See `nemoclaw uninstall` (use the `nemoclaw-user-reference` skill) for the full preservation contract.

`nemoclaw uninstall` runs the version-pinned `uninstall.sh` that shipped with your installed CLI, so it does not fetch anything over the network at uninstall time.

If the `nemoclaw` CLI is missing or broken, fall back to the hosted script:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ Telegram uses a bot token from [BotFather](https://t.me/BotFather).
Open Telegram, send `/newbot` to [@BotFather](https://t.me/BotFather), follow the prompts, and copy the token.
For Telegram group chats, disable privacy mode before testing group replies: in @BotFather, run `/setprivacy`, choose the bot, then choose **Disable**.
After changing privacy mode, remove the bot from each Telegram group and add it back so Telegram applies the new delivery setting to that group.
`TELEGRAM_ALLOWED_IDS` is a comma-separated list of Telegram user IDs for DM access.
`TELEGRAM_ALLOWED_IDS` is a comma-separated list of Telegram user or private-chat IDs for DM access.
For compatibility with older QA scripts, NemoClaw also treats `TELEGRAM_AUTHORIZED_CHAT_IDS` and `TELEGRAM_CHAT_ID` as aliases, but new automation should use `TELEGRAM_ALLOWED_IDS`.
Keep these aliases until QA automation and public repro templates have stopped exporting them for at least one full release.
Group chats stay open by default so rebuilt sandboxes do not silently drop Telegram group messages because of an empty group allowlist.
Set `TELEGRAM_REQUIRE_MENTION=1` to make the bot reply in Telegram groups only when users mention it.
Pairing and `TELEGRAM_ALLOWED_IDS` still govern direct messages.
Expand Down Expand Up @@ -158,6 +160,8 @@ If applying the preset fails, NemoClaw warns and tells you to re-apply manually
Choose the rebuild so the running sandbox image picks up the new channel.
For Telegram, Discord, and Slack, `channels add` also checks the rebuilt runtime for the selected bridge and reports startup, credential, or missing-plugin warnings before returning.
If you need optional channel settings such as `TELEGRAM_ALLOWED_IDS`, `TELEGRAM_REQUIRE_MENTION`, `DISCORD_SERVER_ID`, `DISCORD_USER_ID`, `DISCORD_REQUIRE_MENTION`, `SLACK_ALLOWED_USERS`, or `SLACK_ALLOWED_CHANNELS`, export them before the rebuild starts.
Telegram Bot API `sendMessage` calls prove outbound delivery from the bot; to test inbound agent replies, send a message from the Telegram client as an allowed user.
For a repeatable live Telegram reply check, run `test/e2e/test-messaging-providers.sh` with `TELEGRAM_BOT_TOKEN_REAL`, `TELEGRAM_AUTHORIZED_CHAT_IDS` or `TELEGRAM_CHAT_ID`, and `NEMOCLAW_TELEGRAM_INBOUND_REPLY_E2E=1`.
If you defer the rebuild, apply the change later:
Comment on lines +164 to 165

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Prefer TELEGRAM_ALLOWED_IDS first in the e2e verification example.

This example currently spotlights legacy variables, which conflicts with the “new automation should use TELEGRAM_ALLOWED_IDS” guidance above. Put TELEGRAM_ALLOWED_IDS first and mention legacy aliases as fallback to keep migration messaging consistent.

Suggested doc tweak
-For a repeatable live Telegram reply check, run `test/e2e/test-messaging-providers.sh` with `TELEGRAM_BOT_TOKEN_REAL`, `TELEGRAM_AUTHORIZED_CHAT_IDS` or `TELEGRAM_CHAT_ID`, and `NEMOCLAW_TELEGRAM_INBOUND_REPLY_E2E=1`.
+For a repeatable live Telegram reply check, run `test/e2e/test-messaging-providers.sh` with `TELEGRAM_BOT_TOKEN_REAL`, `TELEGRAM_ALLOWED_IDS` (preferred; legacy aliases: `TELEGRAM_AUTHORIZED_CHAT_IDS` or `TELEGRAM_CHAT_ID`), and `NEMOCLAW_TELEGRAM_INBOUND_REPLY_E2E=1`.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
For a repeatable live Telegram reply check, run `test/e2e/test-messaging-providers.sh` with `TELEGRAM_BOT_TOKEN_REAL`, `TELEGRAM_AUTHORIZED_CHAT_IDS` or `TELEGRAM_CHAT_ID`, and `NEMOCLAW_TELEGRAM_INBOUND_REPLY_E2E=1`.
If you defer the rebuild, apply the change later:
For a repeatable live Telegram reply check, run `test/e2e/test-messaging-providers.sh` with `TELEGRAM_BOT_TOKEN_REAL`, `TELEGRAM_ALLOWED_IDS` (preferred; legacy aliases: `TELEGRAM_AUTHORIZED_CHAT_IDS` or `TELEGRAM_CHAT_ID`), and `NEMOCLAW_TELEGRAM_INBOUND_REPLY_E2E=1`.
If you defer the rebuild, apply the change later:
🤖 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
@.agents/skills/nemoclaw-user-manage-sandboxes/references/messaging-channels.md
around lines 164 - 165, Update the e2e example invocation in
messaging-channels.md to place TELEGRAM_ALLOWED_IDS first and list
TELEGRAM_AUTHORIZED_CHAT_IDS and TELEGRAM_CHAT_ID as legacy fallbacks;
specifically, modify the example that references
test/e2e/test-messaging-providers.sh and NEMOCLAW_TELEGRAM_INBOUND_REPLY_E2E so
it shows TELEGRAM_ALLOWED_IDS first, then mentions the legacy aliases
(TELEGRAM_AUTHORIZED_CHAT_IDS, TELEGRAM_CHAT_ID) as fallback options for
compatibility.


```console
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,24 @@ The table below maps each commonly changed item to the layer that owns it and th
| Sandbox name | **Locked at creation** | Re-onboard with a different `--name` |
| GPU passthrough enable / device selector | **Locked at creation** | Re-onboard with `--gpu` / `--sandbox-gpu-device` |
| Agents allow-list (`agents.list` in `openclaw.json`) | Runtime — hot-reloaded by OpenClaw on config change | Prefer agent or NemoClaw commands that keep host and sandbox state aligned |
| `/etc/hosts` aliases inside the sandbox | Runtime — updates the sandbox pod template and active hosts file | `nemoclaw <name> hosts-add <hostname> <ip>`, `hosts-list`, and `hosts-remove` |
| `openclaw.json` keys (general — model, agents.list, web.backend, channel config, etc.) | Mixed. Individual keys still follow the rebuild rules in the rows above, such as provider switch requiring rebuild even after editing the JSON. | Prefer NemoClaw host commands so the host registry and rebuilt image stay aligned |

If a row above conflicts with what you observe, the runtime source of truth inside the sandbox is `/opt/nemoclaw/openclaw.json`; the host registry caches metadata but the image and OpenClaw read from the in-sandbox file.

## Override DNS Inside the Sandbox

Use host aliases when a sandbox needs to reach a private hostname that normal DNS cannot resolve:

```console
$ nemoclaw my-assistant hosts-add internal.example.com 10.0.0.42
$ nemoclaw my-assistant hosts-list
$ nemoclaw my-assistant hosts-remove internal.example.com
```

Aliases are useful for private test services, local gateways, and temporary lab names.
Use `hosts-add --dry-run` to validate the entry without changing the sandbox.

## See also

The mutability table above is a consolidated index of information that lives in more detail on per-topic pages:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,20 @@ You can edit them in two ways:
1. Ask your agent to update its persona, memory, or user context.
2. Use `nemoclaw <name> connect` to open a terminal inside the sandbox and edit files directly, or use `openshell sandbox upload` to push edited files from your host.

## Mount Sandbox Files on the Host

For longer editing sessions, mount a sandbox path onto the host with SSHFS and use your local editor:

```console
$ nemoclaw my-assistant share mount /sandbox/.openclaw/workspace ~/my-assistant-workspace
$ nemoclaw my-assistant share status
$ nemoclaw my-assistant share unmount ~/my-assistant-workspace
```

`share mount` defaults to the sandbox workspace when no path is provided.
The mount remains active until you unmount it or destroy the sandbox.
If the command reports that `sshfs` is missing, install it on the host and rerun the mount command.

## Next Steps

- Set Up Task-Specific Sub-Agents (use the `nemoclaw-user-configure-inference` skill)
Expand Down
Loading
Loading