Bug Report: Thread Messages Not Loading in CopilotKit v2
Issue Summary
When navigating to a thread page (e.g., /t/[thread_id]), the existing thread messages from LangGraph are not being loaded and displayed in the chat UI, despite the threadId being correctly passed to CopilotChatConfigurationProvider and useAgent.
Environment
- CopilotKit Version:
1.50.0-beta.4
- AG-UI LangGraph:
0.0.19
- Next.js:
16.0.1
- Framework: React with TypeScript
Expected Behavior
- User navigates to
/t/abc123 where abc123 is an existing thread with messages
CopilotChatConfigurationProvider receives the threadId
useAgent hook automatically loads existing messages from that thread
- Messages appear in the chat UI
Actual Behavior
threadId is correctly passed to CopilotChatConfigurationProvider
useAgent hook is called with correct agentId
- No messages are loaded from the thread
- Chat appears empty despite thread having messages in LangGraph backend
Configuration
Page Setup (/t/[thread_id]/page.tsx)
export default function ThreadPage({ params }: { params: Promise<{ thread_id: string }>; }) {
const { thread_id } = use(params);
const setCurrentThread = useStore((state) => state.setCurrentThread);
useEffect(() => {
if (thread_id) {
console.log("Setting thread ID:", thread_id);
setCurrentThread(thread_id);
}
}, [thread_id, setCurrentThread]);
return (
<CopilotKitProvider
runtimeUrl="/api/copilotkit"
showDevConsole={true}
>
<CopilotChatConfigurationProvider
threadId={thread_id}
agentId={agent_id}
>
<HomeContent />
</CopilotChatConfigurationProvider>
</CopilotKitProvider>
);
}
Chat Component (chat-content.tsx)
export function ChatContent() {
// Get threadId from CopilotChatConfigurationProvider
const chatConfig = useCopilotChatConfiguration();
const threadId = chatConfig?.threadId || useStore((state) => state.currentThread);
console.log("Thread ID from config:", threadId);
const graphId = process.env.NEXT_PUBLIC_AGENT_ID || "pricing_agent";
// useAgent should automatically pick up threadId from context
const { agent } = useAgent({
agentId: graphId,
updates: [UseAgentUpdate.OnMessagesChanged]
});
// Debug logging
useEffect(() => {
console.log("Agent messages updated:", agent.messages.length, "messages");
console.log("Messages:", agent.messages);
}, [agent.messages]);
// ... rest of component
}
Backend Configuration (/api/copilotkit/[[...slug]]/route.ts)
const runtime = new CopilotRuntime({
agents: {
"pricing_agent": new LangGraphAgent({
deploymentUrl: process.env.LANGGRAPH_DEPLOYMENT_URL || "http://localhost:2024",
graphId: "pricing_agent",
langsmithApiKey: process.env.LANGSMITH_API_KEY || ""
}),
}
});
const app = createCopilotEndpoint({
runtime,
basePath: "/api/copilotkit"
});
export const GET = handle(app);
export const POST = handle(app);
Console Logs
When navigating to thread page:
Setting thread ID: abc123
Thread ID from config: abc123
CopilotKit: {...}
Agent messages updated: 0 messages
Messages: []
Note: agent.messages always shows as empty array, never populates with thread messages.
What We've Tried
Attempt 1: Manual Message Loading
Added useEffect to manually fetch and set messages:
useEffect(() => {
const loadThreadMessages = async () => {
if (!threadId) return;
const response = await fetch(`/api/langgraph/threads?threadId=${threadId}`);
const threadState = await response.json();
const messages = threadState?.values?.messages || [];
if (messages.length > 0) {
const formattedMessages = messages.map((msg: any) => ({
id: msg.id || crypto.randomUUID(),
role: msg.type === "human" ? "user" :
msg.type === "ai" ? "assistant" :
msg.type || "assistant",
content: msg.content || "",
}));
agent.setMessages(formattedMessages);
}
};
loadThreadMessages();
}, [threadId]);
Result: Messages are loaded from API but agent.setMessages() doesn't persist them or trigger re-render.
Attempt 2: Check AgentConfig Interface
Checked if threadId should be passed directly to useAgent:
interface AgentConfig {
agentId?: string;
description?: string;
threadId?: string; // ← This exists in interface
initialMessages?: Message[];
initialState?: State;
debug?: boolean;
}
Issue: useAgent hook from @copilotkit/react-core/v2 doesn't accept threadId parameter (TypeScript error).
Attempt 3: Using Updates Flag
const { agent } = useAgent({
agentId: graphId,
updates: [UseAgentUpdate.OnMessagesChanged]
});
Result: Still no messages loaded.
Questions
-
Is CopilotChatConfigurationProvider supposed to automatically load thread messages? Or is it just for passing threadId metadata?
-
Should useAgent automatically fetch messages when threadId changes? Or does this require explicit implementation?
-
Is there a method on the agent object to explicitly load thread history? We found setMessages but it doesn't seem to work as expected.
-
Does AG-UI LangGraphAgent integration support thread persistence out of the box? Or does this need custom implementation?
Workaround Needed
Currently, we need a way to:
- Load existing messages from a LangGraph thread
- Display them in the CopilotKit chat UI
- Continue the conversation in that thread context
Additional Context
- LangGraph Backend: Running at
http://localhost:2024
- Thread API:
/api/langgraph/threads?threadId=X returns valid thread state with messages
- New messages: Work fine when creating new threads
- Thread creation: New threads are created successfully
- Thread switching: Problem only occurs when navigating to existing threads
Related Code References
- Thread Page:
src/app/(dashboard)/t/[thread_id]/page.tsx
- Chat Component:
src/components/chat/chat-content.tsx
- API Route:
src/app/api/copilotkit/[[...slug]]/route.ts
- Backend Config: LangGraph server with AG-UI integration
Screenshots/Logs
Console when navigating to thread with existing messages:
✓ Setting thread ID: abc123
✓ Thread ID from config: abc123
✓ Loading thread state for: abc123
✓ Thread state loaded: { values: { messages: [5 messages] } }
✓ Messages from thread: 5 [Array with actual messages]
✓ Setting formatted messages: [5 formatted messages]
✗ Agent messages updated: 0 messages ← Problem: Should be 5
✗ Messages: [] ← Problem: Should contain 5 messages
The thread state is successfully loaded from the backend, messages are formatted correctly, but they never appear in agent.messages.
Impact
- Severity: High
- Frequency: Always
- User Impact: Cannot view or continue existing conversations
- Workaround Available: No
Requested Solution
Documentation or guidance on the correct way to:
- Load and display existing thread messages when using CopilotKit v2 with LangGraph
- Properly integrate thread persistence between CopilotKit UI and LangGraph backend
- Handle thread navigation and message history in AG-UI integration
Created: December 11, 2024
Reporter: Development Team
Priority: High
Bug Report: Thread Messages Not Loading in CopilotKit v2
Issue Summary
When navigating to a thread page (e.g.,
/t/[thread_id]), the existing thread messages from LangGraph are not being loaded and displayed in the chat UI, despite the threadId being correctly passed toCopilotChatConfigurationProvideranduseAgent.Environment
1.50.0-beta.40.0.1916.0.1Expected Behavior
/t/abc123whereabc123is an existing thread with messagesCopilotChatConfigurationProviderreceives thethreadIduseAgenthook automatically loads existing messages from that threadActual Behavior
threadIdis correctly passed toCopilotChatConfigurationProvideruseAgenthook is called with correctagentIdConfiguration
Page Setup (
/t/[thread_id]/page.tsx)Chat Component (
chat-content.tsx)Backend Configuration (
/api/copilotkit/[[...slug]]/route.ts)Console Logs
When navigating to thread page:
Note:
agent.messagesalways shows as empty array, never populates with thread messages.What We've Tried
Attempt 1: Manual Message Loading
Added
useEffectto manually fetch and set messages:Result: Messages are loaded from API but
agent.setMessages()doesn't persist them or trigger re-render.Attempt 2: Check AgentConfig Interface
Checked if
threadIdshould be passed directly touseAgent:Issue:
useAgenthook from@copilotkit/react-core/v2doesn't acceptthreadIdparameter (TypeScript error).Attempt 3: Using Updates Flag
Result: Still no messages loaded.
Questions
Is
CopilotChatConfigurationProvidersupposed to automatically load thread messages? Or is it just for passing threadId metadata?Should
useAgentautomatically fetch messages when threadId changes? Or does this require explicit implementation?Is there a method on the agent object to explicitly load thread history? We found
setMessagesbut it doesn't seem to work as expected.Does AG-UI LangGraphAgent integration support thread persistence out of the box? Or does this need custom implementation?
Workaround Needed
Currently, we need a way to:
Additional Context
http://localhost:2024/api/langgraph/threads?threadId=Xreturns valid thread state with messagesRelated Code References
src/app/(dashboard)/t/[thread_id]/page.tsxsrc/components/chat/chat-content.tsxsrc/app/api/copilotkit/[[...slug]]/route.tsScreenshots/Logs
Console when navigating to thread with existing messages:
The thread state is successfully loaded from the backend, messages are formatted correctly, but they never appear in
agent.messages.Impact
Requested Solution
Documentation or guidance on the correct way to:
Created: December 11, 2024
Reporter: Development Team
Priority: High