# http://docs.copilotkit.ai llms-full.txt

## CopilotKit Documentation
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is CopilotKit?

# Introduction

Build production-ready Copilots and Agents effortlessly.

# [What is CopilotKit?](https://docs.copilotkit.ai/\#what-is-copilotkit)

At its core, CopilotKit is a set of tools that make it easy to **let your users work**
**alongside Large Language Models (LLMs) to accomplish generative tasks** directly in
your application. Instead of just using the LLM to generate content, you can let it
take direct action alongside your users.

Interacting with these models can be done directly ( **Standard**) or through agents ( **CoAgents**).

## [Standard](https://docs.copilotkit.ai/\#standard)

Utilize CopilotKit's standard agentic runloop to get started quickly.

[**Quickstart** \\
Get started with CopilotKit directly in your application.](https://docs.copilotkit.ai/quickstart) [**Tutorial** \\
Build an AI todo app with CopilotKit in minutes.](https://docs.copilotkit.ai/tutorials/ai-todo-app/overview)

## [CoAgents](https://docs.copilotkit.ai/\#coagents)

When you need **complete control** over the agentic runloop, you can use **CoAgents**. Bridge the remaining gap between demos and production-ready experiences.

[**LangGraph** \\
User-interactive agents with LangGraph.](https://docs.copilotkit.ai/coagents) [CrewAI\\
**CrewAI Crews** \\
Build multi-agent workflows with CrewAI.](https://docs.copilotkit.ai/crewai-crews) [CrewAI\\
**CrewAI Flows** \\
Build multi-agent workflows with CrewAI.](https://docs.copilotkit.ai/crewai-flows)

## [CopilotKit in Action](https://docs.copilotkit.ai/\#copilotkit-in-action)

Need some inspiration? Check out somethings we've built with CopilotKit.

[**Feature Viewer** \\
Learn about all of the best features CopilotKit has to offer with an interactive experience.](https://feature-viewer-langgraph.vercel.app/) [**Spreadsheet Copilot** \\
A powerful spreadsheet assistant that helps users analyze data, create formulas, and generate insights.](https://spreadsheet-demo-tau.vercel.app/) [**SaaS Copilot** \\
An AI-powered banking interface that helps users understand and interact with their finances.](https://brex-demo-temp.vercel.app/) [**Agent-Native Travel Planner** \\
Interactive travel planning assistant that helps users generate and build travel itineraries.](https://examples-coagents-ai-travel-app.vercel.app/) [**Agent-Native Research Canvas** \\
An intelligent research assistant that helps users synthesize information across multiple sources.](https://examples-coagents-research-canvas-ui.vercel.app/)

## [How does CopilotKit work?](https://docs.copilotkit.ai/\#how-does-copilotkit-work)

CopilotKit is thoughtfully architected to scale with you, your teams, and your product.

![](https://docs.copilotkit.ai/_next/image?url=%2Fimages%2Farchitecture-diagram.png&w=3840&q=75)

## [Common Questions](https://docs.copilotkit.ai/\#common-questions)

We've got answers to some common questions!

### What is a Copilot?

### What are the main features of CopilotKit?

### How does it all work?

### Can I use any LLM with CopilotKit?

[Next\\
\\
Quickstart](https://docs.copilotkit.ai/quickstart)

### On this page

[What is CopilotKit?](https://docs.copilotkit.ai/#what-is-copilotkit) [Standard](https://docs.copilotkit.ai/#standard) [CoAgents](https://docs.copilotkit.ai/#coagents) [CopilotKit in Action](https://docs.copilotkit.ai/#copilotkit-in-action) [How does CopilotKit work?](https://docs.copilotkit.ai/#how-does-copilotkit-work) [Common Questions](https://docs.copilotkit.ai/#common-questions) [Concierge](https://docs.copilotkit.ai/#concierge) [Worker](https://docs.copilotkit.ai/#worker) [Batteries included chat components](https://docs.copilotkit.ai/#batteries-included-chat-components) [Deeply integrated Copilots](https://docs.copilotkit.ai/#deeply-integrated-copilots) [Rich agentic experiences](https://docs.copilotkit.ai/#rich-agentic-experiences)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Copilot Infrastructure Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageCopilot Infrastructure for LangGraph Agents

# Introduction

Build Agent-Native Applications (ANAs) powered by CopilotKit and LangGraph.

# [Copilot Infrastructure for LangGraph Agents](https://docs.copilotkit.ai/coagents\#copilot-infrastructure-for-langgraph-agents)

Full user-interaction infrastructure for your agents, to turn your agents into Copilot Agents (CoAgents).

![CoAgents demonstration](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/CoAgents.gif)

## [Building blocks of a CoAgent](https://docs.copilotkit.ai/coagents\#building-blocks-of-a-coagent)

Everything you need to build Agent-Native Applications (ANAs), right out of the box.

[Agentic Chat UI\\
\\
In-app chat powered by your agent.](https://docs.copilotkit.ai/coagents/agentic-chat-ui)

[Shared State\\
\\
Your agent can see everything in your app, and vice versa.](https://docs.copilotkit.ai/coagents/shared-state)

[Generative UI\\
\\
UI that updates in real-time based on your agent's state.](https://docs.copilotkit.ai/coagents/generative-ui)

[Frontend Tools\\
\\
Give your agent the ability to take action in your application.](https://docs.copilotkit.ai/coagents/frontend-actions)

[Multi-Agent Coordination\\
\\
Route your agent to the right agent based on the user's request.](https://docs.copilotkit.ai/coagents/multi-agent-flows)

[Human-in-the-Loop\\
\\
Set smart checkpoints where humans can guide your agents.](https://docs.copilotkit.ai/coagents/human-in-the-loop)

## [CoAgents in action](https://docs.copilotkit.ai/coagents\#coagents-in-action)

See **CoAgents** in action with some videos and examples we've made to demonstrate their power.

IntroductionAgent-Native Travel Planner (ANA)Agent-Native Research Canvas (ANA)

Introduction

[Demo](https://examples-coagents-research-canvas-ui.vercel.app/)

Hear from the CEO of CopilotKit, Atai Barkai, and learn how CoAgents are paving the way for the next generation of AI-native apps.

CoAgents Public Beta - YouTube

CopilotKit

1.27K subscribers

[CoAgents Public Beta](https://www.youtube.com/watch?v=tVjVYJE-Nic)

CopilotKit

Search

Watch later

Share

Copy link

Info

Shopping

Tap to unmute

If playback doesn't begin shortly, try restarting your device.

More videos

## More videos

You're signed out

Videos you watch may be added to the TV's watch history and influence TV recommendations. To avoid this, cancel and sign in to YouTube on your computer.

CancelConfirm

Share

Include playlist

An error occurred while retrieving sharing information. Please try again later.

[Watch on](https://www.youtube.com/watch?v=tVjVYJE-Nic&embeds_referring_euri=https%3A%2F%2Fdocs.copilotkit.ai%2F&embeds_referring_origin=https%3A%2F%2Fdocs.copilotkit.ai)

0:00

0:00 / 1:48•Live

•

[Watch on YouTube](https://www.youtube.com/watch?v=tVjVYJE-Nic "Watch on YouTube")

## [Ready to get started?](https://docs.copilotkit.ai/coagents\#ready-to-get-started)

Get started with CoAgents in as little as 5 minutes with one of our guides or tutorials.

[Quickstart\\
\\
Learn how to build your first CoAgent in 10 minutes.](https://docs.copilotkit.ai/coagents/quickstart/langgraph)

[Travel Agent\\
\\
Learn how to build an agent-native travel app with CopilotKit & LangGraph.](https://docs.copilotkit.ai/coagents/tutorials/ai-travel-app)

[Researcher Agent\\
\\
Learn how to build an agent-native researcher with CopilotKit & LangGraph.](https://docs.copilotkit.ai/coagents/videos/research-canvas)

## [Common Questions](https://docs.copilotkit.ai/coagents\#common-questions)

Have a question about CoAgents? You're in the right place!

### Can you explain what a CoAgent is in more detail?

### Can I attach to an existing thread?

### Can I use CopilotKit without LangGraph?

[Next\\
\\
Quickstart (LangGraph)](https://docs.copilotkit.ai/coagents/quickstart/langgraph)

### On this page

[Copilot Infrastructure for LangGraph Agents](https://docs.copilotkit.ai/coagents#copilot-infrastructure-for-langgraph-agents) [Building blocks of a CoAgent](https://docs.copilotkit.ai/coagents#building-blocks-of-a-coagent) [CoAgents in action](https://docs.copilotkit.ai/coagents#coagents-in-action) [Ready to get started?](https://docs.copilotkit.ai/coagents#ready-to-get-started) [Common Questions](https://docs.copilotkit.ai/coagents#common-questions)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotKit API Reference
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this page

# API Reference

API Reference for CopilotKit's components, classes and hooks.

[**UI Components** \\
See the list of all available UI components in CopilotKit.](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotChat) [**Hooks** \\
See the list of all available hooks in CopilotKit.](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotReadable) [**Classes** \\
See the list of all available classes in CopilotKit.](https://docs.copilotkit.ai/reference/v1/classes/CopilotRuntime) [**LLM Adapters** \\
See the list of all available LLM Adapters in CopilotKit.](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAdapter) [**SDKs** \\
Python and JavaScript SDKs for CopilotKit.](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph)

[Next\\
\\
All Chat Components](https://docs.copilotkit.ai/reference/v1/components/chat)

### On this page

No Headings

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Copilot Infrastructure Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageCopilot Infrastructure for CrewAI Flows

# Introduction

Build Agent-Native Applications (ANAs) powered by CopilotKit and CrewAI Flows.

# [Copilot Infrastructure for CrewAI Flows](https://docs.copilotkit.ai/crewai-flows\#copilot-infrastructure-for-crewai-flows)

Full user-interaction infrastructure for your agents, to turn your agents into Copilot Agents (CoAgents).

## [Building blocks of a CoAgent](https://docs.copilotkit.ai/crewai-flows\#building-blocks-of-a-coagent)

Everything you need to build Agent-Native Applications (ANAs), right out of the box.

[Agentic Chat UI\\
\\
In-app chat powered by your agent.](https://docs.copilotkit.ai/crewai-flows/agentic-chat-ui)

[Shared State\\
\\
Your agent can see everything in your app, and vice versa.](https://docs.copilotkit.ai/crewai-flows/shared-state)

[Generative UI\\
\\
UI that updates in real-time based on your agent's state.](https://docs.copilotkit.ai/crewai-flows/generative-ui)

[Frontend Tools\\
\\
Give your agent the ability to take action in your application.](https://docs.copilotkit.ai/crewai-flows/frontend-actions)

[Multi-Agent Coordination\\
\\
Route your agent to the right agent based on the user's request.](https://docs.copilotkit.ai/crewai-flows/multi-agent-flows)

[Human-in-the-Loop\\
\\
Set smart checkpoints where humans can guide your agents.](https://docs.copilotkit.ai/crewai-flows/human-in-the-loop)

## [Ready to get started?](https://docs.copilotkit.ai/crewai-flows\#ready-to-get-started)

Get started with CoAgents in as little as 5 minutes with one of our guides or tutorials.

[Quickstart\\
\\
Learn how to build your first CoAgent in 10 minutes.](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai)

## [Common Questions](https://docs.copilotkit.ai/crewai-flows\#common-questions)

Have a question about CoAgents? You're in the right place!

### Can you explain what a CoAgent is in more detail?

### Can I attach to an existing thread?

[Next\\
\\
Quickstart CrewAI Flows](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai)

### On this page

[Copilot Infrastructure for CrewAI Flows](https://docs.copilotkit.ai/crewai-flows#copilot-infrastructure-for-crewai-flows) [Building blocks of a CoAgent](https://docs.copilotkit.ai/crewai-flows#building-blocks-of-a-coagent) [Ready to get started?](https://docs.copilotkit.ai/crewai-flows#ready-to-get-started) [Common Questions](https://docs.copilotkit.ai/crewai-flows#common-questions)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/crewai-flows/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## LangGraph Quickstart Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pagePrerequisites

# Quickstart (LangGraph)

Turn your LangGraph into an agent-native application in 10 minutes.

## [Prerequisites](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#prerequisites)

Before you begin, you'll need the following:

- [**LangSmith API key**](https://docs.smith.langchain.com/administration/how_to_guides/organization_management/create_account_api_key#api-keys)
- [**OpenAI API key**](https://platform.openai.com/api-keys)

## [Getting started](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#getting-started)

### [Install CopilotKit](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#install-copilotkit)

First, install the latest packages for CopilotKit into your frontend.

npmpnpmyarnbun

```
npm install @copilotkit/react-ui @copilotkit/react-core
```

Do you already have a LangGraph agent?

You will need a LangGraph agent to get started with CoAgents!

Either bring your own or feel free to use our starter repo.

Bring your own LangGraph agent

I already have a LangGraph agent and want to use it with CopilotKit.

![CopilotKit Logo](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/copilotkit-logo.svg)

Use the CoAgents Starter repo

I don't have a LangGraph agent yet, but want to get started quickly.

### [Start your LangGraph Agent](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#start-your-langgraph-agent)

Local (LangGraph Studio)Self hosted (FastAPI)LangGraph Platform

For local development, you can use the [LangGraph CLI](https://docs.langchain.com/langsmith/cli) to start a development server and LangGraph studio session.

You will need a [LangSmith account](https://smith.langchain.com/) to use this method.

```
# For Python 3.11 or above
langgraph dev --host localhost --port 8000
```

```
# For TypeScript with Node 18 or above
npx @langchain/langgraph-cli dev --host localhost --port 8000
```

After starting the LangGraph server, the deployment URL will be `http://localhost:8000`.

### Having trouble?

Choose your connection method

Now you need to connect your LangGraph agent to CopilotKit.

Copilot Cloud (Recommended)

I want to host my Copilot on Copilot Cloud

Self-Hosted Copilot Runtime

I want to self-host the Copilot Runtime

### [Add a remote endpoint for your LangGraph agent](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#add-a-remote-endpoint-for-your-langgraph-agent)

Using Copilot Cloud, you need to connect a remote endpoint that will connect to your LangGraph agent.

Local (LangGraph Studio)Self hosted (FastAPI)LangGraph Platform

When running your LangGraph agent locally, you can open a tunnel to it so Copilot Cloud can connect to it.
First, make sure you're logged in to [Copilot Cloud](https://cloud.copilotkit.ai/), and then authenticate the CLI by running:

```
npx copilotkit@latest login
```

Once authenticated, run:

```
npx copilotkit@latest dev --port 8000
```

### [Setup your CopilotKit provider](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#setup-your-copilotkit-provider)

The [`<CopilotKit>`](https://docs.copilotkit.ai/reference/v1/components/CopilotKit) component must wrap the Copilot-aware parts of your application. For most use-cases,
it's appropriate to wrap the CopilotKit provider around the entire app, e.g. in your layout.tsx.

Since we're using Copilot Cloud, we need to grab our public API key from the [Copilot Cloud dashboard](https://cloud.copilotkit.ai/).

layout.tsx

```
import "./globals.css";
import { ReactNode } from "react";
import { CopilotKit } from "@copilotkit/react-core";

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        {/* Use the public api key you got from Copilot Cloud  */}
        <CopilotKit
          publicApiKey="<your-copilot-cloud-public-api-key>"
          agent="sample_agent" // the name of the agent you want to use
        >
          {children}
        </CopilotKit>
      </body>
    </html>
  );
}
```

Looking for a way to run multiple LangGraph agents? Check out our [Multi-Agent](https://docs.copilotkit.ai/coagents/multi-agent-flows) guide.

## [Choose a Copilot UI](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#choose-a-copilot-ui)

You are almost there! Now it's time to setup your Copilot UI.

First, import the default styles in your root component (typically `layout.tsx`) :

```
import "@copilotkit/react-ui/styles.css";
```

Copilot UI ships with a number of built-in UI patterns, choose whichever one you like.

CopilotPopupCopilotSidebarCopilotChatHeadless UI

`CopilotPopup` is a convenience wrapper for `CopilotChat` that lives at the same level as your main content in the view hierarchy. It provides **a floating chat interface** that can be toggled on and off.

![Popup Example](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/popup-example.gif)

```
import { CopilotPopup } from "@copilotkit/react-ui";

export function YourApp() {
  return (
    <>
      <YourMainContent />
      <CopilotPopup
        instructions={"You are assisting the user as best as you can. Answer in the best way possible given the data you have."}
        labels={{
          title: "Popup Assistant",
          initial: "Need any help?",
        }}
      />
    </>
  );
}
```

### [🎉 Talk to your agent!](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#-talk-to-your-agent)

Congrats! You've successfully integrated a LangGraph agent chatbot to your application. To start, try asking a few questions to your agent.

```
Can you tell me a joke?
```

```
Can you help me understand AI?
```

```
What do you think about React?
```

### Having trouble?

* * *

## [What's next?](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#whats-next)

You've now got a LangGraph agent running in CopilotKit! Now you can start exploring the various ways that CopilotKit
can help you build power agent native applications.

[**Implement Human in the Loop** \\
Allow your users and agents to collaborate together on tasks.](https://docs.copilotkit.ai/coagents/human-in-the-loop) [**Utilize the Shared State** \\
Learn how to synchronize your agent's state with your UI's state, and vice versa.](https://docs.copilotkit.ai/coagents/shared-state) [**Add some generative UI** \\
Render your agent's progress and output in the UI.](https://docs.copilotkit.ai/coagents/generative-ui) [**Setup frontend actions** \\
Give your agent the ability to call frontend tools, directly updating your application.](https://docs.copilotkit.ai/coagents/frontend-actions)

[Previous\\
\\
Introduction](https://docs.copilotkit.ai/coagents) [Next\\
\\
Chat with an Agent](https://docs.copilotkit.ai/coagents/agentic-chat-ui)

### On this page

[Prerequisites](https://docs.copilotkit.ai/coagents/quickstart/langgraph#prerequisites) [Getting started](https://docs.copilotkit.ai/coagents/quickstart/langgraph#getting-started) [Install CopilotKit](https://docs.copilotkit.ai/coagents/quickstart/langgraph#install-copilotkit) [Clone the coagents-starter repo and install dependencies:](https://docs.copilotkit.ai/coagents/quickstart/langgraph#clone-the-coagents-starter-repo-and-install-dependencies) [Install dependencies:](https://docs.copilotkit.ai/coagents/quickstart/langgraph#install-dependencies) [Install dependencies:](https://docs.copilotkit.ai/coagents/quickstart/langgraph#install-dependencies-1) [Create a .env file](https://docs.copilotkit.ai/coagents/quickstart/langgraph#create-a-env-file) [Add your API keys](https://docs.copilotkit.ai/coagents/quickstart/langgraph#add-your-api-keys) [Start your LangGraph Agent](https://docs.copilotkit.ai/coagents/quickstart/langgraph#start-your-langgraph-agent) [Add a remote endpoint for your LangGraph agent](https://docs.copilotkit.ai/coagents/quickstart/langgraph#add-a-remote-endpoint-for-your-langgraph-agent) [Setup your CopilotKit provider](https://docs.copilotkit.ai/coagents/quickstart/langgraph#setup-your-copilotkit-provider) [Install Copilot Runtime](https://docs.copilotkit.ai/coagents/quickstart/langgraph#install-copilot-runtime) [Setup a Copilot Runtime Endpoint](https://docs.copilotkit.ai/coagents/quickstart/langgraph#setup-a-copilot-runtime-endpoint) [Add your LangGraph deployment to Copilot Runtime](https://docs.copilotkit.ai/coagents/quickstart/langgraph#add-your-langgraph-deployment-to-copilot-runtime) [Configure the CopilotKit Provider](https://docs.copilotkit.ai/coagents/quickstart/langgraph#configure-the-copilotkit-provider) [Choose a Copilot UI](https://docs.copilotkit.ai/coagents/quickstart/langgraph#choose-a-copilot-ui) [🎉 Talk to your agent!](https://docs.copilotkit.ai/coagents/quickstart/langgraph#-talk-to-your-agent) [What's next?](https://docs.copilotkit.ai/coagents/quickstart/langgraph#whats-next)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/quickstart/langgraph.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CrewAI Support
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageCopilot Infrastructure for CrewAI Crews

# Introduction

Build Agent-Native Applications (ANAs) powered by CopilotKit and CrewAI Flows.

# [Copilot Infrastructure for CrewAI Crews](https://docs.copilotkit.ai/crewai-crews\#copilot-infrastructure-for-crewai-crews)

Full user-interaction infrastructure for your agents, to turn your agents into Copilot Agents (CoAgents).

## [Building blocks of a CoAgent](https://docs.copilotkit.ai/crewai-crews\#building-blocks-of-a-coagent)

Everything you need to build Agent-Native Applications (ANAs), right out of the box.

[Agentic Chat UI\\
\\
In-app chat powered by your agent.](https://docs.copilotkit.ai/crewai-crews/agentic-chat-ui)

[Shared State\\
\\
Your agent can see everything in your app, and vice versa.](https://docs.copilotkit.ai/crewai-crews/shared-state)

[Generative UI\\
\\
UI that updates in real-time based on your agent's state.](https://docs.copilotkit.ai/crewai-crews/generative-ui)

[Frontend Tools\\
\\
Give your agent the ability to take action in your application.](https://docs.copilotkit.ai/crewai-crews/frontend-actions)

[Multi-Agent Coordination\\
\\
Route your agent to the right agent based on the user's request.](https://docs.copilotkit.ai/crewai-crews/multi-agent-flows)

[Human-in-the-Loop\\
\\
Set smart checkpoints where humans can guide your agents.](https://docs.copilotkit.ai/crewai-crews/human-in-the-loop)

## [Ready to get started?](https://docs.copilotkit.ai/crewai-crews\#ready-to-get-started)

Get started with CoAgents in as little as 5 minutes with one of our guides or tutorials.

[Quickstart\\
\\
Learn how to build your first CoAgent in 10 minutes.](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai)

## [Common Questions](https://docs.copilotkit.ai/crewai-crews\#common-questions)

Have a question about CoAgents? You're in the right place!

### Can you explain what a CoAgent is in more detail?

[Next\\
\\
Quickstart CrewAI Crews](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai)

### On this page

[Copilot Infrastructure for CrewAI Crews](https://docs.copilotkit.ai/crewai-crews#copilot-infrastructure-for-crewai-crews) [Building blocks of a CoAgent](https://docs.copilotkit.ai/crewai-crews#building-blocks-of-a-coagent) [Ready to get started?](https://docs.copilotkit.ai/crewai-crews#ready-to-get-started) [Common Questions](https://docs.copilotkit.ai/crewai-crews#common-questions)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/crewai-crews/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Self-Hosting Copilot Runtime
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageIntegration

# Self Hosting (Copilot Runtime)

Learn how to self-host the Copilot Runtime.

The Copilot Runtime is the back-end component of CopilotKit, handling the communication with LLM, message history, state and more.

You may choose to self-host the Copilot Runtime, or [use Copilot Cloud](https://cloud.copilotkit.ai/) (recommended).

## [Integration](https://docs.copilotkit.ai/guides/self-hosting\#integration)

### [Step 1: Create an Endpoint](https://docs.copilotkit.ai/guides/self-hosting\#step-1-create-an-endpoint)

##### Choose your provider:

![OpenAI logo](https://docs.copilotkit.ai/icons/openai.png)OpenAI

If you are planning to use a single LangGraph agent in [agent-lock mode](https://docs.copilotkit.ai/coagents/multi-agent-flows) as your agentic backend, your LLM adapter will only be used for peripherals such as suggestions, etc.

If you are not sure yet, simply ignore this note.

### [Add your API key](https://docs.copilotkit.ai/guides/self-hosting\#add-your-api-key)

Next, add your API key to your `.env` file in the root of your project (unless you prefer to provide it directly to the client):

.env

```
OPENAI_API_KEY=your_api_key_here
```

Please note that the code below uses GPT-4o, which requires a paid OpenAI API key. **If you are using a free OpenAI API key**, change the model to a different option such as `gpt-3.5-turbo`.

### [Setup the Runtime Endpoint](https://docs.copilotkit.ai/guides/self-hosting\#setup-the-runtime-endpoint)

### [Serverless Function Timeouts](https://docs.copilotkit.ai/guides/self-hosting\#serverless-function-timeouts)

When deploying to serverless platforms (Vercel, AWS Lambda, etc.), be aware that default function timeouts may be too short for CopilotKit's streaming responses:

- Vercel defaults: 10s (Hobby), 15s (Pro)
- AWS Lambda default: 3s

**Solution options:**

1. Increase function timeout:








```
// vercel.json
{
     "functions": {
       "api/copilotkit/**/*": {
         "maxDuration": 60
       }
     }
}
```

2. Use [Copilot Cloud](https://cloud.copilotkit.ai/) to avoid timeout issues entirely

Next.js App RouterNext.js Pages RouterNode.js ExpressNode.js HTTPNestJS

Create a new route to handle the `/api/copilotkit` endpoint.

app/api/copilotkit/route.ts

```
import {
  CopilotRuntime,
  OpenAIAdapter,
  copilotRuntimeNextJSAppRouterEndpoint,
} from '@copilotkit/runtime';

import { NextRequest } from 'next/server';


const serviceAdapter = new OpenAIAdapter();
const runtime = new CopilotRuntime();

export const POST = async (req: NextRequest) => {
  const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
    runtime,
    serviceAdapter,
    endpoint: '/api/copilotkit',
  });

  return handleRequest(req);
};
```

Your Copilot Runtime endpoint should be available at `http://localhost:3000/api/copilotkit`.

### [Step 2: Configure the `<CopilotKit>` Provider](https://docs.copilotkit.ai/guides/self-hosting\#step-2-configure-the-copilotkit-provider)

layout.tsx

```
import "./globals.css";
import { ReactNode } from "react";
import { CopilotKit } from "@copilotkit/react-core";

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        {/* Make sure to use the URL you configured in the previous step  */}
        <CopilotKit runtimeUrl="/api/copilotkit">
          {children}
        </CopilotKit>
      </body>
    </html>
  );
}
```

## [Next Steps](https://docs.copilotkit.ai/guides/self-hosting\#next-steps)

- [`CopilotRuntime` Reference](https://docs.copilotkit.ai/reference/v1/classes/CopilotRuntime)
- [LLM Adapters](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAdapter)

[Previous\\
\\
Copilot Textarea](https://docs.copilotkit.ai/guides/copilot-textarea) [Next\\
\\
Saving and restoring messages](https://docs.copilotkit.ai/guides/messages-localstorage)

### On this page

[Integration](https://docs.copilotkit.ai/guides/self-hosting#integration) [Step 1: Create an Endpoint](https://docs.copilotkit.ai/guides/self-hosting#step-1-create-an-endpoint) [Step 2: Configure the <CopilotKit> Provider](https://docs.copilotkit.ai/guides/self-hosting#step-2-configure-the-copilotkit-provider) [Next Steps](https://docs.copilotkit.ai/guides/self-hosting#next-steps)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/self-hosting.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## useCopilotAction Hook
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageUsage

# useCopilotAction

The useCopilotAction hook allows your copilot to take action in the app.

![](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/use-copilot-action/useCopilotAction.gif)

`useCopilotAction` is a React hook that you can use in your application to provide
custom actions that can be called by the AI. Essentially, it allows the Copilot to
execute these actions contextually during a chat, based on the user’s interactions
and needs.

Here's how it works:

Use `useCopilotAction` to set up actions that the Copilot can call. To provide
more context to the Copilot, you can provide it with a `description` (for example to explain
what the action does, under which conditions it can be called, etc.).

Then you define the parameters of the action, which can be simple, e.g. primitives like strings or numbers,
or complex, e.g. objects or arrays.

Finally, you provide a `handler` function that receives the parameters and returns a result.
CopilotKit takes care of automatically inferring the parameter types, so you get type safety
and autocompletion for free.

To render a custom UI for the action, you can provide a `render()` function. This function
lets you render a custom component or return a string to display.

## [Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction\#usage)

### [Simple Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction\#simple-usage)

```
useCopilotAction({
  name: "sayHello",
  description: "Say hello to someone.",
  parameters: [\
    {\
      name: "name",\
      type: "string",\
      description: "name of the person to say greet",\
    },\
  ],
  handler: async ({ name }) => {
    alert(`Hello, ${name}!`);
  },
});
```

## [Generative UI](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction\#generative-ui)

This hooks enables you to dynamically generate UI elements and render them in the copilot chat. For more information, check out the [Generative UI](https://docs.copilotkit.ai/guides/generative-ui) page.

## [Parameters](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction\#parameters)

actionActionrequired

The function made available to the Copilot. See [Action](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction#action).

namestringrequired

The name of the action.

handler(args) => Promise<any>required

The handler of the action.

descriptionstring

A description of the action. This is used to instruct the Copilot on how to
use the action.

available'enabled' \| 'disabled' \| 'remote'

Use this property to control when the action is available to the Copilot. When set to `"remote"`, the action is
available only for remote agents.

followUpboolean

Default:"true"

Whether to report the result of a function call to the LLM which will then provide a follow-up response. Pass `false` to disable

parametersParameter\[\]

The parameters of the action. See [Parameter](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction#parameter).

namestringrequired

The name of the parameter.

typestringrequired

The type of the argument. One of:

- `"string"`
- `"number"`
- `"boolean"`
- `"object"`
- `"object[]"`
- `"string[]"`
- `"number[]"`
- `"boolean[]"`

descriptionstring

A description of the argument. This is used to instruct the Copilot on what
this argument is used for.

enumstring\[\]

For string arguments, you can provide an array of possible values.

requiredboolean

Whether or not the argument is required. Defaults to true.

attributes

If the argument is of a complex type, i.e. `object` or `object[]`, this field
lets you define the attributes of the object. For example:

```
{
  name: "addresses",
  description: "The addresses extracted from the text.",
  type: "object[]",
  attributes: [\
    {\
      name: "street",\
      type: "string",\
      description: "The street of the address.",\
    },\
    {\
      name: "city",\
      type: "string",\
      description: "The city of the address.",\
    },\
    // ...\
  ],
}
```

renderstring \| (props: ActionRenderProps<T>) => string

Render lets you define a custom component or string to render instead of the
default. You can either pass in a string or a function that takes the following props:

status'inProgress' \| 'executing' \| 'complete'

- `"inProgress"`: arguments are dynamically streamed to the function, allowing you to adjust your UI in real-time.
- `"executing"`: The action handler is executing.
- `"complete"`: The action handler has completed execution.

argsT

The arguments passed to the action in real time. When the status is `"inProgress"`, they are
possibly incomplete.

resultany

The result returned by the action. It is only available when the status is `"complete"`.

renderAndWaitForResponse(props: ActionRenderPropsWait<T>) => React.ReactElement

This is similar to `render`, but provides a `respond` function in the props that you must call with the user's response. The component will remain rendered until `respond` is called. The response will be passed as the result to the action handler.

status'inProgress' \| 'executing' \| 'complete'

- `"inProgress"`: arguments are dynamically streamed to the function, allowing you to adjust your UI in real-time.
- `"executing"`: The action handler is executing.
- `"complete"`: The action handler has completed execution.

argsT

The arguments passed to the action in real time. When the status is `"inProgress"`, they are
possibly incomplete.

respond(result: any) => void

A function that must be called with the user's response. The response will be passed as the result to the action handler.
Only available when status is `"executing"`.

resultany

The result returned by the action. It is only available when the status is `"complete"`.

dependenciesany\[\]

An optional array of dependencies.

[Previous\\
\\
useCopilotReadable](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotReadable) [Next\\
\\
useCopilotAdditionalInstructions](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAdditionalInstructions)

### On this page

[Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction#usage) [Simple Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction#simple-usage) [Generative UI](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction#generative-ui) [Parameters](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction#parameters)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/v1/hooks/useCopilotAction.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## State Machine Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageOverview

# State Machines

Learn how to guide users through multi-step conversations using a state machine pattern.

## [Overview](https://docs.copilotkit.ai/cookbook/state-machine\#overview)

When building chat-based applications, you often need to guide users through a series of steps or **stages**. This recipe shows how to implement a state machine pattern to keep your assistant focused and on-track.

- Live Example: [https://state-machine-copilot.vercel.app/](https://state-machine-copilot.vercel.app/)
- Example Source Code: [https://github.com/CopilotKit/CopilotKit/tree/main/examples/copilot-state-machine](https://github.com/CopilotKit/CopilotKit/tree/main/examples/copilot-state-machine)

This recipe assumes you have completed the [quickstart guide](https://docs.copilotkit.ai/quickstart) and have a basic CopilotKit application running.

### [What is a State Machine?](https://docs.copilotkit.ai/cookbook/state-machine\#what-is-a-state-machine)

A state machine is a model where your application can be in exactly one state at a time, with clear rules about how to move between states. For chat applications, this means:

- The assistant knows exactly what stage of the conversation it's in
- Only certain actions are available in each stage
- There are clear rules for moving to the next stage

### [State Machines in CopilotKit](https://docs.copilotkit.ai/cookbook/state-machine\#state-machines-in-copilotkit)

When implementing a state machine in CopilotKit, the main piece that enables this pattern is the `available` prop present in
most of our hooks. This prop will allow you conditionally control what instructions, context, and actions are available to
the assistant.

In this recipe, we combine the `available` prop with React state to control when each stage is active, sometimes through
standard deterministic update (button clicks), and sometimes through LLM-driven actions.

![State Machine Architecture](https://docs.copilotkit.ai/_next/image?url=%2Fimages%2Fstate-machine-arch.png&w=3840&q=75)

## [Basic Implementation](https://docs.copilotkit.ai/cookbook/state-machine\#basic-implementation)

### [Create a stage](https://docs.copilotkit.ai/cookbook/state-machine\#create-a-stage)

Each stage is composed of stage-specific instructions, context, and actions. These are enabled or disabled
as the stage changes via the `available` prop. In this example of a stage, we are extracting a user's name
and ensuring it is not in a list of other names.

```
import {
  useCopilotAdditionalInstructions,
  useCopilotAction,
  useCopilotReadable
} from "@copilotkit/react-core";

// ...

/*
 * Not required, but it is convenient to use a dedicated hook to define each
 * stage of the state machine
 */
function useStageOne(
  stage: string,
  setStage: (stage: string) => void,
  setName: (name: string) => void
) {

  /*
   * Each stage can define its own instructions, context, and transitions
   * (implemented via copilotActions). We transition between stages by simply
   * setting the `stage` variable from the handler of the transition:
   */

  // Add additional instructions to the system prompt if this stage is active
  useCopilotAdditionalInstructions({
    instructions: "Ask for the user's name politely.",
    // Use "available" argument to enable this only when the stage is correct!
    available: stage === "one" ? "available" : "disabled"
  })

  // Add context to the system prompt if this stage is active
  useCopilotReadable({
    description: "Other names",
    value: ["John", "Jane", "Jim"],
    available: stage === "one" ? "available" : "disabled"
  })

  // Add an action to the assistant that transitions to the next stage if this stage is active
  useCopilotAction({
    name: "transitionToNextStage",
    description: "Moves to the next stage, only call is the user's name is not in the list of other names",
    available: stage === "one" ? "available" : "disabled",
    parameters: [\
      { name: "name", type: "string", description: "The name of the user", required: true },\
    ],
    handler: ({ name }) => {
      // Perform any state updates given the user's input
      setName(name);

      // Transition to the next stage
      setStage("two");
    }
  });
}
```

### [Create another stage](https://docs.copilotkit.ai/cookbook/state-machine\#create-another-stage)

Now, let's create a second stage that's simple and just greets the user by name as a pirate. This is mainly just to
demonstrate how to add any additional stages. The name will be made available to this stage in the next step.

```
import { useCopilotAdditionalInstructions } from "@copilotkit/react-core";

// ...

function useStageTwo(stage: string) => void) {
  // Add stage-specific instructions - only available in stage "two"
  useCopilotAdditionalInstructions({
    instructions: "Talk to the user about their name and refer to them like a pirate would.",
    available: stage === "two" ? "available" : "disabled"
  })

  // ...
}

// Any additional stages you want to add...
```

### [Put it all together](https://docs.copilotkit.ai/cookbook/state-machine\#put-it-all-together)

Finally, bring everything together into a chat component:

```
import { useState } from "react";
import { CopilotKit, useCopilotReadable } from "@copilotkit/react-core";
import { CopilotChat } from "@copilotkit/react-ui";

// ...

function StateMachineChat() {
  // Track the current stage and user's name
  const [stage, setStage] = useState<string>("one");
  const [name, setName] = useState<string>("");

  // Readable context available across all stages
  useCopilotReadable({
    description: "User's name",
    value: name,
  }, [name])

  // Initialize all stages with their required props
  useStageOne(stage, setStage, setName);
  useStageTwo(stage);
  // any additional stages...

  return (
    <CopilotKit>
      <CopilotChat/>
    </CopilotKit>
  )
}
```

### Full example code

### [🎉 You've implemented a state machine!](https://docs.copilotkit.ai/cookbook/state-machine\#-youve-implemented-a-state-machine)

To recap, each stage hook uses the `available` prop to control when its instructions, context, and actions are accessible to the assistant. This ensures that the assistant only uses the correct tools and context for the current stage.

Next, let's see some advanced patterns you can implement with these fundamentals.

## [Advanced Patterns](https://docs.copilotkit.ai/cookbook/state-machine\#advanced-patterns)

This state machine pattern can be extended for complex interactions. Below are some advanced patterns you can implement with code sourced in our
[car sales example](https://github.com/CopilotKit/CopilotKit/tree/main/examples/copilot-state-machine) which you already saw a demo of in the [overview](https://docs.copilotkit.ai/cookbook/state-machine#overview).

### [Stage Transition Approaches](https://docs.copilotkit.ai/cookbook/state-machine\#stage-transition-approaches)

#### [Code-driven Stage Transitions](https://docs.copilotkit.ai/cookbook/state-machine\#code-driven-stage-transitions)

When you want to transition between stages, you can do so by setting the `stage` deterministically, at any point in code.

```
const [stage, setStage] = useState<string>("one");

// ...

<button onClick={() => setStage("two")}>
  Transition to next stage
</button>
```

The car sales demo uses this approach in generative UI (for more on generative UI, see the [section below](https://docs.copilotkit.ai/cookbook/state-machine#generative-ui)) to transition between stages
when a user submits their contact information.

Click here for the [source code](https://github.com/CopilotKit/CopilotKit/tree/main/examples/copilot-state-machine/src/lib/stages/use-stage-get-contact-info.tsx)

src/lib/stages/use-stage-get-contact-info.tsx

```
// imports ...

export function useStageGetContactInfo() {
  const { setContactInfo, stage, setStage } = useGlobalState();

  // ...

  // Render the ContactInfo component and wait for the user's response.
  useCopilotAction(
    {
      name: "getContactInformation",
      description: "Get the contact information of the user",
      available: stage === "getContactInfo" ? "enabled" : "disabled",
      renderAndWaitForResponse: ({ status, respond }) => {
        return (
          <ContactInfo
            status={status}

            onSubmit={(name, email, phone) => {
              // Commit the contact information to the global state.
              setContactInfo({ name, email, phone });

              // Let the agent know that the user has submitted their contact information.
              respond?.("User has submitted their contact information.");

              // This move the state machine to the next stage, buildCar deterministically.
              setStage("buildCar");
            }}
          />
        );
      },
    },
    [stage],
  );
}
```

#### [LLM-Driven Stage Transitions](https://docs.copilotkit.ai/cookbook/state-machine\#llm-driven-stage-transitions)

Sometimes you need stages that can transition to different next stages based on user input or LLM-driven actions.

Click here for the [source code](https://github.com/CopilotKit/CopilotKit/tree/main/examples/copilot-state-machine/src/lib/stages/use-stage-sell-financing.tsx)

src/lib/stages/use-stage-sell-financing.tsx

```
function useStageSellFinancing() {
  const { stage, setStage } = useGlobalState();
  const isActive = stage === "sellFinancing";

  // Provide context to the AI
  useCopilotReadable({
    description: "Financing Information",
    value: "Current promotion: 0% financing for 60 months...",
    available: isActive ? "enabled" : "disabled"
  });

  // Different paths based on financing choice by user, LLM will decide which path to take

  useCopilotAction({
    name: "selectFinancing",
    description: "Select the financing option",
    available: stage === "sellFinancing" ? "enabled" : "disabled",
    handler: () => setStage("getFinancingInfo"),
  }, [stage]);

  useCopilotAction({
    name: "selectNoFinancing",
    description: "Select the no financing option",
    available: stage === "sellFinancing" ? "enabled" : "disabled",
    handler: () => setStage("getPaymentInfo"),
  }, [stage]);

}
```

### [Generative UI](https://docs.copilotkit.ai/cookbook/state-machine\#generative-ui)

[Generative UI](https://docs.copilotkit.ai/guides/generative-ui) is a pattern where tool calls are streamed and rendered for the user to visualize the progress an agent is making. It can also be combined with the **Human-in-the-loop pattern** to allow checkpoints where the user can intervene and help guide the agent.

When combined with the state machine pattern, you can build deep and interactive conversations with the user. For example, the `buildCar` stage in the car sales demo
uses generative UI to show the user available cars that they can choose from.

Click here for the [source code](https://github.com/CopilotKit/CopilotKit/tree/main/examples/copilot-state-machine/src/lib/stages/use-stage-build-car.tsx)

Build Car StageShow Car Component

src/lib/stages/use-stage-build-car.tsx

```
export function useStageBuildCar() {
  const { setSelectedCar, stage, setStage } = useGlobalState();

  // ...

  useCopilotAction({
    name: "showCar",
    description: "Show a single car that you have in mind. Do not call this more than once, call `showMultipleCars` if you have multiple cars to show.",
    available: stage === "buildCar" ? "enabled" : "disabled",
    parameters: [\
      // excluded for brevity, see source code link above for more detail\
    ],
    renderAndWaitForResponse: ({ args, status, respond }) => {
      const { car } = args;
      return (

        <ShowCar
          car={(car as Car) || ({} as Car)}
          status={status}
          onSelect={() => {
            setSelectedCar((car as Car) || ({} as Car));
            respond?.("User has selected a car you can see it in your readables, the system will now move to the next state, do not call call nextState.");
            setStage("sellFinancing");
          }}
          onReject={() => respond?.("User wants to select a different car, please stay in this state and help them select a different car")}
        />
      );
    },
  }, [stage]);
  // ...
}
```

### [Initial message loading](https://docs.copilotkit.ai/cookbook/state-machine\#initial-message-loading)

To add an initial message to the chat, we can use the `appendMessage` function provided by the `useCopilotChat` hook.

Improved experience coming soon

This is a temporary solution and we will be improving this in the near future.

Click here for the [source code](https://github.com/CopilotKit/CopilotKit/tree/main/examples/copilot-state-machine/src/components/car-sales-chat.tsx)

src/components/car-sales-chat.tsx

```
import { useCopilotChat } from "@copilotkit/react-core";

// ...

const { appendMessage, isLoading } = useCopilotChat();

// Render an initial message when the chat is first loaded
useEffect(() => {
  if (initialMessageSent || isLoading) return;

  setTimeout(() => {
    appendMessage(
      new TextMessage({
        content:
          "Hi, I'm Fio, your AI car salesman. First, let's get your contact information before we get started.",
        role: MessageRole.Assistant,
      }),
    );
    setInitialMessageSent(true);
  }, 500);
}, [initialMessageSent, appendMessage, isLoading]);

// ...
```

### [Tools When Entering a Stage](https://docs.copilotkit.ai/cookbook/state-machine\#tools-when-entering-a-stage)

Sometimes you'll want to guide the AI to call a specific tool when entering a stage.

The payment info stage demonstrates how to guide the AI to make specific tool calls by
adding additional instructions to call the `getPaymentInformation` tool explicitly.

Click here for the [source code](https://github.com/CopilotKit/CopilotKit/tree/main/examples/copilot-state-machine/src/lib/stages/use-stage-get-payment-info.tsx)

src/lib/stages/use-stage-get-payment-info.tsx

```
export function useStageGetPaymentInfo() {
  const { setCardInfo, stage, setStage } = useGlobalState();

  // Conditionally add additional instructions for the agent's prompt.
  useCopilotAdditionalInstructions({
    available: stage === "getPaymentInfo" ? "enabled" : "disabled",

    instructions: `
        CURRENT STATE: You are now getting the payment information of the user.
        Say, 'Great! Now I need to get your payment information.' and MAKE SURE
        to then call the 'getPaymentInformation' action.
    `,
  }, [stage]);

  // ...

}
```

## [Recap](https://docs.copilotkit.ai/cookbook/state-machine\#recap)

This recipe introduced a powerful pattern for building conversational AI applications using state machines. By breaking down complex interactions into discrete stages, each with
focused instructions and actions, we can create more maintainable and user-friendly experiences.

With this pattern, you can start building your own multi-stage conversations.

## [Need Help?](https://docs.copilotkit.ai/cookbook/state-machine\#need-help)

Need help or want to share what you've built? Join our [Discord community](https://discord.gg/6dffbvGU3D) or open an issue on [GitHub](https://github.com/CopilotKit/CopilotKit/issues/new/choose).

[Previous\\
\\
Next Steps](https://docs.copilotkit.ai/tutorials/ai-powered-textarea/next-steps) [Next\\
\\
Common Issues](https://docs.copilotkit.ai/troubleshooting/common-issues)

### On this page

[Overview](https://docs.copilotkit.ai/cookbook/state-machine#overview) [What is a State Machine?](https://docs.copilotkit.ai/cookbook/state-machine#what-is-a-state-machine) [State Machines in CopilotKit](https://docs.copilotkit.ai/cookbook/state-machine#state-machines-in-copilotkit) [Basic Implementation](https://docs.copilotkit.ai/cookbook/state-machine#basic-implementation) [Create a stage](https://docs.copilotkit.ai/cookbook/state-machine#create-a-stage) [Create another stage](https://docs.copilotkit.ai/cookbook/state-machine#create-another-stage) [Put it all together](https://docs.copilotkit.ai/cookbook/state-machine#put-it-all-together) [🎉 You've implemented a state machine!](https://docs.copilotkit.ai/cookbook/state-machine#-youve-implemented-a-state-machine) [Advanced Patterns](https://docs.copilotkit.ai/cookbook/state-machine#advanced-patterns) [Stage Transition Approaches](https://docs.copilotkit.ai/cookbook/state-machine#stage-transition-approaches) [Code-driven Stage Transitions](https://docs.copilotkit.ai/cookbook/state-machine#code-driven-stage-transitions) [LLM-Driven Stage Transitions](https://docs.copilotkit.ai/cookbook/state-machine#llm-driven-stage-transitions) [Generative UI](https://docs.copilotkit.ai/cookbook/state-machine#generative-ui) [Initial message loading](https://docs.copilotkit.ai/cookbook/state-machine#initial-message-loading) [Tools When Entering a Stage](https://docs.copilotkit.ai/cookbook/state-machine#tools-when-entering-a-stage) [Recap](https://docs.copilotkit.ai/cookbook/state-machine#recap) [Need Help?](https://docs.copilotkit.ai/cookbook/state-machine#need-help)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/cookbook/state-machine.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

![State Machine Architecture](https://docs.copilotkit.ai/_next/image?url=%2Fimages%2Fstate-machine-arch.png&w=3840&q=75)

## Agent State Management
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageUsage

# useCoAgent

The useCoAgent hook allows you to share state bidirectionally between your application and the agent.

Usage of this hook assumes some additional setup in your application, for more information
on that see the CoAgents [getting started guide](https://docs.copilotkit.ai/coagents/quickstart/langgraph).

![CoAgents demonstration](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/coagents/SharedStateCoAgents.gif)

This hook is used to integrate an agent into your application. With its use, you can
render and update the state of an agent, allowing for a dynamic and interactive experience.
We call these shared state experiences agentic copilots, or CoAgents for short.

## [Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgent\#usage)

### [Simple Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgent\#simple-usage)

```
import { useCoAgent } from "@copilotkit/react-core";

type AgentState = {
  count: number;
}

const agent = useCoAgent<AgentState>({
  name: "my-agent",
  initialState: {
    count: 0,
  },
});

```

`useCoAgent` returns an object with the following properties:

```
const {
  name,     // The name of the agent currently being used.
  nodeName, // The name of the current LangGraph node.
  state,    // The current state of the agent.
  setState, // A function to update the state of the agent.
  running,  // A boolean indicating if the agent is currently running.
  start,    // A function to start the agent.
  stop,     // A function to stop the agent.
  run,      // A function to re-run the agent. Takes a HintFunction to inform the agent why it is being re-run.
} = agent;
```

Finally we can leverage these properties to create reactive experiences with the agent!

```
const { state, setState } = useCoAgent<AgentState>({
  name: "my-agent",
  initialState: {
    count: 0,
  },
});

return (
  <div>
    <p>Count: {state.count}</p>
    <button onClick={() => setState({ count: state.count + 1 })}>Increment</button>
  </div>
);
```

This reactivity is bidirectional, meaning that changes to the state from the agent will be reflected in the UI and vice versa.

## [Parameters](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgent\#parameters)

optionsUseCoagentOptions<T>required

The options to use when creating the coagent.

namestringrequired

The name of the agent to use.

initialStateT \| any

The initial state of the agent.

stateT \| any

State to manage externally if you are using this hook with external state management.

setState(newState: T \| ((prevState: T \| undefined) => T)) => void

A function to update the state of the agent if you are using this hook with external state management.

[Previous\\
\\
useCopilotChatSuggestions](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions) [Next\\
\\
useCoAgentStateRender](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgentStateRender)

### On this page

[Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgent#usage) [Simple Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgent#simple-usage) [Parameters](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgent#parameters)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/v1/hooks/useCoAgent.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotKit Component Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageExample

# CopilotKit

The CopilotKit provider component, wrapping your application.

This component will typically wrap your entire application (or a sub-tree of your application where you want to have a copilot). It provides the copilot context to all other components and hooks.

## [Example](https://docs.copilotkit.ai/reference/v1/components/CopilotKit\#example)

You can find more information about self-hosting CopilotKit [here](https://docs.copilotkit.ai/guides/self-hosting).

```
import { CopilotKit } from "@copilotkit/react-core";

<CopilotKit runtimeUrl="<your-runtime-url>">
  // ... your app ...
</CopilotKit>
```

## [Properties](https://docs.copilotkit.ai/reference/v1/components/CopilotKit\#properties)

publicApiKeystring

Your Copilot Cloud API key. Don't have it yet? Go to [https://cloud.copilotkit.ai](https://cloud.copilotkit.ai/) and get one for free.

guardrails\_c{ validTopics?: string\[\]; invalidTopics?: string\[\]; }

Restrict input to specific topics using guardrails.
@remarks

This feature is only available when using CopilotKit's hosted cloud service. To use this feature, sign up at [https://cloud.copilotkit.ai](https://cloud.copilotkit.ai/) to get your publicApiKey. The feature allows restricting chat conversations to specific topics.

runtimeUrlstring

The endpoint for the Copilot Runtime instance. [Click here for more information](https://docs.copilotkit.ai/concepts/copilot-runtime).

transcribeAudioUrlstring

The endpoint for the Copilot transcribe audio service.

textToSpeechUrlstring

The endpoint for the Copilot text to speech service.

headersRecord<string, string>

Additional headers to be sent with the request.

For example:

```
{
  "Authorization": "Bearer X"
}
```

childrenReactNoderequired

The children to be rendered within the CopilotKit.

propertiesRecord<string, any>

Custom properties to be sent with the request
For example:

```
{
  'user_id': 'users_id',
}
```

credentialsRequestCredentials

Indicates whether the user agent should send or receive cookies from the other domain
in the case of cross-origin requests.

showDevConsoleboolean \| 'auto'

Whether to show the dev console.

If set to "auto", the dev console will be show on localhost only.

agentstring

The name of the agent to use.

forwardedParametersPick<ForwardedParametersInput, 'temperature'>

The forwarded parameters to use for the task.

authConfig\_c{ SignInComponent: React.ComponentType<{ onSignInComplete: (authState: AuthState) => void; }>; }

The auth config to use for the CopilotKit.
@remarks

This feature is only available when using CopilotKit's hosted cloud service. To use this feature, sign up at [https://cloud.copilotkit.ai](https://cloud.copilotkit.ai/) to get your publicApiKey. The feature allows restricting chat conversations to specific topics.

threadIdstring

The thread id to use for the CopilotKit.

mcpEndpointsArray<{ endpoint: string; apiKey?: string }>

Config for connecting to Model Context Protocol (MCP) servers.
Enables CopilotKit runtime to access tools on external MCP servers.

This config merges into the `properties` object with each request as `mcpEndpoints`.
It offers a typed method to set up MCP endpoints for requests.

Each array item should have:

- `endpoint`: MCP server URL (mandatory).
- `apiKey`: Optional API key for server authentication.

Note: A `createMCPClient` function is still needed during runtime initialization to manage these endpoints.

[Previous\\
\\
CopilotTextarea](https://docs.copilotkit.ai/reference/v1/components/CopilotTextarea) [Next\\
\\
useCopilotReadable](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotReadable)

### On this page

[Example](https://docs.copilotkit.ai/reference/v1/components/CopilotKit#example) [Properties](https://docs.copilotkit.ai/reference/v1/components/CopilotKit#properties)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/components/CopilotKit.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Frontend Actions Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is this?

# Frontend Actions

Create frontend actions and use them within your agent.

This video shows the [coagents starter](https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter) repo with the [implementation](https://docs.copilotkit.ai/coagents/frontend-actions#implementation) section applied to it!

## [What is this?](https://docs.copilotkit.ai/coagents/frontend-actions\#what-is-this)

Frontend actions are powerful tools that allow your AI agents to directly interact with and update your application's user interface. Think of them as bridges that connect your agent's decision-making capabilities with your frontend's interactive elements.

## [When should I use this?](https://docs.copilotkit.ai/coagents/frontend-actions\#when-should-i-use-this)

Frontend actions are essential when you want to create truly interactive AI applications where your agent needs to:

- Dynamically update UI elements
- Trigger frontend animations or transitions
- Show alerts or notifications
- Modify application state
- Handle user interactions programmatically

Without frontend actions, agents are limited to just processing and returning data. By implementing frontend actions, you can create rich, interactive experiences where your agent actively drives the user interface.

## [Implementation](https://docs.copilotkit.ai/coagents/frontend-actions\#implementation)

### [Setup CopilotKit](https://docs.copilotkit.ai/coagents/frontend-actions\#setup-copilotkit)

To use frontend actions, you'll need to setup CopilotKit first. For the sake of brevity, we won't cover it here.

Check out our [getting started guide](https://docs.copilotkit.ai/coagents/quickstart/langgraph) and come back here when you're setup!

### [Create a frontend action](https://docs.copilotkit.ai/coagents/frontend-actions\#create-a-frontend-action)

First, you'll need to create a frontend action using the [useCopilotAction](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction) hook. Here's a simple one to get you started
that says hello to the user.

page.tsx

```
import { useCopilotAction } from "@copilotkit/react-core"

export function Page() {
  // ...


  useCopilotAction({
    name: "sayHello",
    description: "Say hello to the user",
    available: "remote", // optional, makes it so the action is *only* available to the agent
    parameters: [\
      {\
        name: "name",\
        type: "string",\
        description: "The name of the user to say hello to",\
        required: true,\
      },\
    ],
    handler: async ({ name }) => {
      alert(`Hello, ${name}!`);
    },
  });

  // ...
}
```

### [Modify your agent](https://docs.copilotkit.ai/coagents/frontend-actions\#modify-your-agent)

Now, we'll need to modify the agent to access these frontend actions. In your terminal, navigate to your agent's folder and continue from there!

### [Install the CopilotKit SDK](https://docs.copilotkit.ai/coagents/frontend-actions\#install-the-copilotkit-sdk)

Any LangGraph agent can be used with CopilotKit. However, creating deep agentic
experiences with CopilotKit requires our LangGraph SDK.

PythonTypeScript

Poetrypipconda

```
poetry add copilotkit
# including support for crewai
poetry add copilotkit[crewai]
```

### [Inheriting from CopilotKitState](https://docs.copilotkit.ai/coagents/frontend-actions\#inheriting-from-copilotkitstate)

To access the frontend actions provided by CopilotKit, you can inherit from CopilotKitState in your agent's state definition:

PythonTypeScript

agent-py/sample\_agent/agent.py

```
from copilotkit import CopilotKitState

class YourAgentState(CopilotKitState):
    your_additional_properties: str
```

By doing this, your agent's state will include the `copilotkit` property, which contains the frontend actions that can be accessed and invoked.

### [Accessing Frontend Actions](https://docs.copilotkit.ai/coagents/frontend-actions\#accessing-frontend-actions)

Once your agent's state includes the `copilotkit` property, you can access the frontend actions and utilize them within your agent's logic.

Here's how you can call a frontend action from your agent:

PythonTypeScript

agent-py/sample\_agent/agent.py

```
async def agent_node(state: YourAgentState, config: RunnableConfig):
    # Access the actions from the copilotkit property

    actions = state.get("copilotkit", {}).get("actions", [])
    model = ChatOpenAI(model="gpt-4o").bind_tools(actions)

    # ...
```

These actions are automatically populated by CopilotKit and are compatible with LangChain's tool call definitions, making it straightforward to integrate them into your agent's workflow.

### [Give it a try!](https://docs.copilotkit.ai/coagents/frontend-actions\#give-it-a-try)

You've now given your agent the ability to directly call any CopilotActions you've defined. These actions will be available as tools to the agent where they can be used as needed.

[Previous\\
\\
Predictive state updates](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates) [Next\\
\\
Multi-Agent Flows](https://docs.copilotkit.ai/coagents/multi-agent-flows)

### On this page

[What is this?](https://docs.copilotkit.ai/coagents/frontend-actions#what-is-this) [When should I use this?](https://docs.copilotkit.ai/coagents/frontend-actions#when-should-i-use-this) [Implementation](https://docs.copilotkit.ai/coagents/frontend-actions#implementation) [Setup CopilotKit](https://docs.copilotkit.ai/coagents/frontend-actions#setup-copilotkit) [Create a frontend action](https://docs.copilotkit.ai/coagents/frontend-actions#create-a-frontend-action) [Modify your agent](https://docs.copilotkit.ai/coagents/frontend-actions#modify-your-agent) [Install the CopilotKit SDK](https://docs.copilotkit.ai/coagents/frontend-actions#install-the-copilotkit-sdk) [Inheriting from CopilotKitState](https://docs.copilotkit.ai/coagents/frontend-actions#inheriting-from-copilotkitstate) [Accessing Frontend Actions](https://docs.copilotkit.ai/coagents/frontend-actions#accessing-frontend-actions) [Give it a try!](https://docs.copilotkit.ai/coagents/frontend-actions#give-it-a-try)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/frontend-actions.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Generative UI Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is Generative UI?

# Generative UI

Render your agent's behavior with custom UI components.

![Demo of Generative UI showing a meeting scheduling agent](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/coagents/AgenticGenerativeUI.gif)

This example shows our [Research Canvas](https://docs.copilotkit.ai/coagents/videos/research-canvas) making use of Generative UI!

## [What is Generative UI?](https://docs.copilotkit.ai/coagents/generative-ui\#what-is-generative-ui)

Generative UI lets you render your agent's state, progress, outputs, and tool calls with custom UI components in real-time. It bridges the gap between AI
agents and user interfaces. As your agent processes information and makes decisions, you can render custom UI components that:

- Show loading states and progress indicators
- Display structured data in tables, cards, or charts
- Create interactive elements for user input
- Animate transitions between different states

## [How can I use this?](https://docs.copilotkit.ai/coagents/generative-ui\#how-can-i-use-this)

There are two main variants of Generative UI.

[Agentic\\
\\
Render your agent's state, progress, and outputs with custom UI components.](https://docs.copilotkit.ai/coagents/generative-ui/agentic)

[Tool-based\\
\\
Render your agent's tool calls with custom UI components.](https://docs.copilotkit.ai/coagents/generative-ui/tool-based)

[Previous\\
\\
Chat with an Agent](https://docs.copilotkit.ai/coagents/agentic-chat-ui) [Next\\
\\
Agentic Generative UI](https://docs.copilotkit.ai/coagents/generative-ui/agentic)

### On this page

[What is Generative UI?](https://docs.copilotkit.ai/coagents/generative-ui#what-is-generative-ui) [How can I use this?](https://docs.copilotkit.ai/coagents/generative-ui#how-can-i-use-this)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/generative-ui/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotKit Quickstart Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageInstall CopilotKit

# Quickstart

Get started with CopilotKit in under 5 minutes.

Copilot Cloud (Recommended)

Use our hosted backend endpoint to get started quickly.

Self-hosting

Learn to host CopilotKit's runtime yourself with your own backend.

## [Install CopilotKit](https://docs.copilotkit.ai/quickstart?component=CopilotChat\#install-copilotkit)

First, install the latest packages for CopilotKit.

npmpnpmyarnbun

```
npm install @copilotkit/react-ui @copilotkit/react-core
```

## [Get a Copilot Cloud Public API Key](https://docs.copilotkit.ai/quickstart?component=CopilotChat\#get-a-copilot-cloud-public-api-key)

Navigate to [Copilot Cloud](https://cloud.copilotkit.ai/) and follow the instructions to get a public API key - it's free!

## [Setup the CopilotKit Provider](https://docs.copilotkit.ai/quickstart?component=CopilotChat\#setup-the-copilotkit-provider)

The [`<CopilotKit>`](https://docs.copilotkit.ai/reference/v1/components/CopilotKit) component must wrap the Copilot-aware parts of your application. For most use-cases,
it's appropriate to wrap the CopilotKit provider around the entire app, e.g. in your layout.tsx.

layout.tsx

```
import "./globals.css";
import { ReactNode } from "react";
import { CopilotKit } from "@copilotkit/react-core";

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        {/* Use the public api key you got from Copilot Cloud  */}
        <CopilotKit publicApiKey="<your-copilot-cloud-public-api-key>">
          {children}
        </CopilotKit>
      </body>
    </html>
  );
}
```

## [Choose a Copilot UI](https://docs.copilotkit.ai/quickstart?component=CopilotChat\#choose-a-copilot-ui)

You are almost there! Now it's time to setup your Copilot UI.

First, import the default styles in your root component (typically `layout.tsx`) :

```
import "@copilotkit/react-ui/styles.css";
```

Copilot UI ships with a number of built-in UI patterns, choose whichever one you like.

CopilotPopupCopilotSidebarCopilotChatHeadless UI

`CopilotChat` is a flexible chat interface component that **can be placed anywhere in your app** and can be resized as you desire.

![Popup Example](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/copilotchat-example.gif)

```
import { CopilotChat } from "@copilotkit/react-ui";

export function YourComponent() {
  return (
    <CopilotChat
      instructions={"You are assisting the user as best as you can. Answer in the best way possible given the data you have."}
      labels={{
        title: "Your Assistant",
        initial: "Hi! 👋 How can I assist you today?",
      }}
    />
  );
}
```

* * *

## [Next Steps](https://docs.copilotkit.ai/quickstart?component=CopilotChat\#next-steps)

🎉 Congrats! You've successfully integrated a fully functional chatbot in your application! Give it a try now and see it in action. Want to
take it further? Learn more about what CopilotKit has to offer!

[**Connecting Your Data** \\
Learn how to connect CopilotKit to your data, application state and user state.](https://docs.copilotkit.ai/guides/connect-your-data) [**Generative UI** \\
Learn how to render custom UI components directly in the CopilotKit chat window.](https://docs.copilotkit.ai/guides/generative-ui) [**Frontend Actions** \\
Learn how to allow your copilot to take applications on frontend.](https://docs.copilotkit.ai/guides/frontend-actions) [**CoAgents (LangGraph)** \\
Check out our section about CoAgents, our approach to building agentic copilots and experiences.](https://docs.copilotkit.ai/coagents)

[Previous\\
\\
Introduction](https://docs.copilotkit.ai/) [Next\\
\\
Customize UI](https://docs.copilotkit.ai/guides/custom-look-and-feel)

### On this page

[Install CopilotKit](https://docs.copilotkit.ai/quickstart?component=CopilotChat#install-copilotkit) [Get a Copilot Cloud Public API Key](https://docs.copilotkit.ai/quickstart?component=CopilotChat#get-a-copilot-cloud-public-api-key) [Setup the CopilotKit Provider](https://docs.copilotkit.ai/quickstart?component=CopilotChat#setup-the-copilotkit-provider) [Choose a Copilot UI](https://docs.copilotkit.ai/quickstart?component=CopilotChat#choose-a-copilot-ui) [Install CopilotKit](https://docs.copilotkit.ai/quickstart?component=CopilotChat#install-copilotkit-1) [Set up a Copilot Runtime Endpoint](https://docs.copilotkit.ai/quickstart?component=CopilotChat#set-up-a-copilot-runtime-endpoint) [Configure the CopilotKit Provider](https://docs.copilotkit.ai/quickstart?component=CopilotChat#configure-the-copilotkit-provider) [Choose a Copilot UI](https://docs.copilotkit.ai/quickstart?component=CopilotChat#choose-a-copilot-ui-1) [Next Steps](https://docs.copilotkit.ai/quickstart?component=CopilotChat#next-steps)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/quickstart.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Message History Management
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this page

# Saving and restoring messages

Learn how to save and restore message history.

See [Loading Message History](https://docs.copilotkit.ai/coagents/persistence/loading-message-history) for an automated way to load the chat history.

As you're building agentic experiences, you may want to persist the user's chat history across runs.
One way to do this is through the use of `localstorage` where chat history is saved in the browser.
In this guide we demonstrate how you can store the state into `localstorage` and how it can be inserted
into the agent.

The following example shows how to save and restore your message history using `localStorage`:

```
import { useCopilotMessagesContext } from "@copilotkit/react-core";
import { ActionExecutionMessage, ResultMessage, TextMessage } from "@copilotkit/runtime-client-gql";

const { messages, setMessages } = useCopilotMessagesContext();

// save to local storage when messages change
useEffect(() => {
  if (messages.length !== 0) {
    localStorage.setItem("copilotkit-messages", JSON.stringify(messages));
  }
}, [JSON.stringify(messages)]);

// initially load from local storage
useEffect(() => {
  const messages = localStorage.getItem("copilotkit-messages");
  if (messages) {
    const parsedMessages = JSON.parse(messages).map((message: any) => {
      if (message.type === "TextMessage") {
        return new TextMessage({
          id: message.id,
          role: message.role,
          content: message.content,
          createdAt: message.createdAt,
        });
      } else if (message.type === "ActionExecutionMessage") {
        return new ActionExecutionMessage({
          id: message.id,
          name: message.name,
          scope: message.scope,
          arguments: message.arguments,
          createdAt: message.createdAt,
        });
      } else if (message.type === "ResultMessage") {
        return new ResultMessage({
          id: message.id,
          actionExecutionId: message.actionExecutionId,
          actionName: message.actionName,
          result: message.result,
          createdAt: message.createdAt,
        });
      } else {
        throw new Error(`Unknown message type: ${message.type}`);
      }
    });
    setMessages(parsedMessages);
  }
}, []);
```

[Previous\\
\\
Self Hosting (Copilot Runtime)](https://docs.copilotkit.ai/guides/self-hosting) [Next\\
\\
Overview](https://docs.copilotkit.ai/tutorials/ai-todo-app/overview)

### On this page

No Headings

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/messages-localstorage.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Copilot Suggestions Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageSimple Usage

# Copilot Suggestions

Learn how to auto-generate suggestions in the chat window based on real time application state.

useCopilotChatSuggestions is experimental. The interface is not final and can
change without notice.

[`useCopilotChatSuggestions`](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions) is a React hook that generates suggestions in the chat window based on real time application state.

![](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/use-copilot-chat-suggestions/use-copilot-chat-suggestions.gif)

### [Simple Usage](https://docs.copilotkit.ai/guides/copilot-suggestions\#simple-usage)

```
import { useCopilotChatSuggestions } from "@copilotkit/react-ui";

export function MyComponent() {

  useCopilotChatSuggestions(
    {
      instructions: "Suggest the most relevant next actions.",
      minSuggestions: 1,
      maxSuggestions: 2,
    },
    [relevantState],
  );
}
```

### [Dependency Management](https://docs.copilotkit.ai/guides/copilot-suggestions\#dependency-management)

```
import { useCopilotChatSuggestions } from "@copilotkit/react-ui";

export function MyComponent() {
  useCopilotChatSuggestions(
    {
      instructions: "Suggest the most relevant next actions.",
      minSuggestions: 1,
      maxSuggestions: 2,
    },
    [relevantState],
  );
}
```

In the example above, the suggestions are generated based on the given instructions.
The hook monitors `relevantState`, and updates suggestions accordingly whenever it changes.

### [Specify `"use client"` (Next.js App Router)](https://docs.copilotkit.ai/guides/copilot-suggestions\#specify-use-client-nextjs-app-router)

This is only necessary if you are using Next.js with the App Router.

YourComponent.tsx

```
"use client"
```

Like other React hooks such as `useState` and `useEffect`, this is a **client-side** hook.
If you're using Next.js with the App Router, you'll need to add the `"use client"` directive at the top of any file using this hook.

## [Next Steps](https://docs.copilotkit.ai/guides/copilot-suggestions\#next-steps)

- Check out the [useCopilotChatSuggestions reference](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions) for more details.

[Previous\\
\\
Guardrails](https://docs.copilotkit.ai/guides/guardrails) [Next\\
\\
Bring Your Own LLM](https://docs.copilotkit.ai/guides/bring-your-own-llm)

### On this page

[Simple Usage](https://docs.copilotkit.ai/guides/copilot-suggestions#simple-usage) [Dependency Management](https://docs.copilotkit.ai/guides/copilot-suggestions#dependency-management) [Next Steps](https://docs.copilotkit.ai/guides/copilot-suggestions#next-steps)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/copilot-suggestions.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotTask Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageExample

# CopilotTask

CopilotTask is used to execute one-off tasks, for example on button click.

This class is used to execute one-off tasks, for example on button press. It can use the context available via [useCopilotReadable](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotReadable) and the actions provided by [useCopilotAction](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction), or you can provide your own context and actions.

## [Example](https://docs.copilotkit.ai/reference/v1/classes/CopilotTask\#example)

In the simplest case, use CopilotTask in the context of your app by giving it instructions on what to do.

```
import { CopilotTask, useCopilotContext } from "@copilotkit/react-core";

export function MyComponent() {
  const context = useCopilotContext();

  const task = new CopilotTask({
    instructions: "Set a random message",
    actions: [\
      {\
        name: "setMessage",\
      description: "Set the message.",\
      argumentAnnotations: [\
        {\
          name: "message",\
          type: "string",\
          description:\
            "A message to display.",\
          required: true,\
        },\
      ],\
     }\
    ]
  });

  const executeTask = async () => {
    await task.run(context, action);
  }

  return (
    <>
      <button onClick={executeTask}>
        Execute task
      </button>
    </>
  )
}
```

Have a look at the [Presentation Example App](https://github.com/CopilotKit/CopilotKit/blob/main/CopilotKit/examples/next-openai/src/app/presentation/page.tsx) for a more complete example.

## [Constructor Parameters](https://docs.copilotkit.ai/reference/v1/classes/CopilotTask\#constructor-parameters)

instructionsstringrequired

The instructions to be given to the assistant.

actionsFrontendAction<any>\[\]

An array of action definitions that can be called.

includeCopilotReadableboolean

Whether to include the copilot readable context in the task.

includeCopilotActionsboolean

Whether to include actions defined via useCopilotAction in the task.

forwardedParametersForwardedParametersInput

The forwarded parameters to use for the task.

runcontext: CopilotContextParams, data?: T

Run the task.

contextCopilotContextParamsrequired

The CopilotContext to use for the task. Use `useCopilotContext` to obtain the current context.

dataT

The data to use for the task.

[Previous\\
\\
GoogleGenerativeAIAdapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/GoogleGenerativeAIAdapter) [Next\\
\\
Remote Endpoints](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints)

### On this page

[Example](https://docs.copilotkit.ai/reference/v1/classes/CopilotTask#example) [Constructor Parameters](https://docs.copilotkit.ai/reference/v1/classes/CopilotTask#constructor-parameters)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/v1/classes/CopilotTask.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Copilot Textarea Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageInstall @copilotkit/react-textarea

# Copilot Textarea

Learn how to use the Copilot Textarea for AI-powered autosuggestions.

![](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/CopilotTextarea.gif)

`<CopilotTextarea>` is a React component that acts as a drop-in replacement for the standard `<textarea>`,
offering enhanced autocomplete features powered by AI. It is context-aware, integrating seamlessly with the
[`useCopilotReadable`](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotReadable) hook to provide intelligent suggestions based on the application context.

In addition, it provides a hovering editor window (available by default via `Cmd + K` on Mac and `Ctrl + K` on Windows) that allows the user to
suggest changes to the text, for example providing a summary or rephrasing the text.

This guide assumes you have completed the [quickstart](https://docs.copilotkit.ai/quickstart) and have successfully set up CopilotKit.

### [Install `@copilotkit/react-textarea`](https://docs.copilotkit.ai/guides/copilot-textarea\#install-copilotkitreact-textarea)

npmpnpmyarnbun

```
npm install @copilotkit/react-textarea
```

### [Import Styles](https://docs.copilotkit.ai/guides/copilot-textarea\#import-styles)

Import the default styles in your root component (typically `layout.tsx`) :

layout.tsx

```
import "@copilotkit/react-textarea/styles.css";
```

### [Add `CopilotTextarea` to Your Component](https://docs.copilotkit.ai/guides/copilot-textarea\#add-copilottextarea-to-your-component)

Below you can find several examples showing how to use the `CopilotTextarea` component in your application.

Example 1Example 2

TextAreaComponent.tsx

```
import { FC, useState } from "react";
import { CopilotTextarea } from '@copilotkit/react-textarea';

const ExampleComponent: FC = () => {
  const [text, setText] = useState<string>('');

  return (
    <CopilotTextarea
      className="w-full p-4 border border-gray-300 rounded-md"
      value={text}
      onValueChange={setText}

      autosuggestionsConfig={{
        textareaPurpose: "the body of an email message",
        chatApiConfigs: {},
      }}
    />
  );
};
```

## [Next Steps](https://docs.copilotkit.ai/guides/copilot-textarea\#next-steps)

- We highly recommend that you check out our simple [Copilot Textarea Tutorial](https://docs.copilotkit.ai/tutorials/ai-powered-textarea/overview).
- Check out the full [CopilotTextarea reference](https://docs.copilotkit.ai/reference/v1/components/CopilotTextarea)

[Previous\\
\\
Bring Your Own LLM](https://docs.copilotkit.ai/guides/bring-your-own-llm) [Next\\
\\
Self Hosting (Copilot Runtime)](https://docs.copilotkit.ai/guides/self-hosting)

### On this page

[Install @copilotkit/react-textarea](https://docs.copilotkit.ai/guides/copilot-textarea#install-copilotkitreact-textarea) [Import Styles](https://docs.copilotkit.ai/guides/copilot-textarea#import-styles) [Add CopilotTextarea to Your Component](https://docs.copilotkit.ai/guides/copilot-textarea#add-copilottextarea-to-your-component) [Next Steps](https://docs.copilotkit.ai/guides/copilot-textarea#next-steps)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/copilot-textarea.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CrewAI Support
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

![CopilotKit Logo](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/copilotkit-logo.svg)

# Page Not Found

Oops! The page you're looking for doesn't exist.

[Go to Documentation](https://docs.copilotkit.ai/)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotRuntime Class Reference
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageUsage

# CopilotRuntime

Copilot Runtime is the back-end component of CopilotKit, enabling interaction with LLMs.

This is the reference for the `CopilotRuntime` class. For more information and example code snippets, please see [Concept: Copilot Runtime](https://docs.copilotkit.ai/concepts/copilot-runtime).

## [Usage](https://docs.copilotkit.ai/reference/v1/classes/CopilotRuntime\#usage)

```
import { CopilotRuntime } from "@copilotkit/runtime";

const copilotKit = new CopilotRuntime();
```

## [Constructor Parameters](https://docs.copilotkit.ai/reference/v1/classes/CopilotRuntime\#constructor-parameters)

middlewareMiddleware

Middleware to be used by the runtime.

```
onBeforeRequest: (options: {
  threadId?: string;
  runId?: string;
  inputMessages: Message[];
  properties: any;
}) => void | Promise<void>;
```

```
onAfterRequest: (options: {
  threadId?: string;
  runId?: string;
  inputMessages: Message[];
  outputMessages: Message[];
  properties: any;
}) => void | Promise<void>;
```

actionsActionsConfiguration<T>

A list of server side actions that can be executed. Will be ignored when remoteActions are set

remoteActionsCopilotKitEndpoint\[\]

Deprecated: Use `remoteEndpoints`.

remoteEndpointsEndpointDefinition\[\]

A list of remote actions that can be executed.

langserveRemoteChainParameters\[\]

An array of LangServer URLs.

delegateAgentProcessingToServiceAdapterboolean

Delegates agent state processing to the service adapter.

When enabled, individual agent state requests will not be processed by the agent itself.
Instead, all processing will be handled by the service adapter.

observability\_cCopilotObservabilityConfig

Configuration for LLM request/response logging.
Requires publicApiKey from CopilotKit component to be set:

```
<CopilotKit publicApiKey="ck_pub_..." />
```

Example logging config:

```
logging: {
  enabled: true, // Enable or disable logging
  progressive: true, // Set to false for buffered logging
  logger: {
    logRequest: (data) => langfuse.trace({ name: "LLM Request", input: data }),
    logResponse: (data) => langfuse.trace({ name: "LLM Response", output: data }),
    logError: (errorData) => langfuse.trace({ name: "LLM Error", metadata: errorData }),
  },
}
```

mcpEndpointsMCPEndpointConfig\[\]

Configuration for connecting to Model Context Protocol (MCP) servers.
Allows fetching and using tools defined on external MCP-compliant servers.
Requires providing the `createMCPClient` function during instantiation.
@experimental

createMCPClientCreateMCPClientFunction

A function that creates an MCP client instance for a given endpoint configuration.
This function is responsible for using the appropriate MCP client library
(e.g., `@copilotkit/runtime`, `ai`) to establish a connection.
Required if `mcpEndpoints` is provided.

```
import { experimental_createMCPClient } from "ai"; // Import from vercel ai library
// ...
const runtime = new CopilotRuntime({
  mcpEndpoints: [{ endpoint: "..." }],
  async createMCPClient(config) {
    return await experimental_createMCPClient({
      transport: {
        type: "sse",
        url: config.endpoint,
        headers: config.apiKey
          ? { Authorization: `Bearer ${config.apiKey}` }
          : undefined,
      },
    });
  }
});
```

processRuntimeRequestrequest: CopilotRuntimeRequest

// \-\-\- MCP Instruction Injection Method ---

requestCopilotRuntimeRequestrequired

discoverAgentsFromEndpointsgraphqlContext: GraphQLContext

graphqlContextGraphQLContextrequired

loadAgentStategraphqlContext: GraphQLContext, threadId: string, agentName: string

graphqlContextGraphQLContextrequired

threadIdstringrequired

agentNamestringrequired

[Previous\\
\\
useLangGraphInterrupt](https://docs.copilotkit.ai/reference/v1/hooks/useLangGraphInterrupt) [Next\\
\\
OpenAIAdapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAdapter)

### On this page

[Usage](https://docs.copilotkit.ai/reference/v1/classes/CopilotRuntime#usage) [Constructor Parameters](https://docs.copilotkit.ai/reference/v1/classes/CopilotRuntime#constructor-parameters)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/v1/classes/CopilotRuntime.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## LangGraph Interrupt Hook
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageUsage

# useLangGraphInterrupt

The useLangGraphInterrupt hook allows setting the generative UI to be displayed on LangGraph's Interrupt event.

`useLangGraphInterrupt` is a React hook that you can use in your application to provide
custom UI to be rendered when using `interrupt` by LangGraph.
Once an Interrupt event is emitted, that hook would execute, allowing to receive user input with a user experience to your choice.

## [Usage](https://docs.copilotkit.ai/reference/v1/hooks/useLangGraphInterrupt\#usage)

### [Simple Usage](https://docs.copilotkit.ai/reference/v1/hooks/useLangGraphInterrupt\#simple-usage)

app/page.tsx

```
import { useLangGraphInterrupt } from "@copilotkit/react-core";
// ...

const YourMainContent = () => {
  // ...

  // styles omitted for brevity
  useLangGraphInterrupt<string>({
    render: ({ event, resolve }) => (
      <div>
        <p>{event.value}</p>
        <form onSubmit={(e) => {
          e.preventDefault();
          resolve((e.target as HTMLFormElement).response.value);
        }}>
          <input type="text" name="response" placeholder="Enter your response" />
          <button type="submit">Submit</button>
        </form>
      </div>
    )
  });
  // ...

  return <div>{/* ... */}</div>
}
```

## [Parameters](https://docs.copilotkit.ai/reference/v1/hooks/useLangGraphInterrupt\#parameters)

actionActionrequired

The action to perform when an Interrupt event is emitted. Either `handler` or `render` must be defined as arguments

namestringrequired

The name of the action.

handler(args: LangGraphInterruptRenderProps<T>) => any \| Promise<any>

A handler to programmatically resolve the Interrupt, or perform operations which result will be passed to the `render` method

render(props: LangGraphInterruptRenderProps<T>) => string \| React.ReactElement

Render lets you define a custom component or string to render when an Interrupt event is emitted.

enabled(args: { eventValue: TEventValue; agentMetadata: AgentSession }) => boolean

Method that returns a boolean, indicating if the interrupt action should run. Useful when using multiple interrupts

dependenciesany\[\]

An optional array of dependencies.

[Previous\\
\\
useCoAgentStateRender](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgentStateRender) [Next\\
\\
CopilotRuntime](https://docs.copilotkit.ai/reference/v1/classes/CopilotRuntime)

### On this page

[Usage](https://docs.copilotkit.ai/reference/v1/hooks/useLangGraphInterrupt#usage) [Simple Usage](https://docs.copilotkit.ai/reference/v1/hooks/useLangGraphInterrupt#simple-usage) [Parameters](https://docs.copilotkit.ai/reference/v1/hooks/useLangGraphInterrupt#parameters)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/v1/hooks/useLangGraphInterrupt.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotTextarea Component
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageExample

# CopilotTextarea

An AI-powered textarea component for your application, which serves as a drop-in replacement for any textarea.

![](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/CopilotTextarea.gif)

`<CopilotTextarea>` is a React component that acts as a drop-in replacement for the standard `<textarea>`,
offering enhanced autocomplete features powered by AI. It is context-aware, integrating seamlessly with the
[`useCopilotReadable`](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotReadable) hook to provide intelligent suggestions based on the application context.

In addition, it provides a hovering editor window (available by default via `Cmd + K` on Mac and `Ctrl + K` on Windows) that allows the user to
suggest changes to the text, for example providing a summary or rephrasing the text.

## [Example](https://docs.copilotkit.ai/reference/v1/components/CopilotTextarea\#example)

```
import { CopilotTextarea } from '@copilotkit/react-textarea';
import "@copilotkit/react-textarea/styles.css";

<CopilotTextarea
  autosuggestionsConfig={{
    textareaPurpose:
     "the body of an email message",
    chatApiConfigs: {},
  }}
/>
```

## [Usage](https://docs.copilotkit.ai/reference/v1/components/CopilotTextarea\#usage)

### [Install Dependencies](https://docs.copilotkit.ai/reference/v1/components/CopilotTextarea\#install-dependencies)

This component is part of the [@copilotkit/react-textarea](https://npmjs.com/package/@copilotkit/react-textarea) package.

```
npm install @copilotkit/react-core @copilotkit/react-textarea
```

### [Usage](https://docs.copilotkit.ai/reference/v1/components/CopilotTextarea\#usage-1)

Use the CopilotTextarea component in your React application similarly to a standard `<textarea />`,
with additional configurations for AI-powered features.

For example:

```
import { useState } from "react";
import { CopilotTextarea } from "@copilotkit/react-textarea";
import "@copilotkit/react-textarea/styles.css";

export function ExampleComponent() {
  const [text, setText] = useState("");

  return (
    <CopilotTextarea
      className="custom-textarea-class"
      value={text}
      onValueChange={(value: string) => setText(value)}
      placeholder="Enter your text here..."
      autosuggestionsConfig={{
        textareaPurpose: "Provide context or purpose of the textarea.",
        chatApiConfigs: {
          suggestionsApiConfig: {
            maxTokens: 20,
            stop: [".", "?", "!"],
          },
        },
      }}
    />
  );
}
```

### [Look & Feel](https://docs.copilotkit.ai/reference/v1/components/CopilotTextarea\#look--feel)

By default, CopilotKit components do not have any styles. You can import CopilotKit's stylesheet at the root of your project:

YourRootComponent.tsx

```
...
import "@copilotkit/react-textarea/styles.css";

export function YourRootComponent() {
  return (
    <CopilotKit>
      ...
    </CopilotKit>
  );
}
```

For more information about how to customize the styles, check out the [Customize Look & Feel](https://docs.copilotkit.ai/guides/custom-look-and-feel/customize-built-in-ui-components) guide.

## [Properties](https://docs.copilotkit.ai/reference/v1/components/CopilotTextarea\#properties)

disableBrandingboolean

Determines whether the CopilotKit branding should be disabled. Default is `false`.

placeholderStyleReact.CSSProperties

Specifies the CSS styles to apply to the placeholder text.

suggestionsStyleReact.CSSProperties

Specifies the CSS styles to apply to the suggestions list.

hoverMenuClassnamestring

A class name to apply to the editor popover window.

valuestring

The initial value of the textarea. Can be controlled via `onValueChange`.

onValueChange(value: string) => void

Callback invoked when the value of the textarea changes.

onChange(event: React.ChangeEvent<HTMLTextAreaElement>) => void

Callback invoked when a `change` event is triggered on the textarea element.

shortcutstring

The shortcut to use to open the editor popover window. Default is `"Cmd-k"`.

autosuggestionsConfigAutosuggestionsConfigUserSpecifiedrequired

Configuration settings for the autosuggestions feature.
For full reference, [check the interface on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/CopilotKit/packages/react-textarea/src/types/base/base-copilot-textarea-props.tsx#L8).

textareaPurposestringrequired

The purpose of the text area in plain text.

Example: "The body of the email response"

chatApiConfigsChatApiConfigs

The chat API configurations.

**NOTE:** You must provide specify at least one of `suggestionsApiConfig` or `insertionApiConfig`.

suggestionsApiConfigSuggestionsApiConfig

For full reference, please [click here](https://github.com/CopilotKit/CopilotKit/blob/main/CopilotKit/packages/react-textarea/src/types/autosuggestions-config/suggestions-api-config.tsx#L4).

insertionApiConfigInsertionApiConfig

For full reference, please [click here](https://github.com/CopilotKit/CopilotKit/blob/main/CopilotKit/packages/react-textarea/src/types/autosuggestions-config/insertions-api-config.tsx#L4).

disabledboolean

Whether the textarea is disabled.

disableBrandingboolean

Whether to disable the CopilotKit branding.

placeholderStyleReact.CSSProperties

Specifies the CSS styles to apply to the placeholder text.

suggestionsStyleReact.CSSProperties

Specifies the CSS styles to apply to the suggestions list.

hoverMenuClassnamestring

A class name to apply to the editor popover window.

valuestring

The initial value of the textarea. Can be controlled via `onValueChange`.

onValueChange(value: string) => void

Callback invoked when the value of the textarea changes.

onChange(event: React.ChangeEvent<HTMLTextAreaElement>) => void

Callback invoked when a `change` event is triggered on the textarea element.

shortcutstring

The shortcut to use to open the editor popover window. Default is `"Cmd-k"`.

[Previous\\
\\
CopilotSidebar](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotSidebar) [Next\\
\\
CopilotKit](https://docs.copilotkit.ai/reference/v1/components/CopilotKit)

### On this page

[Example](https://docs.copilotkit.ai/reference/v1/components/CopilotTextarea#example) [Usage](https://docs.copilotkit.ai/reference/v1/components/CopilotTextarea#usage) [Install Dependencies](https://docs.copilotkit.ai/reference/v1/components/CopilotTextarea#install-dependencies) [Usage](https://docs.copilotkit.ai/reference/v1/components/CopilotTextarea#usage-1) [Look & Feel](https://docs.copilotkit.ai/reference/v1/components/CopilotTextarea#look--feel) [Properties](https://docs.copilotkit.ai/reference/v1/components/CopilotTextarea#properties)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/components/CopilotTextarea.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotKit Quickstart Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageInstall CopilotKit

# Quickstart

Get started with CopilotKit in under 5 minutes.

Copilot Cloud (Recommended)

Use our hosted backend endpoint to get started quickly.

Self-hosting

Learn to host CopilotKit's runtime yourself with your own backend.

## [Install CopilotKit](https://docs.copilotkit.ai/quickstart?component=CopilotSidebar\#install-copilotkit)

First, install the latest packages for CopilotKit.

npmpnpmyarnbun

```
npm install @copilotkit/react-ui @copilotkit/react-core
```

## [Get a Copilot Cloud Public API Key](https://docs.copilotkit.ai/quickstart?component=CopilotSidebar\#get-a-copilot-cloud-public-api-key)

Navigate to [Copilot Cloud](https://cloud.copilotkit.ai/) and follow the instructions to get a public API key - it's free!

## [Setup the CopilotKit Provider](https://docs.copilotkit.ai/quickstart?component=CopilotSidebar\#setup-the-copilotkit-provider)

The [`<CopilotKit>`](https://docs.copilotkit.ai/reference/v1/components/CopilotKit) component must wrap the Copilot-aware parts of your application. For most use-cases,
it's appropriate to wrap the CopilotKit provider around the entire app, e.g. in your layout.tsx.

layout.tsx

```
import "./globals.css";
import { ReactNode } from "react";
import { CopilotKit } from "@copilotkit/react-core";

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        {/* Use the public api key you got from Copilot Cloud  */}
        <CopilotKit publicApiKey="<your-copilot-cloud-public-api-key>">
          {children}
        </CopilotKit>
      </body>
    </html>
  );
}
```

## [Choose a Copilot UI](https://docs.copilotkit.ai/quickstart?component=CopilotSidebar\#choose-a-copilot-ui)

You are almost there! Now it's time to setup your Copilot UI.

First, import the default styles in your root component (typically `layout.tsx`) :

```
import "@copilotkit/react-ui/styles.css";
```

Copilot UI ships with a number of built-in UI patterns, choose whichever one you like.

CopilotPopupCopilotSidebarCopilotChatHeadless UI

`CopilotSidebar` is a convenience wrapper for `CopilotChat` that wraps your main content in the view hierarchy. It provides a **collapsible and expandable sidebar** chat interface.

![Popup Example](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/sidebar-example.gif)

```
import { CopilotSidebar } from "@copilotkit/react-ui";

export function YourApp() {
  return (
    <CopilotSidebar
      defaultOpen={true}
      instructions={"You are assisting the user as best as you can. Answer in the best way possible given the data you have."}
      labels={{
        title: "Sidebar Assistant",
        initial: "How can I help you today?",
      }}
    >
      <YourMainContent />
    </CopilotSidebar>
  );
}
```

* * *

## [Next Steps](https://docs.copilotkit.ai/quickstart?component=CopilotSidebar\#next-steps)

🎉 Congrats! You've successfully integrated a fully functional chatbot in your application! Give it a try now and see it in action. Want to
take it further? Learn more about what CopilotKit has to offer!

[**Connecting Your Data** \\
Learn how to connect CopilotKit to your data, application state and user state.](https://docs.copilotkit.ai/guides/connect-your-data) [**Generative UI** \\
Learn how to render custom UI components directly in the CopilotKit chat window.](https://docs.copilotkit.ai/guides/generative-ui) [**Frontend Actions** \\
Learn how to allow your copilot to take applications on frontend.](https://docs.copilotkit.ai/guides/frontend-actions) [**CoAgents (LangGraph)** \\
Check out our section about CoAgents, our approach to building agentic copilots and experiences.](https://docs.copilotkit.ai/coagents)

[Previous\\
\\
Introduction](https://docs.copilotkit.ai/) [Next\\
\\
Customize UI](https://docs.copilotkit.ai/guides/custom-look-and-feel)

### On this page

[Install CopilotKit](https://docs.copilotkit.ai/quickstart?component=CopilotSidebar#install-copilotkit) [Get a Copilot Cloud Public API Key](https://docs.copilotkit.ai/quickstart?component=CopilotSidebar#get-a-copilot-cloud-public-api-key) [Setup the CopilotKit Provider](https://docs.copilotkit.ai/quickstart?component=CopilotSidebar#setup-the-copilotkit-provider) [Choose a Copilot UI](https://docs.copilotkit.ai/quickstart?component=CopilotSidebar#choose-a-copilot-ui) [Install CopilotKit](https://docs.copilotkit.ai/quickstart?component=CopilotSidebar#install-copilotkit-1) [Set up a Copilot Runtime Endpoint](https://docs.copilotkit.ai/quickstart?component=CopilotSidebar#set-up-a-copilot-runtime-endpoint) [Configure the CopilotKit Provider](https://docs.copilotkit.ai/quickstart?component=CopilotSidebar#configure-the-copilotkit-provider) [Choose a Copilot UI](https://docs.copilotkit.ai/quickstart?component=CopilotSidebar#choose-a-copilot-ui-1) [Next Steps](https://docs.copilotkit.ai/quickstart?component=CopilotSidebar#next-steps)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/quickstart.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Generative UI Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageRender custom components in the chat UI

# Generative UI

Learn how to embed custom UI components in the chat window.

# [Render custom components in the chat UI](https://docs.copilotkit.ai/guides/generative-ui\#render-custom-components-in-the-chat-ui)

When a user interacts with your Copilot, you may want to render a custom UI component. [`useCopilotAction`](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction) allows to give the LLM the
option to render your custom component through the `render` property.

Render a componentFetch data & renderrenderAndWaitForResponse (HITL)Render stringsCatch all renders

[`useCopilotAction`](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction) can be used with a `render` function and without a `handler` to display information or UI elements within the chat.

Here's an example to render a calendar meeting.

![Example of render-only Copilot action](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/render-only-example.png)

```
"use client" // only necessary if you are using Next.js with the App Router.
import { useCopilotAction } from "@copilotkit/react-core";

export function YourComponent() {
  useCopilotAction({
    name: "showCalendarMeeting",
    description: "Displays calendar meeting information",
    parameters: [\
      {\
        name: "date",\
        type: "string",\
        description: "Meeting date (YYYY-MM-DD)",\
        required: true\
      },\
      {\
        name: "time",\
        type: "string",\
        description: "Meeting time (HH:mm)",\
        required: true\
      },\
      {\
        name: "meetingName",\
        type: "string",\
        description: "Name of the meeting",\
        required: false\
      }\
    ],

    render: ({ status, args }) => {
      const { date, time, meetingName } = args;

      if (status === 'inProgress') {
        return <LoadingView />; // Your own component for loading state
      } else {
        const meetingProps: CalendarMeetingCardProps = {
          date: date,
          time,
          meetingName
        };
        return <CalendarMeetingCardComponent {...meetingProps} />;
      }
    },
  });

  return (
    <>...</>
  );
}
```

### What do the different status states mean?

### Why do I need "use client" in Next.js with the App Router?

## [Test it out!](https://docs.copilotkit.ai/guides/generative-ui\#test-it-out)

After defining the action with a render method, ask the copilot to perform the task. For example, you can now ask the copilot to "show tasks" and see the custom UI component rendered in the chat interface.

You can read more about the `useCopilotAction` hook
[here](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction).

[Previous\\
\\
Backend Data](https://docs.copilotkit.ai/guides/connect-your-data/backend) [Next\\
\\
Frontend Actions](https://docs.copilotkit.ai/guides/frontend-actions)

### On this page

[Render custom components in the chat UI](https://docs.copilotkit.ai/guides/generative-ui#render-custom-components-in-the-chat-ui) [Test it out!](https://docs.copilotkit.ai/guides/generative-ui#test-it-out)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/generative-ui.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Chat Suggestions Hook
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageUsage

# useCopilotChatSuggestions

The useCopilotChatSuggestions hook generates suggestions in the chat window based on real-time app state.

useCopilotChatSuggestions is experimental. The interface is not final and
can change without notice.

`useCopilotReadable` is a React hook that provides app-state and other information
to the Copilot. Optionally, the hook can also handle hierarchical state within your
application, passing these parent-child relationships to the Copilot.

![](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/use-copilot-chat-suggestions/use-copilot-chat-suggestions.gif)

## [Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions\#usage)

### [Install Dependencies](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions\#install-dependencies)

This component is part of the [@copilotkit/react-ui](https://npmjs.com/package/@copilotkit/react-ui) package.

```
npm install @copilotkit/react-core @copilotkit/react-ui
```

### [Simple Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions\#simple-usage)

```
import { useCopilotChatSuggestions } from "@copilotkit/react-ui";

export function MyComponent() {
  const [employees, setEmployees] = useState([]);

  useCopilotChatSuggestions({
    instructions: `The following employees are on duty: ${JSON.stringify(employees)}`,
  });
}
```

### [Dependency Management](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions\#dependency-management)

```
import { useCopilotChatSuggestions } from "@copilotkit/react-ui";

export function MyComponent() {
  useCopilotChatSuggestions(
    {
      instructions: "Suggest the most relevant next actions.",
    },
    [appState],
  );
}
```

In the example above, the suggestions are generated based on the given instructions.
The hook monitors `appState`, and updates suggestions accordingly whenever it changes.

### [Behavior and Lifecycle](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions\#behavior-and-lifecycle)

The hook registers the configuration with the chat context upon component mount and
removes it on unmount, ensuring a clean and efficient lifecycle management.

## [Parameters](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions\#parameters)

instructionsstringrequired

A prompt or instructions for the GPT to generate suggestions.

minSuggestionsnumber

Default:"1"

The minimum number of suggestions to generate. Defaults to `1`.

maxSuggestionsnumber

Default:"1"

The maximum number of suggestions to generate. Defaults to `3`.

available'enabled' \| 'disabled'

Default:"enabled"

Whether the suggestions are available. Defaults to `enabled`.

classNamestring

An optional class name to apply to the suggestions.

[Previous\\
\\
useCopilotChat](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChat) [Next\\
\\
useCoAgent](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgent)

### On this page

[Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions#usage) [Install Dependencies](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions#install-dependencies) [Simple Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions#simple-usage) [Dependency Management](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions#dependency-management) [Behavior and Lifecycle](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions#behavior-and-lifecycle) [Parameters](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions#parameters)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/v1/hooks/useCopilotChatSuggestions.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Anonymous Telemetry Management
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageHow to opt out of anonymous telemetry

# Anonymous Telemetry

We use anonymous telemetry (metadata-only) to learn how to improve CopilotKit.

- Open-source telemetry is **completely anonymous**
- We **do not collect any data** about end-users (the users interacting with your copilot)
- We **do not collect any application data** flowing through your system, only CopilotKit metadata
- We do not sell or share any data with third parties
- We do not use cookies or trackers in open-source telemetry
- To minimize the frequency of data sent, we apply batching and sampling to telemetry

## [How to opt out of anonymous telemetry](https://docs.copilotkit.ai/telemetry\#how-to-opt-out-of-anonymous-telemetry)

You can opt out of open-source telemetry in multiple ways.

In CopilotRuntime, simply set `COPILOTKIT_TELEMETRY_DISABLED=true`. We also respect [Do Not Track (DNT)](https://consoledonottrack.com/).

Alternatively, you can directly set the `telemetryDisabled` flag to `true` when configuring your Copilot Runtime endpoint.

## [How to adjust telemetry sample rate](https://docs.copilotkit.ai/telemetry\#how-to-adjust-telemetry-sample-rate)

The default sample rate is `0.05` (5%). You can adjust it by setting the `COPILOTKIT_TELEMETRY_SAMPLE_RATE` to any value between 0 and 1.

## [Get in touch](https://docs.copilotkit.ai/telemetry\#get-in-touch)

If you have any questions or concerns, please reach out at [hello@copilotkit.ai](mailto:hello@copilotkit.ai).

[Previous\\
\\
Documentation Contributions](https://docs.copilotkit.ai/contributing/docs-contributions) [Next\\
\\
LangSmith](https://docs.copilotkit.ai/observability/langsmith)

### On this page

[How to opt out of anonymous telemetry](https://docs.copilotkit.ai/telemetry#how-to-opt-out-of-anonymous-telemetry) [How to adjust telemetry sample rate](https://docs.copilotkit.ai/telemetry#how-to-adjust-telemetry-sample-rate) [Get in touch](https://docs.copilotkit.ai/telemetry#get-in-touch)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/(other)/telemetry/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Shared State Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is shared state?

# Shared State

Create a two-way connection between your UI and agent state.

![Shared State Demo](https://docs.copilotkit.ai/_next/image?url=%2Fimages%2Fcoagents%2FSharedStateCoAgents.gif&w=3840&q=75)

This video demonstrates the [Research Canvas](https://docs.copilotkit.ai/coagents/examples/research-canvas) utilizing shared state.

## [What is shared state?](https://docs.copilotkit.ai/coagents/shared-state\#what-is-shared-state)

CoAgents maintain a shared state that seamlessly connects your UI with the agent's execution. This shared state system allows you to:

- Display the agent's current progress and intermediate results
- Update the agent's state through UI interactions
- React to state changes in real-time across your application

![Agentic Copilot State Diagram](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/coagents/coagents-state-diagram.png)

The foundation of this system is built on LangGraph's stateful architecture. Unlike traditional LangChains, LangGraphs maintain their
internal state throughout execution, which you can access via the `useCoAgentState` hook.

## [When should I use this?](https://docs.copilotkit.ai/coagents/shared-state\#when-should-i-use-this)

State streaming is perfect when you want to faciliate collaboration between your agent and the user. Any state that your LangGraph agent
persists will be automatically shared by the UI. Similarly, any state that the user updates in the UI will be automatically reflected

This allows for a consistent experience where both the agent and the user are on the same page.

[Previous\\
\\
Node-based](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow) [Next\\
\\
Reading agent state](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read)

### On this page

[What is shared state?](https://docs.copilotkit.ai/coagents/shared-state#what-is-shared-state) [When should I use this?](https://docs.copilotkit.ai/coagents/shared-state#when-should-i-use-this)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/shared-state/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

![Shared State Demo](https://docs.copilotkit.ai/_next/image?url=%2Fimages%2Fcoagents%2FSharedStateCoAgents.gif&w=3840&q=75)

## Frontend Actions Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageLet the Copilot Take Action

# Frontend Actions

Learn how to enable your Copilot to take actions in the frontend.

# [Let the Copilot Take Action](https://docs.copilotkit.ai/guides/frontend-actions\#let-the-copilot-take-action)

### [`useCopilotAction`](https://docs.copilotkit.ai/guides/frontend-actions\#usecopilotaction)

In addition to understanding state, you can empower the copilot to take actions. Use the [`useCopilotAction`](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction) hook to define specific tasks that the copilot can perform based on user input.

YourComponent.tsx

```
"use client" // only necessary if you are using Next.js with the App Router.
import { useCopilotAction } from "@copilotkit/react-core";

export function MyComponent() {
  const [todos, setTodos] = useState<string[]>([]);

  // Define Copilot action
  useCopilotAction({
    name: "addTodoItem",
    description: "Add a new todo item to the list",
    parameters: [\
      {\
        name: "todoText",\
        type: "string",\
        description: "The text of the todo item to add",\
        required: true,\
      },\
    ],
    handler: async ({ todoText }) => {
      setTodos([...todos, todoText]);
    },
  });

  return (
    <ul>
      {todos.map((todo, index) => (
        <li key={index}>{todo}</li>
      ))}
    </ul>
  );
}
```

### Changing where/when the action is executed

### [Specify `"use client"` (Next.js App Router)](https://docs.copilotkit.ai/guides/frontend-actions\#specify-use-client-nextjs-app-router)

This is only necessary if you are using Next.js with the App Router.

YourComponent.tsx

```
"use client"
```

Like other React hooks such as `useState` and `useEffect`, this is a **client-side** hook.
If you're using Next.js with the App Router, you'll need to add the `"use client"` directive at the top of any file using this hook.

### [Test it out!](https://docs.copilotkit.ai/guides/frontend-actions\#test-it-out)

After defining the action, ask the copilot to perform the task. For example, you can now ask the copilot to "select an employee" by specifying the `employeeId`.

![Example of Copilot action](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/copilot-action-example.gif)

## [Next Steps](https://docs.copilotkit.ai/guides/frontend-actions\#next-steps)

[**useCopilotAction Reference** \\
Refer to the documentation for the useCopilotAction hook.](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction) [**Actions + Generative UI** \\
Learn how to render custom UI components alongside your actions, directly in the CopilotKit chat window.](https://docs.copilotkit.ai/guides/generative-ui) [**Backend Actions** \\
Enable backend services to trigger actions via copilot backend hooks.](https://docs.copilotkit.ai/guides/backend-actions)

[Previous\\
\\
Generative UI](https://docs.copilotkit.ai/guides/generative-ui) [Next\\
\\
Backend Actions & Agents](https://docs.copilotkit.ai/guides/backend-actions)

### On this page

[Let the Copilot Take Action](https://docs.copilotkit.ai/guides/frontend-actions#let-the-copilot-take-action) [useCopilotAction](https://docs.copilotkit.ai/guides/frontend-actions#usecopilotaction) [Test it out!](https://docs.copilotkit.ai/guides/frontend-actions#test-it-out) [Next Steps](https://docs.copilotkit.ai/guides/frontend-actions#next-steps)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/frontend-actions.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotKit Common Issues
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageI am getting network errors / API not found error

# Common Issues

Common issues you may encounter when using Copilots.

Welcome to the CopilotKit Troubleshooting Guide! Here, you can find answers to common issues

Have an issue not listed here? Open a ticket on [GitHub](https://github.com/CopilotKit/CopilotKit/issues) or reach out on [Discord](https://discord.com/invite/6dffbvGU3D)
and we'll be happy to help.

We also highly encourage any open source contributors that want to add their own troubleshooting issues to [Github as a pull request](https://github.com/CopilotKit/CopilotKit/blob/main/CONTRIBUTING.md).

## [I am getting network errors / API not found error](https://docs.copilotkit.ai/troubleshooting/common-issues\#i-am-getting-network-errors--api-not-found-error)

If you're encountering network or API errors, here's how to troubleshoot:

### Check your endpoint configuration

### localhost vs 127.0.0.1

### Verify your backend is running

## [I am getting "CopilotKit's Remote Endpoint" not found error](https://docs.copilotkit.ai/troubleshooting/common-issues\#i-am-getting-copilotkits-remote-endpoint-not-found-error)

If you're getting a "CopilotKit's Remote Endpoint not found" error, it usually means the server serving `/info` endpoint isn't accessible. Here's how to fix it:

### Check your FastAPI setup (if using python's FastAPI)

### Test your endpoint

## [Connection issues with tunnel creation](https://docs.copilotkit.ai/troubleshooting/common-issues\#connection-issues-with-tunnel-creation)

If you notice the tunnel creation process spinning indefinitely, your router or ISP might be blocking the connection to CopilotKit's tunnel service.

### Router or ISP blocking tunnel connections

[Previous\\
\\
State Machines](https://docs.copilotkit.ai/cookbook/state-machine) [Next\\
\\
Migrate to 1.8.2](https://docs.copilotkit.ai/troubleshooting/migrate-to-1.8.2)

### On this page

[I am getting network errors / API not found error](https://docs.copilotkit.ai/troubleshooting/common-issues#i-am-getting-network-errors--api-not-found-error) [I am getting "CopilotKit's Remote Endpoint" not found error](https://docs.copilotkit.ai/troubleshooting/common-issues#i-am-getting-copilotkits-remote-endpoint-not-found-error) [Connection issues with tunnel creation](https://docs.copilotkit.ai/troubleshooting/common-issues#connection-issues-with-tunnel-creation)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/troubleshooting/common-issues.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## LangGraph Quickstart Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pagePrerequisites

# Quickstart (LangGraph)

Turn your LangGraph into an agent-native application in 10 minutes.

## [Prerequisites](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#prerequisites)

Before you begin, you'll need the following:

- [**LangSmith API key**](https://docs.smith.langchain.com/administration/how_to_guides/organization_management/create_account_api_key#api-keys)
- [**OpenAI API key**](https://platform.openai.com/api-keys)

## [Getting started](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#getting-started)

### [Install CopilotKit](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#install-copilotkit)

First, install the latest packages for CopilotKit into your frontend.

npmpnpmyarnbun

```
npm install @copilotkit/react-ui @copilotkit/react-core
```

Do you already have a LangGraph agent?

You will need a LangGraph agent to get started with CoAgents!

Either bring your own or feel free to use our starter repo.

Bring your own LangGraph agent

I already have a LangGraph agent and want to use it with CopilotKit.

![CopilotKit Logo](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/copilotkit-logo.svg)

Use the CoAgents Starter repo

I don't have a LangGraph agent yet, but want to get started quickly.

### [Start your LangGraph Agent](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#start-your-langgraph-agent)

Local (LangGraph Studio)Self hosted (FastAPI)LangGraph Platform

For local development, you can use the [LangGraph CLI](https://docs.langchain.com/langsmith/cli) to start a development server and LangGraph studio session.

You will need a [LangSmith account](https://smith.langchain.com/) to use this method.

```
# For Python 3.11 or above
langgraph dev --host localhost --port 8000
```

```
# For TypeScript with Node 18 or above
npx @langchain/langgraph-cli dev --host localhost --port 8000
```

After starting the LangGraph server, the deployment URL will be `http://localhost:8000`.

### Having trouble?

Choose your connection method

Now you need to connect your LangGraph agent to CopilotKit.

Copilot Cloud (Recommended)

I want to host my Copilot on Copilot Cloud

Self-Hosted Copilot Runtime

I want to self-host the Copilot Runtime

### [Add a remote endpoint for your LangGraph agent](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#add-a-remote-endpoint-for-your-langgraph-agent)

Using Copilot Cloud, you need to connect a remote endpoint that will connect to your LangGraph agent.

Local (LangGraph Studio)Self hosted (FastAPI)LangGraph Platform

When running your LangGraph agent locally, you can open a tunnel to it so Copilot Cloud can connect to it.
First, make sure you're logged in to [Copilot Cloud](https://cloud.copilotkit.ai/), and then authenticate the CLI by running:

```
npx copilotkit@latest login
```

Once authenticated, run:

```
npx copilotkit@latest dev --port 8000
```

### [Setup your CopilotKit provider](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#setup-your-copilotkit-provider)

The [`<CopilotKit>`](https://docs.copilotkit.ai/reference/v1/components/CopilotKit) component must wrap the Copilot-aware parts of your application. For most use-cases,
it's appropriate to wrap the CopilotKit provider around the entire app, e.g. in your layout.tsx.

Since we're using Copilot Cloud, we need to grab our public API key from the [Copilot Cloud dashboard](https://cloud.copilotkit.ai/).

layout.tsx

```
import "./globals.css";
import { ReactNode } from "react";
import { CopilotKit } from "@copilotkit/react-core";

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        {/* Use the public api key you got from Copilot Cloud  */}
        <CopilotKit
          publicApiKey="<your-copilot-cloud-public-api-key>"
          agent="sample_agent" // the name of the agent you want to use
        >
          {children}
        </CopilotKit>
      </body>
    </html>
  );
}
```

Looking for a way to run multiple LangGraph agents? Check out our [Multi-Agent](https://docs.copilotkit.ai/coagents/multi-agent-flows) guide.

## [Choose a Copilot UI](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#choose-a-copilot-ui)

You are almost there! Now it's time to setup your Copilot UI.

First, import the default styles in your root component (typically `layout.tsx`) :

```
import "@copilotkit/react-ui/styles.css";
```

Copilot UI ships with a number of built-in UI patterns, choose whichever one you like.

CopilotPopupCopilotSidebarCopilotChatHeadless UI

`CopilotPopup` is a convenience wrapper for `CopilotChat` that lives at the same level as your main content in the view hierarchy. It provides **a floating chat interface** that can be toggled on and off.

![Popup Example](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/popup-example.gif)

```
import { CopilotPopup } from "@copilotkit/react-ui";

export function YourApp() {
  return (
    <>
      <YourMainContent />
      <CopilotPopup
        instructions={"You are assisting the user as best as you can. Answer in the best way possible given the data you have."}
        labels={{
          title: "Popup Assistant",
          initial: "Need any help?",
        }}
      />
    </>
  );
}
```

### [🎉 Talk to your agent!](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#-talk-to-your-agent)

Congrats! You've successfully integrated a LangGraph agent chatbot to your application. To start, try asking a few questions to your agent.

```
Can you tell me a joke?
```

```
Can you help me understand AI?
```

```
What do you think about React?
```

### Having trouble?

* * *

## [What's next?](https://docs.copilotkit.ai/coagents/quickstart/langgraph\#whats-next)

You've now got a LangGraph agent running in CopilotKit! Now you can start exploring the various ways that CopilotKit
can help you build power agent native applications.

[**Implement Human in the Loop** \\
Allow your users and agents to collaborate together on tasks.](https://docs.copilotkit.ai/coagents/human-in-the-loop) [**Utilize the Shared State** \\
Learn how to synchronize your agent's state with your UI's state, and vice versa.](https://docs.copilotkit.ai/coagents/shared-state) [**Add some generative UI** \\
Render your agent's progress and output in the UI.](https://docs.copilotkit.ai/coagents/generative-ui) [**Setup frontend actions** \\
Give your agent the ability to call frontend tools, directly updating your application.](https://docs.copilotkit.ai/coagents/frontend-actions)

[Previous\\
\\
Introduction](https://docs.copilotkit.ai/coagents) [Next\\
\\
Chat with an Agent](https://docs.copilotkit.ai/coagents/agentic-chat-ui)

### On this page

[Prerequisites](https://docs.copilotkit.ai/coagents/quickstart/langgraph#prerequisites) [Getting started](https://docs.copilotkit.ai/coagents/quickstart/langgraph#getting-started) [Install CopilotKit](https://docs.copilotkit.ai/coagents/quickstart/langgraph#install-copilotkit) [Clone the coagents-starter repo and install dependencies:](https://docs.copilotkit.ai/coagents/quickstart/langgraph#clone-the-coagents-starter-repo-and-install-dependencies) [Install dependencies:](https://docs.copilotkit.ai/coagents/quickstart/langgraph#install-dependencies) [Install dependencies:](https://docs.copilotkit.ai/coagents/quickstart/langgraph#install-dependencies-1) [Create a .env file](https://docs.copilotkit.ai/coagents/quickstart/langgraph#create-a-env-file) [Add your API keys](https://docs.copilotkit.ai/coagents/quickstart/langgraph#add-your-api-keys) [Start your LangGraph Agent](https://docs.copilotkit.ai/coagents/quickstart/langgraph#start-your-langgraph-agent) [Add a remote endpoint for your LangGraph agent](https://docs.copilotkit.ai/coagents/quickstart/langgraph#add-a-remote-endpoint-for-your-langgraph-agent) [Setup your CopilotKit provider](https://docs.copilotkit.ai/coagents/quickstart/langgraph#setup-your-copilotkit-provider) [Install Copilot Runtime](https://docs.copilotkit.ai/coagents/quickstart/langgraph#install-copilot-runtime) [Setup a Copilot Runtime Endpoint](https://docs.copilotkit.ai/coagents/quickstart/langgraph#setup-a-copilot-runtime-endpoint) [Add your LangGraph deployment to Copilot Runtime](https://docs.copilotkit.ai/coagents/quickstart/langgraph#add-your-langgraph-deployment-to-copilot-runtime) [Configure the CopilotKit Provider](https://docs.copilotkit.ai/coagents/quickstart/langgraph#configure-the-copilotkit-provider) [Choose a Copilot UI](https://docs.copilotkit.ai/coagents/quickstart/langgraph#choose-a-copilot-ui) [🎉 Talk to your agent!](https://docs.copilotkit.ai/coagents/quickstart/langgraph#-talk-to-your-agent) [What's next?](https://docs.copilotkit.ai/coagents/quickstart/langgraph#whats-next)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/quickstart/langgraph.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## LangGraph Framework Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageCoAgents and LangGraph

# LangGraph

An agentic framework for building LLM applications that can be used with CopilotKit.

![CoAgents High Level Overview](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/coagents/coagents-highlevel-overview.png)

LangGraph is an agentic framework for building LLM applications that can be used with CopilotKit. It is built on top of LangChain's
[LangGraph](https://docs.langchain.com/oss/python/langgraph/overview) library and extends it with additional functionality for building agentic
applications.

## [CoAgents and LangGraph](https://docs.copilotkit.ai/coagents/concepts/langgraph\#coagents-and-langgraph)

How do CoAgents extend LangGraph? Let's read the first sentence of their [project page](https://docs.langchain.com/oss/python/langgraph/overview) to understand.

> LangGraph is a library for building stateful, multi-actor applications with LLMs, used to create agent and multi-agent workflows.

There are some key terms here so let's break them down and understand how they relate to and are implemented by CoAgents.

- **Stateful**: CoAgents have bi-directional state sharing with the agent and UI. This allows for the agent to remember
information from previous messages and the UI to update the agent with new information. Read more about how state sharing works
[here](https://docs.copilotkit.ai/coagents/shared-state).
- **Multi-actor**: CoAgents allow for multiple agents to interact with each other. CopilotKit acts as the "ground-truth"
when transitioning between agents. Read more about how multi-actor workflows work [here](https://docs.copilotkit.ai/coagents/multi-agent-flows)
and how messages are managed [here](https://docs.copilotkit.ai/coagents/concepts/message-management).
- **LLMs**: CoAgents use large language models to generate responses. This is useful for building applications that need to
generate natural language responses.

Some additional functionality not mentioned here is:

- **Human in the loop**: CoAgents enabled human review and approval of generated responses. Read more about how this works
[here](https://docs.copilotkit.ai/coagents/human-in-the-loop).
- **Tool calling**: Tool calling is a fundamental building block for agentic workflows. They allow for greater control over what
the agent can do and can be used to interact with external systems. CoAgents allow you to easily render in-progress
tool calls in the UI so your users know what's happening. Read more about streaming tool calls [here](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates).

## [Building with Python or JavaScript](https://docs.copilotkit.ai/coagents/concepts/langgraph\#building-with-python-or-javascript)

You can natively build LangGraph applications using Python or JavaScript. Throughout our documentation of integrating with LangGraph
you will see options for building in Python or JavaScript.

For a quick refresher on each, check out the [Python](https://docs.langchain.com/oss/python/langgraph/overview) and
[JavaScript](https://docs.langchain.com/oss/javascript/langgraph/overview) guides from LangGraph:

## [LangGraph Platform](https://docs.copilotkit.ai/coagents/concepts/langgraph\#langgraph-platform)

LangGraph Platform is a platform for building and deploying LangGraph applications. It is built on top of the LangGraph library and
allows you to build, manage, and deploy graphs that CopilotKit can interface with. For more information checkout the official
[LangGraph Platform](https://docs.langchain.com/oss/python/langgraph/overview) documentation.

If you want to take the next step to deploy your LangGraph application as an CoAgent, check out our [quickstart guide](https://docs.copilotkit.ai/coagents/quickstart/langgraph).

[Previous\\
\\
Agentic Copilots](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots) [Next\\
\\
Message flow](https://docs.copilotkit.ai/coagents/concepts/message-management)

### On this page

[CoAgents and LangGraph](https://docs.copilotkit.ai/coagents/concepts/langgraph#coagents-and-langgraph) [Building with Python or JavaScript](https://docs.copilotkit.ai/coagents/concepts/langgraph#building-with-python-or-javascript) [LangGraph Platform](https://docs.copilotkit.ai/coagents/concepts/langgraph#langgraph-platform)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/concepts/langgraph.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Backend Actions Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this page

# Backend Actions & Agents

Learn how to enable backend actions & agents in your Copilot.

[**TypeScript / Node.js Actions** \\
Implement backend actions using TypeScript or Node.js within the CopilotRuntime.](https://docs.copilotkit.ai/guides/backend-actions/typescript-backend-actions) [**LangChain.js Actions** \\
Integrate LangChain JS chains as backend actions in your Copilot.](https://docs.copilotkit.ai/guides/backend-actions/langchain-js-backend-actions) [**LangServe Integration** \\
Connect your Copilot to LangChain chains hosted as separate services.](https://docs.copilotkit.ai/guides/backend-actions/langserve-backend-actions) [**Python SDK** \\
Use the CopilotKit Python SDK to create powerful remote actions and agents.](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint) [**CoAgents (LangGraph)** \\
Deeply embed LangGraph agents in applications](https://docs.copilotkit.ai/coagents)

[Previous\\
\\
Frontend Actions](https://docs.copilotkit.ai/guides/frontend-actions) [Next\\
\\
TypeScript (Node.js)](https://docs.copilotkit.ai/guides/backend-actions/typescript-backend-actions)

### On this page

No Headings

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/backend-actions/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Agent State Rendering
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageUsage

# useCoAgentStateRender

The useCoAgentStateRender hook allows you to render the state of the agent in the chat.

The useCoAgentStateRender hook allows you to render UI or text based components on a Agentic Copilot's state in the chat.
This is particularly useful for showing intermediate state or progress during Agentic Copilot operations.

## [Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgentStateRender\#usage)

### [Simple Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgentStateRender\#simple-usage)

```
import { useCoAgentStateRender } from "@copilotkit/react-core";

type YourAgentState = {
  agent_state_property: string;
}

useCoAgentStateRender<YourAgentState>({
  name: "basic_agent",
  nodeName: "optionally_specify_a_specific_node",
  render: ({ status, state, nodeName }) => {
    return (
      <YourComponent
        agentStateProperty={state.agent_state_property}
        status={status}
        nodeName={nodeName}
      />
    );
  },
});
```

This allows for you to render UI components or text based on what is happening within the agent.

### [Example](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgentStateRender\#example)

A great example of this is in our Perplexity Clone where we render the progress of an agent's internet search as it is happening.
You can play around with it below or learn how to build it with its [demo](https://docs.copilotkit.ai/coagents/videos/perplexity-clone).

This example is hosted on Vercel and may take a few seconds to load.

AI Researcher

# What would you like to know?

0 / 250

Research

🚙Electric cars sold in 2024 vs 2023

💰Top 10 richest people in the world

🌍 Population of the World

⛅️Weather in Seattle VS New York

OpenAI

## [Parameters](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgentStateRender\#parameters)

namestringrequired

The name of the coagent.

nodeNamestring

The node name of the coagent.

handler(props: CoAgentStateRenderHandlerArguments<T>) => void \| Promise<void>

The handler function to handle the state of the agent.

render\| ((props: CoAgentStateRenderProps<T>) => string \| React.ReactElement \| undefined \| null) \| string

The render function to handle the state of the agent.

[Previous\\
\\
useCoAgent](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgent) [Next\\
\\
useLangGraphInterrupt](https://docs.copilotkit.ai/reference/v1/hooks/useLangGraphInterrupt)

### On this page

[Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgentStateRender#usage) [Simple Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgentStateRender#simple-usage) [Example](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgentStateRender#example) [Parameters](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgentStateRender#parameters)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/v1/hooks/useCoAgentStateRender.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## useCopilotReadable Hook
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageUsage

# useCopilotReadable

The useCopilotReadable hook allows you to provide knowledge to your copilot (e.g. application state).

`useCopilotReadable` is a React hook that provides app-state and other information
to the Copilot. Optionally, the hook can also handle hierarchical state within your
application, passing these parent-child relationships to the Copilot.

## [Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotReadable\#usage)

### [Simple Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotReadable\#simple-usage)

In its most basic usage, useCopilotReadable accepts a single string argument
representing any piece of app state, making it available for the Copilot to use
as context when responding to user input.

```
import { useCopilotReadable } from "@copilotkit/react-core";

export function MyComponent() {
  const [employees, setEmployees] = useState([]);

  useCopilotReadable({
    description: "The list of employees",
    value: employees,
  });
}
```

### [Nested Components](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotReadable\#nested-components)

Optionally, you can maintain the hierarchical structure of information by passing
`parentId`. This allows you to use `useCopilotReadable` in nested components:

```
import { useCopilotReadable } from "@copilotkit/react-core";

function Employee(props: EmployeeProps) {
  const { employeeName, workProfile, metadata } = props;

  // propagate any information to copilot
  const employeeContextId = useCopilotReadable({
    description: "Employee name",
    value: employeeName
  });

  // Pass a parentID to maintain a hierarchical structure.
  // Especially useful with child React components, list elements, etc.
  useCopilotReadable({
    description: "Work profile",
    value: workProfile.description(),
    parentId: employeeContextId
  });

  useCopilotReadable({
    description: "Employee metadata",
    value: metadata.description(),
    parentId: employeeContextId
  });

  return (
    // Render as usual...
  );
}
```

## [Parameters](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotReadable\#parameters)

descriptionstringrequired

The description of the information to be added to the Copilot context.

valueanyrequired

The value to be added to the Copilot context. Object values are automatically stringified.

parentIdstring

The ID of the parent context, if any.

categoriesstring\[\]

An array of categories to control which context are visible where. Particularly useful
with CopilotTextarea (see `useMakeAutosuggestionFunction`)

available'enabled' \| 'disabled'

Whether the context is available to the Copilot.

convert(description: string, value: any) => string

A custom conversion function to use to serialize the value to a string. If not provided, the value
will be serialized using `JSON.stringify`.

[Previous\\
\\
CopilotKit](https://docs.copilotkit.ai/reference/v1/components/CopilotKit) [Next\\
\\
useCopilotAction](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction)

### On this page

[Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotReadable#usage) [Simple Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotReadable#simple-usage) [Nested Components](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotReadable#nested-components) [Parameters](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotReadable#parameters)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/v1/hooks/useCopilotReadable.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotPopup Component
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageInstall Dependencies

[Chat Components](https://docs.copilotkit.ai/reference/v1/components/chat)

# CopilotPopup

The CopilotPopup component, providing a popup interface for interacting with your copilot.

![](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/CopilotPopup.gif)

A chatbot popup component for the CopilotKit framework. The component allows for a high degree
of customization through various props and custom CSS.

See [CopilotSidebar](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotSidebar) for a sidebar version of this component.

## [Install Dependencies](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotPopup\#install-dependencies)

This component is part of the [@copilotkit/react-ui](https://npmjs.com/package/@copilotkit/react-ui) package.

```
npm install @copilotkit/react-core @copilotkit/react-ui
```

## [Usage](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotPopup\#usage)

```
import { CopilotPopup } from "@copilotkit/react-ui";
import "@copilotkit/react-ui/styles.css";

<CopilotPopup
  labels={{
    title: "Your Assistant",
    initial: "Hi! 👋 How can I assist you today?",
  }}
/>
```

### [Look & Feel](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotPopup\#look--feel)

By default, CopilotKit components do not have any styles. You can import CopilotKit's stylesheet at the root of your project:

YourRootComponent.tsx

```
...
import "@copilotkit/react-ui/styles.css";

export function YourRootComponent() {
  return (
    <CopilotKit>
      ...
    </CopilotKit>
  );
}
```

For more information about how to customize the styles, check out the [Customize Look & Feel](https://docs.copilotkit.ai/guides/custom-look-and-feel/customize-built-in-ui-components) guide.

## [Properties](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotPopup\#properties)

instructionsstring

Custom instructions to be added to the system message. Use this property to
provide additional context or guidance to the language model, influencing
its responses. These instructions can include specific directions,
preferences, or criteria that the model should consider when generating
its output, thereby tailoring the conversation more precisely to the
user's needs or the application's requirements.

onInProgress(inProgress: boolean) => void

A callback that gets called when the in progress state changes.

onSubmitMessage(message: string) => void \| Promise<void>

A callback that gets called when a new message it submitted.

onStopGenerationOnStopGeneration

A custom stop generation function.

onReloadMessagesOnReloadMessages

A custom reload messages function.

onRegenerate(messageId: string) => void

A callback function to regenerate the assistant's response

onCopy(message: string) => void

A callback function when the message is copied

onThumbsUp(message: string) => void

A callback function for thumbs up feedback

onThumbsDown(message: string) => void

A callback function for thumbs down feedback

iconsCopilotChatIcons

Icons can be used to set custom icons for the chat window.

labelsCopilotChatLabels

Labels can be used to set custom labels for the chat window.

makeSystemMessageSystemMessageFunction

A function that takes in context string and instructions and returns
the system message to include in the chat request.
Use this to completely override the system message, when providing
instructions is not enough.

AssistantMessageReact.ComponentType<AssistantMessageProps>

A custom assistant message component to use instead of the default.

UserMessageReact.ComponentType<UserMessageProps>

A custom user message component to use instead of the default.

MessagesReact.ComponentType<MessagesProps>

A custom Messages component to use instead of the default.

RenderMessageReact.ComponentType<RenderMessageProps>

A custom RenderMessage component to use instead of the default.

RenderActionExecutionMessageReact.ComponentType<RenderMessageProps>

A custom RenderActionExecutionMessage component to use instead of the default.

RenderAgentStateMessageReact.ComponentType<RenderMessageProps>

A custom RenderAgentStateMessage component to use instead of the default.

RenderResultMessageReact.ComponentType<RenderMessageProps>

A custom RenderResultMessage component to use instead of the default.

InputReact.ComponentType<InputProps>

A custom Input component to use instead of the default.

classNamestring

A class name to apply to the root element.

childrenReact.ReactNode

Children to render.

defaultOpenboolean

Default:"false"

Whether the chat window should be open by default.

clickOutsideToCloseboolean

Default:"true"

If the chat window should close when the user clicks outside of it.

hitEscapeToCloseboolean

Default:"true"

If the chat window should close when the user hits the Escape key.

shortcutstring

Default:"'/'"

The shortcut key to open the chat window.
Uses Command-\[shortcut\] on a Mac and Ctrl-\[shortcut\] on Windows.

onSetOpen(open: boolean) => void

A callback that gets called when the chat window opens or closes.

WindowReact.ComponentType<WindowProps>

A custom Window component to use instead of the default.

ButtonReact.ComponentType<ButtonProps>

A custom Button component to use instead of the default.

HeaderReact.ComponentType<HeaderProps>

A custom Header component to use instead of the default.

[Previous\\
\\
CopilotChat](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotChat) [Next\\
\\
CopilotSidebar](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotSidebar)

### On this page

[Install Dependencies](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotPopup#install-dependencies) [Usage](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotPopup#usage) [Look & Feel](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotPopup#look--feel) [Properties](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotPopup#properties)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/components/chat/CopilotPopup.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CoAgents Troubleshooting
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageMy tool calls are not being streamed

# Common Issues

Common issues you may encounter when using CoAgents.

Welcome to the CoAgents Troubleshooting Guide! If you're having trouble getting tool calls to work, you've come to the right place.

Have an issue not listed here? Open a ticket on [GitHub](https://github.com/CopilotKit/CopilotKit/issues) or reach out on [Discord](https://discord.com/invite/6dffbvGU3D)
and we'll be happy to help.

We also highly encourage any open source contributors that want to add their own troubleshooting issues to [Github as a pull request](https://github.com/CopilotKit/CopilotKit/blob/main/CONTRIBUTING.md).

## [My tool calls are not being streamed](https://docs.copilotkit.ai/coagents/troubleshooting/common-issues\#my-tool-calls-are-not-being-streamed)

This could be due to a few different reasons.

First, we strongly recommend checking out our [Human In the Loop](https://docs.copilotkit.ai/coagents/human-in-the-loop) guide to follow a more in depth example of how to stream tool calls
in your LangGraph agents. You can also check out our [travel tutorial](https://docs.copilotkit.ai/coagents/tutorials/ai-travel-app/step-6-human-in-the-loop) which talks about how to stream
tool calls in a more complex example.

If you have already done that, you can check the following:

### You have not specified the tool call in the \`copilotkit\_customize\_config\`

### You're using llm.invoke() instead of llm.ainvoke()

## [Error: `'AzureOpenAI' object has no attribute 'bind_tools'`](https://docs.copilotkit.ai/coagents/troubleshooting/common-issues\#error-azureopenai-object-has-no-attribute-bind_tools)

This error is typically due to the use of an incorrect import from LangGraph. Instead of importing `AzureOpenAI` import `AzureChatOpenAI` and your
issue will be resolved.

```
from langchain_openai import AzureOpenAI
from langchain_openai import AzureChatOpenAI
```

## [I am getting "agent not found" error](https://docs.copilotkit.ai/coagents/troubleshooting/common-issues\#i-am-getting-agent-not-found-error)

If you're seeing this error, it means CopilotKit couldn't find the LangGraph agent you're trying to use. Here's how to fix it:

### Verify your agent lock mode configuration

### Check your agent registration on a LangGraph Platform endpoint

### Check your agent name in useCoAgent

### Check your agent name in useCoAgentStateRender

## [Connection issues with tunnel creation](https://docs.copilotkit.ai/coagents/troubleshooting/common-issues\#connection-issues-with-tunnel-creation)

If you notice the tunnel creation process spinning indefinitely, your router or ISP might be blocking the connection to CopilotKit's tunnel service.

### Router or ISP blocking tunnel connections

## [I am getting "Failed to find or contact remote endpoint at url, Make sure the API is running and that it's indeed a LangGraph platform url" error](https://docs.copilotkit.ai/coagents/troubleshooting/common-issues\#i-am-getting-failed-to-find-or-contact-remote-endpoint-at-url-make-sure-the-api-is-running-and-that-its-indeed-a-langgraph-platform-url-error)

If you're seeing this error, it means the LangGraph platform client cannot connect to your endpoint.

### Verify the endpoint is reachable

### Verify running a LangGraph platform endpoint using LangGraph deployment tools

### Verify the remote endpoint matches the endpoint definition type

## [I see messages being streamed and disappear](https://docs.copilotkit.ai/coagents/troubleshooting/common-issues\#i-see-messages-being-streamed-and-disappear)

LangGraph agents are stateful. As a graph is traversed, the state is saved at the end of each node. CopilotKit uses the agent's state as
the source of truth for what to display in the frontend chat. However, since state is only emitted at the end of a node, CopilotKit allows
you to stream predictive state updates _in the middle of a node_. By default, CopilotKit will stream messages and tool calls being actively
generated to the frontend chat that initiated the interaction. **If this predictive state is not persisted at the end of the node, it will**
**disappear in the frontend chat**.

In this situation, the most likely scenario is that the `messages` property in the state is being updated in the middle of a node but those edits are not being
persisted at the end of a node.

![](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/coagents/message-state-diagram.png)

### I want these messages to be persisted

### I don't want these messages to streamed at all

[Previous\\
\\
Message flow](https://docs.copilotkit.ai/coagents/concepts/message-management) [Next\\
\\
Migrate from v0.2 to v0.3](https://docs.copilotkit.ai/coagents/troubleshooting/migrate-from-v0.2-to-v0.3)

### On this page

[My tool calls are not being streamed](https://docs.copilotkit.ai/coagents/troubleshooting/common-issues#my-tool-calls-are-not-being-streamed) [Error: 'AzureOpenAI' object has no attribute 'bind\_tools'](https://docs.copilotkit.ai/coagents/troubleshooting/common-issues#error-azureopenai-object-has-no-attribute-bind_tools) [I am getting "agent not found" error](https://docs.copilotkit.ai/coagents/troubleshooting/common-issues#i-am-getting-agent-not-found-error) [Connection issues with tunnel creation](https://docs.copilotkit.ai/coagents/troubleshooting/common-issues#connection-issues-with-tunnel-creation) [I am getting "Failed to find or contact remote endpoint at url, Make sure the API is running and that it's indeed a LangGraph platform url" error](https://docs.copilotkit.ai/coagents/troubleshooting/common-issues#i-am-getting-failed-to-find-or-contact-remote-endpoint-at-url-make-sure-the-api-is-running-and-that-its-indeed-a-langgraph-platform-url-error) [I see messages being streamed and disappear](https://docs.copilotkit.ai/coagents/troubleshooting/common-issues#i-see-messages-being-streamed-and-disappear)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/troubleshooting/common-issues.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Agentic Generative UI
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is this?

[Generative UI](https://docs.copilotkit.ai/coagents/generative-ui)

# Agentic Generative UI

Render the state of your agent with custom UI components.

This video demonstrates the [implementation](https://docs.copilotkit.ai/coagents/generative-ui/agentic#implementation) section applied to our [coagents starter project](https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter).

## [What is this?](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#what-is-this)

All LangGraph agents are stateful. This means that as your agent progresses through nodes, a state object is passed between them perserving
the overall state of a session. CopilotKit allows you to render this state in your application with custom UI components, which we call **Agentic Generative UI**.

## [When should I use this?](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#when-should-i-use-this)

Rendering the state of your agent in the UI is useful when you want to provide the user with feedback about the overall state of a session. A great example of this
is a situation where a user and an agent are working together to solve a problem. The agent can store a draft in its state which is then rendered in the UI.

## [Implementation](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#implementation)

### [Run and Connect your LangGraph to CopilotKit](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#run-and-connect-your-langgraph-to-copilotkit)

First, you'll need to make sure you have a running LangGraph. If you haven't already done this, you can follow the [getting started guide](https://docs.copilotkit.ai/coagents/quickstart/langgraph)

This guide uses the [CoAgents starter repo](https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter) as its starting point.

### [Define your agent state](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#define-your-agent-state)

If you're not familiar with LangGraph, your graphs are stateful. As you progress through nodes, a state object is passed between them. CopilotKit
allows you to easily render this state in your application.

For the sake of this guide, let's say our state looks like this in our agent.

PythonTypeScript

agent-py/sample\_agent/agent.py

```
# ...
from copilotkit import CopilotKitState # extends MessagesState
# ...

# This is the state of the agent.
# It inherits from the CopilotKitState properties from CopilotKit.
class AgentState(CopilotKitState):
    searches: list[dict]
```

### [Simulate state updates](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#simulate-state-updates)

Next, let's write some logic into our agent that will simulate state updates occurring.

PythonTypeScript

agent-py/sample\_agent/agent.py

```
import asyncio
from typing import TypedDict
from langchain_core.runnables import RunnableConfig
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage
from copilotkit import CopilotKitState
from copilotkit.langgraph import copilotkit_emit_state

class Searches(TypedDict):
    query: str
    done: bool

class AgentState(CopilotKitState):
    searches: list[Searches] = []

async def chat_node(state: AgentState, config: RunnableConfig):
    state["searches"] = [\
        {"query": "Initial research", "done": False},\
        {"query": "Retrieving sources", "done": False},\
        {"query": "Forming an answer", "done": False},\
    ]
    await copilotkit_emit_state(config, state)

    # Simulate state updates
    for search in state["searches"]:
        await asyncio.sleep(1)
        search["done"] = True
        await copilotkit_emit_state(config, state)

    # Run the model to generate a response
    response = await ChatOpenAI(model="gpt-4o").ainvoke([\
        SystemMessage(content="You are a helpful assistant."),\
        *state["messages"],\
    ], config)
```

### [Render state of the agent in the chat](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#render-state-of-the-agent-in-the-chat)

Now we can utilize `useCoAgentStateRender` to render the state of our agent **in the chat**.

app/page.tsx

```
// ...
import { useCoAgentStateRender } from "@copilotkit/react-core";
// ...

// Define the state of the agent, should match the state of the agent in your LangGraph.
type AgentState = {
  searches: {
    query: string;
    done: boolean;
  }[];
};

function YourMainContent() {
  // ...


  // styles omitted for brevity
  useCoAgentStateRender<AgentState>({
    name: "sample_agent", // the name the agent is served as
    render: ({ state }) => (
      <div>
        {state.searches?.map((search, index) => (
          <div key={index}>
            {search.done ? "✅" : "❌"} {search.query}{search.done ? "" : "..."}
          </div>
        ))}
      </div>
    ),
  });

  // ...

  return <div>...</div>;
}
```

### [Render state outside of the chat](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#render-state-outside-of-the-chat)

You can also render the state of your agent **outside of the chat**. This is useful when you want to render the state of your agent anywhere
other than the chat.

app/page.tsx

```
import { useCoAgent } from "@copilotkit/react-core";
// ...

// Define the state of the agent, should match the state of the agent in your LangGraph.
type AgentState = {
  searches: {
    query: string;
    done: boolean;
  }[];
};

function YourMainContent() {
  // ...


  const { state } = useCoAgent<AgentState>({
    name: "sample_agent", // the name the agent is served as
  })

  // ...

  return (
    <div>
      {/* ... */}
      <div className="flex flex-col gap-2 mt-4">

        {state.searches?.map((search, index) => (
          <div key={index} className="flex flex-row">
            {search.done ? "✅" : "❌"} {search.query}
          </div>
        ))}
      </div>
    </div>
  )
}
```

### [Give it a try!](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#give-it-a-try)

You've now created a component that will render the agent's state in the chat.

[Previous\\
\\
Generative UI](https://docs.copilotkit.ai/coagents/generative-ui) [Next\\
\\
Tool-based Generative UI](https://docs.copilotkit.ai/coagents/generative-ui/tool-based)

### On this page

[What is this?](https://docs.copilotkit.ai/coagents/generative-ui/agentic#what-is-this) [When should I use this?](https://docs.copilotkit.ai/coagents/generative-ui/agentic#when-should-i-use-this) [Implementation](https://docs.copilotkit.ai/coagents/generative-ui/agentic#implementation) [Run and Connect your LangGraph to CopilotKit](https://docs.copilotkit.ai/coagents/generative-ui/agentic#run-and-connect-your-langgraph-to-copilotkit) [Define your agent state](https://docs.copilotkit.ai/coagents/generative-ui/agentic#define-your-agent-state) [Simulate state updates](https://docs.copilotkit.ai/coagents/generative-ui/agentic#simulate-state-updates) [Render state of the agent in the chat](https://docs.copilotkit.ai/coagents/generative-ui/agentic#render-state-of-the-agent-in-the-chat) [Render state outside of the chat](https://docs.copilotkit.ai/coagents/generative-ui/agentic#render-state-outside-of-the-chat) [Give it a try!](https://docs.copilotkit.ai/coagents/generative-ui/agentic#give-it-a-try)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/generative-ui/agentic.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Agentic Copilots Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat are Agents?

# Agentic Copilots

Agentic copilots provide you with advanced control and orchestration over your agents.

Before we dive into what agentic copilots are, help us help you by telling us your level of experience with LangGraph. We'll explain things in a way that best suits your experience level.

![](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/copilotkit-logo.svg)

I'm new to LangGraph

Help me understand what agentic copilots are, where LangGraph fits in, and how to get started.

I'm already using LangGraph

Help me understand what agentic copilots are, what CopilotKit does to integrate with LangGraph, and how to get started.

![CoAgents Shared State](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/coagents/SharedStateCoAgents.gif)

### [What are Agents?](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots\#what-are-agents)

AI agents are intelligent systems that interact with their environment to achieve specific goals. Think of them as 'virtual colleagues' that can handle tasks ranging from
simple queries like "find the cheapest flight to Paris" to complex challenges like "design a new product layout."

As these AI-driven experiences (or 'Agentic Experiences') become more sophisticated, developers need finer control over how agents make decisions. This is where specialized
frameworks like LangGraph become essential.

### [What is LangGraph?](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots\#what-is-langgraph)

LangGraph is a framework that gives you precise control over AI agents. It uses a graph-based approach where each step in an agent's decision-making process is represented
by a `node`. These nodes are connected by `edges` to form a directed acyclic graph (DAG), creating a clear map of possible actions and decisions.

The key advantage of LangGraph is its tight control over the agent's decision making process. Since all of this is defined in code by you, the behavior is much more
deterministic and predictable.

### [What are Agentic Copilots?](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots\#what-are-agentic-copilots)

Agentic copilots are how CopilotKit brings LangGraph agents into your application. If you're familiar with CopilotKit, you know that copilots are AI assistants that
understand your app's context and can take actions within it. While CopilotKit's standard copilots use a simplified [ReAct pattern](https://www.perplexity.ai/search/what-s-a-react-agent-5hu7ZOaKSAuY7YdFjQLCNQ)
for quick implementation, Agentic copilots give you LangGraph's full orchestration capabilities when you need more control over your agent's behavior.

### [What are CoAgents?](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots\#what-are-coagents)

CoAgents are what we call CopilotKit's approach to building agentic experiences! They're interchangeable with agentic copilots being a more descriptive term for the overall concept.

### [When should I use CopilotKit's CoAgents?](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots\#when-should-i-use-copilotkits-coagents)

You should use CoAgents when you require tight control over the Agentic runloop, as facilitated by an Agentic Orchestration framework like [LangGraph](https://docs.langchain.com/oss/python/langgraph/overview).
With CoAgents, you can carry all of your existing CopilotKit-enabled Copilot capabilities into a customized agentic runloop.

We suggest beginning with a basic Copilot and gradually transitioning specific components to CoAgents.

The need for CoAgents spans a broad spectrum across different applications. At one end, their advanced capabilities might not be required at all, or only for a minimal 10% of the application's
functionality. Progressing further, there are scenarios where they become increasingly vital, managing 60-70% of operations. Ultimately, in some cases, CoAgents are indispensable, orchestrating
up to 100% of the Copilot's tasks (see [agent-lock mode](https://docs.copilotkit.ai/coagents/multi-agent-flows) for the 100% case).

### [Examples](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots\#examples)

An excellent example of the type of experiences you can accomplish with CoAgents applications can be found in our [Research Canvas](https://docs.copilotkit.ai/coagents/videos/research-canvas).

More specifically, it demonstrates how CoAgents allow for AI driven experiences with:

- Precise state management across agent interactions
- Sophisticated multi-step reasoning capabilities
- Seamless orchestration of multiple AI tools
- Interactive human-AI collaboration features
- Real-time state updates and progress streaming

## [Next Steps](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots\#next-steps)

Want to get started? You have some options!

[**Build your first CoAgent** \\
Follow a step-by-step tutorial to build a travel app supercharged with CoAgents.](https://docs.copilotkit.ai/coagents/quickstart/langgraph) [**Learn more CoAgent concepts** \\
Learn more about the concepts used to talk about CoAgents and how to use them.](https://docs.copilotkit.ai/coagents/concepts/terminology) [**Read the reference documentation** \\
Just here for some reference? Checkout the reference documentation for more details.](https://docs.copilotkit.ai/reference) [**See examples of CoAgents in action** \\
Checkout our video examples of CoAgents in action.](https://docs.copilotkit.ai/coagents/videos/research-canvas)

[Previous\\
\\
Terminology](https://docs.copilotkit.ai/coagents/concepts/terminology) [Next\\
\\
LangGraph](https://docs.copilotkit.ai/coagents/concepts/langgraph)

### On this page

[What are Agents?](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots#what-are-agents) [What is LangGraph?](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots#what-is-langgraph) [What are Agentic Copilots?](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots#what-are-agentic-copilots) [What are CoAgents?](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots#what-are-coagents) [When should I use CopilotKit's CoAgents?](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots#when-should-i-use-copilotkits-coagents) [Examples](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots#examples) [Next Steps](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots#next-steps) [What are CoAgents?](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots#what-are-coagents-1) [Next Steps](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots#next-steps-1)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/concepts/agentic-copilots.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Connect Your Data
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this page

# Connecting Your Data

Learn how to connect your data to CopilotKit.

CopilotKit allows you to connect your data through the frontend and through the backend. This enables
a variety of use-cases from simple context to RAG-based LLM interactions.

[**Frontend Data** \\
Learn how to connect your data to CopilotKit on the frontend.](https://docs.copilotkit.ai/guides/connect-your-data/frontend) [**Backend Data** \\
Learn how to connect your data to CopilotKit on the backend.](https://docs.copilotkit.ai/guides/connect-your-data/backend)

[Previous\\
\\
Fully Headless UI](https://docs.copilotkit.ai/guides/custom-look-and-feel/headless-ui) [Next\\
\\
Frontend Data](https://docs.copilotkit.ai/guides/connect-your-data/frontend)

### On this page

No Headings

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/connect-your-data/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotChat Component
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageInstall Dependencies

[Chat Components](https://docs.copilotkit.ai/reference/v1/components/chat)

# CopilotChat

The CopilotChat component, providing a chat interface for interacting with your copilot.

![](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/CopilotChat.gif)

A chatbot panel component for the CopilotKit framework. The component allows for a high degree
of customization through various props and custom CSS.

## [Install Dependencies](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotChat\#install-dependencies)

This component is part of the [@copilotkit/react-ui](https://npmjs.com/package/@copilotkit/react-ui) package.

```
npm install @copilotkit/react-core @copilotkit/react-ui
```

## [Usage](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotChat\#usage)

```
import { CopilotChat } from "@copilotkit/react-ui";
import "@copilotkit/react-ui/styles.css";

<CopilotChat
  labels={{
    title: "Your Assistant",
    initial: "Hi! 👋 How can I assist you today?",
  }}
/>
```

### [Look & Feel](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotChat\#look--feel)

By default, CopilotKit components do not have any styles. You can import CopilotKit's stylesheet at the root of your project:

YourRootComponent.tsx

```
...
import "@copilotkit/react-ui/styles.css";

export function YourRootComponent() {
  return (
    <CopilotKit>
      ...
    </CopilotKit>
  );
}
```

For more information about how to customize the styles, check out the [Customize Look & Feel](https://docs.copilotkit.ai/guides/custom-look-and-feel/customize-built-in-ui-components) guide.

## [Properties](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotChat\#properties)

instructionsstring

Custom instructions to be added to the system message. Use this property to
provide additional context or guidance to the language model, influencing
its responses. These instructions can include specific directions,
preferences, or criteria that the model should consider when generating
its output, thereby tailoring the conversation more precisely to the
user's needs or the application's requirements.

onInProgress(inProgress: boolean) => void

A callback that gets called when the in progress state changes.

onSubmitMessage(message: string) => void \| Promise<void>

A callback that gets called when a new message it submitted.

onStopGenerationOnStopGeneration

A custom stop generation function.

onReloadMessagesOnReloadMessages

A custom reload messages function.

onRegenerate(messageId: string) => void

A callback function to regenerate the assistant's response

onCopy(message: string) => void

A callback function when the message is copied

onThumbsUp(message: string) => void

A callback function for thumbs up feedback

onThumbsDown(message: string) => void

A callback function for thumbs down feedback

iconsCopilotChatIcons

Icons can be used to set custom icons for the chat window.

labelsCopilotChatLabels

Labels can be used to set custom labels for the chat window.

makeSystemMessageSystemMessageFunction

A function that takes in context string and instructions and returns
the system message to include in the chat request.
Use this to completely override the system message, when providing
instructions is not enough.

AssistantMessageReact.ComponentType<AssistantMessageProps>

A custom assistant message component to use instead of the default.

UserMessageReact.ComponentType<UserMessageProps>

A custom user message component to use instead of the default.

MessagesReact.ComponentType<MessagesProps>

A custom Messages component to use instead of the default.

RenderMessageReact.ComponentType<RenderMessageProps>

A custom RenderMessage component to use instead of the default.

RenderActionExecutionMessageReact.ComponentType<RenderMessageProps>

A custom RenderActionExecutionMessage component to use instead of the default.

RenderAgentStateMessageReact.ComponentType<RenderMessageProps>

A custom RenderAgentStateMessage component to use instead of the default.

RenderResultMessageReact.ComponentType<RenderMessageProps>

A custom RenderResultMessage component to use instead of the default.

InputReact.ComponentType<InputProps>

A custom Input component to use instead of the default.

classNamestring

A class name to apply to the root element.

childrenReact.ReactNode

Children to render.

[Previous\\
\\
All Chat Components](https://docs.copilotkit.ai/reference/v1/components/chat) [Next\\
\\
CopilotPopup](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotPopup)

### On this page

[Install Dependencies](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotChat#install-dependencies) [Usage](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotChat#usage) [Look & Feel](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotChat#look--feel) [Properties](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotChat#properties)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/components/chat/CopilotChat.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CrewAI Components Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

![CopilotKit Logo](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/copilotkit-logo.svg)

# Page Not Found

Oops! The page you're looking for doesn't exist.

[Go to Documentation](https://docs.copilotkit.ai/)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotKit Quickstart Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageInstall CopilotKit

# Quickstart

Get started with CopilotKit in under 5 minutes.

Copilot Cloud (Recommended)

Use our hosted backend endpoint to get started quickly.

Self-hosting

Learn to host CopilotKit's runtime yourself with your own backend.

## [Install CopilotKit](https://docs.copilotkit.ai/quickstart?component=Headless+UI\#install-copilotkit)

First, install the latest packages for CopilotKit.

npmpnpmyarnbun

```
npm install @copilotkit/react-ui @copilotkit/react-core
```

## [Get a Copilot Cloud Public API Key](https://docs.copilotkit.ai/quickstart?component=Headless+UI\#get-a-copilot-cloud-public-api-key)

Navigate to [Copilot Cloud](https://cloud.copilotkit.ai/) and follow the instructions to get a public API key - it's free!

## [Setup the CopilotKit Provider](https://docs.copilotkit.ai/quickstart?component=Headless+UI\#setup-the-copilotkit-provider)

The [`<CopilotKit>`](https://docs.copilotkit.ai/reference/v1/components/CopilotKit) component must wrap the Copilot-aware parts of your application. For most use-cases,
it's appropriate to wrap the CopilotKit provider around the entire app, e.g. in your layout.tsx.

layout.tsx

```
import "./globals.css";
import { ReactNode } from "react";
import { CopilotKit } from "@copilotkit/react-core";

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        {/* Use the public api key you got from Copilot Cloud  */}
        <CopilotKit publicApiKey="<your-copilot-cloud-public-api-key>">
          {children}
        </CopilotKit>
      </body>
    </html>
  );
}
```

## [Choose a Copilot UI](https://docs.copilotkit.ai/quickstart?component=Headless+UI\#choose-a-copilot-ui)

You are almost there! Now it's time to setup your Copilot UI.

First, import the default styles in your root component (typically `layout.tsx`) :

```
import "@copilotkit/react-ui/styles.css";
```

Copilot UI ships with a number of built-in UI patterns, choose whichever one you like.

CopilotPopupCopilotSidebarCopilotChatHeadless UI

The built-in Copilot UI can be customized in many ways -- both through css and by passing in custom sub-components.

CopilotKit also offers **fully custom headless UI**, through the `useCopilotChat` hook. Everything built with the built-in UI (and more) can be implemented with the headless UI, providing deep customizability.

```
import { useCopilotChat } from "@copilotkit/react-core";
import { Role, TextMessage } from "@copilotkit/runtime-client-gql";

export function CustomChatInterface() {
  const {
    visibleMessages,
    appendMessage,
    setMessages,
    deleteMessage,
    reloadMessages,
    stopGeneration,
    isLoading,
  } = useCopilotChat();

  const sendMessage = (content: string) => {
    appendMessage(new TextMessage({ content, role: Role.User }));
  };

  return (
    <div>
      {/* Implement your custom chat UI here */}
    </div>
  );
}
```

* * *

## [Next Steps](https://docs.copilotkit.ai/quickstart?component=Headless+UI\#next-steps)

🎉 Congrats! You've successfully integrated a fully functional chatbot in your application! Give it a try now and see it in action. Want to
take it further? Learn more about what CopilotKit has to offer!

[**Connecting Your Data** \\
Learn how to connect CopilotKit to your data, application state and user state.](https://docs.copilotkit.ai/guides/connect-your-data) [**Generative UI** \\
Learn how to render custom UI components directly in the CopilotKit chat window.](https://docs.copilotkit.ai/guides/generative-ui) [**Frontend Actions** \\
Learn how to allow your copilot to take applications on frontend.](https://docs.copilotkit.ai/guides/frontend-actions) [**CoAgents (LangGraph)** \\
Check out our section about CoAgents, our approach to building agentic copilots and experiences.](https://docs.copilotkit.ai/coagents)

[Previous\\
\\
Introduction](https://docs.copilotkit.ai/) [Next\\
\\
Customize UI](https://docs.copilotkit.ai/guides/custom-look-and-feel)

### On this page

[Install CopilotKit](https://docs.copilotkit.ai/quickstart?component=Headless+UI#install-copilotkit) [Get a Copilot Cloud Public API Key](https://docs.copilotkit.ai/quickstart?component=Headless+UI#get-a-copilot-cloud-public-api-key) [Setup the CopilotKit Provider](https://docs.copilotkit.ai/quickstart?component=Headless+UI#setup-the-copilotkit-provider) [Choose a Copilot UI](https://docs.copilotkit.ai/quickstart?component=Headless+UI#choose-a-copilot-ui) [Install CopilotKit](https://docs.copilotkit.ai/quickstart?component=Headless+UI#install-copilotkit-1) [Set up a Copilot Runtime Endpoint](https://docs.copilotkit.ai/quickstart?component=Headless+UI#set-up-a-copilot-runtime-endpoint) [Configure the CopilotKit Provider](https://docs.copilotkit.ai/quickstart?component=Headless+UI#configure-the-copilotkit-provider) [Choose a Copilot UI](https://docs.copilotkit.ai/quickstart?component=Headless+UI#choose-a-copilot-ui-1) [Next Steps](https://docs.copilotkit.ai/quickstart?component=Headless+UI#next-steps)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/quickstart.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## LangGraph SDK Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pagecopilotkit\_customize\_config

Python

# LangGraph SDK

The CopilotKit LangGraph SDK for Python allows you to build and run LangGraph workflows with CopilotKit.

## [copilotkit\_customize\_config](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#copilotkit_customize_config)

Customize the LangGraph configuration for use in CopilotKit.

To install the CopilotKit SDK, run:

```
pip install copilotkit
```

### [Examples](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#examples)

Disable emitting messages and tool calls:

```
from copilotkit.langgraph import copilotkit_customize_config

config = copilotkit_customize_config(
    config,
    emit_messages=False,
    emit_tool_calls=False
)
```

To emit a tool call as streaming LangGraph state, pass the destination key in state,
the tool name and optionally the tool argument. (If you don't pass the argument name,
all arguments are emitted under the state key.)

```
from copilotkit.langgraph import copilotkit_customize_config

config = copilotkit_customize_config(
    config,
    emit_intermediate_state=[\
       {\
            "state_key": "steps",\
            "tool": "SearchTool",\
            "tool_argument": "steps"\
        },\
    ]
)
```

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#parameters)

base\_configOptional\[RunnableConfig\]

The LangChain/LangGraph configuration to customize. Pass None to make a new configuration.

emit\_messagesOptional\[bool\]

Configure how messages are emitted. By default, all messages are emitted. Pass False to disable emitting messages.

emit\_tool\_callsOptional\[Union\[bool, str, List\[str\]\]\]

Configure how tool calls are emitted. By default, all tool calls are emitted. Pass False to disable emitting tool calls. Pass a string or list of strings to emit only specific tool calls.

emit\_intermediate\_stateOptional\[List\[IntermediateStateConfig\]\]

Lets you emit tool calls as streaming LangGraph state.

### [Returns](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#returns)

returnsRunnableConfig

The customized LangGraph configuration.

## [copilotkit\_exit](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#copilotkit_exit)

Exits the current agent after the run completes. Calling copilotkit\_exit() will
not immediately stop the agent. Instead, it signals to CopilotKit to stop the agent after
the run completes.

### [Examples](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#examples-1)

```
from copilotkit.langgraph import copilotkit_exit

def my_node(state: Any):
    await copilotkit_exit(config)
    return state
```

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#parameters-1)

configRunnableConfigrequired

The LangGraph configuration.

### [Returns](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#returns-1)

returnsAwaitable\[bool\]

Always return True.

## [copilotkit\_emit\_state](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#copilotkit_emit_state)

Emits intermediate state to CopilotKit. Useful if you have a longer running node and you want to
update the user with the current state of the node.

### [Examples](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#examples-2)

```
from copilotkit.langgraph import copilotkit_emit_state

for i in range(10):
    await some_long_running_operation(i)
    await copilotkit_emit_state(config, {"progress": i})
```

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#parameters-2)

configRunnableConfigrequired

The LangGraph configuration.

stateAnyrequired

The state to emit (Must be JSON serializable).

### [Returns](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#returns-2)

returnsAwaitable\[bool\]

Always return True.

## [copilotkit\_emit\_message](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#copilotkit_emit_message)

Manually emits a message to CopilotKit. Useful in longer running nodes to update the user.
Important: You still need to return the messages from the node.

### [Examples](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#examples-3)

```
from copilotkit.langgraph import copilotkit_emit_message

message = "Step 1 of 10 complete"
await copilotkit_emit_message(config, message)

# Return the message from the node
return {
    "messages": [AIMessage(content=message)]
}
```

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#parameters-3)

configRunnableConfigrequired

The LangGraph configuration.

messagestrrequired

The message to emit.

### [Returns](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#returns-3)

returnsAwaitable\[bool\]

Always return True.

## [copilotkit\_emit\_tool\_call](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#copilotkit_emit_tool_call)

Manually emits a tool call to CopilotKit.

```
from copilotkit.langgraph import copilotkit_emit_tool_call

await copilotkit_emit_tool_call(config, name="SearchTool", args={"steps": 10})
```

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#parameters-4)

configRunnableConfigrequired

The LangGraph configuration.

namestrrequired

The name of the tool to emit.

argsDict\[str, Any\]required

The arguments to emit.

### [Returns](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph\#returns-4)

returnsAwaitable\[bool\]

Always return True.

[Previous\\
\\
LangGraphAgent](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraphAgent) [Next\\
\\
CrewAIAgent](https://docs.copilotkit.ai/reference/v1/sdk/python/CrewAIAgent)

### On this page

[copilotkit\_customize\_config](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#copilotkit_customize_config) [Examples](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#examples) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#parameters) [Returns](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#returns) [copilotkit\_exit](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#copilotkit_exit) [Examples](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#examples-1) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#parameters-1) [Returns](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#returns-1) [copilotkit\_emit\_state](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#copilotkit_emit_state) [Examples](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#examples-2) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#parameters-2) [Returns](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#returns-2) [copilotkit\_emit\_message](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#copilotkit_emit_message) [Examples](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#examples-3) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#parameters-3) [Returns](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#returns-3) [copilotkit\_emit\_tool\_call](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#copilotkit_emit_tool_call) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#parameters-4) [Returns](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph#returns-4)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/sdk/python/LangGraph.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotKit Remote Endpoints
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageCopilotKitRemoteEndpoint

Python

# Remote Endpoints

CopilotKit Remote Endpoints allow you to connect actions and agents written in Python to your CopilotKit application.

## [CopilotKitRemoteEndpoint](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints\#copilotkitremoteendpoint)

CopilotKitRemoteEndpoint lets you connect actions and agents written in Python to your
CopilotKit application.

To install CopilotKit for Python, run:

```
pip install copilotkit
# or to include crewai
pip install copilotkit[crewai]
```

## [Adding actions](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints\#adding-actions)

In this example, we provide a simple action to the Copilot:

```
from copilotkit import CopilotKitRemoteEndpoint, Action

sdk = CopilotKitRemoteEndpoint(
    actions=[\
        Action(\
            name="greet_user",\
            handler=greet_user_handler,\
            description="Greet the user",\
            parameters=[\
                {\
                    "name": "name",\
                    "type": "string",\
                    "description": "The name of the user"\
                }\
            ]\
        )\
    ]
)
```

You can also dynamically build actions by providing a callable that returns a list of actions.
In this example, we use "name" from the `properties` object to parameterize the action handler.

```
from copilotkit import CopilotKitRemoteEndpoint, Action

sdk = CopilotKitRemoteEndpoint(
    actions=lambda context: [\
        Action(\
            name="greet_user",\
            handler=make_greet_user_handler(context["properties"]["name"]),\
            description="Greet the user"\
        )\
    ]
)
```

Using the same approach, you can restrict the actions available to the Copilot:

```
from copilotkit import CopilotKitRemoteEndpoint, Action

sdk = CopilotKitRemoteEndpoint(
    actions=lambda context: (
        [action_a, action_b] if is_admin(context["properties"]["token"]) else [action_a]
    )
)
```

## [Adding agents](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints\#adding-agents)

Serving agents works in a similar way to serving actions:

```
from copilotkit import CopilotKitRemoteEndpoint, LangGraphAgent
from my_agent.agent import graph

sdk = CopilotKitRemoteEndpoint(
    agents=[\
        LangGraphAgent(\
            name="email_agent",\
            description="This agent sends emails",\
            graph=graph,\
        )\
    ]
)
```

To dynamically build agents, provide a callable that returns a list of agents:

```
from copilotkit import CopilotKitRemoteEndpoint, LangGraphAgent
from my_agent.agent import graph

sdk = CopilotKitRemoteEndpoint(
    agents=lambda context: [\
        LangGraphAgent(\
            name="email_agent",\
            description="This agent sends emails",\
            graph=graph,\
            langgraph_config={\
                "token": context["properties"]["token"]\
            }\
        )\
    ]
)
```

To restrict the agents available to the Copilot, simply return a different list of agents based on the `context`:

```
from copilotkit import CopilotKitRemoteEndpoint
from my_agents import agent_a, agent_b, is_admin

sdk = CopilotKitRemoteEndpoint(
    agents=lambda context: (
        [agent_a, agent_b] if is_admin(context["properties"]["token"]) else [agent_a]
    )
)
```

## [Serving the CopilotKit SDK](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints\#serving-the-copilotkit-sdk)

To serve the CopilotKit SDK, you can use the `add_fastapi_endpoint` function from the `copilotkit.integrations.fastapi` module:

```
from copilotkit.integrations.fastapi import add_fastapi_endpoint
from fastapi import FastAPI

app = FastAPI()
sdk = CopilotKitRemoteEndpoint(...)
add_fastapi_endpoint(app, sdk, "/copilotkit")

def main():
    uvicorn.run(
        "your_package:app",
        host="0.0.0.0",
        port=8000,
        reload=True,
    )
```

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints\#parameters)

actionsOptional\[Union\[List\[Action\], Callable\[\[CopilotKitContext\], List\[Action\]\]\]\]

The actions to make available to the Copilot.

agentsOptional\[Union\[List\[Agent\], Callable\[\[CopilotKitContext\], List\[Agent\]\]\]\]

The agents to make available to the Copilot.

## [CopilotKitContext](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints\#copilotkitcontext)

CopilotKit Context

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints\#parameters-1)

propertiesAnyrequired

The properties provided to the frontend via `<CopilotKit properties={...} />`

frontend\_urlOptional\[str\]

The current URL of the frontend

headersMapping\[str, str\]required

The headers of the request

[Previous\\
\\
CopilotTask](https://docs.copilotkit.ai/reference/v1/classes/CopilotTask) [Next\\
\\
LangGraphAgent](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraphAgent)

### On this page

[CopilotKitRemoteEndpoint](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints#copilotkitremoteendpoint) [Adding actions](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints#adding-actions) [Adding agents](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints#adding-agents) [Serving the CopilotKit SDK](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints#serving-the-copilotkit-sdk) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints#parameters) [CopilotKitContext](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints#copilotkitcontext) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints#parameters-1)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/sdk/python/RemoteEndpoints.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## LangGraph SDK Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pagecopilotkitCustomizeConfig

JavaScript

# LangGraph SDK

The CopilotKit LangGraph SDK for JavaScript allows you to build and run LangGraph workflows with CopilotKit.

## [copilotkitCustomizeConfig](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph\#copilotkitcustomizeconfig)

Customize the LangGraph configuration for use in CopilotKit.

To the CopilotKit SDK, run:

```
npm install @copilotkit/sdk-js
```

### [Examples](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph\#examples)

Disable emitting messages and tool calls:

```
import { copilotkitCustomizeConfig } from "@copilotkit/sdk-js";

config = copilotkitCustomizeConfig(
  config,
  emitMessages=false,
  emitToolCalls=false
)
```

To emit a tool call as streaming LangGraph state, pass the destination key in state,
the tool name and optionally the tool argument. (If you don't pass the argument name,
all arguments are emitted under the state key.)

```
import { copilotkitCustomizeConfig } from "@copilotkit/sdk-js";

config = copilotkitCustomizeConfig(
  config,
  emitIntermediateState=[\
    {\
      "stateKey": "steps",\
      "tool": "SearchTool",\
      "toolArgument": "steps",\
    },\
  ],
)
```

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph\#parameters)

baseConfigRunnableConfigrequired

The LangChain/LangGraph configuration to customize.

optionsOptionsConfig

Configuration options:

- `emitMessages: boolean?`
Configure how messages are emitted. By default, all messages are emitted. Pass false to
disable emitting messages.
- `emitToolCalls: boolean | string | string[]?`
Configure how tool calls are emitted. By default, all tool calls are emitted. Pass false to
disable emitting tool calls. Pass a string or list of strings to emit only specific tool calls.
- `emitIntermediateState: IntermediateStateConfig[]?`
Lets you emit tool calls as streaming LangGraph state.

## [copilotkitExit](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph\#copilotkitexit)

Exits the current agent after the run completes. Calling copilotkit\_exit() will
not immediately stop the agent. Instead, it signals to CopilotKit to stop the agent after
the run completes.

### [Examples](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph\#examples-1)

```
import { copilotkitExit } from "@copilotkit/sdk-js";

async function myNode(state: Any):
  await copilotkitExit(config)
  return state
```

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph\#parameters-1)

configRunnableConfigrequired

The LangChain/LangGraph configuration.

## [copilotkitEmitState](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph\#copilotkitemitstate)

Emits intermediate state to CopilotKit. Useful if you have a longer running node and you want to
update the user with the current state of the node.

### [Examples](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph\#examples-2)

```
import { copilotkitEmitState } from "@copilotkit/sdk-js";

for (let i = 0; i < 10; i++) {
  await someLongRunningOperation(i);
  await copilotkitEmitState(config, { progress: i });
}
```

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph\#parameters-2)

configRunnableConfigrequired

The LangChain/LangGraph configuration.

stateanyrequired

The state to emit.

## [copilotkitEmitMessage](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph\#copilotkitemitmessage)

Manually emits a message to CopilotKit. Useful in longer running nodes to update the user.
Important: You still need to return the messages from the node.

### [Examples](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph\#examples-3)

```
import { copilotkitEmitMessage } from "@copilotkit/sdk-js";

const message = "Step 1 of 10 complete";
await copilotkitEmitMessage(config, message);

// Return the message from the node
return {
  "messages": [AIMessage(content=message)]
}
```

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph\#parameters-3)

configRunnableConfigrequired

The LangChain/LangGraph configuration.

messagestringrequired

The message to emit.

## [copilotkitEmitToolCall](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph\#copilotkitemittoolcall)

Manually emits a tool call to CopilotKit.

### [Examples](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph\#examples-4)

```
import { copilotkitEmitToolCall } from "@copilotkit/sdk-js";

await copilotkitEmitToolCall(config, name="SearchTool", args={"steps": 10})
```

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph\#parameters-4)

configRunnableConfigrequired

The LangChain/LangGraph configuration.

namestringrequired

The name of the tool to emit.

argsanyrequired

The arguments to emit.

[Previous\\
\\
CrewAI SDK](https://docs.copilotkit.ai/reference/v1/sdk/python/CrewAI)

### On this page

[copilotkitCustomizeConfig](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph#copilotkitcustomizeconfig) [Examples](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph#examples) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph#parameters) [copilotkitExit](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph#copilotkitexit) [Examples](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph#examples-1) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph#parameters-1) [copilotkitEmitState](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph#copilotkitemitstate) [Examples](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph#examples-2) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph#parameters-2) [copilotkitEmitMessage](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph#copilotkitemitmessage) [Examples](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph#examples-3) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph#parameters-3) [copilotkitEmitToolCall](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph#copilotkitemittoolcall) [Examples](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph#examples-4) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/js/LangGraph#parameters-4)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/sdk/js/LangGraph.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Multi-Agent Flows
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat are Multi-Agent Flows?

# Multi-Agent Flows

Use multiple agents to orchestrate complex flows.

![Multi-Agent Flows](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/coagents/multi-agent-flows.png)

## [What are Multi-Agent Flows?](https://docs.copilotkit.ai/coagents/multi-agent-flows\#what-are-multi-agent-flows)

When building agentic applications, you often want to orchestrate complex flows together that require the coordination of multiple
agents. This is traditionally called multi-agent orchestration.

## [When should I use this?](https://docs.copilotkit.ai/coagents/multi-agent-flows\#when-should-i-use-this)

Multi-agent flows are useful when you want to orchestrate complex flows together that require the coordination of multiple agents. As
your agentic application grows, delegation of sub-tasks to other agents can help you scale key pieces of your application.

- Divide context into smaller chunks
- Delegate sub-tasks to other agents
- Use a single agent to orchestrate the flow

## [How does CopilotKit support this?](https://docs.copilotkit.ai/coagents/multi-agent-flows\#how-does-copilotkit-support-this)

CopilotKit can be used in either of two distinct modes: **Router Mode**, or **Agent Lock**. By default, CopilotKit
will use Router Mode, leveraging your defined LLM to route requests between agents.

### [Router Mode (default)](https://docs.copilotkit.ai/coagents/multi-agent-flows\#router-mode-default)

Router Mode is enabled by default when using CoAgents. To use it, specify a runtime URL prop in the `CopilotKit` provider component and omit the `agent` prop, like so:

```
<CopilotKit runtimeUrl="<copilot-runtime-url>">
  {/* Your application components */}
</CopilotKit>
```

In router mode, CopilotKit acts as a central hub, dynamically selecting and _routing_ requests between different agents or actions based on the user's input. This mode can be good for chat-first experiences where an LLM chatbot is the entry point for a range of interactions, which can stay in the chat UI or expand to include native React UI widgets.

In this mode, CopilotKit will intelligently route requests to the most appropriate agent or action based on the context and user input.

Be advised that when using this mode, you'll have to "exit the workflow" explicitly in your agent code.
You can find more information about it in the ["Exiting the agent loop" section](https://docs.copilotkit.ai/coagents/advanced/exit-agent).

Router mode requires that you set up an LLM adapter. See how in ["Set up a copilot runtime"](https://docs.copilotkit.ai/direct-to-llm/guides/quickstart?copilot-hosting=self-hosted#set-up-a-copilot-runtime-endpoint) section of the docs.

### [Agent Lock Mode](https://docs.copilotkit.ai/coagents/multi-agent-flows\#agent-lock-mode)

To use Agent Lock Mode, specify the agent name in the `CopilotKit` component with the `agent` prop:

```
<CopilotKit runtimeUrl="<copilot-runtime-url>" agent="<the-name-of-the-agent>">
  {/* Your application components */}
</CopilotKit>
```

In this mode, CopilotKit is configured to work exclusively with a specific agent. This mode is useful when you want to focus on a particular task or domain. Whereas in Router Mode the LLM and CopilotKit's router are free to switch between agents to handle user requests, in Agent Lock Mode all requests will stay within a single workflow graph, ensuring precise control over the workflow.

Use whichever mode works best for your app experience! Also, note that while you cannot nest `CopilotKit` providers, you can use different agents or modes in different areas of your app — for example, you may want a chatbot in router mode that can call on any agent or tool, but may also want to integrate one specific agent elsewhere for a more focused workflow.

[Previous\\
\\
Frontend Actions](https://docs.copilotkit.ai/coagents/frontend-actions) [Next\\
\\
Loading Agent State](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state)

### On this page

[What are Multi-Agent Flows?](https://docs.copilotkit.ai/coagents/multi-agent-flows#what-are-multi-agent-flows) [When should I use this?](https://docs.copilotkit.ai/coagents/multi-agent-flows#when-should-i-use-this) [How does CopilotKit support this?](https://docs.copilotkit.ai/coagents/multi-agent-flows#how-does-copilotkit-support-this) [Router Mode (default)](https://docs.copilotkit.ai/coagents/multi-agent-flows#router-mode-default) [Agent Lock Mode](https://docs.copilotkit.ai/coagents/multi-agent-flows#agent-lock-mode)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/multi-agent-flows.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Copilot Sidebar Component
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageInstall Dependencies

[Chat Components](https://docs.copilotkit.ai/reference/v1/components/chat)

# CopilotSidebar

The CopilotSidebar component, providing a sidebar interface for interacting with your copilot.

![](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/CopilotSidebar.gif)

A chatbot sidebar component for the CopilotKit framework. Highly customizable through various props and custom CSS.

See [CopilotPopup](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotPopup) for a popup version of this component.

## [Install Dependencies](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotSidebar\#install-dependencies)

This component is part of the [@copilotkit/react-ui](https://npmjs.com/package/@copilotkit/react-ui) package.

```
npm install @copilotkit/react-core @copilotkit/react-ui
```

## [Usage](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotSidebar\#usage)

```
import { CopilotSidebar } from "@copilotkit/react-ui";
import "@copilotkit/react-ui/styles.css";

<CopilotSidebar
  labels={{
    title: "Your Assistant",
    initial: "Hi! 👋 How can I assist you today?",
  }}
>
  <YourApp/>
</CopilotSidebar>
```

### [Look & Feel](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotSidebar\#look--feel)

By default, CopilotKit components do not have any styles. You can import CopilotKit's stylesheet at the root of your project:

YourRootComponent.tsx

```
...
import "@copilotkit/react-ui/styles.css";

export function YourRootComponent() {
  return (
    <CopilotKit>
      ...
    </CopilotKit>
  );
}
```

For more information about how to customize the styles, check out the [Customize Look & Feel](https://docs.copilotkit.ai/guides/custom-look-and-feel/customize-built-in-ui-components) guide.

## [Properties](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotSidebar\#properties)

instructionsstring

Custom instructions to be added to the system message. Use this property to
provide additional context or guidance to the language model, influencing
its responses. These instructions can include specific directions,
preferences, or criteria that the model should consider when generating
its output, thereby tailoring the conversation more precisely to the
user's needs or the application's requirements.

onInProgress(inProgress: boolean) => void

A callback that gets called when the in progress state changes.

onSubmitMessage(message: string) => void \| Promise<void>

A callback that gets called when a new message it submitted.

onStopGenerationOnStopGeneration

A custom stop generation function.

onReloadMessagesOnReloadMessages

A custom reload messages function.

onRegenerate(messageId: string) => void

A callback function to regenerate the assistant's response

onCopy(message: string) => void

A callback function when the message is copied

onThumbsUp(message: string) => void

A callback function for thumbs up feedback

onThumbsDown(message: string) => void

A callback function for thumbs down feedback

iconsCopilotChatIcons

Icons can be used to set custom icons for the chat window.

labelsCopilotChatLabels

Labels can be used to set custom labels for the chat window.

makeSystemMessageSystemMessageFunction

A function that takes in context string and instructions and returns
the system message to include in the chat request.
Use this to completely override the system message, when providing
instructions is not enough.

AssistantMessageReact.ComponentType<AssistantMessageProps>

A custom assistant message component to use instead of the default.

UserMessageReact.ComponentType<UserMessageProps>

A custom user message component to use instead of the default.

MessagesReact.ComponentType<MessagesProps>

A custom Messages component to use instead of the default.

RenderMessageReact.ComponentType<RenderMessageProps>

A custom RenderMessage component to use instead of the default.

RenderActionExecutionMessageReact.ComponentType<RenderMessageProps>

A custom RenderActionExecutionMessage component to use instead of the default.

RenderAgentStateMessageReact.ComponentType<RenderMessageProps>

A custom RenderAgentStateMessage component to use instead of the default.

RenderResultMessageReact.ComponentType<RenderMessageProps>

A custom RenderResultMessage component to use instead of the default.

InputReact.ComponentType<InputProps>

A custom Input component to use instead of the default.

classNamestring

A class name to apply to the root element.

childrenReact.ReactNode

Children to render.

defaultOpenboolean

Default:"false"

Whether the chat window should be open by default.

clickOutsideToCloseboolean

Default:"true"

If the chat window should close when the user clicks outside of it.

hitEscapeToCloseboolean

Default:"true"

If the chat window should close when the user hits the Escape key.

shortcutstring

Default:"'/'"

The shortcut key to open the chat window.
Uses Command-\[shortcut\] on a Mac and Ctrl-\[shortcut\] on Windows.

onSetOpen(open: boolean) => void

A callback that gets called when the chat window opens or closes.

WindowReact.ComponentType<WindowProps>

A custom Window component to use instead of the default.

ButtonReact.ComponentType<ButtonProps>

A custom Button component to use instead of the default.

HeaderReact.ComponentType<HeaderProps>

A custom Header component to use instead of the default.

[Previous\\
\\
CopilotPopup](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotPopup) [Next\\
\\
CopilotTextarea](https://docs.copilotkit.ai/reference/v1/components/CopilotTextarea)

### On this page

[Install Dependencies](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotSidebar#install-dependencies) [Usage](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotSidebar#usage) [Look & Feel](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotSidebar#look--feel) [Properties](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotSidebar#properties)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/components/chat/CopilotSidebar.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CrewAI Flows Quickstart
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pagePrerequisites

# Quickstart CrewAI Flows

Turn your CrewAI Flows into an agent-native application in 10 minutes.

## [Prerequisites](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai\#prerequisites)

Before you begin, you'll need the following:

- [**OpenAI API key**](https://platform.openai.com/api-keys)

## [Getting started](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai\#getting-started)

### [Install CopilotKit](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai\#install-copilotkit)

First, install the latest packages for CopilotKit into your frontend.

npmpnpmyarnbun

```
npm install @copilotkit/react-ui @copilotkit/react-core
```

Do you already have a CrewAI Flow agent?

You will need a CrewAI Flow agent to get started!

Either bring your own or feel free to use our starter repo.

CrewAI

Bring your own CrewAI Flow agent

I already have a CrewAI Flow agent and want to use it with CopilotKit.

![CopilotKit Logo](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/copilotkit-logo.svg)

Use the CoAgents Starter repo

I don't have a CrewAI Flow agent yet, but want to get started quickly.

### [Launch your local agent](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai\#launch-your-local-agent)

Start your local CrewAI Flow agent:

```
# Install dependencies
poetry lock
poetry install
# Start the server
poetry run demo
```

This will start a local agent server that you can connect to.

Choose your connection method

Now you need to connect your CrewAI Flow to CopilotKit.

Copilot Cloud (Recommended)

I want to host my Copilot on Copilot Cloud

Self-Hosted Copilot Runtime

I want to self-host the Copilot Runtime

### [Add a remote endpoint for your CrewAI Flow](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai\#add-a-remote-endpoint-for-your-crewai-flow)

Using Copilot Cloud, you need to connect a remote endpoint that will connect to your CrewAI Flow.

Self hosted (FastAPI)CrewAI Enterprise

**Running your FastAPI server in production**

Head over to [Copilot Cloud](https://cloud.copilotkit.ai/) sign up and setup a remote endpoint with the following information:

- OpenAI API key
- Your FastAPI server URL

**Running your FastAPI server locally**

If you're running your FastAPI server locally, you can open a tunnel to it so Copilot Cloud can connect to it.

```
npx copilotkit@latest dev --port 8000
```

### [Setup your CopilotKit provider](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai\#setup-your-copilotkit-provider)

The [`<CopilotKit>`](https://docs.copilotkit.ai/reference/v1/components/CopilotKit) component must wrap the Copilot-aware parts of your application. For most use-cases,
it's appropriate to wrap the CopilotKit provider around the entire app, e.g. in your layout.tsx.

layout.tsx

```
import "./globals.css";
import { ReactNode } from "react";
import { CopilotKit } from "@copilotkit/react-core";

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        {/* Use the public api key you got from Copilot Cloud  */}
        <CopilotKit
          publicApiKey="<your-copilot-cloud-public-api-key>"
          agent="sample_agent" // the name of the agent you want to use
        >
          {children}
        </CopilotKit>
      </body>
    </html>
  );
}
```

Looking for a way to run multiple CrewAI Flows? Check out our [Multi-Agent](https://docs.copilotkit.ai/crewai-flows/multi-agent-flows) guide.

### [Setup the Copilot UI](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai\#setup-the-copilot-ui)

The last step is to use CopilotKit's UI components to render the chat interaction with your agent. In most situations,
this is done alongside your core page components, e.g. in your `page.tsx` file.

page.tsx

```

import "@copilotkit/react-ui/styles.css";
import { CopilotPopup } from "@copilotkit/react-ui";

export function YourApp() {
  return (
    <main>
      <h1>Your main content</h1>

      <CopilotPopup
        labels={{
            title: "Popup Assistant",
            initial: "Hi! I'm connected to an agent. How can I help?",
        }}
      />
    </main>
  );
}
```

Looking for other chat component options? Check out our [Agentic Chat UI](https://docs.copilotkit.ai/crewai-flows/agentic-chat-ui) guide.

### [🎉 Talk to your agent!](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai\#-talk-to-your-agent)

Congrats! You've successfully integrated a CrewAI Flow chatbot to your application. To start, try asking a few questions to your agent.

```
Can you tell me a joke?
```

```
Can you help me understand AI?
```

```
What do you think about React?
```

### Having trouble?

* * *

## [What's next?](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai\#whats-next)

You've now got a CrewAI Flow running in CopilotKit! Now you can start exploring the various ways that CopilotKit
can help you build power agent native applications.

[**Implement Human in the Loop** \\
Allow your users and agents to collaborate together on tasks.](https://docs.copilotkit.ai/crewai-flows/human-in-the-loop) [**Utilize the Shared State** \\
Learn how to synchronize your agent's state with your UI's state, and vice versa.](https://docs.copilotkit.ai/crewai-flows/shared-state) [**Add some generative UI** \\
Render your agent's progress and output in the UI.](https://docs.copilotkit.ai/crewai-flows/generative-ui) [**Setup frontend actions** \\
Give your agent the ability to call frontend tools, directly updating your application.](https://docs.copilotkit.ai/crewai-flows/frontend-actions)

[Previous\\
\\
Introduction](https://docs.copilotkit.ai/crewai-flows) [Next\\
\\
Chat with an Agent](https://docs.copilotkit.ai/crewai-flows/agentic-chat-ui)

### On this page

[Prerequisites](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#prerequisites) [Getting started](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#getting-started) [Install CopilotKit](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#install-copilotkit) [Clone the coagents-starter repo](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#clone-the-coagents-starter-repo) [Create a .env file](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#create-a-env-file) [Add your API keys](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#add-your-api-keys) [Launch your local agent](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#launch-your-local-agent) [Add a remote endpoint for your CrewAI Flow](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#add-a-remote-endpoint-for-your-crewai-flow) [Setup your CopilotKit provider](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#setup-your-copilotkit-provider) [Install Copilot Runtime](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#install-copilot-runtime) [Setup a Copilot Runtime Endpoint](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#setup-a-copilot-runtime-endpoint) [Add your CrewAI Flow deployment to Copilot Runtime](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#add-your-crewai-flow-deployment-to-copilot-runtime) [Configure the CopilotKit Provider](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#configure-the-copilotkit-provider) [Setup the Copilot UI](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#setup-the-copilot-ui) [🎉 Talk to your agent!](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#-talk-to-your-agent) [What's next?](https://docs.copilotkit.ai/crewai-flows/quickstart/crewai#whats-next)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/crewai-flows/quickstart/crewai.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotKit Configuration Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageMessage Streaming

# Streaming and Tool Calls

CoAgents support streaming your messages and tool calls to the frontend.

If you'd like to change how LangGraph agents behave as CoAgents you can utilize our CopilotKit SDK which provides a collection
of functions and utilities for interacting with the agent's state or behavior. One example of this is the CopilotKit config
which is a wrapper of the LangGraph `config` object. This allows you to extend the configuration of your LangGraph nodes to
change how LangGraph and CopilotKit interact with each other. This allows you to change how messages and tool calls are emitted and
streamed to the frontend.

## [Message Streaming](https://docs.copilotkit.ai/coagents/concepts/copilotkit-config\#message-streaming)

If you did not change anything in your LangGraph node, message streaming will be on by default. This allows for a message to be
streamed to CopilotKit as it is being generated, allowing for a more responsive experience. However, you can disable this if you
want to have the message only be sent after the agent has finished generating it.

```
config = copilotkit_customize_config(
    config,
    # True or False
    emit_messages=False,
)
```

## [Emitting Tool Calls](https://docs.copilotkit.ai/coagents/concepts/copilotkit-config\#emitting-tool-calls)

Emission of tool calls are off by default. This means that tool calls will not be sent to CopilotKit for processing and rendering.
However, within a node you can extend the LangGraph `config` object to emit tool calls to CopilotKit. This is useful in situations
where you may to emit what a potential tool call will look like prior to being executed.

```
config = copilotkit_customize_config(
    config,
    # Can set to True, False, or a list of tool call names to emit.
    emit_tool_calls=["tool_name"],
)
```

For more information on how tool calls are utilized check out our [frontend actions](https://docs.copilotkit.ai/coagents/frontend-actions)
documentation.

[Next\\
\\
Introduction](https://docs.copilotkit.ai/)

### On this page

[Message Streaming](https://docs.copilotkit.ai/coagents/concepts/copilotkit-config#message-streaming) [Emitting Tool Calls](https://docs.copilotkit.ai/coagents/concepts/copilotkit-config#emitting-tool-calls)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/concepts/copilotkit-config.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Agentic Chat UI
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is this?

# Chat with an Agent

Chat with an agent using CopilotKit's UI components.

This video shows the [coagents starter](https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter) repo with various Copilot UI components applied to it!

## [What is this?](https://docs.copilotkit.ai/coagents/agentic-chat-ui\#what-is-this)

Agentic chat UIs are ways for your users to interact with your agent. CopilotKit provides a variety of different components to choose from, each
with their own unique use cases.

If you've gone through the [getting started guide](https://docs.copilotkit.ai/coagents/quickstart/langgraph) **you already have a agentic chat UI setup**! Nothing else is needed
to get started.

## [When should I use this?](https://docs.copilotkit.ai/coagents/agentic-chat-ui\#when-should-i-use-this)

CopilotKit provides a variety of different batteries-included components to choose from to create agent native applications. They scale
from simple chat UIs to completely custom applications.

CopilotPopupCopilotSidebarCopilotChatHeadless UI

`CopilotPopup` is a convenience wrapper for `CopilotChat` that lives at the same level as your main content in the view hierarchy. It provides **a floating chat interface** that can be toggled on and off.

![Popup Example](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/popup-example.gif)

```
import { CopilotPopup } from "@copilotkit/react-ui";

export function YourApp() {
  return (
    <>
      <YourMainContent />
      <CopilotPopup
        instructions={"You are assisting the user as best as you can. Answer in the best way possible given the data you have."}
        labels={{
          title: "Popup Assistant",
          initial: "Need any help?",
        }}
      />
    </>
  );
}
```

[Previous\\
\\
Quickstart (LangGraph)](https://docs.copilotkit.ai/coagents/quickstart/langgraph) [Next\\
\\
Generative UI](https://docs.copilotkit.ai/coagents/generative-ui)

### On this page

[What is this?](https://docs.copilotkit.ai/coagents/agentic-chat-ui#what-is-this) [When should I use this?](https://docs.copilotkit.ai/coagents/agentic-chat-ui#when-should-i-use-this)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/agentic-chat-ui.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CrewAIAgent Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageCrewAIAgent

Python

# CrewAIAgent

CrewAIAgent lets you define your agent for use with CopilotKit.

## [CrewAIAgent](https://docs.copilotkit.ai/reference/v1/sdk/python/CrewAIAgent\#crewaiagent)

CrewAIAgent lets you define your agent for use with CopilotKit.

To install, run:

```
pip install copilotkit[crewai]
```

Every agent must have the `name` and either `crew` or `flow` properties defined. An optional
`description` can also be provided. This is used when CopilotKit is dynamically routing requests
to the agent.

## [Serving a Crew based agent](https://docs.copilotkit.ai/reference/v1/sdk/python/CrewAIAgent\#serving-a-crew-based-agent)

To serve a Crew based agent, pass in a `Crew` object to the `crew` parameter.

Note:
You need to make sure to have a `chat_llm` set on the `Crew` object.
See [the CrewAI docs](https://docs.crewai.com/concepts/cli#9-chat) for more information.

```
from copilotkit import CrewAIAgent


CrewAIAgent(
    name="email_agent_crew",
    description="This crew based agent sends emails",
    crew=SendEmailCrew(),
)
```

## [Serving a Flow based agent](https://docs.copilotkit.ai/reference/v1/sdk/python/CrewAIAgent\#serving-a-flow-based-agent)

To serve a Flow based agent, pass in a `Flow` object to the `flow` parameter.

```
CrewAIAgent(
    name="email_agent_flow",
    description="This flow based agent sends emails",
    flow=SendEmailFlow(),
)
```

Note:
Either a `crew` or `flow` must be provided to CrewAIAgent.

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/CrewAIAgent\#parameters)

namestrrequired

The name of the agent.

crewCrewrequired

When using a Crew based agent, pass in a `Crew` object to the `crew` parameter.

flowFlowrequired

When using a Flow based agent, pass in a `Flow` object to the `flow` parameter.

descriptionOptional\[str\]

The description of the agent.

copilotkit\_configOptional\[CopilotKitConfig\]

The CopilotKit config to use with the agent.

## [CopilotKitConfig](https://docs.copilotkit.ai/reference/v1/sdk/python/CrewAIAgent\#copilotkitconfig)

CopilotKit config for CrewAIAgent

This is used for advanced cases where you want to customize how CopilotKit interacts with
CrewAI.

```
# Function signatures:
def merge_state(
    *,
    state: dict,
    messages: List[BaseMessage],
    actions: List[Any],
    agent_name: str
):
    # ...implementation...
```

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/CrewAIAgent\#parameters-1)

merge\_stateCallablerequired

This function lets you customize how CopilotKit merges the agent state.

[Previous\\
\\
LangGraph SDK](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph) [Next\\
\\
CrewAI SDK](https://docs.copilotkit.ai/reference/v1/sdk/python/CrewAI)

### On this page

[CrewAIAgent](https://docs.copilotkit.ai/reference/v1/sdk/python/CrewAIAgent#crewaiagent) [Serving a Crew based agent](https://docs.copilotkit.ai/reference/v1/sdk/python/CrewAIAgent#serving-a-crew-based-agent) [Serving a Flow based agent](https://docs.copilotkit.ai/reference/v1/sdk/python/CrewAIAgent#serving-a-flow-based-agent) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/CrewAIAgent#parameters) [CopilotKitConfig](https://docs.copilotkit.ai/reference/v1/sdk/python/CrewAIAgent#copilotkitconfig) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/CrewAIAgent#parameters-1)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/sdk/python/CrewAIAgent.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CrewAI Quickstart Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pagePrerequisites

# Quickstart CrewAI Crews

Turn your CrewAI Crews into an agent-native application in 10 minutes.

## [Prerequisites](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai\#prerequisites)

Before you begin, you'll need the following:

- [**OpenAI API key**](https://platform.openai.com/api-keys)

## [Getting started](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai\#getting-started)

Use the CopilotKit CLI

Use the CopilotKit CLI

I have a Next.js application and want to get started quickly.

Code along

I want to deeply understand what's happening under the hood or don't have a Next.js application.

### [Run the CLI](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai\#run-the-cli)

Just run this following command in your Next.js application to get started!

### Don't have a Next.js application?

```
npx copilotkit@latest init
```

### [🎉 Talk to your agent!](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai\#-talk-to-your-agent)

Congrats! You've successfully integrated your CrewAI Enterprise agent with CopilotKit.
Try talking to your Copilot. Chat with it to provide the information needed to run your Crew from your app.

You can also check out our [Restaurant Finder Crew demo](https://crew-ai-enterprise-demo.vercel.app/) to see implementation in action.

* * *

## [What's next?](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai\#whats-next)

You've now got a CrewAI Crew running in CopilotKit! Now you can start exploring the various ways that CopilotKit
can help you build power agent native applications.

[**Implement Human in the Loop** \\
Allow your users and agents to collaborate together on tasks.](https://docs.copilotkit.ai/crewai-crews/human-in-the-loop) [**Utilize the Shared State** \\
Learn how to synchronize your agent's state with your UI's state, and vice versa.](https://docs.copilotkit.ai/crewai-crews/shared-state) [**Add some generative UI** \\
Render your agent's progress and output in the UI.](https://docs.copilotkit.ai/crewai-crews/generative-ui) [**Setup frontend actions** \\
Give your agent the ability to call frontend tools, directly updating your application.](https://docs.copilotkit.ai/crewai-crews/frontend-actions)

[Previous\\
\\
Introduction](https://docs.copilotkit.ai/crewai-crews) [Next\\
\\
Chat with an Agent](https://docs.copilotkit.ai/crewai-crews/agentic-chat-ui)

### On this page

[Prerequisites](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai#prerequisites) [Getting started](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai#getting-started) [Run the CLI](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai#run-the-cli) [Connect to Copilot Cloud](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai#connect-to-copilot-cloud) [Setup the CopilotKit Provider](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai#setup-the-copilotkit-provider) [Choose a Copilot UI](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai#choose-a-copilot-ui) [Create a Crew-Quickstart component](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai#create-a-crew-quickstart-component) [🎉 Talk to your agent!](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai#-talk-to-your-agent) [What's next?](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai#whats-next)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/crewai-crews/quickstart/crewai.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## LangGraphAgent Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageLangGraphAgent

Python

# LangGraphAgent

LangGraphAgent lets you define your agent for use with CopilotKit.

## [LangGraphAgent](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraphAgent\#langgraphagent)

LangGraphAgent lets you define your agent for use with CopilotKit.

To install, run:

```
pip install copilotkit
```

### [Examples](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraphAgent\#examples)

Every agent must have the `name` and `graph` properties defined. An optional `description`
can also be provided. This is used when CopilotKit is dynamically routing requests to the
agent.

```
from copilotkit import LangGraphAgent

LangGraphAgent(
    name="email_agent",
    description="This agent sends emails",
    graph=graph,
)
```

If you have a custom LangGraph/LangChain config that you want to use with the agent, you can
pass it in as the `langgraph_config` parameter.

```
LangGraphAgent(
    ...
    langgraph_config=config,
)
```

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraphAgent\#parameters)

namestrrequired

The name of the agent.

graphCompiledGraphrequired

The LangGraph graph to use with the agent.

descriptionOptional\[str\]

The description of the agent.

langgraph\_configOptional\[RunnableConfig\]

The LangGraph/LangChain config to use with the agent.

copilotkit\_configOptional\[CopilotKitConfig\]

The CopilotKit config to use with the agent.

## [CopilotKitConfig](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraphAgent\#copilotkitconfig)

CopilotKit config for LangGraphAgent

This is used for advanced cases where you want to customize how CopilotKit interacts with
LangGraph.

```
# Function signatures:
def merge_state(
    *,
    state: dict,
    messages: List[BaseMessage],
    actions: List[Any],
    agent_name: str
):
    # ...implementation...

def convert_messages(messages: List[Message]):
    # ...implementation...
```

### [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraphAgent\#parameters-1)

merge\_stateCallablerequired

This function lets you customize how CopilotKit merges the agent state.

convert\_messagesCallablerequired

Use this function to customize how CopilotKit converts its messages to LangChain messages.\`

[Previous\\
\\
Remote Endpoints](https://docs.copilotkit.ai/reference/v1/sdk/python/RemoteEndpoints) [Next\\
\\
LangGraph SDK](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraph)

### On this page

[LangGraphAgent](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraphAgent#langgraphagent) [Examples](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraphAgent#examples) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraphAgent#parameters) [CopilotKitConfig](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraphAgent#copilotkitconfig) [Parameters](https://docs.copilotkit.ai/reference/v1/sdk/python/LangGraphAgent#parameters-1)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/sdk/python/LangGraphAgent.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotKit Guardrails Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageIntroduction

# Guardrails  Cloud Only

## [Introduction](https://docs.copilotkit.ai/guides/guardrails\#introduction)

Copilot Cloud provides content moderation capabilities through the `guardrails_c` configuration, helping ensure safe and appropriate AI interactions. The system uses OpenAI's content moderation capabilities to enforce these guardrails.

This feature is only available with [Copilot Cloud](https://cloud.copilotkit.ai/).

## [Implementation](https://docs.copilotkit.ai/guides/guardrails\#implementation)

```
import { CopilotKit } from "@copilotkit/react-core";

export default function App() {
  return (
    <CopilotKit
      publicApiKey={process.env.COPILOTKIT_PUBLIC_API_KEY}
      guardrails_c={{
        // Topics to explicitly block
        invalidTopics: ["politics", "explicit-content", "harmful-content"],
        // Topics to explicitly allow
        validTopics: ["business", "technology", "general-assistance"],
      }}
    >
      {/* Your app */}
    </CopilotKit>
  );
}
```

[Previous\\
\\
Authenticated Actions](https://docs.copilotkit.ai/guides/authenticated-actions) [Next\\
\\
Copilot Suggestions](https://docs.copilotkit.ai/guides/copilot-suggestions)

### On this page

[Introduction](https://docs.copilotkit.ai/guides/guardrails#introduction) [Implementation](https://docs.copilotkit.ai/guides/guardrails#implementation)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/guardrails.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## LangSmith Observability
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this page

Observability

# LangSmith

To trace your LLM runs with LangSmith, make sure to set up your environment variables:

.env

```
LANGCHAIN_API_KEY="<your-api-key>"
LANGCHAIN_PROJECT="<your-project-name>"
LANGCHAIN_TRACING_V2="true"
LANGCHAIN_ENDPOINT="https://api.smith.langchain.com""
```

Next, use the `LangChainAdapter` to trace your CopilotKit runs:

```
const { LangChainAdapter } = await import("@copilotkit/runtime");
const { ChatOpenAI } = await import("@langchain/openai");

async function getLangChainOpenAIAdapter() {
  return new LangChainAdapter({
    chainFn: async ({ messages, tools, threadId }) => {
      const model = new ChatOpenAI({
        modelName: "gpt-4-1106-preview",
      }).bindTools(tools, {
        strict: true,
      });
      return model.stream(messages, {
        tools,
        metadata: { conversation_id: threadId },
      });
    },
  });
}
```

Note that `threadId` is passed to the model as `conversation_id` in the metadata.

[Previous\\
\\
Anonymous Telemetry](https://docs.copilotkit.ai/telemetry)

### On this page

No Headings

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/(other)/observability/langsmith.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Disabling State Streaming
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is this?

Advanced

# Disabling state streaming

Granularly control what is streamed to the frontend.

## [What is this?](https://docs.copilotkit.ai/coagents/advanced/disabling-state-streaming\#what-is-this)

By default, CopilotKit will stream both your state and tool calls to the frontend.
You can disable this by using CopilotKit's custom `RunnableConfig`.

## [When should I use this?](https://docs.copilotkit.ai/coagents/advanced/disabling-state-streaming\#when-should-i-use-this)

Occasionally, you'll want to disable streaming temporarily — for example, the LLM may be
doing something the current user should not see, like emitting tool calls or questions
pertaining to other employees in an HR system.

## [Implementation](https://docs.copilotkit.ai/coagents/advanced/disabling-state-streaming\#implementation)

### [Disable all streaming](https://docs.copilotkit.ai/coagents/advanced/disabling-state-streaming\#disable-all-streaming)

You can disable all message streaming and tool call streaming by passing `emit_messages=False` and `emit_tool_calls=False` to the CopilotKit config.

PythonTypeScript

```
from copilotkit.langgraph import copilotkit_customize_config

async def frontend_actions_node(state: AgentState, config: RunnableConfig):

    # 1) Configure CopilotKit not to emit messages
    modifiedConfig = copilotkit_customize_config(
        config,
        emit_messages=False, # if you want to disable message streaming
        emit_tool_calls=False # if you want to disable tool call streaming
    )

    # 2) Provide the actions to the LLM
    model = ChatOpenAI(model="gpt-4o").bind_tools([\
      *state["copilotkit"]["actions"],\
      # ... any tools you want to make available to the model\
    ])

    # 3) Call the model with CopilotKit's modified config
    response = await model.ainvoke(state["messages"], modifiedConfig)

    # don't return the new response to hide it from the user
    return state
```

BEWARE!

In LangGraph Python, the `config` variable in the surrounding namespace is **implicitly** passed into LangChain LLM calls, even when not explicitly provided.

This is why we create a new variable `modifiedConfig` rather than modifying `config` directly. If we modified `config` itself, it would change the default configuration for all subsequent LLM calls in that namespace.

```
# if we override the config variable name with a new value
config = copilotkit_customize_config(config, ...)

# it will affect every subsequent LangChain LLM call in the same namespace, even when `config` is not explicitly provided
response = await model2.ainvoke(*state["messages"]) # implicitly uses the modified config!
```

[Previous\\
\\
Using Agent Execution Parameters](https://docs.copilotkit.ai/coagents/advanced/adding-runtime-configuration) [Next\\
\\
Manually emitting messages](https://docs.copilotkit.ai/coagents/advanced/emit-messages)

### On this page

[What is this?](https://docs.copilotkit.ai/coagents/advanced/disabling-state-streaming#what-is-this) [When should I use this?](https://docs.copilotkit.ai/coagents/advanced/disabling-state-streaming#when-should-i-use-this) [Implementation](https://docs.copilotkit.ai/coagents/advanced/disabling-state-streaming#implementation) [Disable all streaming](https://docs.copilotkit.ai/coagents/advanced/disabling-state-streaming#disable-all-streaming)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/advanced/disabling-state-streaming.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Integrate Your LLM
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this page

# Bring Your Own LLM

Learn how to use any LLM with CopilotKit.

LLM Adapters are responsible for executing the request with the LLM and standardizing the request/response format in a way that the Copilot Runtime can understand.

Currently, we support the following LLM adapters natively:

- [OpenAI Adapter (Azure also supported)](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAdapter)
- [OpenAI Assistant Adapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAssistantAdapter)
- [LangChain Adapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/LangChainAdapter)
- [Groq Adapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/GroqAdapter)
- [Google Generative AI Adapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/GoogleGenerativeAIAdapter)
- [Anthropic Adapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/AnthropicAdapter)

You can use the [LangChain Adapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/LangChainAdapter) to use any LLM provider we don't yet natively support!

It's not too hard to write your own LLM adapter from scratch -- see the existing adapters for inspiration. And of course, we would love a contribution! ⭐️

Copilot Cloud (Recommended)

Use our hosted backend endpoint to get started quickly.

Self-hosting

Learn to host CopilotKit's runtime yourself with your own backend.

Configure the used LLM adapter [on your Copilot Cloud dashboard](https://cloud.copilotkit.ai/)!

[Previous\\
\\
Copilot Suggestions](https://docs.copilotkit.ai/guides/copilot-suggestions) [Next\\
\\
Copilot Textarea](https://docs.copilotkit.ai/guides/copilot-textarea)

### On this page

No Headings

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/bring-your-own-llm.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Custom UI Options
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this page

# Customize UI

Customize the look, feel, and functionality of CopilotKit's UI components.

CopilotKit offers a variety of ways to create a UI interface for your Copilots and CoAgents. This ranges
from using our built-in UI components to fully customizing the UI with headless UI.

[**Prebuilt Copilot UI** \\
Get started quickly with CopilotKit's ready-to-use UI components.](https://docs.copilotkit.ai/guides/custom-look-and-feel/built-in-ui-components) [**Styling Copilot UI** \\
Customize the appearance of CopilotKit's pre-built components with your own styles.](https://docs.copilotkit.ai/guides/custom-look-and-feel/customize-built-in-ui-components) [**Custom Components** \\
Replace the Copilot UI components with your own while keeping the core functionality.](https://docs.copilotkit.ai/guides/custom-look-and-feel/bring-your-own-components) [**Fully Custom UI** \\
Build your UI from scratch using CopilotKit's hooks and core functionality.](https://docs.copilotkit.ai/guides/custom-look-and-feel/headless-ui)

[Previous\\
\\
Quickstart](https://docs.copilotkit.ai/quickstart) [Next\\
\\
Prebuilt Copilot UI](https://docs.copilotkit.ai/guides/custom-look-and-feel/built-in-ui-components)

### On this page

No Headings

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/custom-look-and-feel/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Self-Host CopilotKit
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageInstall CopilotKit

# Quickstart

Get started with CopilotKit in under 5 minutes.

Copilot Cloud (Recommended)

Use our hosted backend endpoint to get started quickly.

Self-hosting

Learn to host CopilotKit's runtime yourself with your own backend.

## [Install CopilotKit](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted\#install-copilotkit-1)

First, install the latest packages for CopilotKit.

npmpnpmyarnbun

```
npm install @copilotkit/react-ui @copilotkit/react-core @copilotkit/runtime
```

## [Set up a Copilot Runtime Endpoint](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted\#set-up-a-copilot-runtime-endpoint)

##### Choose your provider:

![OpenAI logo](https://docs.copilotkit.ai/icons/openai.png)OpenAI

If you are planning to use a single LangGraph agent in [agent-lock mode](https://docs.copilotkit.ai/coagents/multi-agent-flows) as your agentic backend, your LLM adapter will only be used for peripherals such as suggestions, etc.

If you are not sure yet, simply ignore this note.

### [Add your API key](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted\#add-your-api-key)

Next, add your API key to your `.env` file in the root of your project (unless you prefer to provide it directly to the client):

.env

```
OPENAI_API_KEY=your_api_key_here
```

Please note that the code below uses GPT-4o, which requires a paid OpenAI API key. **If you are using a free OpenAI API key**, change the model to a different option such as `gpt-3.5-turbo`.

### [Setup the Runtime Endpoint](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted\#setup-the-runtime-endpoint)

### [Serverless Function Timeouts](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted\#serverless-function-timeouts)

When deploying to serverless platforms (Vercel, AWS Lambda, etc.), be aware that default function timeouts may be too short for CopilotKit's streaming responses:

- Vercel defaults: 10s (Hobby), 15s (Pro)
- AWS Lambda default: 3s

**Solution options:**

1. Increase function timeout:








```
// vercel.json
{
     "functions": {
       "api/copilotkit/**/*": {
         "maxDuration": 60
       }
     }
}
```

2. Use [Copilot Cloud](https://cloud.copilotkit.ai/) to avoid timeout issues entirely

Next.js App RouterNext.js Pages RouterNode.js ExpressNode.js HTTPNestJS

Create a new route to handle the `/api/copilotkit` endpoint.

app/api/copilotkit/route.ts

```
import {
  CopilotRuntime,
  OpenAIAdapter,
  copilotRuntimeNextJSAppRouterEndpoint,
} from '@copilotkit/runtime';

import { NextRequest } from 'next/server';


const serviceAdapter = new OpenAIAdapter();
const runtime = new CopilotRuntime();

export const POST = async (req: NextRequest) => {
  const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
    runtime,
    serviceAdapter,
    endpoint: '/api/copilotkit',
  });

  return handleRequest(req);
};
```

Your Copilot Runtime endpoint should be available at `http://localhost:3000/api/copilotkit`.

## [Configure the CopilotKit Provider](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted\#configure-the-copilotkit-provider)

layout.tsx

```
import "./globals.css";
import { ReactNode } from "react";
import { CopilotKit } from "@copilotkit/react-core";

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        {/* Make sure to use the URL you configured in the previous step  */}
        <CopilotKit runtimeUrl="/api/copilotkit">
          {children}
        </CopilotKit>
      </body>
    </html>
  );
}
```

## [Choose a Copilot UI](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted\#choose-a-copilot-ui-1)

You are almost there! Now it's time to setup your Copilot UI.

First, import the default styles in your root component (typically `layout.tsx`) :

```
import "@copilotkit/react-ui/styles.css";
```

Copilot UI ships with a number of built-in UI patterns, choose whichever one you like.

CopilotPopupCopilotSidebarCopilotChatHeadless UI

`CopilotPopup` is a convenience wrapper for `CopilotChat` that lives at the same level as your main content in the view hierarchy. It provides **a floating chat interface** that can be toggled on and off.

![Popup Example](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/popup-example.gif)

```
import { CopilotPopup } from "@copilotkit/react-ui";

export function YourApp() {
  return (
    <>
      <YourMainContent />
      <CopilotPopup
        instructions={"You are assisting the user as best as you can. Answer in the best way possible given the data you have."}
        labels={{
          title: "Popup Assistant",
          initial: "Need any help?",
        }}
      />
    </>
  );
}
```

* * *

## [Next Steps](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted\#next-steps)

🎉 Congrats! You've successfully integrated a fully functional chatbot in your application! Give it a try now and see it in action. Want to
take it further? Learn more about what CopilotKit has to offer!

[**Connecting Your Data** \\
Learn how to connect CopilotKit to your data, application state and user state.](https://docs.copilotkit.ai/guides/connect-your-data) [**Generative UI** \\
Learn how to render custom UI components directly in the CopilotKit chat window.](https://docs.copilotkit.ai/guides/generative-ui) [**Frontend Actions** \\
Learn how to allow your copilot to take applications on frontend.](https://docs.copilotkit.ai/guides/frontend-actions) [**CoAgents (LangGraph)** \\
Check out our section about CoAgents, our approach to building agentic copilots and experiences.](https://docs.copilotkit.ai/coagents)

[Previous\\
\\
Introduction](https://docs.copilotkit.ai/) [Next\\
\\
Customize UI](https://docs.copilotkit.ai/guides/custom-look-and-feel)

### On this page

[Install CopilotKit](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted#install-copilotkit) [Get a Copilot Cloud Public API Key](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted#get-a-copilot-cloud-public-api-key) [Setup the CopilotKit Provider](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted#setup-the-copilotkit-provider) [Choose a Copilot UI](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted#choose-a-copilot-ui) [Install CopilotKit](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted#install-copilotkit-1) [Set up a Copilot Runtime Endpoint](https://docs.copilotkit.ai/direct-to-llm/guides/quickstart?copilot-hosting=self-hosted#set-up-a-copilot-runtime-endpoint) [Configure the CopilotKit Provider](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted#configure-the-copilotkit-provider) [Choose a Copilot UI](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted#choose-a-copilot-ui-1) [Next Steps](https://docs.copilotkit.ai/quickstart?copilot-hosting=self-hosted#next-steps)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/quickstart.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Connect Your Data
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageAdd the data to the Copilot

[Connecting Your Data](https://docs.copilotkit.ai/guides/connect-your-data)

# Frontend Data

Learn how to connect your data to CopilotKit.

For your copilot to best answer your users' needs, you will want to provide it with **context-specific**, **user-specific**, and oftentimes **realtime** data. CopilotKit makes it easy to do so.

### [Add the data to the Copilot](https://docs.copilotkit.ai/guides/connect-your-data/frontend\#add-the-data-to-the-copilot)

The [`useCopilotReadable` hook](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotReadable) is used to add data as context to the Copilot.

YourComponent.tsx

```
"use client" // only necessary if you are using Next.js with the App Router.
import { useCopilotReadable } from "@copilotkit/react-core";
import { useState } from 'react';

export function YourComponent() {
  // Create colleagues state with some sample data
  const [colleagues, setColleagues] = useState([\
    { id: 1, name: "John Doe", role: "Developer" },\
    { id: 2, name: "Jane Smith", role: "Designer" },\
    { id: 3, name: "Bob Wilson", role: "Product Manager" }\
  ]);

  // Define Copilot readable state

  useCopilotReadable({
    description: "The current user's colleagues",
    value: colleagues,
  });
  return (
    // Your custom UI component
    <>...</>
  );
}
```

### [Specify `"use client"` (Next.js App Router)](https://docs.copilotkit.ai/guides/connect-your-data/frontend\#specify-use-client-nextjs-app-router)

This is only necessary if you are using Next.js with the App Router.

YourComponent.tsx

```
"use client"
```

Like other React hooks such as `useState` and `useEffect`, this is a **client-side** hook.
If you're using Next.js with the App Router, you'll need to add the `"use client"` directive at the top of any file using this hook.

### [Test it out!](https://docs.copilotkit.ai/guides/connect-your-data/frontend\#test-it-out)

The data you provided is now available to the Copilot.
Test it out by passing some data in the hook and asking the copilot questions about it.

![Example of connecting data to Copilot](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/connect-your-data-example.gif)

[Previous\\
\\
Connecting Your Data](https://docs.copilotkit.ai/guides/connect-your-data) [Next\\
\\
Backend Data](https://docs.copilotkit.ai/guides/connect-your-data/backend)

### On this page

[Add the data to the Copilot](https://docs.copilotkit.ai/guides/connect-your-data/frontend#add-the-data-to-the-copilot) [Test it out!](https://docs.copilotkit.ai/guides/connect-your-data/frontend#test-it-out)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/connect-your-data/frontend.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Loading Message History
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageLoading an Existing Thread

Persistence

# Threads

Learn how to load chat messages and threads within the CopilotKit framework.

LangGraph supports threads, a way to group messages together and ultimately maintain a continuous chat history. CopilotKit
provides a few different ways to interact with this concept.

This guide assumes you have already gone through the [quickstart](https://docs.copilotkit.ai/quickstart) guide.

## [Loading an Existing Thread](https://docs.copilotkit.ai/coagents/persistence/loading-message-history\#loading-an-existing-thread)

To load an existing thread in CopilotKit, you can simply set the `threadId` property on `<CopilotKit>` like so.

When using LangGraph platform, the `threadId` must be a UUID.

```
import { CopilotKit } from "@copilotkit/react-core";

<CopilotKit threadId="37aa68d0-d15b-45ae-afc1-0ba6c3e11353">
  <YourApp />
</CopilotKit>
```

## [Dynamically Switching Threads](https://docs.copilotkit.ai/coagents/persistence/loading-message-history\#dynamically-switching-threads)

You can also make the `threadId` dynamic. Once it is set, CopilotKit will load the previous messages for that thread.

```
import { useState } from "react";
import { CopilotKit } from "@copilotkit/react-core";

const Page = () => {
  const [threadId, setThreadId] = useState("af2fa5a4-36bd-4e02-9b55-2580ab584f89");
  return (
    <CopilotKit threadId={threadId}>
      <YourApp setThreadId={setThreadId} />
    </CopilotKit>
  )
}

const YourApp = ({ setThreadId }) => {
  return (
    <Button onClick={() => setThreadId("679e8da5-ee9b-41b1-941b-80e0cc73a008")}>
      Change Thread
    </Button>
  )
}
```

## [Using setThreadId](https://docs.copilotkit.ai/coagents/persistence/loading-message-history\#using-setthreadid)

CopilotKit will also return the current `threadId` and a `setThreadId` function from the `useCopilotContext` hook. You can use `setThreadId` to change the `threadId`.

```
import { useCopilotContext } from "@copilotkit/react-core";

const ChangeThreadButton = () => {
  const { threadId, setThreadId } = useCopilotContext();
  return (
    <Button onClick={() => setThreadId("d73c22f3-1f8e-4a93-99db-5c986068d64f")}>
      Change Thread
    </Button>
  )
}
```

[Previous\\
\\
Loading Agent State](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state) [Next\\
\\
Message Persistence](https://docs.copilotkit.ai/coagents/persistence/message-persistence)

### On this page

[Loading an Existing Thread](https://docs.copilotkit.ai/coagents/persistence/loading-message-history#loading-an-existing-thread) [Dynamically Switching Threads](https://docs.copilotkit.ai/coagents/persistence/loading-message-history#dynamically-switching-threads) [Using setThreadId](https://docs.copilotkit.ai/coagents/persistence/loading-message-history#using-setthreadid)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/persistence/loading-message-history.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Human-in-the-Loop Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is Human-in-the-Loop (HITL)?

# Human in the Loop (HITL)

Allow your agent and users to collaborate on complex tasks.

This video shows an example of our [AI Travel App](https://docs.copilotkit.ai/coagents/tutorials/ai-travel-app) using HITL to get user feedback.

## [What is Human-in-the-Loop (HITL)?](https://docs.copilotkit.ai/coagents/human-in-the-loop\#what-is-human-in-the-loop-hitl)

Human-in-the-loop (HITL) allows agents to request human input or approval during execution, making AI systems more reliable and trustworthy. This pattern is essential when building AI applications that need to handle complex decisions or actions that require human judgment.

![Agentic Copilot Human in the Loop](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/coagents/coagents-hitl-infographic.png)

Learn more about HITL in [LangGraph's concept guide](https://docs.langchain.com/oss/python/langgraph/interrupts).

## [When should I use this?](https://docs.copilotkit.ai/coagents/human-in-the-loop\#when-should-i-use-this)

HITL combines the efficiency of AI with human judgment, creating a system that's both powerful and reliable. The key advantages include:

- **Quality Control**: Human oversight at critical decision points
- **Edge Cases**: Graceful handling of low-confidence situations
- **Expert Input**: Leverage human expertise when needed
- **Reliability**: More robust system for real-world use

## [How can I use this?](https://docs.copilotkit.ai/coagents/human-in-the-loop\#how-can-i-use-this)

CopilotKit provides two main approaches for HITL LangGraph workflows - interrupt and node-based.

Unsure which approach to use? We recommend starting with the [Interrupt](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow) flow.

[Interrupt\\
\\
Utilize LangGraph's interrupt function to pause the agent and wait for user input.](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow)

[Node-based\\
\\
Utilize nodes and tools to create LLM-driven Human-in-the-Loop workflows.](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow)

[Previous\\
\\
Tool-based Generative UI](https://docs.copilotkit.ai/coagents/generative-ui/tool-based) [Next\\
\\
Interrupt](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow)

### On this page

[What is Human-in-the-Loop (HITL)?](https://docs.copilotkit.ai/coagents/human-in-the-loop#what-is-human-in-the-loop-hitl) [When should I use this?](https://docs.copilotkit.ai/coagents/human-in-the-loop#when-should-i-use-this) [How can I use this?](https://docs.copilotkit.ai/coagents/human-in-the-loop#how-can-i-use-this)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/human-in-the-loop/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotKit Quickstart Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageInstall CopilotKit

# Quickstart

Get started with CopilotKit in under 5 minutes.

Copilot Cloud (Recommended)

Use our hosted backend endpoint to get started quickly.

Self-hosting

Learn to host CopilotKit's runtime yourself with your own backend.

## [Install CopilotKit](https://docs.copilotkit.ai/quickstart?component=Headless%20UI\#install-copilotkit)

First, install the latest packages for CopilotKit.

npmpnpmyarnbun

```
npm install @copilotkit/react-ui @copilotkit/react-core
```

## [Get a Copilot Cloud Public API Key](https://docs.copilotkit.ai/quickstart?component=Headless%20UI\#get-a-copilot-cloud-public-api-key)

Navigate to [Copilot Cloud](https://cloud.copilotkit.ai/) and follow the instructions to get a public API key - it's free!

## [Setup the CopilotKit Provider](https://docs.copilotkit.ai/quickstart?component=Headless%20UI\#setup-the-copilotkit-provider)

The [`<CopilotKit>`](https://docs.copilotkit.ai/reference/v1/components/CopilotKit) component must wrap the Copilot-aware parts of your application. For most use-cases,
it's appropriate to wrap the CopilotKit provider around the entire app, e.g. in your layout.tsx.

layout.tsx

```
import "./globals.css";
import { ReactNode } from "react";
import { CopilotKit } from "@copilotkit/react-core";

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        {/* Use the public api key you got from Copilot Cloud  */}
        <CopilotKit publicApiKey="<your-copilot-cloud-public-api-key>">
          {children}
        </CopilotKit>
      </body>
    </html>
  );
}
```

## [Choose a Copilot UI](https://docs.copilotkit.ai/quickstart?component=Headless%20UI\#choose-a-copilot-ui)

You are almost there! Now it's time to setup your Copilot UI.

First, import the default styles in your root component (typically `layout.tsx`) :

```
import "@copilotkit/react-ui/styles.css";
```

Copilot UI ships with a number of built-in UI patterns, choose whichever one you like.

CopilotPopupCopilotSidebarCopilotChatHeadless UI

The built-in Copilot UI can be customized in many ways -- both through css and by passing in custom sub-components.

CopilotKit also offers **fully custom headless UI**, through the `useCopilotChat` hook. Everything built with the built-in UI (and more) can be implemented with the headless UI, providing deep customizability.

```
import { useCopilotChat } from "@copilotkit/react-core";
import { Role, TextMessage } from "@copilotkit/runtime-client-gql";

export function CustomChatInterface() {
  const {
    visibleMessages,
    appendMessage,
    setMessages,
    deleteMessage,
    reloadMessages,
    stopGeneration,
    isLoading,
  } = useCopilotChat();

  const sendMessage = (content: string) => {
    appendMessage(new TextMessage({ content, role: Role.User }));
  };

  return (
    <div>
      {/* Implement your custom chat UI here */}
    </div>
  );
}
```

* * *

## [Next Steps](https://docs.copilotkit.ai/quickstart?component=Headless%20UI\#next-steps)

🎉 Congrats! You've successfully integrated a fully functional chatbot in your application! Give it a try now and see it in action. Want to
take it further? Learn more about what CopilotKit has to offer!

[**Connecting Your Data** \\
Learn how to connect CopilotKit to your data, application state and user state.](https://docs.copilotkit.ai/guides/connect-your-data) [**Generative UI** \\
Learn how to render custom UI components directly in the CopilotKit chat window.](https://docs.copilotkit.ai/guides/generative-ui) [**Frontend Actions** \\
Learn how to allow your copilot to take applications on frontend.](https://docs.copilotkit.ai/guides/frontend-actions) [**CoAgents (LangGraph)** \\
Check out our section about CoAgents, our approach to building agentic copilots and experiences.](https://docs.copilotkit.ai/coagents)

[Previous\\
\\
Introduction](https://docs.copilotkit.ai/) [Next\\
\\
Customize UI](https://docs.copilotkit.ai/guides/custom-look-and-feel)

### On this page

[Install CopilotKit](https://docs.copilotkit.ai/quickstart?component=Headless%20UI#install-copilotkit) [Get a Copilot Cloud Public API Key](https://docs.copilotkit.ai/quickstart?component=Headless%20UI#get-a-copilot-cloud-public-api-key) [Setup the CopilotKit Provider](https://docs.copilotkit.ai/quickstart?component=Headless%20UI#setup-the-copilotkit-provider) [Choose a Copilot UI](https://docs.copilotkit.ai/quickstart?component=Headless%20UI#choose-a-copilot-ui) [Install CopilotKit](https://docs.copilotkit.ai/quickstart?component=Headless%20UI#install-copilotkit-1) [Set up a Copilot Runtime Endpoint](https://docs.copilotkit.ai/quickstart?component=Headless%20UI#set-up-a-copilot-runtime-endpoint) [Configure the CopilotKit Provider](https://docs.copilotkit.ai/quickstart?component=Headless%20UI#configure-the-copilotkit-provider) [Choose a Copilot UI](https://docs.copilotkit.ai/quickstart?component=Headless%20UI#choose-a-copilot-ui-1) [Next Steps](https://docs.copilotkit.ai/quickstart?component=Headless%20UI#next-steps)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/quickstart.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Customize AI Assistant
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageAppending to the prompt (Recommended)

# Customize Instructions

Learn how to customize the behavior of your AI assistant.

There are three main ways to customize the behavior of your AI assistant:

- [Appending to the prompt](https://docs.copilotkit.ai/guides/custom-ai-assistant-behavior#appending-to-the-prompt-recommended)
- [Passing the `instructions` parameter](https://docs.copilotkit.ai/guides/custom-ai-assistant-behavior#passing-the-instructions-parameter)
- [Overwriting the default `makeSystemMessage`)](https://docs.copilotkit.ai/guides/custom-ai-assistant-behavior#overwriting-the-default-makesystemmessage-not-recommended)

## [Appending to the prompt (Recommended)](https://docs.copilotkit.ai/guides/custom-ai-assistant-behavior\#appending-to-the-prompt-recommended)

CopilotKit provides the [useCopilotAdditionalInstructions](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAdditionalInstructions) hook which allows you to add content to the prompt with whatever
you want.

Home.tsx

```
import { CopilotKit, useCopilotAdditionalInstructions } from "@copilotkit/react-core";
import { CopilotPopup } from "@copilotkit/react-ui"

function Chat() {
  useCopilotAdditionalInstructions({
    instructions: "Do not answer questions about the weather.",
  });
  return <CopilotPopup />
}

export function Home() {
  return (
    <CopilotKit>
      <Chat />
    </CopilotKit>
  )
}
```

You can even conditionally add instructions based on the application's state.

Home.tsx

```
function Chat() {
  const [showWeather, setShowWeather] = useState(false);

  useCopilotAdditionalInstructions({
    instructions: "Do not answer questions about the weather.",
    available: showWeather ? "enabled" : "disabled"
  }, showWeather);
}
```

## [Advanced](https://docs.copilotkit.ai/guides/custom-ai-assistant-behavior\#advanced)

If appending to the prompt is not enough, you have some other options, specifically around updating the prompt directly.

### [Passing the `instructions` parameter](https://docs.copilotkit.ai/guides/custom-ai-assistant-behavior\#passing-the-instructions-parameter)

The `instructions` parameter is the recommended way to customize AI assistant behavior. It will remain compatible with performance optimizations to the CopilotKit platform.

It can be customized for **Copilot UI** as well as **programmatically**:

Copilot UIHeadless UI

Copilot UI components accept an `instructions` property:

CustomCopilot.tsx

```
import { CopilotChat } from "@copilotkit/react-ui";

<CopilotChat
  instructions="You are a helpful assistant specializing in tax preparation. Provide concise and accurate answers to tax-related questions."
  labels={{
    title: "Tax Preparation Assistant",
    initial: "How can I help you with your tax preparation today?",
  }}
/>
```

### [Overwriting the default system message](https://docs.copilotkit.ai/guides/custom-ai-assistant-behavior\#overwriting-the-default-system-message)

For cases requiring complete control over the system message, you can use the `makeSystemMessage` function. We highly recommend reading CopilotKit's default system message before deciding to overwrite it, which can be found [here](https://github.com/CopilotKit/CopilotKit/blob/e48a34a66bb4dfd210e93dc41eee7d0f22d1a0c4/CopilotKit/packages/react-core/src/hooks/use-copilot-chat.ts#L240-L258).

This approach is **not recommended** as it may interfere with more advanced optimizations made by CopilotKit. **Only use this approach if the other options are not enough.**

Copilot UIHeadless UI

```
import { CopilotChat } from "@copilotkit/react-ui";

const CustomCopilot: React.FC = () => (
  <CopilotChat
    instructions="You are a knowledgeable tax preparation assistant. Provide accurate and concise answers to tax-related questions, guiding users through the tax filing process."
    labels={{
      title: "Tax Preparation Assistant",
      initial: "How can I assist you with your taxes today?",
    }}
    makeSystemMessage={myCustomTaxSystemMessage}
  />
);
```

[Previous\\
\\
Remote Endpoint (LangGraph Platform)](https://docs.copilotkit.ai/guides/backend-actions/langgraph-platform-endpoint) [Next\\
\\
Authenticated Actions](https://docs.copilotkit.ai/guides/authenticated-actions)

### On this page

[Appending to the prompt (Recommended)](https://docs.copilotkit.ai/guides/custom-ai-assistant-behavior#appending-to-the-prompt-recommended) [Advanced](https://docs.copilotkit.ai/guides/custom-ai-assistant-behavior#advanced) [Passing the instructions parameter](https://docs.copilotkit.ai/guides/custom-ai-assistant-behavior#passing-the-instructions-parameter) [Overwriting the default system message](https://docs.copilotkit.ai/guides/custom-ai-assistant-behavior#overwriting-the-default-system-message)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/custom-ai-assistant-behavior.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Loading Agent State
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageSetting the threadId

Persistence

# Loading Agent State

Learn how threadId is used to load previous agent states.

### [Setting the threadId](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state\#setting-the-threadid)

When setting the `threadId` property in CopilotKit, i.e:

When using LangGraph platform, the `threadId` must be a UUID.

```
<CopilotKit threadId="2140b272-7180-410d-9526-f66210918b13">
  <YourApp />
</CopilotKit>
```

CopilotKit will restore the complete state of the thread, including the messages, from the database. (See [Message Persistence](https://docs.copilotkit.ai/coagents/persistence/message-persistence) for more details.)

### [Loading Agent State](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state\#loading-agent-state)

This means that the state of any agent will also be restored. For example:

```
const { state } = useCoAgent({name: "research_agent"});

// state will now be the state of research_agent in the thread id given above
```

### [Learn More](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state\#learn-more)

To learn more about persistence and state in CopilotKit, see:

- [Reading agent state](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read)
- [Writing agent state](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write)
- [Loading Message History](https://docs.copilotkit.ai/coagents/persistence/loading-message-history)

[Previous\\
\\
Multi-Agent Flows](https://docs.copilotkit.ai/coagents/multi-agent-flows) [Next\\
\\
Threads](https://docs.copilotkit.ai/coagents/persistence/loading-message-history)

### On this page

[Setting the threadId](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state#setting-the-threadid) [Loading Agent State](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state#loading-agent-state) [Learn More](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state#learn-more)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/persistence/loading-agent-state.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## OpenAIAdapter Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageExample

LLM Adapters

# OpenAIAdapter

Copilot Runtime adapter for OpenAI.

Copilot Runtime adapter for OpenAI.

## [Example](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAdapter\#example)

```
import { CopilotRuntime, OpenAIAdapter } from "@copilotkit/runtime";
import OpenAI from "openai";

const copilotKit = new CopilotRuntime();

const openai = new OpenAI({
  organization: "<your-organization-id>", // optional
  apiKey: "<your-api-key>",
});

return new OpenAIAdapter({ openai });
```

## [Example with Azure OpenAI](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAdapter\#example-with-azure-openai)

```
import { CopilotRuntime, OpenAIAdapter } from "@copilotkit/runtime";
import OpenAI from "openai";

// The name of your Azure OpenAI Instance.
// https://learn.microsoft.com/en-us/azure/cognitive-services/openai/how-to/create-resource?pivots=web-portal#create-a-resource
const instance = "<your instance name>";

// Corresponds to your Model deployment within your OpenAI resource, e.g. my-gpt35-16k-deployment
// Navigate to the Azure OpenAI Studio to deploy a model.
const model = "<your model>";

const apiKey = process.env["AZURE_OPENAI_API_KEY"];
if (!apiKey) {
  throw new Error("The AZURE_OPENAI_API_KEY environment variable is missing or empty.");
}

const copilotKit = new CopilotRuntime();

const openai = new OpenAI({
  apiKey,
  baseURL: `https://${instance}.openai.azure.com/openai/deployments/${model}`,
  defaultQuery: { "api-version": "2024-04-01-preview" },
  defaultHeaders: { "api-key": apiKey },
});

return new OpenAIAdapter({ openai });
```

## [Constructor Parameters](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAdapter\#constructor-parameters)

openaiOpenAI

An optional OpenAI instance to use. If not provided, a new instance will be
created.

modelstring

The model to use.

disableParallelToolCallsboolean

Default:"false"

Whether to disable parallel tool calls.
You can disable parallel tool calls to force the model to execute tool calls sequentially.
This is useful if you want to execute tool calls in a specific order so that the state changes
introduced by one tool call are visible to the next tool call. (i.e. new actions or readables)

[Previous\\
\\
CopilotRuntime](https://docs.copilotkit.ai/reference/v1/classes/CopilotRuntime) [Next\\
\\
OpenAIAssistantAdapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAssistantAdapter)

### On this page

[Example](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAdapter#example) [Example with Azure OpenAI](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAdapter#example-with-azure-openai) [Constructor Parameters](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAdapter#constructor-parameters)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/v1/classes/llm-adapters/OpenAIAdapter.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## GroqAdapter Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageExample

LLM Adapters

# GroqAdapter

Copilot Runtime adapter for Groq.

Copilot Runtime adapter for Groq.

## [Example](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/GroqAdapter\#example)

```
import { CopilotRuntime, GroqAdapter } from "@copilotkit/runtime";
import { Groq } from "groq-sdk";

const groq = new Groq({ apiKey: process.env["GROQ_API_KEY"] });

const copilotKit = new CopilotRuntime();

return new GroqAdapter({ groq, model: "<model-name>" });
```

## [Constructor Parameters](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/GroqAdapter\#constructor-parameters)

groqGroq

An optional Groq instance to use.

modelstring

The model to use.

disableParallelToolCallsboolean

Default:"false"

Whether to disable parallel tool calls.
You can disable parallel tool calls to force the model to execute tool calls sequentially.
This is useful if you want to execute tool calls in a specific order so that the state changes
introduced by one tool call are visible to the next tool call. (i.e. new actions or readables)

[Previous\\
\\
LangChainAdapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/LangChainAdapter) [Next\\
\\
GoogleGenerativeAIAdapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/GoogleGenerativeAIAdapter)

### On this page

[Example](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/GroqAdapter#example) [Constructor Parameters](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/GroqAdapter#constructor-parameters)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/v1/classes/llm-adapters/GroqAdapter.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## OpenAI Assistant Adapter
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageExample

LLM Adapters

# OpenAIAssistantAdapter

Copilot Runtime adapter for OpenAI Assistant API.

Copilot Runtime adapter for the OpenAI Assistant API.

## [Example](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAssistantAdapter\#example)

```
import { CopilotRuntime, OpenAIAssistantAdapter } from "@copilotkit/runtime";
import OpenAI from "openai";

const copilotKit = new CopilotRuntime();

const openai = new OpenAI({
  organization: "<your-organization-id>",
  apiKey: "<your-api-key>",
});

return new OpenAIAssistantAdapter({
  openai,
  assistantId: "<your-assistant-id>",
  codeInterpreterEnabled: true,
  fileSearchEnabled: true,
});
```

## [Constructor Parameters](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAssistantAdapter\#constructor-parameters)

assistantIdstringrequired

The ID of the assistant to use.

openaiOpenAI

An optional OpenAI instance to use. If not provided, a new instance will be created.

codeInterpreterEnabledboolean

Default:"true"

Whether to enable code interpretation.

fileSearchEnabledboolean

Default:"true"

Whether to enable file search.

disableParallelToolCallsboolean

Default:"false"

Whether to disable parallel tool calls.
You can disable parallel tool calls to force the model to execute tool calls sequentially.
This is useful if you want to execute tool calls in a specific order so that the state changes
introduced by one tool call are visible to the next tool call. (i.e. new actions or readables)

[Previous\\
\\
OpenAIAdapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAdapter) [Next\\
\\
AnthropicAdapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/AnthropicAdapter)

### On this page

[Example](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAssistantAdapter#example) [Constructor Parameters](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/OpenAIAssistantAdapter#constructor-parameters)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/v1/classes/llm-adapters/OpenAIAssistantAdapter.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## LangChainAdapter Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageExample

LLM Adapters

# LangChainAdapter

Copilot Runtime adapter for LangChain.

Copilot Runtime adapter for LangChain.

## [Example](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/LangChainAdapter\#example)

```
import { CopilotRuntime, LangChainAdapter } from "@copilotkit/runtime";
import { ChatOpenAI } from "@langchain/openai";

const copilotKit = new CopilotRuntime();

const model = new ChatOpenAI({
  model: "gpt-4o",
  apiKey: "<your-api-key>",
});

return new LangChainAdapter({
  chainFn: async ({ messages, tools }) => {
    return model.bindTools(tools).stream(messages);
    // or optionally enable strict mode
    // return model.bindTools(tools, { strict: true }).stream(messages);
  }
});
```

The asynchronous handler function ( `chainFn`) can return any of the following:

- A simple `string` response
- A LangChain stream ( `IterableReadableStream`)
- A LangChain `BaseMessageChunk` object
- A LangChain `AIMessage` object

## [Constructor Parameters](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/LangChainAdapter\#constructor-parameters)

chainFn(parameters: ChainFnParameters) => Promise<LangChainReturnType>required

A function that uses the LangChain API to generate a response.

[Previous\\
\\
AnthropicAdapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/AnthropicAdapter) [Next\\
\\
GroqAdapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/GroqAdapter)

### On this page

[Example](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/LangChainAdapter#example) [Constructor Parameters](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/LangChainAdapter#constructor-parameters)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/v1/classes/llm-adapters/LangChainAdapter.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Loading Agent State
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageSetting the threadId

Persistence

# Loading Agent State

Learn how threadId is used to load previous agent states.

### [Setting the threadId](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state\#setting-the-threadid)

When setting the `threadId` property in CopilotKit, i.e:

When using LangGraph platform, the `threadId` must be a UUID.

```
<CopilotKit threadId="2140b272-7180-410d-9526-f66210918b13">
  <YourApp />
</CopilotKit>
```

CopilotKit will restore the complete state of the thread, including the messages, from the database. (See [Message Persistence](https://docs.copilotkit.ai/coagents/persistence/message-persistence) for more details.)

### [Loading Agent State](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state\#loading-agent-state)

This means that the state of any agent will also be restored. For example:

```
const { state } = useCoAgent({name: "research_agent"});

// state will now be the state of research_agent in the thread id given above
```

### [Learn More](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state\#learn-more)

To learn more about persistence and state in CopilotKit, see:

- [Reading agent state](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read)
- [Writing agent state](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write)
- [Loading Message History](https://docs.copilotkit.ai/coagents/persistence/loading-message-history)

[Previous\\
\\
Multi-Agent Flows](https://docs.copilotkit.ai/coagents/multi-agent-flows) [Next\\
\\
Threads](https://docs.copilotkit.ai/coagents/persistence/loading-message-history)

### On this page

[Setting the threadId](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state#setting-the-threadid) [Loading Agent State](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state#loading-agent-state) [Learn More](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state#learn-more)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/persistence/loading-agent-state.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotKit Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is CopilotKit?

# Introduction

Build production-ready Copilots and Agents effortlessly.

# [What is CopilotKit?](https://docs.copilotkit.ai/?ref=github_readme\#what-is-copilotkit)

At its core, CopilotKit is a set of tools that make it easy to **let your users work**
**alongside Large Language Models (LLMs) to accomplish generative tasks** directly in
your application. Instead of just using the LLM to generate content, you can let it
take direct action alongside your users.

Interacting with these models can be done directly ( **Standard**) or through agents ( **CoAgents**).

## [Standard](https://docs.copilotkit.ai/?ref=github_readme\#standard)

Utilize CopilotKit's standard agentic runloop to get started quickly.

[**Quickstart** \\
Get started with CopilotKit directly in your application.](https://docs.copilotkit.ai/quickstart) [**Tutorial** \\
Build an AI todo app with CopilotKit in minutes.](https://docs.copilotkit.ai/tutorials/ai-todo-app/overview)

## [CoAgents](https://docs.copilotkit.ai/?ref=github_readme\#coagents)

When you need **complete control** over the agentic runloop, you can use **CoAgents**. Bridge the remaining gap between demos and production-ready experiences.

[**LangGraph** \\
User-interactive agents with LangGraph.](https://docs.copilotkit.ai/coagents) [CrewAI\\
**CrewAI Crews** \\
Build multi-agent workflows with CrewAI.](https://docs.copilotkit.ai/crewai-crews) [CrewAI\\
**CrewAI Flows** \\
Build multi-agent workflows with CrewAI.](https://docs.copilotkit.ai/crewai-flows)

## [CopilotKit in Action](https://docs.copilotkit.ai/?ref=github_readme\#copilotkit-in-action)

Need some inspiration? Check out somethings we've built with CopilotKit.

[**Feature Viewer** \\
Learn about all of the best features CopilotKit has to offer with an interactive experience.](https://feature-viewer-langgraph.vercel.app/) [**Spreadsheet Copilot** \\
A powerful spreadsheet assistant that helps users analyze data, create formulas, and generate insights.](https://spreadsheet-demo-tau.vercel.app/) [**SaaS Copilot** \\
An AI-powered banking interface that helps users understand and interact with their finances.](https://brex-demo-temp.vercel.app/) [**Agent-Native Travel Planner** \\
Interactive travel planning assistant that helps users generate and build travel itineraries.](https://examples-coagents-ai-travel-app.vercel.app/) [**Agent-Native Research Canvas** \\
An intelligent research assistant that helps users synthesize information across multiple sources.](https://examples-coagents-research-canvas-ui.vercel.app/)

## [How does CopilotKit work?](https://docs.copilotkit.ai/?ref=github_readme\#how-does-copilotkit-work)

CopilotKit is thoughtfully architected to scale with you, your teams, and your product.

![](https://docs.copilotkit.ai/_next/image?url=%2Fimages%2Farchitecture-diagram.png&w=3840&q=75)

## [Common Questions](https://docs.copilotkit.ai/?ref=github_readme\#common-questions)

We've got answers to some common questions!

### What is a Copilot?

### What are the main features of CopilotKit?

### How does it all work?

### Can I use any LLM with CopilotKit?

[Next\\
\\
Quickstart](https://docs.copilotkit.ai/quickstart)

### On this page

[What is CopilotKit?](https://docs.copilotkit.ai/?ref=github_readme#what-is-copilotkit) [Standard](https://docs.copilotkit.ai/?ref=github_readme#standard) [CoAgents](https://docs.copilotkit.ai/?ref=github_readme#coagents) [CopilotKit in Action](https://docs.copilotkit.ai/?ref=github_readme#copilotkit-in-action) [How does CopilotKit work?](https://docs.copilotkit.ai/?ref=github_readme#how-does-copilotkit-work) [Common Questions](https://docs.copilotkit.ai/?ref=github_readme#common-questions) [Concierge](https://docs.copilotkit.ai/?ref=github_readme#concierge) [Worker](https://docs.copilotkit.ai/?ref=github_readme#worker) [Batteries included chat components](https://docs.copilotkit.ai/?ref=github_readme#batteries-included-chat-components) [Deeply integrated Copilots](https://docs.copilotkit.ai/?ref=github_readme#deeply-integrated-copilots) [Rich agentic experiences](https://docs.copilotkit.ai/?ref=github_readme#rich-agentic-experiences)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Google Generative AI
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageExample

LLM Adapters

# GoogleGenerativeAIAdapter

Copilot Runtime adapter for Google Generative AI (e.g. Gemini).

Copilot Runtime adapter for Google Generative AI (e.g. Gemini).

## [Example](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/GoogleGenerativeAIAdapter\#example)

```
import { CopilotRuntime, GoogleGenerativeAIAdapter } from "@copilotkit/runtime";
const { GoogleGenerativeAI } = require("@google/generative-ai");

const genAI = new GoogleGenerativeAI(process.env["GOOGLE_API_KEY"]);

const copilotKit = new CopilotRuntime();

return new GoogleGenerativeAIAdapter({ model: "gemini-1.5-pro" });
```

## [Constructor Parameters](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/GoogleGenerativeAIAdapter\#constructor-parameters)

modelstring

A custom Google Generative AI model to use.

[Previous\\
\\
GroqAdapter](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/GroqAdapter) [Next\\
\\
CopilotTask](https://docs.copilotkit.ai/reference/v1/classes/CopilotTask)

### On this page

[Example](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/GoogleGenerativeAIAdapter#example) [Constructor Parameters](https://docs.copilotkit.ai/reference/v1/classes/llm-adapters/GoogleGenerativeAIAdapter#constructor-parameters)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/v1/classes/llm-adapters/GoogleGenerativeAIAdapter.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CrewAI Documentation
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageCopilot Infrastructure for CrewAI Crews

# Introduction

Build Agent-Native Applications (ANAs) powered by CopilotKit and CrewAI Flows.

# [Copilot Infrastructure for CrewAI Crews](https://docs.copilotkit.ai/crewai-crews?ref=blog.crewai.com\#copilot-infrastructure-for-crewai-crews)

Full user-interaction infrastructure for your agents, to turn your agents into Copilot Agents (CoAgents).

## [Building blocks of a CoAgent](https://docs.copilotkit.ai/crewai-crews?ref=blog.crewai.com\#building-blocks-of-a-coagent)

Everything you need to build Agent-Native Applications (ANAs), right out of the box.

[Agentic Chat UI\\
\\
In-app chat powered by your agent.](https://docs.copilotkit.ai/crewai-crews/agentic-chat-ui)

[Shared State\\
\\
Your agent can see everything in your app, and vice versa.](https://docs.copilotkit.ai/crewai-crews/shared-state)

[Generative UI\\
\\
UI that updates in real-time based on your agent's state.](https://docs.copilotkit.ai/crewai-crews/generative-ui)

[Frontend Tools\\
\\
Give your agent the ability to take action in your application.](https://docs.copilotkit.ai/crewai-crews/frontend-actions)

[Multi-Agent Coordination\\
\\
Route your agent to the right agent based on the user's request.](https://docs.copilotkit.ai/crewai-crews/multi-agent-flows)

[Human-in-the-Loop\\
\\
Set smart checkpoints where humans can guide your agents.](https://docs.copilotkit.ai/crewai-crews/human-in-the-loop)

## [Ready to get started?](https://docs.copilotkit.ai/crewai-crews?ref=blog.crewai.com\#ready-to-get-started)

Get started with CoAgents in as little as 5 minutes with one of our guides or tutorials.

[Quickstart\\
\\
Learn how to build your first CoAgent in 10 minutes.](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai)

## [Common Questions](https://docs.copilotkit.ai/crewai-crews?ref=blog.crewai.com\#common-questions)

Have a question about CoAgents? You're in the right place!

### Can you explain what a CoAgent is in more detail?

[Next\\
\\
Quickstart CrewAI Crews](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai)

### On this page

[Copilot Infrastructure for CrewAI Crews](https://docs.copilotkit.ai/crewai-crews?ref=blog.crewai.com#copilot-infrastructure-for-crewai-crews) [Building blocks of a CoAgent](https://docs.copilotkit.ai/crewai-crews?ref=blog.crewai.com#building-blocks-of-a-coagent) [Ready to get started?](https://docs.copilotkit.ai/crewai-crews?ref=blog.crewai.com#ready-to-get-started) [Common Questions](https://docs.copilotkit.ai/crewai-crews?ref=blog.crewai.com#common-questions)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/crewai-crews/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Agent State Management
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is this?

[Shared State](https://docs.copilotkit.ai/coagents/shared-state)

# Agent state inputs and outputs

Decide which state properties are received and returned to the frontend

## [What is this?](https://docs.copilotkit.ai/coagents/shared-state/workflow-execution\#what-is-this)

Not all state properties are relevant for frontend-backend sharing.
This guide shows how to ensure only the right portion of state is communicated back and forth.

This guide is based on [LangGraph's Input/Output Schema feature](https://docs.langchain.com/oss/python/langgraph/use-graph-api#define-input-and-output-schemas)

## [When should I use this?](https://docs.copilotkit.ai/coagents/shared-state/workflow-execution\#when-should-i-use-this)

Depending on your implementation, some properties are meant to be processed internally, while some others are the way for the UI to communicate user input.
In addition, some state properties contain a lot of information. Syncing them back and forth between the agent and UI can be costly, while it might not have any practical benefit.

## [Implementation](https://docs.copilotkit.ai/coagents/shared-state/workflow-execution\#implementation)

### [Examine our old state](https://docs.copilotkit.ai/coagents/shared-state/workflow-execution\#examine-our-old-state)

LangGraph is stateful. As you transition between nodes, that state is updated and passed to the next node. For this example,
let's assume that the state our agent should be using, can be described like this:

PythonTypeScript

agent-py/sample\_agent/agent.py

```
from copilotkit import CopilotKitState
from typing import Literal

class AgentState(CopilotKitState):
    question: str
    answer: str
    resources: List[str]
```

### [Divide state to Input and Output](https://docs.copilotkit.ai/coagents/shared-state/workflow-execution\#divide-state-to-input-and-output)

Our example case lists several state properties, which with its own purpose:

- The question is being asked by the user, expecting the llm to answer
- The answer is what the LLM returns
- The resources list will be used by the LLM to answer the question, and should not be communicated to the user, or set by them.

PythonTypeScript

agent-py/sample\_agent/agent.py

```
from copilotkit import CopilotKitState
from typing import Literal

# Divide the state to 3 parts

# Input schema for inputs you are willing to accept from the frontend
class InputState(CopilotKitState):
  question: str

# Output schema for output you are willing to pass to the frontend
class OutputState(CopilotKitState):
  answer: str

# The full schema, including the inputs, outputs and internal state ("resources" in our case)
class OverallState(InputState, OutputState):
  resources: List[str]

async def answer_node(state: OverallState, config: RunnableConfig):
  """
  Standard chat node, meant to answer general questions.
  """

  model = ChatOpenAI()

  # add the input question in the system prompt so it's passed to the LLM
  system_message = SystemMessage(
    content=f"You are a helpful assistant. Answer the question: {state.get('question')}"
  )

  response = await model.ainvoke([\
    system_message,\
    *state["messages"],\
  ], config)

  # ...add the rest of the agent implementation

  # extract the answer, which will be assigned to the state soon
  answer = response.content

  return {
     "messages": response,
      # include the answer in the returned state
     "answer": answer
  }


# finally, before compiling the graph, we define the 3 state components
builder = StateGraph(OverallState, input=InputState, output=OutputState)

# add all the different nodes and edges and compile the graph
builder.add_node("answer_node", answer_node)
builder.add_edge(START, "answer_node")
builder.add_edge("answer_node", END)
graph = builder.compile()
```

### [Give it a try!](https://docs.copilotkit.ai/coagents/shared-state/workflow-execution\#give-it-a-try)

Now that we know which state properties our agent emits, we can inspect the state and expect the following to happen:

- While we are able to provide a question, we will not receive it back from the agent. If we are using it in our UI, we need to remember the UI is the source of truth for it
- Answer will change once it's returned back from the agent
- The UI has no access to resources.

```
import { useCoAgent } from "@copilotkit/react-core";

type AgentState = {
  question: string;
  answer: string;
}

const { state } = useCoAgent<AgentState>({
  name: "sample_agent",
  initialState: {
    question: "How's the weather in SF?",
  }
});

console.log(state) // You can expect seeing "answer" change, while the others are not returned from the agent
```

[Previous\\
\\
Writing agent state](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write) [Next\\
\\
Predictive state updates](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates)

### On this page

[What is this?](https://docs.copilotkit.ai/coagents/shared-state/workflow-execution#what-is-this) [When should I use this?](https://docs.copilotkit.ai/coagents/shared-state/workflow-execution#when-should-i-use-this) [Implementation](https://docs.copilotkit.ai/coagents/shared-state/workflow-execution#implementation) [Examine our old state](https://docs.copilotkit.ai/coagents/shared-state/workflow-execution#examine-our-old-state) [Divide state to Input and Output](https://docs.copilotkit.ai/coagents/shared-state/workflow-execution#divide-state-to-input-and-output) [Give it a try!](https://docs.copilotkit.ai/coagents/shared-state/workflow-execution#give-it-a-try)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/shared-state/workflow-execution.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Predictive State Updates
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is this?

[Shared State](https://docs.copilotkit.ai/coagents/shared-state)

# Predictive state updates

Stream in-progress agent state updates to the frontend.

This video shows the [coagents starter](https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter) repo with the [implementation](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates#implementation) section applied to it!

## [What is this?](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates\#what-is-this)

A LangGraph agent's state updates discontinuosly; only across node transitions in the graph.
But even a _single node_ in the graph often takes many seconds to run and contain sub-steps of interest to the user.

**Agent-native applications** reflect to the end-user what the agent is doing **as continuously possible.**

CopilotKit enables this through its concept of **_predictive state updates_**.

## [When should I use this?](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates\#when-should-i-use-this)

You can use this when you want to provide the user with feedback about what your agent is doing, specifically to:

- **Keep users engaged** by avoiding long loading indicators
- **Build trust** by demonstrating what the agent is working on
- Enable **agent steering** \- allowing users to course-correct the agent if needed

## [Important Note](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates\#important-note)

When a node in your LangGraph finishes executing, **its returned state becomes the single source of truth**. While intermediate state updates are great for real-time feedback, any changes you want to persist must be explicitly included in the node's final returned state. Otherwise, they will be overwritten when the node completes.

## [Implementation](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates\#implementation)

### [Install the CopilotKit SDK](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates\#install-the-copilotkit-sdk)

Any LangGraph agent can be used with CopilotKit. However, creating deep agentic
experiences with CopilotKit requires our LangGraph SDK.

PythonTypeScript

Poetrypipconda

```
poetry add copilotkit
# including support for crewai
poetry add copilotkit[crewai]
```

### [Define the state](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates\#define-the-state)

We'll be defining a `observed_steps` field in the state, which will be updated as the agent writes different sections of the report.

PythonTypeScript

agent-py/sample\_agent/agent.py

```
from copilotkit import CopilotKitState
from typing import Literal

class AgentState(CopilotKitState):
    observed_steps: list[str]  # Array of completed steps
```

### [Emit the intermediate state](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates\#emit-the-intermediate-state)

How would you like to emit state updates?

You can either manually emit state updates or configure specific tool calls to emit updates.

Manual Predictive State Updates

Manually emit state updates for maximum control over when updates occur.

Tool-Based Predictive State Updates

Configure specific tool calls to automatically emit intermediate state updates.

For long-running tasks, you can emit state updates progressively as predictions of the final state. In this example, we simulate a long-running task by executing a series of steps with a one second delay between each update.

PythonTypeScript

agent-py/sample\_agent/agent.py

```
from copilotkit.langgraph import copilotkit_emit_state
# ...
async def chat_node(state: AgentState, config: RunnableConfig) -> Command[Literal["cpk_action_node", "tool_node", "__end__"]]:
    # ...

    # Simulate executing steps one by one
    steps = [\
        "Analyzing input data...",\
        "Identifying key patterns...",\
        "Generating recommendations...",\
        "Formatting final output..."\
    ]

    for step in steps:
        self.state["observed_steps"] = self.state.get("observed_steps", []) + [step]
        await copilotkit_emit_state(config, state)
        await asyncio.sleep(1)

    # ...
```

### [Observe the predictions](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates\#observe-the-predictions)

These predictions will be emitted as the agent runs, allowing you to track its progress before the final state is determined.

ui/app/page.tsx

```
import { useCoAgent, useCoAgentStateRender } from '@copilotkit/react-core';

// ...
type AgentState = {
    observed_steps: string[];
};

const YourMainContent = () => {
    // Get access to both predicted and final states
    const { state } = useCoAgent<AgentState>({ name: "sample_agent" });

    // Add a state renderer to observe predictions
    useCoAgentStateRender({
        name: "sample_agent",
        render: ({ state }) => {
            if (!state.observed_steps?.length) return null;
            return (
                <div>
                    <h3>Current Progress:</h3>
                    <ul>
                        {state.observed_steps.map((step, i) => (
                            <li key={i}>{step}</li>
                        ))}
                    </ul>
                </div>
            );
        },
    });

    return (
        <div>
            <h1>Agent Progress</h1>
            {state.observed_steps?.length > 0 && (
                <div>
                    <h3>Final Steps:</h3>
                    <ul>
                        {state.observed_steps.map((step, i) => (
                            <li key={i}>{step}</li>
                        ))}
                    </ul>
                </div>
            )}
        </div>
    )
}
```

### [Give it a try!](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates\#give-it-a-try)

Now you'll notice that the state predictions are emitted as the agent makes progress, giving you insight into its work before the final state is determined.
You can apply this pattern to any long-running task in your agent.

[Previous\\
\\
Agent state inputs and outputs](https://docs.copilotkit.ai/coagents/shared-state/workflow-execution) [Next\\
\\
Frontend Actions](https://docs.copilotkit.ai/coagents/frontend-actions)

### On this page

[What is this?](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates#what-is-this) [When should I use this?](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates#when-should-i-use-this) [Important Note](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates#important-note) [Implementation](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates#implementation) [Install the CopilotKit SDK](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates#install-the-copilotkit-sdk) [Define the state](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates#define-the-state) [Emit the intermediate state](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates#emit-the-intermediate-state) [Observe the predictions](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates#observe-the-predictions) [Give it a try!](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates#give-it-a-try)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/shared-state/predictive-state-updates.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CopilotKit Migration Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this page

# Migrate to 1.8.2

Migration guide for CopilotKit 1.8.2

## [What's changed?](https://docs.copilotkit.ai/troubleshooting/migrate-to-1.8.2\#whats-changed)

### [New Look and Feel](https://docs.copilotkit.ai/troubleshooting/migrate-to-1.8.2\#new-look-and-feel)

CopilotKit 1.8.2 introduces a new default look and feel. This includes new use of theming variables, new components, and generally a fresh look.

**Click the button in the bottom right to see the new look and feel in action!**

### [Thumbs Up/Down Handlers](https://docs.copilotkit.ai/troubleshooting/migrate-to-1.8.2\#thumbs-updown-handlers)

The chat components now have `onThumbsUp` and `onThumbsDown` handlers. Specifying these will add icons to each message
on hover allowing the user to provide feedback.

```
<CopilotChat
  onThumbsUp={(message) => console.log(message)}
  onThumbsDown={(message) => console.log(message)}
/>
```

This was previously achievable in our framework, but we're making it first class now! You can use this to help fine-tune your model through CopilotKit
or just generally track user feedback.

### [ResponseButton prop removed](https://docs.copilotkit.ai/troubleshooting/migrate-to-1.8.2\#responsebutton-prop-removed)

The `ResponseButton` prop has been removed. This was a prop that was used to customize the button that appears after a response was generated
in the chat.

In its place, we now place buttons below each message for:

- Thumbs up
- Thumbs down
- Copy
- Regenerate

The behvior, icons and styling for each of these buttons can be customized. Checkout our [look and feel guides](https://docs.copilotkit.ai/guides/custom-look-and-feel) for more details.

### [Out-of-the-box dark mode support](https://docs.copilotkit.ai/troubleshooting/migrate-to-1.8.2\#out-of-the-box-dark-mode-support)

CopilotKit now has out-of-the-box dark mode support. This is controlled by the `.dark` class (Tailwind) as well as the
`color-scheme` CSS selector.

If you would like to make a custom theme, you can do so by checking out the [custom look and feel](https://docs.copilotkit.ai/guides/custom-look-and-feel) guides.

CopilotKit

Hey there Let's have a fun conversation!

[Previous\\
\\
Common Issues](https://docs.copilotkit.ai/troubleshooting/common-issues) [Next\\
\\
Code Contributions](https://docs.copilotkit.ai/contributing/code-contributions)

### On this page

[What's changed?](https://docs.copilotkit.ai/troubleshooting/migrate-to-1.8.2#whats-changed) [New Look and Feel](https://docs.copilotkit.ai/troubleshooting/migrate-to-1.8.2#new-look-and-feel) [Thumbs Up/Down Handlers](https://docs.copilotkit.ai/troubleshooting/migrate-to-1.8.2#thumbs-updown-handlers) [ResponseButton prop removed](https://docs.copilotkit.ai/troubleshooting/migrate-to-1.8.2#responsebutton-prop-removed) [Out-of-the-box dark mode support](https://docs.copilotkit.ai/troubleshooting/migrate-to-1.8.2#out-of-the-box-dark-mode-support)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/troubleshooting/migrate-to-1.8.2.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Generative UI Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageRender custom components in the chat UI

# Generative UI

Learn how to embed custom UI components in the chat window.

# [Render custom components in the chat UI](https://docs.copilotkit.ai/guides/generative-ui?ref=hackernoon.com\#render-custom-components-in-the-chat-ui)

When a user interacts with your Copilot, you may want to render a custom UI component. [`useCopilotAction`](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction) allows to give the LLM the
option to render your custom component through the `render` property.

Render a componentFetch data & renderrenderAndWaitForResponse (HITL)Render stringsCatch all renders

[`useCopilotAction`](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction) can be used with a `render` function and without a `handler` to display information or UI elements within the chat.

Here's an example to render a calendar meeting.

![Example of render-only Copilot action](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/render-only-example.png)

```
"use client" // only necessary if you are using Next.js with the App Router.
import { useCopilotAction } from "@copilotkit/react-core";

export function YourComponent() {
  useCopilotAction({
    name: "showCalendarMeeting",
    description: "Displays calendar meeting information",
    parameters: [\
      {\
        name: "date",\
        type: "string",\
        description: "Meeting date (YYYY-MM-DD)",\
        required: true\
      },\
      {\
        name: "time",\
        type: "string",\
        description: "Meeting time (HH:mm)",\
        required: true\
      },\
      {\
        name: "meetingName",\
        type: "string",\
        description: "Name of the meeting",\
        required: false\
      }\
    ],

    render: ({ status, args }) => {
      const { date, time, meetingName } = args;

      if (status === 'inProgress') {
        return <LoadingView />; // Your own component for loading state
      } else {
        const meetingProps: CalendarMeetingCardProps = {
          date: date,
          time,
          meetingName
        };
        return <CalendarMeetingCardComponent {...meetingProps} />;
      }
    },
  });

  return (
    <>...</>
  );
}
```

### What do the different status states mean?

### Why do I need "use client" in Next.js with the App Router?

## [Test it out!](https://docs.copilotkit.ai/guides/generative-ui?ref=hackernoon.com\#test-it-out)

After defining the action with a render method, ask the copilot to perform the task. For example, you can now ask the copilot to "show tasks" and see the custom UI component rendered in the chat interface.

You can read more about the `useCopilotAction` hook
[here](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAction).

[Previous\\
\\
Backend Data](https://docs.copilotkit.ai/guides/connect-your-data/backend) [Next\\
\\
Frontend Actions](https://docs.copilotkit.ai/guides/frontend-actions)

### On this page

[Render custom components in the chat UI](https://docs.copilotkit.ai/guides/generative-ui?ref=hackernoon.com#render-custom-components-in-the-chat-ui) [Test it out!](https://docs.copilotkit.ai/guides/generative-ui?ref=hackernoon.com#test-it-out)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/generative-ui.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Agentic Generative UI
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is this?

[Generative UI](https://docs.copilotkit.ai/coagents/generative-ui)

# Agentic Generative UI

Render the state of your agent with custom UI components.

This video demonstrates the [implementation](https://docs.copilotkit.ai/coagents/generative-ui/agentic#implementation) section applied to our [coagents starter project](https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter).

## [What is this?](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#what-is-this)

All LangGraph agents are stateful. This means that as your agent progresses through nodes, a state object is passed between them perserving
the overall state of a session. CopilotKit allows you to render this state in your application with custom UI components, which we call **Agentic Generative UI**.

## [When should I use this?](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#when-should-i-use-this)

Rendering the state of your agent in the UI is useful when you want to provide the user with feedback about the overall state of a session. A great example of this
is a situation where a user and an agent are working together to solve a problem. The agent can store a draft in its state which is then rendered in the UI.

## [Implementation](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#implementation)

### [Run and Connect your LangGraph to CopilotKit](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#run-and-connect-your-langgraph-to-copilotkit)

First, you'll need to make sure you have a running LangGraph. If you haven't already done this, you can follow the [getting started guide](https://docs.copilotkit.ai/coagents/quickstart/langgraph)

This guide uses the [CoAgents starter repo](https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter) as its starting point.

### [Define your agent state](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#define-your-agent-state)

If you're not familiar with LangGraph, your graphs are stateful. As you progress through nodes, a state object is passed between them. CopilotKit
allows you to easily render this state in your application.

For the sake of this guide, let's say our state looks like this in our agent.

PythonTypeScript

agent-py/sample\_agent/agent.py

```
# ...
from copilotkit import CopilotKitState # extends MessagesState
# ...

# This is the state of the agent.
# It inherits from the CopilotKitState properties from CopilotKit.
class AgentState(CopilotKitState):
    searches: list[dict]
```

### [Simulate state updates](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#simulate-state-updates)

Next, let's write some logic into our agent that will simulate state updates occurring.

PythonTypeScript

agent-py/sample\_agent/agent.py

```
import asyncio
from typing import TypedDict
from langchain_core.runnables import RunnableConfig
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage
from copilotkit import CopilotKitState
from copilotkit.langgraph import copilotkit_emit_state

class Searches(TypedDict):
    query: str
    done: bool

class AgentState(CopilotKitState):
    searches: list[Searches] = []

async def chat_node(state: AgentState, config: RunnableConfig):
    state["searches"] = [\
        {"query": "Initial research", "done": False},\
        {"query": "Retrieving sources", "done": False},\
        {"query": "Forming an answer", "done": False},\
    ]
    await copilotkit_emit_state(config, state)

    # Simulate state updates
    for search in state["searches"]:
        await asyncio.sleep(1)
        search["done"] = True
        await copilotkit_emit_state(config, state)

    # Run the model to generate a response
    response = await ChatOpenAI(model="gpt-4o").ainvoke([\
        SystemMessage(content="You are a helpful assistant."),\
        *state["messages"],\
    ], config)
```

### [Render state of the agent in the chat](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#render-state-of-the-agent-in-the-chat)

Now we can utilize `useCoAgentStateRender` to render the state of our agent **in the chat**.

app/page.tsx

```
// ...
import { useCoAgentStateRender } from "@copilotkit/react-core";
// ...

// Define the state of the agent, should match the state of the agent in your LangGraph.
type AgentState = {
  searches: {
    query: string;
    done: boolean;
  }[];
};

function YourMainContent() {
  // ...


  // styles omitted for brevity
  useCoAgentStateRender<AgentState>({
    name: "sample_agent", // the name the agent is served as
    render: ({ state }) => (
      <div>
        {state.searches?.map((search, index) => (
          <div key={index}>
            {search.done ? "✅" : "❌"} {search.query}{search.done ? "" : "..."}
          </div>
        ))}
      </div>
    ),
  });

  // ...

  return <div>...</div>;
}
```

### [Render state outside of the chat](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#render-state-outside-of-the-chat)

You can also render the state of your agent **outside of the chat**. This is useful when you want to render the state of your agent anywhere
other than the chat.

app/page.tsx

```
import { useCoAgent } from "@copilotkit/react-core";
// ...

// Define the state of the agent, should match the state of the agent in your LangGraph.
type AgentState = {
  searches: {
    query: string;
    done: boolean;
  }[];
};

function YourMainContent() {
  // ...


  const { state } = useCoAgent<AgentState>({
    name: "sample_agent", // the name the agent is served as
  })

  // ...

  return (
    <div>
      {/* ... */}
      <div className="flex flex-col gap-2 mt-4">

        {state.searches?.map((search, index) => (
          <div key={index} className="flex flex-row">
            {search.done ? "✅" : "❌"} {search.query}
          </div>
        ))}
      </div>
    </div>
  )
}
```

### [Give it a try!](https://docs.copilotkit.ai/coagents/generative-ui/agentic\#give-it-a-try)

You've now created a component that will render the agent's state in the chat.

[Previous\\
\\
Generative UI](https://docs.copilotkit.ai/coagents/generative-ui) [Next\\
\\
Tool-based Generative UI](https://docs.copilotkit.ai/coagents/generative-ui/tool-based)

### On this page

[What is this?](https://docs.copilotkit.ai/coagents/generative-ui/agentic#what-is-this) [When should I use this?](https://docs.copilotkit.ai/coagents/generative-ui/agentic#when-should-i-use-this) [Implementation](https://docs.copilotkit.ai/coagents/generative-ui/agentic#implementation) [Run and Connect your LangGraph to CopilotKit](https://docs.copilotkit.ai/coagents/generative-ui/agentic#run-and-connect-your-langgraph-to-copilotkit) [Define your agent state](https://docs.copilotkit.ai/coagents/generative-ui/agentic#define-your-agent-state) [Simulate state updates](https://docs.copilotkit.ai/coagents/generative-ui/agentic#simulate-state-updates) [Render state of the agent in the chat](https://docs.copilotkit.ai/coagents/generative-ui/agentic#render-state-of-the-agent-in-the-chat) [Render state outside of the chat](https://docs.copilotkit.ai/coagents/generative-ui/agentic#render-state-outside-of-the-chat) [Give it a try!](https://docs.copilotkit.ai/coagents/generative-ui/agentic#give-it-a-try)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/generative-ui/agentic.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## TypeScript Backend Actions
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageModify CopilotRuntime to include TypeScript/Node.js actions

[Backend Actions & Agents](https://docs.copilotkit.ai/guides/backend-actions)

# TypeScript (Node.js)

Implement native backend actions using TypeScript or Node.js in CopilotKit.

### Find your CopilotRuntime

The starting point for this section is the `CopilotRuntime` you set up during quickstart (the CopilotKit backend endpoint).
For a refresher, see [Self-Hosting](https://docs.copilotkit.ai/guides/self-hosting) (or alternatively, revisit the [quickstart](https://docs.copilotkit.ai/quickstart)).

**First, find your `CopilotRuntime` instance in your code.** You can simply search your codebase for `CopilotRuntime`.

If you followed the quickstart, it'll be where you set up the `/api/copilotkit` endpoint.

### [Modify CopilotRuntime to include TypeScript/Node.js actions](https://docs.copilotkit.ai/guides/backend-actions/typescript-backend-actions\#modify-copilotruntime-to-include-typescriptnodejs-actions)

Once you've located your `CopilotRuntime`, you can add TypeScript/Node.js actions by modifying its configuration. Here's how to implement native backend actions:

**Note** that `actions` is not merely an array of actions, but an array **generator**.
This generator takes `properties` and `url` as input.

This means you can **customize which backend actions are made available** according to the current frontend URL, as well as custom properties you can pass from the frontend.

/api/copilotkit/route.ts

```
const runtime = new CopilotRuntime({
  // ... existing configuration
  actions: ({properties, url}) => {
    // Note that actions returns not an array, but an array **generator**.
    // You can use the input parameters to the actions generator to expose different backend actions to the Copilot at different times:
    // `url` is the current URL on the frontend application.
    // `properties` contains custom properties you can pass from the frontend application.

    return [\
      {\
        name: "fetchNameForUserId",\
        description: "Fetches user name from the database for a given ID.",\
        parameters: [\
          {\
            name: "userId",\
            type: "string",\
            description: "The ID of the user to fetch data for.",\
            required: true,\
          },\
        ],\
        handler: async ({userId}: {userId: string}) => {\
          // do something with the userId\
          // return the user data\
          return {\
            name: "Darth Doe",\
          };\
        },\
      },\
    ]
  }
});

// ... rest of your route definition
```

### [Test your implementation](https://docs.copilotkit.ai/guides/backend-actions/typescript-backend-actions\#test-your-implementation)

After adding the action, test it by asking the copilot to perform the task. Observe how it selects the correct task, executes it, and streams back relevant responses.

## [Key Points](https://docs.copilotkit.ai/guides/backend-actions/typescript-backend-actions\#key-points)

- Each action is defined with a name, description, parameters, and a handler function.
- The handler function implements the actual logic of the action and can interact with your backend systems.

By using this method, you can create powerful, context-aware backend actions that integrate seamlessly with your CopilotKit application.

[Previous\\
\\
Backend Actions & Agents](https://docs.copilotkit.ai/guides/backend-actions) [Next\\
\\
LangChain.js](https://docs.copilotkit.ai/guides/backend-actions/langchain-js-backend-actions)

### On this page

[Modify CopilotRuntime to include TypeScript/Node.js actions](https://docs.copilotkit.ai/guides/backend-actions/typescript-backend-actions#modify-copilotruntime-to-include-typescriptnodejs-actions) [Test your implementation](https://docs.copilotkit.ai/guides/backend-actions/typescript-backend-actions#test-your-implementation) [Key Points](https://docs.copilotkit.ai/guides/backend-actions/typescript-backend-actions#key-points)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/backend-actions/typescript-backend-actions.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Tool-based Generative UI
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is this?

[Generative UI](https://docs.copilotkit.ai/crewai-crews/generative-ui)

# Tool-based Generative UI

Render your agent's tool calls with custom UI components.

This video demonstrates the [implementation](https://docs.copilotkit.ai/crewai-crews/generative-ui/tool-based#implementation) section applied
to our [coagents starter\\
project](https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter-crewai-crews).

## [What is this?](https://docs.copilotkit.ai/crewai-crews/generative-ui/tool-based\#what-is-this)

Tools are a way for the LLM to call predefined, typically, deterministic functions. CopilotKit allows you to render these tools in the UI
as a custom component, which we call **Generative UI**.

## [When should I use this?](https://docs.copilotkit.ai/crewai-crews/generative-ui/tool-based\#when-should-i-use-this)

Rendering tools in the UI is useful when you want to provide the user with feedback about what your agent is doing, specifically
when your agent is calling tools. CopilotKit allows you to fully customize how these tools are rendered in the chat.

## [Implementation](https://docs.copilotkit.ai/crewai-crews/generative-ui/tool-based\#implementation)

### [Run and connect your agent](https://docs.copilotkit.ai/crewai-crews/generative-ui/tool-based\#run-and-connect-your-agent)

You'll need to run your agent and connect it to CopilotKit before proceeding. If you haven't done so already,
you can follow the instructions in the [Getting Started](https://docs.copilotkit.ai/crewai-crews/quickstart/crewai) guide.

If you don't already have an agent, you can use the [coagent starter](https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter-crewai-crews) as a starting point
as this guide uses it as a starting point.

### [Render the tool call in your frontend](https://docs.copilotkit.ai/crewai-crews/generative-ui/tool-based\#render-the-tool-call-in-your-frontend)

In the case of CrewAI Crew agents, there is one tool call that indicates that the crew is being executed. It has the same name as the crew. In this example, the crew is named `research_crew`. To display progress of the crew, we just need to add a `useCopilotAction` hook to render the tool call in
the UI.

Important

In order to render a tool call in the UI, the name of the action must match
the name of the tool.

app/page.tsx

```
import { useCopilotAction } from "@copilotkit/react-core";
// ...

const YourMainContent = () => {
  // ...

  useCopilotAction({
    name: "research_crew",
    parameters: [\
      {\
        name: "topic",\
      },\
      {\
        name: "current_year",\
      },\
    ],
    render({ args, status }) {
      return (
        <div className="m-4 p-4 bg-gray-100 rounded shadow">
          <h1 className="text-center text-sm">
            Researching {args.topic} in {args.current_year}{" "}
            {status == "complete" ? "✅" : "⏳"}
          </h1>
        </div>
      );
    },
  });
  // ...
};
```

### [Give it a try!](https://docs.copilotkit.ai/crewai-crews/generative-ui/tool-based\#give-it-a-try)

Try giving the crew enough information to complete the task, i.e. "Research the state of AI in 2025". You should see the custom UI component that we added render the tool call and display the arguments that were passed to the tool.

## [Rendering Arbitrary Tool Calls](https://docs.copilotkit.ai/crewai-crews/generative-ui/tool-based\#rendering-arbitrary-tool-calls)

When working with agents, they may call tools that you haven't explicitly defined UI components for. You can use a catch-all action to render these tool calls:

```
import {
  useCopilotAction,
  CatchAllActionRenderProps,
} from "@copilotkit/react-core";

useCopilotAction({
  name: "*",
  followUp: false,
  render: ({ name, args, status, result }: CatchAllActionRenderProps<[]>) => {
    return (
      <div className="m-4 p-4 bg-gray-100 rounded shadow">
        <h2 className="text-sm font-medium">Tool: {name}</h2>
        <pre className="mt-2 text-xs overflow-auto">
          {JSON.stringify(args, null, 2)}
        </pre>
        {status === "complete" && (
          <div className="mt-2 text-xs text-green-600">✓ Complete</div>
        )}
      </div>
    );
  },
});
```

This will render any tool call that doesn't have a specific UI component defined for it, displaying the tool name, arguments, and completion status.

[Previous\\
\\
Agentic Generative UI](https://docs.copilotkit.ai/crewai-crews/generative-ui/agentic) [Next\\
\\
Human in the Loop (HITL)](https://docs.copilotkit.ai/crewai-crews/human-in-the-loop)

### On this page

[What is this?](https://docs.copilotkit.ai/crewai-crews/generative-ui/tool-based#what-is-this) [When should I use this?](https://docs.copilotkit.ai/crewai-crews/generative-ui/tool-based#when-should-i-use-this) [Implementation](https://docs.copilotkit.ai/crewai-crews/generative-ui/tool-based#implementation) [Run and connect your agent](https://docs.copilotkit.ai/crewai-crews/generative-ui/tool-based#run-and-connect-your-agent) [Render the tool call in your frontend](https://docs.copilotkit.ai/crewai-crews/generative-ui/tool-based#render-the-tool-call-in-your-frontend) [Give it a try!](https://docs.copilotkit.ai/crewai-crews/generative-ui/tool-based#give-it-a-try) [Rendering Arbitrary Tool Calls](https://docs.copilotkit.ai/crewai-crews/generative-ui/tool-based#rendering-arbitrary-tool-calls)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/crewai-crews/generative-ui/tool-based.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## LangGraph Platform Deployment
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageDeploy a Graph to LangGraph Platform

[Backend Actions & Agents](https://docs.copilotkit.ai/guides/backend-actions)

# Remote Endpoint (LangGraph Platform)

Connect your CopilotKit application to an agent deployed on LangGraph Platform.

This guide assumes you've created a LangGraph agent, and have a `langgraph.json` file set up. If you need a quick introduction, check out [this brief example\\
from the LangGraph docs](https://docs.langchain.com/oss/python/langgraph/overview) or follow one of our demos.

## [Deploy a Graph to LangGraph Platform](https://docs.copilotkit.ai/guides/backend-actions/langgraph-platform-endpoint\#deploy-a-graph-to-langgraph-platform)

### [Deploy your agent](https://docs.copilotkit.ai/guides/backend-actions/langgraph-platform-endpoint\#deploy-your-agent)

First, you need to host your agent so that CopilotKit can access it.

Local (LangGraph Studio)Self hosted (FastAPI)LangGraph Platform

For local development, you can use the [LangGraph CLI](https://docs.langchain.com/langsmith/cli) to start a development server and LangGraph studio session.

You will need a [LangSmith account](https://smith.langchain.com/) to use this method.

```
# For Python 3.11 or above
langgraph dev --host localhost --port 8000
```

```
# For TypeScript with Node 18 or above
npx @langchain/langgraph-cli dev --host localhost --port 8000
```

After starting the LangGraph server, the deployment URL will be `http://localhost:8000`.

### Having trouble?

### [Setup your Copilot Runtime](https://docs.copilotkit.ai/guides/backend-actions/langgraph-platform-endpoint\#setup-your-copilot-runtime)

Copilot Cloud (Recommended)

I'm already using or want to use Copilot Cloud.

Self-Hosted

I'm using or want to use a self-hosted Copilot Runtime.

If you followed the [Copilot Cloud Quickstart](https://docs.copilotkit.ai/docs/quickstart) and opted to use CopilotCloud,
you only need to add your LangGraph Platform deployment URL and LangSmith API key to your CopilotCloud.

### Haven't setup Copilot Cloud yet? Click here!

To connect to LangGraph agents through Copilot Cloud, we leverage a concept called "Remote Endpoints"
which allow CopilotKit runtime to connect to various backends.

Navigate to [cloud.copilotkit.ai](https://go.copilotkit.ai/copilot-cloud-button-docs?ref=docs&session_id=0196217c-152e-758e-a4fb-d41efea3cec3) and follow the video!

You'll need a LangSmith API key which you can get with [this guide](https://docs.smith.langchain.com/administration/how_to_guides/organization_management/create_account_api_key#create-an-api-key) on LangSmith's website.

### Using LangGraph Studio

![Configure Remote Endpoint LangGraph](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/copilot-cloud/cpk-cloud-lgp-endpoint.gif)

🎉 You should now see your LangGraph agent in the list of available agents in CopilotKit!

### [Test Your Implementation](https://docs.copilotkit.ai/guides/backend-actions/langgraph-platform-endpoint\#test-your-implementation)

After setting up the remote endpoint and modifying your `CopilotRuntime`, you can test your implementation by asking the copilot to perform actions that invoke your agent.

The graph and interactions can viewed in [LangGraph Studio](https://docs.copilotkit.ai/guides/backend-actions/smith.langchain.com/studio) and any logs should be available on [LangSmith](https://docs.copilotkit.ai/guides/backend-actions/smith.langchain.com)

* * *

## [Troubleshooting](https://docs.copilotkit.ai/guides/backend-actions/langgraph-platform-endpoint\#troubleshooting)

A few things to try if you are running into trouble:

1. Make sure that you listed your agents according to the graphs mentioned in the `langgraph.json` file
2. Make sure the agent names are the same between the agent Python implementation, the `langgraph.json` file and the remote endpoint declaration
3. Make sure the LangGraph Platform deployment has all environment variables listed as you need them to be, according to your agent implementation

[Previous\\
\\
Remote Endpoint (Python)](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint) [Next\\
\\
Customize Instructions](https://docs.copilotkit.ai/guides/custom-ai-assistant-behavior)

### On this page

[Deploy a Graph to LangGraph Platform](https://docs.copilotkit.ai/guides/backend-actions/langgraph-platform-endpoint#deploy-a-graph-to-langgraph-platform) [Deploy your agent](https://docs.copilotkit.ai/guides/backend-actions/langgraph-platform-endpoint#deploy-your-agent) [Setup your Copilot Runtime](https://docs.copilotkit.ai/guides/backend-actions/langgraph-platform-endpoint#setup-your-copilot-runtime) [Test Your Implementation](https://docs.copilotkit.ai/guides/backend-actions/langgraph-platform-endpoint#test-your-implementation) [Troubleshooting](https://docs.copilotkit.ai/guides/backend-actions/langgraph-platform-endpoint#troubleshooting)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/backend-actions/langgraph-platform-endpoint.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Remote Backend Integration
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageStand up a FastAPI server using the CopilotKit Python SDK

[Backend Actions & Agents](https://docs.copilotkit.ai/guides/backend-actions)

# Remote Endpoint (Python)

Connect your CopilotKit application to a remote backend endpoint, allowing integration with Python-based services or other non-Node.js backends.

## [Stand up a FastAPI server using the CopilotKit Python SDK](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint\#stand-up-a-fastapi-server-using-the-copilotkit-python-sdk)

### [Install CopilotKit Python SDK and Dependencies](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint\#install-copilotkit-python-sdk-and-dependencies)

To integrate a Python backend with your CopilotKit application, set up your project and install the necessary dependencies by choosing your dependency management solution below.

Poetrypipconda

#### [Initialize a New Poetry Project](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint\#initialize-a-new-poetry-project)

Run the following command to create and initialize a new Poetry project:

```
poetry new My-CopilotKit-Remote-Endpoint
```

Follow the prompts to set up your `pyproject.toml`.

#### [Install Dependencies](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint\#install-dependencies)

After initializing the project, install the dependencies:

```
poetry add copilotkit fastapi uvicorn
# or including support for crewai
poetry add copilotkit[crewai] fastapi uvicorn
```

**Dependencies:**

- **copilotkit**: The CopilotKit Python SDK.
- **fastapi**: A modern, fast (high-performance) web framework for building APIs with Python.
- **uvicorn**: A lightning-fast ASGI server for Python.

### [Set Up a FastAPI Server](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint\#set-up-a-fastapi-server)

Create a new Python file `/my_copilotkit_remote_endpoint/server.py` and set up a FastAPI server:

/my\_copilotkit\_remote\_endpoint/server.py

```
from fastapi import FastAPI

app = FastAPI()
```

### [Define Your Backend Actions](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint\#define-your-backend-actions)

Import the CopilotKit SDK and define your backend actions. For example:

/my\_copilotkit\_remote\_endpoint/server.py

```
from fastapi import FastAPI
from copilotkit.integrations.fastapi import add_fastapi_endpoint
from copilotkit import CopilotKitRemoteEndpoint, Action as CopilotAction

app = FastAPI()

# Define your backend action
async def fetch_name_for_user_id(userId: str):
    # Replace with your database logic
    return {"name": "User_" + userId}

# this is a dummy action for demonstration purposes
action = CopilotAction(
    name="fetchNameForUserId",
    description="Fetches user name from the database for a given ID.",
    parameters=[\
        {\
            "name": "userId",\
            "type": "string",\
            "description": "The ID of the user to fetch data for.",\
            "required": True,\
        }\
    ],
    handler=fetch_name_for_user_id
)

# Initialize the CopilotKit SDK
sdk = CopilotKitRemoteEndpoint(actions=[action])

# Add the CopilotKit endpoint to your FastAPI app
add_fastapi_endpoint(app, sdk, "/copilotkit_remote")

def main():
    """Run the uvicorn server."""
    import uvicorn
    uvicorn.run("server:app", host="0.0.0.0", port=8000, reload=True)

if __name__ == "__main__":
    main()
```

### [Run Your FastAPI Server](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint\#run-your-fastapi-server)

Since we've added the entry point in `server.py`, you can run your FastAPI server directly by executing the script:

Poetrypipconda

```
poetry run python3 server.py
```

**Note:** Ensure that you're in the same directory as `server.py` when running this command.

## [Connect your app to the remote endpoint](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint\#connect-your-app-to-the-remote-endpoint)

Now that you've set up your FastAPI server with the backend actions, integrate it into your CopilotKit application by modifying your `CopilotRuntime` configuration.

Copilot Cloud (Recommended)

I want to use Copilot Cloud to connect to my remote endpoint.

Self-Hosted Copilot Runtime

I want to use a self-hosted Copilot Runtime to connect to my remote endpoint.

To connect a FastAPI server to Copilot Cloud, we leverage a concept called "Remote Endpoints"
which allow CopilotKit runtime to connect to various backends.

To get started, [navigate to Copilot Cloud](https://go.copilotkit.ai/copilot-cloud-button-docs?ref=docs&session_id=0196217c-93b4-7a50-92fd-231e440765bd).

Don't want to use a tunnel?

Just skip the tunnel setup and use your hosted FastAPI server address instead.

```
npx copilotkit@latest dev --port <port_number>
```

![Configure Remote Endpoint](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/copilot-cloud/cpk-cloud-remote-endpoint-setup.gif)

You should now see your CopilotKit runtime in the list of available agents in CopilotKit!

### [Test Your Implementation](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint\#test-your-implementation)

After setting up the remote endpoint and modifying your `CopilotRuntime`, you can test your implementation by asking the copilot to perform actions that invoke your Python backend. For example, ask the copilot: "Fetch the name for user ID `123`."

### [Advanced](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint\#advanced)

#### [Configuring the Thread Pool Executor](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint\#configuring-the-thread-pool-executor)

The request to the remote endpoint is made in a thread pool executor. You can configure the size of the thread pool executor by passing the `max_workers` parameter to the `add_fastapi_endpoint` function.

```
add_fastapi_endpoint(app, sdk, "/copilotkit_remote", max_workers=10) # default is 10
```

#### [Dynamically returning actions and agents](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint\#dynamically-returning-actions-and-agents)

Both the `actions` and `agents` parameters can optionally be functions that return a list of actions or agents. This allows you to dynamically return actions and agents based on the user's request.

For example, to dynamically configure an agent based on properties from the frontend, set the properties on the frontend first:

```
<CopilotKit properties={{someProperty: "xyz"}}>
   <YourApp />
</CopilotKit>
```

Then, in your backend, use a function to return dynamically configured agents:

```
def build_agents(context):
    return [\
        LangGraphAgent(\
            name="some_agent",\
            description="This agent does something",\
            graph=graph,\
            langgraph_config={\
                "some_property": context["properties"]["someProperty"]\
            }\
        )\
    ]


app = FastAPI()
sdk = CopilotKitRemoteEndpoint(
    agents=build_agents,
)
```

* * *

[Previous\\
\\
LangServe actions](https://docs.copilotkit.ai/guides/backend-actions/langserve-backend-actions) [Next\\
\\
Remote Endpoint (LangGraph Platform)](https://docs.copilotkit.ai/guides/backend-actions/langgraph-platform-endpoint)

### On this page

[Stand up a FastAPI server using the CopilotKit Python SDK](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#stand-up-a-fastapi-server-using-the-copilotkit-python-sdk) [Install CopilotKit Python SDK and Dependencies](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#install-copilotkit-python-sdk-and-dependencies) [Initialize a New Poetry Project](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#initialize-a-new-poetry-project) [Install Dependencies](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#install-dependencies) [Set Up a Virtual Environment (optional)](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#set-up-a-virtual-environment-optional) [Install Dependencies](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#install-dependencies-1) [Create a New Conda Environment](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#create-a-new-conda-environment) [Install Dependencies](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#install-dependencies-2) [Set Up a FastAPI Server](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#set-up-a-fastapi-server) [Define Your Backend Actions](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#define-your-backend-actions) [Run Your FastAPI Server](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#run-your-fastapi-server) [Connect your app to the remote endpoint](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#connect-your-app-to-the-remote-endpoint) [Troubleshooting](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#troubleshooting) [Test Your Implementation](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#test-your-implementation) [Advanced](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#advanced) [Configuring the Thread Pool Executor](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#configuring-the-thread-pool-executor) [Dynamically returning actions and agents](https://docs.copilotkit.ai/guides/backend-actions/remote-backend-endpoint#dynamically-returning-actions-and-agents)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/backend-actions/remote-backend-endpoint.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Human-in-the-Loop Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is Human-in-the-Loop (HITL)?

# Human in the Loop (HITL)

Allow your agent and users to collaborate on complex tasks.

## [What is Human-in-the-Loop (HITL)?](https://docs.copilotkit.ai/crewai-flows/human-in-the-loop\#what-is-human-in-the-loop-hitl)

Human-in-the-loop (HITL) allows agents to request human input or approval during execution, making AI systems more reliable and trustworthy. This pattern is essential when building AI applications that need to handle complex decisions or actions that require human judgment.

![Agentic Copilot Human in the Loop](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/coagents/coagents-hitl-infographic.png)

## [When should I use this?](https://docs.copilotkit.ai/crewai-flows/human-in-the-loop\#when-should-i-use-this)

HITL combines the efficiency of AI with human judgment, creating a system that's both powerful and reliable. The key advantages include:

- **Quality Control**: Human oversight at critical decision points
- **Edge Cases**: Graceful handling of low-confidence situations
- **Expert Input**: Leverage human expertise when needed
- **Reliability**: More robust system for real-world use

## [How can I use this?](https://docs.copilotkit.ai/crewai-flows/human-in-the-loop\#how-can-i-use-this)

Read more about the approach to HITL in CrewAI Flows.

[Flow-based\\
\\
Utilize CrewAI Flows to create Human-in-the-Loop workflows.](https://docs.copilotkit.ai/crewai-flows/human-in-the-loop/flow)

[Previous\\
\\
Tool-based Generative UI](https://docs.copilotkit.ai/crewai-flows/generative-ui/tool-based) [Next\\
\\
CrewAI Flows](https://docs.copilotkit.ai/crewai-flows/human-in-the-loop/flow)

### On this page

[What is Human-in-the-Loop (HITL)?](https://docs.copilotkit.ai/crewai-flows/human-in-the-loop#what-is-human-in-the-loop-hitl) [When should I use this?](https://docs.copilotkit.ai/crewai-flows/human-in-the-loop#when-should-i-use-this) [How can I use this?](https://docs.copilotkit.ai/crewai-flows/human-in-the-loop#how-can-i-use-this)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/crewai-flows/human-in-the-loop/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Authenticated Actions Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageIntroduction

# Authenticated Actions  Cloud Only

## [Introduction](https://docs.copilotkit.ai/guides/authenticated-actions\#introduction)

Copilot Cloud enables secure propagation of authentication state within AI conversations, allowing your copilot to interact with authenticated backend services and tools on behalf of the user.

This feature is only available with [Copilot Cloud](https://cloud.copilotkit.ai/).

## [Overview](https://docs.copilotkit.ai/guides/authenticated-actions\#overview)

When building AI copilots that interact with user-specific data or services (like calendars, emails, or custom APIs), you need to ensure that:

1. The user is properly authenticated
2. The authentication state is securely propagated to backend tools
3. The copilot maintains proper authorization context

## [How It Works](https://docs.copilotkit.ai/guides/authenticated-actions\#how-it-works)

### [Authentication Flow](https://docs.copilotkit.ai/guides/authenticated-actions\#authentication-flow)

1. Your frontend app configures authentication state using `authConfig_c`
2. When a user authenticates, their auth state (headers, metadata) is securely captured
3. Copilot Cloud Runtime maintains this auth context throughout the conversation
4. When the LLM or runloop needs to call your registered endpoints/tools:
   - All auth headers are automatically propagated
   - Your endpoints receive the same auth context
   - Tools can verify user identity and permissions

### [Example Scenario](https://docs.copilotkit.ai/guides/authenticated-actions\#example-scenario)

This means your backend tools and APIs:

- Receive the same authentication headers as your frontend
- Can verify user identity and permissions
- Maintain security context throughout the AI interaction
- Don't need additional auth handling specific to CopilotKit

## [Frontend Implementation](https://docs.copilotkit.ai/guides/authenticated-actions\#frontend-implementation)

### [Configure Authentication State](https://docs.copilotkit.ai/guides/authenticated-actions\#configure-authentication-state)

```
import { CopilotKit } from "@copilotkit/react-core";

interface AuthState {
  status: "authenticated" | "unauthenticated";
  authHeaders: Record<string, string>;
  userId?: string;
  metadata?: Record<string, any>;
}

// Your SignInComponent component
function SignInComponent({
  onSignInComplete,
}: {
  onSignInComplete: (authState: AuthState) => void;
}) {
  const handleAuth = async () => {
    // Your auth logic (e.g., OAuth, custom auth)
    const authState = {
      status: "authenticated",
      authHeaders: {
        Authorization: "Bearer your_token",
        // Add any other headers needed by your backend
      },
      userId: "user_123",
      metadata: {
        email: "user@example.com",
        // Any other user context needed by tools
      },
    };

    onAuthComplete(authState);
  };

  return <button onClick={handleAuth}>Authenticate</button>;
}

// Root configuration
export default function App() {
  return (
    <CopilotKit
      publicApiKey={process.env.COPILOTKIT_PUBLIC_API_KEY}
      authConfig_c={{
        SignInComponent,
      }}
    >
      {/* Your app */}
    </CopilotKit>
  );
}
```

## [Backend Integration](https://docs.copilotkit.ai/guides/authenticated-actions\#backend-integration)

Your backend endpoints will receive the authentication context automatically. Example of a tool endpoint:

```
// Example backend endpoint
async function handleCalendarRequest(req, res) {
  // Auth headers from the frontend are automatically available
  const authHeader = req.headers.authorization;
  const userId = req.headers["x-user-id"];

  // Verify authentication as you normally would
  if (!isValidAuth(authHeader)) {
    return res.status(401).json({ error: "Unauthorized" });
  }

  // Proceed with authenticated operation
  const calendar = await getCalendarForUser(userId);
  return res.json(calendar);
}
```

## [Best Practices](https://docs.copilotkit.ai/guides/authenticated-actions\#best-practices)

1. **Authentication Headers**
   - Include all necessary auth tokens
   - Add relevant user context
   - Consider token expiration
   - Handle refresh tokens if needed
2. **Backend Security**
   - Always verify auth headers
   - Implement proper validation
   - Use secure token verification
   - Handle expired tokens gracefully
3. **Error Handling**
   - Provide clear auth errors
   - Handle token refresh scenarios
   - Implement proper fallbacks
   - Give helpful user feedback

[Previous\\
\\
Customize Instructions](https://docs.copilotkit.ai/guides/custom-ai-assistant-behavior) [Next\\
\\
Guardrails](https://docs.copilotkit.ai/guides/guardrails)

### On this page

[Introduction](https://docs.copilotkit.ai/guides/authenticated-actions#introduction) [Overview](https://docs.copilotkit.ai/guides/authenticated-actions#overview) [How It Works](https://docs.copilotkit.ai/guides/authenticated-actions#how-it-works) [Authentication Flow](https://docs.copilotkit.ai/guides/authenticated-actions#authentication-flow) [Example Scenario](https://docs.copilotkit.ai/guides/authenticated-actions#example-scenario) [Frontend Implementation](https://docs.copilotkit.ai/guides/authenticated-actions#frontend-implementation) [Configure Authentication State](https://docs.copilotkit.ai/guides/authenticated-actions#configure-authentication-state) [Backend Integration](https://docs.copilotkit.ai/guides/authenticated-actions#backend-integration) [Best Practices](https://docs.copilotkit.ai/guides/authenticated-actions#best-practices)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/authenticated-actions.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## CoAgents Terminology
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this page

# Terminology

Here are the key terms and concepts used throughout CoAgents:

| Term | Definition |
| --- | --- |
| Agentic Copilot | An AI agent designed to collaborate with users in Agent-Native applications, rather than operate autonomously. |
| CoAgent | Terminology referring to CopilotKit's suite of tools for building agentic applications. Typically interchangeable with agentic copilot. |
| Agent State | The current data and context maintained by a LangGraph agent during its execution, including both internal state and data that can be synchronized with the frontend UI. |
| Agentic Generative UI | UI components that are dynamically generated and updated based on the agent's current state, providing users with visibility into what the agent is doing and building trust through transparency. |
| Ground Truth | In CoAgents, CopilotKit serves as the "ground truth" for the full chat session, maintaining the persistent chat history and ensuring conversational continuity across different agents. |
| Human-in-the-Loop (HITL) | A workflow pattern where human input or validation is required during agent execution, enabling quality control and oversight at critical decision points. |
| Intermediate State | The updates to agent state that occur during node execution, rather than only at node transitions, enabling real-time feedback about the agent's progress. |
| [LangGraph](https://docs.langchain.com/oss/python/langgraph/overview) | The agent framework integrated with CopilotKit that provides the orchestration layer for CoAgents, enabling sophisticated multi-step reasoning and state management. |
| Agent Lock Mode | A mode where CopilotKit is configured to work exclusively with a specific agent, ensuring all requests stay within a single workflow graph for precise control. |
| Router Mode | A mode where CopilotKit dynamically routes requests between different agents and tools based on context and user input, enabling flexible multi-agent workflows. |
| State Streaming | The real-time synchronization of agent state between the backend and frontend, enabling immediate updates to the UI as the agent performs tasks. |

These terms are referenced throughout the documentation and are essential for understanding how CoAgents work and how to implement them effectively in your applications.

[Previous\\
\\
Video: Perplexity Clone](https://docs.copilotkit.ai/coagents/videos/perplexity-clone) [Next\\
\\
Agentic Copilots](https://docs.copilotkit.ai/coagents/concepts/agentic-copilots)

### On this page

No Headings

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/concepts/terminology.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Contributing to Documentation
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pagePrerequisites

Contributing

# Documentation Contributions

We understand that as we move quickly, sometimes our documentation website can be a bit outdated. Therefore, we highly value contributions to our documentation.

## [Prerequisites](https://docs.copilotkit.ai/contributing/docs-contributions\#prerequisites)

- [Node.js](https://nodejs.org/en/) 20.x or later
- [pnpm](https://pnpm.io/) v9.x installed globally ( `npm i -g pnpm@^9`)

## [How To Contribute](https://docs.copilotkit.ai/contributing/docs-contributions\#how-to-contribute)

### [Fork The Repository](https://docs.copilotkit.ai/contributing/docs-contributions\#fork-the-repository)

First, head over to the [CopilotKit GitHub repository](https://github.com/CopilotKit/CopilotKit) and create a fork.

Then, clone the forked repository to your local machine:

```
git clone https://github.com/<your-username>/CopilotKit
cd CopilotKit/docs
```

### [Run the Documentation Site Locally](https://docs.copilotkit.ai/contributing/docs-contributions\#run-the-documentation-site-locally)

To run the documentation site locally, install the dependencies and then start the docs in development mode:

```
pnpm install
pnpm run dev
```

The documentation site should be available at [http://localhost:3000](http://localhost:3000/).

### [Make Your Changes](https://docs.copilotkit.ai/contributing/docs-contributions\#make-your-changes)

Now, you can make your changes to the documentation website.

- All documentation-related files are located in the docs repository
- You may want to familiarize yourself with [Nextra](https://nextra.site/) to understand how the documentation website is structured.

Please ensure you review your changes for grammar, spelling and formatting errors. Also, ensure that links and images are working.

### [Review Changes & Submit Pull Request](https://docs.copilotkit.ai/contributing/docs-contributions\#review-changes--submit-pull-request)

Once you are happy with your changes, you can commit and push them. Then, head over to the [Pull Requests page](https://github.com/CopilotKit/CopilotKit/pulls) and create a pull request. Thank you for your contribution!

## [Need help?](https://docs.copilotkit.ai/contributing/docs-contributions\#need-help)

If you need help with anything, please don't hesitate to reach out to us on [Discord](https://discord.gg/6dffbvGU3D). We have a dedicated [#contributing](https://discord.com/channels/1122926057641742418/1183863183149117561) channel.

[Previous\\
\\
Advanced: Package Linking](https://docs.copilotkit.ai/contributing/code-contributions/package-linking) [Next\\
\\
Anonymous Telemetry](https://docs.copilotkit.ai/telemetry)

### On this page

[Prerequisites](https://docs.copilotkit.ai/contributing/docs-contributions#prerequisites) [How To Contribute](https://docs.copilotkit.ai/contributing/docs-contributions#how-to-contribute) [Fork The Repository](https://docs.copilotkit.ai/contributing/docs-contributions#fork-the-repository) [Run the Documentation Site Locally](https://docs.copilotkit.ai/contributing/docs-contributions#run-the-documentation-site-locally) [Make Your Changes](https://docs.copilotkit.ai/contributing/docs-contributions#make-your-changes) [Review Changes & Submit Pull Request](https://docs.copilotkit.ai/contributing/docs-contributions#review-changes--submit-pull-request) [Need help?](https://docs.copilotkit.ai/contributing/docs-contributions#need-help)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/(other)/contributing/docs-contributions.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## useCopilotChat Hook
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageUsage

# useCopilotChat

`useCopilotChat` is a React hook that lets you directly interact with the
Copilot instance. Use to implement a fully custom UI (headless UI) or to
programmatically interact with the Copilot instance managed by the default
UI.

## [Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChat\#usage)

### [Simple Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChat\#simple-usage)

```
import { useCopilotChat } from "@copilotkit/react-core";
import { Role, TextMessage } from "@copilotkit/runtime-client-gql";

export function YourComponent() {
  const { appendMessage } = useCopilotChat();

  appendMessage(
    new TextMessage({
      content: "Hello World",
      role: Role.User,
    }),
  );

  // optionally, you can append a message without running chat completion
  appendMessage(yourMessage, { followUp: false });
}
```

`useCopilotChat` returns an object with the following properties:

```
const {
  visibleMessages, // An array of messages that are currently visible in the chat.
  appendMessage, // A function to append a message to the chat.
  setMessages, // A function to set the messages in the chat.
  deleteMessage, // A function to delete a message from the chat.
  reloadMessages, // A function to reload the messages from the API.
  stopGeneration, // A function to stop the generation of the next message.
  reset, // A function to reset the chat.
  isLoading, // A boolean indicating if the chat is loading.
} = useCopilotChat();
```

## [Parameters](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChat\#parameters)

idstring

A unique identifier for the chat. If not provided, a random one will be
generated. When provided, the `useChat` hook with the same `id` will
have shared states across components.

headersRecord<string, string> \| Headers

HTTP headers to be sent with the API request.

initialMessagesMessage\[\]

System messages of the chat. Defaults to an empty array.

makeSystemMessageSystemMessageFunction

A function to generate the system message. Defaults to `defaultSystemMessage`.

[Previous\\
\\
useCopilotAdditionalInstructions](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotAdditionalInstructions) [Next\\
\\
useCopilotChatSuggestions](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChatSuggestions)

### On this page

[Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChat#usage) [Simple Usage](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChat#simple-usage) [Parameters](https://docs.copilotkit.ai/reference/v1/hooks/useCopilotChat#parameters)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/v1/hooks/useCopilotChat.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Human-in-the-Loop Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is this?

[Human in the Loop (HITL)](https://docs.copilotkit.ai/coagents/human-in-the-loop)

# Node-based

Learn how to implement Human-in-the-Loop (HITL) using a node-based flow.

The usage of node based interrupt is [now discouraged](https://docs.langchain.com/oss/python/langgraph/interrupts) by both LangGraph and CopilotKit.
As of LangGraph 0.2.57, the recommended way to set breakpoints is using [the interrupt function](https://https//docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow) as it simplifies human-in-the-loop patterns.

Pictured above is the [coagent starter](https://github.com/copilotkit/copilotkit/tree/main/examples/coagents-starter) with
the implementation below applied!

## [What is this?](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow\#what-is-this)

[Node based flows](https://docs.langchain.com/oss/python/langgraph/interrupts#debugging-with-interrupts) are predicated on LangGraph concept
of `breakpoints` which will interrupt a node before or after its execution to allow for user input.

CopilotKit allows you to add custom UI to take user input and then pass it back to the agent upon completion.

## [Why should I use this?](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow\#why-should-i-use-this)

Human-in-the-loop is a powerful way to implement complex workflows that are production ready. By having a human in the loop,
you can ensure that the agent is always making the right decisions and ultimately is being steered in the right direction.

Node-based flows are a great way to implement HITL for more complex workflows where you want to ensure the agent is aware
of everything that has happened during a HITL interaction. This is contrasted with interrupt-based flows, where the agent
is interrupted and then resumes execution from where it left off, unaware of the context of the interaction by default.

## [Implementation](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow\#implementation)

### [Run and connect your agent](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow\#run-and-connect-your-agent)

You'll need to run your agent and connect it to CopilotKit before proceeding. If you haven't done so already,
you can follow the instructions in the [Getting Started](https://docs.copilotkit.ai/coagents/quickstart/langgraph) guide.

If you don't already have an agent, you can use the [coagent starter](https://github.com/copilotkit/copilotkit/tree/main/examples/coagents-starter) as a starting point
as this guide uses it as a starting point.

### [Install the CopilotKit SDK](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow\#install-the-copilotkit-sdk)

Any LangGraph agent can be used with CopilotKit. However, creating deep agentic
experiences with CopilotKit requires our LangGraph SDK.

PythonTypeScript

Poetrypipconda

```
poetry add copilotkit
# including support for crewai
poetry add copilotkit[crewai]
```

### [Add a `useCopilotAction` to your Frontend](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow\#add-a-usecopilotaction-to-your-frontend)

First, we'll create a component that renders the agent's essay draft and waits for user approval.

ui/app/page.tsx

```
import { useCopilotAction } from "@copilotkit/react-core"
import { Markdown } from "@copilotkit/react-ui"

function YourMainContent() {
  // ...

  useCopilotAction({
    name: "writeEssay",
    available: "remote",
    description: "Writes an essay and takes the draft as an argument.",
    parameters: [\
      { name: "draft", type: "string", description: "The draft of the essay", required: true },\
    ],

    renderAndWaitForResponse: ({ args, respond, status }) => {
      return (
        <div>
          <Markdown content={args.draft || 'Preparing your draft...'} />

          <div className={`flex gap-4 pt-4 ${status !== "executing" ? "hidden" : ""}`}>
            <button
              onClick={() => respond?.("CANCEL")}
              disabled={status !== "executing"}
              className="border p-2 rounded-xl w-full"
            >
              Try Again
            </button>
            <button
              onClick={() => respond?.("SEND")}
              disabled={status !== "executing"}
              className="bg-blue-500 text-white p-2 rounded-xl w-full"
            >
              Approve Draft
            </button>
          </div>
        </div>
      );
    },
  });

  // ...
}
```

### [Setup the LangGraph Agent](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow\#setup-the-langgraph-agent)

Now we'll setup the LangGraph agent. Node-based flows are hard to understand without a complete example, so below
is the complete implementation of the agent with explanations.

Some main things to note:

- The agent's state inherits from `CopilotKitState` to bring in the CopilotKit actions.
- CopilotKit's actions are binded to the model as tools.
- If the `writeEssay` action is found in the model's response, the agent will transition to the `user_feedback_node`.
- The agent is interrupted before the `user_feedback_node` to allow for user input.

PythonTypeScript

agent/sample\_agent/agent.py

```
from typing_extensions import Literal
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, AIMessage
from langchain_core.runnables import RunnableConfig
from langgraph.graph import StateGraph, END
from langgraph.checkpoint.memory import MemorySaver
from langgraph.types import Command
from copilotkit import CopilotKitState

# 1. Define our agent's state and inherit from CopilotKitState, this brings in the CopilotKit actions
class AgentState(CopilotKitState):
    # 1.1 Define any other state variables
    pass

# 2. Define the chat node, this will be where the agent will talk to user and
#    decide if it needs to call the writeEssay tool
async def chat_node(state: AgentState, config: RunnableConfig) -> Command[Literal["user_feedback_node", "__end__"]]:
    # 2.1 Define the model and bind CopilotKit's actions as tools
    model = ChatOpenAI(model="gpt-4o")
    model_with_tools = model.bind_tools([*state.get("copilotkit", {}).get("actions", [])])

    # 2.2 Define the system message
    system_message = SystemMessage(
        content="You write essays. Use your tools to write an essay, don't just write it in plain text."
    )

    # 2.3 Run the model to generate a response
    response = await model_with_tools.ainvoke([\
        system_message,\
        *state["messages"],\
    ], config)


    # 2.4 Check for the writeEssay tool call and, if found, go  to the
    #     user_feedback_node to handle the user's response
    if isinstance(response, AIMessage) and response.tool_calls:
        if response.tool_calls[0].get("name") == "writeEssay":
            return Command(goto="interrupt_node", update={"messages": response})

    # 2.5 If no tool call is found, end the agent
    return Command(goto=END, update={"messages": response})

# 3. Define an empty interrupt node to act as buffer as we use the interrupt_after property
def interrupt_node(state: AgentState, config: RunnableConfig):
  pass

# 4. Define the user_feedback_node, this node will be interrupted before execution
#    where CopilotKit's renderAndWaitForResponse provide the user's response.
def user_feedback_node(state: AgentState, config: RunnableConfig) -> Command[Literal["chat_node"]]:

    # 3.1 Get the last message from the state, this will be
    #     what is returned by respond() in the frontend
    last_message = state["messages"][-1]

    # 3.2 If the user declined the essay, ask them how they'd like to improve it
    if last_message.content != "SEND":
        return Command(goto="chat_node", update={
            "messages": [SystemMessage(content="The user declined they essay, please ask them how they'd like to improve it")]
        })

    # 3.3 If the user approved the essay, ask them if they'd like anything else
    return Command(goto="chat_node", update={
        "messages": [SystemMessage(content="The user approved the essay, ask them if they'd like anything else")]
    })

# 5. Configure the workflow
workflow = StateGraph(AgentState)
workflow.add_node("chat_node", chat_node)
workflow.add_node("interrupt_node", interrupt_node)
workflow.add_node("user_feedback_node", user_feedback_node)
workflow.add_edge("interrupt_node", "user_feedback_node")
workflow.set_entry_point("chat_node")


# 6. Compile the workflow and set the interrupt_after property
graph = workflow.compile(MemorySaver(), interrupt_after=["interrupt_node"])
```

### [Give it a try!](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow\#give-it-a-try)

Try asking your agent to write an essay about the benefits of AI. You'll see that it will generate an essay,
stream the progress and eventually ask you to review it.

[Previous\\
\\
Interrupt](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow) [Next\\
\\
Shared State](https://docs.copilotkit.ai/coagents/shared-state)

### On this page

[What is this?](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow#what-is-this) [Why should I use this?](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow#why-should-i-use-this) [Implementation](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow#implementation) [Run and connect your agent](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow#run-and-connect-your-agent) [Install the CopilotKit SDK](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow#install-the-copilotkit-sdk) [Add a useCopilotAction to your Frontend](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow#add-a-usecopilotaction-to-your-frontend) [Setup the LangGraph Agent](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow#setup-the-langgraph-agent) [Give it a try!](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow#give-it-a-try)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/human-in-the-loop/node-flow.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Headless UI Customization
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageResetting the chat history

[Customize UI](https://docs.copilotkit.ai/guides/custom-look-and-feel)

# Fully Headless UI

Fully customize your Copilot's UI from the ground up using headless UI

The built-in Copilot UI can be customized in many ways -- both through CSS and by passing in custom sub-components.

CopilotKit also offers **fully custom headless UI** through the `useCopilotChat` hook. Everything built with the built-in UI (and more) can be implemented with the headless UI, providing deep customizability.

```
import { useCopilotChat } from "@copilotkit/react-core";
import { Role, TextMessage } from "@copilotkit/runtime-client-gql";

export function CustomChatInterface() {
  const {
    visibleMessages,
    appendMessage,
    setMessages,
    deleteMessage,
    reloadMessages,
    stopGeneration,
    isLoading,
  } = useCopilotChat();

  const sendMessage = (content: string) => {
    appendMessage(new TextMessage({ content, role: Role.User }));
  };

  return (
    <div>
      {/* Implement your custom chat UI here */}
    </div>
  );
}
```

## [Resetting the chat history](https://docs.copilotkit.ai/guides/custom-look-and-feel/headless-ui\#resetting-the-chat-history)

In some cases, users may want to reset the chat to clear the conversation history and start fresh. This can be useful when:

- The current conversation has become too long or confusing.
- You want to test different prompts or approaches from a clean slate.
- A user needs to reset the context to ensure the AI responds appropriately.

This simple method allows you to reset the chat state with a button click.

Why Reset the Chat?

Resetting the chat clears all conversation history, helping you start fresh or troubleshoot AI responses.

PreviewCode

![](https://docs.copilotkit.aihttps://cdn.copilotkit.ai/docs/copilotkit/images/concepts/customize-look-and-feel/reset-chat.gif)

[Previous\\
\\
Custom Sub-Components](https://docs.copilotkit.ai/guides/custom-look-and-feel/bring-your-own-components) [Next\\
\\
Connecting Your Data](https://docs.copilotkit.ai/guides/connect-your-data)

### On this page

[Resetting the chat history](https://docs.copilotkit.ai/guides/custom-look-and-feel/headless-ui#resetting-the-chat-history)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/custom-look-and-feel/headless-ui.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Agent State Writing Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is this?

[Shared State](https://docs.copilotkit.ai/coagents/shared-state)

# Writing agent state

Write to agent's state from your application.

This video shows the [coagents starter](https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter) repo with the previous steps applied to it!

## [What is this?](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#what-is-this)

This guide shows you how to write to your agent's state from your application.

## [When should I use this?](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#when-should-i-use-this)

You can use this when you want to provide the user with feedback about what your agent is doing, specifically
when your agent is calling tools. CopilotKit allows you to fully customize how these tools are rendered in the chat.

## [Implementation](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#implementation)

### [Run and Connect Your Agent to CopilotKit](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#run-and-connect-your-agent-to-copilotkit)

You'll need to run your agent and connect it to CopilotKit before proceeding. If you haven't done so already,
you can follow the instructions in the [Getting Started](https://docs.copilotkit.ai/getting-started) guide.

If you don't already have an agent, you can use the [coagent starter](https://github.com/copilotkit/copilotkit/tree/main/examples/coagents-starter) as a starting point
as this guide uses it as a starting point.

### [Define the Agent State](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#define-the-agent-state)

LangGraph is stateful. As you transition between nodes, that state is updated and passed to the next node. For this example,
let's assume that our agent state looks something like this.

PythonTypeScript

agent-py/sample\_agent/agent.py

```
from copilotkit import CopilotKitState
from typing import Literal

class AgentState(CopilotKitState):
    language: Literal["english", "spanish"] = "english"
```

### [Call `setState` function from the `useCoAgent` hook](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#call-setstate-function-from-the-usecoagent-hook)

`useCoAgent` returns a `setState` function that you can use to update the agent state. Calling this
will update the agent state and trigger a rerender of anything that depends on the agent state.

ui/app/page.tsx

```
import { useCoAgent } from "@copilotkit/react-core";

// Define the agent state type, should match the actual state of your agent
type AgentState = {
  language: "english" | "spanish";
}

// Example usage in a pseudo React component
function YourMainContent() {
  const { state, setState } = useCoAgent<AgentState>({
    name: "sample_agent",
    initialState: { language: "spanish" }  // optionally provide an initial state
  });

  // ...

  const toggleLanguage = () => {
    setState({ language: state.language === "english" ? "spanish" : "english" });
  };

  // ...

  return (
    // style excluded for brevity
    <div>
      <h1>Your main content</h1>
      <p>Language: {state.language}</p>
      <button onClick={toggleLanguage}>Toggle Language</button>
    </div>
  );
}
```

### [Give it a try!](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#give-it-a-try)

You can now use the `setState` function to update the agent state and `state` to read it. Try toggling the language button
and talking to your agent. You'll see the language change to match the agent's state.

## [Advanced Usage](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#advanced-usage)

### [Re-run the agent with a hint about what's changed](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#re-run-the-agent-with-a-hint-about-whats-changed)

The new agent state will be used next time the agent runs.
If you want to re-run it manually, use the `run` argument on the `useCoAgent` hook.

The agent will be re-run, and it will get not only the latest updated state, but also a **hint** that can depend on the data delta between the previous and the current state.

ui/app/page.tsx

```
import { useCoAgent } from "@copilotkit/react-core";
import { TextMessage, MessageRole } from "@copilotkit/runtime-client-gql";

// ...

function YourMainContent() {
  const { state, setState, run } = useCoAgent<AgentState>({
    name: "sample_agent",
    initialState: { language: "spanish" }  // optionally provide an initial state
  });

  // setup to be called when some event in the app occurs
  const toggleLanguage = () => {
    const newLanguage = state.language === "english" ? "spanish" : "english";
    setState({ language: newLanguage });

    // re-run the agent and provide a hint about what's changed
    run(({ previousState, currentState }) => {
      return new TextMessage({
        role: MessageRole.User,
        content: `the language has been updated to ${currentState.language}`,
      });
    });
  };

  return (
    // ...
  );
}
```

### [Intermediately Stream and Render Agent State](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#intermediately-stream-and-render-agent-state)

By default, the LangGraph agent state will only update _between_ LangGraph node transitions --
which means state updates will be discontinuous and delayed.

You likely want to render the agent state as it updates **continuously.**

See **[predictive state updates](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates).**

[Previous\\
\\
Reading agent state](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read) [Next\\
\\
Agent state inputs and outputs](https://docs.copilotkit.ai/coagents/shared-state/workflow-execution)

### On this page

[What is this?](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#what-is-this) [When should I use this?](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#when-should-i-use-this) [Implementation](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#implementation) [Run and Connect Your Agent to CopilotKit](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#run-and-connect-your-agent-to-copilotkit) [Define the Agent State](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#define-the-agent-state) [Call setState function from the useCoAgent hook](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#call-setstate-function-from-the-usecoagent-hook) [Give it a try!](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#give-it-a-try) [Advanced Usage](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#advanced-usage) [Re-run the agent with a hint about what's changed](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#re-run-the-agent-with-a-hint-about-whats-changed) [Intermediately Stream and Render Agent State](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#intermediately-stream-and-render-agent-state)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/shared-state/in-app-agent-write.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Chat Components Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this page

# All Chat Components

[**<CopilotChat />** \\
The CopilotChat component, providing a chat interface for interacting with your copilot.](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotChat) [**<CopilotPopup />** \\
The CopilotPopup component, providing a popup interface for interacting with your copilot.](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotPopup) [**<CopilotSidebar />** \\
The CopilotSidebar component, providing a sidebar interface for interacting with your copilot.](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotSidebar)

[Previous\\
\\
API Reference](https://docs.copilotkit.ai/reference) [Next\\
\\
CopilotChat](https://docs.copilotkit.ai/reference/v1/components/chat/CopilotChat)

### On this page

No Headings

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/reference/components/chat/index.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## LangChain JS Integration
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageIntegrate LangChain JS actions with CopilotRuntime

[Backend Actions & Agents](https://docs.copilotkit.ai/guides/backend-actions)

# LangChain.js

Integrate LangChain JS chains as backend actions in your CopilotKit application.

### Find your CopilotRuntime

The starting point for this section is the `CopilotRuntime` you set up during quickstart (the CopilotKit backend endpoint).
For a refresher, see [Self-Hosting](https://docs.copilotkit.ai/guides/self-hosting) (or alternatively, revisit the [quickstart](https://docs.copilotkit.ai/quickstart)).

**First, find your `CopilotRuntime` instance in your code.** You can simply search your codebase for `CopilotRuntime`.

If you followed the quickstart, it'll be where you set up the `/api/copilotkit` endpoint.

### [Integrate LangChain JS actions with CopilotRuntime](https://docs.copilotkit.ai/guides/backend-actions/langchain-js-backend-actions\#integrate-langchain-js-actions-with-copilotruntime)

CopilotKit allows actions to return not only values but also LangChain streams. This means you can call LangChain chains directly and return their streams as part of your backend actions. Here's how to implement LangChain JS backend actions:

**Note** that `actions` is not merely an array of actions, but an array **generator**.
This generator takes `properties` and `url` as input.

This means you can **customize which backend actions are made available** according to the current frontend URL, as well as custom properties you can pass from the frontend.

/api/copilotkit/route.ts

```
import { ChatOpenAI } from "@langchain/openai";
import { ChatPromptTemplate } from "@langchain/core/prompts";

const runtime = new CopilotRuntime({
  // ... existing configuration
  actions: ({properties, url}) => {
    // Note that actions returns not an array, but an array **generator**.
    // You can use the input parameters to the actions generator to expose different backend actions to the Copilot at different times:
    // `url` is the current URL on the frontend application.
    // `properties` contains custom properties you can pass from the frontend application.

    return [\
      {\
        name: "generateJokeForTopic",\
        description: "Generates a joke for a given topic.",\
        parameters: [\
          {\
            name: "topic",\
            type: "string",\
            description: "The topic to generate a joke about.",\
            required: true,\
          },\
        ],\
        handler: async ({topic}: {topic: string}) => {\
          const prompt = ChatPromptTemplate.fromMessages([\
            [\
              "system",\
              "You are a witty comedian. Generate a short, funny joke about the given topic. But make it sound like a pirate joke!",\
            ],\
            ["user", "Topic: {topic}"],\
          ]);\
          const chain = prompt.pipe(new ChatOpenAI());\
\
          return chain.stream({ // return directly chain.stream\
            topic: topic,\
          });\
        },\
      },\
    ]
  }
});

// ... rest of your route definition
```

### [Test your implementation](https://docs.copilotkit.ai/guides/backend-actions/langchain-js-backend-actions\#test-your-implementation)

After adding the LangChain JS action, test it by asking the copilot to generate a joke about a specific topic. Observe how it uses the LangChain components to generate and stream the response.

[Previous\\
\\
TypeScript (Node.js)](https://docs.copilotkit.ai/guides/backend-actions/typescript-backend-actions) [Next\\
\\
LangServe actions](https://docs.copilotkit.ai/guides/backend-actions/langserve-backend-actions)

### On this page

[Integrate LangChain JS actions with CopilotRuntime](https://docs.copilotkit.ai/guides/backend-actions/langchain-js-backend-actions#integrate-langchain-js-actions-with-copilotruntime) [Test your implementation](https://docs.copilotkit.ai/guides/backend-actions/langchain-js-backend-actions#test-your-implementation)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/(root)/guides/backend-actions/langchain-js-backend-actions.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Read Agent State
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is this?

[Shared State](https://docs.copilotkit.ai/coagents/shared-state)

# Reading agent state

Read the realtime agent state in your native application.

![read agent state](https://docs.copilotkit.ai/_next/image?url=%2Fimages%2Fcoagents%2Fread-agent-state.png&w=3840&q=75)

Pictured above is the [coagent starter](https://github.com/copilotkit/copilotkit/tree/main/examples/coagents-starter) with
the [implementation](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read#implementation) section applied!

## [What is this?](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read\#what-is-this)

You can easily use the realtime agent state not only in the chat UI, but also in the native application UX.

## [When should I use this?](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read\#when-should-i-use-this)

You can use this when you want to provide the user with feedback about your agent's state. As your agent's
state updates, you can reflect these updates natively in your application.

## [Implementation](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read\#implementation)

### [Run and Connect Your Agent to CopilotKit](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read\#run-and-connect-your-agent-to-copilotkit)

You'll need to run your agent and connect it to CopilotKit before proceeding. If you haven't done so already,
you can follow the instructions in the [Getting Started](https://docs.copilotkit.ai/getting-started) guide.

If you don't already have an agent, you can use the [coagent starter](https://github.com/copilotkit/copilotkit/tree/main/examples/coagents-starter) as a starting point
as this guide uses it as a starting point.

### [Define the Agent State](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read\#define-the-agent-state)

LangGraph is stateful. As you transition between nodes, that state is updated and passed to the next node. For this example,
let's assume that our agent state looks something like this.

PythonTypeScript

agent-py/sample\_agent/agent.py

```
from copilotkit import CopilotKitState
from typing import Literal

class AgentState(CopilotKitState):
    language: Literal["english", "spanish"] = "spanish"

def chat_node(state: AgentState, config: RunnableConfig):
  # If language is not defined, set a value.
  # this is because a default value in a state class is not read on runtime
  language = state.get("language", "spanish")

  # ... add the rest of the node implementation and use the language variable

  return {
    # ... add the rest of state to return
    # return the language to make it available for the next nodes & frontend to read
    "language": language
  }
```

### [Use the `useCoAgent` Hook](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read\#use-the-usecoagent-hook)

With your agent connected and running all that is left is to call the [useCoAgent](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgent) hook, pass the agent's name, and
optionally provide an initial state.

ui/app/page.tsx

```
import { useCoAgent } from "@copilotkit/react-core";

// Define the agent state type, should match the actual state of your agent
type AgentState = {
  language: "english" | "spanish";
}

function YourMainContent() {
  const { state } = useCoAgent<AgentState>({
    name: "sample_agent",
    initialState: { language: "spanish" }  // optionally provide an initial state
  });

  // ...

  return (
    // style excluded for brevity
    <div>
      <h1>Your main content</h1>
      <p>Language: {state.language}</p>
    </div>
  );
}
```

The `state` in `useCoAgent` is reactive and will automatically update when the agent's state changes.

### [Give it a try!](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read\#give-it-a-try)

As the agent state updates, your `state` variable will automatically update with it! In this case, you'll see the
language set to "spanish" as that's the initial state we set.

## [Rendering agent state in the chat](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read\#rendering-agent-state-in-the-chat)

You can also render the agent's state in the chat UI. This is useful for informing the user about the agent's state in a
more in-context way. To do this, you can use the [useCoAgentStateRender](https://docs.copilotkit.ai/reference/v1/hooks/useCoAgentStateRender) hook.

ui/app/page.tsx

```
import { useCoAgentStateRender } from "@copilotkit/react-core";

// Define the agent state type, should match the actual state of your agent
type AgentState = {
  language: "english" | "spanish";
}

function YourMainContent() {
  // ...

  useCoAgentStateRender({
    name: "sample_agent",
    render: ({ state }) => {
      if (!state.language) return null;
      return <div>Language: {state.language}</div>;
    },
  });
  // ...
}
```

The `state` in `useCoAgentStateRender` is reactive and will automatically update when the agent's state changes.

## [Intermediately Stream and Render Agent State](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read\#intermediately-stream-and-render-agent-state)

By default, the LangGraph agent state will only update _between_ LangGraph node transitions --
which means state updates will be discontinuous and delayed.

You likely want to render the agent state as it updates **continuously.**

See **[predictive state updates](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates).**

[Previous\\
\\
Shared State](https://docs.copilotkit.ai/coagents/shared-state) [Next\\
\\
Writing agent state](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write)

### On this page

[What is this?](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read#what-is-this) [When should I use this?](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read#when-should-i-use-this) [Implementation](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read#implementation) [Run and Connect Your Agent to CopilotKit](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read#run-and-connect-your-agent-to-copilotkit) [Define the Agent State](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read#define-the-agent-state) [Use the useCoAgent Hook](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read#use-the-usecoagent-hook) [Give it a try!](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read#give-it-a-try) [Rendering agent state in the chat](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read#rendering-agent-state-in-the-chat) [Intermediately Stream and Render Agent State](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read#intermediately-stream-and-render-agent-state)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/shared-state/in-app-agent-read.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

![read agent state](https://docs.copilotkit.ai/_next/image?url=%2Fimages%2Fcoagents%2Fread-agent-state.png&w=3840&q=75)

## Human-in-the-Loop Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is this?

[Human in the Loop (HITL)](https://docs.copilotkit.ai/coagents/human-in-the-loop)

# Interrupt

Learn how to implement Human-in-the-Loop (HITL) using a interrupt-based flow.

Pictured above is the [coagent starter](https://github.com/copilotkit/copilotkit/tree/main/examples/coagents-starter) with
the implementation below applied!

## [What is this?](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow\#what-is-this)

[LangGraph's interrupt flow](https://docs.langchain.com/oss/python/langgraph/interrupts) provides an intuitive way to implement Human-in-the-loop workflows.

This guide will show you how to both use `interrupt` and how to integrate it with CopilotKit.

## [When should I use this?](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow\#when-should-i-use-this)

Human-in-the-loop is a powerful way to implement complex workflows that are production ready. By having a human in the loop,
you can ensure that the agent is always making the right decisions and ultimately is being steered in the right direction.

Interrupt-based flows are a very intuitive way to implement HITL. Instead of having a node await user input before or after its execution,
nodes can be interrupted in the middle of their execution to allow for user input. The trade-off is that the agent is not aware of the
interaction, however [CopilotKit's SDKs provide helpers to alleviate this](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#make-your-agent-aware-of-interruptions).

## [Implementation](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow\#implementation)

### [Run and connect your agent](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow\#run-and-connect-your-agent)

You'll need to run your agent and connect it to CopilotKit before proceeding. If you haven't done so already,
you can follow the instructions in the [Getting Started](https://docs.copilotkit.ai/coagents/quickstart/langgraph) guide.

If you don't already have an agent, you can use the [coagent starter](https://github.com/copilotkit/copilotkit/tree/main/examples/coagents-starter) as a starting point
as this guide uses it as a starting point.

### [Install the CopilotKit SDK](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow\#install-the-copilotkit-sdk)

Any LangGraph agent can be used with CopilotKit. However, creating deep agentic
experiences with CopilotKit requires our LangGraph SDK.

PythonTypeScript

Poetrypipconda

```
poetry add copilotkit
# including support for crewai
poetry add copilotkit[crewai]
```

### [Setup your agent state](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow\#setup-your-agent-state)

We're going to have the agent ask us to name it, so we'll need a state property to store the name.

PythonTypeScript

agent/sample\_agent/agent.py

```
# ...
from copilotkit import CopilotKitState # extends MessagesState
# ...

# This is the state of the agent.
# It inherits from the CopilotKitState properties from CopilotKit.
class AgentState(CopilotKitState):
    agent_name: str
```

Choose how to display the interrupt to the user

As a Custom Chat UI

I'd like to display a custom UI in the chat window

As Message

I'd like to display the interrupt as a copilot message

### [Call `interrupt` in your LangGraph agent](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow\#call-interrupt-in-your-langgraph-agent)

Now we can call `interrupt` in our LangGraph agent.

Your agent will not be aware of the `interrupt` interaction by default in LangGraph.

If you want this behavior, see the [section on it below](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#make-your-agent-aware-of-interruptions).

PythonTypeScript

agent/sample\_agent/agent.py

```
from langgraph.types import interrupt
from langchain_core.messages import SystemMessage
from langchain_openai import ChatOpenAI
from copilotkit import CopilotKitState

# add the agent state definition from the previous step
class AgentState(CopilotKitState):
    agent_name: str

def chat_node(state: AgentState, config: RunnableConfig):
    if not state.get("agent_name"):
    # Interrupt and wait for the user to respond with a name
    state["agent_name"] = interrupt("Before we start, what would you like to call me?")

    # Tell the agent its name
    system_message = SystemMessage(
        content=f"You are a helpful assistant named {state.get('agent_name')}..."
    )

    response = ChatOpenAI(model="gpt-4o").invoke(
        [system_message, *state["messages"]],
        config
    )

    return {
        **state,
        "messages": response,
    }
```

### [Handle the interrupt in your frontend](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow\#handle-the-interrupt-in-your-frontend)

At this point, your LangGraph agent's `interrupt` will be called. However, we currently have no handling for rendering or
responding to the interrupt in the frontend.

To do this, we'll use the `useLangGraphInterrupt` hook, give it a component to render, and then call `resolve` with the user's response.

app/page.tsx

```
import { useLangGraphInterrupt } from "@copilotkit/react-core";
// ...

const YourMainContent = () => {
// ...

// styles omitted for brevity
useLangGraphInterrupt({
    render: ({ event, resolve }) => (
        <div>
            <p>{event.value}</p>
            <form onSubmit={(e) => {
                e.preventDefault();
                resolve((e.target as HTMLFormElement).response.value);
            }}>
                <input type="text" name="response" placeholder="Enter your response" />
                <button type="submit">Submit</button>
            </form>
        </div>
    )
});
// ...

return <div>{/* ... */}</div>
}
```

### [Give it a try!](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow\#give-it-a-try)

Try talking to your agent, you'll see that it now pauses execution and waits for you to respond!

## [Make your agent aware of interruptions](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow\#make-your-agent-aware-of-interruptions)

By default, your agent will not be made aware of LangGraph `interrupts`. This is because the decision is not saved into the message's state.
For simple and sensitive flows, this is ideal. However, you may want to make your agent aware of these interactions.

If you've been using the "As Message" implementation, you may have noticed that the messages are returned from the interrupt function.
These can be used to notify the LLM about the recent communication:

PythonTypeScript

agent-py/sample\_agent/agent.py

```
from copilotkit import copilotkit_interrupt

# ...
agent_name, new_messages = copilotkit_interrupt(message="Before we start, what would you like to call me?")
state["messages"] = state["messages"] + new_messages
state["agent_name"] = agent_name
# ...
```

## [Condition UI executions](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow\#condition-ui-executions)

When opting for custom chat UI while having multiple `interrupt` events in the agent, there could be conflicts between multiple `useLangGraphInterrupt` hooks calls in the UI.
For this reason, the hook can take an `enabled` argument which will apply it conditionally:

### [Define multiple interrupts](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow\#define-multiple-interrupts)

First, let's define two different interrupts. We will include a "type" property to differentiate them.

PythonTypeScript

agent/sample\_agent/agent.py

```
from langgraph.types import interrupt
from langchain_core.messages import SystemMessage
from langchain_openai import ChatOpenAI

# ... your full state definition

def chat_node(state: AgentState, config: RunnableConfig):

  state["approval"] = interrupt({ "type": "approval", "content": "please approve" })

  if not state.get("agent_name"):
    # Interrupt and wait for the user to respond with a name
    state["agent_name"] = interrupt({ "type": "ask", "content": "Before we start, what would you like to call me?" })

  # Tell the agent its name
  system_message = SystemMessage(
    content=f"You are a helpful assistant..."
  )

  response = ChatOpenAI(model="gpt-4o").invoke(
    [system_message, *state["messages"]],
    config
  )

  return {
    **state,
    "messages": response,
  }
```

### [Add multiple frontend handlers](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow\#add-multiple-frontend-handlers)

With the differentiator in mind, we will add a handler that takes care of any "ask" and any "approve" types.
With two `useLangGraphInterrupt` hooks in our page, we can leverage the `enabled` property to enable each in the right time:

app/page.tsx

```
import { useLangGraphInterrupt } from "@copilotkit/react-core";
// ...

const ApproveComponent = ({ content, onAnswer }: { content: string; onAnswer: (approved: boolean) => void }) => (
    // styles omitted for brevity
    <div>
        <h1>Do you approve?</h1>
        <button onClick={() => onAnswer(true)}>Approve</button>
        <button onClick={() => onAnswer(false)}>Reject</button>
    </div>
)

const AskComponent = ({ question, onAnswer }: { question: string; onAnswer: (answer: string) => void }) => (
// styles omitted for brevity
    <div>
        <p>{question}</p>
        <form onSubmit={(e) => {
            e.preventDefault();
            onAnswer((e.target as HTMLFormElement).response.value);
        }}>
            <input type="text" name="response" placeholder="Enter your response" />
            <button type="submit">Submit</button>
        </form>
    </div>
)

const YourMainContent = () => {
    // ...

    useLangGraphInterrupt({
        enabled: ({ eventValue }) => eventValue.type === 'ask',
        render: ({ event, resolve }) => (
            <AskComponent question={event.value.content} onAnswer={answer => resolve(answer)} />
        )
    });

    useLangGraphInterrupt({
        enabled: ({ eventValue }) => eventValue.type === 'approval',
        render: ({ event, resolve }) => (
            <ApproveComponent content={event.value.content} onAnswer={answer => resolve(answer)} />
        )
    });

    // ...
}
```

## [Preprocessing of an interrupt and programmatically handling an interrupt value](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow\#preprocessing-of-an-interrupt-and-programmatically-handling-an-interrupt-value)

When opting for custom chat UI, some cases may require pre-processing of the incoming values of interrupt event or even resolving it entirely without showing a UI for it.
This can be achieved using the `handler` property, which is not required to return a React component.

The return value of the handler will be passed to the `render` method as the `result` argument.

app/page.tsx

```
// We will assume an interrupt event in the following shape
type Department = 'finance' | 'engineering' | 'admin'
interface AuthorizationInterruptEvent {
    type: 'auth',
    accessDepartment: Department,
}

import { useLangGraphInterrupt } from "@copilotkit/react-core";

const YourMainContent = () => {
    const [userEmail, setUserEmail] = useState({ email: 'example@user.com' })
    function getUserByEmail(email: string): { id: string; department: Department } {
        // ... an implementation of user fetching
    }

    // ...
    // styles omitted for brevity

    useLangGraphInterrupt({
        handler: async ({ result, event, resolve }) => {
            const { department } = await getUserByEmail(userEmail)
            if (event.value.accessDepartment === department || department === 'admin') {
                // Following the resolution of the event, we will not proceed to the render method
                resolve({ code: 'AUTH_BY_DEPARTMENT' })
                return;
            }

            return { department, userId }
        },
        render: ({ result, event, resolve }) => (
            <div>
                <h1>Request for {event.value.type}</h1>
                <p>Members from {result.department} department cannot access this information</p>
                <p>You can request access from an administrator to continue.</p>
                <button
                    onClick={() => resolve({ code: 'REQUEST_AUTH', data: { department: result.department, userId: result.userId } })}
                >
                    Request Access
                </button>
                <button
                    onClick={() => resolve({ code: 'CANCEL' })}
                >
                    Cancel
                </button>
            </div>
        )
    });
    // ...

    return <div>{/* ... */}</div>
}
```

[Previous\\
\\
Human in the Loop (HITL)](https://docs.copilotkit.ai/coagents/human-in-the-loop) [Next\\
\\
Node-based](https://docs.copilotkit.ai/coagents/human-in-the-loop/node-flow)

### On this page

[What is this?](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#what-is-this) [When should I use this?](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#when-should-i-use-this) [Implementation](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#implementation) [Run and connect your agent](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#run-and-connect-your-agent) [Install the CopilotKit SDK](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#install-the-copilotkit-sdk) [Setup your agent state](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#setup-your-agent-state) [Call interrupt in your LangGraph agent](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#call-interrupt-in-your-langgraph-agent) [Handle the interrupt in your frontend](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#handle-the-interrupt-in-your-frontend) [Call copilotkit\_interrupt in your LangGraph agent](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#call-copilotkit_interrupt-in-your-langgraph-agent) [Give it a try!](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#give-it-a-try) [Make your agent aware of interruptions](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#make-your-agent-aware-of-interruptions) [Condition UI executions](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#condition-ui-executions) [Define multiple interrupts](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#define-multiple-interrupts) [Add multiple frontend handlers](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#add-multiple-frontend-handlers) [Preprocessing of an interrupt and programmatically handling an interrupt value](https://docs.copilotkit.ai/coagents/human-in-the-loop/interrupt-flow#preprocessing-of-an-interrupt-and-programmatically-handling-an-interrupt-value)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/human-in-the-loop/interrupt-flow.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Writing Agent State
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is this?

[Shared State](https://docs.copilotkit.ai/coagents/shared-state)

# Writing agent state

Write to agent's state from your application.

This video shows the [coagents starter](https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter) repo with the previous steps applied to it!

## [What is this?](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#what-is-this)

This guide shows you how to write to your agent's state from your application.

## [When should I use this?](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#when-should-i-use-this)

You can use this when you want to provide the user with feedback about what your agent is doing, specifically
when your agent is calling tools. CopilotKit allows you to fully customize how these tools are rendered in the chat.

## [Implementation](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#implementation)

### [Run and Connect Your Agent to CopilotKit](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#run-and-connect-your-agent-to-copilotkit)

You'll need to run your agent and connect it to CopilotKit before proceeding. If you haven't done so already,
you can follow the instructions in the [Getting Started](https://docs.copilotkit.ai/getting-started) guide.

If you don't already have an agent, you can use the [coagent starter](https://github.com/copilotkit/copilotkit/tree/main/examples/coagents-starter) as a starting point
as this guide uses it as a starting point.

### [Define the Agent State](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#define-the-agent-state)

LangGraph is stateful. As you transition between nodes, that state is updated and passed to the next node. For this example,
let's assume that our agent state looks something like this.

PythonTypeScript

agent-py/sample\_agent/agent.py

```
from copilotkit import CopilotKitState
from typing import Literal

class AgentState(CopilotKitState):
    language: Literal["english", "spanish"] = "english"
```

### [Call `setState` function from the `useCoAgent` hook](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#call-setstate-function-from-the-usecoagent-hook)

`useCoAgent` returns a `setState` function that you can use to update the agent state. Calling this
will update the agent state and trigger a rerender of anything that depends on the agent state.

ui/app/page.tsx

```
import { useCoAgent } from "@copilotkit/react-core";

// Define the agent state type, should match the actual state of your agent
type AgentState = {
  language: "english" | "spanish";
}

// Example usage in a pseudo React component
function YourMainContent() {
  const { state, setState } = useCoAgent<AgentState>({
    name: "sample_agent",
    initialState: { language: "spanish" }  // optionally provide an initial state
  });

  // ...

  const toggleLanguage = () => {
    setState({ language: state.language === "english" ? "spanish" : "english" });
  };

  // ...

  return (
    // style excluded for brevity
    <div>
      <h1>Your main content</h1>
      <p>Language: {state.language}</p>
      <button onClick={toggleLanguage}>Toggle Language</button>
    </div>
  );
}
```

### [Give it a try!](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#give-it-a-try)

You can now use the `setState` function to update the agent state and `state` to read it. Try toggling the language button
and talking to your agent. You'll see the language change to match the agent's state.

## [Advanced Usage](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#advanced-usage)

### [Re-run the agent with a hint about what's changed](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#re-run-the-agent-with-a-hint-about-whats-changed)

The new agent state will be used next time the agent runs.
If you want to re-run it manually, use the `run` argument on the `useCoAgent` hook.

The agent will be re-run, and it will get not only the latest updated state, but also a **hint** that can depend on the data delta between the previous and the current state.

ui/app/page.tsx

```
import { useCoAgent } from "@copilotkit/react-core";
import { TextMessage, MessageRole } from "@copilotkit/runtime-client-gql";

// ...

function YourMainContent() {
  const { state, setState, run } = useCoAgent<AgentState>({
    name: "sample_agent",
    initialState: { language: "spanish" }  // optionally provide an initial state
  });

  // setup to be called when some event in the app occurs
  const toggleLanguage = () => {
    const newLanguage = state.language === "english" ? "spanish" : "english";
    setState({ language: newLanguage });

    // re-run the agent and provide a hint about what's changed
    run(({ previousState, currentState }) => {
      return new TextMessage({
        role: MessageRole.User,
        content: `the language has been updated to ${currentState.language}`,
      });
    });
  };

  return (
    // ...
  );
}
```

### [Intermediately Stream and Render Agent State](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write\#intermediately-stream-and-render-agent-state)

By default, the LangGraph agent state will only update _between_ LangGraph node transitions --
which means state updates will be discontinuous and delayed.

You likely want to render the agent state as it updates **continuously.**

See **[predictive state updates](https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates).**

[Previous\\
\\
Reading agent state](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-read) [Next\\
\\
Agent state inputs and outputs](https://docs.copilotkit.ai/coagents/shared-state/workflow-execution)

### On this page

[What is this?](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#what-is-this) [When should I use this?](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#when-should-i-use-this) [Implementation](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#implementation) [Run and Connect Your Agent to CopilotKit](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#run-and-connect-your-agent-to-copilotkit) [Define the Agent State](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#define-the-agent-state) [Call setState function from the useCoAgent hook](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#call-setstate-function-from-the-usecoagent-hook) [Give it a try!](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#give-it-a-try) [Advanced Usage](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#advanced-usage) [Re-run the agent with a hint about what's changed](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#re-run-the-agent-with-a-hint-about-whats-changed) [Intermediately Stream and Render Agent State](https://docs.copilotkit.ai/coagents/shared-state/in-app-agent-write#intermediately-stream-and-render-agent-state)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/shared-state/in-app-agent-write.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Message Management Overview
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageCan I modify the message history?

# Message flow

Message management in CoAgents operates with CopilotKit as the "ground truth" for the full chat session.
When an CoAgent session begins, it receives the existing CopilotKit chat history to maintain conversational
continuity across different agents.

While all of this information is great to know, in most cases you won't need to worry about these details to
build rich agentic applications. Use the information here as a reference when getting really deep into
the CoAgent internals.

### [Can I modify the message history?](https://docs.copilotkit.ai/coagents/concepts/message-management\#can-i-modify-the-message-history)

You can modify the message history from LangGraph by using the `RemoveMessage` class. For example to remove all messages from the chat history:

```
from langchain_core.messages import RemoveMessage

def a_node(state: AgentState, config):
    # ...
    return {"messages":  [RemoveMessage(id=m.id) for m in state['messages']]}
```

See the [LangGraph documentation](https://docs.langchain.com/oss/python/langgraph/add-memory#delete-messages) for more information.

Editing the message history is not currently supported on the front-end, but will be soon.

### [Can I persist chat history?](https://docs.copilotkit.ai/coagents/concepts/message-management\#can-i-persist-chat-history)

Yes! There are a few ways to persist various portions of a chat's history:

- [Threads](https://docs.copilotkit.ai/coagents/persistence/threads)
- [Message Persistence](https://docs.copilotkit.ai/coagents/persistence/message-persistence)
- [Agent State](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state)

## [Types of LLM Messages](https://docs.copilotkit.ai/coagents/concepts/message-management\#types-of-llm-messages)

Modern LLM interactions produce two distinct types of messages:

1. **Communication Messages**: Direct responses and interactions with users
2. **Internal Messages**: Agent "thoughts" and reasoning processes

A well known example of this pattern is OpenAI's o1 model, which has sophisticated reasoning capabilities and thoughts. Its internal
thought processes are presented distinctly from 'communication messages' which are clearly visible to the end-user.

LangGraph agents can operate similarly. An LLM call's output can be considered either a communication message, or an internal message.

### [Emitting Messages for long running tasks](https://docs.copilotkit.ai/coagents/concepts/message-management\#emitting-messages-for-long-running-tasks)

Sometimes you'll have a task that is running for a long time, and you want the user to be aware of what's happening. By default, LangGraph does not support this, because messages are only emitted on node transitions. However, CopilotKit allows you to accomplish this by using the `copilotkit_emit_message` function.

```
async def ask_name_node(state: GreetAgentState, config: RunnableConfig):
    """
    Ask the user for their name.
    """

    content = "Hey, what is your name? 🙂"

    await copilotkit_emit_message(config, content)

    # something long running here...

    return {
        "messages": AIMessage(content=content),
    }
```

Want some more help managing messages in your CoAgent application? Check out our guide on [emitting messages](https://docs.copilotkit.ai/coagents/advanced/emit-messages).

## [Message Flow](https://docs.copilotkit.ai/coagents/concepts/message-management\#message-flow)

Messages flow between CopilotKit and LangGraph in a specific way:

- All messages from LangGraph are forwarded to CopilotKit
- On a fresh agent invocation, the full CopilotKit chat history is provided to the LangGraph agent as its pre-existing chat history.

When a CoAgent completes its execution, its relevant messages become part of CopilotKit's persistent chat history. This allows for all future agent invocations to get context from the full chat history.

[Previous\\
\\
LangGraph](https://docs.copilotkit.ai/coagents/concepts/langgraph) [Next\\
\\
Common Issues](https://docs.copilotkit.ai/coagents/troubleshooting/common-issues)

### On this page

[Can I modify the message history?](https://docs.copilotkit.ai/coagents/concepts/message-management#can-i-modify-the-message-history) [Can I persist chat history?](https://docs.copilotkit.ai/coagents/concepts/message-management#can-i-persist-chat-history) [Types of LLM Messages](https://docs.copilotkit.ai/coagents/concepts/message-management#types-of-llm-messages) [Emitting Messages for long running tasks](https://docs.copilotkit.ai/coagents/concepts/message-management#emitting-messages-for-long-running-tasks) [Message Flow](https://docs.copilotkit.ai/coagents/concepts/message-management#message-flow)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/concepts/message-management.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Exiting Agent Loop
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageInstall the CopilotKit SDK

Advanced

# Exiting the agent loop

After your agent has finished a workflow, you'll usually want to explicitly end that loop by calling the CopilotKit exit method in your agent code.

Exiting the agent has different effects depending on mode:

- **Router Mode**: Exiting the agent hands responsibility for handling input back to the router, which can initiate chat, call actions, other agents, etc. The router can return to this agent later (starting a new loop) to satisfy a user request.

- **Agent Lock Mode**: Exiting the agent restarts the workflow loop for the current agent.


In this example from [our email-sending app](https://github.com/copilotkit/copilotkit/tree/main/examples/coagents-qa), the `send_email` node explicitly exits, then manually sends a response back to the user as a `ToolMessage`:

### [Install the CopilotKit SDK](https://docs.copilotkit.ai/coagents/advanced/exit-agent\#install-the-copilotkit-sdk)

Any LangGraph agent can be used with CopilotKit. However, creating deep agentic
experiences with CopilotKit requires our LangGraph SDK.

PythonTypeScript

Poetrypipconda

```
poetry add copilotkit
# including support for crewai
poetry add copilotkit[crewai]
```

### [Exit the agent loop](https://docs.copilotkit.ai/coagents/advanced/exit-agent\#exit-the-agent-loop)

This will exit the agent session as soon as the current LangGraph run is finished, either by a breakpoint or by reaching the `END` node.

PythonTypeScript

```
from copilotkit.langgraph import (copilotkit_exit)
# ...
async def send_email_node(state: EmailAgentState, config: RunnableConfig):
    """Send an email."""

    await copilotkit_exit(config)

    # get the last message and cast to ToolMessage
    last_message = cast(ToolMessage, state["messages"][-1])
    if last_message.content == "CANCEL":
        return {
            "messages": [AIMessage(content="❌ Cancelled sending email.")],
        }
    else:
        return {
            "messages": [AIMessage(content="✅ Sent email.")],
        }
```

[Previous\\
\\
Manually emitting messages](https://docs.copilotkit.ai/coagents/advanced/emit-messages) [Next\\
\\
Overview](https://docs.copilotkit.ai/coagents/tutorials/agent-native-app)

### On this page

[Install the CopilotKit SDK](https://docs.copilotkit.ai/coagents/advanced/exit-agent#install-the-copilotkit-sdk) [Exit the agent loop](https://docs.copilotkit.ai/coagents/advanced/exit-agent#exit-the-agent-loop)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/advanced/exit-agent.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Message Persistence Guide
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this page

Persistence

# Message Persistence

To learn about how to load previous messages and agent states, check out the [Loading Message History](https://docs.copilotkit.ai/coagents/persistence/loading-message-history) and [Loading Agent State](https://docs.copilotkit.ai/coagents/persistence/loading-agent-state) pages.

To persist LangGraph messages to a database, you can use either `AsyncPostgresSaver` or `AsyncSqliteSaver`. Set up the asynchronous memory by configuring the graph within a lifespan function, as follows:

```
from contextlib import asynccontextmanager
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver

@asynccontextmanager
async def lifespan(app: FastAPI):
    async with AsyncPostgresSaver.from_conn_string(
        "postgresql://postgres:postgres@127.0.0.1:5432/postgres"
    ) as checkpointer:
        # NOTE: you need to call .setup() the first time you're using your checkpointer
        await checkpointer.setup()
        # Create an async graph
        graph = workflow.compile(checkpointer=checkpointer)

        # Create SDK with the graph
        sdk = CopilotKitRemoteEndpoint(
            agents=[\
                LangGraphAgent(\
                    name="research_agent",\
                    description="Research agent.",\
                    graph=graph,\
                ),\
            ],
        )

        # Add the CopilotKit FastAPI endpoint
        add_fastapi_endpoint(app, sdk, "/copilotkit")
        yield

app = FastAPI(lifespan=lifespan)
```

To learn more about persistence in LangGraph, check out the [LangGraph documentation](https://docs.langchain.com/oss/python/langgraph/persistence).

[Previous\\
\\
Threads](https://docs.copilotkit.ai/coagents/persistence/loading-message-history) [Next\\
\\
Using Agent Execution Parameters](https://docs.copilotkit.ai/coagents/advanced/adding-runtime-configuration)

### On this page

No Headings

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/persistence/message-persistence.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)

## Emit Messages in Agents
CrewAI CrewAI support is here! Checkout the [Crew](https://docs.copilotkit.ai/crewai-crews) and [Flow](https://docs.copilotkit.ai/crewai-flows) documentation.

Search docs

`⌘`  `K`

On this pageWhat is this?

Advanced

# Manually emitting messages

While most agent interactions happen automatically through shared state updates as the agent runs, you can also **manually send messages from within your agent code** to provide immediate feedback to users.

This video shows the [coagents starter](https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter) repo with the [implementation](https://docs.copilotkit.ai/coagents/advanced/emit-messages#implementation) section applied to it!

## [What is this?](https://docs.copilotkit.ai/coagents/advanced/emit-messages\#what-is-this)

In LangGraph, messages are only emitted when a node is completed. CopilotKit allows you to manually emit messages
in the middle of a node's execution to provide immediate feedback to the user.

## [When should I use this?](https://docs.copilotkit.ai/coagents/advanced/emit-messages\#when-should-i-use-this)

Manually emitted messages are great for **when you don't want to wait for the node** to complete **and you**:

- Have a long running task that you want to provide feedback on
- Want to provide a status update to the user
- Want to provide a warning or error message

## [Implementation](https://docs.copilotkit.ai/coagents/advanced/emit-messages\#implementation)

### [Run and Connect Your Agent to CopilotKit](https://docs.copilotkit.ai/coagents/advanced/emit-messages\#run-and-connect-your-agent-to-copilotkit)

You'll need to run your agent and connect it to CopilotKit before proceeding. If you haven't done so already,
you can follow the instructions in the [Getting Started](https://docs.copilotkit.ai/coagents/quickstart/langgraph) guide.

If you don't already have an agent, you can use the [coagent starter](https://github.com/copilotkit/copilotkit/tree/main/examples/coagents-starter) as a starting point
as this guide uses it as a starting point.

### [Install the CopilotKit SDK](https://docs.copilotkit.ai/coagents/advanced/emit-messages\#install-the-copilotkit-sdk)

Any LangGraph agent can be used with CopilotKit. However, creating deep agentic
experiences with CopilotKit requires our LangGraph SDK.

PythonTypeScript

Poetrypipconda

```
poetry add copilotkit
# including support for crewai
poetry add copilotkit[crewai]
```

### [Manually emit a message](https://docs.copilotkit.ai/coagents/advanced/emit-messages\#manually-emit-a-message)

The `copilotkit_emit_message` method allows you to emit messages early in a node's execution to communicate status updates to the user. This is particularly useful for long running tasks.

PythonTypeScript

```
from langchain_core.messages import SystemMessage, AIMessage
from langchain_openai import ChatOpenAI
from langchain_core.runnables import RunnableConfig
from copilotkit.langgraph import copilotkit_emit_message
# ...

async def chat_node(state: AgentState, config: RunnableConfig):
    model = ChatOpenAI(model="gpt-4o")


    intermediate_message = "Thinking really hard..."
    await copilotkit_emit_message(config, intermediate_message)

    # simulate a long running task
    await asyncio.sleep(2)

    response = await model.ainvoke([\
        SystemMessage(content="You are a helpful assistant."),\
        *state["messages"]\
    ], config)

    return Command(
        goto=END,
        update={
            # Make sure to include the emitted message in the messages history
            "messages": [AIMessage(content=intermediate_message), response]
        }
    )
```

### [Give it a try!](https://docs.copilotkit.ai/coagents/advanced/emit-messages\#give-it-a-try)

Now when you talk to your agent you'll notice that it immediately responds with the message "Thinking really hard..."
before giving you a response 2 seconds later.

[Previous\\
\\
Disabling state streaming](https://docs.copilotkit.ai/coagents/advanced/disabling-state-streaming) [Next\\
\\
Exiting the agent loop](https://docs.copilotkit.ai/coagents/advanced/exit-agent)

### On this page

[What is this?](https://docs.copilotkit.ai/coagents/advanced/emit-messages#what-is-this) [When should I use this?](https://docs.copilotkit.ai/coagents/advanced/emit-messages#when-should-i-use-this) [Implementation](https://docs.copilotkit.ai/coagents/advanced/emit-messages#implementation) [Run and Connect Your Agent to CopilotKit](https://docs.copilotkit.ai/coagents/advanced/emit-messages#run-and-connect-your-agent-to-copilotkit) [Install the CopilotKit SDK](https://docs.copilotkit.ai/coagents/advanced/emit-messages#install-the-copilotkit-sdk) [Manually emit a message](https://docs.copilotkit.ai/coagents/advanced/emit-messages#manually-emit-a-message) [Give it a try!](https://docs.copilotkit.ai/coagents/advanced/emit-messages#give-it-a-try)

[Edit on GitHub](https://github.com/CopilotKit/CopilotKit/blob/main/docs/content/docs/coagents/advanced/emit-messages.mdx)

![](https://static.scarf.sh/a.png?x-pxid=ffc9f65d-0186-4575-b065-61d62ea9d7d3)
