修复连续对话误用缩略图导致画质下降
This commit is contained in:
parent
75993d98af
commit
35d50973db
@ -367,29 +367,13 @@ async function convertMessagesWithImages(messages: ChatMessage[], providerType:
|
|||||||
return convertedMessages;
|
return convertedMessages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function parseImageAltMetadata(altText: string, thumbnailUrl: string): {
|
||||||
* 解析生图 Markdown 并保存图片记录到数据库
|
originalUrl: string;
|
||||||
* 支持三种格式:thumb|||url|||size、thumb$$url$$size、thumb|url|size
|
imageSize: string;
|
||||||
*/
|
} {
|
||||||
async function saveGeneratedImages(
|
|
||||||
imageMarkdown: string,
|
|
||||||
userId: string,
|
|
||||||
chatId: string,
|
|
||||||
messageId: string,
|
|
||||||
prompt: string,
|
|
||||||
modelId: string
|
|
||||||
): Promise<void> {
|
|
||||||
// 匹配 Markdown 图片格式: 
|
|
||||||
const imageRegex = /!\[([^\]]*)\]\(([^)]+)\)/g;
|
|
||||||
const matches = [...imageMarkdown.matchAll(imageRegex)];
|
|
||||||
|
|
||||||
for (const match of matches) {
|
|
||||||
const altText = match[1] || "";
|
|
||||||
const thumbnailUrl = match[2];
|
|
||||||
let originalUrl = thumbnailUrl;
|
let originalUrl = thumbnailUrl;
|
||||||
let imageSize = "2K";
|
let imageSize = "2K";
|
||||||
|
|
||||||
// 解析 alt 中的原图 URL 和尺寸
|
|
||||||
// 格式1: thumb|||originalUrl|||size (新格式)
|
// 格式1: thumb|||originalUrl|||size (新格式)
|
||||||
if (altText.includes("thumb|||")) {
|
if (altText.includes("thumb|||")) {
|
||||||
const content = altText.substring(altText.indexOf("thumb|||") + 8);
|
const content = altText.substring(altText.indexOf("thumb|||") + 8);
|
||||||
@ -421,14 +405,69 @@ async function saveGeneratedImages(
|
|||||||
} else if (thumbnailUrl.includes("volcano-thumb-")) {
|
} else if (thumbnailUrl.includes("volcano-thumb-")) {
|
||||||
originalUrl = thumbnailUrl.replace("volcano-thumb-", "volcano-orig-");
|
originalUrl = thumbnailUrl.replace("volcano-thumb-", "volcano-orig-");
|
||||||
} else if (thumbnailUrl.includes("alibaba-image-thumb-")) {
|
} else if (thumbnailUrl.includes("alibaba-image-thumb-")) {
|
||||||
// 🆕 阿里生图模型
|
|
||||||
originalUrl = thumbnailUrl.replace("alibaba-image-thumb-", "alibaba-image-orig-");
|
originalUrl = thumbnailUrl.replace("alibaba-image-thumb-", "alibaba-image-orig-");
|
||||||
} else if (thumbnailUrl.includes("ruxa-image-thumb-")) {
|
} else if (thumbnailUrl.includes("ruxa-image-thumb-")) {
|
||||||
// 🆕 RUXA 生图模型
|
|
||||||
originalUrl = thumbnailUrl.replace("ruxa-image-thumb-", "ruxa-image-orig-");
|
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
|
||||||
|
*/
|
||||||
|
async function saveGeneratedImages(
|
||||||
|
imageMarkdown: string,
|
||||||
|
userId: string,
|
||||||
|
chatId: string,
|
||||||
|
messageId: string,
|
||||||
|
prompt: string,
|
||||||
|
modelId: string
|
||||||
|
): Promise<void> {
|
||||||
|
// 匹配 Markdown 图片格式: 
|
||||||
|
const imageRegex = /!\[([^\]]*)\]\(([^)]+)\)/g;
|
||||||
|
const matches = [...imageMarkdown.matchAll(imageRegex)];
|
||||||
|
|
||||||
|
for (const match of matches) {
|
||||||
|
const altText = match[1] || "";
|
||||||
|
const thumbnailUrl = match[2];
|
||||||
|
const { originalUrl, imageSize } = parseImageAltMetadata(altText, thumbnailUrl);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await db.insert(generatedImage).values({
|
await db.insert(generatedImage).values({
|
||||||
userId,
|
userId,
|
||||||
@ -595,11 +634,11 @@ export async function POST(request: Request) {
|
|||||||
if (msg.role === "assistant") {
|
if (msg.role === "assistant") {
|
||||||
for (const part of parts) {
|
for (const part of parts) {
|
||||||
if (part.type === "text" && part.text) {
|
if (part.type === "text" && part.text) {
|
||||||
// 匹配所有Markdown图片格式: 
|
// 从 markdown 中优先提取原图 URL,避免把缩略图当作下一轮输入导致画质下降
|
||||||
const imgMatches = part.text.matchAll(/!\[.*?\]\((https?:\/\/[^\s)]+)\)/g);
|
const parsedImageUrls = extractOriginalImageUrlsFromText(part.text);
|
||||||
for (const match of imgMatches) {
|
for (const parsedUrl of parsedImageUrls) {
|
||||||
if (match[1] && !smartAutoHistoryImages.includes(match[1])) {
|
if (!smartAutoHistoryImages.includes(parsedUrl)) {
|
||||||
smartAutoHistoryImages.push(match[1]);
|
smartAutoHistoryImages.push(parsedUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user