chore: apply stashed changes
This commit is contained in:
@@ -614,21 +614,87 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Account Type Selection (Antigravity - OAuth only) -->
|
||||
<!-- Account Type Selection (Antigravity - OAuth or Upstream) -->
|
||||
<div v-if="form.platform === 'antigravity'">
|
||||
<label class="input-label">{{ t('admin.accounts.accountType') }}</label>
|
||||
<div class="mt-2">
|
||||
<div
|
||||
class="flex items-center gap-3 rounded-lg border-2 border-purple-500 bg-purple-50 p-3 dark:bg-purple-900/20"
|
||||
<div class="mt-2 grid grid-cols-2 gap-3">
|
||||
<button
|
||||
type="button"
|
||||
@click="antigravityAccountType = 'oauth'"
|
||||
:class="[
|
||||
'flex items-center gap-3 rounded-lg border-2 p-3 text-left transition-all',
|
||||
antigravityAccountType === 'oauth'
|
||||
? 'border-purple-500 bg-purple-50 dark:bg-purple-900/20'
|
||||
: 'border-gray-200 hover:border-purple-300 dark:border-dark-600 dark:hover:border-purple-700'
|
||||
]"
|
||||
>
|
||||
<div class="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-purple-500 text-white">
|
||||
<div
|
||||
:class="[
|
||||
'flex h-8 w-8 shrink-0 items-center justify-center rounded-lg',
|
||||
antigravityAccountType === 'oauth'
|
||||
? 'bg-purple-500 text-white'
|
||||
: 'bg-gray-100 text-gray-500 dark:bg-dark-600 dark:text-gray-400'
|
||||
]"
|
||||
>
|
||||
<Icon name="key" size="sm" />
|
||||
</div>
|
||||
<div>
|
||||
<span class="block text-sm font-medium text-gray-900 dark:text-white">OAuth</span>
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400">{{ t('admin.accounts.types.antigravityOauth') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
@click="antigravityAccountType = 'upstream'"
|
||||
:class="[
|
||||
'flex items-center gap-3 rounded-lg border-2 p-3 text-left transition-all',
|
||||
antigravityAccountType === 'upstream'
|
||||
? 'border-purple-500 bg-purple-50 dark:bg-purple-900/20'
|
||||
: 'border-gray-200 hover:border-purple-300 dark:border-dark-600 dark:hover:border-purple-700'
|
||||
]"
|
||||
>
|
||||
<div
|
||||
:class="[
|
||||
'flex h-8 w-8 shrink-0 items-center justify-center rounded-lg',
|
||||
antigravityAccountType === 'upstream'
|
||||
? 'bg-purple-500 text-white'
|
||||
: 'bg-gray-100 text-gray-500 dark:bg-dark-600 dark:text-gray-400'
|
||||
]"
|
||||
>
|
||||
<Icon name="cloud" size="sm" />
|
||||
</div>
|
||||
<div>
|
||||
<span class="block text-sm font-medium text-gray-900 dark:text-white">{{ t('admin.accounts.types.upstream') }}</span>
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400">{{ t('admin.accounts.types.upstreamDesc') }}</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Upstream config (only for Antigravity upstream type) -->
|
||||
<div v-if="form.platform === 'antigravity' && antigravityAccountType === 'upstream'" class="space-y-4">
|
||||
<div>
|
||||
<label class="input-label">{{ t('admin.accounts.upstream.baseUrl') }}</label>
|
||||
<input
|
||||
v-model="upstreamBaseUrl"
|
||||
type="text"
|
||||
required
|
||||
class="input"
|
||||
placeholder="https://upstream.example.com"
|
||||
/>
|
||||
<p class="input-hint">{{ t('admin.accounts.upstream.baseUrlHint') }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="input-label">{{ t('admin.accounts.upstream.apiKey') }}</label>
|
||||
<input
|
||||
v-model="upstreamApiKey"
|
||||
type="password"
|
||||
required
|
||||
class="input font-mono"
|
||||
placeholder="sk-..."
|
||||
/>
|
||||
<p class="input-hint">{{ t('admin.accounts.upstream.apiKeyHint') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1940,6 +2006,9 @@ const customErrorCodeInput = ref<number | null>(null)
|
||||
const interceptWarmupRequests = ref(false)
|
||||
const autoPauseOnExpired = ref(true)
|
||||
const mixedScheduling = ref(false) // For antigravity accounts: enable mixed scheduling
|
||||
const antigravityAccountType = ref<'oauth' | 'upstream'>('oauth') // For antigravity: oauth or upstream
|
||||
const upstreamBaseUrl = ref('') // For upstream type: base URL
|
||||
const upstreamApiKey = ref('') // For upstream type: API key
|
||||
const tempUnschedEnabled = ref(false)
|
||||
const tempUnschedRules = ref<TempUnschedRuleForm[]>([])
|
||||
const geminiOAuthType = ref<'code_assist' | 'google_one' | 'ai_studio'>('google_one')
|
||||
@@ -2037,7 +2106,13 @@ const form = reactive({
|
||||
})
|
||||
|
||||
// Helper to check if current type needs OAuth flow
|
||||
const isOAuthFlow = computed(() => accountCategory.value === 'oauth-based')
|
||||
const isOAuthFlow = computed(() => {
|
||||
// Antigravity upstream 类型不需要 OAuth 流程
|
||||
if (form.platform === 'antigravity' && antigravityAccountType.value === 'upstream') {
|
||||
return false
|
||||
}
|
||||
return accountCategory.value === 'oauth-based'
|
||||
})
|
||||
|
||||
const isManualInputMethod = computed(() => {
|
||||
return oauthFlowRef.value?.inputMethod === 'manual'
|
||||
@@ -2077,10 +2152,15 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
// Sync form.type based on accountCategory and addMethod
|
||||
// Sync form.type based on accountCategory, addMethod, and antigravityAccountType
|
||||
watch(
|
||||
[accountCategory, addMethod],
|
||||
([category, method]) => {
|
||||
[accountCategory, addMethod, antigravityAccountType],
|
||||
([category, method, agType]) => {
|
||||
// Antigravity upstream 类型
|
||||
if (form.platform === 'antigravity' && agType === 'upstream') {
|
||||
form.type = 'upstream'
|
||||
return
|
||||
}
|
||||
if (category === 'oauth-based') {
|
||||
form.type = method as AccountType // 'oauth' or 'setup-token'
|
||||
} else {
|
||||
@@ -2108,9 +2188,10 @@ watch(
|
||||
if (newPlatform !== 'anthropic') {
|
||||
interceptWarmupRequests.value = false
|
||||
}
|
||||
// Antigravity only supports OAuth
|
||||
// Antigravity: reset to OAuth by default, but allow upstream selection
|
||||
if (newPlatform === 'antigravity') {
|
||||
accountCategory.value = 'oauth-based'
|
||||
antigravityAccountType.value = 'oauth'
|
||||
}
|
||||
// Reset OAuth states
|
||||
oauth.resetState()
|
||||
@@ -2343,6 +2424,9 @@ const resetForm = () => {
|
||||
sessionIdleTimeout.value = null
|
||||
tlsFingerprintEnabled.value = false
|
||||
sessionIdMaskingEnabled.value = false
|
||||
antigravityAccountType.value = 'oauth'
|
||||
upstreamBaseUrl.value = ''
|
||||
upstreamApiKey.value = ''
|
||||
tempUnschedEnabled.value = false
|
||||
tempUnschedRules.value = []
|
||||
geminiOAuthType.value = 'code_assist'
|
||||
@@ -2371,6 +2455,36 @@ const handleSubmit = async () => {
|
||||
return
|
||||
}
|
||||
|
||||
// For Antigravity upstream type, create directly
|
||||
if (form.platform === 'antigravity' && antigravityAccountType.value === 'upstream') {
|
||||
if (!form.name.trim()) {
|
||||
appStore.showError(t('admin.accounts.pleaseEnterAccountName'))
|
||||
return
|
||||
}
|
||||
if (!upstreamBaseUrl.value.trim()) {
|
||||
appStore.showError(t('admin.accounts.upstream.pleaseEnterBaseUrl'))
|
||||
return
|
||||
}
|
||||
if (!upstreamApiKey.value.trim()) {
|
||||
appStore.showError(t('admin.accounts.upstream.pleaseEnterApiKey'))
|
||||
return
|
||||
}
|
||||
|
||||
submitting.value = true
|
||||
try {
|
||||
const credentials: Record<string, unknown> = {
|
||||
base_url: upstreamBaseUrl.value.trim(),
|
||||
api_key: upstreamApiKey.value.trim()
|
||||
}
|
||||
await createAccountAndFinish(form.platform, 'upstream', credentials)
|
||||
} catch (error: any) {
|
||||
appStore.showError(error.response?.data?.detail || t('admin.accounts.failedToCreate'))
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// For apikey type, create directly
|
||||
if (!apiKeyValue.value.trim()) {
|
||||
appStore.showError(t('admin.accounts.pleaseEnterApiKey'))
|
||||
|
||||
@@ -1034,6 +1034,14 @@ export default {
|
||||
tooltip: 'When enabled, if the request contains MCP tools, an XML format call protocol prompt will be injected into the system prompt. Disable this to avoid interference with certain clients.',
|
||||
enabled: 'Enabled',
|
||||
disabled: 'Disabled'
|
||||
},
|
||||
supportedScopes: {
|
||||
title: 'Supported Model Families',
|
||||
tooltip: 'Select the model families this group supports. Unchecked families will not be routed to this group.',
|
||||
claude: 'Claude',
|
||||
geminiText: 'Gemini Text',
|
||||
geminiImage: 'Gemini Image',
|
||||
hint: 'Select at least one model family'
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1173,7 +1181,9 @@ export default {
|
||||
responsesApi: 'Responses API',
|
||||
googleOauth: 'Google OAuth',
|
||||
codeAssist: 'Code Assist',
|
||||
antigravityOauth: 'Antigravity OAuth'
|
||||
antigravityOauth: 'Antigravity OAuth',
|
||||
upstream: 'Upstream',
|
||||
upstreamDesc: 'Connect via Base URL + API Key'
|
||||
},
|
||||
status: {
|
||||
active: 'Active',
|
||||
@@ -1431,6 +1441,15 @@ export default {
|
||||
pleaseEnterApiKey: 'Please enter API Key',
|
||||
apiKeyIsRequired: 'API Key is required',
|
||||
leaveEmptyToKeep: 'Leave empty to keep current key',
|
||||
// Upstream type
|
||||
upstream: {
|
||||
baseUrl: 'Upstream Base URL',
|
||||
baseUrlHint: 'The address of the upstream Antigravity service, e.g., https://upstream.example.com',
|
||||
apiKey: 'Upstream API Key',
|
||||
apiKeyHint: 'API Key for the upstream service',
|
||||
pleaseEnterBaseUrl: 'Please enter upstream Base URL',
|
||||
pleaseEnterApiKey: 'Please enter upstream API Key'
|
||||
},
|
||||
// OAuth flow
|
||||
oauth: {
|
||||
title: 'Claude Account Authorization',
|
||||
|
||||
@@ -1109,6 +1109,14 @@ export default {
|
||||
tooltip: '启用后,当请求包含 MCP 工具时,会在 system prompt 中注入 XML 格式调用协议提示词。关闭此选项可避免对某些客户端造成干扰。',
|
||||
enabled: '已启用',
|
||||
disabled: '已禁用'
|
||||
},
|
||||
supportedScopes: {
|
||||
title: '支持的模型系列',
|
||||
tooltip: '选择此分组支持的模型系列。未勾选的系列将不会被路由到此分组。',
|
||||
claude: 'Claude',
|
||||
geminiText: 'Gemini Text',
|
||||
geminiImage: 'Gemini Image',
|
||||
hint: '至少选择一个模型系列'
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1294,6 +1302,8 @@ export default {
|
||||
googleOauth: 'Google OAuth',
|
||||
codeAssist: 'Code Assist',
|
||||
antigravityOauth: 'Antigravity OAuth',
|
||||
upstream: '对接上游',
|
||||
upstreamDesc: '通过 Base URL + API Key 连接上游',
|
||||
api_key: 'API Key',
|
||||
cookie: 'Cookie'
|
||||
},
|
||||
@@ -1563,6 +1573,15 @@ export default {
|
||||
pleaseEnterApiKey: '请输入 API Key',
|
||||
apiKeyIsRequired: 'API Key 是必需的',
|
||||
leaveEmptyToKeep: '留空以保持当前密钥',
|
||||
// Upstream type
|
||||
upstream: {
|
||||
baseUrl: '上游 Base URL',
|
||||
baseUrlHint: '上游 Antigravity 服务的地址,例如:https://upstream.example.com',
|
||||
apiKey: '上游 API Key',
|
||||
apiKeyHint: '上游服务的 API Key',
|
||||
pleaseEnterBaseUrl: '请输入上游 Base URL',
|
||||
pleaseEnterApiKey: '请输入上游 API Key'
|
||||
},
|
||||
// OAuth flow
|
||||
oauth: {
|
||||
title: 'Claude 账号授权',
|
||||
|
||||
@@ -365,6 +365,11 @@ export interface AdminGroup extends Group {
|
||||
|
||||
// MCP XML 协议注入(仅 antigravity 平台使用)
|
||||
mcp_xml_inject: boolean
|
||||
|
||||
// 支持的模型系列(仅 antigravity 平台使用)
|
||||
supported_model_scopes?: string[]
|
||||
|
||||
// 分组下账号数量(仅管理员可见)
|
||||
account_count?: number
|
||||
}
|
||||
|
||||
@@ -414,6 +419,7 @@ export interface CreateGroupRequest {
|
||||
claude_code_only?: boolean
|
||||
fallback_group_id?: number | null
|
||||
fallback_group_id_on_invalid_request?: number | null
|
||||
supported_model_scopes?: string[]
|
||||
}
|
||||
|
||||
export interface UpdateGroupRequest {
|
||||
@@ -433,12 +439,13 @@ export interface UpdateGroupRequest {
|
||||
claude_code_only?: boolean
|
||||
fallback_group_id?: number | null
|
||||
fallback_group_id_on_invalid_request?: number | null
|
||||
supported_model_scopes?: string[]
|
||||
}
|
||||
|
||||
// ==================== Account & Proxy Types ====================
|
||||
|
||||
export type AccountPlatform = 'anthropic' | 'openai' | 'gemini' | 'antigravity'
|
||||
export type AccountType = 'oauth' | 'setup-token' | 'apikey'
|
||||
export type AccountType = 'oauth' | 'setup-token' | 'apikey' | 'upstream'
|
||||
export type OAuthAddMethod = 'oauth' | 'setup-token'
|
||||
export type ProxyProtocol = 'http' | 'https' | 'socks5' | 'socks5h'
|
||||
|
||||
|
||||
@@ -404,6 +404,62 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 支持的模型系列(仅 antigravity 平台) -->
|
||||
<div v-if="createForm.platform === 'antigravity'" class="border-t pt-4">
|
||||
<div class="mb-1.5 flex items-center gap-1">
|
||||
<label class="text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
{{ t('admin.groups.supportedScopes.title') }}
|
||||
</label>
|
||||
<!-- Help Tooltip -->
|
||||
<div class="group relative inline-flex">
|
||||
<Icon
|
||||
name="questionCircle"
|
||||
size="sm"
|
||||
:stroke-width="2"
|
||||
class="cursor-help text-gray-400 transition-colors hover:text-primary-500 dark:text-gray-500 dark:hover:text-primary-400"
|
||||
/>
|
||||
<div class="pointer-events-none absolute bottom-full left-0 z-50 mb-2 w-72 opacity-0 transition-all duration-200 group-hover:pointer-events-auto group-hover:opacity-100">
|
||||
<div class="rounded-lg bg-gray-900 p-3 text-white shadow-lg dark:bg-gray-800">
|
||||
<p class="text-xs leading-relaxed text-gray-300">
|
||||
{{ t('admin.groups.supportedScopes.tooltip') }}
|
||||
</p>
|
||||
<div class="absolute -bottom-1.5 left-3 h-3 w-3 rotate-45 bg-gray-900 dark:bg-gray-800"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<label class="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="createForm.supported_model_scopes.includes('claude')"
|
||||
@change="toggleCreateScope('claude')"
|
||||
class="h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500 dark:border-dark-600 dark:bg-dark-700"
|
||||
/>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">{{ t('admin.groups.supportedScopes.claude') }}</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="createForm.supported_model_scopes.includes('gemini_text')"
|
||||
@change="toggleCreateScope('gemini_text')"
|
||||
class="h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500 dark:border-dark-600 dark:bg-dark-700"
|
||||
/>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">{{ t('admin.groups.supportedScopes.geminiText') }}</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="createForm.supported_model_scopes.includes('gemini_image')"
|
||||
@change="toggleCreateScope('gemini_image')"
|
||||
class="h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500 dark:border-dark-600 dark:bg-dark-700"
|
||||
/>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">{{ t('admin.groups.supportedScopes.geminiImage') }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-gray-500 dark:text-gray-400">{{ t('admin.groups.supportedScopes.hint') }}</p>
|
||||
</div>
|
||||
|
||||
<!-- MCP XML 协议注入(仅 antigravity 平台) -->
|
||||
<div v-if="createForm.platform === 'antigravity'" class="border-t pt-4">
|
||||
<div class="mb-1.5 flex items-center gap-1">
|
||||
@@ -907,6 +963,62 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 支持的模型系列(仅 antigravity 平台) -->
|
||||
<div v-if="editForm.platform === 'antigravity'" class="border-t pt-4">
|
||||
<div class="mb-1.5 flex items-center gap-1">
|
||||
<label class="text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
{{ t('admin.groups.supportedScopes.title') }}
|
||||
</label>
|
||||
<!-- Help Tooltip -->
|
||||
<div class="group relative inline-flex">
|
||||
<Icon
|
||||
name="questionCircle"
|
||||
size="sm"
|
||||
:stroke-width="2"
|
||||
class="cursor-help text-gray-400 transition-colors hover:text-primary-500 dark:text-gray-500 dark:hover:text-primary-400"
|
||||
/>
|
||||
<div class="pointer-events-none absolute bottom-full left-0 z-50 mb-2 w-72 opacity-0 transition-all duration-200 group-hover:pointer-events-auto group-hover:opacity-100">
|
||||
<div class="rounded-lg bg-gray-900 p-3 text-white shadow-lg dark:bg-gray-800">
|
||||
<p class="text-xs leading-relaxed text-gray-300">
|
||||
{{ t('admin.groups.supportedScopes.tooltip') }}
|
||||
</p>
|
||||
<div class="absolute -bottom-1.5 left-3 h-3 w-3 rotate-45 bg-gray-900 dark:bg-gray-800"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<label class="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="editForm.supported_model_scopes.includes('claude')"
|
||||
@change="toggleEditScope('claude')"
|
||||
class="h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500 dark:border-dark-600 dark:bg-dark-700"
|
||||
/>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">{{ t('admin.groups.supportedScopes.claude') }}</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="editForm.supported_model_scopes.includes('gemini_text')"
|
||||
@change="toggleEditScope('gemini_text')"
|
||||
class="h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500 dark:border-dark-600 dark:bg-dark-700"
|
||||
/>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">{{ t('admin.groups.supportedScopes.geminiText') }}</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="editForm.supported_model_scopes.includes('gemini_image')"
|
||||
@change="toggleEditScope('gemini_image')"
|
||||
class="h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500 dark:border-dark-600 dark:bg-dark-700"
|
||||
/>
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">{{ t('admin.groups.supportedScopes.geminiImage') }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-gray-500 dark:text-gray-400">{{ t('admin.groups.supportedScopes.hint') }}</p>
|
||||
</div>
|
||||
|
||||
<!-- MCP XML 协议注入(仅 antigravity 平台) -->
|
||||
<div v-if="editForm.platform === 'antigravity'" class="border-t pt-4">
|
||||
<div class="mb-1.5 flex items-center gap-1">
|
||||
@@ -1402,6 +1514,9 @@ const createForm = reactive({
|
||||
fallback_group_id_on_invalid_request: null as number | null,
|
||||
// 模型路由开关
|
||||
model_routing_enabled: false,
|
||||
// 支持的模型系列(仅 antigravity 平台)
|
||||
supported_model_scopes: ['claude', 'gemini_text', 'gemini_image'] as string[],
|
||||
// MCP XML 协议注入开关(仅 antigravity 平台)
|
||||
mcp_xml_inject: true
|
||||
})
|
||||
|
||||
@@ -1472,6 +1587,26 @@ const removeSelectedAccount = (ruleIndex: number, accountId: number, isEdit: boo
|
||||
rule.accounts = rule.accounts.filter(a => a.id !== accountId)
|
||||
}
|
||||
|
||||
// 切换创建表单的模型系列选择
|
||||
const toggleCreateScope = (scope: string) => {
|
||||
const idx = createForm.supported_model_scopes.indexOf(scope)
|
||||
if (idx === -1) {
|
||||
createForm.supported_model_scopes.push(scope)
|
||||
} else {
|
||||
createForm.supported_model_scopes.splice(idx, 1)
|
||||
}
|
||||
}
|
||||
|
||||
// 切换编辑表单的模型系列选择
|
||||
const toggleEditScope = (scope: string) => {
|
||||
const idx = editForm.supported_model_scopes.indexOf(scope)
|
||||
if (idx === -1) {
|
||||
editForm.supported_model_scopes.push(scope)
|
||||
} else {
|
||||
editForm.supported_model_scopes.splice(idx, 1)
|
||||
}
|
||||
}
|
||||
|
||||
// 处理账号搜索输入框聚焦
|
||||
const onAccountSearchFocus = (ruleIndex: number, isEdit: boolean = false) => {
|
||||
const key = `${isEdit ? 'edit' : 'create'}-${ruleIndex}`
|
||||
@@ -1575,6 +1710,9 @@ const editForm = reactive({
|
||||
fallback_group_id_on_invalid_request: null as number | null,
|
||||
// 模型路由开关
|
||||
model_routing_enabled: false,
|
||||
// 支持的模型系列(仅 antigravity 平台)
|
||||
supported_model_scopes: ['claude', 'gemini_text', 'gemini_image'] as string[],
|
||||
// MCP XML 协议注入开关(仅 antigravity 平台)
|
||||
mcp_xml_inject: true
|
||||
})
|
||||
|
||||
@@ -1658,6 +1796,7 @@ const closeCreateModal = () => {
|
||||
createForm.claude_code_only = false
|
||||
createForm.fallback_group_id = null
|
||||
createForm.fallback_group_id_on_invalid_request = null
|
||||
createForm.supported_model_scopes = ['claude', 'gemini_text', 'gemini_image']
|
||||
createForm.mcp_xml_inject = true
|
||||
createModelRoutingRules.value = []
|
||||
}
|
||||
@@ -1710,6 +1849,7 @@ const handleEdit = async (group: AdminGroup) => {
|
||||
editForm.fallback_group_id = group.fallback_group_id
|
||||
editForm.fallback_group_id_on_invalid_request = group.fallback_group_id_on_invalid_request
|
||||
editForm.model_routing_enabled = group.model_routing_enabled || false
|
||||
editForm.supported_model_scopes = group.supported_model_scopes || ['claude', 'gemini_text', 'gemini_image']
|
||||
editForm.mcp_xml_inject = group.mcp_xml_inject ?? true
|
||||
// 加载模型路由规则(异步加载账号名称)
|
||||
editModelRoutingRules.value = await convertApiFormatToRoutingRules(group.model_routing)
|
||||
|
||||
Reference in New Issue
Block a user