fix(image): avoid showing input reference image in output messages
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-02-21 03:00:42 +08:00
parent 6835078cf5
commit 2b7e738e84
3 changed files with 40 additions and 0 deletions

View File

@ -122,6 +122,9 @@ function getImageDimensions(url: string): Promise<{
// 从消息中提取图片 URL(只提取原始图片,避免重复)
function extractImageUrls(text: string): string[] {
if (!/!\[[^\]]*\]\((https?:\/\/[^\s)]+)\)/i.test(text || "")) {
return [];
}
return extractImageUrlsFromText(text);
}

View File

@ -179,6 +179,7 @@ function appendImageDoneSummary(text: string): string {
if (!text) return text;
const normalized = String(text || "").trim();
if (!normalized) return normalized;
if (!/!\[[^\]]*\]\((https?:\/\/[^\s)]+)\)/i.test(normalized)) return normalized;
if (extractImageUrlsFromText(normalized).length === 0) return normalized;
if (normalized.includes(IMAGE_DONE_SUMMARY)) return normalized;
return `${normalized}\n\n${IMAGE_DONE_SUMMARY}`;

View File

@ -1,5 +1,6 @@
import "server-only";
import { createHash } from "node:crypto";
import sharp from "sharp";
import { uploadFile } from "@/lib/storage/service";
@ -59,6 +60,39 @@ function filterSourceImages(urls: string[], sourceUrls: string[]) {
return urls.filter((url) => !sourceSet.has(normalizeUrlForCompare(url)));
}
async function getImageContentHash(url: string): Promise<string | null> {
try {
const response = await fetch(url, { signal: AbortSignal.timeout(15_000) });
if (!response.ok) return null;
const buffer = Buffer.from(await response.arrayBuffer());
return createHash("sha1").update(buffer).digest("hex");
} catch {
return null;
}
}
async function filterSourceImagesByContent(urls: string[], sourceUrls: string[]) {
if (sourceUrls.length === 0 || urls.length === 0) return urls;
const sourceHashes = new Set<string>();
for (const sourceUrl of sourceUrls) {
const hash = await getImageContentHash(sourceUrl);
if (hash) sourceHashes.add(hash);
}
if (sourceHashes.size === 0) return urls;
const filtered: string[] = [];
for (const url of urls) {
const hash = await getImageContentHash(url);
if (hash && sourceHashes.has(hash)) {
continue;
}
filtered.push(url);
}
return filtered.length > 0 ? filtered : urls;
}
function normalizeAspectRatio(aspectRatio?: string) {
if (!aspectRatio) return DEFAULT_ASPECT_RATIO;
const ratio = aspectRatio.trim();
@ -326,9 +360,11 @@ export function createFalImage({ apiKey, baseURL }: FalImageConfig) {
});
let outputUrls = filterSourceImages(collectImageUrls(result), imageUrls);
outputUrls = await filterSourceImagesByContent(outputUrls, imageUrls);
if (outputUrls.length === 0 && result?.data) {
outputUrls = filterSourceImages(collectImageUrls(result.data), imageUrls);
outputUrls = await filterSourceImagesByContent(outputUrls, imageUrls);
}
if (outputUrls.length === 0) {