chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:58:18 +08:00
commit 6d5d58c1a9
18293 changed files with 3502153 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
# @copilotkit/docs
## 0.1.8
## 0.1.7
## 0.1.6
## 0.1.5
## 0.1.4
## 0.1.3
## 0.1.2
## 0.1.1
+102
View File
@@ -0,0 +1,102 @@
{
"$schema": "https://mintlify.com/schema.json",
"name": "CopilotKit vnext_experimental",
"theme": "mint",
"logo": {
"dark": "/logo/dark.svg",
"light": "/logo/light.svg"
},
"favicon": "/favicon.ico",
"colors": {
"primary": "#0D9373",
"light": "#07C983",
"dark": "#0D9373"
},
"topbarLinks": [
{
"name": "Support",
"url": "mailto:hi@copilotkit.ai"
}
],
"topbarCtaButton": {
"name": "Dashboard",
"url": "https://dashboard.copilotkit.ai"
},
"navigation": {
"anchors": [
{
"name": "Community",
"icon": "slack",
"url": "https://discord.gg/6dffbvGU3D"
},
{
"name": "Blog",
"icon": "newspaper",
"url": "https://copilotkit.ai/blog"
}
],
"groups": [
{
"group": "Get Started",
"pages": ["introduction"]
},
{
"group": "API Reference",
"pages": [
{
"group": "Core",
"pages": [
"reference/copilotkit-core",
"reference/proxied-copilot-runtime-agent",
"reference/frontend-tool"
]
},
{
"group": "React",
"pages": [
{
"group": "Providers",
"pages": [
"reference/copilotkit-provider",
"reference/copilot-chat-configuration-provider"
]
},
{
"group": "Components",
"pages": [
"reference/copilot-chat",
"reference/copilot-sidebar",
"reference/copilot-popup",
"reference/copilot-chat-message-view",
"reference/copilot-chat-input",
"reference/copilot-chat-assistant-message",
"reference/copilot-chat-user-message",
"reference/copilot-chat-scroll-view",
"reference/copilot-chat-suggestion-view",
"reference/copilot-chat-welcome-screen",
"reference/slot-system"
]
},
{
"group": "Hooks",
"pages": [
"reference/use-copilotkit",
"reference/use-agent",
"reference/use-agent-context",
"reference/use-frontend-tool",
"reference/use-human-in-the-loop",
"reference/use-render-tool-call"
]
}
]
}
]
}
]
},
"footerSocials": {
"x": "https://x.com/copilotkit",
"github": "https://github.com/copilotkit/copilotkit",
"linkedin": "https://www.linkedin.com/company/copilotkit"
}
}
+92
View File
@@ -0,0 +1,92 @@
---
title: CopilotKit VNext Documentation
description: "CopilotKit VNext Documentation"
---
## API Reference
### Core
<Card title="CopilotKitCore" icon="code" href="/reference/copilotkit-core">
Core CopilotKit class
</Card>
<Card title="CopilotRuntime" icon="server" href="/reference/copilot-runtime">
Host agents and expose runtime endpoints
</Card>
<Card
title="ProxiedCopilotRuntimeAgent"
icon="server"
href="/reference/proxied-copilot-runtime-agent"
>
Proxied runtime agent for CopilotKit
</Card>
<Card title="FrontendTool" icon="wrench" href="/reference/frontend-tool">
Frontend tool utilities
</Card>
### React
#### Providers
<Card
title="CopilotKitProvider"
icon="layer-group"
href="/reference/copilotkit-provider"
>
Main provider for CopilotKit React integration
</Card>
<Card
title="CopilotChatConfigurationProvider"
icon="cog"
href="/reference/copilot-chat-configuration-provider"
>
Configuration provider for CopilotChat
</Card>
#### Components
<Card title="CopilotChat" icon="comments" href="/reference/copilot-chat">
Chat component for CopilotKit
</Card>
#### Hooks
<Card title="useCopilotKit" icon="link" href="/reference/use-copilotkit">
Main hook for CopilotKit functionality
</Card>
<Card title="useAgent" icon="robot" href="/reference/use-agent">
Hook for agent interactions
</Card>
<Card
title="useAgentContext"
icon="square-check"
href="/reference/use-agent-context"
>
Hook for agent context management
</Card>
<Card title="useFrontendTool" icon="hammer" href="/reference/use-frontend-tool">
Hook for frontend tools
</Card>
<Card
title="useHumanInTheLoop"
icon="user-check"
href="/reference/use-human-in-the-loop"
>
Hook for human-in-the-loop functionality
</Card>
<Card
title="useRenderToolCall"
icon="paintbrush"
href="/reference/use-render-tool-call"
>
Hook for rendering tool calls
</Card>
+16
View File
@@ -0,0 +1,16 @@
{
"name": "@copilotkit/docs",
"version": "0.1.8",
"private": true,
"scripts": {
"dev": "mintlify dev --port 4000",
"lint": "mintlify broken-links",
"check-types": "echo 'No TypeScript compilation needed for Mintlify docs'"
},
"dependencies": {
"sharp": "^0.34.2"
},
"devDependencies": {
"mintlify": "^4.2.127"
}
}
@@ -0,0 +1,344 @@
---
title: CopilotChatAssistantMessage
description: "AI response rendering component with toolbar actions"
---
`CopilotChatAssistantMessage` is the default component used by [CopilotChatMessageView](/reference/copilot-chat-message-view) to render AI assistant responses. It handles markdown rendering, feedback collection, and tool call display.
## What is CopilotChatAssistantMessage?
The CopilotChatAssistantMessage component:
- Renders AI responses with full markdown support
- Provides a toolbar with copy, feedback, and action buttons
- Handles thumbs up/down feedback collection
- Supports text-to-speech (read aloud) functionality
- Displays tool call executions with visual feedback
- Built on the [slot system](/reference/slot-system) for deep customization
## Component Architecture
CopilotChatAssistantMessage provides slots for customizing each part of the message:
```mermaid
graph LR
AM[CopilotChatAssistantMessage] --> markdownRenderer
AM --> toolbar
AM --> copyButton
AM --> thumbsUpButton
AM --> thumbsDownButton
AM --> readAloudButton
AM --> regenerateButton
AM --> toolCallsView
```
### Slot Descriptions
| Slot | Description |
| ------------------ | ------------------------------------------------- |
| `markdownRenderer` | Renders the message content with markdown support |
| `toolbar` | Container for action buttons |
| `copyButton` | Button to copy message content |
| `thumbsUpButton` | Positive feedback button |
| `thumbsDownButton` | Negative feedback button |
| `readAloudButton` | Text-to-speech button |
| `regenerateButton` | Button to regenerate the response |
| `toolCallsView` | Renders tool call executions |
## Basic Usage
Customize assistant messages through the `messageView.assistantMessage` slot on [CopilotChat](/reference/copilot-chat):
```tsx
<CopilotChat
messageView={{
assistantMessage: {
className: "bg-slate-50 rounded-xl p-4",
onThumbsUp: (message) => trackFeedback(message.id, "positive"),
onThumbsDown: (message) => trackFeedback(message.id, "negative"),
},
}}
/>
```
## Feedback Callbacks
CopilotChatAssistantMessage provides callbacks for user feedback:
```tsx
<CopilotChat
messageView={{
assistantMessage: {
onThumbsUp: (message) => {
analytics.track("positive_feedback", {
messageId: message.id,
content: message.content,
});
},
onThumbsDown: (message) => {
analytics.track("negative_feedback", {
messageId: message.id,
content: message.content,
});
},
onRegenerate: (message) => {
console.log("Regenerating:", message.id);
},
onReadAloud: (message) => {
speechSynthesis.speak(new SpeechSynthesisUtterance(message.content));
},
},
}}
/>
```
### Callback Props
| Callback | Signature | Description |
| -------------- | ------------------------------------- | -------------------------------------- |
| `onThumbsUp` | `(message: AssistantMessage) => void` | Called when user clicks thumbs up |
| `onThumbsDown` | `(message: AssistantMessage) => void` | Called when user clicks thumbs down |
| `onRegenerate` | `(message: AssistantMessage) => void` | Called when user requests regeneration |
| `onReadAloud` | `(message: AssistantMessage) => void` | Called when user clicks read aloud |
## Slot Customization
CopilotChatAssistantMessage uses the [slot system](/reference/slot-system). Each slot accepts four types of values:
1. **Tailwind class string** - Add or override CSS classes
2. **Props object** - Pass additional props to the default component
3. **Custom component** - Replace the component entirely
4. **Nested sub-slots** - Drill down to customize child components
### Toolbar Customization
Control visibility and styling of the toolbar:
```tsx
<CopilotChat
messageView={{
assistantMessage: {
toolbar: "bg-gray-50 rounded-lg p-2",
},
}}
/>
```
To hide the entire toolbar:
```tsx
<CopilotChat
messageView={{
assistantMessage: {
toolbarVisible: false,
},
}}
/>
```
### Individual Button Customization
Customize specific toolbar buttons:
```tsx
<CopilotChat
messageView={{
assistantMessage: {
copyButton: "text-blue-500 hover:text-blue-700",
thumbsUpButton: "text-green-500 hover:text-green-700",
thumbsDownButton: "text-red-500 hover:text-red-700",
readAloudButton: "text-purple-500 hover:text-purple-700",
regenerateButton: "text-orange-500 hover:text-orange-700",
},
}}
/>
```
### Hiding Specific Buttons
Hide buttons by returning null:
```tsx
<CopilotChat
messageView={{
assistantMessage: {
readAloudButton: () => null,
regenerateButton: () => null,
},
}}
/>
```
Note: `thumbsUpButton` and `thumbsDownButton` only show when their respective callbacks (`onThumbsUp`, `onThumbsDown`) are provided.
### Markdown Renderer Customization
Customize how message content is rendered:
```tsx
<CopilotChat
messageView={{
assistantMessage: {
markdownRenderer: {
className: "prose prose-lg dark:prose-invert",
},
},
}}
/>
```
### Tool Calls View Customization
Customize how tool executions are displayed:
```tsx
<CopilotChat
messageView={{
assistantMessage: {
toolCallsView: "bg-gray-100 rounded-lg p-3",
},
}}
/>
```
## Replacing the Component
To completely replace the assistant message component:
```tsx
import { CopilotChatAssistantMessage } from "@copilotkit/react-core";
function CustomAssistantMessage({ message, isRunning, ...props }) {
return (
<div className="flex gap-3 items-start">
<Avatar src="/ai-avatar.png" />
<div className="flex-1">
<CopilotChatAssistantMessage
message={message}
isRunning={isRunning}
className="bg-white shadow-sm rounded-xl p-4"
{...props}
/>
</div>
</div>
);
}
<CopilotChat
messageView={{
assistantMessage: CustomAssistantMessage,
}}
/>;
```
### Using the Render Function
For full layout control, use the children render function:
```tsx
function CustomAssistantMessage(props) {
return (
<CopilotChatAssistantMessage {...props}>
{({ markdownRenderer, toolbar, toolCallsView, message }) => (
<div className="flex gap-4 p-4 bg-gradient-to-r from-blue-50 to-purple-50 rounded-xl">
<img src="/ai-avatar.png" className="w-8 h-8 rounded-full" />
<div className="flex-1">
<div className="text-sm text-gray-500 mb-1">AI Assistant</div>
{markdownRenderer}
{toolCallsView}
<div className="mt-2 border-t pt-2">{toolbar}</div>
</div>
</div>
)}
</CopilotChatAssistantMessage>
);
}
<CopilotChat
messageView={{
assistantMessage: CustomAssistantMessage,
}}
/>;
```
The render function receives:
| Property | Type | Description |
| ------------------ | ------------------ | ----------------------------- |
| `markdownRenderer` | `ReactElement` | The rendered markdown content |
| `toolbar` | `ReactElement` | The action buttons toolbar |
| `toolCallsView` | `ReactElement` | Tool call display |
| `copyButton` | `ReactElement` | Copy button |
| `thumbsUpButton` | `ReactElement` | Thumbs up button |
| `thumbsDownButton` | `ReactElement` | Thumbs down button |
| `readAloudButton` | `ReactElement` | Read aloud button |
| `regenerateButton` | `ReactElement` | Regenerate button |
| `message` | `AssistantMessage` | The message data |
| `isRunning` | `boolean` | Whether AI is generating |
| `toolbarVisible` | `boolean` | Whether toolbar should show |
## Examples
### Analytics Integration
```tsx
<CopilotChat
messageView={{
assistantMessage: {
onThumbsUp: (message) => {
analytics.track("ai_feedback", {
type: "positive",
messageId: message.id,
messageLength: message.content?.length,
timestamp: new Date().toISOString(),
});
},
onThumbsDown: (message) => {
analytics.track("ai_feedback", {
type: "negative",
messageId: message.id,
messageLength: message.content?.length,
timestamp: new Date().toISOString(),
});
},
},
}}
/>
```
### Minimal Toolbar
Show only the copy button:
```tsx
<CopilotChat
messageView={{
assistantMessage: {
thumbsUpButton: () => null,
thumbsDownButton: () => null,
readAloudButton: () => null,
regenerateButton: () => null,
},
}}
/>
```
### Custom Styling
```tsx
<CopilotChat
messageView={{
assistantMessage: {
className: "bg-white shadow-md rounded-2xl p-6 border border-gray-100",
markdownRenderer: "prose prose-blue max-w-none",
toolbar: "mt-4 pt-4 border-t border-gray-100",
},
}}
/>
```
## Related
- [CopilotChat](/reference/copilot-chat) - Parent component
- [CopilotChatMessageView](/reference/copilot-chat-message-view) - Message list component that uses assistant messages
- [Slot System](/reference/slot-system) - Deep dive into slot customization
@@ -0,0 +1,184 @@
---
title: CopilotChatConfigurationProvider
description: "CopilotChatConfigurationProvider API Reference"
---
`CopilotChatConfigurationProvider` is a React context provider that manages configuration for chat UI components,
including labels, agent ID, and thread ID. It enables customization of all text labels in the chat interface and
provides context for chat components to access configuration values.
## What is CopilotChatConfigurationProvider?
The CopilotChatConfigurationProvider:
- Manages UI labels for all chat components (placeholders, button labels, etc.), allowing for localization or
customization of the chat interface.
- Lets you to access the current `agentId` and `threadId`
- Supports nested configuration with proper inheritance
## Basic Usage
Wrap your chat components with the provider to customize configuration:
```tsx
import { CopilotChatConfigurationProvider } from "@copilotkit/react-core";
function App() {
return (
<CopilotChatConfigurationProvider
threadId="main-thread"
agentId="assistant"
labels={{
chatInputPlaceholder: "Ask me anything...",
assistantMessageToolbarCopyMessageLabel: "Copy response",
}}
>
{/* Your chat components */}
</CopilotChatConfigurationProvider>
);
}
```
## Props
### threadId
`string` **(required)**
A unique identifier for the conversation thread. This is used to maintain conversation history and context.
```tsx
<CopilotChatConfigurationProvider threadId="conversation-123">
{children}
</CopilotChatConfigurationProvider>
```
### agentId
`string` **(optional)**
The ID of the agent to use for this chat context. If not provided, defaults to `"default"`.
```tsx
<CopilotChatConfigurationProvider
threadId="thread-1"
agentId="customer-support"
>
{children}
</CopilotChatConfigurationProvider>
```
### labels
`Partial<CopilotChatLabels>` **(optional)**
Custom labels for chat UI elements. Any labels not provided will use the default values.
```tsx
<CopilotChatConfigurationProvider
threadId="thread-1"
labels={{
chatInputPlaceholder: "Type your message here...",
chatDisclaimerText: "AI responses may contain errors.",
assistantMessageToolbarRegenerateLabel: "Try again",
}}
>
{children}
</CopilotChatConfigurationProvider>
```
### children
`ReactNode` **(required)**
The React components that will have access to the chat configuration context.
## Using with CopilotChat
The `CopilotChat` component automatically creates its own `CopilotChatConfigurationProvider` internally. When using
`CopilotChat`, you can pass configuration directly as props:
```tsx
<CopilotChat
threadId="main-thread"
agentId="assistant"
labels={{
chatInputPlaceholder: "How can I help you today?",
}}
/>
```
### Priority System
When `CopilotChat` is used within an existing `CopilotChatConfigurationProvider`, values are merged with the following
priority (highest to lowest):
1. Props passed directly to `CopilotChat`
2. Values from the outer `CopilotChatConfigurationProvider`
3. Default values
Example:
```tsx
<CopilotChatConfigurationProvider agentId="outer-agent">
<CopilotChat
threadId="inner-thread"
// agentId inherits from outer: "outer-agent"
/>
</CopilotChatConfigurationProvider>
```
## Accessing Configuration
Use the `useCopilotChatConfiguration` hook to access configuration values in your components:
```tsx
import { useCopilotChatConfiguration } from "@copilotkit/react-core";
function MyComponent() {
const config = useCopilotChatConfiguration();
if (!config) {
// No provider found
return null;
}
return (
<div>
<p>Agent: {config.agentId}</p>
<p>Thread: {config.threadId}</p>
<p>Labels: {JSON.stringify(config.labels)}</p>
</div>
);
}
```
Note: The hook returns `null` if no provider is found in the component tree.
## Localization Example
The provider is ideal for implementing localization:
```tsx
import { useTranslation } from "react-i18next";
function LocalizedChat() {
const { t } = useTranslation();
return (
<CopilotChatConfigurationProvider
threadId="chat-1"
labels={{
chatInputPlaceholder: t("chat.input.placeholder"),
assistantMessageToolbarCopyMessageLabel: t("chat.assistant.copy"),
assistantMessageToolbarThumbsUpLabel: t("chat.assistant.thumbsUp"),
assistantMessageToolbarThumbsDownLabel: t("chat.assistant.thumbsDown"),
userMessageToolbarEditMessageLabel: t("chat.user.edit"),
chatDisclaimerText: t("chat.disclaimer"),
}}
>
<CopilotChat />
</CopilotChatConfigurationProvider>
);
}
```
@@ -0,0 +1,302 @@
---
title: CopilotChatInput
description: "Text input component with voice transcription and tools menu"
---
`CopilotChatInput` is the default input component used by [CopilotChat](/reference/copilot-chat). It provides a full-featured text input with support for voice transcription, slash commands, and customizable toolbar buttons.
## What is CopilotChatInput?
The CopilotChatInput component:
- Provides a rich text input with auto-expanding height
- Supports voice transcription via microphone button
- Includes a slash command menu for quick actions
- Shows a tools/add menu button for file uploads and custom actions
- Handles send and stop functionality during streaming
- Built on the [slot system](/reference/slot-system) for deep customization
## Component Architecture
CopilotChatInput provides slots for customizing each part of the input:
```mermaid
graph LR
Input[CopilotChatInput] --> textArea
Input --> sendButton
Input --> startTranscribeButton
Input --> cancelTranscribeButton
Input --> finishTranscribeButton
Input --> addMenuButton
Input --> audioRecorder
Input --> disclaimer
```
### Slot Descriptions
| Slot | Description |
| ------------------------ | ------------------------------------------- |
| `textArea` | The main textarea input element |
| `sendButton` | Send message or stop generation button |
| `startTranscribeButton` | Button to start voice recording |
| `cancelTranscribeButton` | Button to cancel voice recording |
| `finishTranscribeButton` | Button to finish voice recording |
| `addMenuButton` | Plus button for file uploads and tools menu |
| `audioRecorder` | Voice recording visualization component |
| `disclaimer` | Disclaimer text shown below the input |
## Basic Usage
Customize the input through the `input` prop on [CopilotChat](/reference/copilot-chat):
```tsx
<CopilotChat
input={{
className: "border-2 border-blue-200 rounded-xl",
sendButton: "bg-blue-500 hover:bg-blue-600",
}}
/>
```
## Input Modes
CopilotChatInput operates in three modes:
| Mode | Description |
| ------------ | ---------------------------------------- |
| `input` | Normal text input mode (default) |
| `transcribe` | Voice recording mode |
| `processing` | Shows loading spinner while transcribing |
The component automatically switches between modes based on user interaction with the transcription buttons.
## Slot Customization
CopilotChatInput uses the [slot system](/reference/slot-system). Each slot accepts four types of values:
1. **Tailwind class string** - Add or override CSS classes
2. **Props object** - Pass additional props to the default component
3. **Custom component** - Replace the component entirely
4. **Nested sub-slots** - Drill down to customize child components
### TextArea Customization
The `textArea` slot controls the main text input:
```tsx
<CopilotChat
input={{
textArea: {
className: "text-lg font-medium",
placeholder: "What's on your mind?",
},
}}
/>
```
### Send Button Customization
The `sendButton` slot controls the send/stop button:
```tsx
<CopilotChat
input={{
sendButton: "bg-green-500 hover:bg-green-600 text-white",
}}
/>
```
Or with a custom component:
```tsx
function CustomSendButton({ onClick, disabled, children }) {
return (
<button
onClick={onClick}
disabled={disabled}
className="px-4 py-2 bg-gradient-to-r from-blue-500 to-purple-500 text-white rounded-lg"
>
{children}
</button>
);
}
<CopilotChat
input={{
sendButton: CustomSendButton,
}}
/>;
```
### Transcription Buttons
Customize the voice transcription buttons:
```tsx
<CopilotChat
input={{
startTranscribeButton: "text-blue-500",
cancelTranscribeButton: "text-red-500",
finishTranscribeButton: "text-green-500",
}}
/>
```
### Add Menu Button
The add menu button shows a dropdown with file upload and custom tool options:
```tsx
<CopilotChat
input={{
addMenuButton: "text-gray-500 hover:text-gray-700",
}}
/>
```
### Disclaimer Customization
The `disclaimer` slot shows helper text below the input:
```tsx
<CopilotChat
input={{
disclaimer: "text-xs text-gray-400 italic",
}}
/>
```
To hide the disclaimer entirely:
```tsx
<CopilotChat
input={{
disclaimer: () => null,
}}
/>
```
## Replacing the Component
To completely replace the input with your own component:
```tsx
import { CopilotChatInput } from "@copilotkit/react-core";
function CustomInput({ onSubmitMessage, isRunning, onStop, ...props }) {
return (
<div className="custom-input-wrapper">
<CopilotChatInput
onSubmitMessage={onSubmitMessage}
isRunning={isRunning}
onStop={onStop}
textArea="bg-gray-50"
sendButton="bg-blue-600"
{...props}
/>
</div>
);
}
<CopilotChat input={CustomInput} />;
```
### Using the Render Function
For full control, use the children render function pattern:
```tsx
function CustomInput(props) {
return (
<CopilotChatInput {...props}>
{({ textArea, sendButton, addMenuButton }) => (
<div className="flex items-center gap-2 p-4 bg-gray-100 rounded-xl">
{addMenuButton}
<div className="flex-1">{textArea}</div>
{sendButton}
</div>
)}
</CopilotChatInput>
);
}
<CopilotChat input={CustomInput} />;
```
The render function receives:
| Property | Type | Description |
| ------------------------ | ----------------------------------------- | ----------------------------- |
| `textArea` | `ReactElement` | The bound textarea component |
| `sendButton` | `ReactElement` | The bound send/stop button |
| `startTranscribeButton` | `ReactElement` | Start recording button |
| `cancelTranscribeButton` | `ReactElement` | Cancel recording button |
| `finishTranscribeButton` | `ReactElement` | Finish recording button |
| `addMenuButton` | `ReactElement` | The tools menu button |
| `audioRecorder` | `ReactElement` | Voice recording visualization |
| `disclaimer` | `ReactElement` | The disclaimer text |
| `mode` | `'input' \| 'transcribe' \| 'processing'` | Current input mode |
| `isRunning` | `boolean` | Whether AI is generating |
## Keyboard Shortcuts
| Shortcut | Action |
| ------------- | ------------------------------------ |
| `Enter` | Send message (or stop if generating) |
| `Shift+Enter` | Insert newline |
| `/` | Open slash command menu |
| `Escape` | Close slash command menu |
| `↑/↓` | Navigate slash menu items |
## Examples
### Custom Styled Input
```tsx
<CopilotChat
input={{
className: "shadow-lg",
textArea: "text-base placeholder:text-gray-400",
sendButton: "bg-indigo-600 hover:bg-indigo-700",
addMenuButton: "text-indigo-600",
}}
/>
```
### Hiding the Disclaimer
```tsx
<CopilotChat
input={{
disclaimer: () => null,
}}
/>
```
### Custom Disclaimer Text
Use labels to customize the disclaimer text:
```tsx
<CopilotChat
labels={{
chatDisclaimerText:
"AI responses may contain errors. Always verify important information.",
}}
/>
```
### Hide Transcription Button
```tsx
<CopilotChat
input={{
startTranscribeButton: () => null,
}}
/>
```
## Related
- [CopilotChat](/reference/copilot-chat) - Parent component that uses CopilotChatInput
- [Slot System](/reference/slot-system) - Deep dive into slot customization
@@ -0,0 +1,286 @@
---
title: CopilotChatMessageView
description: "Message list container component"
---
`CopilotChatMessageView` is the default component used by [CopilotChat](/reference/copilot-chat) to render the message list. It handles rendering user messages, assistant messages, activity messages, and custom message renderers with optimized memoization for performance.
## What is CopilotChatMessageView?
The CopilotChatMessageView component:
- Renders the conversation message list
- Handles user, assistant, and activity message types
- Supports custom message renderers for extensibility
- Optimizes re-renders with memoization
- Shows a typing cursor during streaming responses
- Built on the [slot system](/reference/slot-system) for deep customization
## Component Architecture
CopilotChatMessageView provides slots for customizing message rendering:
```mermaid
graph LR
MV[CopilotChatMessageView] --> assistantMessage
MV --> userMessage
MV --> cursor
```
### Slot Descriptions
| Slot | Description |
| ------------------ | ----------------------------------------------- |
| `assistantMessage` | Component for rendering assistant (AI) messages |
| `userMessage` | Component for rendering user messages |
| `cursor` | Typing indicator shown during streaming |
## Basic Usage
Customize the message view through the `messageView` prop on [CopilotChat](/reference/copilot-chat):
```tsx
<CopilotChat
messageView={{
className: "space-y-4 p-4",
assistantMessage: "bg-blue-50 rounded-lg",
userMessage: "bg-gray-100 rounded-lg",
}}
/>
```
## Slot Customization
CopilotChatMessageView uses the [slot system](/reference/slot-system). Each slot accepts four types of values:
1. **Tailwind class string** - Add or override CSS classes
2. **Props object** - Pass additional props to the default component
3. **Custom component** - Replace the component entirely
4. **Nested sub-slots** - Drill down to customize child components
### Assistant Message Customization
The `assistantMessage` slot controls how AI responses are rendered:
```tsx
<CopilotChat
messageView={{
assistantMessage: {
className: "bg-slate-50 border border-slate-200 rounded-xl p-4",
onThumbsUp: (message) => sendFeedback(message.id, "positive"),
onThumbsDown: (message) => sendFeedback(message.id, "negative"),
onRegenerate: (message) => regenerateResponse(message.id),
},
}}
/>
```
#### Assistant Message Sub-Slots
| Sub-Slot | Description |
| ------------------ | ------------------------------------------------- |
| `markdownRenderer` | Renders the message content with markdown support |
| `toolbar` | Container for action buttons |
| `copyButton` | Button to copy message content |
| `thumbsUpButton` | Positive feedback button |
| `thumbsDownButton` | Negative feedback button |
| `readAloudButton` | Text-to-speech button |
| `regenerateButton` | Button to regenerate the response |
| `toolCallsView` | Renders tool call executions |
For full details, see [CopilotChatAssistantMessage](/reference/copilot-chat-assistant-message).
### User Message Customization
The `userMessage` slot controls how user messages are rendered:
```tsx
<CopilotChat
messageView={{
userMessage: {
className: "bg-primary text-primary-foreground rounded-2xl px-4 py-2",
onEditMessage: ({ message }) => editMessage(message),
},
}}
/>
```
#### User Message Sub-Slots
| Sub-Slot | Description |
| ------------------ | ------------------------------------ |
| `messageRenderer` | Renders the message text content |
| `toolbar` | Container for action buttons |
| `copyButton` | Button to copy message content |
| `editButton` | Button to edit the message |
| `branchNavigation` | Navigation for conversation branches |
For full details, see [CopilotChatUserMessage](/reference/copilot-chat-user-message).
### Cursor Customization
The cursor appears while the AI is generating a response:
```tsx
<CopilotChat
messageView={{
cursor: "bg-blue-500 w-3 h-3",
}}
/>
```
Or with a custom component:
```tsx
function CustomCursor() {
return (
<div className="flex gap-1">
<span className="w-2 h-2 bg-blue-500 rounded-full animate-bounce" />
<span className="w-2 h-2 bg-blue-500 rounded-full animate-bounce delay-100" />
<span className="w-2 h-2 bg-blue-500 rounded-full animate-bounce delay-200" />
</div>
);
}
<CopilotChat
messageView={{
cursor: CustomCursor,
}}
/>;
```
## Replacing the Message View
To completely replace the message view with your own component, pass a custom component to the `messageView` prop:
```tsx
import { CopilotChatMessageView } from "@copilotkit/react-core";
function CustomMessageView({ messages, isRunning, ...props }) {
return (
<div className="custom-message-list">
<div className="message-count text-sm text-muted-foreground mb-4">
{messages.length} messages
</div>
{/* Use the default implementation with customizations */}
<CopilotChatMessageView
messages={messages}
isRunning={isRunning}
className="space-y-6"
assistantMessage="bg-white shadow-sm rounded-xl p-4"
userMessage="bg-blue-500 text-white rounded-2xl"
{...props}
/>
{isRunning && (
<div className="text-center text-muted-foreground mt-4">
AI is thinking...
</div>
)}
</div>
);
}
<CopilotChat messageView={CustomMessageView} />;
```
### Using the Render Function
For even more control, use the children render function pattern:
```tsx
function CustomMessageView({ messages, isRunning }) {
return (
<CopilotChatMessageView messages={messages} isRunning={isRunning}>
{({ messageElements, messages, isRunning }) => (
<div className="custom-layout">
<header className="sticky top-0 bg-background p-2 border-b">
{messages.length} messages
</header>
<div className="messages p-4">{messageElements}</div>
{isRunning && (
<footer className="sticky bottom-0 bg-background p-2">
Generating response...
</footer>
)}
</div>
)}
</CopilotChatMessageView>
);
}
<CopilotChat messageView={CustomMessageView} />;
```
The render function receives:
| Property | Type | Description |
| ----------------- | ---------------- | ------------------------------- |
| `messageElements` | `ReactElement[]` | Pre-rendered message components |
| `messages` | `Message[]` | Raw message data |
| `isRunning` | `boolean` | Whether AI is generating |
## Examples
### Styling All Messages
```tsx
<CopilotChat
messageView={{
className: "space-y-6 p-4",
assistantMessage: "bg-white shadow-sm rounded-xl p-4",
userMessage: "bg-blue-500 text-white rounded-2xl px-4 py-2",
}}
/>
```
### Adding Feedback Handlers
```tsx
<CopilotChat
messageView={{
assistantMessage: {
onThumbsUp: (message) => {
analytics.track("positive_feedback", { messageId: message.id });
},
onThumbsDown: (message) => {
analytics.track("negative_feedback", { messageId: message.id });
},
},
}}
/>
```
### Custom Assistant Message Component
Replace the assistant message component entirely:
```tsx
function CustomAssistantMessage({ message, isRunning }) {
return (
<div className="flex gap-3">
<Avatar src="/bot-avatar.png" />
<div className="flex-1">
<Markdown>{message.content}</Markdown>
{isRunning && <TypingIndicator />}
</div>
</div>
);
}
<CopilotChat
messageView={{
assistantMessage: CustomAssistantMessage,
}}
/>;
```
## Related
- [CopilotChat](/reference/copilot-chat) - Parent component that uses CopilotChatMessageView
- [CopilotChatAssistantMessage](/reference/copilot-chat-assistant-message) - Assistant message customization
- [CopilotChatUserMessage](/reference/copilot-chat-user-message) - User message customization
- [Slot System](/reference/slot-system) - Deep dive into slot customization
@@ -0,0 +1,205 @@
---
title: CopilotChatScrollView
description: "Scrollable message container with auto-scroll behavior"
---
`CopilotChatScrollView` is the default scroll container used by [CopilotChat](/reference/copilot-chat). It handles auto-scrolling during message streaming, provides a scroll-to-bottom button, and displays a gradient fade (feather) overlay.
## What is CopilotChatScrollView?
The CopilotChatScrollView component:
- Provides a scrollable container for the message list
- Auto-scrolls to bottom during AI response streaming
- Shows a scroll-to-bottom button when scrolled up
- Includes a gradient "feather" overlay for visual polish
- Built on the [slot system](/reference/slot-system) for deep customization
## Component Architecture
CopilotChatScrollView provides slots for customizing its visual elements:
```mermaid
graph LR
SV[CopilotChatScrollView] --> scrollToBottomButton
SV --> feather
```
### Slot Descriptions
| Slot | Description |
| ---------------------- | ------------------------------------------------------ |
| `scrollToBottomButton` | Button that appears when scrolled up from bottom |
| `feather` | Gradient fade overlay at the bottom of the scroll area |
## Basic Usage
Customize the scroll view through the `scrollView` prop on [CopilotChat](/reference/copilot-chat):
```tsx
<CopilotChat
scrollView={{
scrollToBottomButton: "bg-blue-500 hover:bg-blue-600",
}}
/>
```
## Auto-Scroll Behavior
By default, CopilotChatScrollView automatically scrolls to the bottom when:
- New messages are added to the conversation
- The AI is streaming a response
- The user is already near the bottom of the scroll area
To disable auto-scroll:
```tsx
<CopilotChat autoScroll={false} />
```
When auto-scroll is disabled, users must manually scroll to see new messages. The scroll-to-bottom button will appear when new content is available below the viewport.
## Slot Customization
CopilotChatScrollView uses the [slot system](/reference/slot-system). Each slot accepts four types of values:
1. **Tailwind class string** - Add or override CSS classes
2. **Props object** - Pass additional props to the default component
3. **Custom component** - Replace the component entirely
4. **Nested sub-slots** - Drill down to customize child components
### Scroll-to-Bottom Button Customization
Style the scroll-to-bottom button:
```tsx
<CopilotChat
scrollView={{
scrollToBottomButton: "bg-blue-500 shadow-xl rounded-full",
}}
/>
```
Or with a custom component:
```tsx
function CustomScrollButton({ onClick }) {
return (
<button
onClick={onClick}
className="px-4 py-2 bg-gradient-to-r from-blue-500 to-purple-500 text-white rounded-lg shadow-lg"
>
Jump to latest
</button>
);
}
<CopilotChat
scrollView={{
scrollToBottomButton: CustomScrollButton,
}}
/>;
```
### Feather (Gradient Overlay) Customization
The feather provides a gradient fade at the bottom of the scroll area:
```tsx
<CopilotChat
scrollView={{
feather: "from-blue-50 via-blue-50 to-transparent",
}}
/>
```
To remove the feather entirely:
```tsx
<CopilotChat
scrollView={{
feather: () => null,
}}
/>
```
## Replacing the Scroll View
To completely replace the scroll view with your own component:
```tsx
import { CopilotChatView } from "@copilotkit/react-core";
function CustomScrollView({ children, autoScroll, ...props }) {
return (
<CopilotChatView.ScrollView
autoScroll={autoScroll}
scrollToBottomButton="bg-indigo-600"
feather="from-gray-50 via-gray-50 to-transparent"
{...props}
>
{children}
</CopilotChatView.ScrollView>
);
}
<CopilotChat scrollView={CustomScrollView} />;
```
## Examples
### Custom Scroll Button
```tsx
<CopilotChat
scrollView={{
scrollToBottomButton: {
className:
"bg-gradient-to-r from-pink-500 to-orange-500 text-white shadow-xl",
},
}}
/>
```
### Dark Mode Feather
```tsx
<CopilotChat
scrollView={{
feather: "from-gray-900 via-gray-900 to-transparent",
}}
/>
```
### Removing Visual Elements
Remove both the scroll button and feather for a minimal look:
```tsx
<CopilotChat
scrollView={{
scrollToBottomButton: () => null,
feather: () => null,
}}
/>
```
### Custom Themed Scroll View
```tsx
<CopilotChat
className="bg-slate-50"
scrollView={{
className: "bg-slate-50",
scrollToBottomButton: "bg-slate-700 hover:bg-slate-800 text-white",
feather: "from-slate-50 via-slate-50 to-transparent",
}}
/>
```
## Related
- [CopilotChat](/reference/copilot-chat) - Parent component that uses CopilotChatScrollView
- [CopilotChatMessageView](/reference/copilot-chat-message-view) - Message list rendered inside the scroll view
- [Slot System](/reference/slot-system) - Deep dive into slot customization
@@ -0,0 +1,244 @@
---
title: CopilotChatSuggestionView
description: "Clickable suggestion chips component"
---
`CopilotChatSuggestionView` is the default component used by [CopilotChat](/reference/copilot-chat) to render clickable suggestion chips. These chips provide quick actions that users can click to send predefined messages.
## What is CopilotChatSuggestionView?
The CopilotChatSuggestionView component:
- Renders a list of clickable suggestion chips
- Supports loading states for individual suggestions
- Handles click events to trigger message sending
- Displays suggestions in a flexible wrapped layout
- Built on the [slot system](/reference/slot-system) for deep customization
## Component Architecture
CopilotChatSuggestionView provides slots for customizing the container and individual chips:
```mermaid
graph LR
SV[CopilotChatSuggestionView] --> container
SV --> suggestion
```
### Slot Descriptions
| Slot | Description |
| ------------ | --------------------------------------------------- |
| `container` | The outer container that holds all suggestion chips |
| `suggestion` | Individual suggestion chip (pill button) |
## Basic Usage
Customize suggestions through the `suggestionView` prop on [CopilotChat](/reference/copilot-chat):
```tsx
<CopilotChat
suggestionView={{
container: "gap-4",
suggestion: "bg-blue-100 hover:bg-blue-200 text-blue-800",
}}
/>
```
## How Suggestions Work
Suggestions are managed through the `useSuggestions` hook, which:
1. Receives suggestions from the AI agent
2. Displays them as clickable chips
3. Triggers message sending when clicked
4. Shows loading states during processing
You don't need to manage suggestions manually - CopilotChat handles this automatically.
## Slot Customization
CopilotChatSuggestionView uses the [slot system](/reference/slot-system). Each slot accepts four types of values:
1. **Tailwind class string** - Add or override CSS classes
2. **Props object** - Pass additional props to the default component
3. **Custom component** - Replace the component entirely
4. **Nested sub-slots** - Drill down to customize child components
### Container Customization
Style the suggestions container:
```tsx
<CopilotChat
suggestionView={{
container: "flex-wrap gap-2 justify-center",
}}
/>
```
### Suggestion Chip Customization
Style individual suggestion chips:
```tsx
<CopilotChat
suggestionView={{
suggestion:
"bg-gradient-to-r from-blue-500 to-purple-500 text-white px-4 py-2 rounded-full",
}}
/>
```
Or with a props object:
```tsx
<CopilotChat
suggestionView={{
suggestion: {
className: "bg-indigo-100 text-indigo-800 font-medium",
},
}}
/>
```
## Replacing the Component
To completely replace the suggestion view with your own component:
```tsx
import { CopilotChatSuggestionView } from "@copilotkit/react-core";
function CustomSuggestionView({ suggestions, onSelectSuggestion, ...props }) {
return (
<div className="custom-suggestions-wrapper">
<CopilotChatSuggestionView
suggestions={suggestions}
onSelectSuggestion={onSelectSuggestion}
container="gap-3"
suggestion="bg-white shadow-md hover:shadow-lg rounded-xl px-4 py-2"
{...props}
/>
</div>
);
}
<CopilotChat suggestionView={CustomSuggestionView} />;
```
### Using the Render Function
For full layout control, use the children render function:
```tsx
function CustomSuggestionView(props) {
return (
<CopilotChatSuggestionView {...props}>
{({ suggestions, onSelectSuggestion }) => (
<div className="grid grid-cols-2 gap-2 p-4">
{suggestions.map((suggestion, index) => (
<button
key={index}
onClick={() => onSelectSuggestion(suggestion, index)}
className="p-3 bg-white border rounded-lg hover:bg-gray-50 text-left"
>
{suggestion.title}
</button>
))}
</div>
)}
</CopilotChatSuggestionView>
);
}
<CopilotChat suggestionView={CustomSuggestionView} />;
```
The render function receives:
| Property | Type | Description |
| -------------------- | ----------------------------- | ---------------------------------------- |
| `container` | `ReactElement` | The bound container element |
| `suggestion` | `ReactElement` | A sample bound suggestion chip |
| `suggestions` | `Suggestion[]` | Array of suggestion objects |
| `onSelectSuggestion` | `(suggestion, index) => void` | Callback when suggestion is clicked |
| `loadingIndexes` | `ReadonlyArray<number>` | Indexes of suggestions currently loading |
## Loading States
Individual suggestions can show loading states when clicked:
```tsx
// Suggestions automatically show loading states when:
// 1. The suggestion is clicked and processing
// 2. The suggestion has isLoading: true in its data
```
The loading state is indicated by a spinner or visual feedback on the chip.
## Examples
### Pill-Style Suggestions
```tsx
<CopilotChat
suggestionView={{
container: "flex flex-wrap gap-2",
suggestion:
"rounded-full bg-gray-100 hover:bg-gray-200 px-4 py-1.5 text-sm",
}}
/>
```
### Card-Style Suggestions
```tsx
<CopilotChat
suggestionView={{
container: "grid grid-cols-2 gap-3",
suggestion:
"bg-white shadow-sm border rounded-xl p-3 hover:shadow-md text-left",
}}
/>
```
### Colorful Gradient Chips
```tsx
<CopilotChat
suggestionView={{
suggestion:
"bg-gradient-to-r from-pink-500 to-orange-500 text-white hover:from-pink-600 hover:to-orange-600",
}}
/>
```
### Minimal Style
```tsx
<CopilotChat
suggestionView={{
container: "gap-1",
suggestion:
"text-blue-600 hover:text-blue-800 underline underline-offset-2 bg-transparent",
}}
/>
```
### Centered Suggestions
```tsx
<CopilotChat
suggestionView={{
container: "flex justify-center flex-wrap gap-2",
suggestion:
"bg-blue-50 text-blue-700 hover:bg-blue-100 rounded-lg px-3 py-1.5",
}}
/>
```
## Related
- [CopilotChat](/reference/copilot-chat) - Parent component that uses CopilotChatSuggestionView
- [CopilotChatWelcomeScreen](/reference/copilot-chat-welcome-screen) - Welcome screen that displays suggestions
- [Slot System](/reference/slot-system) - Deep dive into slot customization
@@ -0,0 +1,376 @@
---
title: CopilotChatUserMessage
description: "User message rendering component with edit and branch navigation"
---
`CopilotChatUserMessage` is the default component used by [CopilotChatMessageView](/reference/copilot-chat-message-view) to render user messages. It handles message display, editing functionality, and branch navigation for conversation history.
## What is CopilotChatUserMessage?
The CopilotChatUserMessage component:
- Renders user messages in a styled bubble
- Provides a toolbar with copy and edit buttons
- Supports message editing functionality
- Handles branch navigation for conversation forks
- Built on the [slot system](/reference/slot-system) for deep customization
## Component Architecture
CopilotChatUserMessage provides slots for customizing each part of the message:
```mermaid
graph LR
UM[CopilotChatUserMessage] --> messageRenderer
UM --> toolbar
UM --> copyButton
UM --> editButton
UM --> branchNavigation
```
### Slot Descriptions
| Slot | Description |
| ------------------ | ----------------------------------------------- |
| `messageRenderer` | Renders the message text content |
| `toolbar` | Container for action buttons (appears on hover) |
| `copyButton` | Button to copy message content |
| `editButton` | Button to edit the message |
| `branchNavigation` | Navigation controls for conversation branches |
## Basic Usage
Customize user messages through the `messageView.userMessage` slot on [CopilotChat](/reference/copilot-chat):
```tsx
<CopilotChat
messageView={{
userMessage: {
className: "bg-blue-500 text-white rounded-2xl",
onEditMessage: ({ message }) => handleEdit(message),
},
}}
/>
```
## Callbacks
CopilotChatUserMessage provides callbacks for user interactions:
```tsx
<CopilotChat
messageView={{
userMessage: {
onEditMessage: ({ message }) => {
// Open edit modal or inline editor
setEditingMessage(message);
},
onSwitchToBranch: ({ message, branchIndex, numberOfBranches }) => {
// Switch to a different conversation branch
switchToBranch(message.id, branchIndex);
},
},
}}
/>
```
### Callback Props
| Callback | Signature | Description |
| ------------------ | ------------------------------------------------------ | ------------------------------------------- |
| `onEditMessage` | `({ message }) => void` | Called when user clicks the edit button |
| `onSwitchToBranch` | `({ message, branchIndex, numberOfBranches }) => void` | Called when user navigates between branches |
## Slot Customization
CopilotChatUserMessage uses the [slot system](/reference/slot-system). Each slot accepts four types of values:
1. **Tailwind class string** - Add or override CSS classes
2. **Props object** - Pass additional props to the default component
3. **Custom component** - Replace the component entirely
4. **Nested sub-slots** - Drill down to customize child components
### Message Renderer Customization
Style the message bubble:
```tsx
<CopilotChat
messageView={{
userMessage: {
messageRenderer:
"bg-gradient-to-r from-blue-500 to-purple-500 text-white",
},
}}
/>
```
### Toolbar Customization
The toolbar appears on hover and contains action buttons:
```tsx
<CopilotChat
messageView={{
userMessage: {
toolbar: "bg-gray-50 rounded-lg p-1",
},
}}
/>
```
### Individual Button Customization
Customize specific toolbar buttons:
```tsx
<CopilotChat
messageView={{
userMessage: {
copyButton: "text-gray-500 hover:text-gray-700",
editButton: "text-blue-500 hover:text-blue-700",
},
}}
/>
```
### Hiding Buttons
Hide buttons by returning null:
```tsx
<CopilotChat
messageView={{
userMessage: {
editButton: () => null,
branchNavigation: () => null,
},
}}
/>
```
Note: The `editButton` only shows when `onEditMessage` callback is provided.
### Branch Navigation Customization
Customize the branch navigation controls:
```tsx
<CopilotChat
messageView={{
userMessage: {
branchNavigation: "bg-gray-100 rounded-lg px-2",
},
}}
/>
```
Branch navigation only appears when there are multiple branches (conversation forks) available.
## Replacing the Component
To completely replace the user message component:
```tsx
import { CopilotChatUserMessage } from "@copilotkit/react-core";
function CustomUserMessage({ message, ...props }) {
return (
<div className="flex gap-3 items-start justify-end">
<div className="flex-1">
<CopilotChatUserMessage
message={message}
className="bg-blue-600 text-white"
{...props}
/>
</div>
<Avatar src="/user-avatar.png" />
</div>
);
}
<CopilotChat
messageView={{
userMessage: CustomUserMessage,
}}
/>;
```
### Using the Render Function
For full layout control, use the children render function:
```tsx
function CustomUserMessage(props) {
return (
<CopilotChatUserMessage {...props}>
{({ messageRenderer, toolbar, message }) => (
<div className="flex flex-col items-end gap-1">
<div className="flex items-center gap-2">
<span className="text-xs text-gray-400">You</span>
<span className="text-xs text-gray-400">
{new Date(message.createdAt).toLocaleTimeString()}
</span>
</div>
{messageRenderer}
{toolbar}
</div>
)}
</CopilotChatUserMessage>
);
}
<CopilotChat
messageView={{
userMessage: CustomUserMessage,
}}
/>;
```
The render function receives:
| Property | Type | Description |
| ------------------ | -------------- | ---------------------------- |
| `messageRenderer` | `ReactElement` | The rendered message content |
| `toolbar` | `ReactElement` | The action buttons toolbar |
| `copyButton` | `ReactElement` | Copy button |
| `editButton` | `ReactElement` | Edit button |
| `branchNavigation` | `ReactElement` | Branch navigation controls |
| `message` | `UserMessage` | The message data |
| `branchIndex` | `number` | Current branch index |
| `numberOfBranches` | `number` | Total number of branches |
## Branch Navigation
When users edit messages and regenerate responses, CopilotKit creates conversation branches. The branch navigation allows users to switch between these alternative conversation paths:
```tsx
<CopilotChat
messageView={{
userMessage: {
onSwitchToBranch: ({ message, branchIndex, numberOfBranches }) => {
console.log(
`Switching to branch ${branchIndex + 1} of ${numberOfBranches}`,
);
// Your branch switching logic
},
},
}}
/>
```
The branch navigation shows:
- Previous/Next arrows to navigate between branches
- Current branch indicator (e.g., "2/3")
## Examples
### Chat Bubble Style
```tsx
<CopilotChat
messageView={{
userMessage: {
className: "items-end",
messageRenderer:
"bg-blue-600 text-white rounded-2xl px-4 py-2 max-w-[75%]",
toolbar: "opacity-0 group-hover:opacity-100 transition-opacity",
},
}}
/>
```
### With Edit Functionality
```tsx
function ChatWithEdit() {
const [editingMessage, setEditingMessage] = useState(null);
return (
<>
<CopilotChat
messageView={{
userMessage: {
onEditMessage: ({ message }) => setEditingMessage(message),
editButton: "text-blue-500 hover:text-blue-700",
},
}}
/>
{editingMessage && (
<EditMessageModal
message={editingMessage}
onClose={() => setEditingMessage(null)}
/>
)}
</>
);
}
```
### Minimal Style
Hide all toolbar elements for a clean look:
```tsx
<CopilotChat
messageView={{
userMessage: {
toolbar: () => null,
},
}}
/>
```
### Custom Message with Avatar
```tsx
function UserMessageWithAvatar(props) {
return (
<CopilotChatUserMessage {...props}>
{({ messageRenderer, toolbar }) => (
<div className="flex items-start gap-3 justify-end">
<div className="flex flex-col items-end">
{messageRenderer}
{toolbar}
</div>
<img
src="/user-avatar.png"
alt="You"
className="w-8 h-8 rounded-full"
/>
</div>
)}
</CopilotChatUserMessage>
);
}
<CopilotChat
messageView={{
userMessage: UserMessageWithAvatar,
}}
/>;
```
### Styled for Dark Mode
```tsx
<CopilotChat
messageView={{
userMessage: {
messageRenderer: "bg-blue-600 text-white dark:bg-blue-500",
toolbar: "text-gray-400 dark:text-gray-500",
copyButton: "hover:text-white dark:hover:text-gray-300",
editButton: "hover:text-white dark:hover:text-gray-300",
},
}}
/>
```
## Related
- [CopilotChat](/reference/copilot-chat) - Parent component
- [CopilotChatMessageView](/reference/copilot-chat-message-view) - Message list component that uses user messages
- [CopilotChatAssistantMessage](/reference/copilot-chat-assistant-message) - Counterpart for AI messages
- [Slot System](/reference/slot-system) - Deep dive into slot customization
@@ -0,0 +1,292 @@
---
title: CopilotChatWelcomeScreen
description: "Initial empty state and welcome message component"
---
`CopilotChatWelcomeScreen` is the default component displayed by [CopilotChat](/reference/copilot-chat) when there are no messages. It provides a welcoming introduction with an input field and optional suggestion chips.
## What is CopilotChatWelcomeScreen?
The CopilotChatWelcomeScreen component:
- Displays when the conversation is empty (no messages)
- Shows a customizable welcome message
- Includes the chat input for starting conversations
- Displays suggestion chips for quick actions
- Built on the [slot system](/reference/slot-system) for deep customization
## Component Architecture
CopilotChatWelcomeScreen provides a slot for the welcome message and receives input and suggestions as props:
```mermaid
graph LR
WS[CopilotChatWelcomeScreen] --> welcomeMessage
WS --> input[input prop]
WS --> suggestionView[suggestionView prop]
```
### Slot Descriptions
| Slot/Prop | Description |
| ---------------- | --------------------------------------------------- |
| `welcomeMessage` | The greeting text or component displayed at the top |
| `input` | The chat input component (passed as a prop) |
| `suggestionView` | Suggestion chips component (passed as a prop) |
## Basic Usage
Customize the welcome screen through the `welcomeScreen` prop on [CopilotChat](/reference/copilot-chat):
```tsx
<CopilotChat
welcomeScreen={{
className: "bg-gradient-to-b from-blue-50 to-white",
welcomeMessage: "text-2xl font-bold text-blue-900",
}}
/>
```
## Customizing the Welcome Message
The simplest way to customize the welcome message is through labels:
```tsx
<CopilotChat
labels={{
welcomeMessage: "Hello! I'm your AI assistant. How can I help you today?",
}}
/>
```
Or style the welcome message component:
```tsx
<CopilotChat
welcomeScreen={{
welcomeMessage: {
className:
"text-3xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent",
},
}}
/>
```
## Disabling the Welcome Screen
To skip the welcome screen and show an empty chat directly:
```tsx
<CopilotChat welcomeScreen={false} />
```
## Slot Customization
CopilotChatWelcomeScreen uses the [slot system](/reference/slot-system). Each slot accepts four types of values:
1. **Tailwind class string** - Add or override CSS classes
2. **Props object** - Pass additional props to the default component
3. **Custom component** - Replace the component entirely
4. **Nested sub-slots** - Drill down to customize child components
### Welcome Message Customization
Style the welcome message:
```tsx
<CopilotChat
welcomeScreen={{
welcomeMessage: "text-4xl font-extrabold tracking-tight",
}}
/>
```
Or with a custom component:
```tsx
function CustomWelcomeMessage() {
return (
<div className="text-center">
<img src="/logo.svg" alt="Logo" className="w-16 h-16 mx-auto mb-4" />
<h1 className="text-2xl font-bold">Welcome to AI Assistant</h1>
<p className="text-gray-500 mt-2">Ask me anything about your project</p>
</div>
);
}
<CopilotChat
welcomeScreen={{
welcomeMessage: CustomWelcomeMessage,
}}
/>;
```
## Replacing the Welcome Screen
To completely replace the welcome screen with your own component:
```tsx
import { CopilotChatView } from "@copilotkit/react-core";
function CustomWelcomeScreen({ input, suggestionView }) {
return (
<div className="flex flex-col items-center justify-center h-full bg-gradient-to-b from-indigo-50 to-white p-8">
<img src="/mascot.svg" alt="AI Mascot" className="w-32 h-32 mb-6" />
<h1 className="text-3xl font-bold text-gray-900 mb-2">Hi there!</h1>
<p className="text-gray-600 text-center max-w-md mb-8">
I'm your AI assistant. I can help you with coding, research, writing,
and much more. What would you like to explore?
</p>
<div className="w-full max-w-2xl">{input}</div>
<div className="mt-6">{suggestionView}</div>
</div>
);
}
<CopilotChat welcomeScreen={CustomWelcomeScreen} />;
```
### Using the Render Function
For full layout control while keeping the default components:
```tsx
function CustomWelcomeScreen(props) {
return (
<CopilotChatView.WelcomeScreen {...props}>
{({ welcomeMessage, input, suggestionView }) => (
<div className="flex flex-col lg:flex-row h-full">
<div className="lg:w-1/2 bg-indigo-600 text-white p-12 flex items-center justify-center">
<div className="max-w-md">
<h1 className="text-4xl font-bold mb-4">AI Assistant</h1>
<p className="text-indigo-200">
Your intelligent companion for coding, writing, and
problem-solving.
</p>
</div>
</div>
<div className="lg:w-1/2 p-12 flex flex-col items-center justify-center">
<div className="w-full max-w-md">
{welcomeMessage}
<div className="mt-8">{input}</div>
<div className="mt-6">{suggestionView}</div>
</div>
</div>
</div>
)}
</CopilotChatView.WelcomeScreen>
);
}
<CopilotChat welcomeScreen={CustomWelcomeScreen} />;
```
The render function receives:
| Property | Type | Description |
| ---------------- | -------------- | ------------------------------- |
| `welcomeMessage` | `ReactElement` | The rendered welcome message |
| `input` | `ReactElement` | The chat input component |
| `suggestionView` | `ReactElement` | The suggestions chips component |
## Examples
### Branded Welcome Screen
```tsx
<CopilotChat
labels={{
welcomeMessage: "Welcome to Acme AI Assistant",
}}
welcomeScreen={{
className: "bg-brand-50",
welcomeMessage: "text-brand-900 text-3xl font-display",
}}
/>
```
### Minimal Welcome
```tsx
<CopilotChat
labels={{
welcomeMessage: "How can I help?",
}}
welcomeScreen={{
welcomeMessage: "text-lg text-gray-500 font-normal",
}}
/>
```
### Welcome with Custom Layout
```tsx
function CenteredWelcome({ input, suggestionView }) {
return (
<div className="flex flex-col items-center justify-center h-full p-8">
<div className="animate-pulse mb-8">
<div className="w-20 h-20 bg-gradient-to-br from-blue-400 to-purple-500 rounded-full" />
</div>
<h1 className="text-2xl font-semibold text-gray-900 mb-1">
Ready to help
</h1>
<p className="text-gray-500 mb-8">Start a conversation below</p>
<div className="w-full max-w-xl">{input}</div>
<div className="mt-4 flex flex-wrap justify-center gap-2">
{suggestionView}
</div>
</div>
);
}
<CopilotChat welcomeScreen={CenteredWelcome} />;
```
### Welcome Screen with Feature List
```tsx
function FeatureWelcome({ input, suggestionView }) {
return (
<div className="flex flex-col items-center justify-center h-full p-8">
<h1 className="text-3xl font-bold mb-8">AI Assistant</h1>
<div className="grid grid-cols-3 gap-4 mb-8 max-w-2xl">
<div className="text-center p-4">
<div className="text-2xl mb-2">💻</div>
<div className="font-medium">Code Help</div>
</div>
<div className="text-center p-4">
<div className="text-2xl mb-2">📝</div>
<div className="font-medium">Writing</div>
</div>
<div className="text-center p-4">
<div className="text-2xl mb-2">🔍</div>
<div className="font-medium">Research</div>
</div>
</div>
<div className="w-full max-w-xl">{input}</div>
<div className="mt-4">{suggestionView}</div>
</div>
);
}
<CopilotChat welcomeScreen={FeatureWelcome} />;
```
## Related
- [CopilotChat](/reference/copilot-chat) - Parent component that uses CopilotChatWelcomeScreen
- [CopilotChatInput](/reference/copilot-chat-input) - Input component displayed in welcome screen
- [CopilotChatSuggestionView](/reference/copilot-chat-suggestion-view) - Suggestions displayed in welcome screen
- [Slot System](/reference/slot-system) - Deep dive into slot customization
+444
View File
@@ -0,0 +1,444 @@
---
title: CopilotChat
description: "CopilotChat Component API Reference"
---
`CopilotChat` is a React component that provides a complete chat interface for interacting with AI agents. It handles
message display, user input, tool execution rendering, and agent communication automatically.
## What is CopilotChat?
The CopilotChat component:
- Provides a complete chat UI out of the box
- Manages conversation threads and message history
- Automatically connects to agents and handles message routing
- Renders tool executions with visual feedback
- Supports deep customization through the [slot system](/reference/slot-system)
- Handles auto-scrolling and responsive layouts
- Supports voice transcription for hands-free input
## Component Architecture
CopilotChat is built on a composable component hierarchy. Understanding this structure helps you customize exactly what you need.
```mermaid
graph LR
CC[CopilotChat] --> messageView
CC --> scrollView
CC --> input
CC --> suggestionView
CC --> welcomeScreen
```
### Slot Descriptions
| Slot | Description | Reference |
| ---------------- | -------------------------------------------------------------- | -------------------------------------------------------------------- |
| `messageView` | Container for the message list (user and assistant messages) | [CopilotChatMessageView](/reference/copilot-chat-message-view) |
| `scrollView` | Scrollable container with auto-scroll behavior | [CopilotChatScrollView](/reference/copilot-chat-scroll-view) |
| `input` | Text input with toolbar, transcription support, and disclaimer | [CopilotChatInput](/reference/copilot-chat-input) |
| `suggestionView` | Clickable suggestion chips | [CopilotChatSuggestionView](/reference/copilot-chat-suggestion-view) |
| `welcomeScreen` | Initial screen before any messages | [CopilotChatWelcomeScreen](/reference/copilot-chat-welcome-screen) |
See [Slot Customization](#slot-customization) for details on how to customize these slots.
## Basic Usage
```tsx
import { CopilotChat, CopilotKitProvider } from "@copilotkit/react-core";
function App() {
return (
<CopilotKitProvider runtimeUrl="/api/copilotkit">
<CopilotChat />
</CopilotKitProvider>
);
}
```
## Props
### agentId
`string` **(optional)**
The ID of the agent to connect to. Defaults to `"default"`.
```tsx
<CopilotChat agentId="assistant" />
```
### threadId
`string` **(optional)**
The conversation thread ID. If not provided, a new thread ID is automatically generated.
When you provide a `threadId`, CopilotChat automatically loads the conversation history for that thread, including any messages that are currently streaming. This enables seamless continuation of conversations across page reloads or component remounts.
```tsx
<CopilotChat threadId="thread-123" />
```
### labels
`Partial<CopilotChatLabels>` **(optional)**
Customize the text labels used throughout the chat interface.
```tsx
<CopilotChat
labels={{
chatInputPlaceholder: "Ask me anything...",
chatDisclaimerText: "AI assistant - verify important info",
welcomeMessage: "Hello! How can I help you today?",
}}
/>
```
### autoScroll
`boolean` **(optional, default: true)**
Automatically scroll to the bottom when new messages appear.
```tsx
<CopilotChat autoScroll={false} />
```
### className
`string` **(optional)**
CSS class name for the root container.
```tsx
<CopilotChat className="h-screen bg-white" />
```
### isModalDefaultOpen
`boolean` **(optional)**
When using CopilotChat in modal mode, controls whether the modal is open by default.
```tsx
<CopilotChat isModalDefaultOpen={true} />
```
### chatView
`SlotValue<typeof CopilotChatView>` **(optional)**
Customize the main chat view component. See [Slot Customization](#slot-customization) for details.
## Slot Customization
CopilotChat uses a powerful [slot system](/reference/slot-system) that allows you to customize any part of the UI. Each slot accepts four types of values:
1. **Tailwind class string** - Add or override CSS classes
2. **Props object** - Pass additional props to the default component
3. **Custom component** - Replace the component entirely
4. **Nested sub-slots** - Drill down to customize child components
### Customizing Appearance with Tailwind Classes
The simplest way to customize appearance is with Tailwind class strings:
```tsx
<CopilotChat
className="bg-gradient-to-b from-white to-gray-50 rounded-xl shadow-2xl"
messageView="space-y-4"
input="border-2 border-gray-200"
/>
```
### Customizing with Props
Pass a props object to modify component behavior while keeping the default implementation:
```tsx
<CopilotChat
messageView={{ className: "custom-message-view" }}
input={{ placeholder: "Ask a question..." }}
scrollView="custom-scroll-view"
/>
```
### Nested Slot Customization
You can drill down into nested components through props objects:
```tsx
<CopilotChat
messageView={{
assistantMessage: {
onThumbsUp: () => console.log("thumbsUp"),
onThumbsDown: () => console.log("thumbsDown"),
},
}}
/>
```
### Custom Components
For full control, replace components entirely:
```tsx
import { CopilotChatView } from "@copilotkit/react-core";
function CustomChatView(props) {
return (
<div className="custom-chat-layout">
<CopilotChatView
{...props}
messageView="custom-message-from-wrapper"
input="custom-input-from-wrapper"
/>
</div>
);
}
<CopilotChat chatView={CustomChatView} />;
```
## Message View Customization
The `messageView` slot controls how messages are rendered:
```tsx
<CopilotChat
messageView={{
// Style the message container
className: "space-y-4 p-4",
// Customize assistant messages
assistantMessage: {
className: "bg-blue-50 rounded-lg",
onThumbsUp: (message) => trackFeedback(message.id, "positive"),
onThumbsDown: (message) => trackFeedback(message.id, "negative"),
},
// Customize user messages
userMessage: "bg-gray-100 rounded-lg",
// Customize the typing cursor
cursor: "bg-blue-500",
}}
/>
```
### Assistant Message Customization
Customize how assistant messages appear and behave:
```tsx
<CopilotChat
messageView={{
assistantMessage: {
className: "bg-slate-50 border border-slate-200 rounded-xl p-4",
onThumbsUp: (message) => sendFeedback(message.id, "positive"),
onThumbsDown: (message) => sendFeedback(message.id, "negative"),
onRegenerate: (message) => regenerateResponse(message.id),
},
}}
/>
```
For full details on assistant message slots and customization options, see [CopilotChatAssistantMessage](/reference/copilot-chat-assistant-message).
### User Message Customization
Customize how user messages appear:
```tsx
<CopilotChat
messageView={{
userMessage: "bg-blue-500 text-white rounded-2xl px-4 py-2",
}}
/>
```
You can also pass a props object or a custom component:
```tsx
<CopilotChat
messageView={{
userMessage: {
className: "bg-primary text-primary-foreground",
"data-testid": "user-message",
},
}}
/>
```
## Input Customization
The `input` slot controls the text input and its toolbar:
```tsx
<CopilotChat
input={{
className: "border-2 border-primary rounded-xl",
placeholder: "Type your message...",
// Customize individual buttons
sendButton: "bg-blue-500 hover:bg-blue-600",
}}
/>
```
For full details on input slots and customization options, see [CopilotChatInput](/reference/copilot-chat-input).
## Suggestions
CopilotChat automatically manages suggestion chips through the `useSuggestions` hook. Suggestions are generated by the agent and displayed as clickable chips that users can select to quickly send messages.
You can customize suggestions through the `suggestionView` slot, which has two sub-slots:
```tsx
<CopilotChat
suggestionView={{
// Customize the container that holds all chips
container: "gap-4",
// Customize individual suggestion chips
suggestion: "bg-blue-100 hover:bg-blue-200 rounded-full",
}}
/>
```
## Voice Transcription
CopilotChat supports voice input through transcription. To enable it, configure your CopilotKitProvider with transcription settings:
```tsx
<CopilotKitProvider
runtimeUrl="/api/copilotkit"
transcribeAudioUrl="/api/transcribe"
>
<CopilotChat />
</CopilotKitProvider>
```
Once enabled, a microphone button appears in the input toolbar. Users can record audio which is transcribed and inserted into the message input.
## Welcome Screen Customization
The welcome screen is displayed before any messages are sent. You can customize it in several ways:
### Custom Welcome Message
The simplest customization is changing the welcome message text:
```tsx
<CopilotChat
labels={{
welcomeMessage: "Hello! I'm your AI assistant. How can I help you today?",
}}
/>
```
### Custom Welcome Screen Component
For full control, replace the entire welcome screen:
```tsx
function CustomWelcomeScreen() {
return (
<div className="flex flex-col items-center justify-center h-full p-8">
<img src="/logo.svg" alt="Logo" className="w-16 h-16 mb-4" />
<h2 className="text-2xl font-bold mb-2">Welcome to AI Assistant</h2>
<p className="text-muted-foreground text-center">
Ask me anything about your data, documents, or tasks.
</p>
</div>
);
}
<CopilotChat welcomeScreen={CustomWelcomeScreen} />;
```
## Auto-scrolling Behavior
CopilotChat automatically scrolls to the bottom when:
- New messages are added
- The user is already near the bottom
- `autoScroll` prop is true (default)
The scroll-to-bottom button appears when the user scrolls up and new content is available.
```tsx
// Disable auto-scroll
<CopilotChat autoScroll={false} />
// Customize the scroll button
<CopilotChat scrollView={{ scrollToBottomButton: "bg-blue-500 rounded-full shadow-lg" }} />
```
## Complete Example
Here's a fully customized CopilotChat implementation:
```tsx
import { CopilotChat, CopilotKitProvider } from "@copilotkit/react-core";
function App() {
const handleFeedback = (messageId: string, type: "positive" | "negative") => {
analytics.track("message_feedback", { messageId, type });
};
return (
<CopilotKitProvider runtimeUrl="/api/copilotkit">
<div className="h-screen">
<CopilotChat
agentId="my-assistant"
className="h-full"
labels={{
chatInputPlaceholder: "Ask me anything...",
chatDisclaimerText: "AI responses may not be accurate.",
welcomeMessage: "Hello! I'm here to help.",
}}
messageView={{
assistantMessage: {
onThumbsUp: (msg) => handleFeedback(msg.id, "positive"),
onThumbsDown: (msg) => handleFeedback(msg.id, "negative"),
},
}}
input={{
className: "border-2 border-gray-200 rounded-xl",
disclaimer: "text-xs text-gray-400",
}}
/>
</div>
</CopilotKitProvider>
);
}
```
## Related
### Slot Components
- [CopilotChatMessageView](/reference/copilot-chat-message-view) - Message list customization
- [CopilotChatScrollView](/reference/copilot-chat-scroll-view) - Scroll container customization
- [CopilotChatInput](/reference/copilot-chat-input) - Input component customization
- [CopilotChatSuggestionView](/reference/copilot-chat-suggestion-view) - Suggestion chips customization
- [CopilotChatWelcomeScreen](/reference/copilot-chat-welcome-screen) - Welcome screen customization
- [CopilotChatAssistantMessage](/reference/copilot-chat-assistant-message) - Assistant message customization
### Other Components
- [CopilotSidebar](/reference/copilot-sidebar) - Slide-in sidebar chat interface
- [CopilotPopup](/reference/copilot-popup) - Floating popup chat dialog
### Guides & Concepts
- [Slot System](/reference/slot-system) - Deep dive into slot customization
### Providers & Hooks
- [CopilotKitProvider](/reference/copilotkit-provider) - Provider configuration
- [useAgent](/reference/use-agent) - Hook for programmatic agent control
- [useFrontendTool](/reference/use-frontend-tool) - Adding custom tools to the chat
@@ -0,0 +1,216 @@
---
title: CopilotPopup
description: "Floating popup chat dialog"
---
`CopilotPopup` is a React component that provides a floating popup chat interface. It wraps [CopilotChat](/reference/copilot-chat) with additional popup-specific behavior including a toggle button, fade/scale animation, and optional click-outside-to-close functionality.
## What is CopilotPopup?
The CopilotPopup component:
- Provides a floating dialog with smooth fade/scale animation
- Includes a toggle button for open/close
- Supports click-outside-to-close behavior
- Responsive design (fullscreen on mobile, fixed size on desktop)
- Built on [CopilotChat](/reference/copilot-chat) - inherits all its features and customization options
## Component Architecture
CopilotPopup extends [CopilotChat](/reference/copilot-chat#component-architecture) with additional slots:
```mermaid
graph LR
CP[CopilotPopup] --> header
CP --> toggleButton
```
### Slot Descriptions
| Slot | Description |
| -------------- | --------------------------------------- |
| `header` | Header bar with title and close button |
| `toggleButton` | Floating button to open/close the popup |
CopilotPopup also inherits all slots from CopilotChat: `messageView`, `scrollView`, `input`, `suggestionView`, and `welcomeScreen`.
See [Slot Customization](#slot-customization) for details on how to customize these slots.
## Basic Usage
```tsx
import { CopilotPopup, CopilotKitProvider } from "@copilotkit/react-core";
function App() {
return (
<CopilotKitProvider runtimeUrl="/api/copilotkit">
<CopilotPopup />
</CopilotKitProvider>
);
}
```
## Props
### Popup-Specific Props
These props are unique to CopilotPopup:
| Prop | Type | Default | Description |
| --------------------- | ------------------ | ------- | --------------------------------------------------- |
| `defaultOpen` | `boolean` | `true` | Whether the popup is open initially |
| `width` | `number \| string` | `420` | Popup width in pixels or CSS unit |
| `height` | `number \| string` | `560` | Popup height in pixels or CSS unit |
| `clickOutsideToClose` | `boolean` | `false` | Close the popup when clicking outside |
| `header` | `SlotValue` | - | Custom header component with title and close button |
| `toggleButton` | `SlotValue` | - | Custom toggle button to open/close the popup |
### Shared Props
CopilotPopup inherits all props from [CopilotChat](/reference/copilot-chat), including:
- `agentId` - The agent to connect to
- `threadId` - The conversation thread ID
- `labels` - Customize text labels
- `autoScroll` - Auto-scroll behavior
- `className` - CSS class for the root container
See [CopilotChat Props](/reference/copilot-chat#props) for the complete list.
## Header Customization
The popup includes a header with a title and close button. Customize it through the `header` prop:
```tsx
<CopilotPopup
header={{
titleContent: "My Assistant",
closeButton: "hidden",
}}
/>
```
### Header Sub-Slots
| Sub-Slot | Description |
| -------------- | -------------------------------- |
| `titleContent` | The title text or component |
| `closeButton` | The close button (can be hidden) |
### Custom Header Component
Replace the entire header with your own component:
```tsx
function CustomHeader() {
return (
<div className="flex items-center justify-between p-4 border-b">
<div className="flex items-center gap-2">
<BotIcon className="w-5 h-5" />
<span className="font-semibold">My AI Assistant</span>
</div>
<button onClick={() => /* close popup */}>
<XIcon className="w-5 h-5" />
</button>
</div>
);
}
<CopilotPopup header={CustomHeader} />
```
## Toggle Button Customization
The popup includes a floating toggle button to open and close it. Customize it through the `toggleButton` prop:
```tsx
<CopilotPopup
toggleButton={{
className: "bg-purple-500 hover:bg-purple-600",
openIcon: "text-white",
closeIcon: "text-white",
}}
/>
```
### Toggle Button Sub-Slots
| Sub-Slot | Description |
| ----------- | ----------------------------------------------- |
| `openIcon` | Icon shown when popup is closed (click to open) |
| `closeIcon` | Icon shown when popup is open (click to close) |
### Custom Toggle Button Component
Replace the toggle button entirely:
```tsx
function CustomToggleButton() {
return (
<button className="fixed bottom-4 right-4 p-3 bg-blue-500 rounded-full">
<ChatIcon className="w-6 h-6 text-white" />
</button>
);
}
<CopilotPopup toggleButton={CustomToggleButton} />;
```
## Slot Customization
CopilotPopup uses the same [slot system](/reference/slot-system) as CopilotChat. Each slot accepts four types of values:
1. **Tailwind class string** - Add or override CSS classes
2. **Props object** - Pass additional props to the default component
3. **Custom component** - Replace the component entirely
4. **Nested sub-slots** - Drill down to customize child components
### Custom Dimensions
```tsx
<CopilotPopup width={500} height={700} />
// Or with CSS units
<CopilotPopup width="30vw" height="80vh" />
```
### Click Outside to Close
```tsx
<CopilotPopup clickOutsideToClose={true} />
```
### Custom Header Styling
```tsx
<CopilotPopup
header={{
className: "bg-gradient-to-r from-blue-500 to-purple-500 text-white",
titleContent: "AI Assistant",
}}
/>
```
### Nested Slot Customization
```tsx
<CopilotPopup
messageView={{
assistantMessage: {
onThumbsUp: (msg) => console.log("Liked:", msg.id),
onThumbsDown: (msg) => console.log("Disliked:", msg.id),
},
}}
input={{
className: "border-2 border-gray-200",
sendButton: "bg-blue-500 hover:bg-blue-600",
}}
/>
```
## Related
- [CopilotChat](/reference/copilot-chat) - Base chat component with full customization options
- [CopilotSidebar](/reference/copilot-sidebar) - Slide-in sidebar chat interface
- [Slot System](/reference/slot-system) - Deep dive into slot customization
- [CopilotKitProvider](/reference/copilotkit-provider) - Provider configuration
@@ -0,0 +1,341 @@
---
title: CopilotRuntime
description: "Server-side runtime for hosting CopilotKit agents"
---
The `CopilotRuntime` package gives you everything you need to host CopilotKit agents on your own infrastructure. It owns the agent registry, wires an `AgentRunner`, exposes HTTP endpoints (Express or Hono), and optionally coordinates middleware and transcription services.
## Basic Setup
```ts
import { CopilotRuntime, InMemoryAgentRunner } from "@copilotkit/runtime";
import { BasicAgent } from "@copilotkit/runtime/v2";
const runtime = new CopilotRuntime({
agents: {
default: new BasicAgent({
model: "openai/gpt-4o",
prompt: "You are a helpful assistant.",
}),
},
runner: new InMemoryAgentRunner(),
});
```
Once you create a runtime instance you can mount one of the provided HTTP endpoints (Express or Hono) described below.
## `CopilotRuntime` Constructor
```ts
new CopilotRuntime(options: CopilotRuntimeOptions)
```
### `CopilotRuntimeOptions`
| Option | Type | Description |
| ------------------------- | ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `agents` | `Promise<Record<string, AbstractAgent>> \| Record<string, AbstractAgent>` | Required. A map from agent identifier to an `AbstractAgent`. You can return the map synchronously or asynchronously. |
| `runner` | `AgentRunner` | Optional. Defaults to `new InMemoryAgentRunner()`. Controls how agent runs are scheduled and streamed. |
| `transcriptionService` | `TranscriptionService` | Optional. Enables `/transcribe` and reports `audioFileTranscriptionEnabled: true` from `/info`. |
| `beforeRequestMiddleware` | `BeforeRequestMiddleware` | Optional. Runs before every request. Can mutate the incoming `Request` or return `void`. |
| `afterRequestMiddleware` | `AfterRequestMiddleware` | Optional. Runs after every handler resolves. Receives the response along with parsed messages, thread ID, and run ID extracted from the SSE stream. Use this for logging, metrics, telemetry, etc. |
### Passing Agents
- Provide a plain object mapping agent ids to instances. The helper `BasicAgent` covers common OpenAI/Anthropic/Gemini setups, but you can supply any `AbstractAgent`.
- Because `agents` may be an async function, you can lazily load credentials or fetch configuration before returning the record.
- Each request clones the selected agent instance so per-request state (messages, headers, tool registration) does not leak between threads.
- `Authorization` and `x-*` headers on the incoming request are forwarded to the cloned agent automatically. Override or strip them inside `beforeRequestMiddleware` if needed.
```ts
const runtime = new CopilotRuntime({
agents: async () => ({
default: buildDefaultAgent(),
support: buildSupportAgent(),
}),
});
```
### Choosing an `AgentRunner`
`InMemoryAgentRunner` is the default and streams events directly from your Node.js process. Swap it with a custom `AgentRunner` if you need to enqueue work or forward to another service:
```ts
class QueueBackedRunner implements AgentRunner {
/* ... */
}
const runtime = new CopilotRuntime({
agents,
runner: new QueueBackedRunner(),
});
```
### Middleware Hooks
```ts
const runtime = new CopilotRuntime({
agents,
beforeRequestMiddleware: async ({ request, path }) => {
const auth = request.headers.get("authorization");
if (!auth) {
throw new Response("Unauthorized", { status: 401 });
}
},
afterRequestMiddleware: async ({
response,
path,
messages,
threadId,
runId,
}) => {
console.info("Handled", path, response.status);
console.info("Thread:", threadId, "Run:", runId);
console.info("Messages:", messages);
},
});
```
Throwing a `Response` from `beforeRequestMiddleware` short-circuits the request. `afterRequestMiddleware` runs in the background and should swallow its own errors.
#### `AfterRequestMiddlewareParameters`
| Parameter | Type | Description |
| ---------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `runtime` | `CopilotRuntime` | The runtime instance. |
| `response` | `Response` | A clone of the response sent to the client. The body is still readable. |
| `path` | `string` | The matched route path (e.g. `/agent/default/run`). |
| `messages` | `Message[]` | Reconstructed messages from the SSE stream. Empty for non-SSE responses. Each message has `id`, `role`, and optionally `content`, `toolCalls`, or `toolCallId`. |
| `threadId` | `string \| undefined` | Thread ID from the `RUN_STARTED` event. |
| `runId` | `string \| undefined` | Run ID from the `RUN_STARTED` event. |
This makes `afterRequestMiddleware` suitable for telemetry, audit logging, and post-run analytics without needing to manually parse the streamed response.
### Audio Transcription
Enable audio transcription by providing a `transcriptionService`. The `@copilotkit/voice` package includes providers:
```ts
import { CopilotRuntime } from "@copilotkit/runtime";
import { TranscriptionServiceOpenAI } from "@copilotkit/voice";
import OpenAI from "openai";
const runtime = new CopilotRuntime({
agents: { default: yourAgent },
transcriptionService: new TranscriptionServiceOpenAI({
openai: new OpenAI({ apiKey: process.env.OPENAI_API_KEY }),
}),
});
```
This enables the `/transcribe` endpoint and shows a microphone button in the chat UI. The `/info` endpoint will report `audioFileTranscriptionEnabled: true`.
For custom providers, extend `TranscriptionService` from runtime:
```ts
import {
TranscriptionService,
TranscribeFileOptions,
} from "@copilotkit/runtime";
class MyTranscriptionService extends TranscriptionService {
async transcribeFile(options: TranscribeFileOptions): Promise<string> {
// options.audioFile, options.mimeType, options.size
return "transcribed text";
}
}
```
## HTTP Endpoints
Import the helper that matches your server framework and the transport style you want to expose.
### Hono (REST-style)
```ts
import { createCopilotEndpoint } from "@copilotkit/runtime";
const copilot = createCopilotEndpoint({ runtime, basePath: "/api/copilotkit" });
const app = new Hono();
app.route("/", copilot);
```
This mounts five routes under the base path:
| Method | Path | Purpose |
| ------ | -------------------------------- | -------------------------------------------------------------- |
| `POST` | `/agent/:agentId/run` | Streams agent events (SSE). |
| `POST` | `/agent/:agentId/connect` | Creates a live WebSocket/stream connection. |
| `POST` | `/agent/:agentId/stop/:threadId` | Cancels an in-flight thread. |
| `GET` | `/info` | Returns runtime metadata and agent list. |
| `POST` | `/transcribe` | Proxies audio transcription (requires `transcriptionService`). |
### Hono (Single-route)
```ts
import { createCopilotEndpointSingleRoute } from "@copilotkit/runtime";
const copilot = createCopilotEndpointSingleRoute({
runtime,
basePath: "/api/copilotkit",
});
const app = new Hono();
app.route("/", copilot);
```
All interactions happen through a single `POST /api/copilotkit` endpoint. The client sends a JSON envelope:
```json
{
"method": "agent/run",
"params": { "agentId": "default" },
"body": { "messages": [...], "threadId": "thread-123" }
}
```
Allowed `method` values are:
- `agent/run`
- `agent/connect`
- `agent/stop`
- `info`
- `transcribe`
Pair this server endpoint with the React provider flag `<CopilotKitProvider useSingleEndpoint />`.
### Next.js (App Router) with Hono
When you're inside a Next.js `app/` route, export the Hono handlers directly:
```ts
// app/api/copilotkit/[[...slug]]/route.ts
import { CopilotRuntime, createCopilotEndpoint } from "@copilotkit/runtime";
import { handle } from "hono/vercel";
const runtime = new CopilotRuntime({ agents, runner });
const app = createCopilotEndpoint({ runtime, basePath: "/api/copilotkit" });
export const GET = handle(app);
export const POST = handle(app);
```
Swap `createCopilotEndpoint` for `createCopilotEndpointSingleRoute` if you configure the client with `useSingleEndpoint`.
### Express (REST-style)
```ts
import express from "express";
import { createCopilotEndpointExpress } from "@copilotkit/runtime/express";
const app = express();
app.use(
"/api/copilotkit",
createCopilotEndpointExpress({ runtime, basePath: "/" }),
);
```
The router mirrors the Hono REST routes and automatically enables permissive CORS (allowing all origins, headers, and methods). Adjust headers upstream if you need tighter controls.
### Express (Single-route)
```ts
import express from "express";
import { createCopilotEndpointSingleRouteExpress } from "@copilotkit/runtime/express";
const app = express();
app.use(
"/api/copilotkit",
createCopilotEndpointSingleRouteExpress({ runtime, basePath: "/" }),
);
```
Single-route Express works identically to the Hono version: send the JSON envelope described earlier, and set `useSingleEndpoint` on the client.
### NestJS (Express backend)
NestJS uses Express by default. Mount the Express router in `main.ts`:
```ts
// main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { NestExpressApplication } from "@nestjs/platform-express";
import { CopilotRuntime } from "@copilotkit/runtime";
import { createCopilotEndpointExpress } from "@copilotkit/runtime/express";
import { BasicAgent } from "@copilotkit/runtime/v2";
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
const runtime = new CopilotRuntime({
agents: {
default: new BasicAgent({
model: "openai/gpt-4o",
prompt: "You are helpful.",
}),
},
});
// Mount under /api/copilotkit (REST-style routes)
app.use(
"/api/copilotkit",
createCopilotEndpointExpress({ runtime, basePath: "/" }),
);
await app.listen(3000);
}
bootstrap();
```
Available routes (no global prefix):
- `POST /api/copilotkit/agent/:agentId/run`
- `POST /api/copilotkit/agent/:agentId/connect`
- `POST /api/copilotkit/agent/:agentId/stop/:threadId`
- `GET /api/copilotkit/info`
- `POST /api/copilotkit/transcribe`
If you prefer the single-route transport, mount the single-route helper instead and set `useSingleEndpoint` on the client:
```ts
import { createCopilotEndpointSingleRouteExpress } from "@copilotkit/runtime/express";
app.use(
"/api/copilotkit",
createCopilotEndpointSingleRouteExpress({ runtime, basePath: "/" }),
);
```
Notes:
- If you call `app.setGlobalPrefix('api')`, the effective paths become `/api/copilotkit/...` (or `/api/copilotkit` for single-route).
- Endpoints stream ServerSent Events; ensure your proxy honors `text/event-stream` and keepalive.
- The router enables permissive CORS; tighten via Nests `enableCors` if needed.
## Runtime Metadata
Calling `GET /info` (or the `info` single-route method) returns:
```json
{
"version": "0.0.20",
"agents": {
"default": {
"name": "default",
"className": "BasicAgent",
"description": "You are a helpful assistant."
}
},
"audioFileTranscriptionEnabled": false
}
```
Use this to verify deployments and surface diagnostics in your UI.
## Next Steps
- Configure the React client with `runtimeUrl` (and `useSingleEndpoint` if you chose the single endpoint helper).
- Register frontend tools with `CopilotKitProvider` so agents can trigger UI actions.
- Extend the runtime runner or middleware hooks to integrate logging, rate limiting, or background queues.
@@ -0,0 +1,208 @@
---
title: CopilotSidebar
description: "Sidebar chat interface with slide-in animation"
---
`CopilotSidebar` is a React component that provides a slide-in sidebar chat interface. It wraps [CopilotChat](/reference/copilot-chat) with additional sidebar-specific behavior including a toggle button, slide-in animation, and automatic body margin adjustment.
## What is CopilotSidebar?
The CopilotSidebar component:
- Provides a fixed right-side panel with smooth slide-in animation
- Includes a toggle button for open/close
- Automatically adjusts body margin when open to prevent content overlap
- Responsive design (full width on mobile, custom width on desktop)
- Built on [CopilotChat](/reference/copilot-chat) - inherits all its features and customization options
## Component Architecture
CopilotSidebar extends [CopilotChat](/reference/copilot-chat#component-architecture) with additional slots:
```mermaid
graph LR
CS[CopilotSidebar] --> header
CS --> toggleButton
```
### Slot Descriptions
| Slot | Description |
| -------------- | ----------------------------------------- |
| `header` | Header bar with title and close button |
| `toggleButton` | Floating button to open/close the sidebar |
CopilotSidebar also inherits all slots from CopilotChat: `messageView`, `scrollView`, `input`, `suggestionView`, and `welcomeScreen`.
See [Slot Customization](#slot-customization) for details on how to customize these slots.
## Basic Usage
```tsx
import { CopilotSidebar, CopilotKitProvider } from "@copilotkit/react-core";
function App() {
return (
<CopilotKitProvider runtimeUrl="/api/copilotkit">
<CopilotSidebar />
</CopilotKitProvider>
);
}
```
## Props
### Sidebar-Specific Props
These props are unique to CopilotSidebar:
| Prop | Type | Default | Description |
| -------------- | ------------------ | ------- | --------------------------------------------------- |
| `defaultOpen` | `boolean` | `true` | Whether the sidebar is open initially |
| `width` | `number \| string` | `480` | Sidebar width in pixels or CSS unit |
| `header` | `SlotValue` | - | Custom header component with title and close button |
| `toggleButton` | `SlotValue` | - | Custom toggle button to open/close the sidebar |
### Shared Props
CopilotSidebar inherits all props from [CopilotChat](/reference/copilot-chat), including:
- `agentId` - The agent to connect to
- `threadId` - The conversation thread ID
- `labels` - Customize text labels
- `autoScroll` - Auto-scroll behavior
- `className` - CSS class for the root container
See [CopilotChat Props](/reference/copilot-chat#props) for the complete list.
## Header Customization
The sidebar includes a header with a title and close button. Customize it through the `header` prop:
```tsx
<CopilotSidebar
header={{
titleContent: "My Assistant",
closeButton: "hidden",
}}
/>
```
### Header Sub-Slots
| Sub-Slot | Description |
| -------------- | -------------------------------- |
| `titleContent` | The title text or component |
| `closeButton` | The close button (can be hidden) |
### Custom Header Component
Replace the entire header with your own component:
```tsx
function CustomHeader() {
return (
<div className="flex items-center justify-between p-4 border-b">
<div className="flex items-center gap-2">
<BotIcon className="w-5 h-5" />
<span className="font-semibold">My AI Assistant</span>
</div>
<button onClick={() => /* close sidebar */}>
<XIcon className="w-5 h-5" />
</button>
</div>
);
}
<CopilotSidebar header={CustomHeader} />
```
## Toggle Button Customization
The sidebar includes a floating toggle button to open and close it. Customize it through the `toggleButton` prop:
```tsx
<CopilotSidebar
toggleButton={{
className: "bg-purple-500 hover:bg-purple-600",
openIcon: "text-white",
closeIcon: "text-white",
}}
/>
```
### Toggle Button Sub-Slots
| Sub-Slot | Description |
| ----------- | ------------------------------------------------- |
| `openIcon` | Icon shown when sidebar is closed (click to open) |
| `closeIcon` | Icon shown when sidebar is open (click to close) |
### Custom Toggle Button Component
Replace the toggle button entirely:
```tsx
function CustomToggleButton() {
return (
<button className="fixed bottom-4 right-4 p-3 bg-blue-500 rounded-full">
<ChatIcon className="w-6 h-6 text-white" />
</button>
);
}
<CopilotSidebar toggleButton={CustomToggleButton} />;
```
## Slot Customization
CopilotSidebar uses the same [slot system](/reference/slot-system) as CopilotChat. Each slot accepts four types of values:
1. **Tailwind class string** - Add or override CSS classes
2. **Props object** - Pass additional props to the default component
3. **Custom component** - Replace the component entirely
4. **Nested sub-slots** - Drill down to customize child components
### Custom Width
```tsx
<CopilotSidebar width={600} />
// Or with CSS units
<CopilotSidebar width="50vw" />
```
### Custom Header Styling
```tsx
<CopilotSidebar
header={{
className: "bg-gradient-to-r from-blue-500 to-purple-500 text-white",
titleContent: "AI Assistant",
}}
/>
```
### Nested Slot Customization
```tsx
<CopilotSidebar
messageView={{
assistantMessage: {
onThumbsUp: (msg) => console.log("Liked:", msg.id),
onThumbsDown: (msg) => console.log("Disliked:", msg.id),
},
}}
input={{
className: "border-2 border-gray-200",
sendButton: "bg-blue-500 hover:bg-blue-600",
}}
/>
```
## Related
- [CopilotChat](/reference/copilot-chat) - Base chat component with full customization options
- [CopilotPopup](/reference/copilot-popup) - Floating popup chat dialog
- [Slot System](/reference/slot-system) - Deep dive into slot customization
- [CopilotKitProvider](/reference/copilotkit-provider) - Provider configuration
@@ -0,0 +1,550 @@
---
title: CopilotKitCore
description: "CopilotKitCore API Reference"
---
`CopilotKitCore` is the client-side cross-framework orchestration layer that coordinates communication between your
application's UI, agents abd the remote Copilot runtime.
## Architecture Overview
```mermaid
graph TB
subgraph Framework["Framework Layer"]
React["**CopilotKit React**<br/>Components & Hooks"]
Angular["**CopilotKit Angular**<br/>Directives & Services"]
Vue["**CopilotKit ...**<br/>Future frameworks"]
end
subgraph CoreLayer["Core Layer"]
Core["**CopilotKitCore**<br/>Cross-framework Orchestration<br/>State Management & Agent Coordination"]
end
subgraph RuntimeLayer["Runtime Layer"]
Runtime["**CopilotRuntime**<br/>AI Agent Execution<br/>Backend Services"]
end
React --> Core
Angular --> Core
Vue -.-> Core
Core <--> Runtime
```
## What does CopilotKitCore do?
CopilotKitCore solves several complex challenges in building AI-powered applications:
1. **Agent Orchestration**: Handles the entire lifecycle of running AI agents, from starting the agent and executing
tools, to providing tool results, handling follow-ups and handling streaming updates to the UI.
2. **Runtime Connection**: Manages connecting to and synchronizing with the remote `CopilotRuntime`.
3. **State Synchronization**: Maintains consistent state across your application, ensuring all components have access to
the latest agents, tools, and context
4. **Framework Independence**: Works with any frontend framework, providing a consistent API whether you're using React,
Angular, Vue, or vanilla JavaScript
At its heart, CopilotKitCore maintains the authoritative state for these critical elements:
- **Agents**: Both local and remote AI agents that power your application's intelligence
- **Context**: Additional information that agents can use to make more informed decisions
- **Frontend Tools**: Functions that agents can call to interact with your UI
- **Properties and Headers**: Application-specific data forwarded to agents as additional properties or HTTP headers
- **Runtime Metadata**: Connection status, versioning, and configuration details
## Creating a CopilotKitCore Instance
<Info>
In most applications, you dont need to create a `CopilotKitCore` instance
yourself—CopilotKit initializes and manages it behind the scenes.
</Info>
Instantiate `CopilotKitCore` to initialize the client that manages runtime connections, agents, and tools.
```typescript
new CopilotKitCore(config?: CopilotKitCoreConfig)
```
#### Parameters
```typescript
interface CopilotKitCoreConfig {
runtimeUrl?: string; // The endpoint where your CopilotRuntime server is hosted
headers?: Record<string, string>; // Custom HTTP headers to include with every request
properties?: Record<string, unknown>; // Application-specific data forwarded to agents as context
agents__unsafe_dev_only?: Record<string, AbstractAgent>; // Local agents for development only - production requires CopilotRuntime
tools?: FrontendTool<any>[]; // Frontend functions that agents can invoke
}
```
Configuration details:
- `runtimeUrl`: When provided, CopilotKitCore will automatically connect and discover available remote agents.
- `headers`: Headers to include with every request.
- `properties`: Properties forwarded to agents as `forwardedProps`.
- `tools`: Frontend tools that agents can invoke.
- `agents__unsafe_dev_only`: **Development only** - This property is intended solely for rapid prototyping during
development. Production deployments require the security, reliability, and performance guarantees that only the
CopilotRuntime can provide. The key becomes the agent's identifier.
## Core Properties
Once initialized, CopilotKitCore exposes several properties that provide insight into its current state:
### Runtime Configuration
- `runtimeUrl`: `string | undefined` The current runtime endpoint. Changing this property triggers a connection attempt
to the new runtime. Setting it to `undefined` gracefully disconnects from the current runtime.
- `runtimeVersion`: `string | undefined` The version of the connected runtime, helpful for compatibility checks and
debugging.
- `runtimeConnectionStatus`: `CopilotKitCoreRuntimeConnectionStatus` Tracks the current connection state, allowing you
to respond to connection changes in your UI.
### State Management
- `headers`: `Readonly<Record<string, string>>` The current request headers sent with every request.
- `properties`: `Readonly<Record<string, unknown>>` The application properties being forwarded to agents.
- `agents`: `Readonly<Record<string, AbstractAgent>>` A combined view of all available agents, merging local development
agents with those discovered from the runtime.
- `tools`: `Readonly<FrontendTool<any>[]>` The list of registered frontend tools available to agents.
- `context`: `Readonly<Record<string, Context>>` Contextual information that agents can use to make more informed
decisions.
## Understanding Runtime Connections
When you provide a `runtimeUrl`, CopilotKitCore initiates a connection to your CopilotRuntime server. Here's what
happens behind the scenes:
1. CopilotKitCore sends a GET request to `{runtimeUrl}/info`
2. The runtime responds with available agents and metadata
3. For each remote agent, `CopilotKitCore` creates a `ProxiedCopilotRuntimeAgent` instance
4. These remote agents are merged with your local agents
5. Subscribers are notified of the connection status and agent availability
### Runtime Connection States
The connection to your runtime can be in one of four states:
- `Disconnected`: No runtime URL is configured, or the connection was intentionally closed
- `Connecting`: Actively attempting to establish a connection with the runtime
- `Connected`: Successfully connected and remote agents are available
- `Error`: The connection attempt failed, but CopilotKitCore will continue with local agents only
## Event Subscription System
CopilotKitCore implements a robust event system that allows you to react to state changes and agent activities:
### subscribe()
Registers a subscriber to receive events. Returns a subscription object with an `unsubscribe()` method, keeping
unsubscription localized to the subscription object.
```typescript
subscribe(subscriber: CopilotKitCoreSubscriber): { unsubscribe(): void }
```
## Subscribing to Events
The event subscription system allows you to build reactive UIs that respond to CopilotKitCore's state changes. Each
event provides both the CopilotKitCore instance and relevant data:
### onRuntimeConnectionStatusChanged()
Notified whenever the connection to the runtime changes state. Use this to show connection indicators in your UI.
```typescript
onRuntimeConnectionStatusChanged?: (event: {
copilotkit: CopilotKitCore;
status: CopilotKitCoreRuntimeConnectionStatus;
}) => void | Promise<void>
```
### onToolExecutionStart()
Fired when an agent begins executing a tool. Useful for showing loading states or activity indicators.
```typescript
onToolExecutionStart?: (event: {
copilotkit: CopilotKitCore;
toolCallId: string;
agentId: string;
toolName: string;
args: unknown;
}) => void | Promise<void>
```
### onToolExecutionEnd()
Fired when tool execution completes, whether successfully or with an error. Use this to update your UI based on the
results.
```typescript
onToolExecutionEnd?: (event: {
copilotkit: CopilotKitCore;
toolCallId: string;
agentId: string;
toolName: string;
result: string;
error?: string;
}) => void | Promise<void>
```
### onAgentsChanged()
Notified when agents are added, removed, or updated. This includes both local changes and runtime discovery.
```typescript
onAgentsChanged?: (event: {
copilotkit: CopilotKitCore;
agents: Readonly<Record<string, AbstractAgent>>;
}) => void | Promise<void>
```
### onContextChanged()
Fired when context items are added or removed. Use this to keep UI elements in sync with available context.
```typescript
onContextChanged?: (event: {
copilotkit: CopilotKitCore;
context: Readonly<Record<string, Context>>;
}) => void | Promise<void>
```
### onPropertiesChanged()
Notified when application properties are updated. Useful for debugging or showing current configuration.
```typescript
onPropertiesChanged?: (event: {
copilotkit: CopilotKitCore;
properties: Readonly<Record<string, unknown>>;
}) => void | Promise<void>
```
### onHeadersChanged()
Fired when HTTP headers are modified. Important for tracking authentication state changes.
```typescript
onHeadersChanged?: (event: {
copilotkit: CopilotKitCore;
headers: Readonly<Record<string, string>>;
}) => void | Promise<void>
```
### onError()
The central error handler for all CopilotKitCore operations. Every error includes a code and contextual information to
help with debugging.
```typescript
onError?: (event: {
copilotkit: CopilotKitCore;
error: Error;
code: CopilotKitCoreErrorCode;
context: Record<string, any>;
}) => void | Promise<void>
```
## Error Handling
CopilotKitCore provides detailed error information through typed error codes, making it easier to handle different
failure scenarios appropriately:
### Understanding Error Codes
Each error is categorized with a specific code that indicates what went wrong:
- `RUNTIME_INFO_FETCH_FAILED`: The attempt to fetch runtime information failed. This might indicate network issues or an
incorrect runtime URL.
- `AGENT_CONNECT_FAILED`: Failed to establish a connection with an agent. Check that the agent is properly configured.
- `AGENT_RUN_FAILED`: The agent execution failed. This could be due to invalid messages or agent-side errors.
- `AGENT_RUN_FAILED_EVENT`: The agent reported a failure through its event stream.
- `AGENT_RUN_ERROR_EVENT`: The agent emitted an error event during execution.
- `TOOL_ARGUMENT_PARSE_FAILED`: The arguments provided to a tool couldn't be parsed. This usually indicates a mismatch
between expected and actual parameters.
- `TOOL_HANDLER_FAILED`: A tool's handler function threw an error during execution.
## Running Agents
CopilotKitCore provides two primary methods for executing agents: `runAgent` for immediate execution with message
handling, and `connectAgent` for establishing live connections to existing agent sessions.
### runAgent()
Executes an agent and intelligently handles the complete request-response cycle, including automatic tool execution and
follow-up runs.
The execution flow:
1. Sends initial messages (if provided) to the agent
2. Agent processes the request and may request tool calls
3. CopilotKitCore automatically executes any requested frontend tools
4. Tool results are added back to the message history
5. If tools were executed and have `followUp` enabled (default), the agent is automatically re-run with the tool results
6. This cycle continues until the agent completes without requesting more tools
Key behaviors:
- **Automatic Tool Execution**: When an agent requests a tool call, CopilotKitCore finds the matching tool, executes it,
and adds the result to the conversation
- **Smart Follow-ups**: After executing tools, it automatically re-runs the agent so it can process the tool results and
continue its work
- **Error Recovery**: Tool execution errors are captured and returned to the agent, allowing it to handle failures
gracefully
- **Wildcard Tools**: Supports a special "\*" tool that can handle any undefined tool request
```typescript
runAgent(params: CopilotKitCoreRunAgentParams): Promise<RunAgentResult>
```
#### Parameters
```typescript
interface CopilotKitCoreRunAgentParams {
agent: AbstractAgent; // The agent to execute
}
```
### connectAgent()
Establishes a live connection with an agent, restoring any existing conversation history and subscribing to real-time
events. This method is particularly useful when:
- Reconnecting to an agent that's already running (displays new events as they occur)
- Restoring conversation history after a page refresh
- Setting up an agent that will receive updates from background processes
The connection process:
1. Provides the agent with current properties and available tools
2. Sets up error event subscribers for proper error handling
3. Restores any existing message history
4. Returns immediately without triggering a new agent run
```typescript
connectAgent(params: CopilotKitCoreConnectAgentParams): Promise<RunAgentResult>
```
#### Parameters
```typescript
interface CopilotKitCoreConnectAgentParams {
agent: AbstractAgent; // The agent to connect
agentId?: string; // Override the agent's default identifier
}
```
### getAgent()
Retrieves an agent by its identifier. Returns `undefined` if the agent doesn't exist or if the runtime is still
connecting.
```typescript
getAgent(id: string): AbstractAgent | undefined
```
## Managing Context
Context provides agents with additional information about the current state of your application:
### addContext()
Adds contextual information that agents can reference. Returns a unique identifier for later removal.
```typescript
addContext(context: Context): string
```
#### Parameters
```typescript
interface Context {
description: string; // A human-readable description of what this context represents
value: any; // The actual context data
}
```
### removeContext()
Removes previously added context using its identifier.
```typescript
removeContext(id: string): void
```
## Managing Tools
Tools are functions that agents can call to interact with your application:
### addTool()
Registers a new frontend tool. If a tool with the same name and agent scope already exists, the registration is skipped
to prevent duplicates.
```typescript
addTool<T>(tool: FrontendTool<T>): void
```
### removeTool()
Removes a tool from the registry. You can remove tools globally or for specific agents:
- When `agentId` is provided, removes the tool only for that agent
- When `agentId` is omitted, removes only global tools with the matching name
```typescript
removeTool(id: string, agentId?: string): void
```
### getTool()
Retrieves a tool by name, with intelligent fallback behavior:
- If an agent-specific tool isn't found, it falls back to global tools
```typescript
getTool(params: CopilotKitCoreGetToolParams): FrontendTool<any> | undefined
```
#### Parameters
```typescript
interface CopilotKitCoreGetToolParams {
toolName: string; // The tool's name
agentId?: string; // Look for agent-specific tools first
}
```
### setTools()
Replaces all tools at once. Useful for completely reconfiguring available tools.
```typescript
setTools(tools: FrontendTool<any>[]): void
```
## Tool Execution Lifecycle
Understanding how CopilotKitCore handles tool execution is crucial for building responsive AI applications. Here's the
complete lifecycle:
### 1. Tool Request
When an agent needs to interact with your application, it returns a tool call request with:
- Tool name
- Structured arguments (JSON)
- Unique call ID for tracking
### 2. Tool Resolution
CopilotKitCore uses a two-tier resolution strategy:
- First checks for agent-specific tools (scoped to that particular agent)
- Falls back to global tools available to all agents
- Special wildcard tool (`*`) can handle any unmatched tool requests
### 3. Execution & Error Handling
The tool handler is invoked with parsed arguments:
- Successful results are stringified and added to the conversation
- Errors are caught and returned to the agent for graceful handling
- Subscribers are notified of start and completion events
### 4. Automatic Follow-up
By default, after tool execution completes:
- The tool result is inserted into the message history
- The agent is automatically re-run to process the results
- This continues until no more tools are requested
- You can disable follow-up by setting `followUp: false` on specific tools
## Working with Configuration
These methods allow you to dynamically update CopilotKitCore's configuration after initialization:
### setRuntimeUrl()
Changes the runtime endpoint and manages the connection lifecycle. This is useful when switching between different
environments or disconnecting from the runtime entirely.
```typescript
setRuntimeUrl(runtimeUrl: string | undefined): void
```
### setHeaders()
Replaces all HTTP headers. Subscribers are notified so they can react to authentication changes or other header updates.
```typescript
setHeaders(headers: Record<string, string>): void
```
### setProperties()
Updates the properties forwarded to agents. Use this when your application state changes in ways that might affect agent
behavior.
```typescript
setProperties(properties: Record<string, unknown>): void
```
## Managing Local Agents
<Warning>
In production applications, agents must be managed through the CopilotRuntime,
which provides proper isolation, monitoring, and scalability. The local agent
methods below are marked `__unsafe_dev_only` as they're intended solely for
rapid prototyping during development. Production deployments require the
security and performance guarantees that only the CopilotRuntime can provide.
</Warning>
Agents are the AI-powered components that process requests and generate responses. CopilotKitCore provides several
methods to manage them locally during development:
### setAgents\_\_unsafe_dev_only()
Replaces all local development agents while preserving remote agents from the runtime.
```typescript
setAgents__unsafe_dev_only(agents: Record<string, AbstractAgent>): void
```
### addAgent\_\_unsafe_dev_only()
Adds a single agent for development testing.
```typescript
addAgent__unsafe_dev_only(params: CopilotKitCoreAddAgentParams): void
```
#### Parameters
```typescript
interface CopilotKitCoreAddAgentParams {
id: string; // A unique identifier for the agent
agent: AbstractAgent; // The agent instance to add
}
```
### removeAgent\_\_unsafe_dev_only()
Removes a local development agent by its identifier. Remote agents from the runtime cannot be removed this way.
```typescript
removeAgent__unsafe_dev_only(id: string): void
```
@@ -0,0 +1,298 @@
---
title: CopilotKitProvider
description: "CopilotKitProvider API Reference"
---
`CopilotKitProvider` is the React context provider that initializes and manages `CopilotKitCore` for your React
application. It provides all child components with access to agents, tools, and copilot functionality through React's
context API.
## What is CopilotKitProvider?
The CopilotKitProvider is the root component that:
- Creates and manages a `CopilotKitCore` instance
- Provides React-specific features like hooks and render components
- Manages tool rendering and human-in-the-loop interactions
- Handles state synchronization between your React app and AI agents
## Basic Usage
Typically you would wrap your application with `CopilotKitProvider` at the root level:
```tsx
import { CopilotKitProvider } from "@copilotkit/react-core";
function App() {
return (
<CopilotKitProvider runtimeUrl="http://localhost:3000/api/copilotkit">
{/* Your app components */}
</CopilotKitProvider>
);
}
```
## Props
### runtimeUrl
`string` **(optional)**
The URL of your CopilotRuntime server. The provider will automatically connect to the runtime and discover available
agents.
```tsx
<CopilotKitProvider runtimeUrl="https://api.example.com/copilot">
{children}
</CopilotKitProvider>
```
### headers
`Record<string, string>` **(optional)**
Custom HTTP headers to include with every request to the runtime. Useful for authentication and custom metadata.
```tsx
<CopilotKitProvider
runtimeUrl="https://api.example.com"
headers={{
Authorization: "Bearer your-token",
"X-Custom-Header": "value",
}}
>
{children}
</CopilotKitProvider>
```
### properties
`Record<string, unknown>` **(optional)**
Application-specific data that gets forwarded to agents as additional context. Agents receive these as `forwardedProps`.
```tsx
<CopilotKitProvider
properties={{
userId: "user-123",
theme: "dark",
locale: "en-US",
featureFlags: {
betaFeatures: true,
},
}}
>
{children}
</CopilotKitProvider>
```
### agents\_\_unsafe_dev_only
`Record<string, AbstractAgent>` **(optional, development only)**
<Warning>
This property is intended solely for rapid prototyping during development.
Production deployments require the security, reliability, and performance
guarantees that only the CopilotRuntime can provide.
</Warning>
Local agents for development testing. The key becomes the agent's identifier.
```tsx
import { HttpAgent } from "@ag-ui/client";
const devAgent = new HttpAgent({
url: "http://localhost:8000",
});
<CopilotKitProvider
agents__unsafe_dev_only={{
devAgent,
}}
>
{children}
</CopilotKitProvider>;
```
### useSingleEndpoint
`boolean` **(optional, default: `false`)**
When set to `true`, the provider connects to runtimes that expose the **single-route** transport (a single POST endpoint that multiplexes all runtime actions). Leave this `false` for the default REST-style transport.
Pair this flag with the matching server endpoint helper:
```tsx
<CopilotKitProvider runtimeUrl="/api/copilotkit" useSingleEndpoint>
{children}
</CopilotKitProvider>
```
On the server, mount one of the single-route runtimes (`createCopilotEndpointSingleRoute` for Hono or `createCopilotEndpointSingleRouteExpress` for Express).
### renderToolCalls
`ReactToolCallRenderer[]` **(optional)**
A static list of components to render when specific tools are called. Enables visual feedback for tool execution.
```tsx
const renderToolCalls = [
{
name: "searchProducts",
args: z.object({
query: z.string(),
}),
render: ({ args }) => <div>Searching for: {args.query}</div>,
},
];
<CopilotKitProvider renderToolCalls={renderToolCalls}>
{children}
</CopilotKitProvider>;
```
<Note>
The `renderToolCalls` array must be stable across renders. Define it outside
your component or use `useMemo`. For dynamic tool rendering, use the
`useRenderToolCall` hook instead.
</Note>
### frontendTools
`ReactFrontendTool[]` **(optional)**
A static list of frontend tools that agents can invoke. These are React-specific wrappers around the base `FrontendTool`
type with additional rendering capabilities.
```tsx
const tools = [
{
name: "showNotification",
description: "Display a notification to the user",
parameters: z.object({
message: z.string(),
type: z.enum(["info", "success", "warning", "error"]),
}),
handler: async ({ message, type }) => {
toast[type](message);
return "Notification displayed";
},
},
];
<CopilotKitProvider frontendTools={tools}>{children}</CopilotKitProvider>;
```
<Note>
The `frontendTools` array must be stable across renders. For dynamically
adding/removing tools, use the `useFrontendTool` hook.
</Note>
### humanInTheLoop
`ReactHumanInTheLoop[]` **(optional)**
Tools that require human interaction or approval before execution. These tools pause agent execution until the user
responds.
```tsx
const humanInTheLoop = [
{
name: "confirmAction",
description: "Request user confirmation for an action",
parameters: z.object({
action: z.string(),
details: z.string(),
}),
render: ({ args, resolve }) => (
<ConfirmDialog
action={args.action}
details={args.details}
onConfirm={() => resolve({ confirmed: true })}
onCancel={() => resolve({ confirmed: false })}
/>
),
},
];
<CopilotKitProvider humanInTheLoop={humanInTheLoop}>
{children}
</CopilotKitProvider>;
```
### a2ui
`{ theme?: Theme; catalog?: any; loadingComponent?: React.ComponentType; includeSchema?: boolean }` **(optional)**
Configuration for the A2UI (Agent-to-UI) renderer. The built-in renderer activates automatically when the runtime reports that `a2ui` is configured in `CopilotRuntime`. This prop is only needed to override defaults.
| Option | Type | Description |
| ------------------ | --------------------- | ------------------------------------------------------------------------------------------------------------ |
| `theme` | `Theme` | Override the default A2UI viewer theme. |
| `catalog` | `any` | Custom component catalog. Defaults to `basicCatalog`. |
| `loadingComponent` | `React.ComponentType` | Custom loading component shown while a surface is generating. |
| `includeSchema` | `boolean` | When `true` (default), full component schemas are sent as agent context so the agent knows what's available. |
```tsx
<CopilotKitProvider
runtimeUrl="/api/copilotkit"
a2ui={{
theme: myCustomTheme,
catalog: myCustomCatalog,
loadingComponent: MySpinner,
includeSchema: true,
}}
>
{children}
</CopilotKitProvider>
```
### children
`ReactNode` **(required)**
The React components that will have access to the CopilotKit context.
## Context Value
The provider makes a `CopilotKitContextValue` available to child components through React context:
```typescript
interface CopilotKitContextValue {
copilotkit: CopilotKitCore;
renderToolCalls: ReactToolCallRenderer<any>[];
currentRenderToolCalls: ReactToolCallRenderer<unknown>[];
setCurrentRenderToolCalls: React.Dispatch<
React.SetStateAction<ReactToolCallRenderer<unknown>[]>
>;
}
```
Access this context using the `useCopilotKit` hook:
```tsx
import { useCopilotKit } from "@copilotkit/react-core";
function MyComponent() {
const { copilotkit } = useCopilotKit();
// Access CopilotKitCore instance
const agent = copilotkit.getAgent("assistant");
}
```
## Considerations
### Server-Side Rendering (SSR)
The provider is compatible with SSR but won't fetch runtime information during server-side rendering. The runtime
connection is established only on the client side to prevent blocking SSR.
### Dynamic Updates
You can dynamically update the following props:
- `runtimeUrl`: Changing this will disconnect from the current runtime and connect to the new one
- `headers`: Updates are applied to all future requests
- `properties`: Changes are immediately available to agents
@@ -0,0 +1,159 @@
---
title: FrontendTool
description: "FrontendTool API Reference"
---
`FrontendTool` is a cross-platform type that defines tools (functions) that AI agents can invoke in your frontend
application. These tools enable agents to interact the user, retrieve data, perform actions, and integrate with your
application's functionality.
## What is a FrontendTool?
A FrontendTool represents a capability you expose to AI agents, allowing them to:
- Interact with the user
- Fetch or manipulate application data
- Trigger application workflows
Frontend tools are framework-agnostic and work consistently across all frameworks through `CopilotKitCore`.
## Type Definition
```typescript
type FrontendToolHandlerContext = {
toolCall: ToolCall;
agent: AbstractAgent;
};
type FrontendTool<T extends Record<string, unknown> = Record<string, unknown>> =
{
name: string;
description?: string;
parameters?: z.ZodType<T>;
handler?: (
args: T,
context: FrontendToolHandlerContext,
) => Promise<unknown>;
followUp?: boolean;
agentId?: string;
};
```
## Properties
### name
`string` **(required)**
A unique identifier for the tool. This is the name agents will use to request this tool's execution. Avoid spaces and
special characters.
```typescript
{
name: "searchProducts";
}
```
A special wildcard tool is available with the name `*`. This tool will handle any unmatched tool requests.
### description
`string` **(optional)**
A human-readable description that helps agents understand when and how to use this tool. This description is sent to the
LLM to guide its decision-making.
```typescript
{
name: "searchProducts",
description: "Search for products in the catalog by name, category, or price range"
}
```
### parameters
`z.ZodType<T>` **(optional)**
A Zod schema that defines and validates the tool's input parameters. This ensures type safety and provides automatic
validation of agent-provided arguments.
```typescript
import { z } from "zod";
{
name: "updateUserProfile",
parameters: z.object({
firstName: z.string().optional(),
lastName: z.string().optional(),
email: z.string().email().optional(),
preferences: z.object({
theme: z.enum(["light", "dark"]).optional(),
notifications: z.boolean().optional()
}).optional()
})
}
```
### handler
`(args: T, context: FrontendToolHandlerContext) => Promise<unknown>` **(optional)**
The async function that executes when the agent invokes this tool. It receives the validated arguments and a context
object containing the `toolCall` with metadata about the invocation.
```typescript
{
name: "addToCart",
parameters: z.object({
productId: z.string(),
quantity: z.number().min(1)
}),
handler: async ({productId, quantity}) => {
// Add product to cart
const result = await cartService.addItem(productId, quantity);
// Return a string or serializable object
return {
success: true,
cartTotal: result.total,
itemCount: result.itemCount
};
}
}
```
### followUp
`boolean` **(optional, default: true)**
Controls whether the agent should be automatically re-run after this tool completes. When `true`, the tool's result is
added to the conversation and the agent continues processing. Disable follow-up for final actions that complete a
workflow.
```typescript
{
name: "saveDocument",
handler: async (args) => {
await documentService.save(args);
return "Document saved successfully";
},
followUp: false // Don't re-run agent after saving
}
```
### agentId
`string` **(optional)**
Restricts this tool to a specific agent. When set, only the specified agent can invoke this tool.
```typescript
{
name: "adminAction",
agentId: "admin-assistant",
handler: async (args) => {
// Only the admin-assistant agent can call this
return await performAdminAction(args);
}
}
```
@@ -0,0 +1,81 @@
---
title: ProxiedCopilotRuntimeAgent
description: "ProxiedCopilotRuntimeAgent API Reference"
---
`ProxiedCopilotRuntimeAgent` is a specialized HTTP agent that acts as a proxy between your client application and remote
agents hosted on the `CopilotRuntime` server. It extends the base `HttpAgent` class to provide seamless communication
with runtime-hosted agents.
## Architecture Overview
```mermaid
graph LR
subgraph Client["Client Application"]
Core[CopilotKitCore]
PRA1[ProxiedCopilotRuntimeAgent<br/>customer-support]
PRA2[ProxiedCopilotRuntimeAgent<br/>code-assistant]
PRA3[ProxiedCopilotRuntimeAgent<br/>data-analyst]
Core --> PRA1
Core --> PRA2
Core --> PRA3
end
subgraph Server["CopilotRuntime Server"]
Runtime[Runtime API]
Agent1[Agent: customer-support]
Agent2[Agent: code-assistant]
Agent3[Agent: data-analyst]
Runtime --> Agent1
Runtime --> Agent2
Runtime --> Agent3
end
PRA1 -.-> Runtime
PRA2 -.-> Runtime
PRA3 -.-> Runtime
```
## What is ProxiedCopilotRuntimeAgent?
When `CopilotKitCore` connects to a `CopilotRuntime` server, it discovers available remote agents. For each remote
agent, it creates a `ProxiedCopilotRuntimeAgent` instance that handles all communication with that specific agent
through the runtime's API endpoints.
Key characteristics:
- **Remote Agent Communication**: Handles communication with the remote agent through the runtime's API endpoints
- **Header and Property Forwarding**: Inherits and forwards authentication headers and properties from `CopilotKitCore`
- **Connection and History Management**: Handles loading history and reconnecting to existing live agent sessions
## How does it work?
`CopilotKitCore` automatically creates `ProxiedCopilotRuntimeAgent` instances during runtime discovery:
1. `CopilotKitCore` fetches `/info` from the runtime
2. The runtime responds with available agents
3. For each agent, `CopilotKitCore` creates a `ProxiedCopilotRuntimeAgent`
4. These agents are merged with any local agents
5. The agents become available through `copilotKit.getAgent()`
## Creating a ProxiedCopilotRuntimeAgent
<Note>
In typical usage, you don't create `ProxiedCopilotRuntimeAgent` instances
directly. `CopilotKitCore` automatically creates them when discovering agents
from the runtime.
</Note>
```typescript
import { ProxiedCopilotRuntimeAgent } from "@copilotkit/core";
const agent = new ProxiedCopilotRuntimeAgent({
runtimeUrl: "https://your-runtime.example.com",
agentId: "my-agent",
headers: {
Authorization: "Bearer your-token",
},
});
```
+394
View File
@@ -0,0 +1,394 @@
---
title: Slot System
description: "Deep customization system for CopilotKit components"
---
The Slot System is CopilotKit's approach to component customization. It allows you to customize any part of the UI - from simple styling changes to complete component replacement - all through a consistent, composable API.
## What is the Slot System?
The Slot System:
- Provides four levels of customization depth
- Maintains type safety throughout the customization process
- Supports nested slots for drilling into child components
- Uses automatic memoization for optimal performance
- Works consistently across all CopilotKit components
## Four Customization Levels
Every slot accepts one of four value types, from simplest to most flexible:
### 1. Tailwind Class String
Pass a string of Tailwind classes to add or override styles:
```tsx
<CopilotChat
input="border-2 border-blue-500 rounded-xl"
messageView="space-y-4 p-4"
/>
```
Classes are merged with the component's existing classes using `tailwind-merge`, so conflicting classes are resolved intelligently.
### 2. Props Object
Pass an object of props to customize behavior while keeping the default component:
```tsx
<CopilotChat
input={{
className: "custom-input",
autoFocus: false,
}}
messageView={{
className: "custom-messages",
assistantMessage: {
onThumbsUp: (msg) => trackFeedback(msg.id, "positive"),
},
}}
/>
```
Props are merged with defaults, and you can include nested slots to drill down to child components.
### 3. Custom Component
Replace the component entirely with your own implementation:
```tsx
function CustomInput({ onSubmitMessage, isRunning, ...props }) {
return (
<div className="my-custom-wrapper">
<CopilotChatInput
onSubmitMessage={onSubmitMessage}
isRunning={isRunning}
{...props}
/>
</div>
);
}
<CopilotChat input={CustomInput} />;
```
Custom components receive all the props that would have been passed to the default component.
### 4. Render Function (Children)
For full layout control, use the children render function pattern:
```tsx
function CustomInput(props) {
return (
<CopilotChatInput {...props}>
{({ textArea, sendButton, addMenuButton }) => (
<div className="flex gap-2">
{addMenuButton}
<div className="flex-1">{textArea}</div>
{sendButton}
</div>
)}
</CopilotChatInput>
);
}
<CopilotChat input={CustomInput} />;
```
The render function receives pre-built slot elements that you can arrange however you like.
## Nested Slot Customization
Slots can be nested to customize deeply nested components:
```tsx
<CopilotChat
// Top-level slot
messageView={{
// First level nesting
assistantMessage: {
// Second level nesting
toolbar: "bg-gray-50 rounded-lg",
copyButton: "text-blue-500",
thumbsUpButton: () => null, // Hide the button
},
userMessage: "bg-blue-100 rounded-xl",
}}
input={{
textArea: "text-lg",
sendButton: "bg-green-500",
}}
/>
```
## Hiding Components
To hide a slot entirely, return `null` from a component function:
```tsx
<CopilotChat
input={{
disclaimer: () => null, // Hide disclaimer
startTranscribeButton: () => null, // Hide voice button
}}
messageView={{
assistantMessage: {
regenerateButton: () => null, // Hide regenerate
},
}}
/>
```
## Complete Slot Hierarchy
Here's the full hierarchy of all customizable slots in CopilotChat:
```
CopilotChat
├── chatView
│ ├── messageView
│ │ ├── assistantMessage
│ │ │ ├── markdownRenderer
│ │ │ ├── toolbar
│ │ │ ├── copyButton
│ │ │ ├── thumbsUpButton
│ │ │ ├── thumbsDownButton
│ │ │ ├── readAloudButton
│ │ │ ├── regenerateButton
│ │ │ └── toolCallsView
│ │ ├── userMessage (see CopilotChatUserMessage)
│ │ │ ├── messageRenderer
│ │ │ ├── toolbar
│ │ │ ├── copyButton
│ │ │ ├── editButton
│ │ │ └── branchNavigation
│ │ └── cursor
│ ├── scrollView
│ │ ├── scrollToBottomButton
│ │ └── feather
│ ├── input
│ │ ├── textArea
│ │ ├── sendButton
│ │ ├── startTranscribeButton
│ │ ├── cancelTranscribeButton
│ │ ├── finishTranscribeButton
│ │ ├── addMenuButton
│ │ ├── audioRecorder
│ │ └── disclaimer
│ ├── suggestionView
│ │ ├── container
│ │ └── suggestion
│ └── welcomeScreen
│ └── welcomeMessage
```
## How It Works
Under the hood, the slot system uses three key concepts:
### SlotValue Type
Every slot accepts one of three value types:
```typescript
type SlotValue<C extends React.ComponentType<any>> =
| C // Custom component
| string // Tailwind class string
| Partial<React.ComponentProps<C>>; // Props object
```
### renderSlot Function
The `renderSlot` function resolves a slot value into a React element:
```typescript
// Internal implementation (simplified)
function renderSlot(slot, DefaultComponent, props) {
if (typeof slot === "string") {
// Merge className with existing
return <DefaultComponent {...props} className={twMerge(props.className, slot)} />;
}
if (isReactComponent(slot)) {
// Use custom component
return <slot {...props} />;
}
if (isPropsObject(slot)) {
// Merge props
return <DefaultComponent {...props} {...slot} />;
}
// Use default
return <DefaultComponent {...props} />;
}
```
### WithSlots Type
Components use the `WithSlots` type to define their slot interface:
```typescript
type MyComponentProps = WithSlots<
{
button: typeof MyButton;
input: typeof MyInput;
},
{
value: string;
onChange: (value: string) => void;
}
>;
```
## Best Practices
### 1. Start Simple, Escalate as Needed
Begin with Tailwind classes, then move to props objects, and only use custom components when necessary:
```tsx
// Start here
<CopilotChat input="border-blue-500" />
// Then this
<CopilotChat input={{ className: "border-blue-500", autoFocus: false }} />
// Only if needed
<CopilotChat input={CustomInputComponent} />
```
### 2. Use Props Objects for Nested Customization
When customizing nested slots, use props objects to drill down:
```tsx
<CopilotChat
messageView={{
assistantMessage: {
className: "bg-blue-50",
toolbar: "border-t mt-2",
copyButton: "text-blue-600",
},
}}
/>
```
### 3. Preserve Default Behavior
When creating custom components, spread the remaining props to preserve default functionality:
```tsx
function CustomButton({ onClick, disabled, className, ...props }) {
return (
<button
onClick={onClick}
disabled={disabled}
className={twMerge("my-custom-classes", className)}
{...props} // Preserve other props
/>
);
}
```
### 4. Use Render Functions for Complex Layouts
When you need to completely rearrange elements, use the render function pattern:
```tsx
function CustomLayout(props) {
return (
<CopilotChatInput {...props}>
{({ textArea, sendButton, addMenuButton }) => (
<div className="grid grid-cols-[auto_1fr_auto] gap-2">
{addMenuButton}
{textArea}
{sendButton}
</div>
)}
</CopilotChatInput>
);
}
```
## Examples
### Themed Chat Interface
```tsx
<CopilotChat
className="bg-gray-900 text-white"
messageView={{
className: "p-4",
assistantMessage: {
className: "bg-gray-800 rounded-xl p-4",
toolbar: "border-gray-700",
},
userMessage: "bg-blue-600 text-white rounded-2xl px-4 py-2",
}}
input={{
className: "bg-gray-800 border-gray-700",
sendButton: "bg-blue-600 hover:bg-blue-700",
}}
scrollView={{
feather: "from-gray-900 via-gray-900 to-transparent",
}}
/>
```
### Minimal Interface
```tsx
<CopilotChat
welcomeScreen={false}
input={{
disclaimer: () => null,
startTranscribeButton: () => null,
addMenuButton: () => null,
}}
scrollView={{
scrollToBottomButton: () => null,
feather: () => null,
}}
messageView={{
assistantMessage: {
toolbar: () => null,
},
}}
/>
```
### Feedback-Focused Interface
```tsx
<CopilotChat
messageView={{
assistantMessage: {
onThumbsUp: (msg) => {
analytics.track("positive_feedback", { messageId: msg.id });
toast.success("Thanks for your feedback!");
},
onThumbsDown: (msg) => {
analytics.track("negative_feedback", { messageId: msg.id });
showFeedbackModal(msg);
},
toolbar: "bg-yellow-50 border border-yellow-200 rounded-lg p-2",
thumbsUpButton: "text-green-600 hover:text-green-800",
thumbsDownButton: "text-red-600 hover:text-red-800",
},
}}
/>
```
## Related
- [CopilotChat](/reference/copilot-chat) - Main chat component
- [CopilotChatInput](/reference/copilot-chat-input) - Input component slots
- [CopilotChatAssistantMessage](/reference/copilot-chat-assistant-message) - Assistant message slots
- [CopilotChatUserMessage](/reference/copilot-chat-user-message) - User message slots
- [CopilotChatScrollView](/reference/copilot-chat-scroll-view) - Scroll container slots
- [CopilotChatSuggestionView](/reference/copilot-chat-suggestion-view) - Suggestion chips slots
- [CopilotChatWelcomeScreen](/reference/copilot-chat-welcome-screen) - Welcome screen slots
- [CopilotChatMessageView](/reference/copilot-chat-message-view) - Message list slots
@@ -0,0 +1,391 @@
---
title: useAgentContext
description: "useAgentContext Hook API Reference"
---
`useAgentContext` is a React hook that provides contextual information to AI agents during their execution. It allows
you to dynamically add relevant data that agents can use to make more informed decisions and provide better responses.
## What is useAgentContext?
The useAgentContext hook:
- Provides contextual information to agents
- Automatically manages context lifecycle (add on mount, remove on unmount)
- Updates context when values change
- Helps agents understand application state and user data
## Basic Usage
```tsx
import { useAgentContext } from "@copilotkit/react-core";
function UserPreferences() {
const userSettings = {
theme: "dark",
language: "en",
timezone: "UTC-5",
};
useAgentContext({
description: "User preferences and settings",
value: userSettings,
});
return <div>User preferences loaded</div>;
}
```
## Parameters
The hook accepts a single `Context` object with the following properties:
### description
`string` **(required)**
A clear description of what this context represents. This helps agents understand how to use the provided information.
```tsx
useAgentContext({
description: "Current shopping cart contents",
value: cartItems,
});
```
### value
`any` **(required)**
The actual data to provide as context. Can be any serializable value including objects, arrays, strings, or numbers.
```tsx
useAgentContext({
description: "Current form validation state",
value: {
hasErrors: false,
touchedFields: ["email", "name"],
dirtyFields: ["email"],
isSubmitting: false,
},
});
```
## Examples
### User Preferences Context
```tsx
import { useAgentContext } from "@copilotkit/react-core";
import { useUserPreferences } from "./hooks/useUserPreferences";
function UserPreferencesContext() {
const { preferences, isLoading } = useUserPreferences();
useAgentContext({
description: "User display preferences and settings",
value: {
theme: preferences?.theme || "light",
language: preferences?.language || "en",
timezone: preferences?.timezone || "UTC",
displayDensity: preferences?.displayDensity || "comfortable",
isLoading,
},
});
return null; // Context-only component
}
```
### Form State Context
```tsx
import { useAgentContext } from "@copilotkit/react-core";
import { useState } from "react";
function ContactForm() {
const [formData, setFormData] = useState({
name: "",
email: "",
subject: "",
message: "",
});
// Provide form state to agent for assistance
useAgentContext({
description: "Contact form current state",
value: {
formData,
hasUnsavedChanges: Object.values(formData).some((v) => v !== ""),
isValid: formData.email.includes("@") && formData.name.length > 0,
},
});
return (
<form>
<input
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
placeholder="Name"
/>
{/* Rest of form fields */}
</form>
);
}
```
### Application State Context
```tsx
import { useAgentContext } from "@copilotkit/react-core";
import { useLocation } from "react-router-dom";
function AppStateContext() {
const location = useLocation();
const currentTime = new Date().toISOString();
useAgentContext({
description: "Current application state and navigation",
value: {
currentPath: location.pathname,
queryParams: Object.fromEntries(new URLSearchParams(location.search)),
timestamp: currentTime,
},
});
return null;
}
```
### Dynamic Data Context
```tsx
import { useAgentContext } from "@copilotkit/react-core";
import { useEffect, useState } from "react";
function DynamicDataContext() {
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
const response = await fetch("/api/context-data");
setData(await response.json());
};
fetchData();
}, []);
// Context updates automatically when data changes
useAgentContext({
description: "Dynamic application data",
value: data || { loading: true },
});
return null;
}
```
### Multiple Contexts
```tsx
import { useAgentContext } from "@copilotkit/react-core";
function MultipleContexts() {
const userContext = { id: "123", name: "John" };
const appContext = { version: "1.0.0", features: ["chat", "search"] };
// Use multiple hooks for different contexts
useAgentContext({
description: "User information",
value: userContext,
});
useAgentContext({
description: "Application configuration",
value: appContext,
});
return <div>Multiple contexts provided</div>;
}
```
## Context Lifecycle
### Automatic Management
Context is automatically managed throughout the component lifecycle:
```tsx
function ManagedContext() {
const [count, setCount] = useState(0);
useAgentContext({
description: "Counter state",
value: { count, lastUpdated: Date.now() },
});
// Context is:
// 1. Added when component mounts
// 2. Updated when count changes
// 3. Removed when component unmounts
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
```
### Updates on Change
Context automatically updates when values change:
```tsx
function ReactiveContext() {
const [filters, setFilters] = useState({
category: "all",
priceRange: [0, 100],
});
// Context updates whenever filters change
useAgentContext({
description: "Active search filters",
value: filters,
});
return (
<div>
<select
value={filters.category}
onChange={(e) => setFilters({ ...filters, category: e.target.value })}
>
<option value="all">All</option>
<option value="electronics">Electronics</option>
<option value="clothing">Clothing</option>
</select>
</div>
);
}
```
## Best Practices
### Descriptive Context Names
Provide clear, descriptive names for your context:
```tsx
// ✅ Good - Clear and specific
useAgentContext({
description: "E-commerce shopping cart with items and totals",
value: cartData,
});
// ❌ Avoid - Too vague
useAgentContext({
description: "Data",
value: cartData,
});
```
### Structured Data
Organize context data in a structured format:
```tsx
// ✅ Good - Well-structured data
useAgentContext({
description: "Order processing state",
value: {
orderId: "ORD-123",
status: "processing",
items: [{ id: "1", name: "Product", quantity: 2, price: 29.99 }],
customer: {
id: "CUST-456",
email: "user@example.com",
},
timestamps: {
created: "2024-01-01T10:00:00Z",
updated: "2024-01-01T10:30:00Z",
},
},
});
// ❌ Avoid - Unstructured data
useAgentContext({
description: "Order info",
value: "Order ORD-123 for user@example.com with 2 items",
});
```
### Performance Optimization
Memoize complex computed values:
```tsx
import { useMemo } from "react";
function OptimizedContext({ items }) {
const contextValue = useMemo(
() => ({
itemCount: items.length,
totalValue: items.reduce((sum, item) => sum + item.price, 0),
categories: [...new Set(items.map((item) => item.category))],
}),
[items],
);
useAgentContext({
description: "Computed inventory statistics",
value: contextValue,
});
return null;
}
```
## Integration with Agents
Context provided through this hook is available to agents during execution:
```tsx
import {
useAgentContext,
useAgent,
useCopilotKit,
} from "@copilotkit/react-core";
function IntegratedExample() {
const { agent } = useAgent();
const { copilotkit } = useCopilotKit();
const [productSearch, setProductSearch] = useState("");
// Provide search context
useAgentContext({
description: "Current product search parameters",
value: {
searchQuery: productSearch,
resultsPerPage: 20,
sortBy: "relevance",
},
});
const handleSearch = async () => {
// Agent has access to the context when running
agent.addMessage({
id: crypto.randomUUID(),
role: "user",
content: `Help me refine my search for: ${productSearch}`,
});
await copilotkit.runAgent({ agent });
};
return (
<div>
<input
value={productSearch}
onChange={(e) => setProductSearch(e.target.value)}
placeholder="Search products..."
/>
<button onClick={handleSearch}>Get AI Help</button>
</div>
);
}
```
+491
View File
@@ -0,0 +1,491 @@
---
title: useAgent
description: "useAgent Hook API Reference"
---
`useAgent` is a React hook that provides access to [AG-UI](https://ag-ui.com) agents and subscribes to their state
changes. It enables components to interact with agents, access their messages, and respond to updates in real-time.
The hook always returns an agent instance. While the runtime is syncing, it returns a provisional runtime agent; once
the runtime has synced, if the agent id does not exist the hook throws an error.
## What is useAgent?
The useAgent hook:
- Retrieves an agent by ID from the CopilotKit context
- Subscribes to agent state changes (messages, state, run status)
- Automatically triggers component re-renders when the agent updates
- Handles cleanup of subscriptions when the component unmounts
## Basic Usage
```tsx
import { useAgent } from "@copilotkit/react-core";
function ChatComponent() {
const { agent } = useAgent({ agentId: "assistant" });
return (
<div>
<h2>Agent: {agent.id}</h2>
<div>Messages: {agent.messages.length}</div>
<div>Running: {agent.isRunning ? "Yes" : "No"}</div>
</div>
);
}
```
## Parameters
### agentId
`string` **(optional)**
The ID of the agent to retrieve. If not provided, defaults to `"default"`.
```tsx
const { agent } = useAgent({ agentId: "customer-support" });
```
### updates
`UseAgentUpdate[]` **(optional)**
An array of update types to subscribe to. This allows you to optimize re-renders by only subscribing to specific
changes.
```tsx
import { useAgent, UseAgentUpdate } from "@copilotkit/react-core";
const { agent } = useAgent({
agentId: "assistant",
updates: [UseAgentUpdate.OnMessagesChanged],
});
```
Available update types:
- `UseAgentUpdate.OnMessagesChanged` - Updates when messages are added or modified
- `UseAgentUpdate.OnStateChanged` - Updates when agent state changes
- `UseAgentUpdate.OnRunStatusChanged` - Updates when agent starts or stops running
If `updates` is not provided, the hook subscribes to all update types by default.
## Return Value
The hook returns an object with a single property:
### agent
`AbstractAgent`
The agent instance. During runtime synchronization, the hook returns a provisional runtime agent so you can bind UI
immediately. After the runtime has synced (Connected or Error), if the agent id does not exist the hook throws an
error.
## Accessing Agent Messages
The agent's message history is available through the `messages` property. You can read messages and add new ones to
create interactive conversations.
### Reading Messages
```tsx
function SimpleChat() {
const { agent } = useAgent();
return (
<div>
{agent.messages.map((message) => (
<div key={message.id}>
<strong>{message.role}:</strong> {message.content}
</div>
))}
</div>
);
}
```
### Sending Messages
To send a message, add it to the agent and then run the agent:
```tsx
import { useAgent } from "@copilotkit/react-core";
import { useCopilotKit } from "@copilotkit/react-core";
function MessageSender() {
const { agent } = useAgent({ agentId: "assistant" });
const { copilotkit } = useCopilotKit();
const sendMessage = async (content: string) => {
// Add message to agent
agent.addMessage({
id: crypto.randomUUID(),
role: "user",
content,
});
// Run the agent to get a response
await copilotkit.runAgent({
agent,
agentId: "assistant",
});
};
return (
<div>
<button onClick={() => sendMessage("Hello!")} disabled={agent.isRunning}>
Send Hello
</button>
</div>
);
}
```
## Accessing and Updating Shared State
Shared state enables real-time collaboration between users and agents. Both can read and modify the state, creating a
synchronized workspace for interactive features.
### Understanding Shared State
The agent's state is a shared data structure that:
- Can be read by both your application and the agent
- Can be modified by both parties
- Automatically triggers re-renders when changed
- Persists throughout the conversation
State updates cause re-renders when:
- You call `agent.setState()` from your application
- The agent modifies the state during execution
- Any state change occurs, regardless of source
### Reading State
```tsx
function StateDisplay() {
const { agent } = useAgent({
updates: [UseAgentUpdate.OnStateChanged], // Subscribe to state changes
});
return (
<div>
<h3>Current State</h3>
<pre>{JSON.stringify(agent.state, null, 2)}</pre>
</div>
);
}
```
### Updating State
```tsx
function StateController() {
const { agent } = useAgent({
updates: [UseAgentUpdate.OnStateChanged],
});
const updateState = (key: string, value: any) => {
// Update the shared state
agent.setState({
...agent.state,
[key]: value,
});
// This will trigger re-renders for all components
// subscribed to OnStateChanged
};
return (
<div>
<button
onClick={() => updateState("counter", (agent.state.counter || 0) + 1)}
>
Increment Counter: {agent.state.counter || 0}
</button>
</div>
);
}
```
### Collaborative Features
Shared state enables collaborative features where users and agents work together:
```tsx
function CollaborativeTodo() {
const { agent } = useAgent({
updates: [UseAgentUpdate.OnStateChanged],
});
const { copilotkit } = useCopilotKit();
const todos = agent.state.todos || [];
const addTodo = (text: string) => {
agent.setState({
...agent.state,
todos: [...todos, { id: crypto.randomUUID(), text, done: false }],
});
};
const toggleTodo = (id: string) => {
agent.setState({
...agent.state,
todos: todos.map((todo) =>
todo.id === id ? { ...todo, done: !todo.done } : todo,
),
});
};
const askAgentToOrganize = async () => {
// Add a message asking the agent to organize todos
agent.addMessage({
id: crypto.randomUUID(),
role: "user",
content: "Please organize my todos by priority",
});
// The agent can read and modify the todos in agent.state
await copilotkit.runAgent({ agent });
// After the agent runs, the state will be updated
// and the component will re-render automatically
};
return (
<div>
<h3>Shared Todo List</h3>
<ul>
{todos.map((todo) => (
<li key={todo.id}>
<input
type="checkbox"
checked={todo.done}
onChange={() => toggleTodo(todo.id)}
/>
<span className={todo.done ? "done" : ""}>{todo.text}</span>
</li>
))}
</ul>
<button onClick={() => addTodo(prompt("New todo:") || "")}>
Add Todo
</button>
<button onClick={askAgentToOrganize}>Ask Agent to Organize</button>
</div>
);
}
```
## Examples
### Optimized Updates
Subscribe only to message changes to avoid unnecessary re-renders:
```tsx
import { useAgent, UseAgentUpdate } from "@copilotkit/react-core";
function MessageList() {
const { agent } = useAgent({
updates: [UseAgentUpdate.OnMessagesChanged],
});
return (
<ul>
{agent.messages.map((msg) => (
<li key={msg.id}>{msg.content}</li>
))}
</ul>
);
}
```
### Run Status Indicator
Show a loading indicator when the agent is processing:
```tsx
import { useAgent, UseAgentUpdate } from "@copilotkit/react-core";
function RunStatus() {
const { agent } = useAgent({
agentId: "assistant",
updates: [UseAgentUpdate.OnRunStatusChanged],
});
return (
<div className={`status ${agent.isRunning ? "running" : "idle"}`}>
{agent.isRunning ? "🔄 Processing..." : "✅ Ready"}
</div>
);
}
```
### Multiple Agents
Access different agents in different components:
```tsx
function DualAgentView() {
const { agent: primaryAgent } = useAgent({
agentId: "primary-assistant",
});
const { agent: supportAgent } = useAgent({
agentId: "support-assistant",
});
return (
<div className="dual-view">
<div className="primary">
<h3>Primary Assistant</h3>
<div>Messages: {primaryAgent.messages.length}</div>
</div>
<div className="support">
<h3>Support Assistant</h3>
<div>Messages: {supportAgent.messages.length}</div>
</div>
</div>
);
}
```
### No Updates Subscription
For static access without subscribing to updates:
```tsx
const { agent } = useAgent({
agentId: "assistant",
updates: [], // No subscriptions
});
// Component won't re-render on agent changes
```
### Custom Message Rendering with Optimized Updates
```tsx
import { useAgent, UseAgentUpdate } from "@copilotkit/react-core";
import { Message } from "@ag-ui/core";
function MessageRenderer() {
const { agent } = useAgent({
updates: [UseAgentUpdate.OnMessagesChanged], // Only re-render on message changes
});
if (agent.messages.length === 0) {
return <div>No messages yet</div>;
}
const renderMessage = (message: Message) => {
switch (message.role) {
case "user":
return (
<div className="user-message">
<span className="avatar">👤</span>
<span className="content">{message.content}</span>
</div>
);
case "assistant":
return (
<div className="assistant-message">
<span className="avatar">🤖</span>
<span className="content">{message.content}</span>
</div>
);
default:
return null;
}
};
return (
<div className="message-list">
{agent.messages.map((msg) => (
<div key={msg.id}>{renderMessage(msg)}</div>
))}
</div>
);
}
```
## Performance Considerations
### Selective Updates
By default, `useAgent` subscribes to all update types, which can cause frequent re-renders. Use the `updates` parameter
to subscribe only to the changes you need:
```tsx
// ❌ Subscribes to all updates (may cause unnecessary re-renders)
const { agent } = useAgent({ agentId: "assistant" });
// ✅ Only subscribes to message changes
const { agent } = useAgent({
agentId: "assistant",
updates: [UseAgentUpdate.OnMessagesChanged],
});
// ✅ Only subscribes to run status changes
const { agent } = useAgent({
agentId: "assistant",
updates: [UseAgentUpdate.OnRunStatusChanged],
});
```
### Component Splitting
Split components by update type to optimize rendering:
```tsx
// Message display component - only updates on message changes
function Messages() {
const { agent } = useAgent({
updates: [UseAgentUpdate.OnMessagesChanged],
});
// Render messages...
}
// Status indicator - only updates on run status changes
function StatusIndicator() {
const { agent } = useAgent({
updates: [UseAgentUpdate.OnRunStatusChanged],
});
// Render status...
}
// Parent component doesn't need to subscribe
function ChatView() {
return (
<>
<StatusIndicator />
<Messages />
</>
);
}
```
## Error Handling
After the runtime has synced (Connected or Error), `useAgent` throws if the requested agent id does not exist. During
runtime syncing, a provisional agent is returned. To avoid runtime errors:
- Ensure the agent id you request is registered (via `agents__unsafe_dev_only` or exposed by your runtime).
- Optionally wrap the component that calls `useAgent` in an error boundary to render a fallback UI if the agent is
missing due to misconfiguration in development.
Example configuration with a local agent for development:
```tsx
<CopilotKitProvider agents__unsafe_dev_only={{ myAgent: new MyAgent() }}>
<App />
</CopilotKitProvider>
```
@@ -0,0 +1,150 @@
---
title: useCopilotKit
description: "useCopilotKit Hook API Reference"
---
`useCopilotKit` is a React hook that provides access to the CopilotKit context, including the core instance, tool
rendering capabilities, and runtime connection status. It's the primary way to interact with CopilotKit's core
functionality from React components.
## What is useCopilotKit?
The useCopilotKit hook:
- Provides access to the `CopilotKitCore` instance for agent and tool management
- Exposes render tool calls for visual tool execution feedback
- Subscribes to runtime connection status changes
- Enables programmatic control over agents, tools, and context
## Basic Usage
```tsx
import { useCopilotKit } from "@copilotkit/react-core";
function MyComponent() {
const { copilotkit } = useCopilotKit();
// Access runtime status
console.log("Runtime status:", copilotkit.runtimeConnectionStatus);
// Get an agent
const agent = copilotkit.getAgent("assistant");
return (
<div>Connected: {copilotkit.runtimeConnectionStatus === "Connected"}</div>
);
}
```
## Return Value
The hook returns a `CopilotKitContextValue` object with the following properties:
### copilotkit
`CopilotKitCore`
The core CopilotKit instance that manages agents, tools, context, and runtime connections. This is the main interface
for interacting with CopilotKit programmatically.
### renderToolCalls
`ReactToolCallRenderer<any>[]`
An array of tool call render configurations defined at the provider level. These are used to render visual feedback when
tools are executed.
### currentRenderToolCalls
`ReactToolCallRenderer<unknown>[]`
The current list of render tool calls, including both static configurations and dynamically registered ones.
### setCurrentRenderToolCalls
`React.Dispatch<React.SetStateAction<ReactToolCallRenderer<unknown>[]>>`
A setter function to update the current render tool calls. Useful for dynamically adding or removing tool renderers.
## Examples
### Running an Agent
```tsx
import { useCopilotKit } from "@copilotkit/react-core";
import { useAgent } from "@copilotkit/react-core";
function AgentRunner() {
const { copilotkit } = useCopilotKit();
const { agent } = useAgent({ agentId: "assistant" });
const [message, setMessage] = useState("");
const handleSubmit = async () => {
if (!message) return;
// Add user message
agent.addMessage({
id: crypto.randomUUID(),
role: "user",
content: message,
});
// Run the agent
await copilotkit.runAgent({ agent, agentId: "assistant" });
setMessage("");
};
return (
<div>
<input
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Type a message..."
/>
<button onClick={handleSubmit}>Send</button>
</div>
);
}
```
### Monitoring Runtime Connection
```tsx
import { useCopilotKit } from "@copilotkit/react-core";
function ConnectionStatus() {
const { copilotkit } = useCopilotKit();
const getStatusColor = () => {
switch (copilotkit.runtimeConnectionStatus) {
case "Connected":
return "green";
case "Connecting":
return "yellow";
case "Error":
return "red";
default:
return "gray";
}
};
return (
<div className="connection-status">
<div className={`indicator ${getStatusColor()}`} />
<span>Runtime: {copilotkit.runtimeConnectionStatus}</span>
{copilotkit.runtimeVersion && <span>v{copilotkit.runtimeVersion}</span>}
</div>
);
}
```
## Automatic Re-renders
The hook automatically subscribes to runtime connection status changes and triggers re-renders when:
- The runtime connects or disconnects
- The connection status changes
- Connection errors occur
This ensures your components always display the current connection state without manual subscriptions.
@@ -0,0 +1,281 @@
---
title: useFrontendTool
description: "useFrontendTool Hook API Reference"
---
`useFrontendTool` is a React hook that dynamically registers tools (functions) that AI agents can invoke in your
application. It enables components to expose interactive capabilities to agents, with optional visual rendering of tool
execution.
## What is useFrontendTool?
The useFrontendTool hook:
- Registers tools dynamically when components mount
- Automatically cleans up tools when components unmount
- Optionally registers visual renderers for tool execution feedback in the chat interface
- Supports agent-specific tool registration
- Handles tool lifecycle management automatically
## Basic Usage
```tsx
import { useFrontendTool } from "@copilotkit/react-core";
import { z } from "zod";
function SearchComponent() {
useFrontendTool({
name: "searchProducts",
description: "Search for products in the catalog",
parameters: z.object({
query: z.string(),
category: z.string().optional(),
}),
handler: async ({ query, category }) => {
const results = await searchAPI(query, category);
return results;
},
});
return <div>Rest of your component...</div>;
}
```
## Parameters
The hook accepts:
- A required `ReactFrontendTool` object describing the tool
- An optional dependency array to control when the tool is re-registered
### name
`string` **(required)**
A unique identifier for the tool. This is the name agents will use to request this tool's execution.
```tsx
useFrontendTool({
name: "calculateTotal",
// ...
});
```
### description
`string` **(optional)**
A description that helps agents understand when and how to use this tool. This is sent to the LLM to guide its
decision-making.
```tsx
useFrontendTool({
name: "fetchUserData",
description:
"Retrieve detailed user profile information including preferences and history",
// ...
});
```
### parameters
`z.ZodType<T>` **(optional)**
A Zod schema defining the tool's input parameters. Provides type safety and automatic validation.
```tsx
import { z } from "zod";
useFrontendTool({
name: "updateSettings",
parameters: z.object({
theme: z.enum(["light", "dark", "auto"]),
language: z.string(),
notifications: z.boolean(),
}),
handler: async ({ theme, language, notifications }) => {
// settings is fully typed based on the schema
await updateUserSettings({ theme, language, notifications });
return "Settings updated successfully";
},
});
```
### handler
`(args: T, toolCall: ToolCall) => Promise<unknown>` **(optional)**
The async function executed when the agent invokes this tool. Receives validated arguments and metadata about the
invocation.
```tsx
useFrontendTool({
name: "addToCart",
parameters: z.object({
productId: z.string(),
quantity: z.number().min(1),
}),
handler: async ({ productId, quantity }, toolCall) => {
console.log(`Tool called by agent at ${toolCall.id}`);
const result = await cartService.addItem(productId, quantity);
return {
success: true,
cartTotal: result.total,
};
},
});
```
### render
`(props: { name: string; args: T; result?: unknown; status: ToolCallStatus }) => React.ReactNode` **(optional)**
A React component that renders visual feedback when the tool is executed. This appears in the chat interface to show
tool execution progress and results.
```tsx
import { ToolCallStatus } from "@copilotkit/core";
useFrontendTool({
name: "generateChart",
parameters: z.object({
data: z.array(z.number()),
type: z.enum(["bar", "line", "pie"]),
}),
handler: async ({ data, type }) => {
return generateChartData(data, type);
},
render: ({ name, args, result, status }) => (
<div className="tool-execution">
<h3>Generating {args.type} chart...</h3>
{status === ToolCallStatus.InProgress && <Spinner />}
{status === ToolCallStatus.Complete && result && (
<ChartDisplay data={result} />
)}
</div>
),
});
```
### followUp
`boolean` **(optional, default: true)**
Controls whether the agent should automatically continue after this tool completes. Set to `false` for final actions.
```tsx
useFrontendTool({
name: "submitForm",
handler: async (formData) => {
await submitToServer(formData);
return "Form submitted successfully";
},
followUp: false, // Don't continue after submission
});
```
### agentId
`string` **(optional)**
Restricts this tool to a specific agent. Only the specified agent can invoke this tool.
```tsx
useFrontendTool({
name: "adminAction",
agentId: "admin-assistant",
handler: async (args) => {
return await performAdminAction(args);
},
});
```
### deps (second argument)
`ReadonlyArray<unknown>` **(optional)**
Additional dependencies that should trigger re-registration of the tool. By default, the hook only depends on the tool
name and CopilotKit instance to avoid re-register loops from object identity changes. Pass a dependency array as the
second argument when the tool's configuration is derived from changing props or state:
```tsx
function PriceTool({ currency }: { currency: string }) {
useFrontendTool(
{
name: "convertPrice",
handler: async (args) => convertPrice(args.amount, currency),
},
[currency],
);
return null;
}
```
## Lifecycle Management
### Automatic Registration
Tools are automatically registered when the component mounts:
```tsx
function DynamicTool() {
// Tool is registered when this component mounts
useFrontendTool({
name: "dynamicAction",
handler: async () => "Action performed",
});
return <div>Tool available</div>;
}
// Usage
function App() {
const [showTool, setShowTool] = useState(false);
return (
<div>
<button onClick={() => setShowTool(!showTool)}>Toggle Tool</button>
{showTool && <DynamicTool />} {/* Tool only available when mounted */}
</div>
);
}
```
### Cleanup on Unmount
Tools are automatically removed when components unmount, but their renderers persist to maintain chat history:
```tsx
function TemporaryTool() {
useFrontendTool({
name: "tempAction",
handler: async () => "Temporary action",
render: ({ status }) => <div>Temp tool: {status}</div>,
});
// When this component unmounts:
// - The tool handler is removed (agent can't call it anymore)
// - The renderer persists (previous executions still visible in chat)
return null;
}
```
### Tool Override Warning
If a tool with the same name already exists, it will be overridden with a console warning:
```tsx
// First registration
useFrontendTool({
name: "search",
handler: async () => "Search v1",
});
// Second registration (overrides first)
useFrontendTool({
name: "search", // Same name - will override with warning
handler: async () => "Search v2",
});
```
@@ -0,0 +1,223 @@
---
title: useHumanInTheLoop
description: "useHumanInTheLoop Hook API Reference"
---
`useHumanInTheLoop` is a React hook that creates interactive tools requiring human approval or input before the agent
can proceed. It enables you to build approval workflows, confirmation dialogs, and interactive decision points where
human oversight is needed.
## What is useHumanInTheLoop?
The useHumanInTheLoop hook:
- Creates tools that pause execution until human input is received
- Manages status transitions (InProgress → Executing → Complete)
- Provides a `respond` callback for user interactions
- Automatically handles promise resolution for agent continuation
- Renders interactive UI components in the chat interface
## Basic Usage
```tsx
import { useHumanInTheLoop } from "@copilotkit/react-core";
import { ToolCallStatus } from "@copilotkit/core";
import { z } from "zod";
function ApprovalComponent() {
useHumanInTheLoop({
name: "requireApproval",
description: "Requires human approval before proceeding",
parameters: z.object({
action: z.string(),
reason: z.string(),
}),
render: ({ status, args, respond }) => {
if (status === ToolCallStatus.Executing && respond) {
return (
<div className="approval-request">
<p>Approve action: {args.action}</p>
<p>Reason: {args.reason}</p>
<button onClick={() => respond({ approved: true })}>Approve</button>
<button onClick={() => respond({ approved: false })}>Deny</button>
</div>
);
}
return <div>Status: {status}</div>;
},
});
return <div>Approval system active</div>;
}
```
## Parameters
The hook accepts:
- A required `ReactHumanInTheLoop` object describing the tool
- An optional `options` object for controlling dependency behavior
### name
`string` **(required)**
A unique identifier for the human-in-the-loop tool.
```tsx
useHumanInTheLoop({
name: "confirmDeletion",
// ...
});
```
### description
`string` **(optional)**
Describes the tool's purpose to help agents understand when human approval is needed.
```tsx
useHumanInTheLoop({
name: "sensitiveAction",
description: "Requires human confirmation for sensitive operations",
// ...
});
```
### parameters
`z.ZodType<T>` **(optional)**
A Zod schema defining the parameters the agent will provide when requesting human input.
```tsx
import { z } from "zod";
useHumanInTheLoop({
name: "reviewChanges",
parameters: z.object({
changes: z.array(z.string()),
impact: z.enum(["low", "medium", "high"]),
estimatedTime: z.number(),
}),
// ...
});
```
### render
`React.ComponentType` **(required)**
A React component that renders the interactive UI. It receives different props based on the current status:
#### Status: InProgress
Initial state when the tool is called but not yet executing:
```tsx
{
name: string;
description: string;
args: Partial<T>; // Partial arguments as they're being streamed
status: ToolCallStatus.InProgress;
result: undefined;
respond: undefined;
}
```
#### Status: Executing
Active state where user interaction is required:
```tsx
{
name: string;
description: string;
args: T; // Complete arguments
status: ToolCallStatus.Executing;
result: undefined;
respond: (result: unknown) => Promise<void>; // Callback to provide response
}
```
#### Status: Complete
Final state after user has responded:
```tsx
{
name: string;
description: string;
args: T; // Complete arguments
status: ToolCallStatus.Complete;
result: string; // The response provided via respond()
respond: undefined;
}
```
### followUp
`boolean` **(optional, default: true)**
Controls whether the agent continues after receiving the human response. Provided for completeness, but typically you
would want the agent to continue (default behavior).
```tsx
useHumanInTheLoop({
name: "finalConfirmation",
followUp: false, // Don't continue after confirmation
// ...
});
```
### agentId
`string` **(optional)**
Restricts this tool to a specific agent.
```tsx
useHumanInTheLoop({
name: "adminApproval",
agentId: "admin-assistant",
// ...
});
```
## Options
### deps (second argument)
`ReadonlyArray<unknown>` **(optional)**
Additional dependencies that should trigger re-registration of the human-in-the-loop tool. By default, the hook only
depends on stable keys like the tool name and CopilotKit instance to avoid re-register loops from object identity
changes. Pass a dependency array as the second argument when the tool configuration is derived from changing props or
state:
```tsx
function VersionedApproval({ version }: { version: number }) {
useHumanInTheLoop(
{
name: "versionedApproval",
description: `Approve deployment v${version}`,
// ...
},
[version],
);
return null;
}
```
## Differences from useFrontendTool
While `useFrontendTool` executes immediately and returns results, `useHumanInTheLoop`:
- Pauses execution until human input is received
- Provides a `respond` callback during the Executing state
- Manages status transitions automatically
- Is designed specifically for approval workflows and interactive decisions
Choose `useHumanInTheLoop` when you need human oversight, and `useFrontendTool` for automated tool execution.
@@ -0,0 +1,277 @@
---
title: useRenderToolCall
description: "useRenderToolCall Hook API Reference"
---
<Warning>
You would use this hook if you use the headless functionality of CopilotKit,
rendering your own chat UI instead of the default `CopilotChat`. If you are
using `CopilotChat`, you don't need to use this hook.
</Warning>
`useRenderToolCall` is a React hook that provides a function to render visual representations of tool calls in the chat
interface. It manages the rendering of tool execution states (InProgress, Executing, Complete) based on configured
render functions.
## What is useRenderToolCall?
The useRenderToolCall hook:
- Returns a render function for tool calls
- Automatically determines the appropriate status (InProgress, Executing, or Complete)
- Manages tool execution state transitions
- Supports agent-specific and wildcard renderers
- Integrates with CopilotKit's tool rendering system
## Basic Usage
```tsx
import { useRenderToolCall } from "@copilotkit/react-core";
import { ToolCall } from "@ag-ui/core";
function ToolCallDisplay({ toolCall, toolMessage }) {
const renderToolCall = useRenderToolCall();
return (
<div className="tool-call-container">
{renderToolCall({ toolCall, toolMessage })}
</div>
);
}
```
## Return Value
The hook returns a function with the following signature:
```tsx
(props: UseRenderToolCallProps) => React.ReactElement | null;
```
### UseRenderToolCallProps
```tsx
interface UseRenderToolCallProps {
toolCall: ToolCall; // The tool call to render
toolMessage?: ToolMessage; // Optional result message
}
```
## How It Works
### Status Determination
The render function automatically determines the tool's status:
1. **Complete**: When a `toolMessage` is provided
2. **Executing**: When the tool is currently running (tracked internally)
3. **InProgress**: Default state when neither complete nor executing
### Renderer Selection
The function selects renderers based on priority:
1. **Exact match** with matching agentId
2. **Exact match** without agentId (global)
3. **Exact match** (any agentId)
4. **Wildcard** renderer (`*`)
5. **No render** (returns null)
## Examples
### Basic Tool Call Rendering
```tsx
import { useRenderToolCall } from "@copilotkit/react-core";
import { AssistantMessage } from "@ag-ui/core";
function ChatMessage({ message }: { message: AssistantMessage }) {
const renderToolCall = useRenderToolCall();
if (!message.toolCalls) {
return <div>{message.content}</div>;
}
return (
<div>
{message.content}
{message.toolCalls.map((toolCall) => (
<div key={toolCall.id} className="tool-call">
{renderToolCall({ toolCall })}
</div>
))}
</div>
);
}
```
### With Tool Results
```tsx
import { useRenderToolCall } from "@copilotkit/react-core";
import { Message, ToolMessage } from "@ag-ui/core";
function ChatWithResults({
message,
allMessages,
}: {
message: AssistantMessage;
allMessages: Message[];
}) {
const renderToolCall = useRenderToolCall();
return (
<>
{message.toolCalls?.map((toolCall) => {
// Find the corresponding result message
const toolMessage = allMessages.find(
(m): m is ToolMessage =>
m.role === "tool" && m.toolCallId === toolCall.id,
);
return (
<div key={toolCall.id}>
{renderToolCall({
toolCall,
toolMessage, // Pass result if available
})}
</div>
);
})}
</>
);
}
```
## Integration with Tool Renderers
The hook works with tool renderers defined at various levels:
### Provider-Level Renderers
Renderers defined in `CopilotKitProvider`:
```tsx
import {
CopilotKitProvider,
defineToolCallRenderer,
} from "@copilotkit/react-core";
const searchRenderer = defineToolCallRenderer({
name: "search",
render: ({ args, status }) => <SearchDisplay {...args} status={status} />,
});
function App() {
return (
<CopilotKitProvider renderToolCalls={[searchRenderer]}>
{/* Components using useRenderToolCall will use this renderer */}
</CopilotKitProvider>
);
}
```
### Dynamic Tool Renderers
Renderers registered via `useFrontendTool`:
```tsx
function DynamicTool() {
useFrontendTool({
name: "dynamicAction",
handler: async (args) => {
/* ... */
},
render: ({ args, status }) => <div>Dynamic tool: {status}</div>,
});
// This renderer is automatically available to useRenderToolCall
return null;
}
```
### Wildcard Renderer
A fallback renderer for unmatched tools:
```tsx
const wildcardRenderer = defineToolCallRenderer({
name: "*",
render: ({ name, args, status }) => (
<div className="unknown-tool">
<span>Unknown tool: {name}</span>
<span>Status: {status}</span>
</div>
),
});
```
## Status Lifecycle
The hook manages three status states automatically:
### InProgress
Initial state when tool is called but not executing:
```tsx
// Renderer receives:
{
name: string;
args: Partial<T>; // May be incomplete during streaming
status: ToolCallStatus.InProgress;
result: undefined;
}
```
### Executing
Active execution state:
```tsx
// Renderer receives:
{
name: string;
args: T; // Complete arguments
status: ToolCallStatus.Executing;
result: undefined;
}
```
### Complete
Final state with results:
```tsx
// Renderer receives:
{
name: string;
args: T; // Complete arguments
status: ToolCallStatus.Complete;
result: string; // Tool execution result
}
```
## Agent-Specific Rendering
The hook supports agent-specific renderers:
```tsx
import { useCopilotChatConfiguration } from "@copilotkit/react-core";
function AgentAwareRendering() {
const renderToolCall = useRenderToolCall();
const config = useCopilotChatConfiguration();
// The hook automatically selects renderers based on the current agent
// Priority: agent-specific > global > wildcard
return (
<div>
<h3>Agent: {config?.agentId || "default"}</h3>
{/* Renders will use agent-appropriate renderers */}
{toolCalls.map((tc) => renderToolCall({ toolCall: tc }))}
</div>
);
}
```