

























@@ -11,6 +11,7 @@ function createContext(
1111lastAssistant: unknown,
1212overrides?: {
1313onAgentEvent?: (event: unknown) => void;
14+onBeforeLifecycleTerminal?: () => void | Promise<void>;
1415onBlockReplyFlush?: () => void | Promise<void>;
1516},
1617): EmbeddedPiSubscribeContext {
@@ -21,6 +22,7 @@ function createContext(
2122config: {},
2223sessionKey: "agent:main:main",
2324onAgentEvent: overrides?.onAgentEvent,
25+onBeforeLifecycleTerminal: overrides?.onBeforeLifecycleTerminal,
2426 onBlockReply,
2527onBlockReplyFlush: overrides?.onBlockReplyFlush,
2628},
@@ -380,6 +382,90 @@ describe("handleAgentEnd", () => {
380382await endPromise;
381383});
382384385+it("runs the before-lifecycle callback before the lifecycle end event", async () => {
386+const order: string[] = [];
387+const onAgentEvent = vi.fn(() => {
388+order.push("event");
389+});
390+const onBeforeLifecycleTerminal = vi.fn(() => {
391+order.push("before");
392+});
393+const ctx = createContext(undefined, {
394+ onAgentEvent,
395+ onBeforeLifecycleTerminal,
396+});
397+398+await handleAgentEnd(ctx);
399+400+expect(order).toEqual(["before", "event"]);
401+expect(onBeforeLifecycleTerminal).toHaveBeenCalledTimes(1);
402+expect(onAgentEvent).toHaveBeenCalledWith({
403+stream: "lifecycle",
404+data: { phase: "end" },
405+});
406+});
407+408+it("runs an async before-lifecycle callback before the lifecycle end event", async () => {
409+const order: string[] = [];
410+const onAgentEvent = vi.fn(() => {
411+order.push("event");
412+});
413+const onBeforeLifecycleTerminal = vi.fn(() =>
414+Promise.resolve().then(() => {
415+order.push("before");
416+}),
417+);
418+const ctx = createContext(undefined, {
419+ onAgentEvent,
420+ onBeforeLifecycleTerminal,
421+});
422+423+await handleAgentEnd(ctx);
424+425+expect(order).toEqual(["before", "event"]);
426+expect(onBeforeLifecycleTerminal).toHaveBeenCalledTimes(1);
427+expect(onAgentEvent).toHaveBeenCalledWith({
428+stream: "lifecycle",
429+data: { phase: "end" },
430+});
431+});
432+433+it("still emits lifecycle terminal when sync before-lifecycle callback throws", async () => {
434+const onAgentEvent = vi.fn();
435+const onBeforeLifecycleTerminal = vi.fn(() => {
436+throw new Error("hook exploded");
437+});
438+const ctx = createContext(undefined, {
439+ onAgentEvent,
440+ onBeforeLifecycleTerminal,
441+});
442+443+await handleAgentEnd(ctx);
444+445+expect(onBeforeLifecycleTerminal).toHaveBeenCalledTimes(1);
446+expect(onAgentEvent).toHaveBeenCalledWith({
447+stream: "lifecycle",
448+data: { phase: "end" },
449+});
450+});
451+452+it("still emits lifecycle terminal when async before-lifecycle callback rejects", async () => {
453+const onAgentEvent = vi.fn();
454+const onBeforeLifecycleTerminal = vi.fn(() => Promise.reject(new Error("hook failed")));
455+const ctx = createContext(undefined, {
456+ onAgentEvent,
457+ onBeforeLifecycleTerminal,
458+});
459+460+await handleAgentEnd(ctx);
461+462+expect(onBeforeLifecycleTerminal).toHaveBeenCalledTimes(1);
463+expect(onAgentEvent).toHaveBeenCalledWith({
464+stream: "lifecycle",
465+data: { phase: "end" },
466+});
467+});
468+383469it("emits lifecycle end after async channel flush completes", async () => {
384470let resolveChannelFlush: (() => void) | undefined;
385471const onAgentEvent = vi.fn();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。