fix(feishu): pass mediaLocalRoots to enable local media file uploads

The feishu channel was not passing mediaLocalRoots when calling
sendMediaFeishu, causing loadWebMedia to reject local file paths
due to security restrictions. This meant agent-generated media
(like images from image_generate tool) would fail to upload and
fall back to sending the local path as text.

Now properly passes agent-scoped media roots (workspace, tmp, etc.)
to allow reading and uploading local media files to Feishu.
This commit is contained in:
Ben Gao 2026-03-21 10:00:19 +08:00
parent e78129a4d9
commit 9cf0e16925
2 changed files with 7 additions and 0 deletions

View File

@ -3,6 +3,7 @@ import {
resolveConfiguredBindingRoute,
} from "openclaw/plugin-sdk/conversation-runtime";
import { getSessionBindingService } from "openclaw/plugin-sdk/conversation-runtime";
import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
import { deriveLastRoutePolicy } from "openclaw/plugin-sdk/routing";
import { resolveAgentIdFromSessionKey } from "openclaw/plugin-sdk/routing";
import type { ClawdbotConfig, RuntimeEnv } from "../runtime-api.js";
@ -1009,6 +1010,7 @@ export async function handleFeishuMessage(params: {
accountId: account.accountId,
identity,
messageCreateTimeMs,
mediaLocalRoots: getAgentScopedMediaLocalRoots(cfg, agentId),
});
log(
@ -1110,6 +1112,7 @@ export async function handleFeishuMessage(params: {
accountId: account.accountId,
identity,
messageCreateTimeMs,
mediaLocalRoots: getAgentScopedMediaLocalRoots(cfg, route.agentId),
});
log(`feishu[${account.accountId}]: dispatching to agent (session=${route.sessionKey})`);

View File

@ -90,6 +90,8 @@ export type CreateFeishuReplyDispatcherParams = {
/** Epoch ms when the inbound message was created. Used to suppress typing
* indicators on old/replayed messages after context compaction (#30418). */
messageCreateTimeMs?: number;
/** Allowed roots for local media path reads (agent workspace, tmp, etc.). */
mediaLocalRoots?: readonly string[];
};
export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherParams) {
@ -106,6 +108,7 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP
mentionTargets,
accountId,
identity,
mediaLocalRoots,
} = params;
const sendReplyToMessageId = skipReplyToInMessages ? undefined : replyToMessageId;
const threadReplyMode = threadReply === true;
@ -340,6 +343,7 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP
cfg,
to: chatId,
mediaUrl,
mediaLocalRoots,
replyToMessageId: sendReplyToMessageId,
replyInThread: effectiveReplyInThread,
accountId,