diff --git a/lib/ai/providers/volcano-vision.ts b/lib/ai/providers/volcano-vision.ts index ea1ac890f..dbbe6e468 100644 --- a/lib/ai/providers/volcano-vision.ts +++ b/lib/ai/providers/volcano-vision.ts @@ -191,37 +191,6 @@ function formatImageResponse(images: Array<{ thumbnail: string; original: string .join("\n\n"); } -/** - * 下载图片并转换为 Base64 - */ -async function urlToBase64(url: string): Promise { - try { - console.log("[Volcano Vision] Converting image to Base64:", url.substring(0, 100) + "..."); - const response = await fetch(url); - if (!response.ok) { - throw new Error(`Failed to fetch image: ${response.status} ${response.statusText}`); - } - - const arrayBuffer = await response.arrayBuffer(); - const buffer = Buffer.from(arrayBuffer); - const base64 = buffer.toString('base64'); - - // 从 URL 推断图片格式 - let format = 'jpeg'; // 默认 - if (url.includes('.png')) format = 'png'; - else if (url.includes('.webp')) format = 'webp'; - else if (url.includes('.gif')) format = 'gif'; - else if (url.includes('.jpg') || url.includes('.jpeg')) format = 'jpeg'; - - const result = `data:image/${format};base64,${base64}`; - console.log("[Volcano Vision] ✅ Converted to Base64 (format:", format, ", size:", (base64.length / 1024).toFixed(2), "KB)"); - return result; - } catch (error) { - console.error("[Volcano Vision] ❌ Failed to convert image to Base64:", error); - throw error; - } -} - /** * 将消息转换为火山引擎 API 格式 */ @@ -274,16 +243,19 @@ async function convertMessagesToVolcanoFormat(messages: any[]): Promise<{ prompt console.log("[Volcano Vision] Extracted prompt:", prompt.substring(0, 100)); console.log("[Volcano Vision] Extracted images count:", images.length); - // 将所有图片 URL 转换为 Base64 - const base64Images: string[] = []; + // 🆕 直接使用图片URL,不再转换Base64(既梦API支持URL格式) + // 只有当图片是Base64格式时才保持原样 + const processedImages: string[] = []; for (const imageUrl of images) { - // 如果已经是 Base64 格式,直接使用 if (imageUrl.startsWith('data:image')) { - base64Images.push(imageUrl); + // Base64格式:需要先上传到S3获取URL + console.log("[Volcano Vision] Found Base64 image, uploading to S3..."); + const uploaded = await uploadImageToS3(imageUrl); + processedImages.push(uploaded.original); } else { - // 否则下载并转换 - const base64Image = await urlToBase64(imageUrl); - base64Images.push(base64Image); + // URL格式:直接使用 + processedImages.push(imageUrl); + console.log("[Volcano Vision] Using image URL directly:", imageUrl.substring(0, 80) + "..."); } } @@ -295,10 +267,10 @@ async function convertMessagesToVolcanoFormat(messages: any[]): Promise<{ prompt // 构建请求体 const result: { prompt: string; image?: string | string[] } = { prompt: enhancedPrompt }; - if (base64Images.length === 1) { - result.image = base64Images[0]; - } else if (base64Images.length > 1) { - result.image = base64Images; // 多图直接传数组 + if (processedImages.length === 1) { + result.image = processedImages[0]; + } else if (processedImages.length > 1) { + result.image = processedImages; // 多图直接传数组 } return result; @@ -319,7 +291,7 @@ async function sendVolcanoRequest( console.log("[Volcano Vision] Sending non-stream request to:", url); console.log("[Volcano Vision] Using model:", modelId); - // 转换消息格式(含 Base64 转换) + // 转换消息格式(直接使用URL) let { prompt, image } = await convertMessagesToVolcanoFormat(messages); // 根据 maxImages 参数优化提示词 @@ -452,7 +424,7 @@ async function* sendVolcanoStreamRequest( console.log("[Volcano Vision] Sending stream request to:", url); console.log("[Volcano Vision] Using model:", modelId); - // 转换消息格式(含 Base64 转换) + // 转换消息格式(直接使用URL) const { prompt, image } = await convertMessagesToVolcanoFormat(messages); console.log("[Volcano Vision] Prompt:", prompt.substring(0, 100) + "...");