Skip to main content
Agent User Interaction Protocol (AG-UI) is an open, lightweight, event-based protocol that standardizes how AI agents connect to user-facing applications. Exposing a deep agent over AG-UI turns its run into a typed event stream (messages, tool calls, reasoning, state, and lifecycle) that any AG-UI client can consume, so you can drive a frontend without coupling it to LangGraph internals.
AG-UI is designed for agent-to-user interaction: the connection between an agentic backend and a user-facing frontend. It is distinct from the other Deep Agents protocols:

Quickstart

Serve a deep agent as a LangGraph graph, then connect the TypeScript @ag-ui/langgraph adapter so AG-UI clients can drive it.

Install dependencies

Install Deep Agents and the LangGraph CLI to serve the graph. The AG-UI adapter used in later steps is TypeScript (@ag-ui/langgraph). For a Python CopilotKit or AG-UI FastAPI bridge, see CopilotKit.
A deep agent created with createDeepAgent (create_deep_agent in Python) is a LangGraph graph. Expose it to AG-UI clients by serving it as a LangGraph server, then point the AG-UI adapter at that server.

Create a deep agent

Define the agent and export the graph so a LangGraph server can load it.
agent.py

Serve the agent

Register the graph in a langgraph.json file at your project root.
langgraph.json
Start the LangGraph development server. It exposes the graph over HTTP at http://localhost:2024.

Connect the AG-UI adapter

The TypeScript @ag-ui/langgraph adapter wraps the running graph as an AG-UI agent that any client can drive. Point it at the LangGraph server and name the graph to load. This works whether the graph was authored in Python or TypeScript.
ag-ui agent

AG-UI LangGraph adapter on npm

The @ag-ui/langgraph package implements the AG-UI protocol for LangGraph graphs, including deep agents.

Stream events

AG-UI is an event stream. As a deep agent runs, the adapter translates its LangGraph execution into typed AG-UI events. A client subscribes to those events and updates as they arrive, rather than waiting for the final answer. A deep agent run maps onto many AG-UI event types. The main ones, among others: State updates use STATE_SNAPSHOT for a full baseline and STATE_DELTA (JSON Patch, RFC 6902) for incremental changes, so a client can keep todos, plans, and subagent status in sync without re-sending the whole state on every step. To watch the stream directly, run the agent with a subscriber. Each event has a matching on…Event callback:
observe.ts
When a deep agent pauses for human input, the run finishes with an interrupt. By default, @ag-ui/langgraph emits a legacy on_interrupt custom event alongside RUN_FINISHED. To receive the structured AG-UI interrupt outcome on RUN_FINISHED (outcome.type === "interrupt"), set emitInterruptOutcome: true when you construct the agent:
Resume the run by sending the standard AG-UI resume field on the next input:
For the interrupt model itself, see Human-in-the-loop.
For the complete event schema, see the AG-UI events reference.

Connect a frontend

Any AG-UI client can drive a deep agent exposed over the protocol, so you do not have to build message rendering, streaming, or state sync yourself. Point the client at the adapter (or a runtime that wraps it) and select the agent by its graphId.

CopilotKit

React chat runtime with AG-UI support for LangGraph and Deep Agents, including the Python FastAPI bridge.

AG-UI clients

The full list of AG-UI clients and SDKs, including terminal and mobile clients.

Build a custom client

Consume the event stream directly with the AG-UI SDK to build your own interface.

Programmatic API

LangGraphAgent connects to a deep agent on a LangGraph server and exposes it as an AG-UI agent. Construct it with the graph to load, then drive it with a few methods.
  • runAgent(parameters?, subscriber?): Run the agent and stream AG-UI events to the subscriber’s on…Event callbacks (see Stream events). Resolves when the run finishes.
  • subscribe(subscriber): Attach a persistent subscriber that receives events across every run, rather than for a single call.
  • abortRun(): Cancel the run in progress.
To seed input, pass initialMessages to the constructor, or call addMessage or setMessages before running.

See also