mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 01:29:56 +00:00
fix(ui): reuse persisted text during chat streaming (#146831)
This commit is contained in:
parent
9ca900f3b3
commit
dee64cddf3
2 changed files with 55 additions and 3 deletions
|
|
@ -824,6 +824,58 @@ describe("handleChatGatewayEvent", () => {
|
|||
expect(state.chatStream).toBe(expected);
|
||||
});
|
||||
|
||||
it("reuses persisted text across live deltas and refreshes replaced messages", () => {
|
||||
const persistedMessage = (id: string, text: string) => {
|
||||
const readContent = vi.fn(() => [{ type: "text", text }]);
|
||||
return {
|
||||
readContent,
|
||||
message: {
|
||||
role: "assistant",
|
||||
get content() {
|
||||
return readContent();
|
||||
},
|
||||
__openclaw: { id, runId: "run-1" },
|
||||
},
|
||||
};
|
||||
};
|
||||
const first = persistedMessage("part-a", "A");
|
||||
const second = persistedMessage("part-b", "B");
|
||||
const state = createState({
|
||||
chatRunId: "run-1",
|
||||
chatMessages: [first.message, second.message],
|
||||
});
|
||||
const receiveDelta = (text: string) => {
|
||||
expect(
|
||||
handleChatGatewayEvent(state, {
|
||||
runId: "run-1",
|
||||
sessionKey: "main",
|
||||
state: "delta",
|
||||
message: createTextChatMessage("assistant", text),
|
||||
}),
|
||||
).toBe("delta");
|
||||
return visibleCurrentAssistantStreamTail(state, () => false);
|
||||
};
|
||||
|
||||
expect(receiveDelta("ABC")).toBe("C");
|
||||
expect(first.readContent).toHaveBeenCalled();
|
||||
expect(second.readContent).toHaveBeenCalled();
|
||||
first.readContent.mockClear();
|
||||
second.readContent.mockClear();
|
||||
|
||||
for (const text of ["ABCD", "ABCDE", "ABCDEF"]) {
|
||||
expect(receiveDelta(text)).toBe(text.slice(2));
|
||||
}
|
||||
expect(first.readContent).not.toHaveBeenCalled();
|
||||
expect(second.readContent).not.toHaveBeenCalled();
|
||||
|
||||
const replacement = persistedMessage("part-b", "BC");
|
||||
state.chatMessages = [first.message, replacement.message];
|
||||
expect(receiveDelta("ABCDEFG")).toBe("DEFG");
|
||||
expect(replacement.readContent).toHaveBeenCalled();
|
||||
expect(first.readContent).not.toHaveBeenCalled();
|
||||
expect(second.readContent).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("adopts the run id for selected-session live deltas observed from another channel", () => {
|
||||
const state = createState({
|
||||
sessionKey: "agent:main:feishu:direct:peer-1",
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
streamSegmentUsesAccumulatedText,
|
||||
type ChatStreamSegment,
|
||||
} from "../../lib/chat/chat-types.ts";
|
||||
import { extractText } from "../../lib/chat/message-extract.ts";
|
||||
import { extractText, extractTextCached } from "../../lib/chat/message-extract.ts";
|
||||
import { userTurnRunId } from "./chat-thread-items.ts";
|
||||
import { isKeyedAssistantStreamFallbackMessage } from "./chat-thread-run-identity.ts";
|
||||
|
||||
|
|
@ -236,7 +236,7 @@ export function resolveCumulativeAssistantTail(
|
|||
const identity = readSessionMessageIdentity(message);
|
||||
const persistedText =
|
||||
identity?.runId === runId && !isKeyedAssistantStreamFallbackMessage(message)
|
||||
? extractText(message)
|
||||
? extractTextCached(message)
|
||||
: null;
|
||||
if (
|
||||
identity?.role === "assistant" &&
|
||||
|
|
@ -255,7 +255,7 @@ export function resolveCumulativeAssistantTail(
|
|||
return identity?.role === "assistant" &&
|
||||
(!identity.runId || identity.runId === runId) &&
|
||||
!isKeyedAssistantStreamFallbackMessage(message)
|
||||
? extractText(message)
|
||||
? extractTextCached(message)
|
||||
: null;
|
||||
});
|
||||
return resolveAssistantTextTail(persistedTexts, cumulativeText);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue