Commit 5ce517c7 authored by edy's avatar edy

fix(ui): clear completed assistant stream state

parent bdb82411
......@@ -5,7 +5,7 @@ import {
COMPOSER_TEXTAREA_MAX_RATIO,
COMPOSER_TEXTAREA_MIN_RATIO,
COMPOSER_TEXTAREA_SAFE_MIN_HEIGHT
} from "./constants"
} from "./constants.ts"
export type MessageStreamState = "streaming" | "error"
......@@ -92,14 +92,18 @@ export function mergeSessionHistory(current: UiChatMessage[], nextMessages: UiCh
return message
}
if (local.streamState === "streaming" && local.content.length > message.content.length) {
return {
...message,
content: local.content.length > message.content.length ? local.content : message.content,
content: local.content,
createdAt: message.createdAt || local.createdAt,
streamState: local.streamState ?? message.streamState,
statusLabel: local.statusLabel ?? message.statusLabel,
statusDetail: local.statusDetail ?? message.statusDetail
}
}
return message
})
const nextIds = new Set(nextMessages.map((message) => message.id))
const localOnlyMessages = current.filter((message) => !nextIds.has(message.id))
......
import test from "node:test"
import assert from "node:assert/strict"
import type { UiChatMessage } from "../src/lib/chat-utils.ts"
import { mergeSessionHistory } from "../src/lib/chat-utils.ts"
test("mergeSessionHistory clears local assistant transient state when server has final content", () => {
const current: UiChatMessage[] = [{
id: "assistant-1",
role: "assistant",
content: "Final answer",
createdAt: "2026-05-18T08:00:00.000Z",
streamState: "streaming",
statusLabel: "Thinking",
statusDetail: "Using tools"
}]
const nextMessages: UiChatMessage[] = [{
id: "assistant-1",
role: "assistant",
content: "Final answer",
createdAt: "2026-05-18T08:00:01.000Z"
}]
const [message] = mergeSessionHistory(current, nextMessages)
assert.equal(message.content, "Final answer")
assert.equal(message.streamState, undefined)
assert.equal(message.statusLabel, undefined)
assert.equal(message.statusDetail, undefined)
})
test("mergeSessionHistory preserves active local streaming state when server content is stale", () => {
const current: UiChatMessage[] = [{
id: "assistant-1",
role: "assistant",
content: "Streaming answer with more text",
createdAt: "2026-05-18T08:00:00.000Z",
streamState: "streaming",
statusLabel: "Thinking",
statusDetail: "Drafting"
}]
const nextMessages: UiChatMessage[] = [{
id: "assistant-1",
role: "assistant",
content: "Streaming answer",
createdAt: "2026-05-18T08:00:01.000Z"
}]
const [message] = mergeSessionHistory(current, nextMessages)
assert.equal(message.content, "Streaming answer with more text")
assert.equal(message.streamState, "streaming")
assert.equal(message.statusLabel, "Thinking")
assert.equal(message.statusDetail, "Drafting")
})
......@@ -3,6 +3,7 @@
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Bundler",
"allowImportingTsExtensions": true,
"jsx": "react-jsx",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"types": ["vite/client"]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment