




















@@ -2890,6 +2890,109 @@ describe("deliverSubagentAnnouncement completion delivery", () => {
28902890);
28912891});
289228922893+it("directly delivers generated media after active wake failure when requester handoff locks", async () => {
2894+const callGateway = vi.fn(async () => {
2895+throw new Error(
2896+"SessionWriteLockTimeoutError: session file locked (timeout 60000ms): pid=43",
2897+);
2898+}) as unknown as typeof runtimeCallGateway;
2899+const queueEmbeddedAgentMessageWithOutcome = createQueueOutcomeSequenceMock([
2900+"transcript_commit_wait_unsupported",
2901+"no_active_run",
2902+]);
2903+const sendMessage = createSendMessageMock();
2904+const result = await deliverSlackChannelAnnouncement({
2905+ callGateway,
2906+ sendMessage,
2907+ queueEmbeddedAgentMessageWithOutcome,
2908+sessionId: "requester-session-channel",
2909+isActive: true,
2910+expectsCompletionMessage: true,
2911+directIdempotencyKey: "announce-channel-media-handoff-locked",
2912+sourceTool: "image_generate",
2913+internalEvents: [
2914+{
2915+type: "task_completion",
2916+source: "image_generation",
2917+childSessionKey: "image_generate:task-locked",
2918+childSessionId: "task-locked",
2919+announceType: "image generation task",
2920+taskLabel: "locked handoff image",
2921+status: "ok",
2922+statusLabel: "completed successfully",
2923+result: "Generated 1 image.\nMEDIA:/tmp/generated-locked.png",
2924+mediaUrls: ["/tmp/generated-locked.png"],
2925+replyInstruction:
2926+"Tell the user the image is ready and send it through the message tool.",
2927+},
2928+],
2929+});
2930+2931+expectRecordFields(result, {
2932+delivered: true,
2933+path: "direct",
2934+});
2935+expect(queueEmbeddedAgentMessageWithOutcome).toHaveBeenCalledTimes(2);
2936+expect(callGateway).toHaveBeenCalledTimes(1);
2937+expect(sendMessage).toHaveBeenCalledWith(
2938+expect.objectContaining({
2939+channel: "slack",
2940+accountId: "acct-1",
2941+to: "channel:C123",
2942+content: "The generated image is ready.",
2943+mediaUrls: ["/tmp/generated-locked.png"],
2944+idempotencyKey: "announce-channel-media-handoff-locked:generated-media-direct",
2945+}),
2946+);
2947+});
2948+2949+it("keeps generic requester handoff errors visible after active wake failure", async () => {
2950+const callGateway = vi.fn(async () => {
2951+throw new Error("requester handoff exploded after dispatch");
2952+}) as unknown as typeof runtimeCallGateway;
2953+const queueEmbeddedAgentMessageWithOutcome = createQueueOutcomeSequenceMock([
2954+"transcript_commit_wait_unsupported",
2955+"no_active_run",
2956+]);
2957+const sendMessage = createSendMessageMock();
2958+2959+const result = await deliverSlackChannelAnnouncement({
2960+ callGateway,
2961+ sendMessage,
2962+ queueEmbeddedAgentMessageWithOutcome,
2963+sessionId: "requester-session-channel",
2964+isActive: true,
2965+expectsCompletionMessage: true,
2966+directIdempotencyKey: "announce-channel-media-handoff-error",
2967+sourceTool: "image_generate",
2968+internalEvents: [
2969+{
2970+type: "task_completion",
2971+source: "image_generation",
2972+childSessionKey: "image_generate:task-error",
2973+childSessionId: "task-error",
2974+announceType: "image generation task",
2975+taskLabel: "errored handoff image",
2976+status: "ok",
2977+statusLabel: "completed successfully",
2978+result: "Generated 1 image.\nMEDIA:/tmp/generated-error.png",
2979+mediaUrls: ["/tmp/generated-error.png"],
2980+replyInstruction:
2981+"Tell the user the image is ready and send it through the message tool.",
2982+},
2983+],
2984+});
2985+2986+expectRecordFields(result, {
2987+delivered: false,
2988+path: "direct",
2989+error: "requester handoff exploded after dispatch",
2990+});
2991+expect(queueEmbeddedAgentMessageWithOutcome).toHaveBeenCalled();
2992+expect(callGateway).toHaveBeenCalledTimes(1);
2993+expect(sendMessage).not.toHaveBeenCalled();
2994+});
2995+28932996it("directly delivers stale isolated cron run media completions", async () => {
28942997const callGateway = createGatewayMock();
28952998const sendMessage = createSendMessageMock();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。