Skip to content

Offer the P0 agents' native interfaces: OpenClaw's Control UI, Hermes's dashboard and API, and Deep Agents Code's terminal #14011

Description

@cv

Blocked on NVIDIA/NeMo-Fabric#541, NVIDIA/NeMo-Fabric#540 and NVIDIA/NeMo-Fabric#546, under the epic NVIDIA/NeMo-Fabric#547, whose description holds the P0 specification that defines the settings, paths and access used here; its resolved Q9 makes Hermes's API server use the configured model endpoint and key, which the Hermes API check below depends on. This is the NemoClaw side of #13360 (OpenClaw's dashboard), #13973 (signing in to it) and #13969 (Hermes's interfaces).

Change

As each Fabric adapter ships its interfaces, make them usable from a NemoClaw deployment. Each harness can land on its own.

  • Fabric pin: move FABRIC_REVISION to a revision with the adapter's interfaces, from Fabric or, until Fabric takes them, the reference implementation in cv/NeMo-Fabric, regenerate the bundled catalog, and recheck the pinned OpenClaw image and Hermes revision against what the adapters support.
  • Images:
  • Configuration: harness.settings.interfaces already passes through unchanged. Planning rejects interface names and fields an image's adapter doesn't support, using the descriptor's settings_schema in the image catalog, where P0 adapters list their interfaces under properties.interfaces. This is new work in crates/nemoclaw-fabric/src/capabilities.rs, which today checks adapter presence and filesystem grants, tested with and without an interface declaration in the descriptor. HTTP interfaces need an exact port in the YAML.
  • Access: after apply, tell the person how to reach each enabled interface:
    • forward it with openshell forward service SANDBOX --target-port PORT --local 127.0.0.1:PORT;
    • for interfaces with a token (OpenClaw's Control UI, Hermes's API server), read it from /sandbox/artifacts/.fabric/<adapter>/runtimes/<runtime-id>/interfaces/<name>.token with openshell sandbox exec; NemoClaw prints that command, using the runtime ID in its provider state, never the token itself. Hermes's dashboard has no token or sign-in: the forward is its access control;
    • sign in, for example with OpenClaw's #token= URL;
    • for Deep Agents Code, run the launcher with openshell sandbox exec -n SANDBOX --tty -- /sandbox/artifacts/.fabric/deepagents-code/runtimes/<runtime-id>/interfaces/terminal (or through sh on a noexec mount); openshell sandbox connect attaches to fabric-agent-ctl serve, not a shell. Instructions keep the existing gateway and workspace selection.
  • Health: an interface failure must not make the provider treat the agent as stopped; only the runtime check decides that.
  • Docs: restore the interface sections of docs/interfaces.md, docs/agents.md and docs/limits.md; explain that an interface's token and Deep Agents Code's launcher are readable and writable by the agent's own tools in its sandbox, so the agent can sign in to its own interfaces and use their configuration, cron and plugin features; that Hermes's dashboard has no sign-in, so anyone who can reach its forward can use it, and its browser chat runs without approvals; and that Deep Agents Code's agent server has no authentication; and prefer forward service, which the gateway authorizes, over exposed service URLs.
  • Examples: enable the interfaces in the GTC DC templates once qualified.

Acceptance criteria

  • For OpenClaw and Hermes, a live-docker test applies a deployment with the interface enabled and forwards it with openshell forward service:
    • OpenClaw: Control UI sign-in with the retrieved token succeeds, and a missing or wrong token is rejected.
    • Hermes API server: a request with the retrieved api.token succeeds, and one without it is rejected.
    • Hermes dashboard: the page loads, a dashboard API call succeeds with the session token the page provides, and browser chat works through the forward.
    • A failed Hermes child doesn't change the provider's running result.
  • For Deep Agents Code, a live-docker test runs the launcher with openshell sandbox exec --tty, sends one prompt, and gets a reply produced with the generated configuration; OpenShell's access control is the authentication.
  • Planning rejects an interfaces setting the image's adapter doesn't support.
  • No token appears in YAML, plans, OpenTofu state, NemoClaw's command output or logs, or test artifacts; a person's explicit retrieval command is the intended disclosure.
  • The docs cover enabling, forwarding, token retrieval, sign-in and the token's visibility to the agent.
  • OpenClaw's dashboard is unavailable with the pinned Fabric #13360, Question: how does a user sign in to an OpenClaw dashboard? #13973 and Serve Hermes's API server, dashboard and browser chat once Fabric's Hermes adapter supports them #13969 are closed when their harness's part lands.

Owner

NemoClaw, after each Fabric adapter ships its interfaces.

Activity

  1. added
    enhancementNew capability or improvement request
    area: e2eEnd-to-end tests, nightly failures, or validation infrastructure
    area: integrationsThird-party service integration behavior
    v1NemoClaw v1 branch
    on Oct 30, 2026
  2. self-assigned this
    on Oct 30, 2026
  3. cv commented on Oct 30, 2026

    @cv
    CollaboratorAuthor

    Manual acceptance checklist for the three harnesses. It covers what the live tests can't fully check: a real model, a real browser on a person's machine, an interactive terminal, and one deployment through apply, use, restart and destroy.

    Before starting

    • Build: images and bundle from the combined NemoClaw branches (Fabric pin, interfaces, Deep Agents Code image), on Docker first. Record the NemoClaw commit, Fabric 6cad3504, OpenClaw 2026.9.34, Hermes v0.22.5, dcode 0.2.2 and OpenShell 0.1.6.
    • Deployments: one per harness, with a real model through NemoClaw's usual inference setup:
      • OpenClaw: interfaces.dashboard.port;
      • Hermes: interfaces.api.port and interfaces.dashboard.port;
      • Deep Agents Code: interfaces.terminal and approval_mode: auto.
    • Evidence: keep the commands run, the apply output, browser screenshots, and how long stop and destroy took.

    Every harness

    • Planning: an unknown interface name, an unknown field, and a missing port on an HTTP interface each fail with a NemoClaw error naming the field; a valid configuration plans cleanly.
    • Apply output: for each enabled interface, the human-readable and -o json output show the gateway and workspace selection plus the openshell forward service command for HTTP interfaces, the command that reads the token where there is one, and how to sign in, or for Deep Agents Code, the launcher command.
    • No leaks: the retrieved token's value appears nowhere in the YAML, plan, OpenTofu state, or NemoClaw's output and logs. Reading it with the printed command is the only disclosure.
    • Token file: mode 0600, owned by the sandbox user, and absent when its interface is disabled.
    • Restart: after an apply that restarts the runtime, the runtime ID changes, the printed commands use the new one, the new token works, and the old one is rejected.
    • Destroy: the first nemoclaw destroy succeeds, with no stop_failed and no retry, and no interface processes or forwards remain.

    OpenClaw: Control UI

    • Forwarding the port and opening http://127.0.0.1:PORT/#token=<token> loads the Control UI signed in, and the UI removes the token from the address bar.
    • A chat message in the Control UI gets a reply from the configured model.
    • With no token or a wrong one, the UI doesn't sign in.
    • Forwarding to a different local port also works, since OpenClaw accepts any loopback origin; the token is still required.
    • Only when testing an exposed URL: an origin listed in public_origins is accepted, and an unlisted non-loopback origin is rejected.

    Hermes: API server and dashboard

    • API: GET /v1/models returns 200 with Authorization: Bearer <api.token> and 401 without it. A chat completion returns an answer from the configured model, and the model endpoint's logs show the configured key, with nothing sent to api.openai.com.
    • Dashboard: the forwarded page loads with no sign-in (expected), and browser chat works under the default policy and answers through the configured model.
    • Failure isolation: after killing the dashboard child process in the sandbox, the runtime check passes, plan shows no change, and the API still answers.
    • Stop during a request: with a long API request in flight, destroy or restart finishes within core's 10-second stop limit, the request is cut off, and api.token is gone.

    Deep Agents Code: terminal UI

    • openshell sandbox exec -n SANDBOX --tty -- <launcher path> opens the terminal UI; on a noexec mount, sh <launcher path> also works.
    • A prompt in the terminal UI gets a reply from the configured model, with the key taken from the launching environment.
    • After an invocation through NemoClaw, dcode -r <thread-id> from the launcher opens the runtime's thread with that invocation's messages; the terminal.running marker holds the thread ID.
    • Approval modes: with auto, dcode's classifier decides a gated action and the adapter denies what it escalates; with yolo, the action runs. The outcome matches the docs.
    • After the runtime stops, the launcher refuses with "This NeMo Fabric runtime is not running."

    Documented limitations, not failures

    Record any of these, but don't fail the test for them:

    • files left behind when the adapter process is killed (L7);
    • the Hermes dashboard's gateway actions replacing the gateway and outliving stop;
    • OpenClaw accepting any loopback origin;
    • the agent's own tools reading its tokens and launcher and using its interfaces;
    • dcode's terminal UI starting its own agent server on loopback without authentication.

    Passing

    Every item above passes on Docker with a real model on one platform. Kubernetes (live-kind) and AMD64 can be a second round.

  4. cv commented on Oct 30, 2026

    @cv
    CollaboratorAuthor

    Manual test results for the checklist above. Two items failed and are filed as #14028 and NVIDIA/NeMo-Fabric#567.

    Setup: Linux ARM64 on Docker, with a NemoClaw managed gateway and OpenShell 0.1.6. Deep Agents Code ran from feat/deepagents-code-harness (02a7bd0f9e); OpenClaw and Hermes ran from the interfaces branch beneath it (bdc8055542). Both are on the Fabric pin 6cad3504 (OpenClaw 2026.9.34, Hermes v0.22.5, dcode 0.2.2). The model was nemotron-3.5-super-vl, served by an existing vLLM deployment on the same host through an OpenAI-compatible endpoint. Browser checks used headless Chromium through openshell forward service.

    Every harness

    Check Result
    Planning rejects an unknown interface name or field, including terminal.port Pass
    Planning rejects a missing port Fail: interfaces.api: {} plans with no error (#14028)
    Apply output, human and -o json: forward, token command, sign-in; the launcher command for Deep Agents Code Pass; no token appears
    Token absent from the YAML, state, outputs and gateway logs Pass
    Token file mode and owner Pass: 600, node:node
    Restart rotates tokens Pass. A settings change replaced both sandboxes, as the plan said, and the new runtime IDs and tokens took effect; a new token got 200, none or a wrong one 401
    First destroy succeeds Pass: 13.7 s with a Hermes request in flight, and 6 s for Deep Agents Code, with no stop_failed

    OpenClaw

    • The #token= URL signs in to the Control UI, which removes the token from the address bar, and the model answered a chat message.
    • With no token the UI asks for one; with a wrong one it says it "rejected the supplied Gateway secret".
    • A forward to a different local port (28789) also signs in.

    Hermes

    • API: 200 with api.token, 401 without it or with a wrong one. A chat completion answered in 15 s; it made one request to the configured endpoint, and Hermes's config and logs name only that endpoint, never api.openai.com.
    • Dashboard: loads with no sign-in; its API accepts the page's session token and rejects calls without it.
    • Browser chat answers through the configured model under the image's default policy.
    • After the dashboard child is killed, plan shows no changes and the API still answers.
    • Stop during a request: the first destroy succeeded, and the client got 503 admission_queued ("Your input is saved and will run once when it is back").

    Deep Agents Code

    • The printed openshell sandbox exec --tty command opens the terminal UI, and after skipping the first-run question with Escape, a prompt got an answer from the configured model.
    • The sh form runs the launcher. An actual noexec mount wasn't tested.
    • An invocation through fabric-agent-ctl in the sandbox succeeded on the runtime's ACP session, and <launcher> threads list --json shows that thread with its messages.
    • Resuming the runtime's thread with dcode -r <thread> fails while the runtime runs ("open elsewhere"), and the launcher refuses once it stops ([Bug]: Deep Agents Code's terminal UI can't resume the runtime's thread NeMo-Fabric#567).
    • Approval modes: auto rejected even a read-only id -un, so invocations effectively have no shell, and the adapter denied it without hanging; yolo ran both commands and wrote the file.

    Not covered

    • The launcher refusing after the runtime stops: NemoClaw can't stop a runtime without destroying or replacing its sandbox, which removes the launcher. Fabric's tests cover it.
    • An exact check that the old token is rejected: its value wasn't kept. The new token is freshly generated, and wrong tokens get 401.
    • Kubernetes and AMD64.

    Other observations

    • Hermes's dashboard shows a banner offering to share usage metrics with Nous; nothing is sent unless someone opts in.
    • The live-docker run with every branch took 411 s against its 360 s budget, so the tests need to get faster before merging.

    Both test deployments, their retained gateway storage and the saved test tokens are removed.

  5. cv commented on Oct 31, 2026

    @cv
    CollaboratorAuthor

    Retest after #14036, #14037, #14038, #14024, #14039 and #14042, against the same model endpoint as the first run. OpenClaw and Hermes ran from v1 with #14042's pin (Fabric e7913b6c). Deep Agents Code ran from feat/deepagents-code-harness (ee0adf8960, not yet a PR) on top of that pin. Docker, linux_arm64.

    Fixed since the first run

    OpenClaw and Hermes

    • Apply took 23 s and printed the interface section.
    • Hermes API: 200 with the token, 401 without it.
    • Control UI: #token= signs in and the model answers; a missing or wrong token is rejected.
    • The first destroy succeeded in 8 s, with no stop_failed.

    Deep Agents Code

    • Planning rejects terminal.port.
    • Apply took 16 s and printed the launcher command and its sh fallback.
    • threads list through the launcher shows the runtime's thread; the marker holds its ID.
    • A new terminal UI session answers a prompt with the configured model.
    • auto: the shell tool is blocked, so for the file request the agent used its file tool instead.
    • yolo: id -un returns node, and the shell command writes its file.
    • The first destroy succeeded in 6 s, with no stop_failed.

    Left for the Deep Agents Code PR

    • Rebase: onto v1.
    • Time budget: live-docker took 351.5 s against the 360 s budget on a quiet machine. Folding the terminal test into interfaces_live's gateway is in progress, to add margin.
    • Parallel live tests aren't safe yet: OpenShell names its helper containers openshell-supervisor-extract-<pid>-<seq>, and the gateway is PID 1 in every container, so two gateways starting at once on one engine can collide.
    • One remaining OpenClaw request: it looks up clawhub.ai shortly after answering a prompt, and the sandbox policy denies it. No test fails because of it.
  6. cv commented on Oct 31, 2026

    @cv
    CollaboratorAuthor

    Done in v1: #14036 (Fabric, OpenClaw 2026.9.34 and Hermes v0.22.5 pins), #14037 (OpenClaw's and Hermes's interfaces: planning check, apply output, docs, live test), #14038 (interface settings checked against the descriptor schema, #14028), #14039 and #14042 (OpenClaw's 60 s startup deadline, Kind diagnostics, a failed start's cause, no catalog lookup), and #14043 (the Deep Agents Code image and its terminal UI). Manual results are in the comments above. Follow-ups: NVIDIA/OpenShell#5094 (helper container names collide, which keeps live tests serial) and OpenClaw's remaining clawhub.ai lookup after a prompt, left as is for now.

  7. cv commented on Oct 31, 2026

    @cv
    CollaboratorAuthor

    Demo: OpenClaw's Control UI

    Retest on Fabric 995cc79e, the content of #14044, on Docker (ARM64). The model is nemotron-3.5-super-vl on an existing vLLM deployment on the same host.

    1. Apply prints how to reach the dashboard. It shows the forward and token commands, never the token.

    Apply output for OpenClaw's dashboard

    2. Signing in works. After the forward, opening http://127.0.0.1:18789/#token=TOKEN signs in to the Control UI. OpenClaw removes the token from the address bar, and the model answers a chat message.

    Signed-in Control UI with the model's answer

    3. A wrong token is rejected.

    Control UI rejecting a wrong token

    The first nemoclaw destroy of this deployment (OpenClaw and Hermes) succeeded in 12 s.

  8. cv commented on Oct 31, 2026

    @cv
    CollaboratorAuthor

    Demo: Hermes's API server and dashboard

    Retest on Fabric 995cc79e, the content of #14044, on Docker (ARM64). The model is nemotron-3.5-super-vl on an existing vLLM deployment on the same host.

    1. Apply prints how to reach both interfaces. The API server takes a bearer token; the dashboard has no sign-in.

    Apply output for Hermes's interfaces

    2. The API server requires its token and answers through the configured model. Requests with the token get 200, requests without it get 401.

    API server requests with and without the token

    3. The dashboard loads without signing in, as documented. Hermes shows its own metrics opt-in banner; nothing is shared unless someone chooses to.

    Hermes dashboard

    4. Browser chat answers through the configured model, under the image's default sandbox policy, which now allows the terminal devices it needs.

    Hermes browser chat with the model's answer

  9. cv commented on Oct 31, 2026

    @cv
    CollaboratorAuthor

    Demo: Deep Agents Code's terminal UI

    Retest on Fabric 995cc79e, the content of #14044, on Docker (ARM64). The model is nemotron-3.5-super-vl on an existing vLLM deployment on the same host.

    1. Apply prints how to open the terminal, including the sh form for a noexec mount.

    Apply output for Deep Agents Code's terminal

    2. Fabric invocations run on the runtime's dcode thread. The launcher lists that thread, and the marker file names it.

    Invocation, thread list and marker

    3. The terminal UI opens through openshell sandbox exec --tty and answers with the configured model. It runs as a separate session that shares the runtime's state.

    dcode terminal UI answering a prompt

    The first nemoclaw destroy of this deployment succeeded in 6 s.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area: e2eEnd-to-end tests, nightly failures, or validation infrastructurearea: integrationsThird-party service integration behaviorarea: securitySecurity controls, permissions, secrets, or hardeningenhancementNew capability or improvement requestintegration: dcodeLangChain Deep Code integration behaviorintegration: hermesHermes integration behaviorintegration: openclawOpenClaw integration behaviorv1NemoClaw v1 branch

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions