Skip to content

Commit 257d0cb

Browse files
sliverpzhangguiping-xydt
authored andcommitted
fix(qqbot): preserve host-read media roots
1 parent 0a31c35 commit 257d0cb

2 files changed

Lines changed: 31 additions & 10 deletions

File tree

extensions/qqbot/src/engine/messaging/outbound-media-send.test.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,10 @@ describe("trySendViaHostRead error handling", () => {
224224
expect(mockedLoadOutboundMediaFromUrl).toHaveBeenCalledWith(
225225
"/tmp/workspace/report.docx",
226226
expect.objectContaining({
227-
mediaAccess: expect.objectContaining({ workspaceDir: "/tmp/workspace" }),
227+
mediaAccess: expect.objectContaining({
228+
localRoots: ["/tmp/openclaw-sandbox", "/tmp/workspace"],
229+
workspaceDir: "/tmp/workspace",
230+
}),
228231
workspaceDir: "/tmp/workspace",
229232
}),
230233
);
@@ -257,10 +260,9 @@ describe("trySendViaHostRead error handling", () => {
257260
"/workspace/attachments/report.docx",
258261
expect.objectContaining({
259262
mediaAccess: expect.objectContaining({
260-
localRoots: ["/workspace/attachments"],
263+
localRoots: ["/workspace/attachments", "/tmp/agent-workspace"],
261264
workspaceDir: "/tmp/agent-workspace",
262265
}),
263-
mediaLocalRoots: ["/workspace/attachments"],
264266
workspaceDir: "/tmp/agent-workspace",
265267
}),
266268
);
@@ -280,7 +282,13 @@ describe("trySendViaHostRead error handling", () => {
280282
expect(result).toMatchObject({ channel: "qqbot", messageId: "voice-1" });
281283
expect(mockedLoadOutboundMediaFromUrl).toHaveBeenCalledWith(
282284
"/tmp/workspace/clip.mp3",
283-
expect.objectContaining({ maxBytes: expect.any(Number) }),
285+
expect.objectContaining({
286+
maxBytes: expect.any(Number),
287+
mediaAccess: expect.objectContaining({
288+
localRoots: ["/tmp/openclaw-sandbox", "/tmp/workspace"],
289+
workspaceDir: "/tmp/workspace",
290+
}),
291+
}),
284292
);
285293
expect(audioPortMock.waitForFile).toHaveBeenCalledWith(expect.stringMatching(/clip-.*\.mp3$/));
286294
expect(mockedSenderSendMedia).toHaveBeenCalledWith(

extensions/qqbot/src/engine/messaging/outbound-media-send.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,19 @@ function resolveOutboundMediaReadFile(ctx: OutboundMediaAccessContext) {
210210
return ctx.mediaAccess?.readFile ?? ctx.mediaReadFile;
211211
}
212212

213+
function resolveHostReadMediaAccess(
214+
ctx: OutboundMediaAccessContext,
215+
): OutboundMediaAccessContext["mediaAccess"] | undefined {
216+
const mediaLocalRoots = resolveOutboundMediaLocalRoots(ctx);
217+
if (!ctx.mediaAccess && !mediaLocalRoots) {
218+
return undefined;
219+
}
220+
return {
221+
...(ctx.mediaAccess ?? {}),
222+
...(mediaLocalRoots ? { localRoots: mediaLocalRoots } : {}),
223+
};
224+
}
225+
213226
function mediaFileTypeForKind(mediaKind: QQBotMediaKind): MediaFileType {
214227
switch (mediaKind) {
215228
case "image":
@@ -265,12 +278,12 @@ async function stageHostReadVoice(
265278
return null;
266279
}
267280
const hostReadMediaPath = resolveHostReadMediaPath(ctx, mediaPath);
281+
const mediaAccess = resolveHostReadMediaAccess(ctx);
268282
const loaded = await loadOutboundMediaFromUrl(hostReadMediaPath, {
269283
maxBytes: getMaxUploadSize(MediaFileType.VOICE),
270-
mediaAccess: ctx.mediaAccess,
271-
mediaLocalRoots: ctx.mediaLocalRoots,
284+
mediaAccess,
272285
mediaReadFile,
273-
workspaceDir: ctx.mediaAccess?.workspaceDir,
286+
workspaceDir: mediaAccess?.workspaceDir,
274287
});
275288
const stagedDir = getQQBotMediaDir("host-read", "voice");
276289
await mkdir(stagedDir, { recursive: true });
@@ -292,13 +305,13 @@ async function trySendViaHostRead(
292305
return null;
293306
}
294307
const hostReadMediaPath = resolveHostReadMediaPath(ctx, mediaPath);
308+
const mediaAccess = resolveHostReadMediaAccess(ctx);
295309
try {
296310
const loaded = await loadOutboundMediaFromUrl(hostReadMediaPath, {
297311
maxBytes: getMaxUploadSize(mediaFileTypeForKind(mediaKind)),
298-
mediaAccess: ctx.mediaAccess,
299-
mediaLocalRoots: ctx.mediaLocalRoots,
312+
mediaAccess,
300313
mediaReadFile,
301-
workspaceDir: ctx.mediaAccess?.workspaceDir,
314+
workspaceDir: mediaAccess?.workspaceDir,
302315
});
303316
const kind = senderKindForLoadedMedia(mediaKind, loaded.kind);
304317
const creds = accountToCreds(ctx.account);

0 commit comments

Comments
 (0)