

























@@ -111,6 +111,134 @@ describe("runSessionsSendA2AFlow announce delivery", () => {
111111expect(sendParams.threadId).toBeUndefined();
112112});
113113114+it("bypasses the announce decider for same-session channel replies", async () => {
115+await runSessionsSendA2AFlow({
116+targetSessionKey: "agent:main:discord:channel:target-room",
117+displayKey: "agent:main:discord:channel:target-room",
118+message: "Test message",
119+announceTimeoutMs: 10_000,
120+maxPingPongTurns: 2,
121+requesterSessionKey: "agent:main:discord:channel:target-room",
122+requesterChannel: "discord",
123+roundOneReply: "Substantive channel reply",
124+});
125+126+expect(runAgentStep).not.toHaveBeenCalled();
127+const sendCall = requireGatewayCall("send");
128+const sendParams = sendCall.params as Record<string, unknown>;
129+expect(sendParams.channel).toBe("discord");
130+expect(sendParams.to).toBe("channel:target-room");
131+expect(sendParams.message).toBe("Substantive channel reply");
132+});
133+134+it("bypasses the announce decider for delayed same-session channel replies", async () => {
135+vi.mocked(readLatestAssistantReplySnapshot).mockResolvedValueOnce({
136+text: "Delayed channel reply",
137+fingerprint: "delayed-channel-reply",
138+});
139+140+await runSessionsSendA2AFlow({
141+targetSessionKey: "agent:main:discord:channel:target-room",
142+displayKey: "agent:main:discord:channel:target-room",
143+message: "Test message",
144+announceTimeoutMs: 10_000,
145+maxPingPongTurns: 2,
146+requesterSessionKey: "agent:main:discord:channel:target-room",
147+requesterChannel: "discord",
148+baseline: {
149+text: "Previous channel reply",
150+fingerprint: "previous-channel-reply",
151+},
152+waitRunId: "run-delayed-channel",
153+});
154+155+expect(firstMockArg(vi.mocked(waitForAgentRun), "agent run wait").runId).toBe(
156+"run-delayed-channel",
157+);
158+expect(
159+firstMockArg(vi.mocked(readLatestAssistantReplySnapshot), "assistant reply snapshot")
160+.sessionKey,
161+).toBe("agent:main:discord:channel:target-room");
162+expect(runAgentStep).not.toHaveBeenCalled();
163+const sendCall = requireGatewayCall("send");
164+const sendParams = sendCall.params as Record<string, unknown>;
165+expect(sendParams.channel).toBe("discord");
166+expect(sendParams.to).toBe("channel:target-room");
167+expect(sendParams.message).toBe("Delayed channel reply");
168+});
169+170+it("does not direct-deliver a delayed same-session reply that matches the baseline", async () => {
171+vi.mocked(readLatestAssistantReplySnapshot).mockResolvedValueOnce({
172+text: "Previous channel reply",
173+fingerprint: "previous-channel-reply",
174+});
175+176+await runSessionsSendA2AFlow({
177+targetSessionKey: "agent:main:discord:channel:target-room",
178+displayKey: "agent:main:discord:channel:target-room",
179+message: "Test message",
180+announceTimeoutMs: 10_000,
181+maxPingPongTurns: 2,
182+requesterSessionKey: "agent:main:discord:channel:target-room",
183+requesterChannel: "discord",
184+baseline: {
185+text: "Previous channel reply",
186+fingerprint: "previous-channel-reply",
187+},
188+waitRunId: "run-delayed-channel",
189+});
190+191+expect(firstMockArg(vi.mocked(waitForAgentRun), "agent run wait").runId).toBe(
192+"run-delayed-channel",
193+);
194+expect(runAgentStep).not.toHaveBeenCalled();
195+expect(gatewayCalls.find((call) => call.method === "send")).toBeUndefined();
196+});
197+198+it("does not direct-deliver a delayed same-session reply without a baseline", async () => {
199+vi.mocked(readLatestAssistantReplySnapshot).mockResolvedValueOnce({
200+text: "Maybe stale channel reply",
201+fingerprint: "maybe-stale-channel-reply",
202+});
203+204+await runSessionsSendA2AFlow({
205+targetSessionKey: "agent:main:discord:channel:target-room",
206+displayKey: "agent:main:discord:channel:target-room",
207+message: "Test message",
208+announceTimeoutMs: 10_000,
209+maxPingPongTurns: 2,
210+requesterSessionKey: "agent:main:discord:channel:target-room",
211+requesterChannel: "discord",
212+waitRunId: "run-delayed-channel",
213+});
214+215+expect(firstMockArg(vi.mocked(waitForAgentRun), "agent run wait").runId).toBe(
216+"run-delayed-channel",
217+);
218+expect(runAgentStep).not.toHaveBeenCalled();
219+expect(gatewayCalls.find((call) => call.method === "send")).toBeUndefined();
220+});
221+222+it("keeps the announce decider for same-session sends from a different channel", async () => {
223+vi.mocked(runAgentStep).mockResolvedValueOnce("ANNOUNCE_SKIP");
224+225+await runSessionsSendA2AFlow({
226+targetSessionKey: "agent:main:discord:channel:target-room",
227+displayKey: "agent:main:discord:channel:target-room",
228+message: "Test message",
229+announceTimeoutMs: 10_000,
230+maxPingPongTurns: 2,
231+requesterSessionKey: "agent:main:discord:channel:target-room",
232+requesterChannel: "webchat",
233+roundOneReply: "Substantive channel reply",
234+});
235+236+expect(runAgentStep).toHaveBeenCalledTimes(1);
237+const stepInput = firstMockArg(vi.mocked(runAgentStep), "agent step");
238+expect(stepInput.message).toBe("Agent-to-agent announce step.");
239+expect(gatewayCalls.find((call) => call.method === "send")).toBeUndefined();
240+});
241+114242it.each([
115243{
116244source: "deliveryContext.accountId",
@@ -207,7 +335,7 @@ describe("runSessionsSendA2AFlow announce delivery", () => {
207335expect(gatewayCalls.find((call) => call.method === "send")).toBeUndefined();
208336});
209337210-it.each(["NO_REPLY", "HEARTBEAT_OK"])(
338+it.each(["NO_REPLY", "HEARTBEAT_OK", "ANNOUNCE_SKIP"])(
211339"suppresses exact announce control reply %s before channel delivery",
212340async (announceReply) => {
213341vi.mocked(runAgentStep).mockResolvedValueOnce(announceReply);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。