Set Up Task-Specific Sub-Agents

View as Markdown

OpenClaw documents the sub-agent behavior, sessions_spawn tool, agents.list configuration, tool policy, nesting, and auth model in Sub-Agents. Use that page as the source of truth for how OpenClaw sub-agents work.

This page covers the sandbox-specific pieces of a sub-agent setup. It explains where the OpenClaw config lives, where to put per-agent credentials, and which writable workspace path agents should use. It also shows how the Omni VLM demo maps onto those paths.

NemoClaw Sandbox Paths

NemoClaw runs OpenClaw inside an OpenShell sandbox. Use these paths inside the sandbox when you adapt an OpenClaw sub-agent setup:

PathPurpose
/sandbox/.openclaw/openclaw.jsonOpenClaw config, including models.providers, agents.defaults, and agents.list.
/sandbox/.openclaw/.config-hashHash for openclaw.json. Keep it in sync after manual config edits so OpenClaw can detect the updated config.
/sandbox/.openclaw/agents/<agent-id>/agent/auth-profiles.jsonPer-agent provider credentials. Use this when a sub-agent calls an auxiliary provider directly.
/sandbox/.openclaw/workspace/Writable shared workspace path for files the primary agent passes to the sub-agent.
/tmp/gateway.logOpenClaw gateway log. Use it to confirm config reloads and diagnose sub-agent failures.

For file-based tasks, instruct agents to use /sandbox/.openclaw/workspace/. Avoid relying on legacy .openclaw-data paths or read-only OpenClaw paths in delegation instructions.

Omni Vision Sub-Agent Example

The vlm-demo applies the OpenClaw sub-agent pattern to a vision task. It keeps the primary main agent on the normal NemoClaw inference route. It adds a vision-operator sub-agent backed by an Omni vision model.

OpenClaw fieldOmni example value
Primary agentmain
Primary modelinference/nvidia/nemotron-3-super-120b-a12b
Auxiliary providernvidia-omni
Sub-agentvision-operator
Sub-agent modelnvidia-omni/private/nvidia/nemotron-3-nano-omni-reasoning-30b-a3b
Delegation toolsessions_spawn

The sub-agent uses Omni as the specialist model for image tasks. The primary orchestration model remains responsible for conversation, planning, and deciding when to delegate.

Update the Sandbox Config

Finish the Quickstart and start the target sandbox before you run the docker exec commands in this section. These commands run on the host that owns the sandbox containers and discover the running sandbox container from the openshell.ai/sandbox-name Docker label. If you have not created a sandbox yet, onboard one first, such as my-assistant.

Fetch the current OpenClaw config from the sandbox. Patch it with your auxiliary provider and agents.list changes, then upload it. Run the following commands from the host that owns the sandbox containers when you use Docker-driver sandboxes.

Export the Current Config

The container name includes a runtime suffix, so discover it from the OpenShell sandbox label:

$export SANDBOX=my-assistant
$export SANDBOX_CTR=$(docker ps --filter "label=openshell.ai/sandbox-name=$SANDBOX" --format "{{.Names}}" | sed -n '1p')
$if [ -z "$SANDBOX_CTR" ]; then
$ echo "No running sandbox container found for $SANDBOX. Start the sandbox before editing its config."
$ exit 1
$fi
$docker exec --user root "$SANDBOX_CTR" cat /sandbox/.openclaw/openclaw.json > /tmp/openclaw.json

If SANDBOX_CTR is empty, the sandbox is not running on this host. Start the sandbox, confirm that docker ps shows the matching openshell.ai/sandbox-name label, then rerun the export commands before continuing.

Prepare the Updated Config

Create /tmp/openclaw.updated.json with the OpenClaw sub-agent config. For the Omni example, the demo provides vlm-demo/vlm-subagent/openclaw-patch.py. The wrapper reads the key without echoing it and keeps the value out of the child process’s operating-system argument list. Set VLM_DEMO_DIR to the local vlm-demo directory from the demo assets, then run the patch helper.

$export VLM_DEMO_DIR=/path/to/nemoclaw-demos/vlm-demo
$(
> read -rsp "NVIDIA API key: " NVIDIA_API_KEY
> printf '\n'
> export NVIDIA_API_KEY
> python3 -c '
>import os
>import runpy
>import sys
>
>helper = sys.argv[1]
>sys.argv = [helper, os.environ["NVIDIA_API_KEY"]]
>runpy.run_path(helper, run_name="__main__")
>' "$VLM_DEMO_DIR/vlm-subagent/openclaw-patch.py" \
> < /tmp/openclaw.json > /tmp/openclaw.updated.json
>)

The helper reads /tmp/openclaw.json from standard input. It adds the Omni provider and vision-operator entry. It writes the patched config to /tmp/openclaw.updated.json.

For a sub-agent other than the Omni example, copy the exported config to /tmp/openclaw.updated.json. Use cp /tmp/openclaw.json /tmp/openclaw.updated.json. Before uploading the file, add your provider under models.providers and your sub-agent under agents.list. Do not commit /tmp/openclaw.updated.json or any other file that contains a real API key.

Upload the Updated Config

Upload the patched config and refresh the hash. In the default mutable state, this keeps the local hash consistent but does not make it tamper-proof. Use NemoClaw runtime controls when the sandbox needs a hardened config posture after the manual edit.

$docker exec --user root "$SANDBOX_CTR" chmod 644 /sandbox/.openclaw/openclaw.json
$docker exec --user root "$SANDBOX_CTR" chmod 644 /sandbox/.openclaw/.config-hash
$docker exec --user root -i "$SANDBOX_CTR" sh -c 'cat > /sandbox/.openclaw/openclaw.json' < /tmp/openclaw.updated.json
$docker exec --user root "$SANDBOX_CTR" /bin/bash -c "cd /sandbox/.openclaw && sha256sum openclaw.json > .config-hash"
$docker exec --user root "$SANDBOX_CTR" chown sandbox:sandbox /sandbox/.openclaw/openclaw.json /sandbox/.openclaw/.config-hash
$docker exec --user root "$SANDBOX_CTR" chmod 444 /sandbox/.openclaw/openclaw.json
$docker exec --user root "$SANDBOX_CTR" chmod 444 /sandbox/.openclaw/.config-hash

After uploading the config, check /tmp/gateway.log. Confirm that the gateway hot-reloaded the provider or agents.list change:

$nemoclaw "$SANDBOX" logs --since 5m --tail 200
$nemoclaw "$SANDBOX" agents list --json

Expected output:

config change detected; evaluating reload (...)
config hot reload applied (...)

The agents list output should include vision-operator.

Add Sub-Agent Credentials

Put the provider key in the sub-agent auth profile when the auxiliary model uses a provider outside the normal NemoClaw inference route. For the Omni example:

/sandbox/.openclaw/agents/vision-operator/agent/auth-profiles.json

Use the same provider ID that appears in models.providers, such as nvidia-omni. Create /tmp/auth-profiles.json from vlm-demo/vlm-subagent/auth-profiles.template.json. Replace YOUR_NVIDIA_API_KEY_HERE with the provider key. Then upload the file into the sandbox:

$docker exec --user root "$SANDBOX_CTR" mkdir -p /sandbox/.openclaw/agents/vision-operator/agent
$docker exec --user root -i "$SANDBOX_CTR" sh -c 'cat > /sandbox/.openclaw/agents/vision-operator/agent/auth-profiles.json' < /tmp/auth-profiles.json
$docker exec --user root "$SANDBOX_CTR" chmod 600 /sandbox/.openclaw/agents/vision-operator/agent/auth-profiles.json

After uploading the auth profile, make sure the sandbox user owns the sub-agent directory:

$docker exec --user root "$SANDBOX_CTR" chown -R sandbox:sandbox /sandbox/.openclaw/agents/vision-operator

Allow Auxiliary Provider Egress

Update the OpenShell network policy for the binary that makes the request when the sub-agent calls a provider directly. In the Omni demo, the OpenClaw gateway runs as /usr/local/bin/node. The NVIDIA endpoint policy must allow that binary.

Refer to Customize the Network Policy for policy update workflows.

Sub-Agent Gateway Connectivity

Spawned sub-agents connect back to the OpenClaw gateway over WebSocket at OPENCLAW_GATEWAY_URL. Inside the sandbox, this connection runs through the enforced process tree. The OpenShell proxy always blocks loopback destinations in that process tree. NemoClaw points OPENCLAW_GATEWAY_URL at the sandbox’s own interface address, such as ws://10.200.0.2:18790. The base sandbox policy allowlists that endpoint through openclaw_gateway_dialback.

Troubleshoot Dial-Back Failures

The dial-back path is blocked if sessions_spawn returns gateway closed (1006 abnormal closure (no close frame)) and the gateway log shows no connection attempt. Check the following:

  1. OPENCLAW_GATEWAY_URL in the gateway process environment targets the sandbox interface address, not 127.0.0.1.
  2. The active policy allows that address and port. Custom NEMOCLAW_DASHBOARD_PORT or proxy subnet values need a matching openshell policy update.
  3. Do not point the dial-back at 127.0.0.1; the proxy denies loopback regardless of policy.

Add Delegation Instructions

OpenClaw handles sessions_spawn. The primary agent still needs task instructions. Place those instructions in the writable workspace, for example:

/sandbox/.openclaw/workspace/TOOLS.md

The Omni demo includes vlm-demo/vlm-subagent/TOOLS.md. It tells main to delegate image tasks to vision-operator. It tells the sub-agent to read the image path it receives. Adapt that file for other task-specific models.

Demo Assets

Use the vlm-demo repository for runnable Omni assets:

  • vlm-subagent-guide.md for a command-by-command walkthrough.
  • vlm-subagent/openclaw-patch.py for patching openclaw.json.
  • vlm-subagent/auth-profiles.template.json for the sub-agent auth profile.
  • vlm-subagent/TOOLS.md for delegation instructions.

Next Steps

Continue with these resources: