Supported LangChain and LangGraph integration primitives for streaming OpenUI generative interfaces over AG-UI.
The package connects three pieces:
- A LangGraph stream transformer converts protocol-v2
messagesandtoolsevents to AG-UI events on the remotecustom:openuichannel. - A server helper starts a stateless LangGraph run, adds strict AG-UI run lifecycle events, and relays that channel as Server-Sent Events.
- OpenUI's
agUIAdapter()consumes the response without LangChain-specific frontend code.
The APIs use Web-standard Request, Response, fetch, and ReadableStream.
They do not depend on Next.js or DeepAgents.
npm install @openuidev/langchainThe server helpers communicate with LangGraph over HTTP and do not load the
LangGraph runtime. Install @langchain/langgraph only in applications that use
the agent-side transformer:
npm install @openuidev/langchain @langchain/langgraph@langchain/langgraph is an optional peer dependency. The supported range is
declared in this package's peerDependencies so applications retain control of
their LangGraph version.
The server helpers require an agent-protocol-v2 server that supports both the
custom:* and root lifecycle event channels. The tested local-server baseline
is @langchain/langgraph-cli 1.4.x; older servers that reject the lifecycle
channel are not supported.
The transformer works with any agent that accepts LangGraph
streamTransformers. Here is the minimal DeepAgents setup:
import { openUIStreamTransformer } from "@openuidev/langchain/transformer";
import { createDeepAgent } from "deepagents";
export const graph = createDeepAgent({
model: "openai:gpt-5.5",
tools: [getWeather, getStockPrice, searchWeb],
systemPrompt: SYSTEM_PROMPT,
streamTransformers: [openUIStreamTransformer],
});openUIStreamTransformer() converts assistant text, tool-call deltas, tool
results, and run errors into AG-UI events. LangGraph forwards those events
remotely under the custom:openui channel.
createLangChainStreamResponse accepts any Web-standard Request, so it can be
returned directly from Next.js and other compatible route handlers:
import { createLangChainStreamResponse } from "@openuidev/langchain";
export const runtime = "nodejs";
export async function POST(request: Request) {
return createLangChainStreamResponse(request, {
apiUrl: process.env.LANGGRAPH_API_URL ?? "http://localhost:2024",
assistantId: process.env.LANGGRAPH_ASSISTANT_ID ?? "agent",
apiKey: process.env.LANGSMITH_API_KEY,
debug: process.env.NODE_ENV !== "production",
});
}Use prepareInput when the graph needs additional fields from the browser
request, such as a provider-managed conversation id or model selection:
return createLangChainStreamResponse(request, {
apiUrl: process.env.LANGGRAPH_API_URL ?? "http://localhost:2024",
assistantId: "agent",
prepareInput: ({ messages, requestBody }) => ({
messages: messages.slice(-1),
conversationId: requestBody.threadId,
model: requestBody.model,
}),
});The route expects a non-empty { messages: Message[] } body in AG-UI format and
returns a JSON 400 response for malformed input. It converts text and
multimodal user content to LangChain messages. Complete assistant tool-call and
tool-result pairs are preserved; only incomplete calls and orphaned results are
removed before starting the stateless run.
Each call uses a temporary LangGraph thread and makes a bounded cleanup attempt
before closing a normally completed response. Pass cleanupThread: false when
the thread must remain available for local debugging. On serverless platforms,
pass the platform's waitUntil-style registration function through the
waitUntil option so cleanup can survive a client disconnect. Upstream response
bodies and registered graph ids are redacted from stream errors by default;
pass debug: true only in a trusted development environment to include them.
The route returns AG-UI SSE with RUN_STARTED and RUN_FINISHED/RUN_ERROR
lifecycle events, so the browser only needs OpenUI's AG-UI adapter:
import { AgentInterface, agUIAdapter, fetchLLM } from "@openuidev/react-ui";
const llm = fetchLLM({
url: "/api/chat",
streamAdapter: agUIAdapter(),
});
export function Chat() {
return <AgentInterface llm={llm} />;
}Use streamOpenUI when a route needs to build the LangGraph input itself:
import { streamOpenUI } from "@openuidev/langchain";
const body = streamOpenUI({
apiUrl: "http://localhost:2024",
assistantId: "agent",
input: { messages: [{ type: "human", content: "Hello" }] },
signal: request.signal,
});
return new Response(body, {
headers: { "Content-Type": "text/event-stream" },
});Cancelling the returned stream or aborting the supplied signal aborts both upstream LangGraph requests.
openUIStreamTransformer()from@openuidev/langchain/transformer— LangGraph stream-transformer factory that publishes message and tool events oncustom:openui.createLangChainStreamResponse(request, options)— complete AG-UI request to LangGraph response path for stateless chat routes.streamOpenUI(options)— lower-level protocol-v2 runner and custom-channel relay.CreateLangChainStreamResponseOptions,PrepareLangChainRunInputContext,StreamOpenUIOptions, andLangChainInputMessage— exported TypeScript types.
See the repository's
examples/langchain-chat
for a complete local and LangGraph Platform example.