From 4185055cfaf4ed7a37de15712a34752384b80cd0 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Wed, 3 Jun 2026 12:36:37 -0700 Subject: [PATCH 1/6] docs: generate agent variant code samples --- .github/workflows/docs-preview-pr.yaml | 14 +- .gitignore | 1 + docs/CONTRIBUTING.md | 3 + docs/index.yml | 4 +- docs/manage-sandboxes/lifecycle.mdx | 192 ++++--------------------- scripts/docs-to-skills.py | 4 + scripts/sync-agent-variant-docs.ts | 63 +++++++- scripts/watch-fern-preview.ts | 5 +- test/agent-variant-docs.test.ts | 45 ++++++ 9 files changed, 151 insertions(+), 180 deletions(-) create mode 100644 test/agent-variant-docs.test.ts diff --git a/.github/workflows/docs-preview-pr.yaml b/.github/workflows/docs-preview-pr.yaml index df6afe1ba2..853137d2ce 100644 --- a/.github/workflows/docs-preview-pr.yaml +++ b/.github/workflows/docs-preview-pr.yaml @@ -48,14 +48,11 @@ jobs: with: node-version: "24" - - name: Install Fern CLI - run: | - FERN_VERSION=$(node -p "require('./fern/fern.config.json').version") - npm install -g "fern-api@${FERN_VERSION}" + - name: Install docs dependencies + run: npm ci --ignore-scripts - name: Validate docs - working-directory: ./fern - run: fern check + run: npm run docs - name: Generate preview URL if: ${{ steps.fern-preview.outputs.enabled == 'true' }} @@ -63,10 +60,11 @@ jobs: env: FERN_TOKEN: ${{ secrets.FERN_TOKEN }} PREVIEW_ID: pr-${{ github.event.pull_request.number }} - working-directory: ./fern run: | + npm run docs:check-agent-variants + FERN_VERSION=$(node -p "require('./fern/fern.config.json').version") set +e - OUTPUT=$(fern generate --docs --preview --id "$PREVIEW_ID" 2>&1) + OUTPUT=$(cd fern && npx --yes "fern-api@${FERN_VERSION}" generate --docs --preview --id "$PREVIEW_ID" 2>&1) STATUS=$? set -e echo "$OUTPUT" diff --git a/.gitignore b/.gitignore index ddbb67731c..277d0421d8 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ __pycache__/ coverage/ dist/ docs/_build/ +docs/**/*.generated.mdx node_modules/ # OS metadata diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index f6a5673958..175758bc4a 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -261,6 +261,9 @@ These patterns are common in LLM-generated text and erode trust with technical r nemoclaw onboard ``` +- For command examples that differ only by the host CLI binary, write `$$nemoclaw` in the shared source page and let `scripts/sync-agent-variant-docs.ts` render `nemoclaw` or `nemohermes` for Fern. + Use `` blocks only when the surrounding content differs between the OpenClaw and Hermes variants. + - Use `powershell` for Windows PowerShell commands. Use `bash` or `sh` for Linux, macOS, and WSL shell commands. Reserve `console` blocks for terminal transcripts that include prompts, output, or interactive sessions. diff --git a/docs/index.yml b/docs/index.yml index 951fb74ee4..2e50cfa63d 100644 --- a/docs/index.yml +++ b/docs/index.yml @@ -71,7 +71,7 @@ navigation: collapsed: open-by-default contents: - page: "Manage Sandbox Lifecycle" - path: manage-sandboxes/lifecycle.mdx + path: manage-sandboxes/lifecycle.openclaw.generated.mdx slug: lifecycle - page: "Runtime Controls" path: manage-sandboxes/runtime-controls.mdx @@ -222,7 +222,7 @@ navigation: collapsed: open-by-default contents: - page: "Manage Sandbox Lifecycle" - path: manage-sandboxes/lifecycle.mdx + path: manage-sandboxes/lifecycle.hermes.generated.mdx slug: lifecycle - page: "Runtime Controls" path: manage-sandboxes/runtime-controls.mdx diff --git a/docs/manage-sandboxes/lifecycle.mdx b/docs/manage-sandboxes/lifecycle.mdx index 17ba9fd9cc..2f06e47ee4 100644 --- a/docs/manage-sandboxes/lifecycle.mdx +++ b/docs/manage-sandboxes/lifecycle.mdx @@ -31,86 +31,44 @@ When a workflow uses the lower-level OpenShell CLI, see [CLI Selection Guide](.. List every sandbox registered on this host: - -```bash -nemoclaw list -``` - - ```bash -nemohermes list +$$nemoclaw list ``` - The list shows each sandbox's model, provider, policy presets, active SSH session indicator, and dashboard URL when NemoClaw records a dashboard port. Use JSON output for scripts: - ```bash -nemoclaw list --json +$$nemoclaw list --json ``` - - -```bash -nemohermes list --json -``` - ## Check Sandbox Health Check a specific sandbox's health, inference route, active connections, live policy, update status, and messaging-channel overlap warnings: - ```bash -nemoclaw my-assistant status +$$nemoclaw my-assistant status ``` - - -```bash -nemohermes my-assistant status -``` - Use the host-level status command when you want the sandbox inventory plus host auxiliary service state, such as cloudflared: - -```bash -nemoclaw status -``` - - ```bash -nemohermes status +$$nemoclaw status ``` - ## Inspect Logs View recent sandbox logs: - -```bash -nemoclaw my-assistant logs -``` - - ```bash -nemohermes my-assistant logs +$$nemoclaw my-assistant logs ``` - Stream logs while you reproduce a problem: - ```bash -nemoclaw my-assistant logs --follow +$$nemoclaw my-assistant logs --follow ``` - - -```bash -nemohermes my-assistant logs --follow -``` - The log command reads both OpenClaw gateway output and OpenShell audit events, so policy denials appear beside gateway logs. @@ -123,29 +81,15 @@ The log command reads both Hermes gateway output and OpenShell audit events, so Collect diagnostics for bug reports or support handoff: - ```bash -nemoclaw debug --sandbox my-assistant --output nemoclaw-debug.tar.gz +$$nemoclaw debug --sandbox my-assistant --output nemoclaw-debug.tar.gz ``` - - -```bash -nemohermes debug --sandbox my-assistant --output nemoclaw-debug.tar.gz -``` - Use `--quick` for a smaller local summary: - ```bash -nemoclaw debug --quick --sandbox my-assistant +$$nemoclaw debug --quick --sandbox my-assistant ``` - - -```bash -nemohermes debug --quick --sandbox my-assistant -``` - The debug command gathers system information, Docker state, gateway logs, and sandbox status. @@ -175,46 +119,23 @@ When the default API port is already held by another sandbox, `nemohermes onboar If you intentionally run separate OpenShell gateways on the same host, set a different `NEMOCLAW_GATEWAY_PORT` before each onboarding run. NemoClaw isolates the gateway name and local state by port so one port-specific gateway does not replace another. - -```bash -nemoclaw onboard # first sandbox uses 18789 -nemoclaw onboard # second sandbox uses the next free port, such as 18790 -``` - - ```bash -nemohermes onboard # first sandbox uses 18789 -nemohermes onboard # second sandbox uses the next free port, such as 18790 +$$nemoclaw onboard # first sandbox uses 18789 +$$nemoclaw onboard # second sandbox uses the next free port, such as 18790 ``` - To choose a specific port, pass `--control-ui-port`: - -```bash -nemoclaw onboard --control-ui-port 19000 -``` - - ```bash -nemohermes onboard --control-ui-port 19000 +$$nemoclaw onboard --control-ui-port 19000 ``` - You can also set `CHAT_UI_URL` or `NEMOCLAW_DASHBOARD_PORT` before onboarding: - -```bash -CHAT_UI_URL=http://127.0.0.1:19000 nemoclaw onboard -NEMOCLAW_DASHBOARD_PORT=19000 nemoclaw onboard -``` - - ```bash -CHAT_UI_URL=http://127.0.0.1:19000 nemohermes onboard -NEMOCLAW_DASHBOARD_PORT=19000 nemohermes onboard +CHAT_UI_URL=http://127.0.0.1:19000 $$nemoclaw onboard +NEMOCLAW_DASHBOARD_PORT=19000 $$nemoclaw onboard ``` - For full details on port conflicts and overrides, refer to [Port already in use](../reference/troubleshooting#port-already-in-use). @@ -226,16 +147,9 @@ Recover from a misconfigured sandbox without re-running the full onboard wizard Change the active model or provider at runtime without rebuilding the sandbox: - ```bash -nemoclaw inference set --model --provider +$$nemoclaw inference set --model --provider ``` - - -```bash -nemohermes inference set --model --provider -``` - Refer to [Switch Inference Providers](../inference/switch-inference-providers) for provider-specific model IDs and API compatibility notes. @@ -248,16 +162,9 @@ If `nemoclaw status` reports the sandbox is alive but the gateway is not If `nemohermes status` reports the sandbox is alive but the Hermes gateway is not running, run the recover command instead of opening a shell. - ```bash -nemoclaw recover +$$nemoclaw recover ``` - - -```bash -nemohermes recover -``` - The command restarts the in-sandbox gateway and re-establishes the dashboard port-forward in one step. It is idempotent and safe to script. @@ -272,20 +179,11 @@ Refer to the command reference for details on `nemohermes recover`. If you entered a provider credential incorrectly during onboarding, clear the gateway-registered value and re-enter it on the next onboard run: - ```bash -nemoclaw credentials list # see which providers are registered -nemoclaw credentials reset # clear a single provider, for example nvidia-prod -nemoclaw onboard # re-run to re-enter the cleared provider +$$nemoclaw credentials list # see which providers are registered +$$nemoclaw credentials reset # clear a single provider, for example nvidia-prod +$$nemoclaw onboard # re-run to re-enter the cleared provider ``` - - -```bash -nemohermes credentials list # see which providers are registered -nemohermes credentials reset # clear a single provider, for example nvidia-prod -nemohermes onboard # re-run to re-enter the cleared provider -``` - The command reference documents [`nemoclaw credentials reset `](../reference/commands#nemoclaw-credentials-reset-provider) in full. @@ -303,16 +201,9 @@ If you changed the underlying Dockerfile, upgraded OpenClaw, or want to pick up If you changed the underlying Dockerfile, upgraded Hermes, or want to pick up a new base image without losing your sandbox's state files, use `rebuild` instead of destroying and recreating: - ```bash -nemoclaw rebuild +$$nemoclaw rebuild ``` - - -```bash -nemohermes rebuild -``` - Rebuild preserves the mounted workspace and registered policies while recreating the container. If NemoClaw cannot archive any requested state path, it reports the backup failure and stops before deleting the original sandbox. @@ -327,16 +218,9 @@ Refer to the [Commands reference](../reference/commands) for `nemohermes Apply an additional preset, such as Telegram or GitHub, to a running sandbox without re-onboarding: - -```bash -nemoclaw policy-add -``` - - ```bash -nemohermes policy-add +$$nemoclaw policy-add ``` - Refer to [`nemoclaw policy-add`](../reference/commands#nemoclaw-name-policy-add) for usage details and flags. @@ -401,22 +285,12 @@ The installer checks registered sandboxes after onboarding succeeds and runs `ne Use `upgrade-sandboxes` directly to verify the result, rebuild when you skipped the installer or onboarding step, or handle sandboxes that were stopped or could not be version checked. The upgrade flow is non-destructive by default because NemoClaw preserves manifest-defined workspace state, but a manual snapshot before any major upgrade gives you a state restore point. - -```bash -nemoclaw snapshot create --name pre-upgrade # optional, recommended -nemoclaw update --yes # updates CLI through the maintained installer flow -nemoclaw upgrade-sandboxes --check # verify or list remaining stale/unknown sandboxes -nemoclaw upgrade-sandboxes # manually rebuild remaining stale running sandboxes -``` - - ```bash -nemohermes snapshot create --name pre-upgrade # optional, recommended -nemohermes update --yes # updates CLI through the maintained installer flow -nemohermes upgrade-sandboxes --check # verify or list remaining stale/unknown sandboxes -nemohermes upgrade-sandboxes # manually rebuild remaining stale running sandboxes +$$nemoclaw snapshot create --name pre-upgrade # optional, recommended +$$nemoclaw update --yes # updates CLI through the maintained installer flow +$$nemoclaw upgrade-sandboxes --check # verify or list remaining stale/unknown sandboxes +$$nemoclaw upgrade-sandboxes # manually rebuild remaining stale running sandboxes ``` - `nemoclaw update` is the CLI wrapper around the same installer path as `curl -fsSL https://www.nvidia.com/nemoclaw.sh | bash`. @@ -437,16 +311,9 @@ For scripted manual rebuilds, use `nemohermes upgrade-sandboxes --auto` to skip If the upgraded sandbox needs its workspace state reverted, restore the pre-upgrade snapshot into the running sandbox. This restores saved state directories only; it does not downgrade the sandbox image or agent/runtime: - -```bash -nemoclaw snapshot restore pre-upgrade -``` - - ```bash -nemohermes snapshot restore pre-upgrade +$$nemoclaw snapshot restore pre-upgrade ``` - ### What Changes During a Rebuild @@ -494,16 +361,9 @@ Your existing container keeps serving traffic until the new image is ready. To remove NemoClaw and all resources created during setup, run the CLI's built-in uninstall command: - ```bash -nemoclaw uninstall +$$nemoclaw uninstall ``` - - -```bash -nemohermes uninstall -``` - | Flag | Effect | |--------------------|------------------------------------------------------| diff --git a/scripts/docs-to-skills.py b/scripts/docs-to-skills.py index 67527542fd..5eb423925f 100755 --- a/scripts/docs-to-skills.py +++ b/scripts/docs-to-skills.py @@ -410,6 +410,8 @@ def parse_doc(path: Path, doc_platform: str = "myst-md") -> DocPage: """Parse a documentation file into a DocPage.""" raw = path.read_text(encoding="utf-8") fm, body = parse_yaml_frontmatter(raw) + if doc_platform == "fern-mdx": + body = body.replace("$$nemoclaw", "nemoclaw") body = strip_commented_out_blocks(body) page = DocPage(path=path, raw=raw, frontmatter=fm, body=body) @@ -1888,6 +1890,8 @@ def group_individual(pages: list[DocPage]) -> dict[str, list[DocPage]]: def _is_excluded_doc(path: Path, doc_platform: str) -> bool: """Return whether a page should be skipped for the selected source format.""" + if path.name.endswith(".generated.mdx"): + return True if path.name in EXCLUDED_PATTERNS: return True if doc_platform == "fern-mdx" and path.with_suffix(".md").name in EXCLUDED_PATTERNS: diff --git a/scripts/sync-agent-variant-docs.ts b/scripts/sync-agent-variant-docs.ts index adb9ac38f3..335436aa5e 100644 --- a/scripts/sync-agent-variant-docs.ts +++ b/scripts/sync-agent-variant-docs.ts @@ -1,16 +1,27 @@ // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { readFileSync, writeFileSync } from "node:fs"; +import { mkdirSync, readFileSync, writeFileSync } from "node:fs"; import path from "node:path"; import { fileURLToPath, pathToFileURL } from "node:url"; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); const sourcePath = path.join(repoRoot, "docs/reference/commands.mdx"); const targetPath = path.join(repoRoot, "docs/reference/commands-nemohermes.mdx"); +const lifecyclePath = path.join(repoRoot, "docs/manage-sandboxes/lifecycle.mdx"); +const agentVariants = ["openclaw", "hermes"] as const; + +type AgentVariant = (typeof agentVariants)[number]; +type RenderedFile = { + path: string; + contents: string; +}; const GENERATED_NOTICE = "{/* This file is generated from docs/reference/commands.mdx by scripts/sync-agent-variant-docs.ts. Run `npm run docs:sync-agent-variants` to regenerate it. Do not edit by hand. */}"; +const GENERATED_VARIANT_NOTICE = + "{/* This file is generated from a shared agent-variant source by scripts/sync-agent-variant-docs.ts. Run `npm run docs:sync-agent-variants` to regenerate it. Do not edit by hand. */}"; +const CLI_SENTINEL = "$$nemoclaw"; const checkOnly = process.argv.includes("--check"); @@ -18,6 +29,7 @@ function main(): void { const source = readFileSync(sourcePath, "utf8"); const rendered = renderHermesCommandsReference(source); const existing = readOptionalTarget(); + const generatedVariantPages = renderGeneratedAgentVariantPages(); if (checkOnly) { if (existing !== rendered) { @@ -26,6 +38,7 @@ function main(): void { ); process.exit(1); } + writeGeneratedFiles(generatedVariantPages); return; } @@ -35,6 +48,7 @@ function main(): void { } else { console.log(`${path.relative(repoRoot, targetPath)} is already up to date`); } + writeGeneratedFiles(generatedVariantPages); } export function renderHermesCommandsReference(source: string): string { @@ -91,15 +105,54 @@ function replaceFrontmatterLine(frontmatter: string, key: string, value: string) } function stripAgentOnlyBlocks(body: string): string { + return stripAgentOnlyBlocksForVariant(body, "hermes"); +} + +function stripAgentOnlyBlocksForVariant(body: string, activeVariant: AgentVariant): string { return body.replace( /\n?\n([\s\S]*?)\n<\/AgentOnly>\n?/g, (_match, variant: string, content: string) => { - if (variant !== "hermes") return "\n"; + if (variant !== activeVariant) return "\n"; return `\n${content.trim()}\n`; }, ); } +export function renderAgentVariantPage(source: string, variant: AgentVariant): string { + const { frontmatter, body } = splitFrontmatter(source); + const renderedBody = stripAgentOnlyBlocksForVariant( + body.replace(/^import \{ AgentOnly \} from "\.\.\/_components\/AgentGuide";\n\n?/m, ""), + variant, + ) + .replaceAll(CLI_SENTINEL, variant === "hermes" ? "nemohermes" : "nemoclaw") + .replace(/\n{3,}/g, "\n\n") + .trimStart(); + + return `${frontmatter}${GENERATED_VARIANT_NOTICE}\n\n${renderedBody}`.replace(/\s*$/, "\n"); +} + +function renderGeneratedAgentVariantPages(): RenderedFile[] { + const source = readFileSync(lifecyclePath, "utf8"); + const sourceDirectory = path.dirname(lifecyclePath); + const basename = path.basename(lifecyclePath, ".mdx"); + return agentVariants.map((variant) => ({ + path: path.join(sourceDirectory, `${basename}.${variant}.generated.mdx`), + contents: renderAgentVariantPage(source, variant), + })); +} + +function writeGeneratedFiles(files: RenderedFile[]): void { + for (const file of files) { + if (readOptionalFile(file.path) === file.contents) { + console.log(`${path.relative(repoRoot, file.path)} is already up to date`); + continue; + } + mkdirSync(path.dirname(file.path), { recursive: true }); + writeFileSync(file.path, file.contents); + console.log(`Wrote ${path.relative(repoRoot, file.path)}`); + } +} + function transformNemoclawCliInvocations(body: string): string { return restoreProtectedLiterals( protectNonAliasableLiterals(body) @@ -137,8 +190,12 @@ function restoreProtectedLiterals(body: string): string { } function readOptionalTarget(): string | null { + return readOptionalFile(targetPath); +} + +function readOptionalFile(filePath: string): string | null { try { - return readFileSync(targetPath, "utf8"); + return readFileSync(filePath, "utf8"); } catch (error) { if (isNodeError(error) && error.code === "ENOENT") return null; throw error; diff --git a/scripts/watch-fern-preview.ts b/scripts/watch-fern-preview.ts index 5622bc514c..8726bced33 100644 --- a/scripts/watch-fern-preview.ts +++ b/scripts/watch-fern-preview.ts @@ -148,7 +148,10 @@ function isNodeError(error: unknown): error is NodeError { } function shouldIgnorePath(candidatePath: string): boolean { - return candidatePath.split(path.sep).some((part) => ignoredDirectoryNames.has(part)); + return ( + candidatePath.endsWith(".generated.mdx") || + candidatePath.split(path.sep).some((part) => ignoredDirectoryNames.has(part)) + ); } function scheduleRun(): void { diff --git a/test/agent-variant-docs.test.ts b/test/agent-variant-docs.test.ts new file mode 100644 index 0000000000..793556489c --- /dev/null +++ b/test/agent-variant-docs.test.ts @@ -0,0 +1,45 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { describe, expect, it } from "vitest"; + +import { renderAgentVariantPage } from "../scripts/sync-agent-variant-docs"; + +const source = `--- +title: "Example" +--- +import { AgentOnly } from "../_components/AgentGuide"; + + +OpenClaw only. + + +Hermes only. + + +\`\`\`bash +$$nemoclaw list +\`\`\` +`; + +describe("agent variant docs", () => { + it("renders OpenClaw sentinel code and content", () => { + const rendered = renderAgentVariantPage(source, "openclaw"); + + expect(rendered).toContain("OpenClaw only."); + expect(rendered).not.toContain("Hermes only."); + expect(rendered).toContain("nemoclaw list"); + expect(rendered).not.toContain("$$nemoclaw"); + expect(rendered).not.toContain("AgentOnly"); + }); + + it("renders Hermes sentinel code and content", () => { + const rendered = renderAgentVariantPage(source, "hermes"); + + expect(rendered).not.toContain("OpenClaw only."); + expect(rendered).toContain("Hermes only."); + expect(rendered).toContain("nemohermes list"); + expect(rendered).not.toContain("$$nemoclaw"); + expect(rendered).not.toContain("AgentOnly"); + }); +}); From 019dbaa11fb801c1cc72e71cf9627062cb286311 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Wed, 3 Jun 2026 13:21:50 -0700 Subject: [PATCH 2/6] docs: sync nemohermes command reference --- docs/reference/commands-nemohermes.mdx | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/docs/reference/commands-nemohermes.mdx b/docs/reference/commands-nemohermes.mdx index 659576bdd7..5edaae4958 100644 --- a/docs/reference/commands-nemohermes.mdx +++ b/docs/reference/commands-nemohermes.mdx @@ -1521,6 +1521,10 @@ Set them before running `nemohermes onboard`. | `NEMOCLAW_OLLAMA_INSTALL_MODE` | `system`, `user`, or empty/unset | Pins the Linux Ollama install location; see the Linux Ollama install mode details below. | | `NEMOCLAW_PROXY_HOST` | hostname or IP | Overrides the sandbox-side outbound HTTP proxy host. Defaults to `10.200.0.1`. | | `NEMOCLAW_PROXY_PORT` | integer port | Overrides the sandbox-side outbound HTTP proxy port. Defaults to `3128`. | +| `NEMOCLAW_OPENCLAW_OTEL` | `1` to enable | Enables OpenClaw conversation diagnostics export through the `diagnostics-otel` plugin. Disabled by default. | +| `NEMOCLAW_OPENCLAW_OTEL_ENDPOINT` | OTLP/HTTP URL | Sets the OpenTelemetry collector endpoint for OpenClaw diagnostics. Defaults to `http://host.openshell.internal:4318` when `NEMOCLAW_OPENCLAW_OTEL=1`. | +| `NEMOCLAW_OPENCLAW_OTEL_SERVICE_NAME` | service name | Sets the OTEL `service.name` for OpenClaw gateway spans. Defaults to `openclaw-gateway`. | +| `NEMOCLAW_OPENCLAW_OTEL_SAMPLE_RATE` | `0.0` to `1.0` | Sets OpenClaw's root-span sample rate for conversation diagnostics. Defaults to `1.0`. | | `NEMOCLAW_OPENSHELL_BIN` | path | Overrides the `openshell` binary the CLI invokes. Defaults to `openshell` (resolved via `PATH`). | | `NEMOCLAW_SANDBOX` | sandbox name | Alternate spelling of `NEMOCLAW_SANDBOX_NAME`; used by `services` and `debug` lookups when neither a flag nor `NEMOCLAW_SANDBOX_NAME` is set. | | `NEMOCLAW_INSTALL_REF` | git ref | For internal installer commands: the git ref to install from. Overridden by the `--install-ref` flag. | @@ -1593,6 +1597,29 @@ NEMOCLAW_TRACE_FILE=/tmp/nemoclaw-onboard-trace.json nemohermes onboard Trace artifacts include onboard phase timing, sandbox and dashboard readiness waits, policy application, inference validation probes, curl probe results, and sandbox build progress events. Secret-like metadata such as API keys, bearer tokens, cookies, and credentials is redacted before the file is written. +### OpenClaw Conversation OTEL Diagnostics + +Set `NEMOCLAW_OPENCLAW_OTEL=1` before onboarding or rebuilding an OpenClaw sandbox to enable runtime conversation traces through OpenClaw's `diagnostics-otel` plugin. +This is separate from `NEMOCLAW_TRACE`, which records NemoClaw onboarding phases to a local JSON file. +NemoClaw configures OpenClaw for OTLP/HTTP protobuf traces only by default: metrics and logs are disabled, and prompt/tool content capture is not enabled. + +For a local Jaeger collector: + +```bash +docker run --rm --name nemoclaw-jaeger \ + -e COLLECTOR_OTLP_ENABLED=true \ + -p 16686:16686 \ + -p 4318:4318 \ + jaegertracing/all-in-one:1.57 +NEMOCLAW_OPENCLAW_OTEL=1 nemohermes onboard +``` + +Onboarding automatically applies the `openclaw-diagnostics-otel-local` preset at sandbox create and again during the policy step when `NEMOCLAW_OPENCLAW_OTEL=1`, so OTLP export is allowed before the gateway's first trace flush. If you enabled OTEL after an existing sandbox was created, run `nemohermes policy-add openclaw-diagnostics-otel-local --yes` or recreate the sandbox with OTEL enabled at build time. + +Then open `http://localhost:16686` and select the `openclaw-gateway` service. +The built-in `openclaw-diagnostics-otel-local` preset allows only `POST /v1/traces` (and subpaths) to `host.openshell.internal:4318` from `openclaw` and `node`. +For a remote collector, create a custom preset for the collector host and port instead of using the local host-gateway preset. + ### Probe Timeouts These tune how long internal probes wait before giving up. @@ -1634,6 +1661,19 @@ These flags change defaults for commands that manage existing sandboxes. | `NEMOCLAW_DISABLE_INFERENCE_ROUTE_REPAIR` | `1` to enable | Skips the automatic DNS-proxy repair for stale `inference.local` routes during `nemohermes connect` and `nemohermes connect --probe-only`. Use only as a troubleshooting escape hatch. | | `NEMOCLAW_SHIELDS_ACCEPT_LEGACY_BASELINE` | `1` to opt in | Allows advanced immutable-config verification to trust the current on-disk bytes for older or partial content baselines. Use only after you have rebuilt or manually inspected the sandbox state and accepted that the baseline is operator-approved. | +### Remote Deployment + +These variables seed defaults for `nemohermes deploy` and `nemohermes onboard --remote`, which provision a sandbox on a Brev instance. +Each has a flag equivalent on `deploy`; the env var lets non-interactive runs skip the prompt. +For narrative how-to coverage of `NEMOCLAW_BREV_PROVIDER` and `NEMOCLAW_GPU`, see [Deploy to Remote GPU](../deployment/deploy-to-remote-gpu.md). + +| Variable | Default | Effect | +|----------|---------|--------| +| `NEMOCLAW_BREV_PROVIDER` | `gcp` | Cloud provider for Brev instance creation. | +| `NEMOCLAW_GPU` | `a2-highgpu-1g:nvidia-tesla-a100:1` | GPU specification (instance type and GPU model) for the Brev instance. | +| `NEMOCLAW_DEPLOY_NO_CONNECT` | unset | When set to `1`, skips the automatic `connect` step after the remote deploy completes. | +| `NEMOCLAW_DEPLOY_NO_START_SERVICES` | unset | When set to `1`, skips starting services automatically after the remote deploy. | + ### Legacy `nemohermes setup` Deprecated. Use `nemohermes onboard` instead. From 9e958c6542813005c3f9435a6e54d687f33a17d3 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Wed, 3 Jun 2026 13:28:39 -0700 Subject: [PATCH 3/6] docs: document agent CLI sentinel usage --- docs/CONTRIBUTING.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 175758bc4a..35c1122414 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -258,10 +258,13 @@ These patterns are common in LLM-generated text and erode trust with technical r Put only the command text in copyable blocks: ```bash - nemoclaw onboard + $$nemoclaw onboard ``` -- For command examples that differ only by the host CLI binary, write `$$nemoclaw` in the shared source page and let `scripts/sync-agent-variant-docs.ts` render `nemoclaw` or `nemohermes` for Fern. +- Use `$$nemoclaw` for NemoClaw host CLI command examples in shared variant pages. + The docs build resolves it to `nemoclaw` for OpenClaw pages and `nemohermes` for Hermes pages before Fern renders code blocks. + This preserves Fern's native fenced-code UI while keeping one source sample. +- Do not write duplicate `` fenced code blocks when the only difference is `nemoclaw` versus `nemohermes`. Use `` blocks only when the surrounding content differs between the OpenClaw and Hermes variants. - Use `powershell` for Windows PowerShell commands. From 7cf39cd12c0745dc9878bcf4b6cb5883547210a5 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Wed, 3 Jun 2026 13:32:09 -0700 Subject: [PATCH 4/6] docs: teach update skill agent CLI sentinel --- .agents/skills/nemoclaw-contributor-update-docs/SKILL.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.agents/skills/nemoclaw-contributor-update-docs/SKILL.md b/.agents/skills/nemoclaw-contributor-update-docs/SKILL.md index e838d75fb4..e2e93c9b92 100644 --- a/.agents/skills/nemoclaw-contributor-update-docs/SKILL.md +++ b/.agents/skills/nemoclaw-contributor-update-docs/SKILL.md @@ -116,6 +116,8 @@ Write the doc update following these conventions: - **Start sections with an introductory sentence** that orients the reader. - **No superlatives.** Say what the feature does, not how great it is. - **Copyable code examples use language-specific fences** such as `bash`, `sh`, or `powershell`, without prompt markers. +- **Shared NemoClaw CLI examples use `$$nemoclaw`.** In shared OpenClaw/Hermes variant pages, write host CLI examples with the `$$nemoclaw` sentinel so the docs build renders `nemoclaw` on OpenClaw pages and `nemohermes` on Hermes pages before Fern renders fenced code blocks. +- **Do not duplicate code blocks for binary-name-only differences.** Use one fenced block with `$$nemoclaw` when the only difference is `nemoclaw` versus `nemohermes`; keep `` only when the surrounding text, flags, behavior, or setup steps actually differ. - **Use `console` only for terminal transcripts** that include prompts, output, or interactive sessions. - **Include the SPDX header** if creating a new page. - **Match existing frontmatter format** if creating a new page. From ec0d84165f99631f8d9cb8f42800166a879fc691 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Wed, 3 Jun 2026 13:33:59 -0700 Subject: [PATCH 5/6] docs: clarify agent CLI placeholder wording --- .agents/skills/nemoclaw-contributor-update-docs/SKILL.md | 2 +- docs/CONTRIBUTING.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.agents/skills/nemoclaw-contributor-update-docs/SKILL.md b/.agents/skills/nemoclaw-contributor-update-docs/SKILL.md index e2e93c9b92..b737b5d226 100644 --- a/.agents/skills/nemoclaw-contributor-update-docs/SKILL.md +++ b/.agents/skills/nemoclaw-contributor-update-docs/SKILL.md @@ -116,7 +116,7 @@ Write the doc update following these conventions: - **Start sections with an introductory sentence** that orients the reader. - **No superlatives.** Say what the feature does, not how great it is. - **Copyable code examples use language-specific fences** such as `bash`, `sh`, or `powershell`, without prompt markers. -- **Shared NemoClaw CLI examples use `$$nemoclaw`.** In shared OpenClaw/Hermes variant pages, write host CLI examples with the `$$nemoclaw` sentinel so the docs build renders `nemoclaw` on OpenClaw pages and `nemohermes` on Hermes pages before Fern renders fenced code blocks. +- **Shared NemoClaw CLI examples use `$$nemoclaw`.** In shared OpenClaw/Hermes variant pages, write host CLI examples with the `$$nemoclaw` build-time placeholder so the docs build renders `nemoclaw` on OpenClaw pages and `nemohermes` on Hermes pages before Fern renders fenced code blocks. - **Do not duplicate code blocks for binary-name-only differences.** Use one fenced block with `$$nemoclaw` when the only difference is `nemoclaw` versus `nemohermes`; keep `` only when the surrounding text, flags, behavior, or setup steps actually differ. - **Use `console` only for terminal transcripts** that include prompts, output, or interactive sessions. - **Include the SPDX header** if creating a new page. diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 35c1122414..b711f71b0a 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -261,7 +261,7 @@ These patterns are common in LLM-generated text and erode trust with technical r $$nemoclaw onboard ``` -- Use `$$nemoclaw` for NemoClaw host CLI command examples in shared variant pages. +- Use `$$nemoclaw` as a build-time placeholder for NemoClaw host CLI command examples in shared variant pages. The docs build resolves it to `nemoclaw` for OpenClaw pages and `nemohermes` for Hermes pages before Fern renders code blocks. This preserves Fern's native fenced-code UI while keeping one source sample. - Do not write duplicate `` fenced code blocks when the only difference is `nemoclaw` versus `nemohermes`. From ed1d77ae109cdb3d0c58ac0e5348a79c03b0e0bf Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Wed, 3 Jun 2026 13:49:42 -0700 Subject: [PATCH 6/6] docs: collapse inline lifecycle alias variants --- docs/manage-sandboxes/lifecycle.mdx | 72 ++++++----------------------- 1 file changed, 15 insertions(+), 57 deletions(-) diff --git a/docs/manage-sandboxes/lifecycle.mdx b/docs/manage-sandboxes/lifecycle.mdx index 2f06e47ee4..f0d719bfe1 100644 --- a/docs/manage-sandboxes/lifecycle.mdx +++ b/docs/manage-sandboxes/lifecycle.mdx @@ -168,12 +168,7 @@ $$nemoclaw recover The command restarts the in-sandbox gateway and re-establishes the dashboard port-forward in one step. It is idempotent and safe to script. - -Refer to [`nemoclaw recover`](../reference/commands#nemoclaw-name-recover) for details. - - -Refer to the command reference for details on `nemohermes recover`. - +Refer to [`$$nemoclaw recover`](../reference/commands#$$nemoclaw-name-recover) for details. ### Reset a Stored Credential @@ -185,12 +180,7 @@ $$nemoclaw credentials reset # clear a single provider, for exampl $$nemoclaw onboard # re-run to re-enter the cleared provider ``` - -The command reference documents [`nemoclaw credentials reset `](../reference/commands#nemoclaw-credentials-reset-provider) in full. - - -The [Commands reference](../reference/commands) documents the credentials command in full. - +The command reference documents [`$$nemoclaw credentials reset `](../reference/commands#$$nemoclaw-credentials-reset-provider) in full. ### Rebuild a Sandbox While Preserving Workspace State @@ -207,12 +197,7 @@ $$nemoclaw rebuild Rebuild preserves the mounted workspace and registered policies while recreating the container. If NemoClaw cannot archive any requested state path, it reports the backup failure and stops before deleting the original sandbox. - -Refer to [`nemoclaw rebuild`](../reference/commands#nemoclaw-name-rebuild) for flag details. - - -Refer to the [Commands reference](../reference/commands) for `nemohermes rebuild` flag details. - +Refer to [`$$nemoclaw rebuild`](../reference/commands#$$nemoclaw-name-rebuild) for flag details. ### Add a Network Preset After Onboarding @@ -222,20 +207,16 @@ Apply an additional preset, such as Telegram or GitHub, to a running sandbox wit $$nemoclaw policy-add ``` -Refer to [`nemoclaw policy-add`](../reference/commands#nemoclaw-name-policy-add) for usage details and flags. +Refer to [`$$nemoclaw policy-add`](../reference/commands#$$nemoclaw-name-policy-add) for usage details and flags. Non-interactive re-onboards in the default `suggested` policy mode preserve presets added this way. To make a re-onboard authoritative, set `NEMOCLAW_POLICY_MODE=custom` and provide `NEMOCLAW_POLICY_PRESETS` with the exact list to apply; onboarding removes anything else. -See [`NEMOCLAW_POLICY_MODE`](../reference/commands#nemoclaw-onboard) for the full table. +See [`NEMOCLAW_POLICY_MODE`](../reference/commands#$$nemoclaw-onboard) for the full table. ## Update to the Maintained Version - -When a maintained NemoClaw release becomes available, update the `nemoclaw` CLI on your host and check existing sandboxes for stale agent/runtime versions. - - -When a maintained NemoClaw release becomes available, update the `nemohermes` CLI on your host and check existing sandboxes for stale agent/runtime versions. - +When a maintained NemoClaw release becomes available, update the `$$nemoclaw` CLI on your host and check existing sandboxes for stale agent/runtime versions. + The standard installer follows the admin-promoted `lkg` release tag by default, so it can trail the newest semver or `latest` tag while validation completes. To pin a specific release in a `curl | bash` install, set `NEMOCLAW_INSTALL_TAG` on the `bash` side of the pipe, or export it before the pipeline: @@ -252,12 +233,8 @@ If the requested ref cannot be fetched, the installer exits with a clear error i ### Update the NemoClaw CLI Re-run the installer. - -Before it onboards anything, the installer calls [`nemoclaw backup-all`](../reference/commands#nemoclaw-backup-all) automatically, storing a snapshot of each running sandbox in `~/.nemoclaw/rebuild-backups/` as a safety net. - - -Before it onboards anything, the installer calls `nemohermes backup-all` automatically, storing a snapshot of each running sandbox in `~/.nemoclaw/rebuild-backups/` as a safety net. - +Before it onboards anything, the installer calls [`$$nemoclaw backup-all`](../reference/commands#$$nemoclaw-backup-all) 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 installer offers the automatic path only when the existing `nemoclaw` CLI supports `backup-all`. @@ -276,12 +253,7 @@ curl -fsSL https://www.nvidia.com/nemoclaw.sh | bash ### Upgrade Sandboxes with Stale Agent and Runtime Versions - -The installer checks registered sandboxes after onboarding succeeds and runs `nemoclaw upgrade-sandboxes --auto` for stale running sandboxes. - - -The installer checks registered sandboxes after onboarding succeeds and runs `nemohermes upgrade-sandboxes --auto` for stale running sandboxes. - +The installer checks registered sandboxes after onboarding succeeds and runs `$$nemoclaw upgrade-sandboxes --auto` for stale running sandboxes. Use `upgrade-sandboxes` directly to verify the result, rebuild when you skipped the installer or onboarding step, or handle sandboxes that were stopped or could not be version checked. The upgrade flow is non-destructive by default because NemoClaw preserves manifest-defined workspace state, but a manual snapshot before any major upgrade gives you a state restore point. @@ -301,12 +273,7 @@ Use `nemoclaw update --check` when you only want to inspect version state and se Use `nemohermes update --check` when you only want to inspect version state and see the maintained update command. - -For scripted manual rebuilds, use `nemoclaw upgrade-sandboxes --auto` to skip the confirmation prompt. - - -For scripted manual rebuilds, use `nemohermes upgrade-sandboxes --auto` to skip the confirmation prompt. - +For scripted manual rebuilds, use `$$nemoclaw upgrade-sandboxes --auto` to skip the confirmation prompt. If the upgraded sandbox needs its workspace state reverted, restore the pre-upgrade snapshot into the running sandbox. This restores saved state directories only; it does not downgrade the sandbox image or agent/runtime: @@ -340,20 +307,11 @@ When a backup command reports partial archive output, NemoClaw keeps the usable See [Backup and Restore](backup-restore) for the full list of state-preservation guarantees, snapshot retention, and instructions for manual backups when the auto-flow is not enough. - -The rebuild preflight reads the provider credential recorded by your last `nemoclaw onboard` session. +The rebuild preflight reads the provider credential recorded by your last `$$nemoclaw onboard` session. If you have switched providers since onboarding, for example from a remote API to a local Ollama setup, the preflight can still reference the old key and fail before any destroy step runs. -To recover, re-run `nemoclaw onboard` and select your current provider. +To recover, re-run `$$nemoclaw onboard` and select your current provider. This refreshes the session metadata. - - -The rebuild preflight reads the provider credential recorded by your last `nemohermes onboard` session. -If you have switched providers since onboarding, for example from a remote API to a local Ollama setup, the preflight can still reference the old key and fail before any destroy step runs. - -To recover, re-run `nemohermes onboard` and select your current provider. -This refreshes the session metadata. - Your existing container keeps serving traffic until the new image is ready. @@ -376,7 +334,7 @@ The uninstall command preserves `~/.nemoclaw/rebuild-backups/` (host-side snapsh 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 the [Commands reference](../reference/commands#nemoclaw-uninstall) for the full preservation contract. +See the [Commands reference](../reference/commands#$$nemoclaw-uninstall) for the full preservation contract. The CLI uninstall command runs the version-pinned `uninstall.sh` that shipped with your installed CLI, so it does not fetch anything over the network at uninstall time. @@ -393,7 +351,7 @@ The same `--yes`, `--keep-openshell`, and `--delete-models` flags listed above a curl -fsSL https://raw.githubusercontent.com/NVIDIA/NemoClaw/refs/heads/main/uninstall.sh | bash -s -- --yes --delete-models ``` -For a full comparison of the two forms, including what they fetch, what they trust, and when to prefer each, refer to [`nemoclaw uninstall` vs. the hosted `uninstall.sh`](../reference/commands#nemoclaw-uninstall-vs-the-hosted-uninstallsh). +For a full comparison of the two forms, including what they fetch, what they trust, and when to prefer each, refer to [`$$nemoclaw uninstall` vs. the hosted `uninstall.sh`](../reference/commands#$$nemoclaw-uninstall-vs-the-hosted-uninstallsh). ## Related Topics