























@@ -721,9 +721,7 @@ describe("tui-event-handlers: streaming watchdog", () => {
721721722722expect(setActivityStatus).toHaveBeenLastCalledWith("idle");
723723expect(state.activeChatRunId).toBeNull();
724-expect(chatLog.addSystem).toHaveBeenCalledWith(
725-expect.stringContaining("streaming watchdog"),
726-);
724+expect(chatLog.addSystem).toHaveBeenCalledWith(expect.stringContaining("streaming watchdog"));
727725728726handlers.dispose?.();
729727});
@@ -751,8 +749,6 @@ describe("tui-event-handlers: streaming watchdog", () => {
751749752750vi.advanceTimersByTime(3_000);
753751754-// 6s total, but the latest delta was only 3s ago, so the watchdog must not
755-// have fired yet.
756752expect(setActivityStatus).not.toHaveBeenCalledWith("idle");
757753expect(state.activeChatRunId).toBe("run-flow");
758754@@ -784,8 +780,6 @@ describe("tui-event-handlers: streaming watchdog", () => {
784780785781vi.advanceTimersByTime(10_000);
786782787-// After a normal final, the watchdog timer must have been cancelled and
788-// cannot later re-overwrite the status or emit the warning banner.
789783const statusCalls = setActivityStatus.mock.calls.map((c) => c[0]);
790784expect(statusCalls.filter((s) => s === "idle").length).toBe(1);
791785expect(chatLog.addSystem).not.toHaveBeenCalledWith(
@@ -817,6 +811,47 @@ describe("tui-event-handlers: streaming watchdog", () => {
817811handlers.dispose?.();
818812});
819813814+it("does not let an older run steal the active run watchdog", () => {
815+const { state, chatLog, setActivityStatus, handlers } = createHarness({
816+streamingWatchdogMs: 5_000,
817+});
818+819+handlers.handleChatEvent({
820+runId: "run-old",
821+sessionKey: state.currentSessionKey,
822+state: "delta",
823+message: { content: "old" },
824+} satisfies ChatEvent);
825+826+vi.advanceTimersByTime(5_001);
827+expect(state.activeChatRunId).toBeNull();
828+829+handlers.handleChatEvent({
830+runId: "run-new",
831+sessionKey: state.currentSessionKey,
832+state: "delta",
833+message: { content: "new" },
834+} satisfies ChatEvent);
835+expect(state.activeChatRunId).toBe("run-new");
836+837+vi.advanceTimersByTime(3_000);
838+839+handlers.handleChatEvent({
840+runId: "run-old",
841+sessionKey: state.currentSessionKey,
842+state: "delta",
843+message: { content: "old again" },
844+} satisfies ChatEvent);
845+846+vi.advanceTimersByTime(2_001);
847+848+expect(setActivityStatus).toHaveBeenLastCalledWith("idle");
849+expect(state.activeChatRunId).toBeNull();
850+expect(chatLog.addSystem).toHaveBeenCalledTimes(2);
851+852+handlers.dispose?.();
853+});
854+820855it("dispose clears a pending watchdog without firing it", () => {
821856const { setActivityStatus, chatLog, handlers, state } = createHarness({
822857streamingWatchdogMs: 5_000,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。