diff --git a/packages/server/src/server/agent/agent-manager.test.ts b/packages/server/src/server/agent/agent-manager.test.ts index e8870b3aba..1d1ae6853f 100644 --- a/packages/server/src/server/agent/agent-manager.test.ts +++ b/packages/server/src/server/agent/agent-manager.test.ts @@ -1384,7 +1384,7 @@ describe("AgentManager", () => { expect(fetched.rows.map((row) => row.seq)).toEqual([1, 2]); }); - test("streams assistant chunks provisionally and commits one finalized assistant row", async () => { + test("buffers assistant chunks provisionally and streams one finalized assistant row", async () => { const workdir = mkdtempSync(join(tmpdir(), "agent-manager-provisional-timeline-")); const storagePath = join(workdir, "agents"); const storage = new AgentStorage(storagePath, logger); @@ -1435,18 +1435,10 @@ describe("AgentManager", () => { } const assistantTimelineEvents = streamEvents.filter((event) => event.itemType === "assistant_message"); - expect(assistantTimelineEvents).toHaveLength(3); + expect(assistantTimelineEvents).toHaveLength(1); expect(assistantTimelineEvents[0]).toMatchObject({ eventType: "timeline", itemType: "assistant_message", - text: "final ", - }); - expect(assistantTimelineEvents[0]?.seq).toBeUndefined(); - expect(assistantTimelineEvents[1]).toMatchObject({ - text: "reply", - }); - expect(assistantTimelineEvents[1]?.seq).toBeUndefined(); - expect(assistantTimelineEvents[2]).toMatchObject({ text: "final reply", seq: 1, }); diff --git a/packages/server/src/server/agent/agent-manager.ts b/packages/server/src/server/agent/agent-manager.ts index 3d144aa7c3..28279bac68 100644 --- a/packages/server/src/server/agent/agent-manager.ts +++ b/packages/server/src/server/agent/agent-manager.ts @@ -1972,6 +1972,7 @@ export class AgentManager { const isForegroundEvent = Boolean( eventTurnId && agent.activeForegroundTurnId === eventTurnId, ); + let suppressLiveDispatch = false; // Only update timestamp for live events, not history replay if (!options?.fromHistory) { @@ -2027,6 +2028,7 @@ export class AgentManager { } if (event.item.type === "assistant_message") { agent.provisionalAssistantText = `${agent.provisionalAssistantText ?? ""}${event.item.text}`; + suppressLiveDispatch = true; break; } if (event.item.type === "reasoning") { @@ -2194,7 +2196,7 @@ export class AgentManager { } // Skip dispatching individual stream events during history replay. - if (!options?.fromHistory) { + if (!options?.fromHistory && !suppressLiveDispatch) { this.dispatchStream( agent.id, event,