Files
openclaw/src/media/load-options.ts
Kenny Xie 2650ce31fc fix(media): resolve relative MEDIA paths against agent workspace (#58624)
* fix(media): resolve relative MEDIA: paths against agent workspace dir

* fix(agents): remove stale ollama compat import

* fix(media): preserve workspace dir in outbound access
2026-03-31 21:09:28 -04:00

81 lines
2.7 KiB
TypeScript

export type OutboundMediaReadFile = (filePath: string) => Promise<Buffer>;
export type OutboundMediaAccess = {
localRoots?: readonly string[];
readFile?: OutboundMediaReadFile;
/** Agent workspace directory for resolving relative MEDIA: paths. */
workspaceDir?: string;
};
export type OutboundMediaLoadParams = {
maxBytes?: number;
mediaAccess?: OutboundMediaAccess;
mediaLocalRoots?: readonly string[];
mediaReadFile?: OutboundMediaReadFile;
optimizeImages?: boolean;
/** Agent workspace directory for resolving relative MEDIA: paths. */
workspaceDir?: string;
};
export type OutboundMediaLoadOptions = {
maxBytes?: number;
localRoots?: readonly string[] | "any";
readFile?: (filePath: string) => Promise<Buffer>;
hostReadCapability?: boolean;
optimizeImages?: boolean;
/** Agent workspace directory for resolving relative MEDIA: paths. */
workspaceDir?: string;
};
export function resolveOutboundMediaLocalRoots(
mediaLocalRoots?: readonly string[],
): readonly string[] | undefined {
return mediaLocalRoots && mediaLocalRoots.length > 0 ? mediaLocalRoots : undefined;
}
export function resolveOutboundMediaAccess(
params: {
mediaAccess?: OutboundMediaAccess;
mediaLocalRoots?: readonly string[];
mediaReadFile?: OutboundMediaReadFile;
} = {},
): OutboundMediaAccess | undefined {
const localRoots = resolveOutboundMediaLocalRoots(
params.mediaAccess?.localRoots ?? params.mediaLocalRoots,
);
const readFile = params.mediaAccess?.readFile ?? params.mediaReadFile;
const workspaceDir = params.mediaAccess?.workspaceDir;
if (!localRoots && !readFile && !workspaceDir) {
return undefined;
}
return {
...(localRoots ? { localRoots } : {}),
...(readFile ? { readFile } : {}),
...(workspaceDir ? { workspaceDir } : {}),
};
}
export function buildOutboundMediaLoadOptions(
params: OutboundMediaLoadParams = {},
): OutboundMediaLoadOptions {
const mediaAccess = resolveOutboundMediaAccess(params);
const workspaceDir = mediaAccess?.workspaceDir ?? params.workspaceDir;
if (mediaAccess?.readFile) {
return {
...(params.maxBytes !== undefined ? { maxBytes: params.maxBytes } : {}),
localRoots: "any",
readFile: mediaAccess.readFile,
hostReadCapability: true,
...(params.optimizeImages !== undefined ? { optimizeImages: params.optimizeImages } : {}),
...(workspaceDir ? { workspaceDir } : {}),
};
}
const localRoots = mediaAccess?.localRoots;
return {
...(params.maxBytes !== undefined ? { maxBytes: params.maxBytes } : {}),
...(localRoots ? { localRoots } : {}),
...(params.optimizeImages !== undefined ? { optimizeImages: params.optimizeImages } : {}),
...(workspaceDir ? { workspaceDir } : {}),
};
}