fix(image): allow workspace and sandbox media paths (#15541)

This commit is contained in:
Tyler Yust
2026-02-14 17:15:15 -08:00
committed by Vignesh
parent ceae46ce33
commit edb06170f5
7 changed files with 139 additions and 4 deletions

View File

@@ -1,5 +1,14 @@
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { describe, expect, it } from "vitest";
import { detectAndLoadPromptImages, detectImageReferences, modelSupportsImages } from "./images.js";
import { createHostSandboxFsBridge } from "../../test-helpers/host-sandbox-fs-bridge.js";
import {
detectAndLoadPromptImages,
detectImageReferences,
loadImageFromRef,
modelSupportsImages,
} from "./images.js";
describe("detectImageReferences", () => {
it("detects absolute file paths with common extensions", () => {
@@ -196,6 +205,41 @@ describe("modelSupportsImages", () => {
});
});
describe("loadImageFromRef", () => {
it("allows sandbox-validated host paths outside default media roots", async () => {
const sandboxParent = await fs.mkdtemp(path.join(os.homedir(), "openclaw-sandbox-image-"));
try {
const sandboxRoot = path.join(sandboxParent, "sandbox");
await fs.mkdir(sandboxRoot, { recursive: true });
const imagePath = path.join(sandboxRoot, "photo.png");
const pngB64 =
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/woAAn8B9FD5fHAAAAAASUVORK5CYII=";
await fs.writeFile(imagePath, Buffer.from(pngB64, "base64"));
const image = await loadImageFromRef(
{
raw: "./photo.png",
type: "path",
resolved: "./photo.png",
},
sandboxRoot,
{
sandbox: {
root: sandboxRoot,
bridge: createHostSandboxFsBridge(sandboxRoot),
},
},
);
expect(image).not.toBeNull();
expect(image?.type).toBe("image");
expect(image?.data.length).toBeGreaterThan(0);
} finally {
await fs.rm(sandboxParent, { recursive: true, force: true });
}
});
});
describe("detectAndLoadPromptImages", () => {
it("returns no images for non-vision models even when existing images are provided", async () => {
const result = await detectAndLoadPromptImages({

View File

@@ -211,6 +211,7 @@ export async function loadImageFromRef(
const media = options?.sandbox
? await loadWebMedia(targetPath, {
maxBytes: options.maxBytes,
localRoots: "any",
readFile: (filePath) =>
options.sandbox!.bridge.readFile({ filePath, cwd: options.sandbox!.root }),
})