use proxy if configured in all Gemini API requests

This commit is contained in:
Feng Yue
2025-08-31 01:21:25 +08:00
parent 1762669de4
commit b00d0eb9e1
3 changed files with 66 additions and 16 deletions

View File

@@ -2395,7 +2395,7 @@ router.post('/gemini-accounts/generate-auth-url', authenticateAdmin, async (req,
state: authState, state: authState,
codeVerifier, codeVerifier,
redirectUri: finalRedirectUri redirectUri: finalRedirectUri
} = await geminiAccountService.generateAuthUrl(state, redirectUri) } = await geminiAccountService.generateAuthUrl(state, redirectUri, proxy)
// 创建 OAuth 会话,包含 codeVerifier 和代理配置 // 创建 OAuth 会话,包含 codeVerifier 和代理配置
const sessionId = authState const sessionId = authState

View File

@@ -331,7 +331,17 @@ async function handleLoadCodeAssist(req, res) {
apiKeyId: req.apiKey?.id || 'unknown' apiKeyId: req.apiKey?.id || 'unknown'
}) })
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken) // 解析账户的代理配置
let proxyConfig = null
if (account.proxy) {
try {
proxyConfig = typeof account.proxy === 'string' ? JSON.parse(account.proxy) : account.proxy
} catch (e) {
logger.warn('Failed to parse proxy configuration:', e)
}
}
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken, proxyConfig)
// 根据账户配置决定项目ID // 根据账户配置决定项目ID
// 1. 如果账户有项目ID -> 使用账户的项目ID强制覆盖 // 1. 如果账户有项目ID -> 使用账户的项目ID强制覆盖
@@ -348,7 +358,11 @@ async function handleLoadCodeAssist(req, res) {
logger.info('No project ID in account for loadCodeAssist, removing project parameter') logger.info('No project ID in account for loadCodeAssist, removing project parameter')
} }
const response = await geminiAccountService.loadCodeAssist(client, effectiveProjectId) const response = await geminiAccountService.loadCodeAssist(
client,
effectiveProjectId,
proxyConfig
)
res.json(response) res.json(response)
} catch (error) { } catch (error) {
@@ -387,7 +401,17 @@ async function handleOnboardUser(req, res) {
apiKeyId: req.apiKey?.id || 'unknown' apiKeyId: req.apiKey?.id || 'unknown'
}) })
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken) // 解析账户的代理配置
let proxyConfig = null
if (account.proxy) {
try {
proxyConfig = typeof account.proxy === 'string' ? JSON.parse(account.proxy) : account.proxy
} catch (e) {
logger.warn('Failed to parse proxy configuration:', e)
}
}
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken, proxyConfig)
// 根据账户配置决定项目ID // 根据账户配置决定项目ID
// 1. 如果账户有项目ID -> 使用账户的项目ID强制覆盖 // 1. 如果账户有项目ID -> 使用账户的项目ID强制覆盖
@@ -410,7 +434,8 @@ async function handleOnboardUser(req, res) {
client, client,
tierId, tierId,
effectiveProjectId, // 使用处理后的项目ID effectiveProjectId, // 使用处理后的项目ID
metadata metadata,
proxyConfig
) )
res.json(response) res.json(response)
@@ -419,7 +444,8 @@ async function handleOnboardUser(req, res) {
const response = await geminiAccountService.setupUser( const response = await geminiAccountService.setupUser(
client, client,
effectiveProjectId, // 使用处理后的项目ID effectiveProjectId, // 使用处理后的项目ID
metadata metadata,
proxyConfig
) )
res.json(response) res.json(response)
@@ -460,7 +486,8 @@ async function handleCountTokens(req, res) {
sessionHash, sessionHash,
model model
) )
const { accessToken, refreshToken } = await geminiAccountService.getAccount(accountId) const account = await geminiAccountService.getAccount(accountId)
const { accessToken, refreshToken } = account
const version = req.path.includes('v1beta') ? 'v1beta' : 'v1internal' const version = req.path.includes('v1beta') ? 'v1beta' : 'v1internal'
logger.info(`CountTokens request (${version})`, { logger.info(`CountTokens request (${version})`, {
@@ -469,8 +496,18 @@ async function handleCountTokens(req, res) {
apiKeyId: req.apiKey?.id || 'unknown' apiKeyId: req.apiKey?.id || 'unknown'
}) })
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken) // 解析账户的代理配置
const response = await geminiAccountService.countTokens(client, contents, model) let proxyConfig = null
if (account.proxy) {
try {
proxyConfig = typeof account.proxy === 'string' ? JSON.parse(account.proxy) : account.proxy
} catch (e) {
logger.warn('Failed to parse proxy configuration:', e)
}
}
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken, proxyConfig)
const response = await geminiAccountService.countTokens(client, contents, model, proxyConfig)
res.json(response) res.json(response)
} catch (error) { } catch (error) {
@@ -544,8 +581,6 @@ async function handleGenerateContent(req, res) {
apiKeyId: req.apiKey?.id || 'unknown' apiKeyId: req.apiKey?.id || 'unknown'
}) })
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken)
// 解析账户的代理配置 // 解析账户的代理配置
let proxyConfig = null let proxyConfig = null
if (account.proxy) { if (account.proxy) {
@@ -556,6 +591,8 @@ async function handleGenerateContent(req, res) {
} }
} }
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken, proxyConfig)
const response = await geminiAccountService.generateContent( const response = await geminiAccountService.generateContent(
client, client,
{ model, request: actualRequestData }, { model, request: actualRequestData },
@@ -680,8 +717,6 @@ async function handleStreamGenerateContent(req, res) {
} }
}) })
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken)
// 解析账户的代理配置 // 解析账户的代理配置
let proxyConfig = null let proxyConfig = null
if (account.proxy) { if (account.proxy) {
@@ -692,6 +727,8 @@ async function handleStreamGenerateContent(req, res) {
} }
} }
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken, proxyConfig)
const streamResponse = await geminiAccountService.generateContentStream( const streamResponse = await geminiAccountService.generateContentStream(
client, client,
{ model, request: actualRequestData }, { model, request: actualRequestData },

View File

@@ -311,6 +311,16 @@ router.post('/v1/chat/completions', authenticateApiKey, async (req, res) => {
// 标记账户被使用 // 标记账户被使用
await geminiAccountService.markAccountUsed(account.id) await geminiAccountService.markAccountUsed(account.id)
// 解析账户的代理配置
let proxyConfig = null
if (account.proxy) {
try {
proxyConfig = typeof account.proxy === 'string' ? JSON.parse(account.proxy) : account.proxy
} catch (e) {
logger.warn('Failed to parse proxy configuration:', e)
}
}
// 创建中止控制器 // 创建中止控制器
abortController = new AbortController() abortController = new AbortController()
@@ -325,7 +335,8 @@ router.post('/v1/chat/completions', authenticateApiKey, async (req, res) => {
// 获取OAuth客户端 // 获取OAuth客户端
const client = await geminiAccountService.getOauthClient( const client = await geminiAccountService.getOauthClient(
account.accessToken, account.accessToken,
account.refreshToken account.refreshToken,
proxyConfig
) )
if (actualStream) { if (actualStream) {
// 流式响应 // 流式响应
@@ -341,7 +352,8 @@ router.post('/v1/chat/completions', authenticateApiKey, async (req, res) => {
null, // user_prompt_id null, // user_prompt_id
account.projectId, // 使用有权限的项目ID account.projectId, // 使用有权限的项目ID
apiKeyData.id, // 使用 API Key ID 作为 session ID apiKeyData.id, // 使用 API Key ID 作为 session ID
abortController.signal // 传递中止信号 abortController.signal, // 传递中止信号
proxyConfig // 传递代理配置
) )
// 设置流式响应头 // 设置流式响应头
@@ -541,7 +553,8 @@ router.post('/v1/chat/completions', authenticateApiKey, async (req, res) => {
{ model, request: geminiRequestBody }, { model, request: geminiRequestBody },
null, // user_prompt_id null, // user_prompt_id
account.projectId, // 使用有权限的项目ID account.projectId, // 使用有权限的项目ID
apiKeyData.id // 使用 API Key ID 作为 session ID apiKeyData.id, // 使用 API Key ID 作为 session ID
proxyConfig // 传递代理配置
) )
// 转换为 OpenAI 格式并返回 // 转换为 OpenAI 格式并返回