{{ expr }} syntax to embed dynamic values in workflow YAML. Expressions are
resolved at node execution time — values from upstream nodes are available once those nodes
complete.
Syntax
Basic placeholder
Default filter
Use| default('value') to supply a fallback. It fires both when the key is missing and when the resolved value is an empty string (""):
JSON-or-default filter
Use| json_or_default('value') when the value should parse as JSON but might not. It returns the fallback when the key is missing, when the value is an empty string, or when the value cannot be parsed as JSON. This covers LLM outputs that return "" or fenced markdown instead of a clean JSON array:
Multiple placeholders per string
Namespaces
inputs.* — Workflow input fields
Resolves against the workflow’s top-level input.
message field is always present. Additional fields defined in input: are also available.
env.* — Environment variables
Reads os.environ at node execution time, not at parse time.
Security note:Unset variables raiseenv.*values are redacted (***) in execution traces. Use env vars for non-sensitive runtime configuration — feature flags, environment names, region identifiers. Never inject secrets or API keys intosystem:orprompt:fields; use HTTPheaders:in tool nodes instead.
InterpolationError. Use a default if the variable is optional:
node_id.output — Canonical node output
Every node (agent, swrm, factory, workflow) writes its primary output to working.{node_id}.output
automatically. Reference it in downstream nodes:
node_id.* — Arbitrary node context access
Any value written to the working dict is accessible by its path:
node_id.agents.agent_id.output — SWRM sub-agent output
Inside a swrm synthesis prompt, each sub-agent’s output is available:
item — Loop iteration value (factory nodes)
Inside a factory node’s inputs: values, {{ item }} refers to the current list element:
{{ item }} outside a factory loop raises InterpolationError.
index — Loop iteration index (factory nodes)
Zero-based position of the current item in the list:
total — Total item count (factory nodes)
The total number of items in the current factory loop. Available in agent prompts, swrm agent prompts, synthesis prompts, and factory inputs: templates:
Error Behaviour
Any unresolvable expression raisesInterpolationError with three attributes:
Example:
| default('fallback') to suppress the error and return a static value instead.
Circular Reference Detection
At workflow load time, SirenSpec scans all prompt templates for{{ node_id.* }} references
and builds a dependency graph. If node A’s prompt references node B and node B’s prompt
references node A, loading raises InterpolationError with namespace="circular_ref".
This check runs automatically in load_workflow() — no configuration needed.
Security
env.*values are never written to execution traces. The trace shows***instead.when:edge conditions use a separate, restrictedeval()namespace — not the interpolation engine.- YAML is loaded with
SafeLoader, so no code can be injected via YAML tags.
Examples
Sequential pipeline with node output chaining
SWRM synthesis referencing sub-agent outputs
Factory node with loop variables
Environment variables for runtime configuration
Useenv.* to inject non-sensitive configuration into prompts — environment names,
feature flags, locale identifiers, and similar non-secret values:
Credentials and API keys must never appear insystem:orprompt:fields. Prompt content can surface in logs, traces, and model context windows. Pass secrets via HTTPheaders:in tool nodes instead: