GVA GraphVIAgent
PyPI GitHub

Graph-View-Agent 1.5.0-dev

See your LangGraph run as it happens.

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
Get started
uninstrumented pipelines Python 3.11+ Statistics · Routing, Runtime & Cost

Features

Watch a run live, replay a node, then see every visit on the board, in Compare, and in Statistics.

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.

Steps, Gantt, Agents

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.

Logs you already write

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 a node, or from a 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 board and Compare

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.

Statistics: Routing, Runtime, and Cost

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.

Stop, step, and HITL

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.

Queue and cancel

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.

Local history

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.

State you can trust

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.

Start

Install the package, drop a pipeline in a folder, press Run.

1

Install

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.

2

Add a 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.

3

Open the UI

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.

4

Run

  1. Select the pipeline in the sidebar.
  2. Edit the JSON input if you need to.
  3. Click Run. The topology appears immediately and pulses while nodes execute. Clicking the selected pipeline keeps that live Trace.
  4. Single-click a node to select it. Double-click to open Node view.

Manual

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

Trace

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.

Graph / Gantt / AgentsTopology, wall-clock bars, or a speaker chain when a node returns messages. Fit scales width and height to the pane and centers the drawing.
StepsVisit order, duration, spark metrics. Concurrent runs do not zero each other’s memory. Final state, Log, Memory, and Text tree fold under it.
Stop hereGutter dots, Continue / Step, and HITL — see Stop.
Keep the runExport, import, or drop JSON. Clicking the selected pipeline keeps the open Trace, including a live run. Jump to Runs / Statistics. Delete run is red.

02 Pause before a node

Stop

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.

ContinueResumes and keeps those breakpoints. The next matching node pauses again.
StepRuns the next node, then pauses. Use it to walk the graph one visit at a time.
HITLinterrupt(...) 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.
CancelAbandons a paused run, a Replay, or a queued Continue / Step (stored as canceled, not failed). Closing the tab dequeues a wait and still cancels a live run or replay.

03 Same node, other branch

Replay

Replay step runs only the selected node. Replay from continues from that checkpoint so routing can take the other branch.

Real functionsBoth invoke the node you wrote. Side effects fire. Cancel and closing the tab abort a replay like a live Run.
Outdated runsIf the graph hash changed, replay asks before continuing. Continue / Step skip that prompt and reuse the interned checkpointer.
Node viewInput, output, state_in vs state_out (each parallel Send visit keeps its own), tools, traceback. Call node is Replay step.
CheckpointerAttached in-process when the pipeline did not. Approximate only with no checkpointer; a failed fork is an error, not a silent approximate run.

04 The board

Runs

Airflow-style cards: duration bars, then task × run (✓ / ✕ / ○). Failed nodes stay in history and show as red.

Open a runClick the name for Trace. Click a bar, cell, or play control for that run.
Stay on this graphTrace and Statistics jump here. Clear deletes every run for the pipeline.
#/runs/echo_pipeline

05 Across every visit

Statistics

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.

RoutingRun count, average visits, success / failed / canceled. Click a node for grouped reasons.
RuntimeGrand total, average per run, violet average vs orange longest. Click a node for min / avg / max from the filtered visits.
CostAverage in/out tokens per node, pipeline totals. Tokens, not dollars.
LegendHover a color strip for one label per color. Trace and Runs sit before the modes.
#/statistics/tokens_pipeline

06 Run A vs Run B

Compare

Filter by pipeline (default all). Diff input, path, per-node output, and timing. Hover a cell to copy.

Every visitLoops and branches align each visit separately — not only the first.
Same graphPick a pipeline and Run A / Run B only list that pipeline’s runs.

Pipeline contract

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__
  • compiled or StateGraph GRAPH
  • compiled app (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.

graphviagent.toml

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.

Privacy and storage

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.

Limits

  • Alpha: APIs, UI, and on-disk run format may change. 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).
  • Local only. Nothing is uploaded.
  • logging still respects the logger’s level. Root defaults to WARNING, so logger.info appears only if that logger is enabled for INFO.
  • File watch is non-recursive on the workspace root and pipeline parents; skipped trees are never scheduled. Hashing is skipped when size is unchanged (cloud-sync 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.
  • Cancel interrupts time.sleep quickly. Other blocking calls (network, LLM) still finish before the run stops.

CLI

List, run, and serve from the folder that holds your pipelines.

graphviagent .
graphviagent list .

List *_pipeline.py files under a folder.

graphviagent run echo_pipeline.py --input '{"text":"hi"}'

Record a run without the browser. Stored under .graphviagent/ in the current directory. Exit status is 1 if the graph raised.

graphviagent serve .
graphviagent serve . --open

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).