fix: 修复gemini api账户转发的传参问题

This commit is contained in:
shaw
2025-11-28 16:20:26 +08:00
parent 28caa93d99
commit 4a0ba6ed63
2 changed files with 64 additions and 2 deletions

View File

@@ -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
} }
] ]
} }

View File

@@ -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