Skip to content
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
86aab9a
first draft of v5
whoiskatrin Jul 10, 2025
5b8de15
fixed human in the loop
whoiskatrin Aug 4, 2025
f4adfed
Cleanup
whoiskatrin Aug 4, 2025
204378d
another cleanup
whoiskatrin Aug 4, 2025
2a73310
fix build
whoiskatrin Aug 4, 2025
3fc2d36
another fix for formatting
whoiskatrin Aug 4, 2025
bed6298
fix dependency conflict
whoiskatrin Aug 4, 2025
4000861
fix dependency conflict
whoiskatrin Aug 4, 2025
6246767
another formatting fix
whoiskatrin Aug 4, 2025
03eacb6
ai react issue fix
whoiskatrin Aug 4, 2025
c0d6e13
cleanup
whoiskatrin Aug 4, 2025
db1ddc6
Add pkg.pr.new workflow
whoiskatrin Aug 4, 2025
48194ff
improve type safety and stream handling
whoiskatrin Aug 20, 2025
7557c3c
minor fixes
whoiskatrin Aug 20, 2025
862d1ca
fix observability event payload
whoiskatrin Aug 20, 2025
69b9c61
fix biome lint issues
whoiskatrin Aug 20, 2025
b5c6777
fix: regenerate clean package-lock.json
whoiskatrin Aug 20, 2025
a60c03f
fix lint issues
whoiskatrin Aug 20, 2025
2bc5aa8
fix changes from the main
whoiskatrin Aug 20, 2025
e006203
fix workflows
whoiskatrin Aug 20, 2025
ea89ac3
try ci again
whoiskatrin Aug 20, 2025
cf83355
fix a2a
whoiskatrin Aug 20, 2025
9ec9a6c
update openai agents package
whoiskatrin Aug 21, 2025
b8a043d
fix minor issues
whoiskatrin Aug 21, 2025
ca376cb
add migration guide, changeset, small fixes for types
whoiskatrin Aug 21, 2025
255d334
updated guide, added utils for migration, fixed types
whoiskatrin Aug 21, 2025
b06d9de
update packages
whoiskatrin Aug 21, 2025
72df075
fix persistance and mcp tool calling
whoiskatrin Aug 26, 2025
ff9084e
migration cleanup
whoiskatrin Aug 26, 2025
ab31d57
fixed SSE raw output
whoiskatrin Aug 26, 2025
20f858e
fix SSE output
whoiskatrin Aug 26, 2025
1e5a792
fix streaming
whoiskatrin Aug 26, 2025
1bfb39e
fix SSE format
whoiskatrin Aug 26, 2025
6084d4a
fix for the chat format
whoiskatrin Aug 26, 2025
30cbea2
fix for ReadableStreamDefaultController enqueue
whoiskatrin Aug 26, 2025
7629f90
fix streaming
whoiskatrin Aug 27, 2025
fb6796d
fixes tool calls returning as raw SSE, streaming UI updates, and save…
whoiskatrin Aug 27, 2025
5e272c8
fix data.error
whoiskatrin Aug 27, 2025
ec0ca29
fix for persistance and migration updates
whoiskatrin Aug 27, 2025
0dfcc49
implement automatic tool resolution with human confirmation detection
whoiskatrin Sep 1, 2025
b94acf7
add automatic tool resolution and improve streaming response handling
whoiskatrin Sep 1, 2025
066622c
persist complete assistant response after streaming finishes
whoiskatrin Sep 1, 2025
e09e8f2
fix: update text-delta property name from textDelta to delta in chat …
whoiskatrin Sep 1, 2025
58459f0
allow custom message types
deathbyknowledge Sep 2, 2025
8bdb1da
handle v5 sse errors
deathbyknowledge Sep 2, 2025
b90b33f
track and persist tool call states in chat messages
whoiskatrin Sep 2, 2025
9501be1
types and docs amends
deathbyknowledge Sep 2, 2025
af697d9
add serverExecuted flag to skip confirmation UI for server-side tools
whoiskatrin Sep 3, 2025
8527613
replace serverExecuted for toolsRequiringConfirmation
deathbyknowledge Sep 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/clear-trains-jam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"agents": minor
---

update to ai sdk v5
2 changes: 1 addition & 1 deletion .github/workflows/prerelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
node-version: 20
cache: "npm"

- run: npm install
- run: npm ci

- name: Modify package.json version
run: npx tsx .github/version-script.ts
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pullrequest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
node-version: 20
cache: "npm"

- run: npm install
- run: npm ci
- run: npm run build
- run: npm run check
- run: CI=true npm run test
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
node-version: 20
cache: "npm"

- run: npm install
- run: npm ci
- run: npm run build

- id: changesets
Expand Down
3 changes: 3 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
"complexity": {
"noBannedTypes": "off"
},
"suspicious": {
"noExplicitAny": "warn"
},
"recommended": true,
"style": {
"noInferrableTypes": "error",
Expand Down
287 changes: 287 additions & 0 deletions docs/migration-to-ai-sdk-v5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
# Migration Guide: Upgrading to Agents SDK with AI SDK v5

This guide helps you migrate your existing code to a new version of our SDK. The Agents SDK now uses AI SDK v5, which introduces several breaking changes and new features.

## Overview of Changes

### 1. Message Format Changes

The most significant change is the message format. AI SDK v5 uses a new `UIMessage` format that replaces the older `Message` format.

#### Before (AI SDK v4):

```typescript
import type { Message } from "ai";

// Messages had a simple structure
const message: Message = {
id: "123",
role: "user",
content: "Hello, assistant!"
};
```

#### After (AI SDK v5):

```typescript
import type { UIMessage } from "ai";

// Messages now use a parts-based structure
const message: UIMessage = {
id: "123",
role: "user",
// New: parts array replaces content property
parts: [
{
type: "text",
text: "Hello, assistant!"
}
]
};
```

### 2. Import Changes

Update your imports to use the new types and packages:

#### Before:

```typescript
import type { Message, StreamTextOnFinishCallback } from "ai";
import { useChat } from "ai/react";
```

#### After:

```typescript
import type { UIMessage as ChatMessage, StreamTextOnFinishCallback } from "ai";
import { useChat } from "@ai-sdk/react";
```

Note: Some imports moved to scoped packages like `@ai-sdk/react`, `@ai-sdk/ui-utils`, etc.

### 3. AIChatAgent Changes

If you're extending `AIChatAgent`, the message handling has been updated:

#### Before:

```typescript
class MyAgent extends AIChatAgent<Env> {
async onChatMessage(
onFinish: StreamTextOnFinishCallback<ToolSet>,
options?: { abortSignal: AbortSignal | undefined }
): Promise<Response | undefined> {
// Your implementation
}
}
```

#### After:

```typescript
class MyAgent extends AIChatAgent<Env> {
async onChatMessage(
onFinish: StreamTextOnFinishCallback<ToolSet>,
options?: { abortSignal: AbortSignal | undefined }
): Promise<Response | undefined> {
// Same signature, but internally handles UIMessage format
}
}
```

### 4. Tool Definitions

Tool definitions now use `inputSchema` instead of `parameters`:

#### Before:

```typescript
const tools = {
weather: {
description: "Get weather information",
parameters: z.object({
city: z.string()
}),
execute: async (args) => {
// Implementation
}
}
};
```

#### After:

```typescript
const tools = {
weather: {
description: "Get weather information",
inputSchema: z.object({
// Changed from 'parameters' to 'inputSchema'
city: z.string()
}),
execute: async (args) => {
// Implementation
}
}
};
```

### 5. Streaming Response Changes

AI SDK v5 introduces a new streaming pattern with start/delta/end events:

#### Before (v4):

```typescript
for await (const chunk of result.fullStream) {
if (chunk.type === "text-delta") {
process.stdout.write(chunk.textDelta);
}
}
```

#### After (v5):

```typescript
for await (const chunk of result.fullStream) {
switch (chunk.type) {
case "text-start":
// New: Called when text generation starts
break;
case "text-delta":
process.stdout.write(chunk.delta); // Note: 'delta' not 'textDelta'
break;
case "text-end":
// New: Called when text generation completes
break;
}
}
```

### 6. Message Persistence and Migration

The SDK automatically detects legacy message formats but **does NOT automatically rewrite your stored messages**. When old format messages are detected, you'll see a console warning:

```
🔄 [AIChatAgent] Detected messages in legacy format (role/content). These will continue to work but consider migrating to the new message format for better compatibility with AI SDK v5 features.
To migrate: import { migrateMessagesToUIFormat } from '@cloudflare/agents' and call await this.persistMessages(migrateMessagesToUIFormat(this.messages))
```

#### Important Notes:

- **No automatic rewriting**: The SDK reads and works with old format messages but doesn't modify your stored data
- **Backward compatibility**: Your existing messages will continue to work without migration
- **Manual migration**: You control when/if to migrate your data

#### How to migrate stored messages:

```typescript
import { migrateMessagesToUIFormat } from "@cloudflare/agents";

class MyAgent extends AIChatAgent<Env> {
async migrateStoredMessages() {
// Convert messages to new format
const migratedMessages = migrateMessagesToUIFormat(this.messages);

// Persist the migrated messages
await this.persistMessages(migratedMessages);

console.log("Messages migrated to UIMessage format");
}
}
```

## Step-by-Step Migration

### Step 1: Update Dependencies

```bash
npm update @cloudflare/agents ai
```

### Step 2: Update Imports

Search and replace the following imports in your codebase:

- `import type { Message } from "ai"` → `import type { UIMessage } from "ai"`
- If you aliased Message as ChatMessage, you can now use: `import type { UIMessage as ChatMessage } from "ai"`

### Step 3: Update Tool Definitions

Find all tool definitions and rename `parameters` to `inputSchema`:

```typescript
// Find all occurrences of tool definitions
// Replace 'parameters:' with 'inputSchema:'
```

### Step 4: Test Your Application

1. Run your type checker: `npm run typecheck`
2. Run your tests: `npm test`
3. Check the console for any migration warnings about legacy message formats

### Step 5: (Optional) Migrate Legacy Messages

The Agents SDK now provides migration utilities to help convert messages to the new format:

```typescript
import {
migrateToUIMessage,
migrateMessagesToUIFormat,
needsMigration,
isUIMessage
} from "@cloudflare/agents";

// Check if migration is needed
if (needsMigration(messages)) {
console.log("Some messages need migration");
}

// Migrate a single message
const newMessage = migrateToUIMessage(oldMessage);

// Migrate an array of messages
const newMessages = migrateMessagesToUIFormat(oldMessages);

// Check if a message is already in UIMessage format
if (isUIMessage(message)) {
console.log("Message is already in new format");
}
```

Note: The SDK handles this conversion automatically at runtime, so manual migration is usually not necessary. These utilities are provided for cases where you want to explicitly migrate stored messages.

## Converting Messages to New Format

The SDK automatically handles old format messages, but if you want to convert them:

### Automatic Conversion (Recommended)

```typescript
import { convertToModelMessages } from "ai";

// Converts any message format to model-compatible format
const modelMessages = convertToModelMessages(messages);
```

### Manual Conversion

Use the migration utilities from Step 5 above. The Agents SDK now provides these utilities for explicit migration when needed.

## Additional Changes

### Type Renames

- `CoreMessage` → `ModelMessage` (when working with model-specific messages)
- Various streaming chunk properties renamed (e.g., `textDelta` → `delta`)

## Need Help?

- Check the [official AI SDK v5 migration guide](https://ai-sdk.dev/docs/migration-guides/migration-guide-5-0)
- Check the [AI SDK v5 documentation](https://sdk.vercel.ai/docs)
- Report issues on the [Agents SDK GitHub repository](https://github.com/cloudflare/agents/issues)
- Join the community discussions for migration tips and best practices

Your existing code will continue to work with minimal changes, and the SDK provides backward compatibility for legacy message formats.
13 changes: 7 additions & 6 deletions examples/a2a/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import type {
A2ARequestHandler,
A2AResponse,
JSONRPCErrorResponse,
JSONRPCSuccessResponse
import {
A2AError,
JsonRpcTransportHandler,
type A2ARequestHandler,
type A2AResponse,
type JSONRPCErrorResponse,
type JSONRPCSuccessResponse
} from "@a2a-js/sdk";
import { A2AError, JsonRpcTransportHandler } from "@a2a-js/sdk";
import type { Context, Hono } from "hono";

export class A2AHonoApp {
Expand Down
2 changes: 1 addition & 1 deletion examples/mcp-elicitation-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"nanoid": "^5.1.5",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"zod": "^3.25.67"
"zod": "^3.25.76"
},
"keywords": [],
"name": "@cloudflare/agents-mcp-elicitation-demo",
Expand Down
21 changes: 6 additions & 15 deletions examples/playground/src/agents/chat.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
import { AIChatAgent } from "agents/ai-chat-agent";
import type { StreamTextOnFinishCallback } from "ai";
import { createDataStreamResponse, streamText } from "ai";
import { convertToCoreMessages, streamText } from "ai";
import { model } from "../model";
import type { Env } from "../server";

export class Chat extends AIChatAgent<Env> {
async onChatMessage(onFinish: StreamTextOnFinishCallback<{}>) {
const dataStreamResponse = createDataStreamResponse({
execute: async (dataStream) => {
const result = streamText({
messages: this.messages,
model,

onFinish
});

result.mergeIntoDataStream(dataStream);
}
async onChatMessage() {
const result = await streamText({
messages: convertToCoreMessages(this.messages),
model
});

return dataStreamResponse;
return result.toTextStreamResponse();
}
}
Loading