























@@ -47,18 +47,22 @@ function createActiveStreamingState() {
4747});
4848}
494950-function createOtherRunNoReplyFinalPayload(): ChatEventPayload {
50+function createOtherRunSilentFinalPayload(text: string): ChatEventPayload {
5151return {
5252runId: "run-announce",
5353sessionKey: "main",
5454state: "final",
5555message: {
5656role: "assistant",
57-content: [{ type: "text", text: "NO_REPLY" }],
57+content: [{ type: "text", text }],
5858},
5959};
6060}
616162+function createOtherRunNoReplyFinalPayload(): ChatEventPayload {
63+return createOtherRunSilentFinalPayload("NO_REPLY");
64+}
65+6266describe("handleChatEvent", () => {
6367it("returns null when payload is missing", () => {
6468const state = createState();
@@ -144,6 +148,20 @@ describe("handleChatEvent", () => {
144148expect(state.chatMessages).toEqual([]);
145149});
146150151+it.each(["no_reply", "ANNOUNCE_SKIP", "REPLY_SKIP"])(
152+"keeps plain-text %s final payload from another run without clearing active stream",
153+(text) => {
154+const state = createActiveStreamingState();
155+const payload = createOtherRunSilentFinalPayload(text);
156+157+expect(handleChatEvent(state, payload)).toBe(null);
158+expect(state.chatRunId).toBe("run-user");
159+expect(state.chatStream).toBe("Working...");
160+expect(state.chatStreamStartedAt).toBe(123);
161+expect(state.chatMessages).toEqual([payload.message]);
162+},
163+);
164+147165it("replaces the stream when a delta snapshot gets shorter", () => {
148166const state = createState({
149167sessionKey: "main",
@@ -440,6 +458,32 @@ describe("handleChatEvent", () => {
440458expect(state.chatStream).toBe(null);
441459});
442460461+it.each(["no_reply", "ANNOUNCE_SKIP", "REPLY_SKIP"])(
462+"keeps plain-text %s final payload from own run",
463+(text) => {
464+const state = createState({
465+sessionKey: "main",
466+chatRunId: "run-1",
467+chatStream: text,
468+chatStreamStartedAt: 100,
469+});
470+const payload: ChatEventPayload = {
471+runId: "run-1",
472+sessionKey: "main",
473+state: "final",
474+message: {
475+role: "assistant",
476+content: [{ type: "text", text }],
477+},
478+};
479+480+expect(handleChatEvent(state, payload)).toBe("final");
481+expect(state.chatMessages).toEqual([payload.message]);
482+expect(state.chatRunId).toBe(null);
483+expect(state.chatStream).toBe(null);
484+},
485+);
486+443487it("does not persist NO_REPLY stream text on final without message", () => {
444488const state = createState({
445489sessionKey: "main",
@@ -522,10 +566,13 @@ describe("handleChatEvent", () => {
522566});
523567524568describe("loadChatHistory", () => {
525-it("filters NO_REPLY assistant messages from history", async () => {
569+it("filters legacy silent assistant messages from history", async () => {
526570const messages = [
527571{ role: "user", content: [{ type: "text", text: "Hello" }] },
528572{ role: "assistant", content: [{ type: "text", text: "NO_REPLY" }] },
573+{ role: "assistant", content: [{ type: "text", text: "no_reply" }] },
574+{ role: "assistant", content: [{ type: "text", text: "ANNOUNCE_SKIP" }] },
575+{ role: "assistant", content: [{ type: "text", text: "REPLY_SKIP" }] },
529576{ role: "assistant", content: [{ type: "text", text: "Real answer" }] },
530577{ role: "assistant", text: " NO_REPLY " },
531578];
@@ -539,9 +586,12 @@ describe("loadChatHistory", () => {
539586540587await loadChatHistory(state);
541588542-expect(state.chatMessages).toHaveLength(2);
589+expect(state.chatMessages).toHaveLength(5);
543590expect(state.chatMessages[0]).toEqual(messages[0]);
544591expect(state.chatMessages[1]).toEqual(messages[2]);
592+expect(state.chatMessages[2]).toEqual(messages[3]);
593+expect(state.chatMessages[3]).toEqual(messages[4]);
594+expect(state.chatMessages[4]).toEqual(messages[5]);
545595expect(state.chatThinkingLevel).toBe("low");
546596expect(state.chatLoading).toBe(false);
547597});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。