Nodes
Updated 6 hours ago • May 22, 2026
A node is one executable step in a workflow.
Use nodes for the units of work you want Kortyx to orchestrate: classify a message, call a model with useReason(...), fetch data from your app, ask a human for input, route to another branch, or produce the final response.
Each workflow node has two parts:
- a workflow definition entry, where you choose the handler and static
params - a node function, where your app code receives
inputandparams, then returns aNodeResult
Where nodes are declared
Nodes are declared inside defineWorkflow(...).
Node definition fields:
run: the node handler. Use a direct function in TypeScript workflows, or a module path / registry key for YAML and JSON workflows.params: static configuration passed to that node every time it runs.metadata: app-defined metadata for tooling, docs, or inspection.behavior.retry.maxAttempts: number of attempts for this node.behavior.retry.delayMs: delay between retries.
Good to know:
paramsare not the user message. They are static per-node configuration from the workflow definition. Use them for model refs, prompt settings, feature flags, limits, tool config, or app-specific constants.
How client messages reach a node
In the normal chat path, the client sends messages to your route, and your route passes them to agent.streamChat(...).
From there, Kortyx does this:
- Validates the request body.
- Finds the latest non-empty
usermessage. - Stores that message content as the initial workflow
input. - Selects the workflow.
- Runs the first node connected from
__start__. - Calls that node as
node({ input: state.input, params: node.params ?? {} }).
For this request:
The first node receives:
Good to know: Previous chat messages are preserved in runtime state as prior messages for orchestration context. The
inputargument passed to the first node is the latest user message content, not the full message array.
Request context is runtime configuration for the run. It does not become node params, and it does not replace the initial node input. Read it with Runtime Context when node code needs request metadata.
How data reaches the next node
Nodes pass data forward by returning data.
Kortyx merges returned data into workflow state before the next node runs:
state.inputbecomes the next node'sinputstate.datakeeps an accumulated data view for the run- object fields are deep-merged
- arrays are overwritten, not concatenated
- if the previous
inputwas not an object, it is preserved asrawInput
After the classifyNode return above, the next node receives:
If a node does not return data, the next node sees the existing input unchanged.
Node return values
A node returns a NodeResult. All fields are optional.
Return fields:
Prefer data for node-to-node handoff, ui for client-visible output, and condition / intent for graph routing.
Routing from a node
Use condition when the node chooses between outgoing edges.
Then match that token in workflow edges.
See Conditional Routing for loops, fallback behavior, and workflow transitions.
What to read next
- Define Workflows for the full workflow shape
- Conditional Routing for edge matching
- Hooks for
useReason(...), interrupts, and runtime state - Runtime Context for request metadata in nodes
- Node Resolution for
runstrings, module paths, and registry keys