fix: restrict client affinity to Anthropic OAuth/SetupToken accounts only

客户端亲和仅对 Claude Code 账号(Anthropic OAuth/SetupToken)生效,
移除 Antigravity 平台支持。UI toggle 移动到拦截预热请求下方。
This commit is contained in:
erio
2026-03-06 14:46:47 +08:00
parent c1816f39f2
commit 63dff62673
4 changed files with 39 additions and 47 deletions
+1 -1
View File
@@ -250,7 +250,7 @@ func AccountFromServiceShallow(a *service.Account) *Account {
}
}
// 客户端亲和调度(适用于 Anthropic/Antigravity 平台)
// 客户端亲和调度(仅 Anthropic OAuth/SetupToken 账号)
if a.IsClientAffinityEnabled() {
enabled := true
out.ClientAffinityEnabled = &enabled
+1 -1
View File
@@ -188,7 +188,7 @@ type Account struct {
CacheTTLOverrideEnabled *bool `json:"cache_ttl_override_enabled,omitempty"`
CacheTTLOverrideTarget *string `json:"cache_ttl_override_target,omitempty"`
// 客户端亲和调度(仅 Anthropic/Antigravity 平台有效)
// 客户端亲和调度(仅 Anthropic OAuth/SetupToken 账号有效)
// 启用后新会话会优先调度到客户端之前使用过的账号
ClientAffinityEnabled *bool `json:"client_affinity_enabled,omitempty"`
+2 -2
View File
@@ -1100,10 +1100,10 @@ func (a *Account) IsSessionIDMaskingEnabled() bool {
}
// IsClientAffinityEnabled 检查是否启用客户端亲和调度
// 仅适用于 Anthropic 平台账号(包括 anthropic 和 antigravity 平台)
// 仅适用于 Anthropic OAuth/SetupToken 账号(Claude Code)
// 启用后,新会话会优先调度到之前使用过的账号
func (a *Account) IsClientAffinityEnabled() bool {
if a.Platform != PlatformAnthropic && a.Platform != PlatformAntigravity {
if !a.IsAnthropicOAuthOrSetupToken() {
return false
}
if a.Extra == nil {
@@ -645,6 +645,36 @@
</div>
</div>
<!-- Client Affinity (Anthropic OAuth/SetupToken only) -->
<div
v-if="account?.platform === 'anthropic' && (account?.type === 'oauth' || account?.type === 'setup-token')"
class="border-t border-gray-200 pt-4 dark:border-dark-600"
>
<div class="flex items-center justify-between">
<div>
<label class="input-label mb-0">{{ t('admin.accounts.quotaControl.clientAffinity.label') }}</label>
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
{{ t('admin.accounts.quotaControl.clientAffinity.hint') }}
</p>
</div>
<button
type="button"
@click="clientAffinityEnabled = !clientAffinityEnabled"
:class="[
'relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2',
clientAffinityEnabled ? 'bg-primary-600' : 'bg-gray-200 dark:bg-dark-600'
]"
>
<span
:class="[
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out',
clientAffinityEnabled ? 'translate-x-5' : 'translate-x-0'
]"
/>
</button>
</div>
</div>
<div>
<label class="input-label">{{ t('admin.accounts.proxy') }}</label>
<ProxySelector v-model="form.proxy_id" :proxies="proxies" />
@@ -1165,38 +1195,6 @@
</div>
</div>
<!-- Client Affinity (Anthropic/Antigravity platform) -->
<div
v-if="(account?.platform === 'anthropic' && (account?.type === 'oauth' || account?.type === 'setup-token')) || account?.platform === 'antigravity'"
class="border-t border-gray-200 pt-4 dark:border-dark-600"
>
<div class="rounded-lg border border-gray-200 p-4 dark:border-dark-600">
<div class="flex items-center justify-between">
<div>
<label class="input-label mb-0">{{ t('admin.accounts.quotaControl.clientAffinity.label') }}</label>
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
{{ t('admin.accounts.quotaControl.clientAffinity.hint') }}
</p>
</div>
<button
type="button"
@click="clientAffinityEnabled = !clientAffinityEnabled"
:class="[
'relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2',
clientAffinityEnabled ? 'bg-primary-600' : 'bg-gray-200 dark:bg-dark-600'
]"
>
<span
:class="[
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out',
clientAffinityEnabled ? 'translate-x-5' : 'translate-x-0'
]"
/>
</button>
</div>
</div>
</div>
<div class="border-t border-gray-200 pt-4 dark:border-dark-600">
<div>
<label class="input-label">{{ t('common.status') }}</label>
@@ -1907,16 +1905,16 @@ function loadQuotaControlSettings(account: Account) {
cacheTTLOverrideTarget.value = '5m'
clientAffinityEnabled.value = false
// Client affinity applies to both Anthropic and Antigravity platforms
if (account.client_affinity_enabled === true) {
clientAffinityEnabled.value = true
}
// Only applies to Anthropic OAuth/SetupToken accounts
if (account.platform !== 'anthropic' || (account.type !== 'oauth' && account.type !== 'setup-token')) {
return
}
// Client affinity (Anthropic OAuth/SetupToken only)
if (account.client_affinity_enabled === true) {
clientAffinityEnabled.value = true
}
// Load from extra field (via backend DTO fields)
if (account.window_cost_limit != null && account.window_cost_limit > 0) {
windowCostEnabled.value = true
@@ -2235,12 +2233,6 @@ const handleSubmit = async () => {
} else {
delete newExtra.mixed_scheduling
}
// Client affinity setting
if (clientAffinityEnabled.value) {
newExtra.client_affinity_enabled = true
} else {
delete newExtra.client_affinity_enabled
}
updatePayload.extra = newExtra
}