Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
fad7a02
feat(onboard): add agents.yaml declarative manifest
laitingsheng Jun 15, 2026
22d8ba0
test(generate-openclaw-config): split agents-manifest cases into focu…
laitingsheng Jun 15, 2026
576e74c
fix(onboard): address CodeRabbit and CodeQL review findings
laitingsheng Jun 15, 2026
317f6c9
docs(reference): list --agents under onboard + setup aliases for cli-…
laitingsheng Jun 15, 2026
7361e69
test(onboard): split --agents lifecycle into focused legacy-command-a…
laitingsheng Jun 15, 2026
9c4110f
Merge remote-tracking branch 'origin/main' into feat/agents-manifest
laitingsheng Jun 15, 2026
5017ed7
fix(onboard): advisor follow-ups, credential denylist, allowAgents co…
laitingsheng Jun 15, 2026
222486f
feat(sandbox): add `nemoclaw <name> agents apply -f <agents.yaml>` verb
laitingsheng Jun 15, 2026
a918593
fix(sandbox): register agents apply in display layout + parity + vari…
laitingsheng Jun 15, 2026
d0191dc
fix(sandbox): treat agents[].tools as rebuild-only in apply
laitingsheng Jun 15, 2026
a740052
docs(reference): sync Hermes variant after agents apply tools warning
laitingsheng Jun 15, 2026
12ea9d7
fix(onboard): catch camelCase secret names in manifest credential scan
laitingsheng Jun 15, 2026
fcdf36f
feat(onboard): gate --agents and agents apply to OpenClaw sandboxes
laitingsheng Jun 15, 2026
ffe4377
fix(sandbox): validate agents manifest ids and paths before live apply
laitingsheng Jun 15, 2026
021a754
Merge branch 'main' into feat/agents-manifest
cv Jun 15, 2026
b920beb
merge(main): resolve PR 5440 conflicts
cv Jun 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ navigation:
- page: "Set Up Task-Specific Sub-Agents"
path: inference/set-up-sub-agent.mdx
slug: set-up-sub-agent
- page: "Declarative Multi-Agent Manifest"
path: inference/declarative-agents-manifest.mdx
slug: declarative-agents-manifest
- section: "Manage Sandboxes"
slug: manage-sandboxes
collapsed: open-by-default
Expand Down
154 changes: 154 additions & 0 deletions docs/inference/declarative-agents-manifest.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
---
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
title: "Declarative Multi-Agent Manifest"
sidebar-title: "Declarative Multi-Agent Manifest"
description: "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."
description-agent: "Documents the `nemoclaw onboard --agents <agents.yaml>` flag and the YAML schema it consumes. Use when users ask how to declare a manager-worker layout, how to give a secondary agent its own model, or how to express OpenClaw's `subagents.allowAgents` from NemoClaw."
keywords:
- "nemoclaw agents.yaml"
- "declarative agents"
- "agents.list bake"
- "manager worker agents"
- "subagents allowAgents"
- "per-agent model"
content:
type: "how_to"
skill:
priority: 30
---
Comment thread
coderabbitai[bot] marked this conversation as resolved.

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>` and NemoClaw embeds the resulting `agents.list` entries, per-agent overrides, and `agents.defaults.subagents` block into `openclaw.json` during the image build.

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

## When To Use This

Use `--agents` when:

- You want a repeatable, GitOps-friendly multi-agent sandbox (manager + workers, or a research / 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 — 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, sets `NEMOCLAW_EXTRA_AGENTS_JSON` for the Dockerfile patcher, and 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.

## Manifest Shape

```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[]` |

The `main` agent is always written first into `agents.list` with `default: true`.
Operators cannot set `default: true` on a secondary agent and cannot 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. See below. |

### Sub-Agent Delegation Block

Both `main.subagents` and `agents[].subagents` use the same shape, which 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. |

`maxSpawnDepth` is **not accepted per-agent** — OpenClaw only honours it on `agents.defaults.subagents`, so the manifest exposes it only under the top-level `defaults` block.

### Multi-Model Sandboxes

When a secondary agent declares its own `model` (or `subagents.model`), NemoClaw widens the baked `models.providers[<onboard-provider>].models[]` array with one entry per unique `provider/model` reference.
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.

## Example: Manager-Worker

```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]
```

What this produces in the baked `openclaw.json`:

- `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 because the runtime startup script provisions them on first boot rather than baking their contents.

For ad-hoc per-agent edits inside an existing sandbox (no rebuild), use the in-sandbox CLI: `nemoclaw <name> agents add|delete|list`.
The manifest path is for fixed, checked-in layouts; the CLI passthrough is for interactive work.
Loading
Loading