Skip to content

Nodes

A Node is a unit of work that is executed by the graph. It can be a single agent, a tool, a router, or any other type of node.

FieldTypeDescription
idstringThe ID of the node.
typestringThe type of the node.
agent_idstringThe ID of the agent to run (agent, supervisor, synthesizer nodes).
tool_idstringThe tool to execute (tool nodes).
toolsArray<ToolSource>Tool sources for this node. Overrides agent config tools when set.
subgraph_idstringThe ID of the graph to embed (subgraph nodes).
subgraph_configSubgraphConfigInput/output mapping and iteration limits (subgraph nodes).
supervisor_configSupervisorConfigManaged nodes and iteration limits (supervisor nodes).
approval_configApprovalGateConfigApproval type, review keys, and timeout (approval nodes).
map_reduce_configMapReduceConfigWorker node, items path, concurrency, and error strategy (map nodes).
voting_configVotingConfigVoter agents, aggregation strategy, and quorum (voting nodes).
annealing_configAnnealingConfigSelf-annealing iterative refinement (agent nodes).
swarm_configSwarmConfigSwarm peer delegation (agent nodes).
evolution_configEvolutionConfigPopulation size, fitness evaluation, and selection strategy (evolution nodes).
verifier_configVerifierConfigVerification predicate — LLM judge, expression, or JSONPath assertion (verifier nodes).
reflection_configReflectionConfigSource keys, extractor variant, and tags for compound learning (reflection nodes).
memory_queryMemoryQueryPer-node retrieval directive. When set, the runner calls memoryRetriever before building the agent / supervisor prompt and renders results into a ## Relevant Memory section.
read_keysArray<string>The keys to read from the state.
write_keysArray<string>The keys to write to the state.
failure_policyFailurePolicyThe failure policy for the node.
budgetNodeBudgetPer-node resource caps (max_tokens, max_cost_usd). Breaching either throws NodeBudgetExceededError.
requires_compensationbooleanWhether the node requires compensation.
TypeDescription
agentRuns an LLM with tools via streamText. The workhorse of the system.
toolExecutes a specific MCP tool directly, without an LLM.
routerEvaluates a state expression and routes to the matching target node.
supervisorLLM-powered dynamic routing — delegates to managed nodes iteratively.
approvalPauses the workflow for human review. Resumes when approved or rejected.
mapFans out work to parallel workers (one per item).
synthesizerMerges parallel outputs into a single result using an LLM agent.
votingMultiple agents vote on a decision to reach consensus.
subgraphDelegates to a nested graph with isolated state. Input/output mapping between parent and child.
evolutionPopulation-based selection — runs N candidates, scores fitness, breeds next generation.
verifierGates a target memory key against a verification predicate (LLM judge, filtrex expression, or JSONPath assertion).
reflectionDistills source memory keys into atomic facts and persists them via memoryWriter — feeds future runs of the graph that declare a matching memory_query.

Nodes declare which state keys they can read and write. Both default to [] (least privilege) — a node that omits read_keys sees only goal and constraints, and one that omits write_keys can write nothing. Opt into exactly what each node needs:

read_keys: ['goal', 'notes'] — the node sees only these keys from memory (plus goal/constraints, which are always available)
write_keys: ['draft'] — the node can only write to these keys
read_keys: ['*'] / write_keys: ['*'] — allow all memory access. validateGraph emits a warning for any node using ['*'] reads, since it defeats state slicing; reserve it for nodes that genuinely need every prior output (e.g. a final summarizer).

This enforces the principle of least privilege — a writer agent can’t read database credentials, and a researcher can’t overwrite the final draft. Because the default is [], a node that consumes an upstream node’s output must declare it: a writer reading research notes needs read_keys: ['notes'], not the implicit full access of earlier versions.

Nodes can opt into compensation for rollback support by setting requires_compensation: true. If the workflow fails after a compensatable node completes, the orchestrator executes the compensation_stack in reverse order — unwinding side effects like a database transaction rollback.

Controls retry behaviour when a node fails. Applied per-node.

FieldTypeDefaultDescription
max_retriesnumber3Maximum retry attempts before the node fails permanently.
backoff_strategy'linear' | 'exponential' | 'fixed''exponential'Delay growth between retries.
initial_backoff_msnumber1000Initial delay between retries (ms).
max_backoff_msnumber60000Maximum delay cap (ms).
timeout_msnumberPer-node execution timeout (ms).
circuit_breakerobjectTrip after repeated failures, auto-recover via half-open probes.

Caps a single node’s resource consumption. Useful for guarding against a runaway annealing loop or an oversized LLM reflection extraction eating the whole workflow budget.

FieldTypeDefaultDescription
max_tokensnumberCap on tokens used by this node’s execution.
max_cost_usdnumberCap on USD spent by this node’s execution.

Breaching either cap throws NodeBudgetExceededError and stops the workflow immediately — no retry, since a retry would just compound the spend. Workflow-level budgets (WorkflowState.budget_usd, max_token_budget) remain enforced independently.

{
id: 'reflect',
type: 'reflection',
read_keys: ['notes'],
write_keys: ['reflect_reflection'],
reflection_config: { /* … */ },
budget: {
max_tokens: 20_000,
max_cost_usd: 0.10,
},
}

Optional. Prevents repeatedly calling a failing external service.

FieldTypeDefaultDescription
enabledbooleanfalseWhether the circuit breaker is active.
failure_thresholdnumber5Consecutive failures before the circuit opens.
success_thresholdnumber2Consecutive successes to close the circuit.
timeout_msnumber60000Half-open probe timeout (ms).

Each node type has an optional config block that controls its behaviour. These are set as top-level fields on the node object (e.g. supervisor_config, subgraph_config).

Used by supervisor nodes. The supervisor LLM dynamically routes work between managed sub-nodes until a completion condition is met or the iteration limit is reached.

FieldTypeDefaultDescription
agent_idstringAgent ID for the routing LLM. Falls back to node.agent_id if omitted.
managed_nodesstring[]requiredNode IDs this supervisor can delegate to.
max_iterationsnumber10Max routing iterations before forced completion (loop guard).
completion_conditionstringJSONPath expression that, when truthy, signals completion.

Used by subgraph nodes. Executes an entire nested workflow as a single step, with isolated state and explicit memory mapping.

FieldTypeDefaultDescription
subgraph_idstringrequiredID of the graph to embed (loaded via loadGraphFn).
input_mappingRecord<string, string>{}Maps parent memory keys → child memory keys.
output_mappingRecord<string, string>{}Maps child memory keys → parent memory keys.
max_iterationsnumber50Iteration cap for the child workflow.

The child gets a fresh, isolated WorkflowState. Only mapped keys cross the boundary. The child inherits the parent’s remaining token budget. A _subgraph_stack prevents cyclic nesting (e.g. A → B → A throws immediately).

Used by approval nodes. Pauses execution until a human reviewer approves or rejects.

FieldTypeDefaultDescription
approval_type'human_review''human_review'Type of approval required.
prompt_messagestring'Please review and approve this workflow step.'Message shown to the reviewer.
review_keysstring[]['*']Memory keys the reviewer should see.
timeout_msnumber86400000 (24h)Timeout before auto-rejection.
rejection_node_idstringNode to route to on rejection. If unset, the workflow fails.

Used by map nodes. Fans out work to parallel workers, then optionally fans in via a synthesizer.

FieldTypeDefaultDescription
worker_node_idstringrequiredNode ID of the worker to fan out to.
items_pathstringJSONPath to extract the items array from memory.
static_itemsunknown[]Static items array (alternative to items_path).
synthesizer_node_idstringNode ID of the synthesizer to fan results into.
error_strategy'fail_fast' | 'best_effort''best_effort'How to handle worker errors.
max_concurrencynumber5Maximum concurrent workers.

Used by voting nodes. Multiple agents vote independently and a strategy aggregates the results.

FieldTypeDefaultDescription
voter_agent_idsstring[]requiredAgent IDs that will vote (min 1).
strategy'majority_vote' | 'weighted_vote' | 'llm_judge''majority_vote'Aggregation strategy.
vote_keystring'vote'Memory key where each voter writes their vote.
quorumnumberMinimum votes required for a valid result.
judge_agent_idstringAgent ID for the llm_judge strategy.
weightsRecord<string, number>Per-agent weights for weighted_vote.

Used by agent nodes for iterative self-refinement. Progressively lowers the LLM temperature and re-evaluates until a quality threshold is met.

FieldTypeDefaultDescription
evaluator_agent_idstringAgent ID for the evaluator. Falls back to score_path extraction.
score_pathstring'$.score'JSONPath to extract a numeric score from agent output.
thresholdnumber0.8Quality threshold (0–1) to stop iteration.
max_iterationsnumber5Maximum annealing iterations.
initial_temperaturenumber1.0Starting LLM temperature.
final_temperaturenumber0.2Ending temperature (converges toward this).
diminishing_returns_deltanumber0.02Stop if score improvement is less than this delta.

Used by agent nodes in swarm mode. Peer agents hand off work to each other until the task is complete.

FieldTypeDefaultDescription
peer_nodesstring[]requiredNode IDs of peer agents in the swarm.
max_handoffsnumber10Maximum handoffs before forcing completion.
handoff_mode'agent_choice''agent_choice'How peers are selected for handoff.

Used by evolution nodes. Population-based optimization — generates N candidates, scores fitness, selects the best, and breeds the next generation.

FieldTypeDefaultDescription
population_sizenumber5Number of candidates per generation (min 2).
candidate_agent_idstringrequiredAgent that generates candidate solutions.
evaluator_agent_idstringrequiredAgent that scores fitness.
selection_strategy'rank' | 'tournament' | 'roulette''rank'How parents are selected.
elite_countnumber1Top candidates preserved unchanged across generations.
max_generationsnumber10Maximum number of generations.
fitness_thresholdnumber0.9Fitness score (0–1) for early exit.
stagnation_generationsnumber3Stop if no improvement for this many generations.
initial_temperaturenumber1.0Starting temperature (diversity).
final_temperaturenumber0.3Ending temperature (exploitation).
tournament_sizenumber3Tournament size for tournament strategy.
max_concurrencynumber5Max concurrent candidate evaluations.
error_strategy'fail_fast' | 'best_effort''best_effort'How to handle candidate generation errors.
evaluation_criteriastringCustom instruction passed to the fitness evaluator.

Used by verifier nodes. Gates a target memory key against a verification predicate. Three flavours via a discriminated union on type:

FieldTypeDefaultDescription
target_keystringrequiredMemory key whose value is evaluated.
evaluator_agent_idstringrequiredAgent ID for the LLM-as-judge evaluator.
pass_thresholdnumber0.8Pass when the evaluator’s score (0–1) is ≥ this threshold.
evaluation_criteriastringCustom instruction passed to the evaluator.
FieldTypeDefaultDescription
expressionstringrequiredFiltrex expression evaluated against { memory, goal }. Passes when truthy.
FieldTypeDefaultDescription
target_keystringrequiredMemory key whose value is queried.
pathstringrequiredJSONPath expression against memory[target_key].
assertionJsonPathAssertionrequiredOne of exists, equals, matches, gt, gte, lt, lte.
FieldTypeDefaultDescription
result_keystring{node.id}_verificationMemory key the structured result envelope is written to. Also writes {result_key}_passed boolean for routing.
throw_on_failbooleanfalseWhen true, the node throws on failure (engages failure_policy retry). When false, downstream edges route on {result_key}_passed.

Used by reflection nodes. Distills source_keys from workflow memory into atomic SemanticFacts and persists them via the injected memoryWriter. Pairs with memory_query on downstream nodes to close the compound-learning loop.

FieldTypeDefaultDescription
source_keysstring[]required (min 1)Memory keys whose values feed the extractor. Must be declared in the node’s read_keys.
extractorRuleBasedExtractor | LLMExtractorrequiredExtraction strategy (see below).
tagsstring[][]Tags applied to every fact written. Namespace by graph (graph:my-graph-v1) or category (lesson, failure) so downstream retrieval can scope.
entity_keysstring[]Memory keys whose string values name entities the produced facts relate to. Linked into the knowledge graph for entity-driven retrieval.
result_keystring{node.id}_reflectionMemory key the structured ReflectionResult envelope is written to.

Deterministic sentence-level extraction. No LLM call.

FieldTypeDefaultDescription
min_sentence_lengthnumber15Minimum sentence length (chars) to qualify as a fact.

Uses the extractFactsExecutor primitive to distill structured lessons via an LLM.

FieldTypeDefaultDescription
agent_idstringrequiredAgent ID for the LLM extractor.
max_factsnumber10Soft cap on facts returned (1–50).
instructionstringOptional override for the default lesson-distillation prompt.

Used by agent, supervisor, and any wrapper-agent node (annealing, map worker, swarm, synthesizer, voting voter, evolution candidate). When set, the runner calls memoryRetriever once before building the node’s prompt and renders the result into a ## Relevant Memory section.

FieldTypeDefaultDescription
textstringstateView.goal (only when no other field is set)Natural-language semantic query.
entity_idsstring[]Seed entity IDs for knowledge-graph subgraph extraction.
tagsstring[]Restrict matches to facts carrying at least one of these tags.
max_factsnumberSoft cap on facts injected into the prompt.

Routing rule: if text, entity_ids, or tags is set, retrieval uses that knob explicitly. Only when none of them are set does the runtime default text to stateView.goal (zero-config RAG). Voting and evolution nodes propagate memory_query automatically to their synthetic sub-nodes.