

























@@ -60,6 +60,7 @@ async function deliverSlackThreadAnnouncement(params: {
6060queueEmbeddedPiMessage?: (sessionId: string, message: string) => boolean;
6161sendMessage?: typeof runtimeSendMessage;
6262internalEvents?: AgentInternalEvent[];
63+sourceTool?: string;
6364}) {
6465__testing.setDepsForTest({
6566callGateway: params.callGateway,
@@ -88,13 +89,15 @@ async function deliverSlackThreadAnnouncement(params: {
8889bestEffortDeliver: true,
8990directIdempotencyKey: params.directIdempotencyKey,
9091internalEvents: params.internalEvents,
92+sourceTool: params.sourceTool,
9193});
9294}
93959496async function deliverDiscordDirectMessageCompletion(params: {
9597callGateway: typeof runtimeCallGateway;
9698sendMessage?: typeof runtimeSendMessage;
9799internalEvents?: AgentInternalEvent[];
100+sourceTool?: string;
98101}) {
99102const origin = {
100103channel: "discord",
@@ -125,6 +128,7 @@ async function deliverDiscordDirectMessageCompletion(params: {
125128bestEffortDeliver: true,
126129directIdempotencyKey: "announce-dm-fallback-empty",
127130internalEvents: params.internalEvents,
131+sourceTool: params.sourceTool,
128132});
129133}
130134@@ -185,6 +189,7 @@ async function deliverSlackChannelAnnouncement(params: {
185189queueEmbeddedPiMessage?: (sessionId: string, message: string) => boolean;
186190sendMessage?: typeof runtimeSendMessage;
187191internalEvents?: AgentInternalEvent[];
192+sourceTool?: string;
188193}) {
189194const origin = {
190195channel: "slack",
@@ -219,6 +224,7 @@ async function deliverSlackChannelAnnouncement(params: {
219224bestEffortDeliver: true,
220225directIdempotencyKey: params.directIdempotencyKey,
221226internalEvents: params.internalEvents,
227+sourceTool: params.sourceTool,
222228});
223229}
224230@@ -1141,6 +1147,119 @@ describe("deliverSubagentAnnouncement completion delivery", () => {
11411147expect(sendMessage).not.toHaveBeenCalled();
11421148});
114311491150+it("delivers generated media completions through the announce agent in automatic DMs", async () => {
1151+const callGateway = createGatewayMock({
1152+result: {
1153+payloads: [
1154+{
1155+text: "The track is ready.",
1156+mediaUrls: ["/tmp/generated-night-drive.mp3"],
1157+},
1158+],
1159+},
1160+});
1161+const sendMessage = createSendMessageMock();
1162+const result = await deliverDiscordDirectMessageCompletion({
1163+ callGateway,
1164+ sendMessage,
1165+sourceTool: "music_generate",
1166+internalEvents: [
1167+{
1168+type: "task_completion",
1169+source: "music_generation",
1170+childSessionKey: "music_generate:task-123",
1171+childSessionId: "task-123",
1172+announceType: "music generation task",
1173+taskLabel: "night-drive synthwave",
1174+status: "ok",
1175+statusLabel: "completed successfully",
1176+result: "Generated 1 track.\nMEDIA:/tmp/generated-night-drive.mp3",
1177+mediaUrls: ["/tmp/generated-night-drive.mp3"],
1178+replyInstruction:
1179+"Tell the user the music is ready. If visible source delivery requires the message tool, send it there with the generated media attached.",
1180+},
1181+],
1182+});
1183+1184+expect(result).toEqual(
1185+expect.objectContaining({
1186+delivered: true,
1187+path: "direct",
1188+}),
1189+);
1190+expect(callGateway).toHaveBeenCalledWith(
1191+expect.objectContaining({
1192+method: "agent",
1193+params: expect.objectContaining({
1194+deliver: true,
1195+channel: "discord",
1196+accountId: "acct-1",
1197+to: "dm:U123",
1198+threadId: undefined,
1199+}),
1200+}),
1201+);
1202+expect(sendMessage).not.toHaveBeenCalled();
1203+});
1204+1205+it("requires message-tool delivery for generated media completions in default group routes", async () => {
1206+const callGateway = createGatewayMock({
1207+result: {
1208+payloads: [
1209+{
1210+text: "The track is ready.",
1211+},
1212+],
1213+},
1214+});
1215+const sendMessage = createSendMessageMock();
1216+const result = await deliverSlackChannelAnnouncement({
1217+ callGateway,
1218+ sendMessage,
1219+sessionId: "requester-session-channel",
1220+isActive: false,
1221+expectsCompletionMessage: true,
1222+directIdempotencyKey: "announce-channel-media-message-tool",
1223+sourceTool: "music_generate",
1224+internalEvents: [
1225+{
1226+type: "task_completion",
1227+source: "music_generation",
1228+childSessionKey: "music_generate:task-123",
1229+childSessionId: "task-123",
1230+announceType: "music generation task",
1231+taskLabel: "night-drive synthwave",
1232+status: "ok",
1233+statusLabel: "completed successfully",
1234+result: "Generated 1 track.\nMEDIA:/tmp/generated-night-drive.mp3",
1235+mediaUrls: ["/tmp/generated-night-drive.mp3"],
1236+replyInstruction:
1237+"Tell the user the music is ready. If visible source delivery requires the message tool, send it there with the generated media attached.",
1238+},
1239+],
1240+});
1241+1242+expect(result).toEqual(
1243+expect.objectContaining({
1244+delivered: false,
1245+path: "direct",
1246+}),
1247+);
1248+expect(callGateway).toHaveBeenCalledWith(
1249+expect.objectContaining({
1250+method: "agent",
1251+params: expect.objectContaining({
1252+deliver: false,
1253+channel: "slack",
1254+accountId: "acct-1",
1255+to: "channel:C123",
1256+threadId: undefined,
1257+}),
1258+}),
1259+);
1260+expect(sendMessage).not.toHaveBeenCalled();
1261+});
1262+11441263it("uses a direct channel fallback when announce-agent returns no visible output", async () => {
11451264const callGateway = createGatewayMock({
11461265result: {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。