### Execute Development Commands
Source: https://context7.com/copilotkit/with-langgraph-python/llms.txt
Standard commands for installing dependencies, running the development environment, and managing build/lint processes for the monorepo.
```bash
# Install dependencies (all apps)
pnpm install
# Start all apps (app, agent, mcp)
pnpm dev
# Start individually
pnpm dev:app # Next.js frontend on port 3000
pnpm dev:agent # LangGraph agent on port 8123
pnpm dev:mcp # MCP server
# Build all apps
pnpm build
# Lint all apps
pnpm lint
# Environment setup
echo 'OPENAI_API_KEY=your-key-here' > apps/agent/.env
```
--------------------------------
### CopilotKit Provider Setup in Layout
Source: https://context7.com/copilotkit/with-langgraph-python/llms.txt
Wrap your application with the CopilotKit provider to enable agent integration. Ensure the runtimeUrl is correctly set to your API endpoint.
```typescript
// apps/app/src/app/layout.tsx
"use client";
import "./globals.css";
import "@copilotkit/react-core/v2/styles.css";
import { CopilotKit } from "@copilotkit/react-core";
import { ThemeProvider } from "@/hooks/use-theme";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
{children}
);
}
```
--------------------------------
### Define Todo and Agent State Schema
Source: https://github.com/copilotkit/with-langgraph-python/blob/main/CLAUDE.md
Defines the structure for individual todos and the overall agent state, including a tool for managing todos. This is part of the Python agent's backend setup.
```python
class Todo(TypedDict):
id: str
title: str
description: str
emoji: str
status: Literal["pending", "completed"]
class AgentState(TypedDict):
todos: list[Todo]
@tool
def manage_todos(todos: list[Todo], runtime: ToolRuntime) -> Command:
"""Manage the current todos."""
return Command(update={"todos": todos, ...})
```
--------------------------------
### Set up CopilotKit Runtime API Route
Source: https://context7.com/copilotkit/with-langgraph-python/llms.txt
Configure the Next.js API route to connect the frontend to the LangGraph agent. This involves setting up the CopilotRuntime with agent connection, A2UI support, and optional MCP integrations.
```typescript
// apps/app/src/app/api/copilotkit/route.ts
import {
CopilotRuntime,
ExperimentalEmptyAdapter,
copilotRuntimeNextJSAppRouterEndpoint,
} from "@copilotkit/runtime";
import { LangGraphAgent } from "@copilotkit/runtime/langgraph";
import { NextRequest } from "next/server";
// Define the agent connection to LangGraph
const defaultAgent = new LangGraphAgent({
deploymentUrl: process.env.LANGGRAPH_DEPLOYMENT_URL || "http://localhost:8123",
graphId: "sample_agent",
langsmithApiKey: process.env.LANGSMITH_API_KEY || "",
});
// Define the route and CopilotRuntime
export const POST = async (req: NextRequest) => {
const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
endpoint: "/api/copilotkit",
serviceAdapter: new ExperimentalEmptyAdapter(),
runtime: new CopilotRuntime({
agents: { default: defaultAgent },
a2ui: { injectA2UITool: true },
mcpApps: {
servers: [{
type: "http",
url: process.env.MCP_SERVER_URL || "https://mcp.excalidraw.com",
serverId: "example_mcp_app",
}],
},
}),
});
return handleRequest(req);
};
```
--------------------------------
### Configure Environment Variables
Source: https://github.com/copilotkit/with-langgraph-python/blob/main/CLAUDE.md
Sets the required API key for the agent.
```bash
# Set OpenAI API key for the agent
echo 'OPENAI_API_KEY=your-key-here' > apps/agent/.env
```
--------------------------------
### Development Commands
Source: https://github.com/copilotkit/with-langgraph-python/blob/main/CLAUDE.md
Common CLI commands for managing the Turborepo monorepo.
```bash
# Install dependencies (all apps)
pnpm install
# Start all apps (app, agent, mcp)
pnpm dev
# Start individually
pnpm dev:app # Next.js frontend on port 3000
pnpm dev:agent # LangGraph agent on port 8123
pnpm dev:mcp # MCP server
# Build all apps
pnpm build
# Lint all apps
pnpm lint
```
--------------------------------
### Implement Todo Management Tool
Source: https://context7.com/copilotkit/with-langgraph-python/llms.txt
Create a tool to manage the current todos, ensuring all todos have unique IDs and updating the agent's state. This tool returns a Command to persist state changes.
```python
from langchain.tools import ToolRuntime, tool
from langchain.messages import ToolMessage
from langgraph.types import Command
import uuid
@tool
def manage_todos(todos: list[Todo], runtime: ToolRuntime) -> Command:
"""
Manage the current todos.
"""
# Ensure all todos have unique IDs
for todo in todos:
if "id" not in todo or not todo["id"]:
todo["id"] = str(uuid.uuid4())
# Update the state
return Command(update={
"todos": todos,
"messages": [
ToolMessage(
content="Successfully updated todos",
tool_call_id=runtime.tool_call_id
)
]
})
@tool
def get_todos(runtime: ToolRuntime):
"""
Get the current todos.
"""
return runtime.state.get("todos", [])
todo_tools = [manage_todos, get_todos]
```
--------------------------------
### Create LangGraph Agent with CopilotKit Middleware
Source: https://context7.com/copilotkit/with-langgraph-python/llms.txt
Initialize a LangGraph agent with CopilotKit middleware, tools, and state schema. The agent processes user messages and can manipulate application state through defined tools.
```python
from copilotkit import CopilotKitMiddleware
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from src.todos import AgentState, todo_tools
from src.query import query_data
from src.form import generate_form
agent = create_agent(
model=ChatOpenAI(model="gpt-5-mini", reasoning={"effort": "low", "summary": "concise"}),
tools=[query_data, *todo_tools, generate_form],
middleware=[CopilotKitMiddleware()],
state_schema=AgentState,
system_prompt="""
You are a helpful assistant that helps users understand CopilotKit and LangGraph used together.
Be brief in your explanations of CopilotKit and LangGraph, 1 to 2 sentences.
When demonstrating charts, always call the query_data tool to fetch all data from the database first.
""",
)
graph = agent
```
--------------------------------
### Implement Todo Tools
Source: https://github.com/copilotkit/with-langgraph-python/blob/main/CLAUDE.md
Defines tools for managing and retrieving todo items within the agent state.
```python
@tool
def manage_todos(todos: list[Todo], runtime: ToolRuntime) -> Command:
"""Manage the current todos."""
# Ensure todos have unique IDs
for todo in todos:
if "id" not in todo or not todo["id"]:
todo["id"] = str(uuid.uuid4())
# Update agent state
return Command(update={
"todos": todos,
"messages": [ToolMessage(...)]
})
@tool
def get_todos(runtime: ToolRuntime):
"""Get the current todos."""
return runtime.state.get("todos", [])
```
--------------------------------
### Implement Data Query Tool
Source: https://context7.com/copilotkit/with-langgraph-python/llms.txt
Create a tool to query data from a CSV database. This tool takes a natural language query and should always be called before displaying charts or graphs. The data is read at module load time.
```python
from langchain.tools import tool
from pathlib import Path
import csv
# Read data at module load time
_csv_path = Path(__file__).parent / "db.csv"
with open(_csv_path) as _f:
_cached_data = list(csv.DictReader(_f))
@tool
def query_data(query: str):
"""
Query the database, takes natural language. Always call before showing a chart or graph.
"""
return _cached_data
# Example data structure returned:
# [
# {"date": "2026-01-05", "category": "Revenue", "subcategory": "Enterprise Subscriptions", "amount": "45000", "type": "income"},
# {"date": "2026-01-10", "category": "Expenses", "subcategory": "Engineering Salaries", "amount": "42000", "type": "expense"},
# ...
# ]
```
--------------------------------
### Define LangGraph Agent
Source: https://github.com/copilotkit/with-langgraph-python/blob/main/CLAUDE.md
Initializes the agent with tools, middleware, and state schema.
```python
from langchain.agents import create_agent
from copilotkit import CopilotKitMiddleware
from src.todos import todo_tools, AgentState
agent = create_agent(
model="gpt-5.2",
tools=[*todo_tools, ...], # manage_todos, get_todos
middleware=[CopilotKitMiddleware()],
state_schema=AgentState, # Defines state shape
system_prompt="You are a helpful assistant..."
)
```
--------------------------------
### Create Human-in-the-Loop Component with useHumanInTheLoop
Source: https://context7.com/copilotkit/with-langgraph-python/llms.txt
Create interactive components that pause agent execution to collect user input. The agent waits for the user's response before continuing. This is useful for scheduling or confirming actions.
```typescript
// apps/app/src/hooks/use-generative-ui-examples.tsx
import { z } from "zod";
import { useHumanInTheLoop } from "@copilotkit/react-core/v2";
import { MeetingTimePicker } from "@/components/generative-ui/meeting-time-picker";
export const useGenerativeUIExamples = () => {
useHumanInTheLoop({
name: "scheduleTime",
description: "Use human-in-the-loop to schedule a meeting with the user.",
parameters: z.object({
reasonForScheduling: z.string().describe("Reason for scheduling, very brief - 5 words."),
meetingDuration: z.number().describe("Duration of the meeting in minutes"),
}),
render: ({ respond, status, args }) => {
return ;
},
});
};
// MeetingTimePicker component
export function MeetingTimePicker({ status, respond, reasonForScheduling, meetingDuration }) {
const handleSelectSlot = (slot) => {
// Send response back to agent
respond?.(`Meeting scheduled for ${slot.date} at ${slot.time} (${slot.duration}).`);
};
const handleDecline = () => {
respond?.("The user declined all proposed meeting times. Please suggest alternative times.");
};
// Render time slot selection UI...
}
```
--------------------------------
### Register Frontend Tool with useFrontendTool
Source: https://context7.com/copilotkit/with-langgraph-python/llms.txt
Register frontend tools that the agent can invoke to manipulate the UI. These tools run in the browser and can access React state and hooks. Use this to allow agents to perform actions like toggling themes.
```typescript
// apps/app/src/hooks/use-generative-ui-examples.tsx
import { z } from "zod";
import { useFrontendTool } from "@copilotkit/react-core/v2";
import { useTheme } from "@/hooks/use-theme";
export const useGenerativeUIExamples = () => {
const { theme, setTheme } = useTheme();
// Agent can call this tool to toggle dark/light mode
useFrontendTool({
name: "toggleTheme",
description: "Frontend tool for toggling the theme of the app.",
parameters: z.object({}),
handler: async () => {
setTheme(theme === "dark" ? "light" : "dark");
},
}, [theme, setTheme]);
};
// Usage: Agent says "toggle the theme" and this tool runs in the browser
```
--------------------------------
### Register React Component with useComponent
Source: https://context7.com/copilotkit/with-langgraph-python/llms.txt
Register React components that the agent can render in the chat. Use Zod schemas to define component props that the agent will provide. This allows for rich, interactive UI elements to be displayed directly in the conversation.
```typescript
// apps/app/src/hooks/use-generative-ui-examples.tsx
import { z } from "zod";
import { useComponent } from "@copilotkit/react-core/v2";
import { PieChart, PieChartProps } from "@/components/generative-ui/charts/pie-chart";
import { BarChart, BarChartProps } from "@/components/generative-ui/charts/bar-chart";
export const useGenerativeUIExamples = () => {
// Register pie chart component
useComponent({
name: "pieChart",
description: "Controlled Generative UI that displays data as a pie chart.",
parameters: PieChartProps,
render: PieChart,
});
// Register bar chart component
useComponent({
name: "barChart",
description: "Controlled Generative UI that displays data as a bar chart.",
parameters: BarChartProps,
render: BarChart,
});
};
// Chart props schema
export const PieChartProps = z.object({
title: z.string().describe("Chart title"),
description: z.string().describe("Brief description or subtitle"),
data: z.array(
z.object({
label: z.string(),
value: z.number(),
}),
),
});
```
--------------------------------
### Build Custom Chat Interface with useAgent API
Source: https://context7.com/copilotkit/with-langgraph-python/llms.txt
Build custom chat interfaces using the low-level `useAgent` hook. Access messages, send user input, and control agent execution directly. This provides full control over the chat UI and agent interaction.
```typescript
// apps/app/src/components/headless-chat.tsx
import { useAgent } from "@copilotkit/react-core/v2";
import { useCallback, useState } from "react";
export const HeadlessChat = () => {
const { agent } = useAgent();
const [message, setMessage] = useState("");
const sendMessage = useCallback((message: string) => {
// Add user message to the conversation
agent.addMessage({
role: "user",
id: crypto.randomUUID(),
content: message,
});
// Trigger agent execution
agent.runAgent();
setMessage("");
}, [agent]);
return (
Chat
{/* Display all messages */}
{agent.messages.map((message) => (
{JSON.stringify(message.content)}
))}
{/* Input and send button */}
setMessage(e.target.value)}
/>
);
};
```
--------------------------------
### Define Agent State Schema with TypedDict
Source: https://context7.com/copilotkit/with-langgraph-python/llms.txt
Define the state structure for the agent using Python's TypedDict. This schema is shared between the agent backend and synced to the frontend via CopilotKit.
```python
from langchain.agents import AgentState as BaseAgentState
from typing import TypedDict, Literal
class Todo(TypedDict):
id: str
title: str
description: str
emoji: str
status: Literal["pending", "completed"]
class AgentState(BaseAgentState):
todos: list[Todo]
```
--------------------------------
### Create Canvas Component
Source: https://github.com/copilotkit/with-langgraph-python/blob/main/CLAUDE.md
Uses the useAgent hook to read and update agent state in the UI.
```typescript
export function Canvas() {
const { agent } = useAgent(); // CopilotKit v2 hook
return (
);
}
```
--------------------------------
### Implement Todo List Component
Source: https://github.com/copilotkit/with-langgraph-python/blob/main/CLAUDE.md
Handles local todo logic and triggers state updates via the onUpdate callback.
```typescript
export function TodoList({ todos, onUpdate, isAgentRunning }: TodoListProps) {
const toggleStatus = (todo: Todo) => {
const updated = todos.map((t) =>
t.id === todo.id
? { ...t, status: t.status === "completed" ? "pending" : "completed" }
: t
);
onUpdate(updated); // Calls agent.setState()
};
const addTodo = () => {
const newTodo = { id: crypto.randomUUID(), ... };
onUpdate([...todos, newTodo]);
};
return (
);
}
```
--------------------------------
### TodoList Component for Agent State Manipulation
Source: https://context7.com/copilotkit/with-langgraph-python/llms.txt
Implement UI components that interact with agent state. All state modifications should be performed using `agent.setState()`, which ensures synchronization with the backend.
```typescript
// apps/app/src/components/example-canvas/todo-list.tsx
"use client";
interface Todo {
id: string;
title: string;
description: string;
emoji: string;
status: "pending" | "completed";
}
interface TodoListProps {
todos: Todo[];
onUpdate: (todos: Todo[]) => void;
isAgentRunning: boolean;
}
export function TodoList({ todos, onUpdate, isAgentRunning }: TodoListProps) {
const pendingTodos = todos.filter((t) => t.status === "pending");
const completedTodos = todos.filter((t) => t.status === "completed");
const toggleStatus = (todo: Todo) => {
const updated = todos.map((t) =>
t.id === todo.id
? { ...t, status: t.status === "completed" ? "pending" : "completed" }
: t
);
onUpdate(updated);
};
const deleteTodo = (todo: Todo) => {
onUpdate(todos.filter((t) => t.id !== todo.id));
};
const addTodo = () => {
const newTodo: Todo = {
id: crypto.randomUUID(),
title: "New Todo",
description: "Add a description",
emoji: "🎯",
status: "pending",
};
onUpdate([...todos, newTodo]);
};
// Render columns for pending and completed todos
return (
);
}
```
--------------------------------
### Customize Tool Rendering with useDefaultRenderTool
Source: https://context7.com/copilotkit/with-langgraph-python/llms.txt
Use this hook to control how backend tool executions appear in the chat UI. It allows filtering specific tools and rendering custom components based on execution status and parameters.
```typescript
// apps/app/src/hooks/use-generative-ui-examples.tsx
import { useDefaultRenderTool } from "@copilotkit/react-core/v2";
import { ToolReasoning } from "@/components/tool-rendering";
export const useGenerativeUIExamples = () => {
const ignoredTools = ["generate_form"];
useDefaultRenderTool({
render: ({ name, status, parameters }) => {
// Skip rendering for certain tools
if (ignoredTools.includes(name)) return <>>;
// Show tool execution status
return ;
},
});
};
// ToolReasoning component shows:
// - Tool name
// - Execution status (inProgress, executing, complete)
// - Parameters passed to the tool
```
--------------------------------
### Read Agent State in Frontend
Source: https://github.com/copilotkit/with-langgraph-python/blob/main/CLAUDE.md
Fetches and displays the todo list from the agent's state in the React frontend. It uses the `useAgent` hook to access the agent's state and provides a callback for state updates.
```typescript
const { agent } = useAgent();
return (
agent.setState({ todos: updatedTodos })}
isAgentRunning={agent.isRunning}
/>
);
```
--------------------------------
### Update Agent State on User Interaction
Source: https://github.com/copilotkit/with-langgraph-python/blob/main/CLAUDE.md
Handles user interactions, such as toggling a todo's status, by updating the agent's state directly using `agent.setState()`. This ensures changes are reflected in the single source of truth.
```typescript
// User clicks checkbox → frontend calls agent.setState()
const toggleStatus = (todo) => {
const updated = todos.map(t =>
t.id === todo.id ? { ...t, status: t.status === "completed" ? "pending" : "completed" } : t
);
agent.setState({ todos: updated });
};
```
--------------------------------
### Use useAgent Hook for State Management
Source: https://context7.com/copilotkit/with-langgraph-python/llms.txt
Utilize the `useAgent` hook to read agent state and update it from React components. State changes are synchronized bidirectionally between the frontend and the agent backend.
```typescript
// apps/app/src/components/example-canvas/index.tsx
"use client";
import { useAgent } from "@copilotkit/react-core/v2";
import { TodoList } from "./todo-list";
export function ExampleCanvas() {
const { agent } = useAgent();
return (
);
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.