Code Steps (code_step)
Some logic is too specific for a compute operator, yet too deterministic to warrant a LLM agent: multi-source reconciliations, bespoke business computations, exotic normalizations. For these cases, the code_step node executes code inside a sandbox, with no LLM call and a predictable output.
The code is edited directly, like any other configuration field, and runs as soon as it is saved.
The execution model
code_step executes Starlark — a Python dialect designed for isolation: no filesystem access, no network, no arbitrary imports, deterministic, bounded by a time budget. The code only sees:
- The inputs you explicitly map to it (
input_paths). - The tools you authorise it to call (
allowed_tools).
Everything else is out of reach. A code step cannot access a resource you have not handed to it.
Configuration
| Field | Purpose |
|---|---|
| Code | The Starlark source that is executed, edited directly. |
Inputs (input_paths) | variable → selector mapping. Only these context keys are exposed to the code. Internal keys (_*) are rejected. |
| Tool allowlist | The tools callable via tool(name, args). Each call inherits the tool's own safeguards (SSRF protection, billing, audit, killswitch). |
| Output key | Where to place the result in the context. Downstream nodes read this key. |
| Execution budget | Time ceiling (ms), capped server-side. A step that exceeds it is interrupted. |
Where the security boundary is
The language is not the threat: Starlark is sandboxed by design — on its own it can neither read a file, reach the network, nor loop forever. Pure computation is harmless.
The only real capability is the tool() bridge, and it is bounded by the allowlist enforced at runtime: the code can only call the tools you have listed, and each one carries its own safeguards (SSRF protection, billing, audit, killswitch). That — the choice of tools — is where you scope what a step is allowed to do.
An empty allowlist = no side-effect capability: the step merely computes over its inputs and produces an output.
When to use it
- Yes: deterministic logic you can describe precisely, but which exceeds the built-in
computeoperations (reconciling multiple lists, composite business rules, proprietary formats). - No: a simple filter, aggregation, or projection → a
computeoperator is sufficient. - No: a task that requires judgment or open-ended writing → that is an agent, not code.