Skip to main content
Agent commands. Your AI agent uses this node in workflows. You don’t configure it directly.
The code node runs Python in-process with direct access to input data as native objects. Use it when the logic is deterministic — filtering, reshaping, merging, computing values. If you can write a Python expression for it, there’s no reason to burn tokens on an LLM call.

Parameters

Output

Type annotations

Every input variable and the result variable must have a type annotation. pflow uses these to validate inputs before your code runs — so a wrong type gets caught immediately with a fix suggestion, not as a cryptic Python error mid-workflow.
Use Any when you don’t know or care what the input type is. pflow auto-injects Any, so you don’t need from typing import Any.
Only the outer type is checked — list[dict] validates that the value is a list, but doesn’t check whether the elements are dicts.

Template placement

Templates go in inputs, never in the code block. The code block is literal Python — ${var} isn’t valid Python syntax, so putting templates there causes a parse error.
Templates in the inputs dict get resolved before your code runs. By the time Python sees data, it’s already a native object — no parsing needed.

Bridge to workflow inputs

Workflow ## Inputs / ## Outputs use canonical names. Code blocks use Python annotations.

Inputs are native objects

Upstream JSON is auto-parsed before your code runs. If the source node produced a JSON string, declare dict or list, not str — you get real Python objects, not strings.

Examples

Simple transformation

Multiple inputs

Access fields downstream: ${merge-sources.result.items}, ${merge-sources.result.count}.

No inputs

Using subprocess

Imports

Standard library imports work without restrictions — json, re, subprocess, pathlib, datetime. Third-party packages work too, but they need to be installed in pflow’s environment.
pflow runs in an isolated environment, so pip install pandas won’t work. How you add packages depends on how you installed pflow:pipx (simpler — additive, doesn’t touch existing packages):
uv tool (replaces the full environment — list existing extras first):
uv tool install is not additive — it recreates pflow’s environment from scratch. If you previously installed with --with llm-openrouter and now run --with pandas alone, you’ll lose llm-openrouter. Always run uv tool list --show-with first and include all existing --with flags.
A simpler way to manage code node dependencies is coming in a future release.

Security

Code runs directly in the pflow process via exec() without sandboxing. It has full access to your filesystem, network, and standard library — same as running a Python script yourself. Sandboxed execution is planned for a future release.
You’re in control. Your agent asks before running workflows, and you can open any .pflow.md file to see exactly what code will run. To disable this node entirely: pflow settings deny code.

External code file

For larger scripts, reference an external Python file. The file is read and used as the code block. Path is relative to the workflow file.

Error handling

Errors include line numbers, the actual source line, and a suggestion for how to fix it. For example, a type mismatch looks like:
The node doesn’t retry — code execution is deterministic, so retrying the same code produces the same result.