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
+73
View File
@@ -2009,6 +2009,79 @@ describe("useNanobotStream", () => {
expect(result.current.messages.every((message) => !message.isStreaming)).toBe(true);
});
it("keeps length-recovery segments in one assistant message", async () => {
const fake = fakeClient();
const { result } = renderHook(() => useNanobotStream("chat-length", EMPTY_MESSAGES), {
wrapper: wrap(fake.client),
});
act(() => {
result.current.send("give a long answer");
});
const activeTurnId = fake.client.sendMessage.mock.calls.at(-1)![3]?.turnId;
act(() => {
fake.emit("chat-length", {
event: "delta",
chat_id: "chat-length",
text: "first ",
turn_id: activeTurnId,
});
});
await flushStreamFrame();
const assistantId = result.current.messages[1].id;
act(() => {
fake.emit("chat-length", {
event: "stream_end",
chat_id: "chat-length",
text: "first ",
resuming: true,
merge_next: true,
turn_id: activeTurnId,
});
});
expect(result.current.messages).toHaveLength(2);
expect(result.current.messages[1]).toMatchObject({
id: assistantId,
content: "first ",
isStreaming: true,
});
act(() => {
fake.emit("chat-length", {
event: "delta",
chat_id: "chat-length",
text: "second",
turn_id: activeTurnId,
});
});
await flushStreamFrame();
expect(result.current.messages).toHaveLength(2);
expect(result.current.messages[1]).toMatchObject({
id: assistantId,
content: "first second",
isStreaming: true,
});
act(() => {
fake.emit("chat-length", {
event: "turn_end",
chat_id: "chat-length",
turn_id: activeTurnId,
});
});
expect(result.current.messages).toHaveLength(2);
expect(result.current.messages[1]).toMatchObject({
id: assistantId,
content: "first second",
isStreaming: false,
});
});
it("keeps streaming alive across stream_end when tool activity follows", async () => {
const fake = fakeClient();
const onTurnEnd = vi.fn();