feat(FN-4835): complete Step 4 — prefer streamed accumulator on done

Fusion-Task-Id: FN-4835
Fusion-Task-Lineage: 09eb6339-a476-4cf1-b7e5-e60fa6c263ce
This commit is contained in:
Fusion (runfusion.ai)
2026-05-16 23:38:30 -07:00
committed by gsxdsm
parent c1cbb668ea
commit 7351852a61
3 changed files with 21 additions and 6 deletions

View File

@@ -610,7 +610,7 @@ describe("useChat", () => {
});
});
it("prefers done payload assistant snapshot over streamed text", async () => {
it("prefers accumulated streamed text over done payload snapshot when both exist", async () => {
const session = makeSession({ id: "session-001", agentId: "agent-001" });
mockFetchChatSessions.mockResolvedValueOnce({ sessions: [session] });
mockFetchChatMessages.mockResolvedValueOnce({ messages: [] });
@@ -633,16 +633,21 @@ describe("useChat", () => {
result.current.selectSession("session-001");
});
await waitFor(() => {
expect(result.current.activeSession?.id).toBe("session-001");
});
act(() => {
result.current.sendMessage("Hello!");
textHandler?.("streamed text");
textHandler?.("Hello.");
textHandler?.(" World.");
doneHandler?.({
messageId: "msg-003",
message: {
id: "msg-003",
sessionId: "session-001",
role: "assistant",
content: "snapshot wins",
content: "Hello.World.",
thinkingOutput: null,
metadata: null,
createdAt: "2026-01-01T00:00:00.000Z",
@@ -653,7 +658,7 @@ describe("useChat", () => {
await waitFor(() => {
expect(result.current.messages.at(-1)).toEqual(expect.objectContaining({
id: "msg-003",
content: "snapshot wins",
content: "Hello. World.",
}));
});
});

View File

@@ -734,7 +734,12 @@ export function useChat(
},
onDone: ({ messageId, message: finalMessage, accumulated }) => {
const assistantMessage: ChatMessageInfo = finalMessage
? mapChatMessageToInfo(finalMessage)
? {
...mapChatMessageToInfo(finalMessage),
// FN-4835 (downstream of FN-3817): the streamed accumulator is
// the authoritative wire transcript, so keep it when present.
...(accumulated.text.length > 0 ? { content: accumulated.text } : {}),
}
: {
id: messageId || `msg-${Date.now()}`,
sessionId: activeSession.id,

View File

@@ -738,7 +738,12 @@ export function useQuickChat(
},
onDone: ({ messageId, message: finalMessage, accumulated }) => {
const assistantMessage: ChatMessageInfo = finalMessage
? mapChatMessageToInfo(finalMessage)
? {
...mapChatMessageToInfo(finalMessage),
// FN-4835 (downstream of FN-3817): keep wire-accurate streamed
// text when available instead of potentially lossy snapshots.
...(accumulated.text.length > 0 ? { content: accumulated.text } : {}),
}
: {
id: messageId || `msg-${Date.now()}`,
sessionId: activeSession.id,