Graph & Workflows¶
Neurosurfer has a graph layer for multi-step pipelines:
neurosurfer.graph.engine— a standalone DAG engine (Graph,GraphNode,GraphExecutor). Think of it as the framework's LangGraph analog.neurosurfer.graph.workflow— a persisted, versioned Workflow package layered on the engine: save a graph to disk, register it, and run it later.
The Architect builds these graphs for you from plain English — these pages cover building and running them directly.
The pages¶
| Page | Answers |
|---|---|
| Node kinds | The eleven kinds, their classes, and what each one needs. |
| Control flow | Branching, looping, fanning out, recovering from errors. |
| Authoring in YAML | The graph.yaml format, key by key. |
| Python in a graph | The functions: sidecar, and what your callables receive. |
| State & secrets | What a node can see — and what it must never see. |
| Validation | What is checked, when, and what a failure means. |
| Workflow packages | Persisting, registering, and running a graph later. |
| Building in Python | The GraphBuilder fluent API. |
Two ways to write a graph¶
Python, where each kind is a class:
from neurosurfer.graph import Graph, BaseNode
graph = Graph(name="pipeline", nodes=[BaseNode(id="writer", instructions="…")])
YAML, which is what a package stores on disk:
Same Graph, same validation, no second code path. See Authoring in YAML.
Build a graph¶
A Graph is a set of GraphNodes. Each node has an id, a kind, instructions, and optional depends_on edges.
What a node receives is what its own text names, plus the outputs of its depends_on. Nothing ambient: the graph's inputs are not appended to every node's prompt as a block, so a step that needs one interpolates it by name.
from neurosurfer.graph import Graph, GraphNode
researcher = GraphNode(
id="researcher",
kind="base",
description="Fact-finding node.",
goal="Research {topic} and produce exactly 5 key bullet points.", # names its input
)
writer = GraphNode(
id="writer",
kind="base",
description="Turns research notes into prose.",
goal="Write a clear, 2-paragraph explanation from the research notes above.",
depends_on=["researcher"], # names nothing; the edge carries the notes
)
graph = Graph(
name="content_pipeline",
description="Research a topic, then explain it.",
nodes=[researcher, writer],
inputs=[{"name": "topic", "type": "string"}],
)
A declared input that no step names is reported by the validator, because the run would otherwise go green while the model answers as though it had been passed nothing.
Upgrading an existing workflow?
This scoping rule changed, and a workflow written against the older behaviour still validates and still runs — it just answers as though handed nothing. See Upgrading.
The kinds, briefly¶
Each has a class; the kind= string is the same node by another name.
BaseNode— one bounded LLM step. Reasons; cannot act repeatedly.ReactNode— a multi-step tool-using node. Reasons and acts.ToolNode— one registered tool, called directly. Acts; cannot reason.FunctionNode/PythonNode— deterministic Python by import path.RouterNode,LoopNode,MapNode,SubgraphNode— control flow.InputNode,OutputNode— the edges of a run.
Full field reference: Node kinds.
Run a graph¶
GraphExecutor runs the DAG on a provider, resolving dependencies and passing outputs downstream:
from neurosurfer.graph import GraphExecutor
executor = GraphExecutor(graph, provider=provider)
result = executor.run({"topic": "how attention works in Transformers"})
print(result.execution_summary())
print("succeeded:", result.succeeded)
print("errors:", result.errors or "none")
The GraphExecutionResult exposes execution_summary(), succeeded, errors, and per-node output.
Validation runs first. A graph that cannot run is refused before a model is called, rather than partway through — see Validation.
Persist it¶
A graph saved as a versioned package can be registered and run anywhere:
from neurosurfer.graph.workflow import load_package, WorkflowRunner
pkg = load_package(pkg_dir)
result = WorkflowRunner(provider, cwd=repo_root).run(pkg, inputs={"topic": "gradient descent"})
See Workflow packages.
Don't want to hand-build graphs?
The Architect designs and builds a Workflow package from a plain-English description — then you run it exactly as above.