Promise.all,
while, and if to fan out work, collect results, and make decisions.
There is no graph DSL and no separate workflow format. The program is the
orchestration. Swarm adds awaitable collector children, structured results,
bounded concurrency, and progress reporting to that program.
Enable Swarm
Swarm needs no enablement setting. Omittedtools.swarm, an empty object, or
an object that sets only limits all leave Swarm enabled. Code Mode remains
separately opt-in, and normal tool policy still applies. Existing Codex sessions
can retain an older tool catalog; see the
fresh-session guidance below.
To opt out, turn off Settings → Agents & Tools → Labs → Swarm in the
Control UI. The switch saves tools.swarm.enabled: false immediately and
applies to future runs without restarting the Gateway. Or set the boolean
shorthand in openclaw.json:
swarm: { enabled: false } has the same effect while preserving configured
limits. To re-enable Swarm, remove the explicit opt-out, set swarm: true or
swarm: { enabled: true }, or turn the Labs switch back on.
To tune the limits, use object form. These are the defaults; you only need to
include values you want to change:
Numeric values must be positive integers. OpenClaw bounds
maxConcurrent to 1–1000, maxChildrenPerGroup to 1–10000,
maxTotalPerGroup to 1–100000, and waitTimeoutSecondsMax to
1–86400.
You can override Swarm for one configured agent with
agents.entries.*.tools.swarm. Per-agent values merge over the top-level
setting. An agent’s false or { enabled: false } disables Swarm for that
agent; true or { enabled: true } enables it even if globally disabled.
A limits-only per-agent object inherits global enablement, so it does not
re-enable a global false.
Requirements
To use theagents.run, phase, and log guest globals, enable OpenClaw Code
Mode and leave Swarm enabled:
API.read("agents.d.ts"), and Swarm prompt
hints only when its catalog contains the native OpenClaw sessions_spawn
tool and the run’s execution allowlist permits it. An MCP tool with the same
name does not qualify. Tool profiles, allow/deny policy, provider rules, and
sandbox policy can remove the native tool. If the Swarm API is absent, check
Code Mode activation and
Sub-agents.
Code Mode waits for collector results internally; its agents.run() API does
not require the standalone agents_wait tool to be allowed. The
low-level tool flow needs both
sessions_spawn and agents_wait allowed. Enabling Swarm never grants tools
or bypasses policy.
defaultAgentId and per-run agentId values must name a configured target
permitted by the requester’s subagents.allowAgents policy. OpenClaw rejects
an unknown or disallowed target instead of falling back to another agent.
Write a Swarm script
When the requirements are met, Code Mode exposes this guest API:schema, agents.run() resolves to the child’s final text. With a
JSON Schema, it resolves to the value submitted through the child’s
structured_output tool. A failed, killed, timed-out, or schema-invalid child
rejects the promise with a SwarmAgentError. Read the exact generated
declarations and short orchestration idioms from API.read("agents.d.ts")
inside Code Mode.
Use label for a recognizable child name in the dashboard and sidebar. Use
phase in the options to publish a phase immediately before that child
starts, or call phase() when several children belong to the same stage.
log() publishes a short progress note. Progress calls are fire-and-forget;
they do not delay the script if the UI is unavailable.
Fan out in parallel with structured results
This example launches one researcher per topic, waits for all of them, then asks a final child to synthesize their structured reports:Promise.all is the fan-out and fan-in boundary. OpenClaw starts up to
maxConcurrent children for the group and queues the rest in submission
order.
Code Mode separately bounds concurrent guest bridge calls with
tools.codeMode.maxPendingToolCalls (default 16, maximum 128). Swarm
launches, progress notes, and result waits queue automatically when those slots
are full. Queued requests retain their original arguments across snapshot
resumes; stopping the run discards requests that have not been admitted.
maxConcurrent still limits running children, and group child limits still
apply. Raw tool calls do not use this Swarm queue and must remain within the
bridge-call limit.
Loop on a decision gate
Use a boundedwhile loop when each pass decides whether another pass is
needed:
maxTotalPerGroup is the final safety backstop,
not a substitute for a clear stopping condition.
Process the first child that finishes
agents.run() returns an ordinary promise, so Promise.race can react to the
first Code Mode child. For harnesses that call the lower-level tools,
agents_wait provides the same first-completion boundary: it returns as soon
as at least one requested run completes, or when the bounded timeout expires.
See Use Swarm from other harnesses for the
complete drain loop.
How collector children behave
Collector children are ordinary isolated sub-agent sessions with a different completion path. They write a durable collector result for the parent to await instead of announcing or steering a reply back into the parent session. The accepted spawn receipt describes this path: collect the result withagents_wait, or await agents.run() in OpenClaw Code Mode. Do not use
sessions_yield to wait for collectors; they do not send completion notifications.
The target agent resolves in this order:
agentIdon the spawn oragents.run()call.tools.swarm.defaultAgentId.- The requesting agent.
worker agent id; configure one before naming it as the default.
Harden that worker with tools.swarm: false in its per-agent configuration so
it can be spawned but cannot start swarms from its own top-level sessions:
structured_output tool to
the child and validates its payload against the supplied JSON Schema. An
invalid payload gets one corrective nudge. If no payload is submitted, or the
retry still does not validate, the collector completion keeps the child’s raw
text, leaves structured unset, and includes schemaError. The low-level agents_wait
result exposes those fields for explicit recovery logic.
Children are leaves
Swarm children are leaves by default. The universalagents.defaults.subagents.maxSpawnDepth guard prevents a child from spawning
its own children at the default depth of 1. The usual orchestration idiom is
to return work to the parent, not spawn more work from a child:
agents.defaults.subagents.maxSpawnDepth and are discouraged for Swarm.
Group caps, budgets, and observability all assume flat collector groups.
Every child has one admission owner. Announce and interactive children use
agents.defaults.subagents.maxChildrenPerAgent (default 5) and do not count
collector children. Collector children use only maxChildrenPerGroup and
maxTotalPerGroup; they do not consume the per-session child budget. The spawn
depth guard still applies to both modes.
After admission, children above maxConcurrent queue FIFO within their swarm
group, nested inside the global sub-agent lane. These concurrency layers queue
work rather than rejecting it. A collector spawn that exceeds either group cap
is rejected with the relevant config key in the error.
Observe a Swarm
Keep the parent session open in Chat while a swarm is active. The Control UI and native Android, iOS, and macOS chat surfaces show a compact Swarm progress widget between the transcript and composer. In the Control UI, each active collector group appears as a card with a completion count and phase progress segments. Hover over a card or focus it with the keyboard to reveal a list of child names, status icons, and run durations. Native Android, iOS, and macOS chat surfaces show phase-grouped grids of child status markers, capped at 256 markers per phase with an overflow count for additional children. Accessible labels identify each child and its queued, running, done, or failed status. All clients present killed and timed-out children as failed. Each group leaves the widget when none of its children are queued or running, and the widget disappears when no active groups remain. The session sidebar keeps the normal parent/child tree. Expand the parent row to inspect a collector child or open its transcript without losing the swarm hierarchy. Collector results remain waitable until their group is archived. After every member reaches its retention deadline, OpenClaw archives the group’s children as a batch so completed swarms do not remain in the live session tree.Stop a Swarm
Use Stop in the parent chat to cancel a running swarm. A Stop targeting a specific parent run also cancels its associated collector children and their nested descendants. Collector mode changes result delivery, not cancellation scope. Successful cancellation prevents selected queued children from starting as running siblings stop; it does not cancel work from unrelated parent turns. If Stop reports incomplete descendant cancellation, inspect the remaining work on the Tasks page and retry cancellation for those children. A stopped parent alone does not confirm that every child stopped, and a cancellation acknowledgment does not promise instantaneous runtime cleanup. Already-accepted children remain independent when the parent completes normally, yields, or times out. If the parent is no longer active, cancel the child tasks directly. See Sub-agent stopping for exact-run and session-wide Stop scopes.Use Swarm from other harnesses
You can use Swarm without OpenClaw Code Mode. Its core tools are harness-independent: start collector children withsessions_spawn({ collect: true }) and drain them with bounded agents_wait
calls. Both tools must be allowed by the effective tool policy; default-on
Swarm does not add them to a restrictive tool profile or allowlist.
Codex Code Mode automatically exposes eligible dynamic OpenClaw tools under
tools.*. It does not use OpenClaw’s QuickJS guest API or require
tools.codeMode, but tools.swarm must still be enabled. Codex harness
agents_wait calls support the full 600-second timeout.
Codex records its dynamic tool catalog when a native thread starts. A thread
created without agents_wait cannot gain that reader just by enabling Swarm or
upgrading OpenClaw, so collector spawn fields remain unavailable on that thread.
For an ordinary unlocked chat, use /new or /reset to start with current tools.
For a supervised, model-locked Chat,
open the Control UI’s global New Session page and select a concrete
Codex-backed model to start a separate ordinary session. Keep the supervised
Chat intact: /new, /reset, and parent-linked New chat are blocked there.
The new session still needs a tool policy that permits both collector tools.
With the currently supported Codex runtime, dynamic OpenClaw tool results reach
Code Mode as JSON text. Parse each result before reading fields. Codex also
serializes dynamic tool calls, so Promise.all does not submit several
sessions_spawn calls concurrently. Launch collectors in a bounded loop;
already-accepted children can still run while later launches are submitted.
agents_wait call accepts 1–1000 run ids. It returns:
structured data and still have
status: "failed" when the provider or runtime fails afterward. In that case,
error is the authoritative terminal failure. Recovery code should prefer a
nonblank error, then schemaError, then a nonblank result, and finally a
run/status fallback.
Individual failed items do not make a mixed agents_wait poll a top-level tool
error. The poll remains a successful JSON result so callers can process its
completed, pending, and errors arrays independently.
The call returns immediately when any requested child is already complete,
when at least one pending child completes, when no valid pending ids remain,
or when its timeout expires. Completed records are idempotent, so passing an
already-completed run id returns its result again. Only the spawning session
or its authorized parent chain can wait on a collector.
This is bounded long polling, not a busy status loop. Keep passing only the
remaining run ids until pending is empty. Collector mode supports native
OpenClaw sub-agents; it does not support ACP runtime, thread binding, visible
sessions, or persistent session mode.
Limits and roadmap
Swarm v1 runs one-shot collector children; the plannedagents.session() API
will add stateful multi-turn workers. Children currently run on the local
Gateway’s sub-agent lane; cloud placement is planned as an explicit spawn
option. Saved workflow definitions and a graph DSL are not part of Swarm’s
current direction.
Related
- Code Mode for the QuickJS guest runtime and activation rules
- Sub-agents for child policy, isolation, and session behavior
- Multi-agent sandbox tools for per-agent restrictions
- Tools overview for tool profiles and policy routing