Skip to content
This repository was archived by the owner on May 21, 2026. It is now read-only.

Commit 505eaff

Browse files
committed
Add AI SDK Integration Utilities
1 parent 87aaf7f commit 505eaff

1 file changed

Lines changed: 75 additions & 0 deletions

File tree

src/agents/utils/ai_sdk.ts

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**
2+
* AI SDK Integration Utilities
3+
*
4+
* Utility functions for integrating MCPAgent's streamEvents with Vercel AI SDK.
5+
* These utilities help convert stream events to AI SDK compatible formats.
6+
*/
7+
8+
import type { StreamEvent } from '@langchain/core/tracers/log_stream'
9+
10+
/**
11+
* Converts streamEvents to AI SDK compatible stream (basic version)
12+
* Only yields the actual content tokens from chat model streams
13+
*/
14+
export async function* streamEventsToAISDK(
15+
streamEvents: AsyncGenerator<StreamEvent, void, void>,
16+
): AsyncGenerator<string, void, void> {
17+
for await (const event of streamEvents) {
18+
if (event.event === 'on_chat_model_stream' && event.data?.chunk?.text) {
19+
const textContent = event.data.chunk.text
20+
if (typeof textContent === 'string' && textContent.length > 0) {
21+
yield textContent
22+
}
23+
}
24+
}
25+
}
26+
27+
/**
28+
* Converts async generator to ReadableStream for AI SDK compatibility
29+
*/
30+
export function createReadableStreamFromGenerator(
31+
generator: AsyncGenerator<string, void, void>,
32+
): ReadableStream<string> {
33+
return new ReadableStream({
34+
async start(controller) {
35+
try {
36+
for await (const chunk of generator) {
37+
controller.enqueue(chunk)
38+
}
39+
controller.close()
40+
}
41+
catch (error) {
42+
controller.error(error)
43+
}
44+
},
45+
})
46+
}
47+
48+
/**
49+
* Enhanced adapter that includes tool information along with chat content
50+
* Yields both content tokens and tool usage notifications
51+
*/
52+
export async function* streamEventsToAISDKWithTools(
53+
streamEvents: AsyncGenerator<StreamEvent, void, void>,
54+
): AsyncGenerator<string, void, void> {
55+
for await (const event of streamEvents) {
56+
switch (event.event) {
57+
case 'on_chat_model_stream':
58+
if (event.data?.chunk?.text) {
59+
const textContent = event.data.chunk.text
60+
if (typeof textContent === 'string' && textContent.length > 0) {
61+
yield textContent
62+
}
63+
}
64+
break
65+
66+
case 'on_tool_start':
67+
yield `\n🔧 Using tool: ${event.name}\n`
68+
break
69+
70+
case 'on_tool_end':
71+
yield `\n✅ Tool completed: ${event.name}\n`
72+
break
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)