branch:
migration-to-ai-sdk-v6.md
5164 bytesRaw
# Migrating from AI SDK v5 to v6
This guide covers the changes needed when upgrading from AI SDK v5 to v6 with `@cloudflare/ai-chat`.
## Installation
```bash
npm install ai@latest @ai-sdk/react@latest @ai-sdk/openai@latest
```
## Breaking changes
### 1. `convertToModelMessages()` is now async
Add `await` to all calls:
```typescript
// v5
const result = streamText({
messages: convertToModelMessages(this.messages),
model: openai("gpt-4o")
});
// v6
const result = streamText({
messages: await convertToModelMessages(this.messages),
model: openai("gpt-4o")
});
```
### 2. `CoreMessage` removed
Replace `CoreMessage` with `ModelMessage` and `convertToCoreMessages()` with `convertToModelMessages()`:
```typescript
// v5
import { convertToCoreMessages, type CoreMessage } from "ai";
// v6
import { convertToModelMessages, type ModelMessage } from "ai";
```
### 3. Tool pattern: server-side tools (recommended)
v6 introduces `needsApproval` and the `onToolCall` callback. For most apps, define tools on the server with `tool()` from `"ai"` for full Zod type safety:
**Before (v5):**
```typescript
// Client defined tools with AITool type
useAgentChat({
agent,
tools: clientTools,
experimental_automaticToolResolution: true,
toolsRequiringConfirmation: ["askConfirmation"]
});
```
**After (v6):**
```typescript
// Server: all tools defined here
const tools = {
getWeather: tool({
description: "Get weather",
inputSchema: z.object({ city: z.string() }),
execute: async ({ city }) => fetchWeather(city)
}),
getLocation: tool({
description: "Get user location",
inputSchema: z.object({})
// No execute -- client handles via onToolCall
}),
processPayment: tool({
description: "Process payment",
inputSchema: z.object({ amount: z.number() }),
needsApproval: async ({ amount }) => amount > 100,
execute: async ({ amount }) => charge(amount)
})
};
// Client: handle tools via callbacks
useAgentChat({
agent,
onToolCall: async ({ toolCall, addToolOutput }) => {
if (toolCall.toolName === "getLocation") {
const pos = await getPosition();
addToolOutput({
toolCallId: toolCall.toolCallId,
output: { lat: pos.coords.latitude, lng: pos.coords.longitude }
});
}
}
});
```
**Dynamic client tools (SDK/platform pattern):**
If you are building an SDK or platform where tools are defined dynamically by the embedding application at runtime, the `tools` option on `useAgentChat` and `createToolsFromClientSchemas()` on the server are still fully supported:
```typescript
// Server: accept whatever tools the client sends
const tools = {
...createToolsFromClientSchemas(options.clientTools),
...serverTools
};
// Client: register tools dynamically
useAgentChat({
agent,
tools: dynamicTools,
onToolCall: async ({ toolCall, addToolOutput }) => {
const tool = dynamicTools[toolCall.toolName];
if (tool?.execute) {
const output = await tool.execute(toolCall.input);
addToolOutput({ toolCallId: toolCall.toolCallId, output });
}
}
});
```
### 4. `generateObject` mode option removed
Remove `mode: "json"` or similar from `generateObject` calls.
### 5. `isToolUIPart` and `getToolName` now include dynamic tools
In v6, these check both static and dynamic tool parts. For the old behavior, use `isStaticToolUIPart` and `getStaticToolName`. Most users do not need to change anything.
## Deprecated APIs
| Deprecated | Replacement |
| -------------------------------------- | --------------------------------------------------------- |
| `toolsRequiringConfirmation` | [`needsApproval`](./human-in-the-loop.md) on server tools |
| `experimental_automaticToolResolution` | [`onToolCall`](./client-tools-continuation.md) callback |
| `addToolResult()` | `addToolOutput()` or `addToolApprovalResponse()` |
**Not deprecated:** `AITool`, `createToolsFromClientSchemas()`, `extractClientToolSchemas()`, and the `tools` option on `useAgentChat` are supported for SDK/platform use cases where tools are defined dynamically at runtime.
## Migration checklist
**Packages:**
- `ai` to `^6.0.0`
- `@ai-sdk/react` to `^3.0.0`
- `@ai-sdk/openai` (and other providers) to `^3.0.0`
**Code changes:**
- Add `await` to all `convertToModelMessages()` calls
- Replace `CoreMessage` with `ModelMessage`
- Replace `convertToCoreMessages()` with `convertToModelMessages()`
- Remove `mode` from `generateObject` calls
- Move static tool definitions to server using `tool()` (recommended for most apps)
- Use `onToolCall` in `useAgentChat` for client-side tool execution
- Replace `toolsRequiringConfirmation` with `needsApproval`
- Replace `addToolResult()` with `addToolOutput()` or `addToolApprovalResponse()`
## Further reading
- [Official AI SDK v6 migration guide](https://ai-sdk.dev/docs/migration-guides/migration-guide-6-0)
- [Human in the Loop](./human-in-the-loop.md) -- `needsApproval` and `addToolApprovalResponse`
- [Client Tools](./client-tools-continuation.md) -- `onToolCall` and auto-continuation