mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-22 16:43:35 +00:00
fix: 修复gemini api账户转发的传参问题
This commit is contained in:
16
README.md
16
README.md
@@ -504,6 +504,22 @@ Droid CLI 读取 `~/.factory/config.json`。可以在该文件中添加自定义
|
|||||||
"api_key": "后台创建的API密钥",
|
"api_key": "后台创建的API密钥",
|
||||||
"provider": "openai",
|
"provider": "openai",
|
||||||
"max_tokens": 16384
|
"max_tokens": 16384
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model_display_name": "Gemini-3-Pro [crs]",
|
||||||
|
"model": "gemini-3-pro-preview",
|
||||||
|
"base_url": "http://127.0.0.1:3000/droid/comm/v1/",
|
||||||
|
"api_key": "后台创建的API密钥",
|
||||||
|
"provider": "generic-chat-completion-api",
|
||||||
|
"max_tokens": 32000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model_display_name": "GLM-4.6 [crs]",
|
||||||
|
"model": "glm-4.6",
|
||||||
|
"base_url": "http://127.0.0.1:3000/droid/comm/v1/",
|
||||||
|
"api_key": "后台创建的API密钥",
|
||||||
|
"provider": "generic-chat-completion-api",
|
||||||
|
"max_tokens": 32000
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,6 +109,42 @@ function isReadableStream(value) {
|
|||||||
return value && typeof value.on === 'function' && typeof value.pipe === 'function'
|
return value && typeof value.on === 'function' && typeof value.pipe === 'function'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理 contents 中 functionResponse 不被标准 Gemini API 支持的字段
|
||||||
|
* 标准 Gemini API (generativelanguage.googleapis.com) 的 functionResponse 只支持 name 和 response 字段,不支持 id 字段
|
||||||
|
* 注意:此函数仅用于 API Key 账户,OAuth 账户使用的 Cloud Code Assist API 可能支持额外字段
|
||||||
|
*/
|
||||||
|
function sanitizeFunctionResponsesForApiKey(contents) {
|
||||||
|
if (!contents || !Array.isArray(contents)) {
|
||||||
|
return contents
|
||||||
|
}
|
||||||
|
|
||||||
|
return contents.map((content) => {
|
||||||
|
if (!content.parts || !Array.isArray(content.parts)) {
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
|
||||||
|
const sanitizedParts = content.parts.map((part) => {
|
||||||
|
if (part.functionResponse) {
|
||||||
|
// 只保留标准 Gemini API 支持的字段:name 和 response
|
||||||
|
const { name, response } = part.functionResponse
|
||||||
|
return {
|
||||||
|
functionResponse: {
|
||||||
|
name,
|
||||||
|
response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return part
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
...content,
|
||||||
|
parts: sanitizedParts
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取可读流内容为字符串
|
* 读取可读流内容为字符串
|
||||||
*/
|
*/
|
||||||
@@ -351,7 +387,9 @@ async function handleMessages(req, res) {
|
|||||||
url: apiUrl,
|
url: apiUrl,
|
||||||
data: requestBody,
|
data: requestBody,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json',
|
||||||
|
'x-api-key': account.apiKey,
|
||||||
|
'x-goog-api-key': account.apiKey
|
||||||
},
|
},
|
||||||
responseType: stream ? 'stream' : 'json',
|
responseType: stream ? 'stream' : 'json',
|
||||||
signal: abortController.signal
|
signal: abortController.signal
|
||||||
@@ -1659,6 +1697,9 @@ async function handleStandardGenerateContent(req, res) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// API Key 账户:清理 functionResponse 中标准 Gemini API 不支持的字段(如 id)
|
||||||
|
actualRequestData.contents = sanitizeFunctionResponsesForApiKey(actualRequestData.contents)
|
||||||
|
|
||||||
logger.info(`Standard Gemini API generateContent request (${version}) - API Key Account`, {
|
logger.info(`Standard Gemini API generateContent request (${version}) - API Key Account`, {
|
||||||
model,
|
model,
|
||||||
accountId: actualAccountId,
|
accountId: actualAccountId,
|
||||||
@@ -1910,6 +1951,9 @@ async function handleStandardStreamGenerateContent(req, res) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// API Key 账户:清理 functionResponse 中标准 Gemini API 不支持的字段(如 id)
|
||||||
|
actualRequestData.contents = sanitizeFunctionResponsesForApiKey(actualRequestData.contents)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
`Standard Gemini API streamGenerateContent request (${version}) - API Key Account`,
|
`Standard Gemini API streamGenerateContent request (${version}) - API Key Account`,
|
||||||
{
|
{
|
||||||
@@ -1956,7 +2000,9 @@ async function handleStandardStreamGenerateContent(req, res) {
|
|||||||
url: apiUrl,
|
url: apiUrl,
|
||||||
data: actualRequestData,
|
data: actualRequestData,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json',
|
||||||
|
'x-api-key': account.apiKey,
|
||||||
|
'x-goog-api-key': account.apiKey
|
||||||
},
|
},
|
||||||
responseType: 'stream',
|
responseType: 'stream',
|
||||||
signal: abortController.signal
|
signal: abortController.signal
|
||||||
|
|||||||
Reference in New Issue
Block a user