Files
2026-07-13 12:58:18 +08:00

356 lines
16 KiB
Markdown

# CopilotKit v2 Breaking Changes
## Package Structure
### Consolidated React packages
v1 split React functionality across three packages:
- `@copilotkit/react-core` -- provider, hooks, types
- `@copilotkit/react-ui` -- chat components (CopilotChat, CopilotPopup, CopilotSidebar)
- `@copilotkit/react-textarea` -- CopilotTextarea component
v2 consolidates the React surface under the **`/v2` subpath of the same `@copilotkit/react-core` package** (there is no `@copilotkit/react` package):
- `@copilotkit/react-core/v2` -- provider, hooks, types, chat components, and AG-UI re-exports (`@copilotkit/react-core/v2/styles.css` for styles)
### Same package names, new subpath
The v2 API is exposed through the same `@copilotkit/*` packages -- no package name changes are required when upgrading. The v2 symbols live under the `/v2` subpath (`@copilotkit/react-core/v2`, `@copilotkit/runtime/v2`, `@copilotkit/runtime/v2/express`).
### Removed packages
| Package | Status |
| -------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `@copilotkit/react-textarea` | No v2 equivalent. The v1 package stays installable; remove it only after migrating off `CopilotTextarea`. |
| `@copilotkit/runtime-client-gql` | Replaced by `@ag-ui/client` (re-exported from `@copilotkit/react-core/v2`) |
| `@copilotkit/sdk-js` | Removed. `BuiltInAgent` and agent definitions ship from `@copilotkit/runtime/v2` |
---
## Protocol Change: GraphQL to AG-UI
The most fundamental breaking change is the protocol layer. v1 used a GraphQL-based protocol (`@copilotkit/runtime-client-gql`). v2 uses the AG-UI protocol (`@ag-ui/client` / `@ag-ui/core`), which is SSE-based.
**Impact:**
- All GraphQL message types (`TextMessage`, `ActionExecutionMessage`, `ResultMessage`, etc.) are replaced by AG-UI event types (`TextMessageChunkEvent`, `ToolCallStartEvent`, `ToolCallArgsEvent`, `ToolCallEndEvent`, `ToolCallResultEvent`, etc.)
- The `MessageRole` enum is replaced by AG-UI message roles
- Custom GraphQL queries/mutations against the runtime are no longer possible
- The runtime no longer exposes a GraphQL endpoint
---
## Provider Changes
### Component import path change
The provider keeps the name `CopilotKit`; the import path changes from the package root (`@copilotkit/react-core`, legacy v1) to the `/v2` subpath (`@copilotkit/react-core/v2`). The `/v2` subpath also exports a `CopilotKitProvider` component -- do **not** migrate to it. It is a functionality subset of `CopilotKit`, which is the compatibility bridge across v1 and v2 (its `CopilotKitProps` extends `Omit<CopilotKitProviderProps, "children">` with a narrowed `children` type, so every non-`children` `CopilotKitProvider` prop works on it).
### Props changes
| v1 Prop | v2 Status | Notes |
| -------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `runtimeUrl` | Kept | Same behavior |
| `headers` | Kept | Same behavior |
| `publicApiKey` | Kept (deprecated) | `publicLicenseKey` is the canonical name |
| `properties` | Kept | Same behavior |
| `agents` | Removed | Use `selfManagedAgents` or `agents__unsafe_dev_only` |
| `guardrails_c` | Kept (CopilotCloud only) | Marked `@internal`/defunct in source, but still wired into the legacy CopilotCloud `restrictToTopic` config when a cloud key (`publicApiKey`) is set; has no effect on the v2 AG-UI runtime path |
| `children` | Kept | Same behavior |
| -- | Added: `credentials` | `RequestCredentials` for fetch (e.g., `"include"` for cookies) |
| -- | Added: `selfManagedAgents` | `Record<string, AbstractAgent>` for client-side agents |
| -- | Added: `renderToolCalls` | `ReactToolCallRenderer[]` for provider-level tool renderers |
| -- | Added: `renderActivityMessages` | `ReactActivityMessageRenderer[]` for activity renderers |
| -- | Added: `useSingleEndpoint` | Boolean to use single-route endpoint mode |
### Context hook rename
`useCopilotContext` is replaced by `useCopilotKit` (imported from `@copilotkit/react-core/v2/context`), which returns `{ copilotkit: CopilotKitCoreReact, executingToolCallIds: ReadonlySet<string> }`.
---
## Hook Renames and API Changes
### useCopilotAction -> useFrontendTool
**Parameter definition change:** v1 used a custom parameter descriptor format. v2 uses Zod schemas.
```ts
// v1 parameters
parameters: [
{ name: "city", type: "string", description: "City name", required: true },
{ name: "units", type: "string", enum: ["celsius", "fahrenheit"] },
];
// v2 parameters (Zod)
parameters: z.object({
city: z.string().describe("City name"),
units: z.enum(["celsius", "fahrenheit"]).optional(),
});
```
**Handler signature change:**
```ts
// v1
handler: ({ city, units }) => { ... }
// v2
handler: async (args) => { ... } // args is typed from the Zod schema
```
**Render props change:**
```ts
// v1 render status: the string literals "inProgress" | "executing" | "complete"
// v1 uses `respond()` callback for interactive actions
// v2 render status: the `ToolCallStatus` enum (ToolCallStatus.InProgress | .Executing | .Complete).
// Its values ARE those same strings, so `status === "inProgress"` still works;
// prefer comparing against the enum members.
// v2 render props: { name, toolCallId, args, status, result }
```
**Availability change:**
```ts
// v1
disabled: true;
// v2 — `available` is a boolean (defaults to true; set false to hide the tool)
available: false;
```
### useCopilotReadable -> useAgentContext
**Breaking:** The `parentId` parameter for hierarchical context is removed. Flatten nested contexts.
```ts
// v1 (hierarchical)
const parentId = useCopilotReadable({ description: "Parent", value: "..." });
useCopilotReadable({ description: "Child", value: "...", parentId });
// v2 (flat)
useAgentContext({
description: "Parent - Child context",
value: { parent: "...", child: "..." },
});
```
### useCoAgent -> useAgent
**Breaking:** Completely different return type.
```ts
// v1 returns
{
(name, nodeName, state, setState, running, start, stop, run);
}
// v2 returns
AbstractAgent; // AG-UI agent instance with run(), stop(), etc.
```
- `name` -> `agentId` (in props)
- `initialState` -> removed (no client-side state initialization)
- `setState` -> removed (state flows via AG-UI events)
- `nodeName` -> removed
- `state` -> accessed through AG-UI `StateSnapshotEvent` / `StateDeltaEvent`
### useLangGraphInterrupt -> useInterrupt
**Breaking:** Different API shape.
- `agentName` -> `agentId`
- `nodeName` -> removed (use `enabled` predicate to filter)
- `render` props change: v2 receives `InterruptRenderProps<TValue, TResult>` = `{ event, resolve, result }` (still includes `event`/`resolve`, adds `result`)
- New `renderInChat` prop (default `true`) controls whether interrupt renders inside CopilotChat
- New `handler` prop for programmatic handling before rendering
- New `enabled` predicate prop for filtering interrupts
### useCopilotChat -> removed
Replaced by `useAgent` for agent interaction. The headless chat API (appendMessage, visibleMessages, etc.) is replaced by the AG-UI agent event stream.
### useCopilotChatSuggestions -> useConfigureSuggestions + useSuggestions
Split into two hooks: one for configuration, one for reading state.
### useCoAgentStateRender -> useRenderToolCall / useRenderActivityMessage
Split into two hooks based on the type of rendering needed.
### useCopilotAdditionalInstructions -> useAgentContext
Use `useAgentContext` with an appropriate description to provide instructions.
### useMakeCopilotDocumentReadable -> useAgentContext
Use `useAgentContext` to pass document content. The `DocumentPointer` type and category-based filtering are removed.
---
## Runtime Breaking Changes
### Service adapters removed
All service adapters are removed from the runtime:
| Removed Adapter | v2 Alternative |
| --------------------------- | ------------------------------------------------------------------- |
| `OpenAIAdapter` | Use `BuiltInAgent({ model: "openai/gpt-4o" })` |
| `AnthropicAdapter` | Use `BuiltInAgent({ model: "anthropic/claude-sonnet-4.5" })` |
| `GoogleGenerativeAIAdapter` | Use `BuiltInAgent({ model: "google/gemini-2.5-pro" })` |
| `LangChainAdapter` | Use a custom `AbstractAgent` implementation |
| `GroqAdapter` | Use a custom `AbstractAgent` (pass a Groq `LanguageModel` instance) |
| `UnifyAdapter` | Use a custom `AbstractAgent` implementation |
| `OpenAIAssistantAdapter` | Use a custom `AbstractAgent` implementation |
| `BedrockAdapter` | Use a custom `AbstractAgent` implementation |
| `OllamaAdapter` | Use a custom `AbstractAgent` implementation |
| `EmptyAdapter` | Not needed |
### Runtime constructor changes
```ts
// v1
new CopilotRuntime({
actions: [...], // Removed
remoteEndpoints: [...], // Removed
remoteActions: [...], // Removed
onBeforeRequest: (options) => {}, // Deprecated
onAfterRequest: (options) => {}, // Deprecated
})
// v2
new CopilotRuntime({
agents: { ... }, // Required: Record<string, AbstractAgent>
transcriptionService: ..., // Optional: TranscriptionService
beforeRequestMiddleware: ..., // Optional: BeforeRequestMiddleware
afterRequestMiddleware: ..., // Optional: AfterRequestMiddleware
a2ui: { ... }, // Optional: A2UIMiddleware config
mcpApps: { servers: [...] }, // Optional: MCP Apps middleware
// Intelligence mode only:
intelligence: new CopilotKitIntelligence({ ... }),
identifyUser: (request) => ({ id: "..." }),
generateThreadNames: true,
})
```
### Framework integrations removed
v1 had built-in integrations for Next.js (App Router, Pages Router), Express, NestJS, and Node HTTP. v2 uses Hono as the standard HTTP layer:
| v1 Integration | v2 Replacement |
| ----------------------------------------- | ---------------------------------------------------------------- |
| `copilotRuntimeNextJSAppRouterEndpoint` | `createCopilotHonoHandler` (Hono, works with Next.js) |
| `copilotRuntimeNextJSPagesRouterEndpoint` | `createCopilotHonoHandler` (Hono) |
| `CopilotRuntimeNodeExpressEndpoint` | `createCopilotExpressHandler` (`@copilotkit/runtime/v2/express`) |
| `CopilotRuntimeNestEndpoint` | Use Hono adapter or Express endpoint |
| `CopilotRuntimeNodeHttpEndpoint` | Use Hono or Express endpoint |
### Endpoint configuration
```ts
// v1 (Next.js App Router example)
import { copilotRuntimeNextJSAppRouterEndpoint } from "@copilotkit/runtime";
export const POST = copilotRuntimeNextJSAppRouterEndpoint({
runtime,
serviceAdapter,
endpoint: "/api/copilotkit",
});
// v2 -- use createCopilotHonoHandler (createCopilotEndpoint is a deprecated alias)
import { createCopilotHonoHandler } from "@copilotkit/runtime/v2";
const app = createCopilotHonoHandler({
runtime,
basePath: "/api/copilotkit",
cors: {
origin: "https://myapp.com",
credentials: true,
},
});
// For Next.js App Router, export the Hono app's fetch handler
export const POST = app.fetch;
export const GET = app.fetch;
```
### LangGraph agent configuration
```ts
// v1 (remote endpoint)
new CopilotRuntime({
remoteEndpoints: [
{
url: "http://localhost:8000/copilotkit",
type: "langgraph",
},
],
});
// v2 (direct agent instance)
import { LangGraphAgent } from "@copilotkit/runtime/langgraph";
new CopilotRuntime({
agents: {
myAgent: new LangGraphAgent({
deploymentUrl: "http://localhost:8000",
graphId: "my-graph",
}),
},
});
```
---
## Type System Changes
### Parameter types
v1 used a custom `Parameter` type for defining tool parameters:
```ts
type Parameter = {
name: string;
type:
| "string"
| "number"
| "boolean"
| "object"
| "string[]"
| "number[]"
| "boolean[]"
| "object[]";
description?: string;
required?: boolean;
enum?: string[];
attributes?: Parameter[]; // for object types
};
```
v2 uses Zod schemas (`z.object(...)`) or Standard Schema V1 (`StandardSchemaV1`).
### Message types
v1 GraphQL types from `@copilotkit/runtime-client-gql` are replaced by AG-UI types:
| v1 Type | v2 Type |
| ------------------------ | --------------------------- |
| `TextMessage` | `Message` with text content |
| `ActionExecutionMessage` | `ToolCall` |
| `ResultMessage` | `ToolMessage` |
| `MessageRole` | AG-UI role types |
### Event types
v2 introduces AG-UI event types for streaming:
- `RunStartedEvent`, `RunFinishedEvent`, `RunErrorEvent`
- `TextMessageChunkEvent`
- `ToolCallStartEvent`, `ToolCallArgsEvent`, `ToolCallEndEvent`, `ToolCallResultEvent`
- `StateSnapshotEvent`, `StateDeltaEvent`
- `ReasoningStartEvent`, `ReasoningMessageStartEvent`, `ReasoningMessageContentEvent`, `ReasoningMessageEndEvent`, `ReasoningEndEvent`