fix(extensions): synthesize mediaLocalRoots propagation across sendMedia adapters

Restore deterministic mediaLocalRoots propagation through extension sendMedia adapters and add coverage for local/remote media handling in Google Chat.

Synthesis of #33581, #33545, #33540, #33536, #33528.

Co-authored-by: bmendonca3 <bmendonca3@users.noreply.github.com>
This commit is contained in:
Tak Hoffman
2026-03-03 21:30:41 -06:00
committed by GitHub
parent 9889c6da53
commit 87e6ce7c3a
11 changed files with 342 additions and 9 deletions

View File

@@ -63,4 +63,33 @@ describe("imessagePlugin outbound", () => {
);
expect(result).toEqual({ channel: "imessage", messageId: "m-media" });
});
it("forwards mediaLocalRoots on direct sendMedia adapter path", async () => {
const sendIMessage = vi.fn().mockResolvedValue({ messageId: "m-media-local" });
const sendMedia = imessagePlugin.outbound?.sendMedia;
expect(sendMedia).toBeDefined();
const mediaLocalRoots = ["/tmp/workspace"];
const result = await sendMedia!({
cfg,
to: "chat_id:88",
text: "caption",
mediaUrl: "/tmp/workspace/pic.png",
mediaLocalRoots,
accountId: "acct-1",
deps: { sendIMessage },
});
expect(sendIMessage).toHaveBeenCalledWith(
"chat_id:88",
"caption",
expect.objectContaining({
mediaUrl: "/tmp/workspace/pic.png",
mediaLocalRoots,
accountId: "acct-1",
maxBytes: 3 * 1024 * 1024,
}),
);
expect(result).toEqual({ channel: "imessage", messageId: "m-media-local" });
});
});

View File

@@ -54,6 +54,7 @@ async function sendIMessageOutbound(params: {
to: string;
text: string;
mediaUrl?: string;
mediaLocalRoots?: readonly string[];
accountId?: string;
deps?: { sendIMessage?: IMessageSendFn };
replyToId?: string;
@@ -69,6 +70,7 @@ async function sendIMessageOutbound(params: {
});
return await send(params.to, params.text, {
...(params.mediaUrl ? { mediaUrl: params.mediaUrl } : {}),
...(params.mediaLocalRoots?.length ? { mediaLocalRoots: params.mediaLocalRoots } : {}),
maxBytes,
accountId: params.accountId ?? undefined,
replyToId: params.replyToId ?? undefined,
@@ -239,12 +241,13 @@ export const imessagePlugin: ChannelPlugin<ResolvedIMessageAccount> = {
});
return { channel: "imessage", ...result };
},
sendMedia: async ({ cfg, to, text, mediaUrl, accountId, deps, replyToId }) => {
sendMedia: async ({ cfg, to, text, mediaUrl, mediaLocalRoots, accountId, deps, replyToId }) => {
const result = await sendIMessageOutbound({
cfg,
to,
text,
mediaUrl,
mediaLocalRoots,
accountId: accountId ?? undefined,
deps,
replyToId: replyToId ?? undefined,