


























@@ -44,6 +44,7 @@ import {
4444createAgentEventHandler,
4545createChatRunState,
4646createSessionEventSubscriberRegistry,
47+createChatAbortMarker,
4748createSessionMessageSubscriberRegistry,
4849createToolEventRecipientRegistry,
4950type AgentEventHandlerOptions,
@@ -2762,7 +2763,7 @@ describe("agent event handler", () => {
27622763sessionKey: "session-aborted",
27632764clientRunId: "client-aborted",
27642765});
2765-chatRunState.abortedRuns.set("client-aborted", 1_000);
2766+chatRunState.abortedRuns.set("client-aborted", createChatAbortMarker());
2766276727672768handler({
27682769runId: "run-aborted",
@@ -2777,6 +2778,81 @@ describe("agent event handler", () => {
27772778expect(chatBroadcastCalls(broadcast)).toHaveLength(0);
27782779});
277927802781+it.each([
2782+{
2783+name: "older timestamp",
2784+marker: () => 1_000,
2785+},
2786+{
2787+name: "same-millisecond older sequence",
2788+marker: () => ({ abortedAtMs: 2_000, sequence: -1 }),
2789+},
2790+])(
2791+"ignores stale aborted markers from older same-key runs for fresh chat lifecycle events ($name)",
2792+({ marker }) => {
2793+const { broadcast, nodeSendToSession, chatRunState, handler } = createHarness({ now: 2_000 });
2794+chatRunState.abortedRuns.set("client-stale-abort", marker());
2795+chatRunState.registry.add("run-stale-abort", {
2796+sessionKey: "session-stale-abort",
2797+clientRunId: "client-stale-abort",
2798+});
2799+2800+handler({
2801+runId: "run-stale-abort",
2802+seq: 1,
2803+stream: "assistant",
2804+ts: 2_100,
2805+data: { text: "Fresh output", delta: "Fresh output" },
2806+});
2807+handler({
2808+runId: "run-stale-abort",
2809+seq: 2,
2810+stream: "lifecycle",
2811+ts: 2_200,
2812+data: { phase: "end" },
2813+});
2814+2815+const chatCalls = chatBroadcastCalls(broadcast);
2816+expect(chatCalls).toHaveLength(2);
2817+const deltaPayload = chatCalls[0][1];
2818+const finalPayload = chatCalls[1][1];
2819+expect(deltaPayload.state).toBe("delta");
2820+expect(finalPayload.state).toBe("final");
2821+expect(sessionChatCalls(nodeSendToSession)).toHaveLength(2);
2822+expect(chatRunState.abortedRuns.has("client-stale-abort")).toBe(true);
2823+expect(chatRunState.registry.peek("run-stale-abort")).toBeUndefined();
2824+},
2825+);
2826+2827+it("honors same-millisecond abort markers from the current same-key run", () => {
2828+const { broadcast, nodeSendToSession, chatRunState, handler } = createHarness({ now: 3_000 });
2829+chatRunState.registry.add("run-current-abort", {
2830+sessionKey: "session-current-abort",
2831+clientRunId: "client-current-abort",
2832+});
2833+chatRunState.abortedRuns.set("client-current-abort", createChatAbortMarker());
2834+2835+handler({
2836+runId: "run-current-abort",
2837+seq: 1,
2838+stream: "assistant",
2839+ts: 3_100,
2840+data: { text: "Suppressed output", delta: "Suppressed output" },
2841+});
2842+handler({
2843+runId: "run-current-abort",
2844+seq: 2,
2845+stream: "lifecycle",
2846+ts: 3_200,
2847+data: { phase: "end", aborted: true, stopReason: "rpc" },
2848+});
2849+2850+expect(chatBroadcastCalls(broadcast)).toHaveLength(0);
2851+expect(sessionChatCalls(nodeSendToSession)).toHaveLength(0);
2852+expect(chatRunState.abortedRuns.has("client-current-abort")).toBe(true);
2853+expect(chatRunState.registry.peek("run-current-abort")).toBeUndefined();
2854+});
2855+27802856it("keeps live session setting metadata at the top level for lifecycle updates", async () => {
27812857vi.mocked(loadGatewaySessionRow).mockReturnValue({
27822858key: "session-finished",
@@ -3166,7 +3242,7 @@ describe("agent event handler", () => {
31663242data: { phase: "error", error: "provider failed" },
31673243});
316832443169-expect(chatRunState.registry.peek("run-fallback-retry")).toEqual({
3245+expect(chatRunState.registry.peek("run-fallback-retry")).toMatchObject({
31703246sessionKey: "session-fallback",
31713247clientRunId: "run-fallback-client",
31723248});
@@ -3189,7 +3265,7 @@ describe("agent event handler", () => {
3189326531903266vi.advanceTimersByTime(100);
319132673192-expect(chatRunState.registry.peek("run-fallback-retry")).toEqual({
3268+expect(chatRunState.registry.peek("run-fallback-retry")).toMatchObject({
31933269sessionKey: "session-fallback",
31943270clientRunId: "run-fallback-client",
31953271});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。