> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemoclaw/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemoclaw/_mcp/server.

# Declarative Multi-Agent Manifest

> Bake secondary OpenClaw agents into a NemoClaw sandbox image from a checked-in agents.yaml manifest, including per-agent models and OpenClaw-native sub-agent delegation.

NemoClaw can bake a multi-agent OpenClaw layout into a sandbox image from a single checked-in manifest.
Supply the manifest at onboard time with `--agents <path>`.
During the image build, NemoClaw embeds the resulting `agents.list` entries, per-agent overrides, and `agents.defaults.subagents` block into `openclaw.json`.

The schema mirrors OpenClaw's `agents.list[]` field names.
The manifest uses the same keys that appear in [OpenClaw's sub-agents reference](https://docs.openclaw.ai/tools/subagents).

## When to Use This

Use `--agents` when:

* You want a repeatable, GitOps-friendly multi-agent sandbox, such as a manager-worker layout or a research and writing split.
* A secondary agent needs its own model (different size, different capability profile).
* You want OpenClaw's `sessions_spawn` validator to enforce a fixed spawn allowlist, not the broad default.

For a single primary agent on the configured inference route, no manifest is required because the canonical `main` agent is always baked in as the default.

## Invocation

```bash
nemoclaw onboard --agents ./agents.yaml --name my-assistant
```

NemoClaw reads the manifest on the host and sets `NEMOCLAW_EXTRA_AGENTS_JSON` for the Dockerfile patcher.
The build-time validator in `scripts/generate-openclaw-config.mts` is the single source of truth for structured errors.
A malformed manifest fails the image build with a clear error message.

## Define the Manifest

Define the primary and secondary agents in a checked-in YAML manifest.

```yaml
defaults:
  subagents:
    maxSpawnDepth: 2          # optional; OpenClaw allows 1..5

main:                          # optional augments to the canonical "main" agent
  tools:
    profile: minimal
    allow: [read]
  subagents:
    allowAgents: [logs-reader, writer]
    delegationMode: prefer
    requireAgentId: true

agents:                        # required when secondary agents are needed
  - id: logs-reader
    description: "Reads sandbox logs"
    model: nvidia/nemotron-3-nano-30b
    tools:
      allow: [read, exec]
    subagents:
      requireAgentId: true

  - id: writer
    model: nvidia/nemotron-3-super-120b-a12b
    tools:
      allow: [read, write]
```

### Top-Level Fields

| Field                              | Purpose                                                                                      | Bakes Into                                |
| ---------------------------------- | -------------------------------------------------------------------------------------------- | ----------------------------------------- |
| `defaults.subagents.maxSpawnDepth` | Maximum nesting depth for sub-agent spawning. Integer 1..5.                                  | `agents.defaults.subagents.maxSpawnDepth` |
| `main.tools`                       | Per-agent tool policy for the canonical `main` agent.                                        | `agents.list[id=main].tools`              |
| `main.subagents`                   | Sub-agent delegation policy for `main`. Same shape as a secondary agent's `subagents` block. | `agents.list[id=main].subagents`          |
| `agents[]`                         | Secondary agents to append after `main` in `agents.list`.                                    | `agents.list[]`                           |

### Primary Agent

NemoClaw always writes the `main` agent first into `agents.list` with `default: true`.
You cannot set `default: true` on a secondary agent or rename the primary slot.

### Per-Agent Fields

| Field         | Required    | Purpose                                                                                                                    |
| ------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------- |
| `id`          | yes         | Lowercase alphanumeric + `_`/`-`, 1-32 chars, must start with a letter. Cannot be `main`.                                  |
| `workspace`   | auto-filled | Defaults to `/sandbox/.openclaw/workspace-<id>`. Must match the canonical sandbox layout if supplied.                      |
| `agentDir`    | auto-filled | Defaults to `/sandbox/.openclaw/agents/<id>`. Must match the canonical sandbox layout if supplied.                         |
| `tools`       | yes         | `{profile?, allow?, deny?}`. Must declare a non-empty `allow[]` or `deny[]`; secondary agents inherit no tools by default. |
| `description` | no          | Human-readable. Baked verbatim.                                                                                            |
| `model`       | no          | `provider/model` reference. The provider must match the onboard provider; cross-provider manifests are not supported.      |
| `subagents`   | no          | OpenClaw-native sub-agent delegation policy. Refer to the section below.                                                   |

### Configure Sub-Agent Delegation

Both `main.subagents` and `agents[].subagents` use the same shape.
That shape mirrors OpenClaw's [`agents.list[].subagents`](https://docs.openclaw.ai/gateway/config-agents).

| Field            | Type                      | Purpose                                                                                                                      |
| ---------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `delegationMode` | `"suggest"` or `"prefer"` | Prompt-only steering for how strongly this agent should delegate. No enforcement.                                            |
| `allowAgents`    | `string[]`                | Allowlist of agent ids this agent may target via `sessions_spawn`. `["*"]` allows any configured target; omit for self-only. |
| `model`          | `provider/model`          | Default model for spawned sub-agents. Provider must match the onboard provider.                                              |
| `thinking`       | string                    | Default thinking level for spawned sub-agents.                                                                               |
| `requireAgentId` | boolean                   | Force the model to pass `agentId` explicitly to `sessions_spawn` rather than defaulting to self.                             |

OpenClaw only honors `maxSpawnDepth` on `agents.defaults.subagents`, so the manifest exposes it only under the top-level `defaults` block.
Do not set `maxSpawnDepth` per agent.

## Configure Multiple Models

When a secondary agent declares its own `model` or `subagents.model`, NemoClaw adds each unique `provider/model` reference to the baked `models.providers[<onboard-provider>].models[]` array.
The base `contextWindow`, `maxTokens`, `reasoning`, and `input` settings from the onboard route apply to each appended entry.
Per-model overrides beyond these defaults are out of scope for v1.
Edit the generated `openclaw.json` in place if you need finer control.

## Create a Manager-Worker Layout

Use the following manifest to let `main` delegate log-reading tasks to a dedicated secondary agent.

```yaml
defaults:
  subagents:
    maxSpawnDepth: 2

main:
  subagents:
    allowAgents: [logs-reader]
    delegationMode: prefer
    requireAgentId: true

agents:
  - id: logs-reader
    description: "Reads /var/log and surfaces error lines"
    tools:
      allow: [read]
```

This manifest produces the following baked `openclaw.json` configuration:

* `agents.list[0]` is `main` with `default: true`, the operator-supplied `tools`/`subagents` merged in.
* `agents.list[1]` is `logs-reader` at the canonical workspace/agentDir paths.
* The primary model stays whatever was selected at onboard.
* `agents.defaults.subagents.maxSpawnDepth` is `2`.
* `sessions_spawn` from `main` resolves to `logs-reader` only.

## Iterating

Edit `agents.yaml`, re-run `nemoclaw onboard --agents ./agents.yaml --recreate-sandbox`.
Workspaces under `/sandbox/.openclaw/workspace-<id>` are preserved across rebuilds.
The runtime startup script provisions them on first boot rather than baking their contents.

For ad-hoc per-agent edits inside an existing sandbox without a rebuild, use the in-sandbox CLI, `nemoclaw <name> agents add|delete|list`.

Use the manifest for fixed, checked-in layouts.
Use the CLI passthrough for interactive work.

## Apply to an Existing Sandbox

`nemoclaw <name> agents apply -f <agents.yaml>` reconciles the live sandbox roster against the manifest without a rebuild.
The command lists current agents with `openclaw agents list --json`.
It compares the current roster with the manifest and runs `openclaw agents add|delete` for each difference.

Per-agent `model`, `subagents.*`, top-level `defaults`, and `main` overrides require a sandbox rebuild.
The command reports those unsupported live changes as warnings before it exits.
Re-run `nemoclaw onboard --agents <file> --recreate-sandbox` to bake them.

```bash
nemoclaw my-assistant agents apply -f ./agents.yaml --yes
```

The `--yes` and `--non-interactive` flags are required for scripted use.
The `--yes` flag confirms the printed roster diff.
The `--non-interactive` flag makes the command fail fast when `--yes` is absent rather than waiting for an interactive prompt that a script cannot answer.

## Next Steps

Continue with these resources:

* Refer to [OpenClaw Sub-Agents](https://docs.openclaw.ai/tools/subagents) for the runtime semantics of `sessions_spawn`, `subagents.allowAgents`, and nesting depth.
* Refer to [Set Up Task-Specific Sub-Agents](set-up-sub-agent) for the in-sandbox path that edits `agents.list` directly without a rebuild.
* Refer to [Switch Inference Providers](../inference/manage-inference/switch-providers) before swapping the primary onboard provider because per-agent `model` refs must share that provider.
* Refer to [Workspace Files](../manage-sandboxes/workspace-files) to understand how per-agent `workspace-<id>` directories are provisioned and persisted across rebuilds.