fix(provider): 避免重复增加provider使用计数

当从provider池重新选择服务时跳过usageCount增加,因为初次选择时已经增加过。同时优化token刷新逻辑,合并强制刷新和即将过期的检查条件。
This commit is contained in:
hex2077 2025-12-04 12:53:17 +08:00
parent bc3725e901
commit 211d677d00
4 changed files with 25 additions and 20 deletions

View file

@ -395,9 +395,10 @@ export async function handleContentGenerationRequest(req, res, service, endpoint
console.log(`[Content Generation] Model: ${model}, Stream: ${isStream}`);
// 2.5. 如果使用了提供商池,根据模型重新选择提供商
// 注意:这里使用 skipUsageCount: true因为初次选择时已经增加了 usageCount
if (providerPoolManager && CONFIG.providerPools && CONFIG.providerPools[CONFIG.MODEL_PROVIDER]) {
const { getApiService } = await import('./service-manager.js');
service = await getApiService(CONFIG, model);
service = await getApiService(CONFIG, model, { skipUsageCount: true });
console.log(`[Content Generation] Re-selected service adapter based on model: ${model}`);
}

View file

@ -249,11 +249,12 @@ export class AntigravityApiService {
}
async initializeAuth(forceRefresh = false) {
if (this.authClient.credentials.access_token && !forceRefresh) {
// 检查 Token 是否即将过期
if (!this.isTokenExpiringSoon()) {
return;
}
// 检查是否需要刷新 Token
const needsRefresh = forceRefresh || this.isTokenExpiringSoon();
if (this.authClient.credentials.access_token && !needsRefresh) {
// Token 有效且不需要刷新
return;
}
// Antigravity 不支持 base64 配置,直接使用文件路径
@ -265,13 +266,13 @@ export class AntigravityApiService {
this.authClient.setCredentials(credentials);
console.log('[Antigravity Auth] Authentication configured successfully from file.');
if (forceRefresh) {
console.log('[Antigravity Auth] Forcing token refresh...');
if (needsRefresh) {
console.log('[Antigravity Auth] Token expiring soon or force refresh requested. Refreshing token...');
const { credentials: newCredentials } = await this.authClient.refreshAccessToken();
this.authClient.setCredentials(newCredentials);
// 保存刷新后的凭证
// 保存刷新后的凭证到文件
await fs.writeFile(credPath, JSON.stringify(newCredentials, null, 2));
console.log('[Antigravity Auth] Token refreshed and saved successfully.');
console.log(`[Antigravity Auth] Token refreshed and saved to ${credPath} successfully.`);
}
} catch (error) {
console.error('[Antigravity Auth] Error initializing authentication:', error.code);

View file

@ -98,7 +98,7 @@ export class ProviderPoolManager {
* @param {string} [requestedModel] - Optional. The model name to filter providers by.
* @returns {object|null} The selected provider's configuration, or null if no healthy provider is found.
*/
selectProvider(providerType, requestedModel = null) {
selectProvider(providerType, requestedModel = null, options = {}) {
// 参数校验
if (!providerType || typeof providerType !== 'string') {
this._log('error', `Invalid providerType: ${providerType}`);
@ -147,14 +147,15 @@ export class ProviderPoolManager {
// 更新下次轮询的索引
this.roundRobinIndex[indexKey] = (currentIndex + 1) % availableAndHealthyProviders.length;
// 更新使用信息
selected.config.lastUsed = new Date().toISOString();
selected.config.usageCount++;
// 更新使用信息(除非明确跳过)
if (!options.skipUsageCount) {
selected.config.lastUsed = new Date().toISOString();
selected.config.usageCount++;
// 使用防抖保存
this._debouncedSave(providerType);
}
this._log('debug', `Selected provider for ${providerType} (round-robin): ${selected.config.uuid}${requestedModel ? ` for model: ${requestedModel}` : ''}`);
// 使用防抖保存
this._debouncedSave(providerType);
this._log('debug', `Selected provider for ${providerType} (round-robin): ${selected.config.uuid}${requestedModel ? ` for model: ${requestedModel}` : ''}${options.skipUsageCount ? ' (skip usage count)' : ''}`);
return selected.config;
}

View file

@ -60,13 +60,15 @@ export async function initApiService(config) {
* Get API service adapter, considering provider pools
* @param {Object} config - The current request configuration
* @param {string} [requestedModel] - Optional. The model name to filter providers by.
* @param {Object} [options] - Optional. Additional options.
* @param {boolean} [options.skipUsageCount] - Optional. If true, skip incrementing usage count.
* @returns {Promise<Object>} The API service adapter
*/
export async function getApiService(config, requestedModel = null) {
export async function getApiService(config, requestedModel = null, options = {}) {
let serviceConfig = config;
if (providerPoolManager && config.providerPools && config.providerPools[config.MODEL_PROVIDER]) {
// 如果有号池管理器,并且当前模型提供者类型有对应的号池,则从号池中选择一个提供者配置
const selectedProviderConfig = providerPoolManager.selectProvider(config.MODEL_PROVIDER, requestedModel);
const selectedProviderConfig = providerPoolManager.selectProvider(config.MODEL_PROVIDER, requestedModel, options);
if (selectedProviderConfig) {
// 合并选中的提供者配置到当前请求的 config 中
serviceConfig = deepmerge(config, selectedProviderConfig);