Skip to main content

Overview

A factory node generates its instances at runtime rather than at authoring time. Where a swrm node has a static, author-defined set of agents, a factory decides how many instances to spawn based on a list resolved during execution — one instance per item, or a fixed count. Every instance runs in parallel (bounded by concurrency), and all outputs are collected into a list written to a single context path.

Execution modes

A factory node has three mutually exclusive modes, determined by which fields you set.
ModeRequired fieldsSpawnsLoop variables
Agent + for_eachagent, for_eachOne agent call per list item{{ item }}, {{ index }}, {{ total }}
Agent + swarm_sizeagent, swarm_sizeN identical agent calls on the same input{{ index }}, {{ total }} (no {{ item }})
Swrm + for_eachswrm, for_eachOne full swrm (parallel specialists + optional synthesis) per list item{{ item }}, {{ index }}, {{ total }}

Mode 1 — Agent + for_each

One call to a named agent for each element in a runtime list.

Mode 2 — Agent + swarm_size

N identical calls to the same agent on the same input — useful for sampling multiple candidate responses.
swarm_size accepts a static integer or a template expression (e.g. "{{ inputs.count }}").

Mode 3 — Swrm + for_each

One full swrm — parallel specialist agents with an optional synthesis step — per list item.

Node fields

FieldRequiredTypeDefaultDescription
typeYes"factory"Node type discriminator.
agentOne of agent / swrmstringNamed agent from the workflow’s top-level agents map. Mutually exclusive with swrm.
swrmOne of agent / swrmobjectInline swrm spec (agents, optional synthesis, optional concurrency) executed per item. Mutually exclusive with agent.
for_eachOne of for_each / swarm_sizestringTemplate expression resolved to a list at runtime. Accepts a native Python list, a JSON array string, or a fenced ```json block. Mutually exclusive with swarm_size.
swarm_sizeOne of for_each / swarm_sizeint or stringStatic count or template expression for parallel agent instances. Only valid in agent mode.
inputsNoobject{}Template strings for each input. Supports {{ item }}, {{ index }}, {{ total }}. Each resolved key is also exposed to the spawned agent’s prompt as {{ inputs.<key> }}.
concurrencyNointeger1Maximum parallel worker instances.
timeout_per_instanceNointeger60Per-instance timeout in seconds.
on_failureNo"abort" | "continue""abort"abort raises FactoryNodeError; continue skips the failed instance and keeps the rest.
writesYesstringDot-notation path where the list of instance outputs is stored.

Loop variables

Inside inputs: templates, agent prompts, and swrm agent/synthesis prompts, three special variables are available:
VariableAvailabilityTypeDescription
{{ item }}for_each mode onlyanyThe current list element.
{{ index }}All modesintZero-based position in the list.
{{ total }}All modesintTotal number of items.
Each key under inputs: is additionally available in the spawned agent’s system prompt as {{ inputs.<key> }} once resolved — so inputs: { task: "{{ item }}" } makes {{ inputs.task }} reference the current item inside the agent’s prompt.
When for_each points at an LLM output that may emit prose, an empty string, or a fenced ```json block instead of a clean array, wrap it with | json_or_default('[]') so a bad response falls back to an empty list rather than failing the run. See Interpolation.

Output shape

All instance outputs are collected, in list order, and written to the writes path:
In Swrm + for_each mode, each entry is that item’s swrm result — the synthesis output when synthesis is defined, otherwise the list of agent outputs. Reference the collected list downstream like any other context value:

Failure handling

on_failureBehaviour
abort (default)The first failing instance raises FactoryNodeError and the workflow stops.
continueThe failing instance is recorded in the trace and skipped; the remaining instances still contribute to the output list.
FactoryNodeError is importable from sirenspec.exceptions:

When to use a factory

Use a factory when:
  • The number of work items is unknown until runtime (e.g. a planner agent emits a task list).
  • You want N independent samples of the same prompt (swarm_size).
  • Each item needs a full committee-of-experts review (Swrm + for_each).
Use something else when:
  • The set of agents is fixed and known up front — use swrm.
  • Items must share intermediate state or run in sequence — use ordinary nodes with edges.

Cookbook recipes

See the YAML Reference for the full field-by-field listing.