fix: 既梦API直接使用图片URL,不再转Base64

- 删除urlToBase64函数
- 直接传递图片URL给既梦API(API原生支持)
- 只有前端上传的Base64图片才需要先上传S3获取URL
- 大幅减少请求体大小和处理时间

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Your Name 2026-01-31 23:59:51 +08:00
parent 04bd6dda32
commit 6ccdd73c65

View File

@ -191,37 +191,6 @@ function formatImageResponse(images: Array<{ thumbnail: string; original: string
.join("\n\n"); .join("\n\n");
} }
/**
* 下载图片并转换为 Base64
*/
async function urlToBase64(url: string): Promise<string> {
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 格式 * 将消息转换为火山引擎 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 prompt:", prompt.substring(0, 100));
console.log("[Volcano Vision] Extracted images count:", images.length); console.log("[Volcano Vision] Extracted images count:", images.length);
// 将所有图片 URL 转换为 Base64 // 🆕 直接使用图片URL,不再转换Base64(既梦API支持URL格式)
const base64Images: string[] = []; // 只有当图片是Base64格式时才保持原样
const processedImages: string[] = [];
for (const imageUrl of images) { for (const imageUrl of images) {
// 如果已经是 Base64 格式,直接使用
if (imageUrl.startsWith('data:image')) { 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 { } else {
// 否则下载并转换 // URL格式:直接使用
const base64Image = await urlToBase64(imageUrl); processedImages.push(imageUrl);
base64Images.push(base64Image); 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 }; const result: { prompt: string; image?: string | string[] } = { prompt: enhancedPrompt };
if (base64Images.length === 1) { if (processedImages.length === 1) {
result.image = base64Images[0]; result.image = processedImages[0];
} else if (base64Images.length > 1) { } else if (processedImages.length > 1) {
result.image = base64Images; // 多图直接传数组 result.image = processedImages; // 多图直接传数组
} }
return result; return result;
@ -319,7 +291,7 @@ async function sendVolcanoRequest(
console.log("[Volcano Vision] Sending non-stream request to:", url); console.log("[Volcano Vision] Sending non-stream request to:", url);
console.log("[Volcano Vision] Using model:", modelId); console.log("[Volcano Vision] Using model:", modelId);
// 转换消息格式(含 Base64 转换) // 转换消息格式(直接使用URL)
let { prompt, image } = await convertMessagesToVolcanoFormat(messages); let { prompt, image } = await convertMessagesToVolcanoFormat(messages);
// 根据 maxImages 参数优化提示词 // 根据 maxImages 参数优化提示词
@ -452,7 +424,7 @@ async function* sendVolcanoStreamRequest(
console.log("[Volcano Vision] Sending stream request to:", url); console.log("[Volcano Vision] Sending stream request to:", url);
console.log("[Volcano Vision] Using model:", modelId); console.log("[Volcano Vision] Using model:", modelId);
// 转换消息格式(含 Base64 转换) // 转换消息格式(直接使用URL)
const { prompt, image } = await convertMessagesToVolcanoFormat(messages); const { prompt, image } = await convertMessagesToVolcanoFormat(messages);
console.log("[Volcano Vision] Prompt:", prompt.substring(0, 100) + "..."); console.log("[Volcano Vision] Prompt:", prompt.substring(0, 100) + "...");