feat: Claude Console账号增强,升级模型支持列表为模型映射表!

This commit is contained in:
KevinLiao
2025-07-30 23:13:59 +08:00
parent acf8dbb970
commit 3c797a85e0
16 changed files with 289 additions and 102 deletions

View File

@@ -25,7 +25,7 @@ class ClaudeConsoleAccountService {
apiUrl = '',
apiKey = '',
priority = 50, // 默认优先级501-100
supportedModels = [], // 支持的模型列表,空数组表示支持所有
supportedModels = [], // 支持的模型列表或映射表,空数组/对象表示支持所有
userAgent = 'claude-cli/1.0.61 (console, cli)',
rateLimitDuration = 60, // 限流时间(分钟)
proxy = null,
@@ -41,6 +41,9 @@ class ClaudeConsoleAccountService {
const accountId = uuidv4();
// 处理 supportedModels确保向后兼容
const processedModels = this._processModelMapping(supportedModels);
const accountData = {
id: accountId,
platform: 'claude-console',
@@ -49,7 +52,7 @@ class ClaudeConsoleAccountService {
apiUrl: apiUrl,
apiKey: this._encryptSensitiveData(apiKey),
priority: priority.toString(),
supportedModels: JSON.stringify(supportedModels),
supportedModels: JSON.stringify(processedModels),
userAgent,
rateLimitDuration: rateLimitDuration.toString(),
proxy: proxy ? JSON.stringify(proxy) : '',
@@ -209,7 +212,9 @@ class ClaudeConsoleAccountService {
if (updates.priority !== undefined) updatedData.priority = updates.priority.toString();
if (updates.supportedModels !== undefined) {
logger.debug(`[DEBUG] Updating supportedModels: ${JSON.stringify(updates.supportedModels)}`);
updatedData.supportedModels = JSON.stringify(updates.supportedModels);
// 处理 supportedModels,确保向后兼容
const processedModels = this._processModelMapping(updates.supportedModels);
updatedData.supportedModels = JSON.stringify(processedModels);
}
if (updates.userAgent !== undefined) updatedData.userAgent = updates.userAgent;
if (updates.rateLimitDuration !== undefined) updatedData.rateLimitDuration = updates.rateLimitDuration.toString();
@@ -488,6 +493,55 @@ class ClaudeConsoleAccountService {
minutesRemaining: 0
};
}
// 🔄 处理模型映射,确保向后兼容
_processModelMapping(supportedModels) {
// 如果是空值,返回空对象(支持所有模型)
if (!supportedModels || (Array.isArray(supportedModels) && supportedModels.length === 0)) {
return {};
}
// 如果已经是对象格式(新的映射表格式),直接返回
if (typeof supportedModels === 'object' && !Array.isArray(supportedModels)) {
return supportedModels;
}
// 如果是数组格式(旧格式),转换为映射表
if (Array.isArray(supportedModels)) {
const mapping = {};
supportedModels.forEach(model => {
if (model && typeof model === 'string') {
mapping[model] = model; // 映射到自身
}
});
return mapping;
}
// 其他情况返回空对象
return {};
}
// 🔍 检查模型是否支持(用于调度)
isModelSupported(modelMapping, requestedModel) {
// 如果映射表为空,支持所有模型
if (!modelMapping || Object.keys(modelMapping).length === 0) {
return true;
}
// 检查请求的模型是否在映射表的键中
return Object.prototype.hasOwnProperty.call(modelMapping, requestedModel);
}
// 🔄 获取映射后的模型名称
getMappedModel(modelMapping, requestedModel) {
// 如果映射表为空,返回原模型
if (!modelMapping || Object.keys(modelMapping).length === 0) {
return requestedModel;
}
// 返回映射后的模型,如果不存在则返回原模型
return modelMapping[requestedModel] || requestedModel;
}
}
module.exports = new ClaudeConsoleAccountService();

View File

@@ -25,6 +25,22 @@ class ClaudeConsoleRelayService {
logger.debug(`🔑 Account has apiKey: ${!!account.apiKey}`);
logger.debug(`📝 Request model: ${requestBody.model}`);
// 处理模型映射
let mappedModel = requestBody.model;
if (account.supportedModels && typeof account.supportedModels === 'object' && !Array.isArray(account.supportedModels)) {
const newModel = claudeConsoleAccountService.getMappedModel(account.supportedModels, requestBody.model);
if (newModel !== requestBody.model) {
logger.info(`🔄 Mapping model from ${requestBody.model} to ${newModel}`);
mappedModel = newModel;
}
}
// 创建修改后的请求体
const modifiedRequestBody = {
...requestBody,
model: mappedModel
};
// 模型兼容性检查已经在调度器中完成,这里不需要再检查
// 创建代理agent
@@ -67,7 +83,7 @@ class ClaudeConsoleRelayService {
const requestConfig = {
method: 'POST',
url: apiEndpoint,
data: requestBody,
data: modifiedRequestBody,
headers: {
'Content-Type': 'application/json',
'x-api-key': account.apiKey,

View File

@@ -174,10 +174,20 @@ class UnifiedClaudeScheduler {
account.schedulable !== false) { // 检查是否可调度
// 检查模型支持(如果有请求的模型)
if (requestedModel && account.supportedModels && account.supportedModels.length > 0) {
if (!account.supportedModels.includes(requestedModel)) {
logger.info(`🚫 Claude Console account ${account.name} does not support model ${requestedModel}`);
continue;
if (requestedModel && account.supportedModels) {
// 兼容旧格式(数组)和新格式(对象)
if (Array.isArray(account.supportedModels)) {
// 旧格式:数组
if (account.supportedModels.length > 0 && !account.supportedModels.includes(requestedModel)) {
logger.info(`🚫 Claude Console account ${account.name} does not support model ${requestedModel}`);
continue;
}
} else if (typeof account.supportedModels === 'object') {
// 新格式:映射表
if (Object.keys(account.supportedModels).length > 0 && !claudeConsoleAccountService.isModelSupported(account.supportedModels, requestedModel)) {
logger.info(`🚫 Claude Console account ${account.name} does not support model ${requestedModel}`);
continue;
}
}
}