mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 00:53:33 +00:00
fix: 修复部分账号转发gemini api失败的问题
This commit is contained in:
@@ -366,6 +366,14 @@ async function handleLoadCodeAssist(req, res) {
|
|||||||
proxyConfig
|
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)
|
res.json(response)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const version = req.path.includes('v1beta') ? 'v1beta' : 'v1internal'
|
const version = req.path.includes('v1beta') ? 'v1beta' : 'v1internal'
|
||||||
|
|||||||
@@ -102,13 +102,46 @@ async function handleStandardGenerateContent(req, res) {
|
|||||||
|
|
||||||
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken, proxyConfig)
|
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken, proxyConfig)
|
||||||
|
|
||||||
// 使用账户的项目ID(如果有的话)
|
// 项目ID优先级:账户配置的项目ID > 临时项目ID > 尝试获取
|
||||||
const effectiveProjectId = account.projectId || null
|
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处理逻辑', {
|
logger.info('📋 Standard API 项目ID处理逻辑', {
|
||||||
accountProjectId: account.projectId,
|
accountProjectId: account.projectId,
|
||||||
|
tempProjectId: account.tempProjectId,
|
||||||
effectiveProjectId,
|
effectiveProjectId,
|
||||||
decision: account.projectId ? '使用账户配置' : '不使用项目ID'
|
decision: account.projectId
|
||||||
|
? '使用账户配置'
|
||||||
|
: account.tempProjectId
|
||||||
|
? '使用临时项目ID'
|
||||||
|
: '从loadCodeAssist获取'
|
||||||
})
|
})
|
||||||
|
|
||||||
// 生成一个符合 Gemini CLI 格式的 user_prompt_id
|
// 生成一个符合 Gemini CLI 格式的 user_prompt_id
|
||||||
@@ -119,7 +152,7 @@ async function handleStandardGenerateContent(req, res) {
|
|||||||
client,
|
client,
|
||||||
{ model, request: actualRequestData },
|
{ model, request: actualRequestData },
|
||||||
userPromptId, // 使用生成的 user_prompt_id
|
userPromptId, // 使用生成的 user_prompt_id
|
||||||
effectiveProjectId || 'oceanic-graph-cgcz4', // 如果没有项目ID,使用默认值
|
effectiveProjectId, // 使用处理后的项目ID
|
||||||
req.apiKey?.id, // 使用 API Key ID 作为 session ID
|
req.apiKey?.id, // 使用 API Key ID 作为 session ID
|
||||||
proxyConfig
|
proxyConfig
|
||||||
)
|
)
|
||||||
@@ -288,13 +321,46 @@ async function handleStandardStreamGenerateContent(req, res) {
|
|||||||
|
|
||||||
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken, proxyConfig)
|
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken, proxyConfig)
|
||||||
|
|
||||||
// 使用账户的项目ID(如果有的话)
|
// 项目ID优先级:账户配置的项目ID > 临时项目ID > 尝试获取
|
||||||
const effectiveProjectId = account.projectId || null
|
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处理逻辑', {
|
logger.info('📋 Standard API 流式项目ID处理逻辑', {
|
||||||
accountProjectId: account.projectId,
|
accountProjectId: account.projectId,
|
||||||
|
tempProjectId: account.tempProjectId,
|
||||||
effectiveProjectId,
|
effectiveProjectId,
|
||||||
decision: account.projectId ? '使用账户配置' : '不使用项目ID'
|
decision: account.projectId
|
||||||
|
? '使用账户配置'
|
||||||
|
: account.tempProjectId
|
||||||
|
? '使用临时项目ID'
|
||||||
|
: '从loadCodeAssist获取'
|
||||||
})
|
})
|
||||||
|
|
||||||
// 生成一个符合 Gemini CLI 格式的 user_prompt_id
|
// 生成一个符合 Gemini CLI 格式的 user_prompt_id
|
||||||
@@ -305,7 +371,7 @@ async function handleStandardStreamGenerateContent(req, res) {
|
|||||||
client,
|
client,
|
||||||
{ model, request: actualRequestData },
|
{ model, request: actualRequestData },
|
||||||
userPromptId, // 使用生成的 user_prompt_id
|
userPromptId, // 使用生成的 user_prompt_id
|
||||||
effectiveProjectId || 'oceanic-graph-cgcz4', // 如果没有项目ID,使用默认值
|
effectiveProjectId, // 使用处理后的项目ID
|
||||||
req.apiKey?.id, // 使用 API Key ID 作为 session ID
|
req.apiKey?.id, // 使用 API Key ID 作为 session ID
|
||||||
abortController.signal,
|
abortController.signal,
|
||||||
proxyConfig
|
proxyConfig
|
||||||
|
|||||||
@@ -394,6 +394,9 @@ async function createAccount(accountData) {
|
|||||||
// 项目 ID(Google Cloud/Workspace 账号需要)
|
// 项目 ID(Google Cloud/Workspace 账号需要)
|
||||||
projectId: accountData.projectId || '',
|
projectId: accountData.projectId || '',
|
||||||
|
|
||||||
|
// 临时项目 ID(从 loadCodeAssist 接口自动获取)
|
||||||
|
tempProjectId: accountData.tempProjectId || '',
|
||||||
|
|
||||||
// 支持的模型列表(可选)
|
// 支持的模型列表(可选)
|
||||||
supportedModels: accountData.supportedModels || [], // 空数组表示支持所有模型
|
supportedModels: accountData.supportedModels || [], // 空数组表示支持所有模型
|
||||||
|
|
||||||
@@ -1426,6 +1429,29 @@ async function generateContentStream(
|
|||||||
return response.data // 返回流对象
|
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 = {
|
module.exports = {
|
||||||
generateAuthUrl,
|
generateAuthUrl,
|
||||||
pollAuthorizationStatus,
|
pollAuthorizationStatus,
|
||||||
@@ -1454,6 +1480,7 @@ module.exports = {
|
|||||||
countTokens,
|
countTokens,
|
||||||
generateContent,
|
generateContent,
|
||||||
generateContentStream,
|
generateContentStream,
|
||||||
|
updateTempProjectId,
|
||||||
OAUTH_CLIENT_ID,
|
OAUTH_CLIENT_ID,
|
||||||
OAUTH_SCOPES
|
OAUTH_SCOPES
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user