From e5b3088671c4f9eb34b8c5d258894c9270b6f8a5 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 12 Jan 2026 12:25:52 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E9=98=BF=E9=87=8C?= =?UTF-8?q?=E7=94=9F=E5=9B=BE=E6=A8=A1=E5=9E=8B=E9=94=99=E8=AF=AF=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=EF=BC=8C=E4=BD=BF=E7=94=A8=E5=90=8E=E5=8F=B0=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E7=9A=84=E6=A8=A1=E5=9E=8B=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 错误提示中显示后台配置的模型显示名称 - 添加 modelDisplayName 参数到 doGenerate 接口 - 当用户只发文字时,提示需要上传图片 --- app/(chat)/api/chat/route.ts | 7 ++++++- lib/ai/providers/alibaba-image.ts | 13 ++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/(chat)/api/chat/route.ts b/app/(chat)/api/chat/route.ts index baa3b3f..4d82716 100644 --- a/app/(chat)/api/chat/route.ts +++ b/app/(chat)/api/chat/route.ts @@ -897,6 +897,10 @@ export async function POST(request: Request) { console.log("[Chat API] Using Alibaba Image generation"); console.log("[Chat API] Image params:", requestBody.imageParams); + // 🆕 获取模型显示名称,用于错误提示 + const alibabaModelConfig = await getAiModelById({ id: finalModelId }); + const modelDisplayName = alibabaModelConfig?.displayName || actualModelId; + const alibabaStream = createUIMessageStream({ execute: async ({ writer }) => { try { @@ -908,10 +912,11 @@ export async function POST(request: Request) { // 转换消息(阿里生图支持 URL,会自动上传 base64) const modelMessages = await convertMessagesWithImages(messagesForAlibaba, "alibaba-image"); - // 调用 doGenerate 获取图片 + // 调用 doGenerate 获取图片,传递模型显示名称 const result = await (languageModel as any).doGenerate({ messages: modelMessages, imageParams: requestBody.imageParams || { aspectRatio: "auto", imageSize: "2K", imageCount: 1 }, + modelDisplayName, // 🆕 传递模型显示名称 }); const imageMarkdown = result.text || "图片生成失败"; diff --git a/lib/ai/providers/alibaba-image.ts b/lib/ai/providers/alibaba-image.ts index 3a924c7..6c81b5b 100644 --- a/lib/ai/providers/alibaba-image.ts +++ b/lib/ai/providers/alibaba-image.ts @@ -286,6 +286,7 @@ export function createAlibabaImage({ apiKey, baseURL }: AlibabaImageConfig) { doGenerate: async (options: { messages: Array<{ role: string; content: string | Array<{ type: string; text?: string; image?: string }> }>; imageParams?: AlibabaImageParams & { aspectRatio?: string; imageSize?: string; imageCount?: number }; + modelDisplayName?: string; // 🆕 模型显示名称,用于错误提示 }) => { console.log("[Alibaba Image] doGenerate called"); console.log("[Alibaba Image] Model:", modelId); @@ -344,6 +345,12 @@ export function createAlibabaImage({ apiKey, baseURL }: AlibabaImageConfig) { throw new Error("No prompt found in message"); } + // 验证:qwen-image-edit 系列模型必须有输入图片 + if (imageUrls.length === 0) { + const modelName = options.modelDisplayName || modelId; + throw new Error(`「${modelName}」是图片编辑模型,需要至少上传一张图片才能进行编辑。如需纯文生图,请使用其他生图模型。`); + } + // 构建参数 const params: AlibabaImageParams = { n: options.imageParams?.imageCount || options.imageParams?.n || 1, @@ -366,7 +373,10 @@ export function createAlibabaImage({ apiKey, baseURL }: AlibabaImageConfig) { params.size = sizeMap[options.imageParams.imageSize] || "1024*1024"; } - console.log("[Alibaba Image] Prompt:", prompt.substring(0, 100) + "..."); + // 根据图片数量确定编辑模式 + const editMode = imageUrls.length === 1 ? "单图编辑" : `多图融合 (${imageUrls.length}张)`; + console.log("[Alibaba Image] 编辑模式:", editMode); + console.log("[Alibaba Image] Prompt:", prompt.substring(0, 100) + (prompt.length > 100 ? "..." : "")); console.log("[Alibaba Image] Input images:", imageUrls.length); console.log("[Alibaba Image] Final params:", params); @@ -403,6 +413,7 @@ export function createAlibabaImage({ apiKey, baseURL }: AlibabaImageConfig) { doStream: async function* (options: { messages: Array<{ role: string; content: string | Array<{ type: string; text?: string; image?: string }> }>; imageParams?: AlibabaImageParams & { aspectRatio?: string; imageSize?: string; imageCount?: number }; + modelDisplayName?: string; }) { console.log("[Alibaba Image] doStream called (using doGenerate internally)");