From e2cece6162abcfe87d72bb942c863889b5edde3d Mon Sep 17 00:00:00 2001 From: shaw Date: Tue, 22 Jul 2025 18:36:53 +0800 Subject: [PATCH] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8Dx-request-id=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/claudeRelayService.js | 12 ++++++++- src/services/openaiToClaude.js | 41 +++++++++++++++++++++++++----- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/services/claudeRelayService.js b/src/services/claudeRelayService.js index e58ce36c..11ccaaa3 100644 --- a/src/services/claudeRelayService.js +++ b/src/services/claudeRelayService.js @@ -318,12 +318,22 @@ class ClaudeRelayService { 'transfer-encoding' ]; + // 应该保留的 headers(用于会话一致性和追踪) + const allowedHeaders = [ + 'x-request-id' + ]; + const filteredHeaders = {}; // 转发客户端的非敏感 headers Object.keys(clientHeaders || {}).forEach(key => { const lowerKey = key.toLowerCase(); - if (!sensitiveHeaders.includes(lowerKey)) { + // 如果在允许列表中,直接保留 + if (allowedHeaders.includes(lowerKey)) { + filteredHeaders[key] = clientHeaders[key]; + } + // 如果不在敏感列表中,也保留 + else if (!sensitiveHeaders.includes(lowerKey)) { filteredHeaders[key] = clientHeaders[key]; } }); diff --git a/src/services/openaiToClaude.js b/src/services/openaiToClaude.js index 9e505d6e..48131405 100644 --- a/src/services/openaiToClaude.js +++ b/src/services/openaiToClaude.js @@ -219,14 +219,41 @@ class OpenAIToClaudeConverter { text: item.text }; } else if (item.type === 'image_url') { - return { - type: 'image', - source: { - type: 'base64', - media_type: 'image/jpeg', // 默认类型 - data: item.image_url.url.split(',')[1] // 假设是 base64 + const imageUrl = item.image_url.url; + + // 检查是否是 base64 格式的图片 + if (imageUrl.startsWith('data:')) { + // 解析 data URL: data:image/jpeg;base64,/9j/4AAQ... + const matches = imageUrl.match(/^data:([^;]+);base64,(.+)$/); + if (matches) { + const mediaType = matches[1]; // e.g., 'image/jpeg', 'image/png' + const base64Data = matches[2]; + + return { + type: 'image', + source: { + type: 'base64', + media_type: mediaType, + data: base64Data + } + }; + } else { + // 如果格式不正确,尝试使用默认处理 + logger.warn('⚠️ Invalid base64 image format, using default parsing'); + return { + type: 'image', + source: { + type: 'base64', + media_type: 'image/jpeg', + data: imageUrl.split(',')[1] || '' + } + }; } - }; + } else { + // 如果是 URL 格式的图片,Claude 不支持直接 URL,需要报错 + logger.error('❌ URL images are not supported by Claude API, only base64 format is accepted'); + throw new Error('Claude API only supports base64 encoded images, not URLs. Please convert the image to base64 format.'); + } } return item; });