diff --git a/.gitignore b/.gitignore index 54554a3ed7..bb4d930548 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ Thumbs.db # Project-specific .nemoclaw-maintainer/ +# Legacy DORI status file; no longer read, kept ignored to prevent accidental commits. .dori_user_status draft_newsletter_* research/ diff --git a/AGENTS.md b/AGENTS.md index c052d60aa2..3dd7c2425b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -297,46 +297,28 @@ If the command trace contains no reviewer-request write, report the event as an ### NVIDIA DORI Routing -Use the ignored `.dori_user_status` file at the repository root to select the -documentation path. The file can contain only one line: `authorized` or -`external`. - -1. Read `.dori_user_status` before checking for DORI. - - If the value is `external`, use the - [Writing Style Guide](docs/AGENTS.md#writing-style-guide) without checking - DORI. - - If the value is `authorized`, continue to step 2. - - If the file is absent or invalid, ask the user to select one of these - options. Use selectable options when the host supports them. Otherwise, - present the numbered list: - - 1. Select `authorized` if you are an NVIDIA employee or authorized - contractor with access to `gitlab-master.nvidia.com`. - 2. Select `external` for all other contributors. - - - Normalize an unambiguous response and write only the corresponding - lowercase value to `.dori_user_status`. - - Store `authorized` for option 1, `1`, `authorized`, or a response that - clearly selects `authorized`, such as `yes, authorized`. - - Store `external` for option 2, `2`, `external`, or a response that - clearly selects `external`. - - If the response is ambiguous, selects both options, or does not select - either option, ask again and do not write the file. - - If the user declines to answer or store a value, do not create the file. - Use the [Writing Style Guide](docs/AGENTS.md#writing-style-guide). - - Tell the user that deleting `.dori_user_status` resets the choice. -2. Only after an `authorized` value, check whether the current agent exposes - `dori_handle` or `dori_route`. - - If DORI is available, use it for task routing. When `dori_collections` is - available, verify that a collection source contains - `tech-docs/skill-library`. - - If DORI is unavailable or the Skill Library is missing, follow - [NVIDIA DORI Setup](docs/DORI_SETUP.md). - -The stored value does not prove access or approve installation or host -configuration. Use the -[Writing Style Guide](docs/AGENTS.md#writing-style-guide) if setup is declined -or fails. +Select the documentation path from current host capabilities. +Do not ask the user to classify themselves or store repository-scoped identity +state during a normal documentation task. + +1. Check whether the current agent exposes `dori_handle` or `dori_route` and + `dori_collections`. + If the user explicitly asks not to use DORI, use the + [Writing Style Guide](docs/AGENTS.md#writing-style-guide) instead. +2. When those tools are available, list the installed collections. + - If a collection source contains `tech-docs/skill-library`, use DORI for + task routing. + - If the collection is missing, inaccessible, or cannot be verified, + continue with the + [Writing Style Guide](docs/AGENTS.md#writing-style-guide). +3. When the DORI tools are unavailable, continue with the Writing Style Guide. + Do not inspect a shell-visible CLI, install software, or configure the host + during a normal documentation task. +4. Use [NVIDIA DORI Setup](docs/DORI_SETUP.md) only when the user explicitly + asks to install or configure DORI. + +Capability detection does not approve installation or host configuration. +DORI unavailability must not block documentation work. ## PR Requirements diff --git a/docs/AGENTS.md b/docs/AGENTS.md index 26d6c105e0..ac44d5a5f6 100644 --- a/docs/AGENTS.md +++ b/docs/AGENTS.md @@ -75,10 +75,10 @@ Apply these rules to documentation, examples, headings, UI text, and release not ## Use DORI for Complete NVIDIA Doc Tools -Follow [NVIDIA DORI Routing](../AGENTS.md#nvidia-dori-routing) before checking for DORI. -Only an `authorized` value can select the DORI path. -When root routing selects that path, you can use DORI for additional documentation tools. -Complete the documentation before the developer opens the pull or merge request. +Follow [NVIDIA DORI Routing](../AGENTS.md#nvidia-dori-routing). +Use the following DORI workflow only when current host capabilities include the +verified NVIDIA documentation Skill Library. Complete the documentation before +the developer opens the pull or merge request. 1. Route the documentation task through DORI. Include the changed source files, the user-visible impact, the documentation that might need updates, and the @@ -91,8 +91,9 @@ Complete the documentation before the developer opens the pull or merge request. 4. When the host does not support subagents, complete the same documentation work in the primary task. -If root routing directs you to the Writing Style Guide, or if DORI is unavailable, inaccessible, declined, or fails, do not block the change. -Continue using the Writing Style Guide above. +If the verified Skill Library is unavailable, inaccessible, or fails, skip DORI. +Do not attempt routing, prompt for setup, or ask for or persist a user +classification. Continue using the Writing Style Guide above. ## Before Editing diff --git a/docs/DORI_SETUP.md b/docs/DORI_SETUP.md index f48a8df1ad..b586eaac38 100644 --- a/docs/DORI_SETUP.md +++ b/docs/DORI_SETUP.md @@ -5,10 +5,15 @@ # NVIDIA DORI Setup -Use this guide only after the root `AGENTS.md` reads an `authorized` value from `.dori_user_status`. -The stored value does not prove private access or approve installation or host configuration. +Use this guide only when the user explicitly asks to install or configure NVIDIA DORI. +Before inspecting or installing private components, ask the user to confirm that they can access `gitlab-master.nvidia.com`. +If the user does not confirm access, stop this setup and use the checked-in [Writing Style Guide](AGENTS.md#writing-style-guide). +Access confirmation does not approve installation or host configuration. -If the status is not `authorized`, stop this setup and use the checked-in [Writing Style Guide](AGENTS.md#writing-style-guide). +Use these internal sources for the current installation and registration instructions: + +- [NVIDIA Skill Library](https://gitlab-master.nvidia.com/tech-docs/skill-library) contains documentation-focused Agent Skills and guidance for installing them with DORI and other supported hosts. +- [NVIDIA Template Library](https://gitlab-master.nvidia.com/tech-docs/template-library) contains reusable documentation templates and guidance for installing its template skills with DORI. ## Inspect the Environment @@ -50,7 +55,7 @@ Before an installation or host configuration change, ask: > Do you want me to install or configure these components in your user environment? Continue only after explicit approval. -An `authorized` status does not approve these changes. +The user's private-source access confirmation does not approve these changes. If the user declines, use the [Writing Style Guide](AGENTS.md#writing-style-guide). ## Install Missing Components @@ -103,8 +108,8 @@ Until the current agent exposes DORI tools, continue the original task with the - Never search for, request, print, copy, export, or embed a token, password, cookie, SSH key, or credential-bearing URL. - Let `uv`, Git, and DORI use credentials that the user already configured. If access is denied or authentication is missing, stop and refer to the internal DORI installation guide. -- Never stage or commit `.dori_user_status`. - Do not treat its value as proof of employment, authorization, or current private access. +- Do not create repository-scoped identity or authorization files. + Confirm private-source access only for an explicit setup request. - Do not bypass approval controls for writes outside the repository. - Do not create or commit project-scoped DORI state or MCP configuration without separate repository-owner authorization. - Do not retry a failed installation in the same task. diff --git a/docs/changelog/2026-07-30.mdx b/docs/changelog/2026-07-30.mdx index a528c16766..4244295544 100644 --- a/docs/changelog/2026-07-30.mdx +++ b/docs/changelog/2026-07-30.mdx @@ -35,7 +35,8 @@ It also hardens host readiness, inference health checks, managed images, documen - Trusted CI now publishes agent-complete Open Container Initiative images by immutable digest, validates anonymous pulls and runtime contracts, and promotes aliases only after those checks pass. Dormant managed-image selection and startup-profile contracts resolve exact all-agent cohorts and bounded agent-specific startup data without activating buildless onboarding or changing the current `Dockerfile` path. - Documentation now keeps provider-switch sections within the applicable OpenClaw and Hermes guide variants, corrects the Omni sub-agent model ID, and generalizes agent-selection guidance. - The contributor workflow also separates pre-tag release entries from post-tag Announcements and corrects the NVIDIA DORI installation pin from 0.10.0 to 0.9.0. + The runtime identity, two-DGX Station vLLM, and memory search guides are now separate focused pages. + The NVIDIA DORI installation pin is corrected from 0.10.0 to 0.9.0. For more information, refer to [Switch Inference Providers](/user-guide/openclaw/inference/manage-inference/switch-providers) and [Set Up Task-Specific Sub-Agents](/user-guide/openclaw/configure-agents/set-up-sub-agent). - Release E2E now preserves command and agent first-turn latency separately, evaluates recurring anomalies within an exact 12-sample cohort, and routes retired rebuild selectors to focused replacement evidence. The credential-generation window runs independently, managed startup recovery covers the persisted startup command, and the standing Brev Launchable waits for the staging image family before deployment. diff --git a/docs/configure-agents/configure-memory-search.mdx b/docs/configure-agents/configure-memory-search.mdx index 4ec51c19aa..5c0f69179b 100644 --- a/docs/configure-agents/configure-memory-search.mdx +++ b/docs/configure-agents/configure-memory-search.mdx @@ -16,8 +16,8 @@ This setup lets another local server, such as managed vLLM, continue to serve th ## Prepare the Embedding Server -Start the host Ollama container with the embedding model. -This example uses `qwen3-embedding:4b` on port `11434`. +Before you continue, ensure that a host Ollama container is running on port `11434` and has the `qwen3-embedding:4b` model available. +This procedure does not start the container or pull the model. The sandbox reaches the container through `http://host.openshell.internal:11434`. Keep the container bound to the local host or a reviewed host interface. @@ -34,6 +34,8 @@ nemoclaw my-assistant policy add local-inference --yes nemoclaw my-assistant exec -- curl -fsS http://host.openshell.internal:11434/api/tags ``` +Continue only when the returned JSON `models` array contains an entry whose `name` is `qwen3-embedding:4b`. + ## Configure the Embedding Provider Open a bounded shields-down window before you change the OpenClaw configuration. diff --git a/docs/get-started/quickstart-langchain-deepagents-code.mdx b/docs/get-started/quickstart-langchain-deepagents-code.mdx index f519924001..f38c84400b 100644 --- a/docs/get-started/quickstart-langchain-deepagents-code.mdx +++ b/docs/get-started/quickstart-langchain-deepagents-code.mdx @@ -136,150 +136,9 @@ The image includes `ripgrep`, and ordinary sessions suppress the optional Tavily - -### Choose the Default Sandbox - -When you manage multiple sandboxes, use the Deep Agents alias to promote a registered Deep Agents Code sandbox to the default. - -```bash -nemo-deepagents use -``` - -The command updates NemoClaw's host-side registry. -It does not modify the sandbox or the `dcode` configuration. - -### Use the Harness - -Connect to the sandbox, then launch the terminal UI. - -```bash -nemoclaw connect -dcode -``` - -For a single headless task, run: - -```bash -dcode -n "Summarize this repository" -``` - -For automation, add `--json`. -The managed runtime writes exactly one UTF-8 JSON object to stdout and suppresses other stdout text. -Progress is suppressed. -Warnings and diagnostics go to stderr. - -```bash -dcode -n "Summarize this repository" --json -``` - -A successful run has this version 1 envelope: - -```json -{ - "schema_version": 1, - "command": "non-interactive", - "data": { - "status": "success", - "exit_code": 0, - "response": "The repository contains...", - "completion": { - "thread_id": "thread-id", - "duration_ms": 842, - "response_bytes": 26 - } - } -} -``` - -`response` contains the exact final assistant text on success and is `null` on failure. -`response_bytes` is its UTF-8 byte length on success and is `0` on failure. -The process exit code matches `data.exit_code`. -The terminal statuses are `success`, `agent_failure`, `process_failure`, `timeout`, `turn_limit`, `cancelled`, and `output_limit`. -A timeout exits `124`, cancellation exits `130`, and other failures exit nonzero. - -The complete serialized envelope is limited to 1 MiB. -If the response cannot fit, the runtime discards it and emits a bounded `output_limit` failure envelope. -If it cannot write the envelope, the command exits nonzero and reports the write failure on stderr; callers must reject empty, malformed, additional, or unsupported-version stdout. - -The managed `dcode`, `dcode.real`, and `deepagents-code` launchers use `/opt/venv/bin/python3 -I` to run the pinned package with an isolated import path and `HOME=/sandbox`. -For interactive and headless sessions, each launcher supervises its own process descendants so completion, terminal exit, or disconnect terminates the associated LangGraph server tree without affecting another session. -After a disconnect, the supervisor uses bounded grace periods before it kills unresponsive processes from that session. -The supervisor runs inside the Linux OpenShell sandbox and fails closed if invoked outside Linux; the host operating system does not change this sandbox guarantee. -They disable Deep Agents Code package update checks and the LangGraph server version check, block CLI and TUI update/install commands, and disable nested remote sandbox providers, remote async subagents, MCP commands and project auto-loading, startup commands, executable hooks, ACP mode, interpreter tool calling, shell allow-list overrides, native LangSmith tracing, and ambient OpenTelemetry exporter configuration. -The managed model constructor accepts only Deep Agents Code's `openai` provider path and reads its endpoint from a root-owned image file. -It supplies the non-secret gateway placeholder key and ignores mutable provider classes, credentials, endpoints, and constructor parameters in Deep Agents Code config. -CLI and TUI model parameter overrides and custom rubric models are blocked. -For headless runs, `--max-retries` remains available after Deep Agents Code validates the retry count. -The managed boundary discards every other model parameter, including credentials, endpoints, and provider settings. -Project and user-defined subagents remain available, but they inherit the managed chat model instead of accepting their own model override. -MCP servers registered through `nemoclaw mcp add` remain available through NemoClaw's dedicated `/sandbox/.deepagents/.nemoclaw-mcp.json` projection and OpenShell egress policy. -Project and user MCP files are never auto-loaded. -Sandboxes with the older managed MCP v1 runtime must rebuild before `mcp add` or `mcp restart`; remove, rebuild, and destroy can still scrub exact registry-owned legacy entries without claiming unrelated user content. -Before launch, NemoClaw validates and canonicalizes the complete managed file as HTTPS-only definitions with exact OpenShell credential placeholders, then gives Deep Agents Code a process-local, integrity-bound snapshot for server starts and restarts. -It prefers a sealed in-memory file when available; the OpenShell-compatible anonymous read-only descriptor fallback verifies the inode, size, and SHA-256 digest and fails closed on drift. -Stdio commands, extra headers, raw credentials, and unrelated top-level configuration fail closed. -For authenticated MCP setup and credential rotation, see [Add an MCP Server](../manage-sandboxes/mcp-servers/add-an-mcp-server) and [Manage MCP Servers](../manage-sandboxes/mcp-servers/manage-mcp-servers). -This isolated-mode guarantee applies to those managed launchers, not arbitrary Python commands in the sandbox. - -Interactive shell execution and other destructive tools remain behind human-in-the-loop approval prompts by default. -Thread-wide auto-approval is unavailable unless you enable the managed thread opt-in capability, and shell allow-list auto-approval remains disabled. -Headless `dcode -n` is an explicit automation boundary. -It has no approval UI and automatically approves non-shell tool requests, including file writes and edits. -The managed headless path still disables shell execution, startup commands, interpreter tool calling, executable hooks, unmanaged MCP configuration, nested remote sandboxes, remote async subagents, and alternate model routes. -Use the interactive TUI when you need to inspect each destructive tool request before it runs. - -#### Configure Thread Auto-Approval - -Managed Deep Agents sandboxes keep interactive thread auto-approval disabled by default. -In this mode, the TUI auto-approval choice and `dcode -y` fail closed. - -Enable the capability for a named sandbox through a transactional rebuild because NemoClaw bakes the capability into the managed image. - -```bash -nemo-deepagents rebuild --dcode-auto-approval thread-opt-in --yes -``` - -The `thread-opt-in` setting grants permission to activate auto-approval, but it does not activate auto-approval by itself. -For each thread, select **Auto-approve for this thread** in the approval menu or start that `dcode` process with `dcode -y`. -The TUI shows the upstream active-state indicator and a warning while the current thread can run tool calls, including shell commands, without further confirmation. - -NemoClaw resets the active state when you start a new `dcode` process, run `/clear` or `/force-clear`, switch or resume a different thread, or switch agents. -You must opt in again after each reset. -The host-side status command reports the configured capability, not whether one live TUI thread currently has auto-approval active. - -```bash -nemo-deepagents status -``` - -Thread auto-approval does not bypass OpenShell network policy, credential isolation, the managed inference route, managed MCP validation, or the other Deep Agents runtime restrictions described above. -Headless `dcode -n` remains a separate automation boundary with non-shell auto-approval and managed shell execution disabled. - -Return the sandbox to the default posture with another transactional rebuild. - -```bash -nemo-deepagents rebuild --dcode-auto-approval disabled --yes -``` - -To confirm which sandbox a session is in, run the identity command: - -```bash -dcode status -``` - -The command prints the sandbox name, NemoClaw harness, active `dcode` agent, configured inference route, upstream provider, model, endpoint, and runtime, then exits without starting the interactive UI. -`dcode whoami` and `dcode identity` are aliases. -`dcode --help` lists the managed aliases before the upstream Deep Agents Code help. -The sandbox name resolves when you run the command from a `nemoclaw connect` shell, which loads the NemoClaw runtime environment. - -Inspect the generated Deep Agents configuration from the host with: - -```bash -nemo-deepagents config get -``` - -NemoClaw parses `config.toml`, removes gateway auth data, and redacts credential-shaped values before printing it. -`config set` is not supported for this image-baked configuration; re-onboard the named sandbox to change its managed provider or model selection. - + + + Continue with [Run Deep Agents Code](../manage-sandboxes/operate-sandboxes/run-deep-agents-code) for sandbox selection, interactive and headless tasks, the JSON output contract, runtime restrictions, thread auto-approval, and identity checks. @@ -405,6 +264,7 @@ There is no dashboard port or long-running gateway process for this harness. ## Next Steps +- [Run Deep Agents Code](../manage-sandboxes/operate-sandboxes/run-deep-agents-code) explains interactive and headless operation, automation output, and approval boundaries. - [Choose an Inference Provider](../inference/learn-and-choose/choose-inference-provider) explains how to choose a provider and model. - [Understand Sandbox State](../manage-sandboxes/state-and-backups/understand-sandbox-state) explains `/sandbox/.deepagents`, memory, skills, and what NemoClaw preserves. - [Create and Restore Snapshots](../manage-sandboxes/state-and-backups/create-and-restore-snapshots) explains snapshot and rebuild preservation. diff --git a/docs/index.yml b/docs/index.yml index 9abc8f647d..44506d3947 100644 --- a/docs/index.yml +++ b/docs/index.yml @@ -406,6 +406,9 @@ navigation: - page: "Community Solutions" path: _build/agent-variants/resources/community-contributions.openclaw.generated.mdx slug: community-contributions + - page: "Engineer Documentation for AI Agents" + path: _build/agent-variants/resources/engineer-agentic-documentation.openclaw.generated.mdx + slug: engineer-agentic-documentation - link: "Discord" href: https://discord.gg/XFpfPv9Uvx - link: "Report Vulnerabilities" @@ -575,6 +578,9 @@ navigation: - page: "Run Sandboxes" path: _build/agent-variants/manage-sandboxes/run-sandboxes.deepagents.generated.mdx slug: run-sandboxes + - page: "Run Deep Agents Code" + path: manage-sandboxes/run-deep-agents-code.mdx + slug: run-deep-agents-code - page: "Recover and Rebuild Sandboxes" path: _build/agent-variants/manage-sandboxes/recover-rebuild-sandboxes.deepagents.generated.mdx slug: recover-and-rebuild-sandboxes @@ -719,6 +725,9 @@ navigation: - page: "Community Solutions" path: _build/agent-variants/resources/community-contributions.deepagents.generated.mdx slug: community-contributions + - page: "Engineer Documentation for AI Agents" + path: _build/agent-variants/resources/engineer-agentic-documentation.deepagents.generated.mdx + slug: engineer-agentic-documentation - link: "Report Vulnerabilities" href: https://github.com/NVIDIA/NemoClaw/blob/main/SECURITY.md - page: "License" @@ -1098,6 +1107,9 @@ navigation: - page: "Community Solutions" path: _build/agent-variants/resources/community-contributions.hermes.generated.mdx slug: community-contributions + - page: "Engineer Documentation for AI Agents" + path: _build/agent-variants/resources/engineer-agentic-documentation.hermes.generated.mdx + slug: engineer-agentic-documentation - link: "Report Vulnerabilities" href: https://github.com/NVIDIA/NemoClaw/blob/main/SECURITY.md - page: "License" diff --git a/docs/inference/set-up-vllm-on-two-dgx-stations.mdx b/docs/inference/set-up-vllm-on-two-dgx-stations.mdx index 59290e66da..d6b8062b54 100644 --- a/docs/inference/set-up-vllm-on-two-dgx-stations.mdx +++ b/docs/inference/set-up-vllm-on-two-dgx-stations.mdx @@ -70,6 +70,19 @@ curl -fsSL https://www.nvidia.com/nemoclaw.sh | \ bash ``` +## Verify the Installed Route + +After the installer completes, inspect the live route and the sandbox inference path. + +```bash +$$nemoclaw my-assistant inference get +$$nemoclaw my-assistant status +``` + +Confirm that `inference get` reports the `vllm-local` provider and the `nemotron-ultra` model. +Continue only when the `Inference` row in the status output reports `reachable`. +This result confirms that the sandbox route returned HTTP `200` through `499`; it does not prove a successful model invocation. + ## Review Reboot and Resume Behavior If the local host requires a reboot during initial preparation, the installer stops with status `10`. diff --git a/docs/manage-sandboxes/run-deep-agents-code.mdx b/docs/manage-sandboxes/run-deep-agents-code.mdx new file mode 100644 index 0000000000..e9ffc9f1c6 --- /dev/null +++ b/docs/manage-sandboxes/run-deep-agents-code.mdx @@ -0,0 +1,196 @@ +--- +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +title: "Run LangChain Deep Agents Code" +sidebar-title: "Run Deep Agents Code" +description: "Run interactive and headless Deep Agents Code tasks inside a NemoClaw sandbox." +description-agent: "Explains how to select a Deep Agents sandbox, run dcode interactively or headlessly, consume the managed JSON envelope, understand runtime restrictions, configure thread auto-approval, and inspect runtime identity. Use when operating an existing Deep Agents Code sandbox." +keywords: ["run deep agents code", "dcode json", "dcode auto approval", "deep agents runtime"] +topics: ["manage-sandboxes", "terminal-runtime", "langchain-deepagents-code", "automation"] +tags: ["deep-agents-code", "dcode", "managed-runtime"] +difficulty: "intermediate" +audience: "operators" +status: published +content: + type: "how_to" +agent-variants: ["deepagents"] +--- + +Use the managed `dcode` launchers to run interactive or headless work inside an existing Deep Agents Code sandbox. +Complete [Quickstart with Deep Agents](../../get-started/quickstart) before you use these operating workflows. + +## Choose the Default Sandbox + +When you manage multiple sandboxes, use the Deep Agents alias to promote a registered Deep Agents Code sandbox to the default: + +```bash +nemo-deepagents use +``` + +The command updates NemoClaw's host-side registry. +It does not modify the sandbox or the `dcode` configuration. + +## Run Interactive or Headless Tasks + +Connect to the sandbox, then launch the terminal UI: + +```bash +nemo-deepagents connect +dcode +``` + + +Headless `dcode -n` has no approval UI and automatically approves non-shell tool requests, including file writes and edits. +Use the interactive TUI when you need to inspect each destructive tool request before it runs. + + +For a single headless task, run: + +```bash +dcode -n "Summarize this repository" +``` + +For automation, add `--json`: + +```bash +dcode -n "Summarize this repository" --json +``` + +The managed runtime writes exactly one UTF-8 JSON object to stdout and suppresses progress and other stdout text. +Warnings and diagnostics go to stderr. +A successful run has this version 1 envelope: + +```json +{ + "schema_version": 1, + "command": "non-interactive", + "data": { + "status": "success", + "exit_code": 0, + "response": "The repository contains...", + "completion": { + "thread_id": "thread-id", + "duration_ms": 842, + "response_bytes": 26 + } + } +} +``` + +`response` contains the exact final assistant text on success and is `null` on failure. +`response_bytes` is its UTF-8 byte length on success and is `0` on failure. +The process exit code matches `data.exit_code`. +The terminal statuses are `success`, `agent_failure`, `process_failure`, `timeout`, `turn_limit`, `cancelled`, and `output_limit`. +A timeout exits `124`, cancellation exits `130`, and other failures exit nonzero. + +The complete serialized envelope is limited to 1 MiB. +If the response cannot fit, the runtime discards it and emits a bounded `output_limit` failure envelope. +If it cannot write the envelope, the command exits nonzero and reports the write failure on stderr. +Callers must reject empty, malformed, additional, or unsupported-version stdout. + +## Understand the Managed Runtime + +The managed `dcode`, `dcode.real`, and `deepagents-code` launchers use `/opt/venv/bin/python3 -I` to run the pinned package with an isolated import path and `HOME=/sandbox`. +For interactive and headless sessions, each launcher supervises its own process descendants. +Completion, terminal exit, or disconnect terminates the associated LangGraph server tree without affecting another session. +After a disconnect, the supervisor uses bounded grace periods before it kills unresponsive processes from that session. +The supervisor runs inside the Linux OpenShell sandbox and fails closed if invoked outside Linux; the host operating system does not change this sandbox guarantee. + +The managed launchers disable the following mutable or unsupported behavior: + +- Deep Agents Code package update checks and the LangGraph server version check +- CLI and TUI update or install commands +- Nested remote sandbox providers and remote asynchronous subagents +- Deep Agents Model Context Protocol (MCP) commands, project MCP auto-loading, startup commands, and executable hooks +- ACP mode, interpreter tool calling, and shell allowlist overrides +- Native LangSmith tracing and ambient OpenTelemetry exporter configuration + +The managed model constructor accepts only Deep Agents Code's `openai` provider path and reads its endpoint from a root-owned image file. +It supplies the non-secret gateway placeholder key and ignores mutable provider classes, credentials, endpoints, and constructor parameters in Deep Agents Code config. +CLI and TUI model parameter overrides and custom rubric models are blocked. +For headless runs, `--max-retries` remains available after Deep Agents Code validates the retry count. +The managed boundary discards every other model parameter, including credentials, endpoints, and provider settings. +Project and user-defined subagents remain available, but they inherit the managed chat model instead of accepting their own model override. + +MCP servers registered through `nemo-deepagents mcp add` remain available through NemoClaw's dedicated `/sandbox/.deepagents/.nemoclaw-mcp.json` projection and OpenShell egress policy. +Project and user MCP files are never auto-loaded. +Sandboxes with the older managed MCP v1 runtime must rebuild before `mcp add` or `mcp restart`. +Remove, rebuild, and destroy can still scrub exact registry-owned legacy entries without claiming unrelated user content. +Before launch, NemoClaw validates and canonicalizes the complete managed file as HTTPS-only definitions with exact OpenShell credential placeholders. +It then gives Deep Agents Code a process-local, integrity-bound snapshot for server starts and restarts. +It prefers a sealed in-memory file when available. +The OpenShell-compatible anonymous read-only descriptor fallback verifies the inode, size, and SHA-256 digest and fails closed on drift. +Stdio commands, extra headers, raw credentials, and unrelated top-level configuration fail closed. +For authenticated MCP setup and credential rotation, refer to [Add an MCP Server](../mcp-servers/add-an-mcp-server) and [Manage MCP Servers](../mcp-servers/manage-mcp-servers). +This isolated-mode guarantee applies to the managed launchers, not arbitrary Python commands in the sandbox. + +## Choose an Approval Boundary + +Interactive shell execution and other destructive tools remain behind human-in-the-loop approval prompts by default. +Thread-wide auto-approval is unavailable unless you enable the managed thread opt-in capability, and shell allowlist auto-approval remains disabled. + +Headless `dcode -n` is an explicit automation boundary. +The managed headless path still disables shell execution, startup commands, interpreter tool calling, executable hooks, unmanaged MCP configuration, nested remote sandboxes, remote asynchronous subagents, and alternate model routes. + +## Configure Thread Auto-Approval + +Managed Deep Agents sandboxes keep interactive thread auto-approval disabled by default. +In this mode, the TUI auto-approval choice and `dcode -y` fail closed. + +Enable the capability for a named sandbox through a transactional rebuild because NemoClaw bakes the capability into the managed image: + +```bash +nemo-deepagents rebuild --dcode-auto-approval thread-opt-in --yes +``` + +The `thread-opt-in` setting grants permission to activate auto-approval, but it does not activate auto-approval by itself. +For each thread, select **Auto-approve for this thread** in the approval menu or start that `dcode` process with `dcode -y`. +The TUI shows the upstream active-state indicator and a warning while the current thread can run tool calls, including shell commands, without further confirmation. + +NemoClaw resets the active state when you start a new `dcode` process, run `/clear` or `/force-clear`, switch or resume a different thread, or switch agents. +You must opt in again after each reset. +The host-side status command reports the configured capability, not whether one live TUI thread currently has auto-approval active: + +```bash +nemo-deepagents status +``` + +Thread auto-approval does not bypass OpenShell network policy, credential isolation, the managed inference route, managed MCP validation, or the other Deep Agents runtime restrictions. +Headless `dcode -n` remains a separate automation boundary with non-shell auto-approval and managed shell execution disabled. + +Return the sandbox to the default posture with another transactional rebuild: + +```bash +nemo-deepagents rebuild --dcode-auto-approval disabled --yes +``` + +## Inspect Runtime Identity and Configuration + +To confirm which sandbox a session is in, run: + +```bash +dcode status +``` + +The command prints the sandbox name, NemoClaw harness, active `dcode` agent, configured inference route, upstream provider, model, endpoint, and runtime. +It then exits without starting the interactive UI. +`dcode whoami` and `dcode identity` are aliases. +`dcode --help` lists the managed aliases before the upstream Deep Agents Code help. +The sandbox name resolves when you run the command from a `nemo-deepagents connect` shell, which loads the NemoClaw runtime environment. + +Inspect the generated Deep Agents configuration from the host: + +```bash +nemo-deepagents config get +``` + +NemoClaw parses `config.toml`, removes gateway auth data, and redacts credential-shaped values before printing it. +`config set` is not supported for this image-baked configuration. +Re-onboard the named sandbox to change its managed provider or model selection. + +## Related Topics + +- [View Sandbox Status](view-sandbox-status) covers health, logs, and diagnostic collection. +- [Recover and Rebuild Sandboxes](recover-and-rebuild-sandboxes) explains recovery and transactional rebuild behavior. +- [Understand Sandbox State](../state-and-backups/understand-sandbox-state) explains the Deep Agents state directory and preservation boundaries. +- [Troubleshooting](../../reference/troubleshooting) covers common setup and runtime failures. diff --git a/docs/reference/commands.mdx b/docs/reference/commands.mdx index fd20c6cbe6..b3e80cdce8 100644 --- a/docs/reference/commands.mdx +++ b/docs/reference/commands.mdx @@ -110,7 +110,7 @@ dcode -n "Summarize this repository" --json dcode status ``` -For the JSON schema, status and exit behavior, and 1 MiB output limit, refer to [Quickstart with LangChain Deep Agents Code](/user-guide/deepagents/get-started/quickstart#use-the-harness). +For the JSON schema, status and exit behavior, and 1 MiB output limit, refer to [Run Deep Agents Code](/user-guide/deepagents/manage-sandboxes/operate-sandboxes/run-deep-agents-code). @@ -1067,7 +1067,7 @@ Bare invocations run `dcode`, and `--help` runs `dcode --help`. Use `dcode -n` for explicit headless automation when you are already connected to the sandbox, or use `$$nemoclaw agent -n ""` from the host. Add `--json` to either form for one managed, versioned JSON envelope on stdout. The host wrapper forwards the flag to `dcode`. -For the schema, status and exit behavior, and 1 MiB output limit, refer to [Quickstart with LangChain Deep Agents Code](/user-guide/deepagents/get-started/quickstart#use-the-harness). +For the schema, status and exit behavior, and 1 MiB output limit, refer to [Run Deep Agents Code](/user-guide/deepagents/manage-sandboxes/operate-sandboxes/run-deep-agents-code). The host wrapper keeps `HOME=/sandbox`, the managed proxy environment, and the manifest-declared Deep Agents config path aligned with `connect`. Interactive `$$nemoclaw agent` launches the same terminal TUI as `dcode`. Headless `$$nemoclaw agent -n ""` uses the managed headless boundary, where non-shell tools can auto-run without the interactive approval UI. @@ -1393,7 +1393,8 @@ A successful recovery clears the stale stopped-container failure. If OpenShell already reports the registered Docker-driver sandbox as present and `Ready`, status verifies the OpenClaw gateway and host forward. It recovers either component when the verification reports it absent. -If Docker readiness or the agent delivery chain cannot be proven, status exits non-zero and reports the failed recovery layer. +When status finds the sandbox but cannot prove its agent delivery chain, it exits non-zero and reports the `sandbox_recovery_failed` state. +Address the reported recovery layer, then run the displayed `$$nemoclaw recover` command. If the sandbox's recorded dashboard port is also held by a foreign listener, the header escalates to the `sandbox_dashboard_port_conflict` failure layer with the message `sandbox container is stopped and the dashboard port is held by a foreign listener.` so the operator can recover the port before restarting the sandbox. diff --git a/docs/reference/configure-runtime-identity.mdx b/docs/reference/configure-runtime-identity.mdx index ace491e0fc..0c803cbbc6 100644 --- a/docs/reference/configure-runtime-identity.mdx +++ b/docs/reference/configure-runtime-identity.mdx @@ -162,8 +162,10 @@ identity: ``` Register a separate Entra application for the delegated runtime flow. -Grant only the Microsoft Graph delegated `User.Read` permission needed by [`GET /me`](https://learn.microsoft.com/en-us/graph/api/user-get?view=graph-rest-1.0), and request [`offline_access`](https://learn.microsoft.com/en-us/entra/identity-platform/scopes-oidc#the-offline_access-scope) during the external authorization-code bootstrap so the v2 endpoint returns a refresh token. -Microsoft documents `offline_access` as an explicit requirement for v2 refresh-token issuance and [documents replacement of the stored refresh token](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow#refresh-the-access-token) when a refresh response carries a new one. +Grant only the Microsoft Graph delegated `User.Read` permission needed by [`GET /me`](https://learn.microsoft.com/en-us/graph/api/user-get?view=graph-rest-1.0). +During the external authorization-code bootstrap, request [`offline_access`](https://learn.microsoft.com/en-us/entra/identity-platform/scopes-oidc#the-offline_access-scope) so the v2 endpoint returns a refresh token. +Microsoft documents `offline_access` as an explicit requirement for v2 refresh-token issuance. +It also [documents replacement of the stored refresh token](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow#refresh-the-access-token) when a refresh response carries a new refresh token. Use a confidential web application and `ENTRA_CLIENT_SECRET` when the bootstrap client can keep a secret. Omit `client_secret_env` for a public client rather than placing a public-client secret on the host. NemoClaw does not package the authorization redirect, consent UI, PKCE exchange, or MSAL cache. diff --git a/docs/reference/troubleshooting.mdx b/docs/reference/troubleshooting.mdx index f4a66193e4..21d98e9268 100644 --- a/docs/reference/troubleshooting.mdx +++ b/docs/reference/troubleshooting.mdx @@ -134,6 +134,26 @@ docker info The managed default gateway service accepts `DOCKER_HOST` only as an absolute local `unix://` socket path. It rejects remote endpoints and relative socket paths before service startup. +### Onboarding reports `invalid_docker_host` + +The `invalid_docker_host` advisory means that `DOCKER_HOST` is not an absolute local `unix://` socket path that NemoClaw can write to the managed OpenShell gateway service environment. +Remove the override to use Docker's default local socket: + +```bash +unset DOCKER_HOST +$$nemoclaw onboard +``` + +If your Docker daemon uses another local socket, set an absolute `unix://` path before you retry: + +```bash +export DOCKER_HOST=unix:///var/run/docker.sock +$$nemoclaw onboard +``` + +NemoClaw rejects TCP and SSH endpoints, relative socket paths, values that contain single quotes, and values that contain line breaks. +Do not wrap the socket path in single quotes inside the variable value. + ### macOS first-run failures The two most common first-run failures on macOS are missing developer tools and Docker connection errors. @@ -2716,8 +2736,11 @@ If the command succeeds because the dashboard profile is missing, the dashboard ### Shields Reports Drift for the Hermes Configuration Root -The Hermes configuration root holds the agent's top-level runtime state, not only its configuration: `auth.json`, the drain request, and the temporary files that back every atomic `gateway_state.json` and `gateway.pid` replace are created directly in `/sandbox/.hermes`. -Lockdown therefore moves that directory to `root:sandbox` mode `3770`, keeping the set-id and sticky bits, so the gateway can still manage its own runtime files while the sticky bit stops the sandbox identity from unlinking or renaming the sealed root-owned configuration. +The Hermes configuration root holds the agent's top-level runtime state, not only its configuration. +The configuration root stores `auth.json`, the drain request, and temporary files for atomic `gateway_state.json` and `gateway.pid` replacement. +Lockdown moves that directory to `root:sandbox` mode `3770`, which preserves the set-group-ID and sticky bits. +The gateway can still manage its runtime files. +The sticky bit prevents the sandbox identity from unlinking or renaming sealed root-owned configuration. Run the following command to inspect a locked root: ```bash diff --git a/docs/resources/engineer-agentic-documentation.mdx b/docs/resources/engineer-agentic-documentation.mdx index 0ef65298c2..dd3a545985 100644 --- a/docs/resources/engineer-agentic-documentation.mdx +++ b/docs/resources/engineer-agentic-documentation.mdx @@ -400,7 +400,7 @@ agent-variants: ["openclaw", "hermes"] The generator compares this declaration with the source's actual navigation membership and fails when the declaration is missing or differs. An all-variant source omits the declaration, so removing one of its navigation targets also fails until the author restores the route or explicitly declares the narrower scope. -If this source-only guide is added to Fern navigation, it would use the following mapping: +This guide uses the following Fern navigation mapping: | Guide variant | Generated target in `docs/index.yml` | Published route suffix | |---|---|---| @@ -416,10 +416,10 @@ The route suffix above comes from the variant, section, and page slug hierarchy The version entry in `fern/docs.yml` points Fern to `docs/index.yml`. That index defines the navigation and published route tree for every supported agent variant. -An OpenClaw navigation entry for this guide would use the following shape: +The OpenClaw navigation entry for this guide uses the following shape: ```yaml -- page: "Engineer Agentic Docs" +- page: "Engineer Documentation for AI Agents" path: _build/agent-variants/resources/engineer-agentic-documentation.openclaw.generated.mdx slug: engineer-agentic-documentation ``` diff --git a/docs/security/hermes-0.19.0-dependency-review.md b/docs/security/hermes-0.19.0-dependency-review.md index e69ab9929d..573e9506e3 100644 --- a/docs/security/hermes-0.19.0-dependency-review.md +++ b/docs/security/hermes-0.19.0-dependency-review.md @@ -71,7 +71,8 @@ The outgoing release restricted cookies, storage, clipboard, form values, and ne Because NemoClaw exposes the browser toolset, generated configuration now writes `browser.restrict_evaluate: true` to preserve that fail-closed posture; broadening page-context JavaScript evaluation requires a separate security decision. Hermes 0.19 changes the omitted gateway session-reset policy from `both` (daily and idle expiry) to `none`. -Generated configuration now writes the complete outgoing policy—`mode: both`, 04:00 daily reset, 1,440-minute idle reset, notifications except on API server and webhook, and a 24-hour background-process age bound—so the upgrade does not silently make gateway sessions indefinitely durable or leave the remaining policy to mutable dependency defaults. +Generated configuration now writes the complete outgoing policy: `mode: both`, 04:00 daily reset, 1,440-minute idle reset, notifications except on API server and webhook, and a 24-hour background-process age bound. +This prevents the upgrade from silently making gateway sessions indefinitely durable or leaving the remaining policy to mutable dependency defaults. Hermes 0.19 also changes `display.show_reasoning` from `false` to `true`. Generated configuration now writes `display.show_reasoning: false` so internal reasoning is not newly disclosed through user-visible channel output. diff --git a/scripts/check-docs-published-routes.mts b/scripts/check-docs-published-routes.mts index 99a5fc8eab..2ebe0a6cbc 100644 --- a/scripts/check-docs-published-routes.mts +++ b/scripts/check-docs-published-routes.mts @@ -413,6 +413,27 @@ export type RouteViolation = { resolved: string; }; +export type PublishedPageBody = { + route: string; + body: string; +}; + +export function renderPublishedPageBodies( + sourcePath: string, + index: PublishedRouteIndex, + docsDir: string = docsRoot, +): PublishedPageBody[] { + const publishedRoutes = index.sourceToRoutes.get(sourcePath); + if (!publishedRoutes || publishedRoutes.length === 0) { + throw new Error(`${sourcePath} is not a published navigation page in docs/index.yml`); + } + const source = readFileSync(path.join(docsDir, sourcePath), "utf8"); + return publishedRoutes.map((publishedRoute) => ({ + route: publishedRoute.route, + body: renderBodyForPublishedRoute(source, sourcePath, publishedRoute), + })); +} + /** * Validate every internal cross-page link on a docs source page against the * published route map. Returns the links that resolve to no published route. @@ -422,19 +443,14 @@ export function findBrokenPublishedRoutes( index: PublishedRouteIndex, docsDir: string = docsRoot, ): RouteViolation[] { - const publishedRoutes = index.sourceToRoutes.get(sourcePath); - if (!publishedRoutes || publishedRoutes.length === 0) { - throw new Error(`${sourcePath} is not a published navigation page in docs/index.yml`); - } - const source = readFileSync(path.join(docsDir, sourcePath), "utf8"); const violations: RouteViolation[] = []; - for (const publishedRoute of publishedRoutes) { - const body = renderBodyForPublishedRoute(source, sourcePath, publishedRoute); + for (const publishedPage of renderPublishedPageBodies(sourcePath, index, docsDir)) { + const { body } = publishedPage; const links = extractMarkdownLinks(body).filter((link) => isInternalRouteLink(link.target)); for (const link of links) { - const resolved = resolvePublishedRoute(publishedRoute.route, link.target); + const resolved = resolvePublishedRoute(publishedPage.route, link.target); if (!index.routes.has(resolved)) { - violations.push({ sourcePath, fromRoute: publishedRoute.route, ...link, resolved }); + violations.push({ sourcePath, fromRoute: publishedPage.route, ...link, resolved }); } } } diff --git a/test/check-docs-published-routes.test.ts b/test/check-docs-published-routes.test.ts index 62b9cdc535..450b7b8304 100644 --- a/test/check-docs-published-routes.test.ts +++ b/test/check-docs-published-routes.test.ts @@ -10,6 +10,7 @@ import { parse } from "yaml"; import { buildPublishedRouteIndex, + extractMarkdownLinks, findBrokenChangelogRoutes, findBrokenPublishedInferenceRoutes, findBrokenPublishedManageSandboxRoutes, @@ -17,6 +18,7 @@ import { findBrokenPublishedRoutes, findMissingDirectLegacyManageSandboxRedirects, findMissingDirectLegacyReleaseNotesRedirects, + renderPublishedPageBodies, resolvePublishedRoute, } from "../scripts/check-docs-published-routes.mts"; @@ -459,6 +461,59 @@ describe("Manage Sandboxes extension routes", () => { index.routes.has("/user-guide/deepagents/manage-sandboxes/install-openclaw-plugins"), ).toBe(false); }); + + it("publishes the Deep Agents runtime guide only in the Deep Agents guide", () => { + const source = "manage-sandboxes/run-deep-agents-code.mdx"; + const quickstartSource = "get-started/quickstart-langchain-deepagents-code.mdx"; + const quickstartRoute = "/user-guide/deepagents/get-started/quickstart"; + const runtimeRoute = + "/user-guide/deepagents/manage-sandboxes/operate-sandboxes/run-deep-agents-code"; + const [quickstartPage] = renderPublishedPageBodies(quickstartSource, index); + + expect(index.sourceToRoutes.get(source)?.map(({ route }) => route)).toEqual([runtimeRoute]); + expect(findBrokenPublishedRoutes(source, index)).toEqual([]); + expect(findBrokenPublishedRoutes(quickstartSource, index)).toEqual([]); + expect(quickstartPage.route).toBe(quickstartRoute); + expect( + extractMarkdownLinks(quickstartPage.body).map(({ target }) => + resolvePublishedRoute(quickstartRoute, target), + ), + ).toContain(runtimeRoute); + expect( + index.routes.has( + "/user-guide/openclaw/manage-sandboxes/operate-sandboxes/run-deep-agents-code", + ), + ).toBe(false); + expect( + index.routes.has( + "/user-guide/hermes/manage-sandboxes/operate-sandboxes/run-deep-agents-code", + ), + ).toBe(false); + }); + + it("preserves the legacy Deep Agents harness anchor", () => { + const [quickstartPage] = renderPublishedPageBodies( + "get-started/quickstart-langchain-deepagents-code.mdx", + index, + ); + + expect(quickstartPage.body.match(/<\/a>/g)).toHaveLength(1); + }); +}); + +describe("Documentation Engineering routes", () => { + const index = buildPublishedRouteIndex(); + + it("publishes the agentic documentation guide for every agent variant", () => { + const source = "resources/engineer-agentic-documentation.mdx"; + + expect(index.sourceToRoutes.get(source)?.map(({ route }) => route)).toEqual([ + "/user-guide/openclaw/resources/engineer-agentic-documentation", + "/user-guide/deepagents/resources/engineer-agentic-documentation", + "/user-guide/hermes/resources/engineer-agentic-documentation", + ]); + expect(findBrokenPublishedRoutes(source, index)).toEqual([]); + }); }); describe("headless server deployment routes", () => {