feat: 支持历史多张图片的连续编辑
- 从历史对话中提取多张图片,支持多图融合编辑 - 收集同一条消息中的所有图片(用户上传或AI生成) - 将所有历史图片注入到后续编辑请求中 - 日志输出图片数量便于调试 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
691e9862e7
commit
0901bc6329
@ -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图片格式: 
|
||||
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图片格式: 
|
||||
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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user