Live topology
The graph is a map of your pipeline, not an unrolled column. Cards pulse while a node runs. Taken, skipped, loop, and parallel edges stay on one picture, including ×N fan-out.
Graph-View-Agent 1.5.0-dev
GraphVIAgent is an inspector for LangGraph. Point it at a folder of
*_pipeline.py files, press Run, and watch topology, steps, state, and logs
update live. Pipelines stay uninstrumented.
Only the runs you start are stored.
pip install graphviagent
Watch a run live, replay a node, then see every visit on the board, in Compare, and in Statistics.
The graph is a map of your pipeline, not an unrolled column. Cards pulse while a node runs. Taken, skipped, loop, and parallel edges stay on one picture, including ×N fan-out.
Switch the same run between a topology map, a Gantt of wall time, and an Agents view when nodes return messages. Click a node to select it. Double-click to open Node view.
print() and stderr are captured as PRINT / STDERR. Python logging keeps its level. DEBUG, INFO, WARN, ERROR, and CRIT each have their own color. Logger names show when they differ from the node.
Replay step runs only the selected node. Replay from continues from that checkpoint so routing can take the other branch. Both invoke the real function — side effects will fire. Outdated runs (graph hash changed) ask before replay. Continue / Step on a paused run do not — they reuse the interned checkpointer, including after a topology change. Cancel and closing the tab abort a replay the same way as a live Run. Approximate replay is only when there is no checkpointer; a failed fork is an error.
Runs is an Airflow-style grid of duration and task × run. Compare diffs input, path, per-node output, and timing between two runs, including each visit when a node ran more than once.
Same topology as Trace. Filter status (success, failed, or all; default success), nodes (default all), and last (10 / 20 / 50 / 100 / all; default 10); every metric follows that selection. Routing shows run count, average node visits, and success vs failed vs canceled. Runtime writes average duration, a pipeline grand total, and average vs longest run, including the node min / avg / max panel. Cost writes average in/out tokens, a pipeline grand total, and average per run. Hover a color strip for a dotted legend (one label per color). Colored jumps keep you on that pipeline.
Click the gutter dot on a topology card to break before that node. Breakpoints persist per pipeline. Continue resumes with those stops; Step runs the next node and pauses again. Graphs that call interrupt(...) pause with a resume-value box; the box keeps what you type until Continue or a new pause. A pipeline or toml reload in the same serve process keeps the in-memory checkpointer; restarting serve, or deleting / unlisting that pipeline file, does not. Replay asks if the graph is outdated; Continue / Step do not, so a topology edit can feed an old checkpoint into the new compile.
Default three runs at a time (--concurrent); extra work waits in a FIFO (--queue-limit). Overflow is HTTP 429. Cancel stops a live run, a paused one, a Replay, or a Continue / Step still waiting for a slot. Closing the tab dequeues a wait and leaves a paused graph alone. time.sleep is interrupted within ~50ms. Other blocking calls still finish first.
Each run is JSON under .graphviagent/runs/<pipeline>/ named with a 32-character hex id (still that length when crypto.randomUUID is missing). Export, import, or drop a file on the run list. Search input fields. Filter success, paused, canceled, or failed. Trace loads 40 runs, then the next page when you scroll the list.
Final state, a Memory table of who wrote and read each key, and a per-node state diff in Node view. Parallel Send visits keep their own state_out, not the merged superstep. Optional decisions, reason, and choice label branches on the graph.
Install the package, drop a pipeline in a folder, press Run.
Python 3.11 or newer. Use a virtualenv.
python3 -m venv .venv source .venv/bin/activate pip install -U pip pip install graphviagent
The package does not copy example files into your project. You add your own pipeline.
The file name must end with _pipeline.py. Save this as echo_pipeline.py in an empty folder:
from typing import TypedDict
from langgraph.graph import END, START, StateGraph
EXAMPLES = [
{"label": "hello", "input": {"text": "hello"}},
{"label": "GraphVIAgent", "input": {"text": "GraphVIAgent"}},
]
class EchoState(TypedDict):
text: str
echoed: str
length: int
def echo(state: EchoState) -> dict:
text = state["text"]
return {
"echoed": text[::-1],
"length": len(text),
"reason": f"reversed {len(text)} chars",
}
def build_graph():
graph = StateGraph(EchoState)
graph.add_node("echo", echo)
graph.add_edge(START, "echo")
graph.add_edge("echo", END)
return graph.compile()
EXAMPLES is optional. The first item prefills the input box. Use {"label": "…", "input": {…}} or a bare dict.
graphviagent serve . --open
Or open http://127.0.0.1:8765. Leave the terminal running. The UI only accepts requests from its own origin (http or https; a TLS reverse proxy on the same host is fine). Bind stays on localhost unless you pass --expose:
graphviagent serve . --port 9000 graphviagent serve . --host 127.0.0.1 graphviagent serve . --host 0.0.0.0 --expose
--expose prints a warning. Anyone who can open that URL can run your pipelines and read stored runs. New or edited *_pipeline.py files (and toml-listed pipelines, including files outside the serve root) refresh the sidebar without a restart. Watchdog watches the workspace root and each pipeline parent (not .venv). A file in a new nested folder can take up to 45s to appear. The first snapshot does not hash; same-size edits are not re-hashed until you click Run.
How Trace, replay, the board, and Compare work once you are in the UI.
Four rooms, one pipeline. Jump Trace, Runs, Statistics, and Compare without losing the graph. Breakpoints live on Trace.
01 Live inspector
The graph is a map, not an unrolled column. Cards pulse while a node runs. Taken, skipped, loops, and parallel Send stay on one picture. Send arrows go to the declared target, not every node that was missing an incoming edge.
messages. Fit scales width and height to the pane and centers the drawing.02 Pause before a node
Click the gutter dot on a topology card to break before that node. LangGraph sees interrupt_before. Dots persist per pipeline until you clear them.
interrupt(...) pauses with a resume-value box. Continue sends that JSON. The box keeps what you type until Continue or a new pause. A reload in the same serve keeps the checkpointer; Continue / Step do not ask if the graph topology changed. A restart drops it.03 Same node, other branch
Replay step runs only the selected node. Replay from continues from that checkpoint so routing can take the other branch.
state_in vs state_out (each parallel Send visit keeps its own), tools, traceback. Call node is Replay step.04 The board
Airflow-style cards: duration bars, then task × run (✓ / ✕ / ○). Failed nodes stay in history and show as red.
05 Across every visit
Same topology as Trace. Pick a pipeline — there is no all view — then filter status, nodes, and last N. Colored jump buttons keep you on that graph.
reasons.06 Run A vs Run B
Filter by pipeline (default all). Diff input, path, per-node output, and timing. Hover a cell to copy.
A file is viewable if it is named *_pipeline.py (or listed in graphviagent.toml) and exposes, in this order:
build_graph() / get_graph() / create_graph() / __graph__StateGraph GRAPHapp (stream, invoke, and ainvoke — a package named app is ignored)Do not import GraphVIAgent in the pipeline. The viewer loads the file and records runs you start from the UI or CLI.
Optional project file. root and pythonpath are resolved relative to the toml, so from app.graph import build_graph works no matter where you launch serve.
root = "."
pythonpath = ["."]
env_file = ".env"
context = {}
[pipeline.decision]
file = "decision_pipeline.py"
With [pipeline.*] tables, those files are the graphs (file may be any .py, including a path outside the serve root). Those files are watched too. Without them, GraphVIAgent globs *_pipeline.py, skipping environments by directory name (.venv / venv, tox / pixi / direnv, node_modules). Folders whose names look like envs are probed for pyvenv.cfg, conda-meta, or bin/Scripts python plus lib/Lib.
context is LangGraph runtime context (runtime.context / get_runtime()), not graph state. It is passed on every UI, CLI, HITL resume, and replay run. Empty {} is omitted.
Everything stays on your machine. Runs are written under the folder you served or ran from:
my_graphs/.graphviagent/runs/echo_pipeline/<id>.json
Each run file has schema_version (currently 1) and gva_version. Older files still load. Import of a newer schema is refused. Add .graphviagent/ to .gitignore.
POST /api/run and POST /api/rerun return one JSON run. The live UI uses POST /api/run/stream and POST /api/rerun/stream (text/event-stream).logging still respects the logger’s level. Root defaults to WARNING, so logger.info appears only if that logger is enabled for INFO.mtime jitter), including the first snapshot. Same-size edits do not refresh the sidebar hash until you click Run. UI scan/change//api/pipelines polls read the watcher snapshot; they re-walk at most every 45s if watchdog missed an event.time.sleep quickly. Other blocking calls (network, LLM) still finish before the run stops.List, run, and serve from the folder that holds your pipelines.
List *_pipeline.py files under a folder.
Record a run without the browser. Stored under .graphviagent/ in the current directory. Exit status is 1 if the graph raised.
Open the UI (default 127.0.0.1:8765). --open launches a browser. --host and --port override the bind address. Binding beyond localhost requires --expose. --concurrent N is in-flight graphs (default 3); --queue-limit N is how many may wait; --node-concurrency N is LangGraph node fan-out (omitted = unlimited).
With a clone of the repo you can also run graphviagent serve examples to browse the bundled pipelines (branch, loop, parallel Send, tools, agents, memory, waits, runtime context, errors).