Skip to content

Commit cccbd0f

Browse files
authored
convert internal AI SDK stream events to UIMessageStreamPart format (#678)
* convert internal AI SDK stream events to UIMessageStreamPart format, fix error handling in useAgentChat by wrapping controller.close() in try-catch * Convert AI SDK stream events to UIMessageStreamPart Convert internal AI SDK stream events to UIMessageStreamPart format.
1 parent 93589e5 commit cccbd0f

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

.changeset/silent-timers-hope.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"agents": patch
3+
---
4+
5+
convert internal AI SDK stream events to UIMessageStreamPart format

packages/agents/src/ai-chat-agent.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,11 +1224,28 @@ export class AIChatAgent<Env = unknown, State = unknown> extends Agent<
12241224
// Do we want to handle data parts?
12251225
}
12261226

1227+
// Convert internal AI SDK stream events to valid UIMessageStreamPart format.
1228+
// The "finish" event with "finishReason" is an internal LanguageModelV3StreamPart,
1229+
// not a UIMessageStreamPart (which expects "messageMetadata" instead).
1230+
// See: https://github.com/cloudflare/agents/issues/677
1231+
let eventToSend: unknown = data;
1232+
if (data.type === "finish" && "finishReason" in data) {
1233+
const { finishReason, ...rest } = data as {
1234+
finishReason: string;
1235+
[key: string]: unknown;
1236+
};
1237+
eventToSend = {
1238+
...rest,
1239+
type: "finish",
1240+
messageMetadata: { finishReason }
1241+
};
1242+
}
1243+
12271244
// Store chunk for replay on reconnection
1228-
const chunkBody = JSON.stringify(data);
1245+
const chunkBody = JSON.stringify(eventToSend);
12291246
this._storeStreamChunk(streamId, chunkBody);
12301247

1231-
// Always forward the raw part to the client
1248+
// Forward the converted event to the client
12321249
this._broadcastChatMessage({
12331250
body: chunkBody,
12341251
done: false,

packages/agents/src/ai-react.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,11 @@ export function useAgentChat<
255255
// }))
256256
abortController.abort();
257257
// Make sure to also close the stream (cf. https://github.com/cloudflare/agents-starter/issues/69)
258-
controller.close();
258+
try {
259+
controller.close();
260+
} catch {
261+
// Stream may already be errored or closed
262+
}
259263
});
260264

261265
currentAgent.addEventListener(
@@ -282,7 +286,11 @@ export function useAgentChat<
282286
);
283287
}
284288
if (data.done) {
285-
controller.close();
289+
try {
290+
controller.close();
291+
} catch {
292+
// Stream may already be errored or closed
293+
}
286294
abortController.abort();
287295
}
288296
}

0 commit comments

Comments
 (0)