fix(webui): merge length recovery stream segments

This commit is contained in:
chengyongru
2026-07-27 01:39:46 +08:00
committed by Xubin Ren
parent 3cc5a98d9f
commit 27a00c7a4f
26 changed files with 325 additions and 29 deletions
+20 -6
View File
@@ -26,7 +26,7 @@ import type {
} from "@/lib/types";
interface StreamBuffer {
/** ID of the assistant message currently receiving deltas (cleared on ``stream_end``). */
/** ID of the assistant message currently receiving deltas (cleared when its segment closes). */
messageId: string;
}
@@ -780,15 +780,20 @@ export function useNanobotStream(
?? findStreamingAssistantIndex(next, closedAssistantStreamIdsRef.current, turn);
if (targetIndex !== null) {
const target = next[targetIndex];
next = replaceMessageAt(next, targetIndex, {
const merged = {
...target,
content: finalAnswerText,
isStreaming: true,
...turn,
});
};
next = replaceMessageAt(next, targetIndex, merged);
if (!options?.closeAnswerSegment) {
closedAssistantStreamIdsRef.current.delete(merged.id);
activeAssistantRef.current = { id: merged.id, index: targetIndex };
buffer.current = { messageId: merged.id };
}
} else {
const id = crypto.randomUUID();
closedAssistantStreamIdsRef.current.add(id);
next = [
...next,
{
@@ -800,6 +805,12 @@ export function useNanobotStream(
createdAt: Date.now(),
},
];
if (options?.closeAnswerSegment) {
closedAssistantStreamIdsRef.current.add(id);
} else {
activeAssistantRef.current = { id, index: next.length - 1 };
buffer.current = { messageId: id };
}
}
}
if (options?.closeAnswerSegment) closeActiveAssistantStream();
@@ -911,8 +922,9 @@ export function useNanobotStream(
if (ev.event === "stream_end") {
const turn = turnFieldsFromEvent(ev, "answer");
const mergeNext = ev.resuming === true && ev.merge_next === true;
flushPendingStreamEvents({
closeAnswerSegment: true,
closeAnswerSegment: !mergeNext,
...(typeof ev.text === "string" ? { finalAnswerText: ev.text } : {}),
turn,
});
@@ -920,7 +932,9 @@ export function useNanobotStream(
if (ev.resuming) {
cancelStreamEndTimer();
setIsStreaming(true);
setMessages((prev) => finalizeStreamedTurn(prev, turn));
if (!mergeNext) {
setMessages((prev) => finalizeStreamedTurn(prev, turn));
}
return;
}
scheduleStreamEndTimer(turn);