Integrate cloud persistence and thread management with LangGraph Cloud.
Overview
assistant-cloud provides thread management and persistent chat history for applications built with LangGraph Cloud. This guide shows you how to integrate cloud persistence into your LangGraph application.
Prerequisites
You need an assistant-cloud account to follow this guide. Sign up here to get started.
Setup Guide
Create a Cloud Project
Create a new project in the assistant-cloud dashboard and from the settings page, copy:
- Frontend API URL:
https://proj-[ID].assistant-api.com - API Key: For server-side operations
Configure Environment Variables
Add the following environment variables to your project:
# Frontend API URL from your cloud project settings
NEXT_PUBLIC_ASSISTANT_BASE_URL=https://proj-[YOUR-ID].assistant-api.com
# API key for server-side operations
ASSISTANT_API_KEY=your-api-key-hereInstall Dependencies
Install the required packages:
npm install @assistant-ui/react @assistant-ui/react-langgraphCreate the Runtime Provider
Create a runtime provider that integrates LangGraph with assistant-cloud. Choose between anonymous mode for demos/prototypes or authenticated mode for production:
"use client";
import {
AssistantCloud,
AssistantRuntimeProvider,
} from "@assistant-ui/react";
import { useLangGraphRuntime } from "@assistant-ui/react-langgraph";
import { createThread, getThreadState, sendMessage } from "@/lib/chatApi";
import { LangChainMessage } from "@assistant-ui/react-langgraph";
import { useMemo } from "react";
export function MyRuntimeProvider({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const cloud = useMemo(
() =>
new AssistantCloud({
baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
anonymous: true, // Creates browser session-based user ID
}),
[],
);
const runtime = useLangGraphRuntime({
cloud,
stream: async function* (messages, { initialize }) {
const { externalId } = await initialize();
if (!externalId) throw new Error("Thread not found");
return sendMessage({
threadId: externalId,
messages,
});
},
create: async () => {
const { thread_id } = await createThread();
return { externalId: thread_id };
},
load: async (externalId) => {
const state = await getThreadState(externalId);
return {
messages:
(state.values as { messages?: LangChainMessage[] }).messages ?? [],
};
},
});
return (
<AssistantRuntimeProvider runtime={runtime}>
{children}
</AssistantRuntimeProvider>
);
}"use client";
import {
AssistantCloud,
AssistantRuntimeProvider,
} from "@assistant-ui/react";
import { useLangGraphRuntime } from "@assistant-ui/react-langgraph";
import { createThread, getThreadState, sendMessage } from "@/lib/chatApi";
import { LangChainMessage } from "@assistant-ui/react-langgraph";
import { useAuth } from "@clerk/nextjs";
import { useMemo } from "react";
export function MyRuntimeProvider({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const { getToken } = useAuth();
const cloud = useMemo(
() =>
new AssistantCloud({
baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
authToken: async () => getToken({ template: "assistant-ui" }),
}),
[getToken],
);
const runtime = useLangGraphRuntime({
cloud,
stream: async function* (messages, { initialize }) {
const { externalId } = await initialize();
if (!externalId) throw new Error("Thread not found");
return sendMessage({
threadId: externalId,
messages,
});
},
create: async () => {
const { thread_id } = await createThread();
return { externalId: thread_id };
},
load: async (externalId) => {
const state = await getThreadState(externalId);
return {
messages:
(state.values as { messages?: LangChainMessage[] }).messages ?? [],
};
},
});
return (
<AssistantRuntimeProvider runtime={runtime}>
{children}
</AssistantRuntimeProvider>
);
}For Clerk authentication, configure the "assistant-ui" token template in
your Clerk dashboard.
The useLangGraphRuntime hook now directly accepts cloud, create, and load parameters for simplified thread management. The runtime handles thread lifecycle internally.
Add Thread UI Components
Install the thread list component:
npx assistant-ui@latest add thread-listnpx shadcn@latest add https://r.assistant-ui.com/thread-list.jsonnpx shadcn@latest add https://r.assistant-ui.com/thread-list.jsonThen add it to your application layout:
import { Thread } from "@/components/assistant-ui/thread";
import { ThreadList } from "@/components/assistant-ui/thread-list";
export default function ChatPage() {
return (
<div className="grid h-dvh grid-cols-[250px_1fr] gap-x-2">
<ThreadList />
<Thread />
</div>
);
}Authentication
The examples above show two authentication modes:
- Anonymous: Suitable for demos and prototypes. Creates a browser session-based user ID.
- Authenticated: For production use with user accounts. The authenticated example uses Clerk, but you can integrate any auth provider.
For other authentication providers or custom implementations, see the Cloud Authorization guide.
Next Steps
- Learn about LangGraph runtime setup for your application
- Explore ThreadListRuntime for advanced thread management
- Check out the LangGraph example on GitHub