mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 12:00:44 +00:00
fix(cli): fall back to sips for HEIC infer inputs
This commit is contained in:
@@ -179,6 +179,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Anthropic: reject uppercase provider-prefixed forward-compat model ids locally instead of sending malformed dynamic ids upstream. Fixes #73715.
|
||||
- OpenAI/embeddings: pass configured output dimensionality through single and batched embedding requests so memory embedding indexes can request smaller vectors. Fixes #55126.
|
||||
- CLI/infer: normalize HEIC/HEIF image files to JPEG before model-run requests, avoiding providers that reject Apple image container formats. Fixes #50081.
|
||||
- CLI/infer: fall back to macOS `sips` when optional image tooling cannot decode HEIC/HEIF input files before model-run requests. Refs #50081.
|
||||
- OpenRouter: keep the default `openrouter/auto` model ref canonical while preventing TUI and Control UI catalog pickers from displaying or submitting `openrouter/openrouter/auto`. Fixes #62655.
|
||||
- Status/Claude CLI: show `oauth (claude-cli)` for working Claude CLI OAuth runtime sessions instead of `unknown` when no local auth profile exists. Fixes #78632. Thanks @gorkem2020.
|
||||
- Memory search: preserve keyword-only hybrid FTS matches when vector scoring is unavailable or below the configured minimum score, so exact lexical hits are not dropped by weighted min-score filtering.
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { getImageMetadata, MAX_IMAGE_INPUT_PIXELS, resizeToJpeg } from "./image-ops.js";
|
||||
import {
|
||||
convertHeicToJpeg,
|
||||
getImageMetadata,
|
||||
MAX_IMAGE_INPUT_PIXELS,
|
||||
resizeToJpeg,
|
||||
} from "./image-ops.js";
|
||||
import { createPngBufferWithDimensions } from "./test-helpers.js";
|
||||
|
||||
const PNG_1X1_BASE64 =
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADUlEQVR4nGP8z8BQDwAFgwJ/lH3vWQAAAABJRU5ErkJggg==";
|
||||
|
||||
describe("image input pixel guard", () => {
|
||||
const oversizedPng = createPngBufferWithDimensions({ width: 8_000, height: 4_000 });
|
||||
const overflowedPng = createPngBufferWithDimensions({
|
||||
@@ -53,4 +65,30 @@ describe("image input pixel guard", () => {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const itIfMac = process.platform === "darwin" ? it : it.skip;
|
||||
|
||||
itIfMac("converts macOS-generated HEIC images to JPEG", async () => {
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-heic-convert-"));
|
||||
try {
|
||||
const pngPath = path.join(tempDir, "input.png");
|
||||
const heicPath = path.join(tempDir, "input.heic");
|
||||
await fs.writeFile(pngPath, Buffer.from(PNG_1X1_BASE64, "base64"));
|
||||
const result = spawnSync(
|
||||
"/usr/bin/sips",
|
||||
["-s", "format", "heic", pngPath, "--out", heicPath],
|
||||
{
|
||||
encoding: "utf8",
|
||||
},
|
||||
);
|
||||
expect(result.status, result.stderr || result.stdout).toBe(0);
|
||||
|
||||
const jpeg = await convertHeicToJpeg(await fs.readFile(heicPath));
|
||||
|
||||
expect(jpeg[0]).toBe(0xff);
|
||||
expect(jpeg[1]).toBe(0xd8);
|
||||
} finally {
|
||||
await fs.rm(tempDir, { force: true, recursive: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -572,7 +572,14 @@ export async function convertHeicToJpeg(buffer: Buffer): Promise<Buffer> {
|
||||
return await sipsConvertToJpeg(buffer);
|
||||
}
|
||||
const ops = await loadMediaAttachmentImageOps();
|
||||
return await ops.convertHeicToJpeg(buffer);
|
||||
try {
|
||||
return await ops.convertHeicToJpeg(buffer);
|
||||
} catch (error) {
|
||||
if (process.platform !== "darwin") {
|
||||
throw error;
|
||||
}
|
||||
return await sipsConvertToJpeg(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user