





















@@ -247,6 +247,102 @@ describe("agent event handler", () => {
247247return payload;
248248}
249249250+it("injects isHeartbeat into agent broadcast payloads when present in run context", () => {
251+const harness = createHarness();
252+registerAgentRunContext("run-heartbeat-true", { sessionKey: "session-1", isHeartbeat: true });
253+registerAgentRunContext("run-heartbeat-false", { sessionKey: "session-2", isHeartbeat: false });
254+255+// 1. isHeartbeat: true
256+harness.handler({
257+runId: "run-heartbeat-true",
258+seq: 1,
259+stream: "assistant",
260+ts: 100,
261+data: { text: "hello" },
262+});
263+264+const agentPayload1 = harness.broadcast.mock.calls.find(
265+([event]) => event === "agent",
266+)?.[1] as Record<string, unknown>;
267+expect(agentPayload1).toBeDefined();
268+expect(agentPayload1.isHeartbeat).toBe(true);
269+270+// sessionKey is required for nodeSendToSession to be called
271+harness.chatRunState.registry.add("run-heartbeat-true", {
272+sessionKey: "session-1",
273+clientRunId: "run-heartbeat-true",
274+});
275+harness.handler({
276+runId: "run-heartbeat-true",
277+seq: 2,
278+stream: "assistant",
279+ts: 100,
280+data: { text: "hello" },
281+});
282+283+const nodeSendPayload1 = harness.nodeSendToSession.mock.calls.find(
284+([, event]) => event === "agent",
285+)?.[2] as Record<string, unknown>;
286+expect(nodeSendPayload1).toBeDefined();
287+expect(nodeSendPayload1.isHeartbeat).toBe(true);
288+289+harness.broadcast.mockClear();
290+harness.nodeSendToSession.mockClear();
291+292+// 2. isHeartbeat: false
293+harness.chatRunState.registry.add("run-heartbeat-false", {
294+sessionKey: "session-2",
295+clientRunId: "run-heartbeat-false",
296+});
297+harness.handler({
298+runId: "run-heartbeat-false",
299+seq: 1,
300+stream: "assistant",
301+ts: 101,
302+data: { text: "hello" },
303+});
304+305+const agentPayload2 = harness.broadcast.mock.calls.find(
306+([event]) => event === "agent",
307+)?.[1] as Record<string, unknown>;
308+expect(agentPayload2).toBeDefined();
309+expect(agentPayload2.isHeartbeat).toBe(false);
310+311+const nodeSendPayload2 = harness.nodeSendToSession.mock.calls.find(
312+([, event]) => event === "agent",
313+)?.[2] as Record<string, unknown>;
314+expect(nodeSendPayload2).toBeDefined();
315+expect(nodeSendPayload2.isHeartbeat).toBe(false);
316+317+harness.broadcast.mockClear();
318+harness.nodeSendToSession.mockClear();
319+320+// 3. isHeartbeat: undefined (absent)
321+harness.chatRunState.registry.add("run-normal", {
322+sessionKey: "session-3",
323+clientRunId: "run-normal",
324+});
325+harness.handler({
326+runId: "run-normal",
327+seq: 1,
328+stream: "assistant",
329+ts: 102,
330+data: { text: "hello" },
331+});
332+333+const normalBroadcast = harness.broadcast.mock.calls.find(
334+([event]) => event === "agent",
335+)?.[1] as Record<string, unknown>;
336+expect(normalBroadcast).toBeDefined();
337+expect("isHeartbeat" in normalBroadcast).toBe(false);
338+339+const normalNodeSend = harness.nodeSendToSession.mock.calls.find(
340+([, event]) => event === "agent",
341+)?.[2] as Record<string, unknown>;
342+expect(normalNodeSend).toBeDefined();
343+expect("isHeartbeat" in normalNodeSend).toBe(false);
344+});
345+250346it("emits chat delta for assistant text-only events", () => {
251347const { broadcast, nodeSendToSession, nowSpy } = emitRun1AssistantText(
252348createHarness({ now: 1_000 }),
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。