Overview
Afactory 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.| Mode | Required fields | Spawns | Loop variables |
|---|---|---|---|
Agent + for_each | agent, for_each | One agent call per list item | {{ item }}, {{ index }}, {{ total }} |
Agent + swarm_size | agent, swarm_size | N identical agent calls on the same input | {{ index }}, {{ total }} (no {{ item }}) |
Swrm + for_each | swrm, for_each | One 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
| Field | Required | Type | Default | Description |
|---|---|---|---|---|
type | Yes | "factory" | — | Node type discriminator. |
agent | One of agent / swrm | string | — | Named agent from the workflow’s top-level agents map. Mutually exclusive with swrm. |
swrm | One of agent / swrm | object | — | Inline swrm spec (agents, optional synthesis, optional concurrency) executed per item. Mutually exclusive with agent. |
for_each | One of for_each / swarm_size | string | — | Template 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_size | One of for_each / swarm_size | int or string | — | Static count or template expression for parallel agent instances. Only valid in agent mode. |
inputs | No | object | {} | Template strings for each input. Supports {{ item }}, {{ index }}, {{ total }}. Each resolved key is also exposed to the spawned agent’s prompt as {{ inputs.<key> }}. |
concurrency | No | integer | 1 | Maximum parallel worker instances. |
timeout_per_instance | No | integer | 60 | Per-instance timeout in seconds. |
on_failure | No | "abort" | "continue" | "abort" | abort raises FactoryNodeError; continue skips the failed instance and keeps the rest. |
writes | Yes | string | — | Dot-notation path where the list of instance outputs is stored. |
Loop variables
Insideinputs: templates, agent prompts, and swrm agent/synthesis prompts, three special variables are available:
| Variable | Availability | Type | Description |
|---|---|---|---|
{{ item }} | for_each mode only | any | The current list element. |
{{ index }} | All modes | int | Zero-based position in the list. |
{{ total }} | All modes | int | Total number of items. |
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.
Output shape
All instance outputs are collected, in list order, and written to thewrites path:
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_failure | Behaviour |
|---|---|
abort (default) | The first failing instance raises FactoryNodeError and the workflow stops. |
continue | The 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).
- 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
- Changelog Annotator — agent +
for_each - GitHub Issues Triage — agent +
for_each - Grading Factory — swrm +
for_each