merge: 合并 main 分支到 test,解决 config 和 modelWhitelist 冲突
- config.go: 保留 Sora 配置,合入 SubscriptionCache 配置 - useModelWhitelist.ts: 同时保留 soraModels 和 antigravityModels Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -69,6 +69,29 @@ const soraModels = [
|
||||
'prompt-enhance-long-10s', 'prompt-enhance-long-15s', 'prompt-enhance-long-20s'
|
||||
]
|
||||
|
||||
// Antigravity 官方支持的模型(精确匹配)
|
||||
// 基于官方 API 返回的模型列表,只支持 Claude 4.5+ 和 Gemini 2.5+
|
||||
const antigravityModels = [
|
||||
// Claude 4.5+ 系列
|
||||
'claude-opus-4-6',
|
||||
'claude-opus-4-5-thinking',
|
||||
'claude-sonnet-4-5',
|
||||
'claude-sonnet-4-5-thinking',
|
||||
// Gemini 2.5 系列
|
||||
'gemini-2.5-flash',
|
||||
'gemini-2.5-flash-lite',
|
||||
'gemini-2.5-flash-thinking',
|
||||
'gemini-2.5-pro',
|
||||
// Gemini 3 系列
|
||||
'gemini-3-flash',
|
||||
'gemini-3-pro-high',
|
||||
'gemini-3-pro-low',
|
||||
'gemini-3-pro-image',
|
||||
// 其他
|
||||
'gpt-oss-120b-medium',
|
||||
'tab_flash_lite_preview'
|
||||
]
|
||||
|
||||
// 智谱 GLM
|
||||
const zhipuModels = [
|
||||
'glm-4', 'glm-4v', 'glm-4-plus', 'glm-4-0520',
|
||||
@@ -254,6 +277,41 @@ const geminiPresetMappings = [
|
||||
{ label: '2.5 Pro', from: 'gemini-2.5-pro', to: 'gemini-2.5-pro', color: 'bg-purple-100 text-purple-700 hover:bg-purple-200 dark:bg-purple-900/30 dark:text-purple-400' }
|
||||
]
|
||||
|
||||
// Antigravity 预设映射(支持通配符)
|
||||
const antigravityPresetMappings = [
|
||||
// Claude 通配符映射
|
||||
{ label: 'Claude→Sonnet', from: 'claude-*', to: 'claude-sonnet-4-5', color: 'bg-blue-100 text-blue-700 hover:bg-blue-200 dark:bg-blue-900/30 dark:text-blue-400' },
|
||||
{ label: 'Sonnet→Sonnet', from: 'claude-sonnet-*', to: 'claude-sonnet-4-5', color: 'bg-indigo-100 text-indigo-700 hover:bg-indigo-200 dark:bg-indigo-900/30 dark:text-indigo-400' },
|
||||
{ label: 'Opus→Opus', from: 'claude-opus-*', to: 'claude-opus-4-6-thinking', color: 'bg-purple-100 text-purple-700 hover:bg-purple-200 dark:bg-purple-900/30 dark:text-purple-400' },
|
||||
{ label: 'Haiku→Sonnet', from: 'claude-haiku-*', to: 'claude-sonnet-4-5', color: 'bg-emerald-100 text-emerald-700 hover:bg-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-400' },
|
||||
// Gemini 通配符映射
|
||||
{ label: 'Gemini 3→Flash', from: 'gemini-3*', to: 'gemini-3-flash', color: 'bg-amber-100 text-amber-700 hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-400' },
|
||||
{ label: 'Gemini 2.5→Flash', from: 'gemini-2.5*', to: 'gemini-2.5-flash', color: 'bg-orange-100 text-orange-700 hover:bg-orange-200 dark:bg-orange-900/30 dark:text-orange-400' },
|
||||
// 精确映射
|
||||
{ label: 'Sonnet 4.5', from: 'claude-sonnet-4-5', to: 'claude-sonnet-4-5', color: 'bg-cyan-100 text-cyan-700 hover:bg-cyan-200 dark:bg-cyan-900/30 dark:text-cyan-400' },
|
||||
{ label: 'Opus 4.6-thinking', from: 'claude-opus-4-6-thinking', to: 'claude-opus-4-6-thinking', color: 'bg-pink-100 text-pink-700 hover:bg-pink-200 dark:bg-pink-900/30 dark:text-pink-400' }
|
||||
]
|
||||
|
||||
// Antigravity 默认映射(从后端 API 获取,与 constants.go 保持一致)
|
||||
// 使用 fetchAntigravityDefaultMappings() 异步获取
|
||||
import { getAntigravityDefaultModelMapping } from '@/api/admin/accounts'
|
||||
|
||||
let _antigravityDefaultMappingsCache: { from: string; to: string }[] | null = null
|
||||
|
||||
export async function fetchAntigravityDefaultMappings(): Promise<{ from: string; to: string }[]> {
|
||||
if (_antigravityDefaultMappingsCache !== null) {
|
||||
return _antigravityDefaultMappingsCache
|
||||
}
|
||||
try {
|
||||
const mapping = await getAntigravityDefaultModelMapping()
|
||||
_antigravityDefaultMappingsCache = Object.entries(mapping).map(([from, to]) => ({ from, to }))
|
||||
} catch (e) {
|
||||
console.warn('[fetchAntigravityDefaultMappings] API failed, using empty fallback', e)
|
||||
_antigravityDefaultMappingsCache = []
|
||||
}
|
||||
return _antigravityDefaultMappingsCache
|
||||
}
|
||||
|
||||
// =====================
|
||||
// 常用错误码
|
||||
// =====================
|
||||
@@ -280,6 +338,7 @@ export function getModelsByPlatform(platform: string): string[] {
|
||||
case 'claude': return claudeModels
|
||||
case 'gemini': return geminiModels
|
||||
case 'sora': return soraModels
|
||||
case 'antigravity': return antigravityModels
|
||||
case 'zhipu': return zhipuModels
|
||||
case 'qwen': return qwenModels
|
||||
case 'deepseek': return deepseekModels
|
||||
@@ -304,6 +363,7 @@ export function getPresetMappingsByPlatform(platform: string) {
|
||||
if (platform === 'openai') return openaiPresetMappings
|
||||
if (platform === 'gemini') return geminiPresetMappings
|
||||
if (platform === 'sora') return soraPresetMappings
|
||||
if (platform === 'antigravity') return antigravityPresetMappings
|
||||
return anthropicPresetMappings
|
||||
}
|
||||
|
||||
@@ -311,6 +371,15 @@ export function getPresetMappingsByPlatform(platform: string) {
|
||||
// 构建模型映射对象(用于 API)
|
||||
// =====================
|
||||
|
||||
// isValidWildcardPattern 校验通配符格式:* 只能放在末尾
|
||||
// 导出供表单组件使用实时校验
|
||||
export function isValidWildcardPattern(pattern: string): boolean {
|
||||
const starIndex = pattern.indexOf('*')
|
||||
if (starIndex === -1) return true // 无通配符,有效
|
||||
// * 必须在末尾,且只能有一个
|
||||
return starIndex === pattern.length - 1 && pattern.lastIndexOf('*') === starIndex
|
||||
}
|
||||
|
||||
export function buildModelMappingObject(
|
||||
mode: 'whitelist' | 'mapping',
|
||||
allowedModels: string[],
|
||||
@@ -320,13 +389,29 @@ export function buildModelMappingObject(
|
||||
|
||||
if (mode === 'whitelist') {
|
||||
for (const model of allowedModels) {
|
||||
mapping[model] = model
|
||||
// whitelist 模式的本意是"精确模型列表",如果用户输入了通配符(如 claude-*),
|
||||
// 写入 model_mapping 会导致 GetMappedModel() 把真实模型映射成 "claude-*",从而转发失败。
|
||||
// 因此这里跳过包含通配符的条目。
|
||||
if (!model.includes('*')) {
|
||||
mapping[model] = model
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const m of modelMappings) {
|
||||
const from = m.from.trim()
|
||||
const to = m.to.trim()
|
||||
if (from && to) mapping[from] = to
|
||||
if (!from || !to) continue
|
||||
// 校验通配符格式:* 只能放在末尾
|
||||
if (!isValidWildcardPattern(from)) {
|
||||
console.warn(`[buildModelMappingObject] 无效的通配符格式,跳过: ${from}`)
|
||||
continue
|
||||
}
|
||||
// to 不允许包含通配符
|
||||
if (to.includes('*')) {
|
||||
console.warn(`[buildModelMappingObject] 目标模型不能包含通配符,跳过: ${from} -> ${to}`)
|
||||
continue
|
||||
}
|
||||
mapping[from] = to
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user