feat(account): 支持 Pro 账号使用 Opus 4.5+ 模型

Opus 4.5 已对 Claude Pro 用户开放,调整账户模型限制逻辑:

- Pro 账号:支持 Opus 4.5+,不支持历史版本 (3.x/4.0/4.1)
- Free 账号:不支持任何 Opus 模型
- Max 账号:支持所有 Opus 版本

修改内容:
- 新增 isOpus45OrNewer() 函数用于精确识别模型版本
- 更新 claudeAccountService.js 中的账户选择逻辑
- 更新 unifiedClaudeScheduler.js 中的模型支持检查
- 新增测试脚本验证官方模型名称识别

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
lusipad
2025-12-05 07:38:55 +08:00
parent 1b18a1226d
commit b94bd2b822
4 changed files with 311 additions and 29 deletions

View File

@@ -70,9 +70,82 @@ function getVendorType(modelStr) {
return vendor
}
/**
* 检查模型是否为 Opus 4.5 或更新版本
* 支持格式:
* - 新格式: claude-opus-{major}[-{minor}][-date] 如 claude-opus-4-5-20251101
* - 新格式: claude-opus-{major}.{minor} 如 claude-opus-4.5
* - 旧格式: claude-{version}-opus[-date] 如 claude-3-opus-20240229
*
* @param {string} modelName - 模型名称
* @returns {boolean} - 是否为 Opus 4.5+
*/
function isOpus45OrNewer(modelName) {
if (!modelName) return false
const lowerModel = modelName.toLowerCase()
if (!lowerModel.includes('opus')) return false
// 处理 latest 特殊情况
if (lowerModel.includes('opus-latest') || lowerModel.includes('opus_latest')) {
return true
}
// 旧格式: claude-{version}-opus (版本在 opus 前面)
// 例如: claude-3-opus-20240229, claude-3.5-opus
const oldFormatMatch = lowerModel.match(/claude[- ](\d+)(?:[\.-](\d+))?[- ]opus/)
if (oldFormatMatch) {
const majorVersion = parseInt(oldFormatMatch[1], 10)
const minorVersion = oldFormatMatch[2] ? parseInt(oldFormatMatch[2], 10) : 0
// 旧格式的版本号指的是 Claude 大版本
if (majorVersion > 4) return true
if (majorVersion === 4 && minorVersion >= 5) return true
return false
}
// 新格式 1: opus-{major}.{minor} (点分隔)
// 例如: claude-opus-4.5, opus-4.5
const dotFormatMatch = lowerModel.match(/opus[- ]?(\d+)\.(\d+)/)
if (dotFormatMatch) {
const majorVersion = parseInt(dotFormatMatch[1], 10)
const minorVersion = parseInt(dotFormatMatch[2], 10)
if (majorVersion > 4) return true
if (majorVersion === 4 && minorVersion >= 5) return true
return false
}
// 新格式 2: opus-{major}[-{minor}][-date] (横线分隔)
// 例如: claude-opus-4-5-20251101, claude-opus-4-20250514, claude-opus-4-1-20250805
// 关键:小版本号必须是 1 位数字,且后面紧跟 8 位日期或结束
// 如果 opus-{major} 后面直接是 8 位日期,则没有小版本号
// 提取 opus 后面的部分
const opusIndex = lowerModel.indexOf('opus')
const afterOpus = lowerModel.substring(opusIndex + 4) // 'opus' 后面的内容
// 尝试匹配: -{major}-{minor}-{date} 或 -{major}-{date} 或 -{major}
// 小版本号只能是 1 位数字 (如 1, 5),不会是 2 位以上
const versionMatch = afterOpus.match(/^[- ](\d+)(?:[- ](\d)(?=[- ]\d{8}|$))?/)
if (versionMatch) {
const majorVersion = parseInt(versionMatch[1], 10)
const minorVersion = versionMatch[2] ? parseInt(versionMatch[2], 10) : 0
if (majorVersion > 4) return true
if (majorVersion === 4 && minorVersion >= 5) return true
return false
}
// 其他包含 opus 但无法解析版本的情况,默认认为是旧版本
return false
}
module.exports = {
parseVendorPrefixedModel,
hasVendorPrefix,
getEffectiveModel,
getVendorType
getVendorType,
isOpus45OrNewer
}