fix: 既梦API直接使用图片URL,不再转Base64
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

- 删除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");
}
/**
* 下载图片并转换为 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 格式
*/
@ -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) + "...");