A full-stack chat application built on LangChain Managed Deep Agents, with human-in-the-loop tool approval, multi-runtime support, and Docker Compose for one-command startup.
Open the interactive diagram: canvases/langch-architecture.canvas.tsx (Canvas beside chat).
flowchart TB
subgraph Client
UI[React Chat UI :5173]
end
subgraph Backend
API[FastAPI :8000]
RT[Runtime Router]
end
subgraph Runtimes
MDA[Managed Deep Agents API]
LOC[Local deepagents]
DEP[LangSmith Deployment]
end
subgraph External
MCP[Fleet MCP tools]
LS[LangSmith traces]
LLM[Anthropic / OpenAI]
end
DEF[agent/ definitions] -.provision.-> MDA
UI -->|REST + SSE| API
API --> RT
RT --> MDA
RT --> LOC
RT --> DEP
MDA --> MCP
MDA --> LS
LOC --> LLM
| Layer | Role |
|---|---|
agent/ |
Instructions, tools, skills, subagents (version-controlled) |
backend/ |
Runtime abstraction + SSE streaming + HITL resolve/resume |
frontend/ |
Chat UI, interrupt approval modal, markdown rendering |
langgraph.json |
Deploy graph to LangSmith via langgraph up |
| Mode | When | Requirements |
|---|---|---|
auto (default) |
Picks best available | See priority below |
managed |
Production on LangSmith | LANGSMITH_API_KEY, MANAGED_AGENT_ID |
local |
Dev without preview access | ANTHROPIC_API_KEY or OPENAI_API_KEY |
deployment |
Self-hosted Agent Server | LANGGRAPH_DEPLOYMENT_URL, LANGGRAPH_ASSISTANT_ID |
Auto priority: deployment URL → managed → local.
- Managed Deep Agents — create agent, threads, streamed runs via
/v1/deepagents - Human-in-the-loop — web search requires approval (
REQUIRE_HITL_APPROVAL=true); UI modal +resolve-interrupt+resume-stream - Local fallback — open-source
deepagentswith in-memory checkpoints (stub web search) - LangSmith Deployment —
langgraph.json+backend/agent.pyforlanggraph up - Docker Compose —
make docker-up→ frontend on :3000, backend on :8000
cp .env.example .env
# Set LANGSMITH_API_KEY (+ provider keys for local mode)make installmake provisionmake backend # terminal 1
make frontend # terminal 2 → http://localhost:5173make docker-up # http://localhost:3000agent/tools.json enables interrupts for tavily_web_search. When the agent calls that tool:
- Stream emits an
interruptSSE event - UI shows Approve / Reject
POST /api/chat/resolve-interruptcompletes the pausePOST /api/chat/resume-streamcontinues token streaming
Toggle at provision time:
REQUIRE_HITL_APPROVAL=false make provisionDeploy the same graph defined in backend/agent.py:
pip install langgraph-cli
langgraph up
# Set LANGGRAPH_DEPLOYMENT_URL and LANGGRAPH_ASSISTANT_ID in .env
# AGENT_RUNTIME=deployment| Method | Path | Description |
|---|---|---|
| GET | /api/health |
Runtime mode + readiness |
| POST | /api/conversations |
Create thread |
| POST | /api/chat/stream |
Send message (SSE) |
| POST | /api/chat/resolve-interrupt |
Approve/reject tool call |
| POST | /api/chat/resume-stream |
Continue after approval (SSE) |
langch/
├── agent/ # Deep Agent definition
├── backend/
│ ├── app/runtime/ # managed | local | deployment
│ ├── agent.py # LangGraph deploy entry
│ └── scripts/provision_agent.py
├── frontend/
├── langgraph.json
├── docker-compose.yml
└── Makefile