refactor(plugin-sdk): discriminate delivery and exec results (#124979)

* refactor(plugin-sdk): discriminate delivery and exec results

* test(plugin-sdk): update delivery target expectations

* fix(outbound): preserve canonical delivery targets

* fix(irc): normalize message delivery target
This commit is contained in:
Peter Steinberger
2026-08-16 22:55:41 -07:00
committed by GitHub
parent 54cbce25bd
commit f9b1ccc4fa
56 changed files with 611 additions and 418 deletions
+150 -121
View File
@@ -152,11 +152,16 @@ type FeishuOutboundPayload = Parameters<
type FeishuSendPayloadContext = Parameters<NonNullable<ChannelOutboundAdapter["sendPayload"]>>[0];
type FeishuSendTextContext = Parameters<NonNullable<ChannelOutboundAdapter["sendText"]>>[0];
async function reportFeishuOutboundDelivery<T extends { messageId: string }>(
function toFeishuOutboundResult<T extends { chatId: string }>(result: T) {
const { chatId, ...delivery } = result;
return { ...delivery, target: { kind: "chat" as const, id: chatId } };
}
async function reportFeishuOutboundDelivery<T extends { messageId: string; chatId: string }>(
result: T,
onDeliveryResult: FeishuSendTextContext["onDeliveryResult"],
): Promise<T> {
await onDeliveryResult?.(attachChannelToResult("feishu", result));
await onDeliveryResult?.(attachChannelToResult("feishu", toFeishuOutboundResult(result)));
return result;
}
@@ -701,14 +706,16 @@ export const feishuOutbound: ChannelOutboundAdapter = {
});
return attachChannelToResult(
"feishu",
await sendCardFeishu({
cfg: ctx.cfg,
to: ctx.to,
card,
replyToMessageId,
replyInThread,
accountId: ctx.accountId ?? undefined,
}),
toFeishuOutboundResult(
await sendCardFeishu({
cfg: ctx.cfg,
to: ctx.to,
card,
replyToMessageId,
replyInThread,
accountId: ctx.accountId ?? undefined,
}),
),
);
},
});
@@ -733,44 +740,48 @@ export const feishuOutbound: ChannelOutboundAdapter = {
const mediaUrls = normalizeStringEntries(resolvePayloadMediaUrls(payload));
return attachChannelToResult(
"feishu",
await sendPayloadMediaSequenceAndFinalize<
SendMediaResult,
Awaited<ReturnType<typeof sendCardFeishu>>
>({
text: payload.text ?? "",
mediaUrls,
onResult: async (deliveryResult) => {
await ctx.onDeliveryResult?.(attachChannelToResult("feishu", deliveryResult));
},
send: async ({ mediaUrl }) => {
const { replyToMessageId, replyInThread } = nextReplyMode();
return await sendMediaFeishu({
cfg: ctx.cfg,
to: ctx.to,
mediaUrl,
accountId: ctx.accountId ?? undefined,
mediaAccess: ctx.mediaAccess,
mediaLocalRoots: ctx.mediaLocalRoots,
mediaReadFile: ctx.mediaReadFile,
replyToMessageId,
replyInThread,
...(payload.audioAsVoice === true || ctx.audioAsVoice === true
? { audioAsVoice: true }
: {}),
});
},
finalize: async () => {
const { replyToMessageId, replyInThread } = nextReplyMode();
return await sendCardFeishu({
cfg: ctx.cfg,
to: ctx.to,
card,
replyToMessageId,
replyInThread,
accountId: ctx.accountId ?? undefined,
});
},
}),
toFeishuOutboundResult(
await sendPayloadMediaSequenceAndFinalize<
SendMediaResult,
Awaited<ReturnType<typeof sendCardFeishu>>
>({
text: payload.text ?? "",
mediaUrls,
onResult: async (deliveryResult) => {
await ctx.onDeliveryResult?.(
attachChannelToResult("feishu", toFeishuOutboundResult(deliveryResult)),
);
},
send: async ({ mediaUrl }) => {
const { replyToMessageId, replyInThread } = nextReplyMode();
return await sendMediaFeishu({
cfg: ctx.cfg,
to: ctx.to,
mediaUrl,
accountId: ctx.accountId ?? undefined,
mediaAccess: ctx.mediaAccess,
mediaLocalRoots: ctx.mediaLocalRoots,
mediaReadFile: ctx.mediaReadFile,
replyToMessageId,
replyInThread,
...(payload.audioAsVoice === true || ctx.audioAsVoice === true
? { audioAsVoice: true }
: {}),
});
},
finalize: async () => {
const { replyToMessageId, replyInThread } = nextReplyMode();
return await sendCardFeishu({
cfg: ctx.cfg,
to: ctx.to,
card,
replyToMessageId,
replyInThread,
accountId: ctx.accountId ?? undefined,
});
},
}),
),
);
},
...createAttachedChannelResultAdapter({
@@ -819,44 +830,52 @@ export const feishuOutbound: ChannelOutboundAdapter = {
throw err;
}
console.error(`[feishu] local image path auto-send failed:`, err);
return await sendOutboundText({
return toFeishuOutboundResult(
await sendOutboundText({
cfg,
to,
text: await buildFeishuMediaFallbackText({}),
accountId: accountId ?? undefined,
replyToMessageId,
replyInThread,
...deliveryOptions,
}),
);
}
return toFeishuOutboundResult(
await reportFeishuOutboundDelivery(mediaResult, onDeliveryResult),
);
}
if (parseFeishuCommentTarget(to)) {
return toFeishuOutboundResult(
await sendOutboundText({
cfg,
to,
text: await buildFeishuMediaFallbackText({}),
text,
accountId: accountId ?? undefined,
replyToMessageId,
replyInThread,
...deliveryOptions,
});
}
return await reportFeishuOutboundDelivery(mediaResult, onDeliveryResult);
}
if (parseFeishuCommentTarget(to)) {
return await sendOutboundText({
cfg,
to,
text,
accountId: accountId ?? undefined,
replyToMessageId,
replyInThread,
...deliveryOptions,
});
}),
);
}
const card = readNativeFeishuCardJson(text);
if (card) {
assertFeishuCardWithinEnvelope(card, "Feishu native card");
return await reportFeishuOutboundDelivery(
await sendCardFeishu({
cfg,
to,
card: markRenderedFeishuCard(card),
accountId: accountId ?? undefined,
replyToMessageId,
replyInThread,
}),
onDeliveryResult,
return toFeishuOutboundResult(
await reportFeishuOutboundDelivery(
await sendCardFeishu({
cfg,
to,
card: markRenderedFeishuCard(card),
accountId: accountId ?? undefined,
replyToMessageId,
replyInThread,
}),
onDeliveryResult,
),
);
}
@@ -870,28 +889,32 @@ export const feishuOutbound: ChannelOutboundAdapter = {
template: "blue" as const,
}
: undefined;
return await reportFeishuOutboundDelivery(
await sendStructuredCardFeishu({
cfg,
to,
text,
replyToMessageId,
replyInThread,
accountId: accountId ?? undefined,
header: header?.title ? header : undefined,
}),
onDeliveryResult,
return toFeishuOutboundResult(
await reportFeishuOutboundDelivery(
await sendStructuredCardFeishu({
cfg,
to,
text,
replyToMessageId,
replyInThread,
accountId: accountId ?? undefined,
header: header?.title ? header : undefined,
}),
onDeliveryResult,
),
);
}
return await sendOutboundText({
cfg,
to,
text,
accountId: accountId ?? undefined,
replyToMessageId,
replyInThread,
...deliveryOptions,
});
return toFeishuOutboundResult(
await sendOutboundText({
cfg,
to,
text,
accountId: accountId ?? undefined,
replyToMessageId,
replyInThread,
...deliveryOptions,
}),
);
},
sendMedia: async ({
cfg,
@@ -934,25 +957,29 @@ export const feishuOutbound: ChannelOutboundAdapter = {
mediaLinkStyle: "plain",
})
: (text?.trim() ?? "");
return await sendOutboundText({
cfg,
to,
text: commentText,
accountId: accountId ?? undefined,
...nextReplyMode(),
...deliveryOptions,
});
return toFeishuOutboundResult(
await sendOutboundText({
cfg,
to,
text: commentText,
accountId: accountId ?? undefined,
...nextReplyMode(),
...deliveryOptions,
}),
);
}
if (!mediaUrl) {
return await sendOutboundText({
cfg,
to,
text: text ?? "",
accountId: accountId ?? undefined,
...nextReplyMode(),
...deliveryOptions,
});
return toFeishuOutboundResult(
await sendOutboundText({
cfg,
to,
text: text ?? "",
accountId: accountId ?? undefined,
...nextReplyMode(),
...deliveryOptions,
}),
);
}
const suppressTextForVoiceMedia = shouldSuppressFeishuTextForVoiceMedia({
@@ -998,15 +1025,17 @@ export const feishuOutbound: ChannelOutboundAdapter = {
text: textSent ? undefined : text,
mediaUrl,
});
return await sendOutboundText({
cfg,
to,
text: fallbackText,
accountId: accountId ?? undefined,
// A rejected upload never delivered its attempted reply target.
...(textSent ? nextReplyMode() : mediaReplyMode),
...deliveryOptions,
});
return toFeishuOutboundResult(
await sendOutboundText({
cfg,
to,
text: fallbackText,
accountId: accountId ?? undefined,
// A rejected upload never delivered its attempted reply target.
...(textSent ? nextReplyMode() : mediaReplyMode),
...deliveryOptions,
}),
);
}
// Persist the accepted attachment before any later fallible text action.
@@ -1021,7 +1050,7 @@ export const feishuOutbound: ChannelOutboundAdapter = {
...deliveryOptions,
});
}
return mediaResult;
return toFeishuOutboundResult(mediaResult);
},
}),
};