refactor: consolidate message delivery API

This commit is contained in:
Peter Steinberger
2026-05-09 07:02:33 +01:00
parent 195db88d71
commit a4b17d65a8
74 changed files with 1561 additions and 340 deletions

View File

@@ -13,6 +13,7 @@ const deliverOutboundPayloadsMock = vi.hoisted(() =>
);
vi.mock("../../infra/outbound/deliver.js", () => ({
deliverOutboundPayloads: deliverOutboundPayloadsMock,
deliverOutboundPayloadsInternal: deliverOutboundPayloadsMock,
}));
const createReplyMediaPathNormalizerMock = vi.hoisted(() =>
@@ -228,7 +229,35 @@ describe("normalizeAgentCommandReplyPayloads", () => {
it("does not report success when best-effort delivery records an error", async () => {
deliverOutboundPayloadsMock.mockImplementationOnce(async (params: unknown) => {
(params as { onError?: (err: unknown) => void }).onError?.(new Error("send failed"));
(
params as {
onError?: (err: unknown, payload: ReplyPayload) => void;
onPayloadDeliveryOutcome?: (outcome: {
index: number;
payload: ReplyPayload;
status: "failed";
error: Error;
stage: "send";
}) => void;
}
).onError?.(new Error("send failed"), { text: "here you go" });
(
params as {
onPayloadDeliveryOutcome?: (outcome: {
index: number;
payload: ReplyPayload;
status: "failed";
error: Error;
stage: "send";
}) => void;
}
).onPayloadDeliveryOutcome?.({
index: 0,
payload: { text: "here you go" },
status: "failed",
error: new Error("send failed"),
stage: "send",
});
return [];
});
@@ -259,6 +288,12 @@ describe("normalizeAgentCommandReplyPayloads", () => {
expect(delivered.deliverySucceeded).toBe(false);
expect(runtime.error).toHaveBeenCalledWith(expect.stringContaining("send failed"));
expect(deliverOutboundPayloadsMock).toHaveBeenCalledWith(
expect.objectContaining({
bestEffort: true,
queuePolicy: "best_effort",
}),
);
});
it("threads agentId into the normalizer when sessionKey is unresolved", async () => {

View File

@@ -3,6 +3,7 @@ import { resolveSessionAgentId } from "../../agents/agent-scope.js";
import type { ReplyPayload } from "../../auto-reply/reply-payload.js";
import { normalizeReplyPayload } from "../../auto-reply/reply/normalize-reply.js";
import { createReplyMediaPathNormalizer } from "../../auto-reply/reply/reply-media-paths.runtime.js";
import { sendDurableMessageBatch } from "../../channels/message/runtime.js";
import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js";
import { createReplyPrefixContext } from "../../channels/reply-prefix.js";
import { createOutboundSendDeps, type CliDeps } from "../../cli/outbound-send-deps.js";
@@ -13,7 +14,6 @@ import {
resolveAgentOutboundTarget,
} from "../../infra/outbound/agent-delivery.js";
import { resolveMessageChannelSelection } from "../../infra/outbound/channel-selection.js";
import { deliverOutboundPayloads } from "../../infra/outbound/deliver.js";
import { buildOutboundResultEnvelope } from "../../infra/outbound/envelope.js";
import {
createOutboundPayloadPlan,
@@ -381,7 +381,7 @@ export async function deliverAgentCommandResult(params: {
}
if (deliver && deliveryChannel && !isInternalMessageChannel(deliveryChannel)) {
if (deliveryTarget) {
await deliverOutboundPayloads({
const send = await sendDurableMessageBatch({
cfg,
channel: deliveryChannel,
to: deliveryTarget,
@@ -391,10 +391,17 @@ export async function deliverAgentCommandResult(params: {
replyToId: resolvedReplyToId ?? null,
threadId: resolvedThreadTarget ?? null,
bestEffort: bestEffortDeliver,
durability: bestEffortDeliver ? "best_effort" : "required",
onError: markDeliveryError,
onPayload: logPayload,
deps: createOutboundSendDeps(deps),
});
if (!bestEffortDeliver && (send.status === "failed" || send.status === "partial_failed")) {
throw send.error;
}
if (send.status === "failed" || send.status === "partial_failed") {
deliveryHadError = true;
}
deliverySucceeded = !deliveryHadError;
}
}