id — and how later nodes read earlier results with {{node_id.field}} references.
For the engine that compiles and runs these nodes (the state graph, the run state, edges, and loops), see Workflow engine & nodes. For the cross-node data flow in depth, see Variables & references.
The nine node types
These are the canonicalNodeType values. The string in the first column is the exact type you set on a node — there is no other set, and an unknown value raises Unsupported node type.
Pick a node by intent
Use the decision guide below if you are not sure which type fits a step. Each node’s own page documents every parameter, input, output, error, and credit impact in full.
The output-to-state convention
Every node writes its result into the run state under a key equal to its own nodeid. There is no separate “output name” to wire up — the node id is the output key.
If a node with id: "node_summary" produces the string "Quarterly revenue rose 12%.", then after that node runs the state contains:
- When the graph is compiled, one state field is added per node id (typed
Any) so each node’s output streams back into state correctly. - Each node’s executor returns a single-key dict of the form
{node_id: result}. The node id is the only output key.
result depends on the node type — a string for a simple LLM node, an object for a Tool node, a list of chunks plus context for a Knowledge node, and so on. Each node page documents its exact result shape under “Output”. A few nodes write a structured envelope rather than a bare value, which you reference by sub-path:
Referencing earlier results: {{node_id.field}}
Later nodes read earlier results with the template syntax {{node_id.path}}. This is the single mechanism for passing data between nodes — there are no explicit input wires beyond the graph edges.
How resolution behaves:
- A value that is exactly one reference (for example
{{node_search.results}}) resolves to the native typed value — a list stays a list, a number stays a number. - A reference inside a larger string (for example
Summarize: {{node_search.title}}) is substituted into the string; non-string values are JSON-encoded into the text. - The path supports dot and bracket access:
{{node_abc.results[0].title}}reads thetitleof the first item ofnode_abc’sresults. - An unresolved or out-of-range path resolves to
null(and an unresolved reference left in a template string is kept intact, not blanked). - In a list, an item written as
{{...node_id.path}}(note the leading...) is a spread: if it resolves to a list, its items are spliced into the surrounding list; a scalar or object is appended;nullcontributes nothing.
{{...}}.
Reference patterns
The same
{{node_id.field}} syntax is what the AI Composer writes when it wires nodes together for you, and what the canvas shows in field pickers. See Variables & references for the full resolution rules, reducers, and the run state model.What every node shares
These fields exist on every node regardless of type. They are set on the node itself, not inside the type-specific config.string
required
Unique node identifier. This is also the key its output is written under in run state (see the output-to-state convention above). Referenced elsewhere as
{{id.field}}.string
required
One of the nine node types:
llm, tool, agent, function, conditional, interrupt, transformer, guardrails, knowledge. Any other value raises Unsupported node type at compile time.string
Human-readable label shown on the canvas. Optional.
string
What the node does. Optional, display only.
boolean
default:"true"
Whether the node runs. A disabled node is skipped at execution time and its edges are rewired to the next enabled target, but it remains visible in the workflow definition.
null is treated as true.object
Per-node retry policy. Applies to every node type except
interrupt, which is never retry-wrapped (pausing for a human is not a retriable failure). See the fields below.llm_config, tool_config, agent_config, function_config, conditional_config, interrupt_config, transformer_config, guardrails_config, or knowledge_config — documented in full on that node’s page. (The builder also accepts a wrapped {config: {...}} form and normalizes it to the type-specific key.)
How a node fails
When a node raises after exhausting its retries, the run emits anode_error event and the run stops. The error carries a machine-readable reason — for example credit_exhausted when the billing gate stops a managed call mid-run — so a client can match it deterministically. See Error handling & retries for retry behavior and debugging, and Errors & status codes for the envelope shapes returned by the run surface.
Credit impact
There is no flat per-node credit charge. Credits are metered inline based on what a node actually does:llmandagentnodes, and the LLM call inside aconditionalnode’s LLM routing, record credit usage per call from the model’s input and output tokens. The agent node records usage on every iteration of its loop.knowledgenodes consume credits only when retrieving from the managedmodulexdbstore — a retrieval base plus the query-embedding cost. Bring-your-own-vector-store providers (Qdrant, Pinecone, Weaviate, MongoDB Atlas) are not metered by ModuleX.tool,function,transformer,conditional(expression),guardrails, andinterruptnodes do not themselves consume credits. Atoolnode may incur cost at the connected provider, but ModuleX does not meter it.
How to pick a node
I need to call a language model
I need to call a language model
Use an LLM node for a single, deterministic model call — one prompt in, one answer out, optionally constrained to a JSON schema. Reach for an Agent node only when the model must decide which tools to call and loop until it is done; an agent costs more credits because it records usage on every iteration.
I need to call an external service
I need to call an external service
Use a Tool node to call one integration tool with values you control (it honors both
parameter_defaults and parameter_overrides). Use a Function node for a raw HTTP request, an outbound webhook, or schema validation without an integration. Let an Agent node call tools only when the model should choose them.I need company knowledge or RAG context
I need company knowledge or RAG context
Use a Knowledge node to retrieve chunks from a knowledge base, then feed
{{node_id.context}} into a downstream LLM node prompt.I need to reshape or combine data
I need to reshape or combine data
Use a Transformer node for string, object, array, type, date, and math operations — picking fields, mapping a list, parsing JSON, formatting a date, and so on — without writing code.
I need to branch or loop
I need to branch or loop
Use a Conditional node: an expression branch for deterministic routing, an LLM decision for fuzzy routing, or a loop (
for / foreach / while) to iterate over data.I need to validate or sanitize content
I need to validate or sanitize content
Use a Guardrails node to check content against a JSON schema or regex, detect and mask PII, then block, warn, transform, or route on failure.
I need a human to approve or supply input
I need a human to approve or supply input
Use an Interrupt node. It pauses the run and waits for a structured answer that you resume with — see Human-in-the-loop resume.
Worked example: a three-node retrieve-and-summarize flow
This example chains a Knowledge node, an LLM node, and a Guardrails node. It shows the output-to-state convention and{{node_id.field}} references end to end. Each node writes under its own id; the next node reads it by reference.
1
Retrieve context from a knowledge base
node_kb queries the managed store and writes {total_results, chunks, context} under node_kb. The query itself is a reference to the run input.2
Summarize with an LLM
node_summary reads {{node_kb.context}} into its user prompt and writes the model’s answer under node_summary.3
Validate the answer
node_guard checks {{node_summary}} for PII and writes its validation envelope under node_guard, blocking the run if a check fails.Workflow nodes (excerpt)
object
The Knowledge node’s result.
string
The LLM node’s answer — written directly under the node id as a string.
object
The Guardrails node’s validation envelope.
Run it
Run the workflow over the API or an SDK. Streaming the run lets you watch eachnode_update arrive — one per node, keyed by node with the per-node output — followed by done. See Run via API and SSE run streaming for the full event taxonomy.
Per-node references
Each node’s page documents every config field with its type, default, and required/optional flag, every input it reads, the exact shape it writes, every error it can raise, and its credit impact.LLM node
Call a model with prompts and optional structured output.
Agent node
A model-plus-tools loop that runs until done.
Tool node
Call one integration tool deterministically.
Knowledge node
Retrieve RAG context from a knowledge base.
Function node
HTTP request, webhook, or schema validation.
Transformer node
Reshape, map, filter, and convert data.
Conditional node
Branch on expressions or LLM decisions, or loop.
Guardrails node
Validate content and block, warn, transform, or route.
Interrupt node
Pause for a human answer, then resume.
Related
Workflow engine & nodes
How nodes compile into a graph, the run state, edges, and loops.
Variables & references
The full
{{node_id.field}} resolution rules, reducers, and run state.Error handling & retries
How node failures surface and how retries behave.
Glossary
Canonical ModuleX terminology, including every node term.