diff --git a/.changeset/fix-finish-step-event-name.md b/.changeset/fix-finish-step-event-name.md new file mode 100644 index 00000000..95c0e6f8 --- /dev/null +++ b/.changeset/fix-finish-step-event-name.md @@ -0,0 +1,5 @@ +--- +"chat": patch +--- + +Fix `fromFullStream()` step separator detection for AI SDK v5+: rename `step-finish` event check to `finish-step` diff --git a/packages/chat/src/from-full-stream.test.ts b/packages/chat/src/from-full-stream.test.ts index 79740cf6..81683011 100644 --- a/packages/chat/src/from-full-stream.test.ts +++ b/packages/chat/src/from-full-stream.test.ts @@ -30,7 +30,7 @@ describe("fromFullStream", () => { it("injects separator between steps", async () => { const stream = events([ { type: "text-delta", textDelta: "hello." }, - { type: "step-finish" }, + { type: "finish-step" }, { type: "text-delta", textDelta: "how are you?" }, ]); expect(await collect(fromFullStream(stream))).toBe( @@ -38,10 +38,10 @@ describe("fromFullStream", () => { ); }); - it("does not add trailing separator after final step-finish", async () => { + it("does not add trailing separator after final finish-step", async () => { const stream = events([ { type: "text-delta", textDelta: "done." }, - { type: "step-finish" }, + { type: "finish-step" }, ]); expect(await collect(fromFullStream(stream))).toBe("done."); }); @@ -49,9 +49,9 @@ describe("fromFullStream", () => { it("handles multiple steps", async () => { const stream = events([ { type: "text-delta", textDelta: "step 1" }, - { type: "step-finish" }, + { type: "finish-step" }, { type: "text-delta", textDelta: "step 2" }, - { type: "step-finish" }, + { type: "finish-step" }, { type: "text-delta", textDelta: "step 3" }, ]); expect(await collect(fromFullStream(stream))).toBe( @@ -64,26 +64,26 @@ describe("fromFullStream", () => { { type: "text-delta", textDelta: "before" }, { type: "tool-call", toolName: "search", args: {} }, { type: "tool-result", toolName: "search", result: "data" }, - { type: "step-finish" }, + { type: "finish-step" }, { type: "tool-call-streaming-start", toolName: "lookup" }, { type: "text-delta", textDelta: " after" }, ]); expect(await collect(fromFullStream(stream))).toBe("before\n\n after"); }); - it("handles consecutive step-finish events", async () => { + it("handles consecutive finish-step events", async () => { const stream = events([ { type: "text-delta", textDelta: "a" }, - { type: "step-finish" }, - { type: "step-finish" }, + { type: "finish-step" }, + { type: "finish-step" }, { type: "text-delta", textDelta: "b" }, ]); expect(await collect(fromFullStream(stream))).toBe("a\n\nb"); }); - it("does not inject separator when step-finish comes before any text", async () => { + it("does not inject separator when finish-step comes before any text", async () => { const stream = events([ - { type: "step-finish" }, + { type: "finish-step" }, { type: "text-delta", textDelta: "first text" }, ]); expect(await collect(fromFullStream(stream))).toBe("first text"); @@ -124,7 +124,7 @@ describe("fromFullStream", () => { it("injects separator between steps with text property", async () => { const stream = events([ { type: "text-delta", id: "0", text: "step 1." }, - { type: "step-finish" }, + { type: "finish-step" }, { type: "text-delta", id: "0", text: "step 2." }, ]); expect(await collect(fromFullStream(stream))).toBe("step 1.\n\nstep 2."); diff --git a/packages/chat/src/from-full-stream.ts b/packages/chat/src/from-full-stream.ts index d07e3856..fe85e1e4 100644 --- a/packages/chat/src/from-full-stream.ts +++ b/packages/chat/src/from-full-stream.ts @@ -64,7 +64,7 @@ export async function* fromFullStream( needsSeparator = false; hasEmittedText = true; yield textContent; - } else if (typed.type === "step-finish") { + } else if (typed.type === "finish-step") { needsSeparator = true; } }