chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,533 @@
|
||||
# CopilotKit v2 Public API Reference
|
||||
|
||||
Package imports: `@copilotkit/react-core/v2`, `@copilotkit/runtime/v2`, `@copilotkit/core`.
|
||||
|
||||
Note: `@copilotkit/react-core/v2` re-exports everything from `@ag-ui/client` (which itself re-exports `@ag-ui/core`), so applications typically only need `@copilotkit/react-core/v2` and `@copilotkit/runtime/v2`.
|
||||
|
||||
---
|
||||
|
||||
## Hooks (`@copilotkit/react-core/v2`)
|
||||
|
||||
### useFrontendTool
|
||||
|
||||
```ts
|
||||
function useFrontendTool<T extends Record<string, unknown>>(
|
||||
tool: ReactFrontendTool<T>,
|
||||
deps?: ReadonlyArray<unknown>,
|
||||
): void;
|
||||
```
|
||||
|
||||
Registers a tool that the agent can invoke in the browser. The tool object has these fields:
|
||||
|
||||
- `name: string` -- Tool name (must be unique per agentId scope).
|
||||
- `description?: string` -- Human/model-readable description.
|
||||
- `parameters?: StandardSchemaV1<any, T>` -- Schema for tool arguments (Zod, Valibot, ArkType, etc.).
|
||||
- `handler?: (args: T, context: FrontendToolHandlerContext) => Promise<unknown>` -- Function called when the agent invokes the tool.
|
||||
- `render?: React.ComponentType<...>` -- Optional inline renderer for the tool call in chat.
|
||||
- `agentId?: string` -- Constrain to a specific agent.
|
||||
- `available?: boolean` -- Toggle visibility without unregistering. Defaults to `true`.
|
||||
- `followUp?: boolean` -- Whether the agent should follow up after tool execution.
|
||||
|
||||
Re-registers when `tool.name`, `tool.available`, or any value in `deps` changes.
|
||||
|
||||
---
|
||||
|
||||
### useComponent
|
||||
|
||||
```ts
|
||||
function useComponent<TSchema extends StandardSchemaV1 | undefined = undefined>(
|
||||
config: {
|
||||
name: string;
|
||||
description?: string;
|
||||
parameters?: TSchema;
|
||||
render: ComponentType<InferRenderProps<TSchema>>;
|
||||
agentId?: string;
|
||||
},
|
||||
deps?: ReadonlyArray<unknown>,
|
||||
): void;
|
||||
```
|
||||
|
||||
Convenience wrapper around `useFrontendTool`. Registers a React component as a visual tool in chat. The model is told to use the tool to "display the component." Render props are inferred from the `parameters` schema.
|
||||
|
||||
---
|
||||
|
||||
### useAgentContext
|
||||
|
||||
```ts
|
||||
function useAgentContext(context: AgentContextInput): void;
|
||||
|
||||
interface AgentContextInput {
|
||||
description: string;
|
||||
value: JsonSerializable; // string | number | boolean | null | array | object
|
||||
}
|
||||
```
|
||||
|
||||
Shares application state with the agent. The `value` is serialized to JSON and registered as context. Context is removed on unmount.
|
||||
|
||||
---
|
||||
|
||||
### useAgent
|
||||
|
||||
```ts
|
||||
function useAgent(props?: UseAgentProps): { agent: AbstractAgent };
|
||||
|
||||
interface UseAgentProps {
|
||||
agentId?: string;
|
||||
updates?: UseAgentUpdate[];
|
||||
}
|
||||
|
||||
enum UseAgentUpdate {
|
||||
OnMessagesChanged = "OnMessagesChanged",
|
||||
OnStateChanged = "OnStateChanged",
|
||||
OnRunStatusChanged = "OnRunStatusChanged",
|
||||
}
|
||||
```
|
||||
|
||||
Returns the `AbstractAgent` instance for the given `agentId` (defaults to `"default"`). Subscribes to the specified update categories to trigger re-renders. By default subscribes to all three.
|
||||
|
||||
While the runtime is connecting, returns a provisional `ProxiedCopilotRuntimeAgent` to prevent crashes.
|
||||
|
||||
---
|
||||
|
||||
### useInterrupt
|
||||
|
||||
```ts
|
||||
function useInterrupt<
|
||||
TResult = never,
|
||||
TRenderInChat extends boolean | undefined = undefined,
|
||||
>(
|
||||
config: UseInterruptConfig<any, TResult, TRenderInChat>,
|
||||
): React.ReactElement | null | void;
|
||||
|
||||
interface UseInterruptConfig<TValue, TResult, TRenderInChat> {
|
||||
render: (
|
||||
props: InterruptRenderProps<TValue, TResult | null>,
|
||||
) => React.ReactElement;
|
||||
handler?: (
|
||||
props: InterruptHandlerProps<TValue>,
|
||||
) => TResult | PromiseLike<TResult>;
|
||||
enabled?: (event: InterruptEvent<TValue>) => boolean;
|
||||
agentId?: string;
|
||||
renderInChat?: TRenderInChat; // default: true
|
||||
}
|
||||
|
||||
interface InterruptEvent<TValue = unknown> {
|
||||
name: string;
|
||||
value: TValue;
|
||||
}
|
||||
|
||||
interface InterruptRenderProps<TValue, TResult> {
|
||||
event: InterruptEvent<TValue>;
|
||||
result: TResult;
|
||||
resolve: (response: unknown) => void;
|
||||
}
|
||||
```
|
||||
|
||||
Handles agent `on_interrupt` events. When `renderInChat` is `true` (default), the element is published into `<CopilotChat>` and the hook returns `void`. When `false`, it returns the element for manual placement. Call `resolve()` from your render to resume the agent.
|
||||
|
||||
---
|
||||
|
||||
### useHumanInTheLoop
|
||||
|
||||
```ts
|
||||
function useHumanInTheLoop<T extends Record<string, unknown>>(
|
||||
tool: ReactHumanInTheLoop<T>,
|
||||
deps?: ReadonlyArray<unknown>,
|
||||
): void;
|
||||
```
|
||||
|
||||
Registers a tool that pauses agent execution until the user responds. The `render` component receives a `respond` callback during the `"executing"` phase. Built on top of `useFrontendTool` with a promise-based handler.
|
||||
|
||||
```ts
|
||||
type ReactHumanInTheLoop<T> = Omit<FrontendTool<T>, "handler"> & {
|
||||
render: React.ComponentType<
|
||||
| { status: "inProgress"; args: Partial<T>; respond: undefined }
|
||||
| {
|
||||
status: "executing";
|
||||
args: T;
|
||||
respond: (result: unknown) => Promise<void>;
|
||||
}
|
||||
| { status: "complete"; args: T; result: string; respond: undefined }
|
||||
>;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### useRenderTool
|
||||
|
||||
```ts
|
||||
// Named tool renderer with typed parameters
|
||||
function useRenderTool<S extends StandardSchemaV1>(
|
||||
config: {
|
||||
name: string;
|
||||
parameters: S;
|
||||
render: (props: RenderToolProps<S>) => React.ReactElement;
|
||||
agentId?: string;
|
||||
},
|
||||
deps?: ReadonlyArray<unknown>,
|
||||
): void;
|
||||
|
||||
// Wildcard renderer (fallback for unregistered tools)
|
||||
function useRenderTool(
|
||||
config: {
|
||||
name: "*";
|
||||
render: (props: any) => React.ReactElement;
|
||||
agentId?: string;
|
||||
},
|
||||
deps?: ReadonlyArray<unknown>,
|
||||
): void;
|
||||
|
||||
type RenderToolProps<S> =
|
||||
| {
|
||||
name: string;
|
||||
parameters: Partial<InferSchemaOutput<S>>;
|
||||
status: "inProgress";
|
||||
result: undefined;
|
||||
}
|
||||
| {
|
||||
name: string;
|
||||
parameters: InferSchemaOutput<S>;
|
||||
status: "executing";
|
||||
result: undefined;
|
||||
}
|
||||
| {
|
||||
name: string;
|
||||
parameters: InferSchemaOutput<S>;
|
||||
status: "complete";
|
||||
result: string;
|
||||
};
|
||||
```
|
||||
|
||||
Registers a visual renderer for tool calls in the chat. Renderers are deduplicated by `agentId:name`. The renderer is intentionally NOT removed on unmount so historical tool calls can still render.
|
||||
|
||||
---
|
||||
|
||||
### useDefaultRenderTool
|
||||
|
||||
```ts
|
||||
function useDefaultRenderTool(
|
||||
config?: { render?: (props: DefaultRenderProps) => React.ReactElement },
|
||||
deps?: ReadonlyArray<unknown>,
|
||||
): void;
|
||||
```
|
||||
|
||||
Registers a wildcard `"*"` renderer via `useRenderTool`. With no arguments, uses the built-in expandable card UI showing tool name, status badge, arguments, and result.
|
||||
|
||||
---
|
||||
|
||||
### useSuggestions
|
||||
|
||||
```ts
|
||||
function useSuggestions(options?: { agentId?: string }): UseSuggestionsResult;
|
||||
|
||||
interface UseSuggestionsResult {
|
||||
suggestions: Suggestion[];
|
||||
reloadSuggestions: () => void;
|
||||
clearSuggestions: () => void;
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
type Suggestion = {
|
||||
title: string;
|
||||
message: string;
|
||||
isLoading: boolean;
|
||||
};
|
||||
```
|
||||
|
||||
Reads the current suggestion list for an agent. Subscribes to real-time updates.
|
||||
|
||||
---
|
||||
|
||||
### useConfigureSuggestions
|
||||
|
||||
```ts
|
||||
function useConfigureSuggestions(
|
||||
config: SuggestionsConfigInput | null | undefined,
|
||||
deps?: ReadonlyArray<unknown>,
|
||||
): void;
|
||||
```
|
||||
|
||||
Registers a suggestion configuration. Two modes:
|
||||
|
||||
**Dynamic** (LLM-generated):
|
||||
|
||||
```ts
|
||||
{
|
||||
instructions: "Suggest follow-up questions about the data",
|
||||
minSuggestions?: number, // default 1
|
||||
maxSuggestions?: number, // default 3
|
||||
available?: "before-first-message" | "after-first-message" | "always" | "disabled",
|
||||
providerAgentId?: string,
|
||||
consumerAgentId?: string, // default "*"
|
||||
}
|
||||
```
|
||||
|
||||
**Static**:
|
||||
|
||||
```ts
|
||||
{
|
||||
suggestions: [{ title: "...", message: "..." }],
|
||||
available?: SuggestionAvailability,
|
||||
consumerAgentId?: string,
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### useThreads
|
||||
|
||||
```ts
|
||||
function useThreads(input: UseThreadsInput): UseThreadsResult;
|
||||
|
||||
interface UseThreadsInput {
|
||||
agentId: string;
|
||||
includeArchived?: boolean; // default: false
|
||||
limit?: number; // enables cursor-based pagination when set
|
||||
}
|
||||
|
||||
interface UseThreadsResult {
|
||||
threads: Thread[];
|
||||
isLoading: boolean;
|
||||
error: Error | null;
|
||||
hasMoreThreads: boolean;
|
||||
isFetchingMoreThreads: boolean;
|
||||
fetchMoreThreads: () => void;
|
||||
renameThread: (threadId: string, name: string) => Promise<void>;
|
||||
archiveThread: (threadId: string) => Promise<void>;
|
||||
deleteThread: (threadId: string) => Promise<void>;
|
||||
}
|
||||
|
||||
interface Thread {
|
||||
id: string;
|
||||
agentId: string;
|
||||
name: string | null;
|
||||
archived: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
lastRunAt?: string; // last agent run; prefer over updatedAt for "last activity"
|
||||
}
|
||||
```
|
||||
|
||||
Lists and manages Intelligence platform threads. Thread operations are scoped to the runtime-authenticated user (no `userId` input) and the given `agentId`. Uses a realtime WebSocket subscription when available.
|
||||
|
||||
---
|
||||
|
||||
### useRenderToolCall (internal)
|
||||
|
||||
```ts
|
||||
function useRenderToolCall(): (props: {
|
||||
toolCall: ToolCall;
|
||||
toolMessage?: ToolMessage;
|
||||
}) => React.ReactElement | null;
|
||||
```
|
||||
|
||||
Returns a function that resolves the correct renderer for a tool call. Priority: exact name match (prefer agent-scoped) > wildcard `"*"`.
|
||||
|
||||
---
|
||||
|
||||
### useRenderActivityMessage (internal)
|
||||
|
||||
```ts
|
||||
function useRenderActivityMessage(): {
|
||||
renderActivityMessage: (
|
||||
message: ActivityMessage,
|
||||
) => React.ReactElement | null;
|
||||
findRenderer: (activityType: string) => ReactActivityMessageRenderer | null;
|
||||
};
|
||||
```
|
||||
|
||||
Resolves and renders activity messages by type. Matches by `activityType` with agent-scoping, falls back to wildcard `"*"`.
|
||||
|
||||
---
|
||||
|
||||
### useRenderCustomMessages (internal)
|
||||
|
||||
Returns a function to render custom message decorators at `"before"` or `"after"` positions relative to each message.
|
||||
|
||||
---
|
||||
|
||||
## Components (`@copilotkit/react-core/v2`)
|
||||
|
||||
### CopilotKit (provider)
|
||||
|
||||
Import from `@copilotkit/react-core/v2`. The recommended root provider -- a compatibility bridge across v1 and v2 and a strict superset of the legacy `CopilotKitProvider` (all props below work on it).
|
||||
|
||||
```tsx
|
||||
<CopilotKit
|
||||
runtimeUrl?: string
|
||||
headers?: Record<string, string>
|
||||
credentials?: RequestCredentials
|
||||
publicLicenseKey?: string // deprecated alias: publicApiKey
|
||||
properties?: Record<string, unknown>
|
||||
agents__unsafe_dev_only?: Record<string, AbstractAgent>
|
||||
selfManagedAgents?: Record<string, AbstractAgent>
|
||||
renderToolCalls?: ReactToolCallRenderer[]
|
||||
renderActivityMessages?: ReactActivityMessageRenderer[]
|
||||
renderCustomMessages?: ReactCustomMessageRenderer[]
|
||||
frontendTools?: ReactFrontendTool[]
|
||||
humanInTheLoop?: ReactHumanInTheLoop[]
|
||||
showDevConsole?: boolean | "auto"
|
||||
useSingleEndpoint?: boolean
|
||||
onError?: (event: { error: Error; code: CopilotKitCoreErrorCode; context: Record<string, any> }) => void
|
||||
a2ui?: { theme?: A2UITheme }
|
||||
>
|
||||
{children}
|
||||
</CopilotKit>
|
||||
```
|
||||
|
||||
Root provider. Configures the runtime connection, registers static tool renderers and tools, and provides the CopilotKit context to all descendant hooks and components.
|
||||
|
||||
---
|
||||
|
||||
### CopilotChat
|
||||
|
||||
```tsx
|
||||
<CopilotChat
|
||||
agentId?: string // default: "default"
|
||||
threadId?: string // auto-generated if omitted
|
||||
labels?: Partial<CopilotChatLabels>
|
||||
chatView?: SlotValue<typeof CopilotChatView>
|
||||
onError?: (event: { error: Error; code: CopilotKitCoreErrorCode; context: Record<string, any> }) => void
|
||||
// Plus all CopilotChatViewProps (messageView, input, suggestionView, welcomeScreen, etc.)
|
||||
/>
|
||||
```
|
||||
|
||||
Full chat interface. Connects to the agent on mount, handles message submission, suggestion selection, stop, and audio transcription.
|
||||
|
||||
---
|
||||
|
||||
### CopilotPopup
|
||||
|
||||
```tsx
|
||||
<CopilotPopup
|
||||
// All CopilotChat props, plus:
|
||||
header?: SlotValue
|
||||
toggleButton?: SlotValue
|
||||
defaultOpen?: boolean
|
||||
width?: number | string
|
||||
height?: number | string
|
||||
clickOutsideToClose?: boolean
|
||||
/>
|
||||
```
|
||||
|
||||
Chat in a floating popup with a toggle button.
|
||||
|
||||
---
|
||||
|
||||
### CopilotSidebar
|
||||
|
||||
```tsx
|
||||
<CopilotSidebar
|
||||
// All CopilotChat props, plus:
|
||||
header?: SlotValue
|
||||
toggleButton?: SlotValue
|
||||
defaultOpen?: boolean
|
||||
width?: number | string
|
||||
/>
|
||||
```
|
||||
|
||||
Chat in a collapsible sidebar panel.
|
||||
|
||||
---
|
||||
|
||||
### CopilotChatView
|
||||
|
||||
Headless chat view with a slot-based architecture. Accepts slots for `messageView`, `scrollView`, `input`, `suggestionView`, and `welcomeScreen`. Also exposes sub-components: `CopilotChatView.ScrollView`, `CopilotChatView.Feather`, `CopilotChatView.WelcomeScreen`, `CopilotChatView.WelcomeMessage`, `CopilotChatView.ScrollToBottomButton`.
|
||||
|
||||
---
|
||||
|
||||
### Other Chat Sub-Components
|
||||
|
||||
- `CopilotChatInput` -- Textarea with send, stop, and transcription controls.
|
||||
- `CopilotChatMessageView` -- Renders the message list.
|
||||
- `CopilotChatAssistantMessage` -- Single assistant message bubble.
|
||||
- `CopilotChatUserMessage` -- Single user message bubble.
|
||||
- `CopilotChatReasoningMessage` -- Reasoning/thinking message display.
|
||||
- `CopilotChatSuggestionView` -- Renders suggestion pills.
|
||||
- `CopilotChatSuggestionPill` -- Individual suggestion pill.
|
||||
- `CopilotChatToolCallsView` -- Renders tool call results in a message.
|
||||
- `CopilotChatToggleButton` -- Open/close toggle for popup/sidebar.
|
||||
- `CopilotModalHeader` -- Header bar for popup/sidebar modals.
|
||||
- `CopilotPopupView` -- Popup layout wrapper.
|
||||
- `CopilotSidebarView` -- Sidebar layout wrapper.
|
||||
- `CopilotKitInspector` -- Dev console overlay (controlled by `showDevConsole`).
|
||||
- `MCPAppsActivityRenderer` -- Built-in renderer for MCP Apps activity messages.
|
||||
- `WildcardToolCallRender` -- Built-in wildcard tool call renderer component.
|
||||
|
||||
---
|
||||
|
||||
## Types (`@copilotkit/react-core/v2`)
|
||||
|
||||
### ReactFrontendTool
|
||||
|
||||
```ts
|
||||
type ReactFrontendTool<T> = FrontendTool<T> & {
|
||||
render?: ReactToolCallRenderer<T>["render"];
|
||||
};
|
||||
```
|
||||
|
||||
### ReactToolCallRenderer
|
||||
|
||||
```ts
|
||||
interface ReactToolCallRenderer<T> {
|
||||
name: string;
|
||||
args: StandardSchemaV1<any, T>;
|
||||
agentId?: string;
|
||||
render: React.ComponentType<
|
||||
| {
|
||||
name: string;
|
||||
args: Partial<T>;
|
||||
status: "inProgress";
|
||||
result: undefined;
|
||||
}
|
||||
| { name: string; args: T; status: "executing"; result: undefined }
|
||||
| { name: string; args: T; status: "complete"; result: string }
|
||||
>;
|
||||
}
|
||||
```
|
||||
|
||||
### ReactHumanInTheLoop
|
||||
|
||||
See `useHumanInTheLoop` above.
|
||||
|
||||
### ReactActivityMessageRenderer
|
||||
|
||||
```ts
|
||||
interface ReactActivityMessageRenderer<TActivityContent> {
|
||||
activityType: string; // or "*" for wildcard
|
||||
agentId?: string;
|
||||
content: StandardSchemaV1<any, TActivityContent>;
|
||||
render: React.ComponentType<{
|
||||
activityType: string;
|
||||
content: TActivityContent;
|
||||
message: ActivityMessage;
|
||||
agent: AbstractAgent | undefined;
|
||||
}>;
|
||||
}
|
||||
```
|
||||
|
||||
### ToolCallStatus
|
||||
|
||||
```ts
|
||||
enum ToolCallStatus {
|
||||
InProgress = "inProgress",
|
||||
Executing = "executing",
|
||||
Complete = "complete",
|
||||
}
|
||||
```
|
||||
|
||||
### FrontendToolHandlerContext
|
||||
|
||||
```ts
|
||||
type FrontendToolHandlerContext = {
|
||||
toolCall: ToolCall;
|
||||
agent: AbstractAgent;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Runtime (`@copilotkit/runtime/v2`)
|
||||
|
||||
See [runtime-api.md](./runtime-api.md) for full runtime reference.
|
||||
@@ -0,0 +1,242 @@
|
||||
# CopilotChat Customization Reference
|
||||
|
||||
## CopilotChat Props
|
||||
|
||||
`CopilotChat` is the primary chat component. It wraps `CopilotChatView` and handles agent connection, message submission, suggestions, stop, and audio transcription.
|
||||
|
||||
```tsx
|
||||
interface CopilotChatProps {
|
||||
// Agent configuration
|
||||
agentId?: string; // Agent to connect to. Default: "default"
|
||||
threadId?: string; // Thread ID. Auto-generated UUID if omitted.
|
||||
|
||||
// Labels and text customization
|
||||
labels?: Partial<CopilotChatLabels>;
|
||||
|
||||
// Layout override
|
||||
chatView?: SlotValue<typeof CopilotChatView>;
|
||||
|
||||
// Error handling (scoped to this chat's agent)
|
||||
onError?: (event: {
|
||||
error: Error;
|
||||
code: CopilotKitCoreErrorCode;
|
||||
context: Record<string, any>;
|
||||
}) => void;
|
||||
|
||||
// All CopilotChatViewProps are also accepted (see below)
|
||||
}
|
||||
```
|
||||
|
||||
## CopilotChatView Props (Layout Slots)
|
||||
|
||||
`CopilotChatView` uses a slot-based architecture. Each slot can be:
|
||||
|
||||
- Omitted (uses the default component)
|
||||
- A props object (merges with the default component)
|
||||
- A custom React component (replaces the default)
|
||||
|
||||
```tsx
|
||||
interface CopilotChatViewProps {
|
||||
// Slot overrides
|
||||
messageView?: SlotValue<typeof CopilotChatMessageView>;
|
||||
scrollView?: SlotValue<typeof CopilotChatView.ScrollView>;
|
||||
input?: SlotValue<typeof CopilotChatInput>;
|
||||
suggestionView?: SlotValue<typeof CopilotChatSuggestionView>;
|
||||
|
||||
// Welcome screen: true (default), false (disabled), or custom component
|
||||
welcomeScreen?: SlotValue<React.FC<WelcomeScreenProps>> | boolean;
|
||||
|
||||
// Data (usually provided by CopilotChat, not set directly)
|
||||
messages?: Message[];
|
||||
isRunning?: boolean;
|
||||
suggestions?: Suggestion[];
|
||||
autoScroll?: boolean; // Default: true
|
||||
|
||||
// Input behavior (usually provided by CopilotChat)
|
||||
onSubmitMessage?: (value: string) => void;
|
||||
onStop?: () => void;
|
||||
inputMode?: "input" | "transcribe" | "processing";
|
||||
inputValue?: string;
|
||||
onInputChange?: (value: string) => void;
|
||||
|
||||
// Transcription handlers
|
||||
onStartTranscribe?: () => void;
|
||||
onCancelTranscribe?: () => void;
|
||||
onFinishTranscribe?: () => void;
|
||||
onFinishTranscribeWithAudio?: (audioBlob: Blob) => Promise<void>;
|
||||
|
||||
// Standard HTML div props
|
||||
className?: string;
|
||||
// ...rest HTMLAttributes<HTMLDivElement>
|
||||
}
|
||||
```
|
||||
|
||||
## Labels (Text Customization)
|
||||
|
||||
All user-visible text can be customized via the `labels` prop:
|
||||
|
||||
```tsx
|
||||
const CopilotChatDefaultLabels = {
|
||||
chatInputPlaceholder: "Type a message...",
|
||||
chatInputToolbarStartTranscribeButtonLabel: "Transcribe",
|
||||
chatInputToolbarCancelTranscribeButtonLabel: "Cancel",
|
||||
chatInputToolbarFinishTranscribeButtonLabel: "Finish",
|
||||
chatInputToolbarAddButtonLabel: "Add photos or files",
|
||||
chatInputToolbarToolsButtonLabel: "Tools",
|
||||
assistantMessageToolbarCopyCodeLabel: "Copy",
|
||||
assistantMessageToolbarCopyCodeCopiedLabel: "Copied",
|
||||
assistantMessageToolbarCopyMessageLabel: "Copy",
|
||||
assistantMessageToolbarThumbsUpLabel: "Good response",
|
||||
assistantMessageToolbarThumbsDownLabel: "Bad response",
|
||||
assistantMessageToolbarReadAloudLabel: "Read aloud",
|
||||
assistantMessageToolbarRegenerateLabel: "Regenerate",
|
||||
userMessageToolbarCopyMessageLabel: "Copy",
|
||||
userMessageToolbarEditMessageLabel: "Edit",
|
||||
chatDisclaimerText:
|
||||
"AI can make mistakes. Please verify important information.",
|
||||
chatToggleOpenLabel: "Open chat",
|
||||
chatToggleCloseLabel: "Close chat",
|
||||
modalHeaderTitle: "CopilotKit Chat",
|
||||
welcomeMessageText: "How can I help you today?",
|
||||
};
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```tsx
|
||||
<CopilotChat
|
||||
agentId="myAgent"
|
||||
labels={{
|
||||
chatInputPlaceholder: "Ask me anything...",
|
||||
welcomeMessageText: "Welcome! How can I assist you?",
|
||||
modalHeaderTitle: "AI Assistant",
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
## CopilotPopup Props
|
||||
|
||||
```tsx
|
||||
interface CopilotPopupProps extends CopilotChatProps {
|
||||
header?: SlotValue; // Custom header component
|
||||
toggleButton?: SlotValue; // Custom toggle button
|
||||
defaultOpen?: boolean; // Start open? Default: true
|
||||
width?: number | string; // Popup width
|
||||
height?: number | string; // Popup height
|
||||
clickOutsideToClose?: boolean; // Close on outside click
|
||||
}
|
||||
```
|
||||
|
||||
## CopilotSidebar Props
|
||||
|
||||
```tsx
|
||||
interface CopilotSidebarProps extends CopilotChatProps {
|
||||
header?: SlotValue; // Custom header component
|
||||
toggleButton?: SlotValue; // Custom toggle button
|
||||
defaultOpen?: boolean; // Start open? Default: true
|
||||
width?: number | string; // Sidebar width
|
||||
}
|
||||
```
|
||||
|
||||
## Styling
|
||||
|
||||
CopilotKit v2 uses Tailwind CSS with a `cpk:` prefix namespace. All internal classes use this prefix to avoid conflicts with your application's styles.
|
||||
|
||||
### CSS Data Attributes
|
||||
|
||||
The chat container exposes data attributes for CSS targeting:
|
||||
|
||||
- `[data-copilotkit]` -- Present on the root chat element.
|
||||
- `[data-testid="copilot-chat"]` -- The main chat container.
|
||||
- `[data-copilot-running="true"]` -- While the agent is running.
|
||||
- `[data-testid="copilot-welcome-screen"]` -- The welcome screen container.
|
||||
- `[data-sidebar-chat]` -- On sidebar layout wrapper.
|
||||
- `[data-popup-chat]` -- On popup layout wrapper.
|
||||
|
||||
### Dark Mode
|
||||
|
||||
The components support dark mode through Tailwind's `dark:` variant. All internal components include `cpk:dark:` color variants. Enable dark mode by adding the `dark` class to a parent element per Tailwind convention.
|
||||
|
||||
### Slot-Based Customization
|
||||
|
||||
Every visual sub-component is a "slot" that can be replaced or extended:
|
||||
|
||||
```tsx
|
||||
// Override the input component with custom props
|
||||
<CopilotChat
|
||||
input={{ className: "my-custom-input" }}
|
||||
/>
|
||||
|
||||
// Replace the input entirely
|
||||
<CopilotChat
|
||||
input={MyCustomInput}
|
||||
/>
|
||||
|
||||
// Override welcome screen
|
||||
<CopilotChat
|
||||
welcomeScreen={({ input, suggestionView }) => (
|
||||
<div className="my-welcome">
|
||||
<h1>Hello!</h1>
|
||||
{input}
|
||||
{suggestionView}
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
|
||||
// Disable welcome screen
|
||||
<CopilotChat welcomeScreen={false} />
|
||||
```
|
||||
|
||||
### CopilotChatView Sub-Components
|
||||
|
||||
These can be used directly when building fully custom layouts:
|
||||
|
||||
- `CopilotChatView.ScrollView` -- Scroll container with auto-scroll (uses `use-stick-to-bottom`).
|
||||
- `CopilotChatView.ScrollToBottomButton` -- Floating "scroll to bottom" button.
|
||||
- `CopilotChatView.Feather` -- Bottom gradient overlay.
|
||||
- `CopilotChatView.WelcomeScreen` -- Default welcome layout.
|
||||
- `CopilotChatView.WelcomeMessage` -- Welcome heading text.
|
||||
|
||||
### CopilotChatInput Slots
|
||||
|
||||
The input component has its own slots:
|
||||
|
||||
- `textArea` -- The textarea element.
|
||||
- `sendButton` -- Send/stop button.
|
||||
- `startTranscribeButton` -- Microphone button.
|
||||
- `cancelTranscribeButton` -- Cancel recording button.
|
||||
- `finishTranscribeButton` -- Finish recording button.
|
||||
- `addMenuButton` -- File attachment button.
|
||||
- `audioRecorder` -- Audio recording component.
|
||||
- `disclaimer` -- Disclaimer text below the input.
|
||||
|
||||
## System Prompt / Agent Context
|
||||
|
||||
CopilotKit v2 does not have a `systemPrompt` prop on the chat component. Instead, context is provided to agents through:
|
||||
|
||||
1. **`useAgentContext`** -- Share structured application data.
|
||||
2. **Agent configuration** -- System prompts are configured on the agent itself (server-side), not on the React chat component.
|
||||
|
||||
## Error Handling
|
||||
|
||||
Errors can be handled at two levels:
|
||||
|
||||
```tsx
|
||||
// Provider-level: catches all errors
|
||||
<CopilotKit
|
||||
runtimeUrl="/api/copilotkit"
|
||||
onError={({ error, code, context }) => {
|
||||
console.error("CopilotKit error:", code, error.message);
|
||||
}}
|
||||
>
|
||||
{/* Chat-level: catches errors for this specific agent */}
|
||||
<CopilotChat
|
||||
agentId="myAgent"
|
||||
onError={({ error, code }) => {
|
||||
showToast(`Agent error: ${error.message}`);
|
||||
}}
|
||||
/>
|
||||
</CopilotKit>
|
||||
```
|
||||
|
||||
The chat-level `onError` fires in addition to (not instead of) the provider-level handler. It only receives errors whose `context.agentId` matches the chat's agent.
|
||||
@@ -0,0 +1,370 @@
|
||||
# CopilotKit v2 Runtime API Reference
|
||||
|
||||
Package: `@copilotkit/runtime/v2` (`createCopilotExpressHandler` from `@copilotkit/runtime/v2/express`)
|
||||
|
||||
---
|
||||
|
||||
## Runtime Classes
|
||||
|
||||
### CopilotRuntime
|
||||
|
||||
Compatibility shim that auto-detects the mode based on whether `intelligence` is provided. Delegates to `CopilotSseRuntime` or `CopilotIntelligenceRuntime`.
|
||||
|
||||
```ts
|
||||
import { CopilotRuntime } from "@copilotkit/runtime/v2";
|
||||
|
||||
const runtime = new CopilotRuntime({
|
||||
agents: { myAgent: new LangGraphAgent({ ... }) },
|
||||
// If intelligence is provided, uses Intelligence mode; otherwise SSE mode
|
||||
});
|
||||
```
|
||||
|
||||
### CopilotSseRuntime
|
||||
|
||||
Explicit SSE-mode runtime. Agents run in-memory via `InMemoryAgentRunner`.
|
||||
|
||||
```ts
|
||||
import { CopilotSseRuntime } from "@copilotkit/runtime/v2";
|
||||
|
||||
const runtime = new CopilotSseRuntime({
|
||||
agents: { myAgent: agent },
|
||||
runner?: AgentRunner, // default: InMemoryAgentRunner
|
||||
});
|
||||
```
|
||||
|
||||
### CopilotIntelligenceRuntime
|
||||
|
||||
Intelligence-mode runtime with durable threads, realtime events, and persistent state.
|
||||
|
||||
```ts
|
||||
import {
|
||||
CopilotIntelligenceRuntime,
|
||||
CopilotKitIntelligence,
|
||||
} from "@copilotkit/runtime/v2";
|
||||
|
||||
const runtime = new CopilotIntelligenceRuntime({
|
||||
agents: { myAgent: agent },
|
||||
intelligence: new CopilotKitIntelligence({ ... }),
|
||||
identifyUser: async (request) => ({
|
||||
id: getUserIdFromRequest(request),
|
||||
name: getUserNameFromRequest(request),
|
||||
}),
|
||||
generateThreadNames?: boolean, // default: true
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Runtime Options
|
||||
|
||||
All runtime constructors accept these base options:
|
||||
|
||||
```ts
|
||||
interface BaseCopilotRuntimeOptions {
|
||||
// Map of available agents. Can be a promise for lazy loading.
|
||||
agents: MaybePromise<Record<string, AbstractAgent>>;
|
||||
|
||||
// Optional transcription service for audio processing
|
||||
transcriptionService?: TranscriptionService;
|
||||
|
||||
// Middleware hooks
|
||||
beforeRequestMiddleware?: BeforeRequestMiddleware;
|
||||
afterRequestMiddleware?: AfterRequestMiddleware;
|
||||
|
||||
// Auto-apply A2UI middleware to agents
|
||||
a2ui?: {
|
||||
agents?: string[]; // Limit to specific agents; omit for all
|
||||
// ... A2UIMiddlewareConfig from @ag-ui/a2ui-middleware
|
||||
};
|
||||
|
||||
// Auto-apply MCP Apps middleware
|
||||
mcpApps?: {
|
||||
servers: McpAppsServerConfig[];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### McpAppsServerConfig
|
||||
|
||||
```ts
|
||||
type McpAppsServerConfig = MCPClientConfig & {
|
||||
agentId?: string; // Bind to specific agent; omit for all agents
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Endpoint Factories
|
||||
|
||||
### createCopilotHonoHandler (Hono)
|
||||
|
||||
```ts
|
||||
import { createCopilotHonoHandler } from "@copilotkit/runtime/v2";
|
||||
|
||||
const app = createCopilotHonoHandler({
|
||||
runtime: CopilotRuntimeLike,
|
||||
basePath: string,
|
||||
mode?: "multi-route" | "single-route", // default: "multi-route"
|
||||
cors?: {
|
||||
origin: string | string[] | ((origin: string) => string | null);
|
||||
credentials?: boolean;
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Returns a Hono app instance with all CopilotKit routes mounted under `basePath`. Defaults to multi-route mode; pass `mode: "single-route"` to expose a single combined route.
|
||||
|
||||
### createCopilotExpressHandler (Express)
|
||||
|
||||
```ts
|
||||
import { createCopilotExpressHandler } from "@copilotkit/runtime/v2/express";
|
||||
|
||||
const router = createCopilotExpressHandler({
|
||||
runtime: CopilotRuntimeLike,
|
||||
basePath: string,
|
||||
mode?: "multi-route" | "single-route", // default: "multi-route"
|
||||
});
|
||||
|
||||
// Use in Express app:
|
||||
app.use(router);
|
||||
```
|
||||
|
||||
Returns an Express `Router` with all CopilotKit routes mounted under `basePath`.
|
||||
|
||||
---
|
||||
|
||||
## HTTP Routes
|
||||
|
||||
Both endpoint factories create these routes under `basePath`:
|
||||
|
||||
| Method | Path | Description |
|
||||
| -------- | -------------------------------- | ------------------------------------------------------------ |
|
||||
| `GET` | `/info` | Runtime info: available agents, mode, capabilities |
|
||||
| `POST` | `/agent/:agentId/run` | Run an agent (SSE stream response) |
|
||||
| `POST` | `/agent/:agentId/connect` | Connect to an agent (initial handshake for existing threads) |
|
||||
| `POST` | `/agent/:agentId/stop/:threadId` | Stop a running agent |
|
||||
| `POST` | `/transcribe` | Transcribe audio file |
|
||||
| `GET` | `/threads` | List threads (Intelligence mode) |
|
||||
| `POST` | `/threads/subscribe` | Subscribe to thread updates (Intelligence mode) |
|
||||
| `PATCH` | `/threads/:threadId` | Update thread metadata |
|
||||
| `POST` | `/threads/:threadId/archive` | Archive a thread |
|
||||
| `DELETE` | `/threads/:threadId` | Permanently delete a thread |
|
||||
|
||||
---
|
||||
|
||||
## Middleware
|
||||
|
||||
### BeforeRequestMiddleware
|
||||
|
||||
Called before each request handler. Can modify or replace the request.
|
||||
|
||||
```ts
|
||||
type BeforeRequestMiddleware = (params: {
|
||||
runtime: CopilotRuntimeLike;
|
||||
request: Request;
|
||||
path: string;
|
||||
}) => MaybePromise<Request | void>;
|
||||
```
|
||||
|
||||
If a `Request` is returned, it replaces the original request for the handler.
|
||||
|
||||
### AfterRequestMiddleware
|
||||
|
||||
Called after each request handler. Receives the response and parsed SSE messages.
|
||||
|
||||
```ts
|
||||
type AfterRequestMiddleware = (params: {
|
||||
runtime: CopilotRuntimeLike;
|
||||
response: Response;
|
||||
path: string;
|
||||
messages?: Message[]; // Reconstructed from SSE stream
|
||||
threadId?: string; // From RUN_STARTED event
|
||||
runId?: string; // From RUN_STARTED event
|
||||
}) => MaybePromise<void>;
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
```ts
|
||||
const runtime = new CopilotRuntime({
|
||||
agents: { myAgent: agent },
|
||||
beforeRequestMiddleware: async ({ request, path }) => {
|
||||
console.log(`Incoming request to ${path}`);
|
||||
// Optionally return a modified Request
|
||||
},
|
||||
afterRequestMiddleware: async ({ response, path, threadId, messages }) => {
|
||||
console.log(
|
||||
`Response from ${path}, thread: ${threadId}, ${messages?.length} messages`,
|
||||
);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Intelligence Platform
|
||||
|
||||
### CopilotKitIntelligence
|
||||
|
||||
Client for the CopilotKit Intelligence platform (durable threads, realtime WebSocket).
|
||||
|
||||
```ts
|
||||
import { CopilotKitIntelligence } from "@copilotkit/runtime/v2";
|
||||
|
||||
const intelligence = new CopilotKitIntelligence({
|
||||
// Configuration for the Intelligence platform
|
||||
// (API keys, URLs, etc.)
|
||||
});
|
||||
```
|
||||
|
||||
### identifyUser
|
||||
|
||||
Required for Intelligence mode. Resolves the authenticated user from the incoming request.
|
||||
|
||||
```ts
|
||||
type IdentifyUserCallback = (
|
||||
request: Request,
|
||||
) => MaybePromise<{ id: string; name: string }>;
|
||||
```
|
||||
|
||||
### Thread Management Types
|
||||
|
||||
```ts
|
||||
interface CreateThreadRequest {
|
||||
/* platform-specific */
|
||||
}
|
||||
interface ThreadSummary {
|
||||
/* id, name, timestamps */
|
||||
}
|
||||
interface ListThreadsResponse {
|
||||
/* thread list */
|
||||
}
|
||||
interface UpdateThreadRequest {
|
||||
/* name updates */
|
||||
}
|
||||
interface SubscribeToThreadsRequest {
|
||||
/* WebSocket subscription params */
|
||||
}
|
||||
interface SubscribeToThreadsResponse {
|
||||
/* realtime thread updates */
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Agent Runners
|
||||
|
||||
### AgentRunner (abstract)
|
||||
|
||||
Base class for executing agents. Custom runners can be implemented for custom execution environments.
|
||||
|
||||
### InMemoryAgentRunner
|
||||
|
||||
Default runner for SSE mode. Runs agents in the Node.js process.
|
||||
|
||||
### IntelligenceAgentRunner
|
||||
|
||||
Runner for Intelligence mode. Delegates execution to the Intelligence platform via WebSocket.
|
||||
|
||||
---
|
||||
|
||||
## Transcription Service
|
||||
|
||||
### TranscriptionService (abstract)
|
||||
|
||||
```ts
|
||||
interface TranscribeFileOptions {
|
||||
audioFile: File;
|
||||
mimeType?: string;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
abstract class TranscriptionService {
|
||||
abstract transcribeFile(options: TranscribeFileOptions): Promise<string>;
|
||||
}
|
||||
```
|
||||
|
||||
Implement this class to provide audio-to-text transcription. The runtime exposes it via the `/transcribe` endpoint.
|
||||
|
||||
---
|
||||
|
||||
## CORS Configuration
|
||||
|
||||
The Hono endpoint factory accepts explicit CORS configuration:
|
||||
|
||||
```ts
|
||||
createCopilotHonoHandler({
|
||||
runtime,
|
||||
basePath: "/api/copilotkit",
|
||||
cors: {
|
||||
origin: "https://myapp.com", // or array, or function
|
||||
credentials: true, // for HTTP-only cookies
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
When `credentials` is `true`, `origin` must be explicitly specified (cannot be `"*"`).
|
||||
|
||||
The Express endpoint factory uses `cors({ origin: "*" })` by default. Override by wrapping or configuring the Express cors middleware separately.
|
||||
|
||||
---
|
||||
|
||||
## Complete Example: Next.js API Route (using Hono)
|
||||
|
||||
```ts
|
||||
// app/api/copilotkit/[[...path]]/route.ts
|
||||
import {
|
||||
CopilotRuntime,
|
||||
createCopilotHonoHandler,
|
||||
} from "@copilotkit/runtime/v2";
|
||||
import { LangGraphAgent } from "@copilotkit/runtime/langgraph";
|
||||
import { handle } from "hono/vercel";
|
||||
|
||||
const runtime = new CopilotRuntime({
|
||||
agents: {
|
||||
researcher: new LangGraphAgent({
|
||||
graphId: "researcher",
|
||||
deploymentUrl: process.env.LANGGRAPH_URL!,
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
const app = createCopilotHonoHandler({
|
||||
runtime,
|
||||
basePath: "/api/copilotkit",
|
||||
});
|
||||
|
||||
export const GET = handle(app);
|
||||
export const POST = handle(app);
|
||||
export const PATCH = handle(app);
|
||||
export const DELETE = handle(app);
|
||||
```
|
||||
|
||||
## Complete Example: Express
|
||||
|
||||
```ts
|
||||
import express from "express";
|
||||
import { CopilotRuntime } from "@copilotkit/runtime/v2";
|
||||
import { createCopilotExpressHandler } from "@copilotkit/runtime/v2/express";
|
||||
import { LangGraphAgent } from "@copilotkit/runtime/langgraph";
|
||||
|
||||
const app = express();
|
||||
|
||||
const runtime = new CopilotRuntime({
|
||||
agents: {
|
||||
researcher: new LangGraphAgent({
|
||||
graphId: "researcher",
|
||||
deploymentUrl: process.env.LANGGRAPH_URL!,
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
app.use(
|
||||
createCopilotExpressHandler({
|
||||
runtime,
|
||||
basePath: "/api/copilotkit",
|
||||
}),
|
||||
);
|
||||
|
||||
app.listen(3000);
|
||||
```
|
||||
Reference in New Issue
Block a user