Self-hostable · Open source

LangGraph App

A chat surface for a real agent graph.

Streaming chat backed by a LangGraph StateGraph. A second graph quietly runs memory summarization, observability capture, and thread housekeeping after every turn. Ship the whole thing on a single VPS.

Agent
What is this project?

Everything the chat needs, nothing it doesn't.

The project ships the parts of an LLM product that you would otherwise rebuild every time. Each is small, observable, and swappable.

Chat anything

Ask the model about anything — web lookups, code reviews, prices, weather, even trade approvals. Tokens reach the chat live, the moment the model emits. Markdown, code blocks, and tool-call UI render inline on the same wire. A click stops the reply mid-flight — the SDK cancels, nothing half-written persists.

Live

Memory + Knowledge Base

User facts surface in the system block; PDFs, images, plain text, markdown, and Office Open XML (DOCX / XLSX / PPTX) — plus pasted URLs fetched server-side — all go through a per-doc pipeline (OCR or structured parse → chunk → embed → entity) and become a hybrid-searchable index. Both are reviewable and deletable from settings.

Dual-graph agent

Chat handles the turn; a second graph runs memory, summarization, and observability capture behind the scenes.

Observability waterfall

Every span, every tool — one tree. Redacted at write, indexed by turn, viewable alongside the reply.

Evaluation & A/B

Per-agent rubrics, benchmark datasets, and an LLM-as-a-Judge that scores every run. Online executions surface judge work; benchmarks replay one prompt through any agent.

Human in the loop

LangGraph's interrupt() pauses the run for the user — locations, wallets, trade confirmations.

Self-host first

One docker-compose, one Postgres, one repo. No SaaS, no per-seat pricing, no tracking pixels.

How it works

Each piece of the system has a scroll-driven explainer below. They run on real code paths in the project — the same shapes, same state, same animation choices.

Streaming

Tokens appear the moment the model emits them.

The chat runtime subscribes to a LangGraph stream. Each token is appended to the message in place; the assistant-ui markdown renderer keeps a blinking caret on the trailing line. Aborts cancel at the SDK layer — no half-written replies ever reach the database.
Stream00 / 39
The chat graph routes to a sub-agent. The sub-agent picks tools and streams tokens back to the runtime. Each emitted token is appended in place to the message. Aborts cancel at the SDK layer and never reach the database.

Multi-graph

Two graphs, one turn. The chat hands off, the background finishes.

When the chat graph completes a turn, it dispatches a runs.create to a second graph on a fresh AbortSignal. The user already has the reply; memory, observability, and thread housekeeping run after.
Agent GraphBackground Agent Graph
runs.create dispatch

Memory

The model sees what you told it. Across threads.

On every turn, a small system block surfaces stable user facts and a short summary of recent threads. The chat graph reads the block, not the raw history. The Memory settings tab lets you review and delete what's stored.

system

Memory

  • · User prefers TypeScript over JavaScript
  • · Working on a self-hosted LangGraph chat project
  • · Time zone: UTC+8

threads

Recent threads

  • · Today · LangGraph checkpoint migration
  • · Yesterday · Drizzle + Better Auth setup
  • · Last week · Tailwind v4 theme tokens

user

What did I do with Tailwind last week?

Observability

Every span, every call, one waterfall.

A single capturing handler subscribes to the chat and background runs in parallel. Spans are written to Postgres under a per-turn key, redacted at the boundary, and rendered as a collapsible tree in the right panel.
waterfallper turn
chain
node
llm
tool
node
llm
tool
0ms240ms480ms

Human in the loop

Some tools only run with your sign-off.

LangGraph's interrupt() halts a run mid-execution, hands control to the user, and resumes when they send a payload back. Locations, wallet picks, trade confirmations — every input that needs judgement passes through one card chrome.

Client-side UI rendered while the graph pauses.

Requires approvalask_location

Share your location so the agent can pull the forecast.

Tool execution paused — the graph resumes on click.

Knowledge base

Drop a file (or paste a URL), query the entity graph.

Seven source kinds plus pasted URLs land in one pipeline — PDF, images, plain text, markdown, and the three Office Open XML formats (DOCX, XLSX, PPTX). PDFs and images go through vision OCR; Office formats are parsed structurally by officeparser (one page per slide / sheet, with embedded images extracted to R2); text and markdown skip straight to chunking; pasted URLs are fetched server-side via Jina Reader and land as a markdown attachment. Every chunk is embedded and run through an entity-extraction pass — relationships, themes, and entity names all become structured columns the retrieval legs can score on.

Hybrid Search: three legs run in one round-trip — BM25 for the exact term, pgvector cosine for semantic closeness, and an entity-overlap leg that walks the graph from your query node. The three are fused with RRF (Reciprocal Rank Fusion).

KB ingest pipelineper source · PDF · image · md · txt · docx · xlsx · pptx · URL
Source
OCR
Chunk
Extract
Embed
what does the doc say about @kb-doc?

[chunk 7 · vector + entity hit · 0.94] The BM25 leg finds the exact term; the entity leg ties it to the canonical name.

Entity graphgraph traversal
?
Query ? lights up its 2-hop neighborhood. The graph leg scores every entity it touches alongside BM25 + vector.

Evaluation

Score every run against the rubric — by hand or by AI Judge.

Online Executions: every chat turn, every KB ingest, every AI Judge scoring run shows up under its own agent card. Click a row for the per-turn waterfall; click the thumbs-up to stamp a 1–5 rating onto the same eval_run the model produced. The chat UI sends the assistant message id and the route resolves it against eval_run.parent_message_id — no match, silent no-op (the thumbs-up never crashes on a dangling row).

LLM-as-a-Judge: a separate evalAgent graph runs an LLM against the same span context the target agent saw and emits one structured score per rubric criterion plus a reasoning paragraph. The rubric lives in eval_rubric — seeded per agent (incl. judgeByLLM itself), editable in /admin/eval. Benchmarks replay one input through a target agent under the same harness; the judge scores the output and the result lands inline on the Benchmark Datasets table.

Evaluation · AI Judgerun → criteria → score
User · What's the capital of France?
Assistant · Paris.
overall 4.5 / 5
judgeByLLMrubric · chatAgent
relevance
accuracy
reasoning · accurate, concise; could acknowledge the user's framing.
The judge reads the same span context the model produced — same input, same output — then stamps a per-criterion score + reasoning. Online executions surface every run; benchmarks replay one input against a target agent under the same harness.

Self-host

One VPS. One Postgres. One repo.

The project ships as a single docker-compose on a single box. No SaaS, no per-seat pricing, no background services talking to a third party. Bring your own OpenAI-compatible endpoint and your own Postgres; the rest is in the repo.

  • Next.js frontend (App Router, RSC, route groups)
  • LangGraph dev server (`:2024`) with Postgres checkpointer
  • Drizzle migrations + Better Auth email + OAuth
  • OpenAI-compatible chat model — bring your own key
  • Observability collector + retention cron
Agent promptview source ↗

Paste this into your agent chat (Claude Code, Cursor, etc.). The agent reads the skill and walks you through the whole flow — anchors, cold start, daily CD, rollback, backup.

Please help me deploy LangGraph App by following the skill at https://github.com/FireTable/langgraph-app/blob/main/skills/langgraph-app-maintain.md.

Read the code. Run it. Skip the demo.

The repo is the documentation. README for the tour, docs/ for the design notes, the source for everything else. If something is unclear, open an issue — issues are answered in public.

LangGraph App

A self-hostable chat surface for a real LangGraph agent. Streaming chat, background work, memory, observability — the parts of an LLM product you would otherwise rebuild every time.

© 2026 LangGraph App. Released under the MIT License.

Built with Next.js, LangGraph, and Drizzle.