Skip to content

Live visualization

A 3-agent chain (researcher → analyst → writer) wrapped in a Visualizer context manager. The browser tab opens automatically; pulses travel along graph edges as agents call tools, the inspector lets you click into every event, the store viewer highlights writes as they happen.

The same UI replays a finished session via Visualizer.replay(db="...").open().

Source

"""Pipeline Visualizer demo — a small chain of three agents that calls
two tools, all wrapped in a live :class:`Visualizer` so you can watch
the data flow in your browser.

Run::

    python examples/viz_demo.py

The browser tab opens automatically on a local URL. To replay the
recorded run later::

    python -c "from lazybridge.ext.viz import Visualizer; \\
               Visualizer.replay('examples/viz_demo.db').open()"
"""

from __future__ import annotations

import time

from lazybridge import Agent, LLMEngine, Session, Tool
from lazybridge.ext.viz import Visualizer

DB = "examples/viz_demo.db"


def search(query: str) -> str:
    """Stub web search tool — returns a fake result with a short delay."""
    time.sleep(0.4)
    return f"[search] results for '{query}': 5 hits, top is example.com"


def summarise(text: str) -> str:
    """Stub summariser tool that pretends to compress text."""
    time.sleep(0.3)
    return f"[summary] {text[:120]}..."


def main() -> None:
    sess = Session(db=DB, console=False)

    researcher = Agent(
        engine=LLMEngine("claude-haiku-4-5", system="Find facts. Cite sources."),
        tools=[Tool.wrap(search, name="search")],
        name="researcher",
        session=sess,
    )
    analyst = Agent(
        engine=LLMEngine("claude-haiku-4-5", system="Summarise findings."),
        tools=[Tool.wrap(summarise, name="summarise")],
        name="analyst",
        session=sess,
    )
    writer = Agent(
        engine=LLMEngine("claude-haiku-4-5", system="Write a short brief."),
        name="writer",
        session=sess,
    )
    pipeline = Agent.chain(researcher, analyst, writer)

    with Visualizer(sess) as viz:
        print(f"[viz] open -> {viz.url}")
        print("[viz] running pipeline…")
        envelope = pipeline("Brief me on the state of fusion energy in 2026.")
        print("[viz] pipeline done")
        print("--- result ---")
        print(envelope.text())
        print("---")
        print("[viz] press Ctrl+C to stop the server")
        try:
            while True:
                time.sleep(3600)
        except KeyboardInterrupt:
            pass


if __name__ == "__main__":
    main()

Walkthrough

  • with Visualizer(sess) as viz — context-manager pattern is what the recipe shows. The HTTP server starts on __enter__, shuts down on __exit__. The browser tab survives the boundary; close it yourself.
  • session=sess on every agent — the live GraphSchema is populated from the agents that register with the session. An agent without session=sess is invisible in the topology even if it runs.
  • viz.url is the bound URL (127.0.0.1:<ephemeral> by default). Print it before the pipeline runs so you can switch to the browser before tools start firing.

Variations

  • For a fixed port (e.g. to share with a teammate over a tunnel), pass port=8765 to Visualizer(sess, port=8765).
  • For headless / CI runs that should NOT open a browser, pass auto_open=False.
  • For a recorded run replayed at half speed: Visualizer.replay(db="demo.db", speed=0.5).open().

See also

  • Visualizer — the deep reference for live + replay modes, control endpoints, and custom-UI hooks.
  • Visualization mock — the same UI driven by a synthetic event stream (no LLM calls).
  • Session — the bus the Visualizer reads from; covers db=, batched=, exporters.