fix: 修复部分账号转发gemini api失败的问题

This commit is contained in:
shaw
2025-09-12 11:41:14 +08:00
parent 9c4dc714f8
commit b7da43f615
3 changed files with 109 additions and 8 deletions

View File

@@ -366,6 +366,14 @@ async function handleLoadCodeAssist(req, res) {
proxyConfig
)
// 如果响应中包含 cloudaicompanionProject保存到账户作为临时项目 ID
if (response.cloudaicompanionProject && !account.projectId) {
await geminiAccountService.updateTempProjectId(accountId, response.cloudaicompanionProject)
logger.info(
`📋 Cached temporary projectId from loadCodeAssist: ${response.cloudaicompanionProject}`
)
}
res.json(response)
} catch (error) {
const version = req.path.includes('v1beta') ? 'v1beta' : 'v1internal'

View File

@@ -102,13 +102,46 @@ async function handleStandardGenerateContent(req, res) {
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken, proxyConfig)
// 使用账户的项目ID如果有的话
const effectiveProjectId = account.projectId || null
// 项目ID优先级账户配置的项目ID > 临时项目ID > 尝试获取
let effectiveProjectId = account.projectId || account.tempProjectId || null
// 如果没有任何项目ID尝试调用 loadCodeAssist 获取
if (!effectiveProjectId) {
try {
logger.info('📋 No projectId available, attempting to fetch from loadCodeAssist...')
const loadResponse = await geminiAccountService.loadCodeAssist(client, null, proxyConfig)
if (loadResponse.cloudaicompanionProject) {
effectiveProjectId = loadResponse.cloudaicompanionProject
// 保存临时项目ID
await geminiAccountService.updateTempProjectId(accountId, effectiveProjectId)
logger.info(`📋 Fetched and cached temporary projectId: ${effectiveProjectId}`)
}
} catch (loadError) {
logger.warn('Failed to fetch projectId from loadCodeAssist:', loadError.message)
}
}
// 如果还是没有项目ID返回错误
if (!effectiveProjectId) {
return res.status(403).json({
error: {
message:
'This account requires a project ID to be configured. Please configure a project ID in the account settings.',
type: 'configuration_required'
}
})
}
logger.info('📋 Standard API 项目ID处理逻辑', {
accountProjectId: account.projectId,
tempProjectId: account.tempProjectId,
effectiveProjectId,
decision: account.projectId ? '使用账户配置' : '不使用项目ID'
decision: account.projectId
? '使用账户配置'
: account.tempProjectId
? '使用临时项目ID'
: '从loadCodeAssist获取'
})
// 生成一个符合 Gemini CLI 格式的 user_prompt_id
@@ -119,7 +152,7 @@ async function handleStandardGenerateContent(req, res) {
client,
{ model, request: actualRequestData },
userPromptId, // 使用生成的 user_prompt_id
effectiveProjectId || 'oceanic-graph-cgcz4', // 如果没有项目ID使用默认值
effectiveProjectId, // 使用处理后的项目ID
req.apiKey?.id, // 使用 API Key ID 作为 session ID
proxyConfig
)
@@ -288,13 +321,46 @@ async function handleStandardStreamGenerateContent(req, res) {
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken, proxyConfig)
// 使用账户的项目ID如果有的话
const effectiveProjectId = account.projectId || null
// 项目ID优先级账户配置的项目ID > 临时项目ID > 尝试获取
let effectiveProjectId = account.projectId || account.tempProjectId || null
// 如果没有任何项目ID尝试调用 loadCodeAssist 获取
if (!effectiveProjectId) {
try {
logger.info('📋 No projectId available, attempting to fetch from loadCodeAssist...')
const loadResponse = await geminiAccountService.loadCodeAssist(client, null, proxyConfig)
if (loadResponse.cloudaicompanionProject) {
effectiveProjectId = loadResponse.cloudaicompanionProject
// 保存临时项目ID
await geminiAccountService.updateTempProjectId(accountId, effectiveProjectId)
logger.info(`📋 Fetched and cached temporary projectId: ${effectiveProjectId}`)
}
} catch (loadError) {
logger.warn('Failed to fetch projectId from loadCodeAssist:', loadError.message)
}
}
// 如果还是没有项目ID返回错误
if (!effectiveProjectId) {
return res.status(403).json({
error: {
message:
'This account requires a project ID to be configured. Please configure a project ID in the account settings.',
type: 'configuration_required'
}
})
}
logger.info('📋 Standard API 流式项目ID处理逻辑', {
accountProjectId: account.projectId,
tempProjectId: account.tempProjectId,
effectiveProjectId,
decision: account.projectId ? '使用账户配置' : '不使用项目ID'
decision: account.projectId
? '使用账户配置'
: account.tempProjectId
? '使用临时项目ID'
: '从loadCodeAssist获取'
})
// 生成一个符合 Gemini CLI 格式的 user_prompt_id
@@ -305,7 +371,7 @@ async function handleStandardStreamGenerateContent(req, res) {
client,
{ model, request: actualRequestData },
userPromptId, // 使用生成的 user_prompt_id
effectiveProjectId || 'oceanic-graph-cgcz4', // 如果没有项目ID使用默认值
effectiveProjectId, // 使用处理后的项目ID
req.apiKey?.id, // 使用 API Key ID 作为 session ID
abortController.signal,
proxyConfig

View File

@@ -394,6 +394,9 @@ async function createAccount(accountData) {
// 项目 IDGoogle Cloud/Workspace 账号需要)
projectId: accountData.projectId || '',
// 临时项目 ID从 loadCodeAssist 接口自动获取)
tempProjectId: accountData.tempProjectId || '',
// 支持的模型列表(可选)
supportedModels: accountData.supportedModels || [], // 空数组表示支持所有模型
@@ -1426,6 +1429,29 @@ async function generateContentStream(
return response.data // 返回流对象
}
// 更新账户的临时项目 ID
async function updateTempProjectId(accountId, tempProjectId) {
if (!tempProjectId) {
return
}
try {
const account = await getAccount(accountId)
if (!account) {
logger.warn(`Account ${accountId} not found when updating tempProjectId`)
return
}
// 只有在没有固定项目 ID 的情况下才更新临时项目 ID
if (!account.projectId && tempProjectId !== account.tempProjectId) {
await updateAccount(accountId, { tempProjectId })
logger.info(`Updated tempProjectId for account ${accountId}: ${tempProjectId}`)
}
} catch (error) {
logger.error(`Failed to update tempProjectId for account ${accountId}:`, error)
}
}
module.exports = {
generateAuthUrl,
pollAuthorizationStatus,
@@ -1454,6 +1480,7 @@ module.exports = {
countTokens,
generateContent,
generateContentStream,
updateTempProjectId,
OAUTH_CLIENT_ID,
OAUTH_SCOPES
}