Orchestration
An agent can spawn sub-agents, start registered workflows, and wait durably for their results; because the engine journals every step, those waits survive restarts and cost nothing while pending. One run coordinates many: a research loop fans out sub-questions, an outreach sequence paces touches over days, a pipeline sweep processes a batch of records.
Sub-agents with agents.spawn
Section titled “Sub-agents with agents.spawn”agents.spawn {agentPage?, instruction, wait?} starts a child run. It is gated (a
sub-agent can do anything an agent can) and claims on its call id so a workflow replay never
double-spawns.
agentPage string?
The agents/ page to run as the child. Absent runs the default agent with the given
instruction.
instruction string
The instruction sent to the child run.
wait boolean?
true blocks durably until the child finishes and appends the child’s terminal status to
the tool result (spawn-and-wait). Omit for background work you gather later.
Children are tracked in ops.run_edges with a depth cap of 3 and 8 children per run,
so a runaway fan-out is bounded structurally. In the run tree
a spawned child renders as a nested subtree under the parent’s spawn row, so you can drill
into a child’s steps, approvals, and observations from the parent’s panel.
Orchestrator tools
Section titled “Orchestrator tools”Every workflow registry exposes the same coordination tools:
| Tool | Gate | What it does |
|---|---|---|
agents.spawn {agentPage?, instruction, wait?} |
gated | Start a child run (see above). |
workflows.start {name, args?} |
gated | Start a registered workflow as a linked child run. |
time.sleep {duration} |
ungated | Durable sleep. On the engine it journals and resumes; outside it, it declines. |
runs.await {runId} or runs.await {runIds:[…]} |
ungated | Wait for one child, or gather up to six background children concurrently. |
runs.gather {runIds:[…]} |
ungated | Wait for up to six of THIS run’s children and return each one’s schema-validated result or an explicit typed error. |
time.sleep and runs.await use durable journaled polling on the WDK engine, so a
three-day wait is a row, not a held process. Outside the engine (the fallback executor),
time.sleep declines and runs.await polls inline up to 60s. A non-loop workflow journals
its own tool executions as standalone tree rows, so you can watch a pipeline sweep step
through its work in the run tree just like an agent loop.
Registered workflows
Section titled “Registered workflows”A definition can set workflow: <name> to run something other than the default
agent-loop. Registered workflows are durable, journaled programs that compose the same
tools and gates as an agent loop:
follow-up-nudge
A gated send, then a durable sleep (default 3 days), then a reply check, then a conditional nudge only if the thread stayed quiet. The canonical “wait days, then act unless something changed” shape.
outreach.sequence
A multi-channel sequence per prospect across email and messaging: intro, connect, nudge if quiet, follow-up. It waits durably between touches, gates every outbound step, logs to CRM, and cancels the remaining steps the moment the prospect replies on any channel. See outreach.
Pipeline sweeps
Batch workflows that step through a set of records or observations. The pattern sweep and eval sweep are sweeps over run telemetry; the same shape drives CRM and ingestion batches.
Research loops
Durable loops that fan out sub-questions, gather child runs, and synthesize. See autoresearch loops.
How it composes
Section titled “How it composes”Because spawns, workflow starts, and waits are all journaled steps, an orchestration is as
durable and inspectable as a single run: restart the server mid-sequence and it resumes from
Postgres, and the whole tree streams live over the run:<id> topic. See the
agent engine for the journal and hook model.