feat: 支持历史多张图片的连续编辑

- 从历史对话中提取多张图片,支持多图融合编辑
- 收集同一条消息中的所有图片(用户上传或AI生成)
- 将所有历史图片注入到后续编辑请求中
- 日志输出图片数量便于调试

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Your Name 2026-01-31 23:41:07 +08:00
parent 691e9862e7
commit 0901bc6329

View File

@ -334,7 +334,7 @@ export async function POST(request: Request) {
// 🆕 存储智能模式的相关信息
let smartAutoFriendlyMessage: string | undefined; // AI的自然对话回复
let smartAutoOptimizedPrompt: string | undefined; // 优化后的提示词(不修改用户消息,只用于API调用)
let smartAutoHistoryImage: string | undefined; // 从历史对话中提取的图片URL
let smartAutoHistoryImages: string[] = []; // 从历史对话中提取的图片URL(支持多张)
// ========== Smart Auto Mode Logic ==========
if (finalModelId === "auto") {
@ -358,53 +358,61 @@ export async function POST(request: Request) {
.filter((p: any) => p.type === "file" && p.url)
.map((p: any) => p.url as string);
// 🆕 历史图片上下文感知:如果用户没有发送新图片,自动使用历史中最近的图片
// 🆕 历史图片上下文感知:如果用户没有发送新图片,自动使用历史中最近的图片(支持多张)
// 逻辑:只要用户在对话中没有附上新图片,就默认继续处理之前的图片
if (!hasImage && messagesFromDb.length > 0) {
console.log("[Smart Auto Mode] 🔍 No image in current message, auto-searching history...");
// 从历史消息中倒序查找最近的图片
// 优先找AI生成的图片(用户可能想修改生成结果),其次是用户上传的图片
// 从历史消息中倒序查找最近一轮包含图片的消息
// 收集该消息中的所有图片(支持多图融合编辑)
for (let i = messagesFromDb.length - 1; i >= 0; i--) {
const msg = messagesFromDb[i];
const parts = msg.parts as any[];
if (!parts) continue;
// 查找文本中的Markdown图片(AI生成的)
// 查找AI生成的图片(从Markdown中提取所有图片)
if (msg.role === "assistant") {
for (const part of parts) {
if (part.type === "text" && part.text) {
// 匹配Markdown图片格式: ![alt](url)
const imgMatch = part.text.match(/!\[.*?\]\((https?:\/\/[^\s)]+)\)/);
if (imgMatch && imgMatch[1]) {
smartAutoHistoryImage = imgMatch[1];
console.log("[Smart Auto Mode] 🖼️ Found AI-generated image:", smartAutoHistoryImage.substring(0, 80));
break;
// 匹配所有Markdown图片格式: ![alt](url)
const imgMatches = part.text.matchAll(/!\[.*?\]\((https?:\/\/[^\s)]+)\)/g);
for (const match of imgMatches) {
if (match[1] && !smartAutoHistoryImages.includes(match[1])) {
smartAutoHistoryImages.push(match[1]);
}
}
}
}
}
// 查找用户上传的图片
if (msg.role === "user" && !smartAutoHistoryImage) {
for (const part of parts) {
if ((part.type === "file" || part.type === "image") && part.url) {
smartAutoHistoryImage = part.url;
console.log("[Smart Auto Mode] 🖼️ Found user-uploaded image:", smartAutoHistoryImage.substring(0, 80));
break;
}
// 如果在这条assistant消息中找到了图片,就停止搜索(使用最近一轮的结果)
if (smartAutoHistoryImages.length > 0) {
console.log("[Smart Auto Mode] 🖼️ Found AI-generated images:", smartAutoHistoryImages.length);
break;
}
}
if (smartAutoHistoryImage) break;
// 查找用户上传的图片(收集该消息中的所有图片)
if (msg.role === "user" && smartAutoHistoryImages.length === 0) {
for (const part of parts) {
if ((part.type === "file" || part.type === "image") && part.url) {
if (!smartAutoHistoryImages.includes(part.url)) {
smartAutoHistoryImages.push(part.url);
}
}
}
// 如果在这条user消息中找到了图片,就停止搜索
if (smartAutoHistoryImages.length > 0) {
console.log("[Smart Auto Mode] 🖼️ Found user-uploaded images:", smartAutoHistoryImages.length);
break;
}
}
}
// 如果找到了历史图片,标记为有图片
if (smartAutoHistoryImage) {
if (smartAutoHistoryImages.length > 0) {
hasImage = true;
imageUrls = [smartAutoHistoryImage];
console.log("[Smart Auto Mode] ✅ Auto-using history image for context continuity");
imageUrls = smartAutoHistoryImages;
console.log("[Smart Auto Mode] ✅ Auto-using", smartAutoHistoryImages.length, "history image(s) for context continuity");
} else {
console.log("[Smart Auto Mode] ℹ️ No image found in history, proceeding as pure text");
}
@ -418,7 +426,7 @@ export async function POST(request: Request) {
text: textContent,
hasImage,
imageUrls,
imageFromHistory: !!smartAutoHistoryImage, // 🆕 标识图片是否来自历史
imageFromHistory: smartAutoHistoryImages.length > 0, // 🆕 标识图片是否来自历史
});
console.log("[Smart Auto Mode] Analysis result:", {
@ -997,9 +1005,9 @@ export async function POST(request: Request) {
}));
}
// 🆕 如果使用了历史图片,将其注入到消息中
if (smartAutoHistoryImage && messagesForAlibaba.length > 0) {
console.log("[Chat API] 🖼️ Injecting history image into message");
// 🆕 如果使用了历史图片,将其注入到消息中(支持多张)
if (smartAutoHistoryImages.length > 0 && messagesForAlibaba.length > 0) {
console.log("[Chat API] 🖼️ Injecting", smartAutoHistoryImages.length, "history image(s) into message");
messagesForAlibaba = messagesForAlibaba.map((msg) => {
// 检查消息中是否已有图片
const hasExistingImage = msg.parts.some(
@ -1007,13 +1015,15 @@ export async function POST(request: Request) {
);
if (!hasExistingImage) {
// 注入历史图片
// 注入所有历史图片
const imageParts = smartAutoHistoryImages.map((url) => ({
type: "file" as const,
url,
mimeType: "image/png",
}));
return {
...msg,
parts: [
...msg.parts,
{ type: "file", url: smartAutoHistoryImage, mimeType: "image/png" },
],
parts: [...msg.parts, ...imageParts],
};
}
return msg;