


























@@ -107,6 +107,61 @@ function mockPendingMessagePresentationWarningOutcome() {
107107});
108108}
109109110+function requireRecord(value: unknown, label: string): Record<string, unknown> {
111+if (typeof value !== "object" || value === null || Array.isArray(value)) {
112+throw new Error(`expected ${label} to be an object`);
113+}
114+return value as Record<string, unknown>;
115+}
116+117+function expectRecordFields(
118+value: unknown,
119+expected: Record<string, unknown>,
120+label: string,
121+): Record<string, unknown> {
122+const record = requireRecord(value, label);
123+for (const [key, expectedValue] of Object.entries(expected)) {
124+expect(record[key], `${label}.${key}`).toEqual(expectedValue);
125+}
126+return record;
127+}
128+129+function getMockCallArg(
130+mock: { mock: { calls: readonly unknown[][] } },
131+callIndex: number,
132+argIndex: number,
133+label: string,
134+): unknown {
135+const call = (mock.mock.calls as unknown[][])[callIndex];
136+if (!call) {
137+throw new Error(`expected ${label} call ${callIndex}`);
138+}
139+return call[argIndex];
140+}
141+142+function expectEmbeddedRunFields(expected: Record<string, unknown>): Record<string, unknown> {
143+return expectRecordFields(
144+getMockCallArg(runEmbeddedPiAgentMock, 0, 0, "embedded run"),
145+expected,
146+"embedded run params",
147+);
148+}
149+150+function expectDispatchFields(expected: Record<string, unknown>): Record<string, unknown> {
151+return expectRecordFields(
152+getMockCallArg(dispatchCronDeliveryMock, 0, 0, "cron delivery dispatch"),
153+expected,
154+"cron delivery dispatch params",
155+);
156+}
157+158+function expectDeliveryFields(
159+delivery: unknown,
160+expected: Record<string, unknown>,
161+): Record<string, unknown> {
162+return expectRecordFields(delivery, expected, "cron delivery result");
163+}
164+110165describe("runCronIsolatedAgentTurn message tool policy", () => {
111166let previousFastTestEnv: string | undefined;
112167@@ -157,7 +212,7 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
157212158213expect(resolveDeliveryTargetMock).toHaveBeenCalledTimes(1);
159214expect(runEmbeddedPiAgentMock).toHaveBeenCalledTimes(1);
160-expect(runEmbeddedPiAgentMock.mock.calls[0]?.[0]).toMatchObject({
215+expectEmbeddedRunFields({
161216disableMessageTool: false,
162217forceMessageTool: true,
163218messageChannel: "messagechat",
@@ -180,21 +235,17 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
180235});
181236182237expect(dispatchCronDeliveryMock).toHaveBeenCalledTimes(1);
183-expect(dispatchCronDeliveryMock.mock.calls[0]?.[0]).toEqual(
184-expect.objectContaining({
185-deliveryRequested: true,
186-skipMessagingToolDelivery: true,
187-}),
188-);
189-expect(result.delivery).toEqual(
190-expect.objectContaining({
191-intended: { channel: "messagechat", to: "123", source: "explicit" },
192-resolved: { ok: true, channel: "messagechat", to: "123", source: "explicit" },
193-messageToolSentTo: [{ channel: "messagechat", to: "123" }],
194-fallbackUsed: false,
195-delivered: true,
196-}),
197-);
238+expectDispatchFields({
239+deliveryRequested: true,
240+skipMessagingToolDelivery: true,
241+});
242+expectDeliveryFields(result.delivery, {
243+intended: { channel: "messagechat", to: "123", source: "explicit" },
244+resolved: { ok: true, channel: "messagechat", to: "123", source: "explicit" },
245+messageToolSentTo: [{ channel: "messagechat", to: "123" }],
246+fallbackUsed: false,
247+delivered: true,
248+});
198249}
199250200251beforeEach(() => {
@@ -301,7 +352,7 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
301352302353expect(resolveDeliveryTargetMock).not.toHaveBeenCalled();
303354expect(runEmbeddedPiAgentMock).toHaveBeenCalledTimes(1);
304-expect(runEmbeddedPiAgentMock.mock.calls[0]?.[0]).toMatchObject({
355+expectEmbeddedRunFields({
305356disableMessageTool: false,
306357forceMessageTool: true,
307358});
@@ -338,7 +389,7 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
338389});
339390340391expect(runEmbeddedPiAgentMock).toHaveBeenCalledTimes(1);
341-expect(runEmbeddedPiAgentMock.mock.calls[0]?.[0]).toMatchObject({
392+expectEmbeddedRunFields({
342393disableMessageTool: false,
343394forceMessageTool: true,
344395messageChannel: "topicchat",
@@ -382,25 +433,23 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
382433});
383434384435expect(runEmbeddedPiAgentMock).toHaveBeenCalledTimes(1);
385-expect(runEmbeddedPiAgentMock.mock.calls[0]?.[0]).toMatchObject({
436+expectEmbeddedRunFields({
386437disableMessageTool: false,
387438messageChannel: "topicchat",
388439messageTo: "room#42",
389440messageThreadId: 42,
390441currentChannelId: "room#42",
391442});
392-expect(result.delivery).toEqual(
393-expect.objectContaining({
394-intended: { channel: "topicchat", to: "room#42", threadId: 42, source: "explicit" },
395-resolved: {
396-ok: true,
397-channel: "topicchat",
398-to: "room#42",
399-threadId: 42,
400-source: "explicit",
401-},
402-}),
403-);
443+expectDeliveryFields(result.delivery, {
444+intended: { channel: "topicchat", to: "room#42", threadId: 42, source: "explicit" },
445+resolved: {
446+ok: true,
447+channel: "topicchat",
448+to: "room#42",
449+threadId: 42,
450+source: "explicit",
451+},
452+});
404453});
405454406455it('does not resolve implicit "last" context for bare delivery.mode none', async () => {
@@ -425,7 +474,7 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
425474426475expect(resolveDeliveryTargetMock).not.toHaveBeenCalled();
427476expect(runEmbeddedPiAgentMock).toHaveBeenCalledTimes(1);
428-expect(runEmbeddedPiAgentMock.mock.calls[0]?.[0]).toMatchObject({
477+expectEmbeddedRunFields({
429478disableMessageTool: false,
430479forceMessageTool: true,
431480});
@@ -461,7 +510,7 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
461510await executor.runPrompt("send a message");
462511463512expect(runEmbeddedPiAgentMock).toHaveBeenCalledTimes(1);
464-expect(runEmbeddedPiAgentMock.mock.calls[0]?.[0]).toMatchObject({
513+expectEmbeddedRunFields({
465514messageChannel: "topicchat",
466515agentAccountId: "ops",
467516messageTo: "room#42",
@@ -484,7 +533,7 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
484533await executor.runPrompt("send a message");
485534486535expect(runEmbeddedPiAgentMock).toHaveBeenCalledTimes(1);
487-expect(runEmbeddedPiAgentMock.mock.calls[0]?.[0]).toMatchObject({
536+expectEmbeddedRunFields({
488537messageChannel: "topicchat",
489538agentAccountId: "ops",
490539messageTo: "room",
@@ -567,12 +616,10 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
567616});
568617569618expect(dispatchCronDeliveryMock).toHaveBeenCalledTimes(1);
570-expect(dispatchCronDeliveryMock.mock.calls[0]?.[0]).toEqual(
571-expect.objectContaining({
572-deliveryRequested: true,
573-skipHeartbeatDelivery: true,
574-}),
575-);
619+expectDispatchFields({
620+deliveryRequested: true,
621+skipHeartbeatDelivery: true,
622+});
576623});
577624578625it("skips cron fallback delivery when the message tool already sent to the same target", async () => {
@@ -606,12 +653,10 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
606653}),
607654});
608655609-expect(result.delivery).toEqual(
610-expect.objectContaining({
611-resolved: { ok: true, channel: "messagechat", to: "123", source: "explicit" },
612-messageToolSentTo: [{ channel: "messagechat", to: "123" }],
613-}),
614-);
656+expectDeliveryFields(result.delivery, {
657+resolved: { ok: true, channel: "messagechat", to: "123", source: "explicit" },
658+messageToolSentTo: [{ channel: "messagechat", to: "123" }],
659+});
615660});
616661617662it("preserves accountId when rewriting generic message provider to resolved channel", async () => {
@@ -633,11 +678,9 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
633678}),
634679});
635680636-expect(result.delivery).toEqual(
637-expect.objectContaining({
638-messageToolSentTo: [{ channel: "messagechat", to: "123", accountId: "bot-a" }],
639-}),
640-);
681+expectDeliveryFields(result.delivery, {
682+messageToolSentTo: [{ channel: "messagechat", to: "123", accountId: "bot-a" }],
683+});
641684});
642685643686it("rewrites generic message provider when tool send omits accountId (tool fills at exec)", async () => {
@@ -657,11 +700,9 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
657700}),
658701});
659702660-expect(result.delivery).toEqual(
661-expect.objectContaining({
662-messageToolSentTo: [{ channel: "messagechat", to: "123" }],
663-}),
664-);
703+expectDeliveryFields(result.delivery, {
704+messageToolSentTo: [{ channel: "messagechat", to: "123" }],
705+});
665706});
666707667708it("does not rewrite generic message provider when tool names a different accountId (spoof guard)", async () => {
@@ -683,11 +724,9 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
683724}),
684725});
685726686-expect(result.delivery).toEqual(
687-expect.objectContaining({
688-messageToolSentTo: [{ channel: "message", to: "123", accountId: "bot-b" }],
689-}),
690-);
727+expectDeliveryFields(result.delivery, {
728+messageToolSentTo: [{ channel: "message", to: "123", accountId: "bot-b" }],
729+});
691730});
692731693732it("does not mark message tool delivery as matched when cron target resolution failed", async () => {
@@ -713,25 +752,25 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
713752const result = await runCronIsolatedAgentTurn(makeParams());
714753715754expect(dispatchCronDeliveryMock).toHaveBeenCalledTimes(1);
716-expect(dispatchCronDeliveryMock.mock.calls[0]?.[0]).toEqual(
717-expect.objectContaining({
718- deliveryRequested: true,
719- skipMessagingToolDelivery: false,
720- unverifiedMessagingToolDelivery: true,
721- }),
722-);
723-expect(result.delivery).toEqual(
724-expect.objectContaining({
725- intended: { channel: "last", to: null, source: "last" },
726- resolved: expect.objectContaining({
727- ok: false,
728- source: "last",
729- error: "sessionKey is required to resolve delivery.channel=last",
730-}),
731-messageToolSentTo: [{ channel: "messagechat", to: "123" }],
732-fallbackUsed: false,
733- delivered: false,
734-}),
755+expectDispatchFields({
756+deliveryRequested: true,
757+skipMessagingToolDelivery: false,
758+unverifiedMessagingToolDelivery: true,
759+});
760+const delivery = expectDeliveryFields(result.delivery, {
761+ intended: { channel: "last", to: null, source: "last" },
762+ messageToolSentTo: [{ channel: "messagechat", to: "123" }],
763+fallbackUsed: false,
764+delivered: false,
765+});
766+expectRecordFields(
767+delivery.resolved,
768+{
769+ok: false,
770+source: "last",
771+error: "sessionKey is required to resolve delivery.channel=last",
772+},
773+"cron delivery resolved target",
735774);
736775});
737776@@ -749,23 +788,19 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
749788const result = await runCronIsolatedAgentTurn(makeParams());
750789751790expect(dispatchCronDeliveryMock).toHaveBeenCalledTimes(1);
752-expect(dispatchCronDeliveryMock.mock.calls[0]?.[0]).toEqual(
753-expect.objectContaining({
754-deliveryRequested: false,
755-skipMessagingToolDelivery: false,
756-unverifiedMessagingToolDelivery: true,
757-}),
758-);
791+expectDispatchFields({
792+deliveryRequested: false,
793+skipMessagingToolDelivery: false,
794+unverifiedMessagingToolDelivery: true,
795+});
759796expect(result.delivered).toBe(false);
760797expect(result.deliveryAttempted).toBe(false);
761-expect(result.delivery).toEqual(
762-expect.objectContaining({
763-intended: { channel: "last", to: null, source: "last" },
764-messageToolSentTo: [{ channel: "messagechat", to: "123" }],
765-fallbackUsed: false,
766-delivered: false,
767-}),
768-);
798+expectDeliveryFields(result.delivery, {
799+intended: { channel: "last", to: null, source: "last" },
800+messageToolSentTo: [{ channel: "messagechat", to: "123" }],
801+fallbackUsed: false,
802+delivered: false,
803+});
769804expect(result.delivery).not.toHaveProperty("resolved");
770805});
771806@@ -788,11 +823,9 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
788823789824expect(result.status).toBe("ok");
790825expect(result.error).toBeUndefined();
791-expect(dispatchCronDeliveryMock).toHaveBeenCalledWith(
792-expect.objectContaining({
793-deliveryPayloads: [{ text: "Final cron report" }],
794-}),
795-);
826+expectDispatchFields({
827+deliveryPayloads: [{ text: "Final cron report" }],
828+});
796829});
797830798831it("keeps pending message presentation warnings fatal when cron delivery does not succeed", async () => {
@@ -812,12 +845,10 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
812845expect(result.status).toBe("error");
813846expect(result.error).toBe("⚠️ ✉️ Message failed");
814847expect(result.summary).toBe("Final cron report");
815-expect(dispatchCronDeliveryMock).toHaveBeenCalledWith(
816-expect.objectContaining({
817-deliveryRequested: false,
818-deliveryPayloads: [{ text: "Final cron report" }],
819-}),
820-);
848+expectDispatchFields({
849+deliveryRequested: false,
850+deliveryPayloads: [{ text: "Final cron report" }],
851+});
821852});
822853});
823854此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。