graph-live is the live demo at earl-mcgowen.com/graph-live: type a question in plain English, watch a LangGraph pipeline execute step by step in real time, and get a SQL answer at the end. The pipeline is opaque AI made inspectable — every node lights up as it runs.
This post is the build narrative. The companion post — earl-mcgowen.com/blog/coding-bakeoff-methodology — explains how I picked the coding tool that wrote most of the code.
What's behind the page
The architecture, top to bottom:
- A LangGraph SQL agent. Nodes parse the question, build the query, run it against the database, format the result, and stream each step back to the browser.
- A FastAPI server with a Server-Sent Events (SSE) streaming endpoint. As each LangGraph node finishes, the server pushes a structured event to the client.
- A SvelteKit frontend that listens on the SSE stream and animates the pipeline visualization — each node lights up as the event for it arrives.
A LangGraph is a directed pipeline of AI steps. Each node is a discrete operation: parse, route, query, format. You can compose them, branch on conditions, and stream their progress as they run.
Server-Sent Events (SSE) is a one-way HTTP stream from server to browser. Lighter than WebSockets, well-suited to "show me what's happening" pipelines like this one.
The model swapping happens at the agent layer. One config setting picks which underlying LLM the agent uses for natural-language-to-SQL — local, hosted-open, or frontier — without touching the rest of the system.
What Qwen Code wrote
The bake-off (see companion post) picked Qwen Code on Qwen3.7-Max via OpenRouter as the workhorse. In the real build, it wrote:
- The FastAPI SSE streaming endpoint (
server.py). Got the fussy parts right first try: event formatting, connection lifecycle, graceful error handling on broken streams. - The shared-secret authentication including a fallback path for when the primary auth header is missing. Fallback logic is the kind of thing I expected to debug by hand. Qwen got it right.
- The rate-limiting middleware sized for a public read-only demo: per-IP throttling with restricted origins so this endpoint can't be hammered from someone else's site.
- The forwarded-IP fix — extracting the real client IP from the proxy chain so the rate limiter doesn't see every request as coming from the same edge node.
- The Svelte frontend pages for graph-live and the supporting routes, including the navigation edits to slot the new page into the existing site structure. The nav edit was the small test: it required reading the existing nav component, understanding its structural constraint, and adapting — not just transcribing. Qwen did.
Most of it was correct on first read. Some of it needed adjustment under human review. Nothing was broken in a way that made me regret the choice.
What Claude Code did
Claude Code on Claude Opus 4.7 came in for a specific job: closing an invisible-edges bug in the visualization that Qwen got close on but didn't fully land. The graph visualization had edges that should have been visible on certain transition states and weren't. Claude diagnosed and fixed it.
That's the human-in-command pattern in practice. Workhorse on most of the work; specialist on the part that needs a second opinion.
Right-sized security
The hardening on this endpoint matches what it is: a free, public, read-only demo on a personal site. Specifically:
- Authentication via shared secret to keep the endpoint from being trivially scraped.
- Rate-limiting per-IP to keep one visitor from monopolizing the model behind it.
- Restricted origins so the endpoint only responds to requests from earl-mcgowen.com — no embedding it on someone else's site to burn my credits.
What's not in this build, deliberately:
- No PII handling — there's none to handle.
- No audit logging — there's nothing legally required to log.
- No SSO or per-user accounts — it's a demo, not an app.
If this were a regulated production build, the hardening would look different. I'd add OAuth, encrypted at-rest storage, audit trails, and a more conservative model deployment posture. The point of right-sizing isn't doing less; it's matching the investment to the stakes.
The live visualization
The graph-live page itself is the part most visitors react to. As the LangGraph runs, each node animates as its event arrives over the SSE stream. You can watch the AI think.
This solves a problem that comes up in every stakeholder demo of an AI system: "it's a black box, we can't tell what it's doing or whether it worked." The visualization doesn't make the AI transparent in the deepest technical sense — the model is still the model — but it makes the pipeline transparent. You see the steps, you see the order, you see which step's output became the next step's input. For regulated and risk-averse audiences, that's a different conversation from "trust me."
What broke and what I fixed
A few things that didn't come out clean and took real debugging:
- The invisible-edges bug above — Qwen got close, Claude closed it.
- An SSE connection lifecycle issue where the client wasn't cleanly reconnecting on transient errors. Tracked this down by hand reading the network panel.
- A forwarded-IP edge case where one of the upstream proxies wasn't passing the header I expected. The fix was a fallback chain.
None of these were blockers. All of them needed a human in the loop.
What this is and isn't
What it is: a working, hardened, public demo of an AI SQL agent with a live pipeline visualization, built mostly by Qwen Code under human supervision.
What it isn't: an enterprise-grade governed deployment. The next direction I'm scoping uses the same pattern — same model-swappable agent design, same human-in-command supervision — sized for regulated environments. That build is a direction, not a thing.
If you want to see what this looks like before that next build exists, the live demo is at earl-mcgowen.com/graph-live. Type a question, watch the pipeline.
