修复连续对话误用缩略图导致画质下降
This commit is contained in:
parent
75993d98af
commit
35d50973db
@ -367,6 +367,86 @@ async function convertMessagesWithImages(messages: ChatMessage[], providerType:
|
||||
return convertedMessages;
|
||||
}
|
||||
|
||||
function parseImageAltMetadata(altText: string, thumbnailUrl: string): {
|
||||
originalUrl: string;
|
||||
imageSize: string;
|
||||
} {
|
||||
let originalUrl = thumbnailUrl;
|
||||
let imageSize = "2K";
|
||||
|
||||
// 格式1: thumb|||originalUrl|||size (新格式)
|
||||
if (altText.includes("thumb|||")) {
|
||||
const content = altText.substring(altText.indexOf("thumb|||") + 8);
|
||||
const parts = content.split("|||");
|
||||
originalUrl = parts[0] || thumbnailUrl;
|
||||
imageSize = parts[1] || "2K";
|
||||
}
|
||||
// 格式2: thumb$$originalUrl$$size (中间格式,可能被 LaTeX 解析器破坏)
|
||||
else if (altText.includes("thumb$$")) {
|
||||
const content = altText.substring(altText.indexOf("thumb$$") + 7);
|
||||
const parts = content.split("$$");
|
||||
originalUrl = parts[0] || thumbnailUrl;
|
||||
imageSize = parts[1] || "2K";
|
||||
}
|
||||
// 格式3: thumb|originalUrl|size (旧格式)
|
||||
else if (altText.includes("thumb|")) {
|
||||
const content = altText.substring(altText.indexOf("thumb|") + 6);
|
||||
const parts = content.split("|");
|
||||
originalUrl = parts[0] || thumbnailUrl;
|
||||
imageSize = parts[1] || "2K";
|
||||
}
|
||||
|
||||
// 回退策略:从缩略图 URL 推断原图 URL
|
||||
if (originalUrl === thumbnailUrl) {
|
||||
if (thumbnailUrl.includes("gemini-thumb-")) {
|
||||
originalUrl = thumbnailUrl.replace("gemini-thumb-", "gemini-orig-");
|
||||
} else if (thumbnailUrl.includes("openai-thumb-")) {
|
||||
originalUrl = thumbnailUrl.replace("openai-thumb-", "openai-orig-");
|
||||
} else if (thumbnailUrl.includes("volcano-thumb-")) {
|
||||
originalUrl = thumbnailUrl.replace("volcano-thumb-", "volcano-orig-");
|
||||
} else if (thumbnailUrl.includes("alibaba-image-thumb-")) {
|
||||
originalUrl = thumbnailUrl.replace("alibaba-image-thumb-", "alibaba-image-orig-");
|
||||
} else if (thumbnailUrl.includes("ruxa-image-thumb-")) {
|
||||
originalUrl = thumbnailUrl.replace("ruxa-image-thumb-", "ruxa-image-orig-");
|
||||
}
|
||||
}
|
||||
|
||||
return { originalUrl, imageSize };
|
||||
}
|
||||
|
||||
function extractOriginalImageUrlsFromText(text: string): string[] {
|
||||
const imageRegex = /!\[([^\]]*)\]\((https?:\/\/[^\s)]+)\)/g;
|
||||
const imageUrls: string[] = [];
|
||||
const added = new Set<string>();
|
||||
let hasMarkdownImages = false;
|
||||
let match: RegExpExecArray | null;
|
||||
|
||||
while ((match = imageRegex.exec(text)) !== null) {
|
||||
hasMarkdownImages = true;
|
||||
const altText = match[1] || "";
|
||||
const thumbnailUrl = match[2];
|
||||
const { originalUrl } = parseImageAltMetadata(altText, thumbnailUrl);
|
||||
const finalUrl = originalUrl || thumbnailUrl;
|
||||
if (finalUrl && /^https?:\/\//i.test(finalUrl) && !added.has(finalUrl)) {
|
||||
added.add(finalUrl);
|
||||
imageUrls.push(finalUrl);
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasMarkdownImages) {
|
||||
const urlRegex = /https?:\/\/[^\s"'<>]+\.(?:jpg|jpeg|png|gif|webp|bmp|svg)(?:\?[^\s"'<>]*)?/gi;
|
||||
const matchedUrls = text.match(urlRegex) || [];
|
||||
for (const url of matchedUrls) {
|
||||
if (!added.has(url)) {
|
||||
added.add(url);
|
||||
imageUrls.push(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return imageUrls;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析生图 Markdown 并保存图片记录到数据库
|
||||
* 支持三种格式:thumb|||url|||size、thumb$$url$$size、thumb|url|size
|
||||
@ -386,48 +466,7 @@ async function saveGeneratedImages(
|
||||
for (const match of matches) {
|
||||
const altText = match[1] || "";
|
||||
const thumbnailUrl = match[2];
|
||||
let originalUrl = thumbnailUrl;
|
||||
let imageSize = "2K";
|
||||
|
||||
// 解析 alt 中的原图 URL 和尺寸
|
||||
// 格式1: thumb|||originalUrl|||size (新格式)
|
||||
if (altText.includes("thumb|||")) {
|
||||
const content = altText.substring(altText.indexOf("thumb|||") + 8);
|
||||
const parts = content.split("|||");
|
||||
originalUrl = parts[0] || thumbnailUrl;
|
||||
imageSize = parts[1] || "2K";
|
||||
}
|
||||
// 格式2: thumb$$originalUrl$$size (中间格式,可能被 LaTeX 解析器破坏)
|
||||
else if (altText.includes("thumb$$")) {
|
||||
const content = altText.substring(altText.indexOf("thumb$$") + 7);
|
||||
const parts = content.split("$$");
|
||||
originalUrl = parts[0] || thumbnailUrl;
|
||||
imageSize = parts[1] || "2K";
|
||||
}
|
||||
// 格式3: thumb|originalUrl|size (旧格式)
|
||||
else if (altText.includes("thumb|")) {
|
||||
const content = altText.substring(altText.indexOf("thumb|") + 6);
|
||||
const parts = content.split("|");
|
||||
originalUrl = parts[0] || thumbnailUrl;
|
||||
imageSize = parts[1] || "2K";
|
||||
}
|
||||
|
||||
// 回退策略:从缩略图 URL 推断原图 URL
|
||||
if (originalUrl === thumbnailUrl) {
|
||||
if (thumbnailUrl.includes("gemini-thumb-")) {
|
||||
originalUrl = thumbnailUrl.replace("gemini-thumb-", "gemini-orig-");
|
||||
} else if (thumbnailUrl.includes("openai-thumb-")) {
|
||||
originalUrl = thumbnailUrl.replace("openai-thumb-", "openai-orig-");
|
||||
} else if (thumbnailUrl.includes("volcano-thumb-")) {
|
||||
originalUrl = thumbnailUrl.replace("volcano-thumb-", "volcano-orig-");
|
||||
} else if (thumbnailUrl.includes("alibaba-image-thumb-")) {
|
||||
// 🆕 阿里生图模型
|
||||
originalUrl = thumbnailUrl.replace("alibaba-image-thumb-", "alibaba-image-orig-");
|
||||
} else if (thumbnailUrl.includes("ruxa-image-thumb-")) {
|
||||
// 🆕 RUXA 生图模型
|
||||
originalUrl = thumbnailUrl.replace("ruxa-image-thumb-", "ruxa-image-orig-");
|
||||
}
|
||||
}
|
||||
const { originalUrl, imageSize } = parseImageAltMetadata(altText, thumbnailUrl);
|
||||
|
||||
try {
|
||||
await db.insert(generatedImage).values({
|
||||
@ -595,11 +634,11 @@ export async function POST(request: Request) {
|
||||
if (msg.role === "assistant") {
|
||||
for (const part of parts) {
|
||||
if (part.type === "text" && part.text) {
|
||||
// 匹配所有Markdown图片格式: 
|
||||
const imgMatches = part.text.matchAll(/!\[.*?\]\((https?:\/\/[^\s)]+)\)/g);
|
||||
for (const match of imgMatches) {
|
||||
if (match[1] && !smartAutoHistoryImages.includes(match[1])) {
|
||||
smartAutoHistoryImages.push(match[1]);
|
||||
// 从 markdown 中优先提取原图 URL,避免把缩略图当作下一轮输入导致画质下降
|
||||
const parsedImageUrls = extractOriginalImageUrlsFromText(part.text);
|
||||
for (const parsedUrl of parsedImageUrls) {
|
||||
if (!smartAutoHistoryImages.includes(parsedUrl)) {
|
||||
smartAutoHistoryImages.push(parsedUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user