fix(failover): switch to P1 immediately when enabling auto failover

Previously, enabling auto failover kept using the current provider until
the first failure, causing inconsistency when the current provider was
not in the failover queue. When stopping proxy, the restored config
would not match user expectations.

New behavior:
- Enable auto failover = immediately switch to queue P1
- Subsequent routing follows queue order (P1→P2→...)
- Auto-add current provider to queue if queue is empty

Changes:
- Add switch_proxy_target() for hot-switching during proxy mode
- Update provider_router to use queue order when failover enabled
- Sync tray menu Auto click with the same logic
- Update UI tooltips to reflect new semantics
- Add tests for queue-only routing scenario
This commit is contained in:
Jason
2026-01-21 11:27:44 +08:00
parent b993b1f664
commit a187380d6f
12 changed files with 357 additions and 28 deletions
@@ -140,7 +140,8 @@ export function FailoverQueueManager({
</div>
<p className="text-xs text-muted-foreground">
{t("proxy.failover.autoSwitchDescription", {
defaultValue: "开启后,请求失败时自动切换到队列中的下一个供应商",
defaultValue:
"开启后将立即切换到队列 P1,并在请求失败时自动切换到队列中的下一个供应商",
})}
</p>
</div>
+2 -2
View File
@@ -39,11 +39,11 @@ export function FailoverToggle({ className, activeApp }: FailoverToggleProps) {
const tooltipText = isEnabled
? t("failover.tooltip.enabled", {
app: appLabel,
defaultValue: `${appLabel} 故障转移已启用\n自动切换到下一个可用供应商`,
defaultValue: `${appLabel} 故障转移已启用\n按队列优先级(P1→P2→...)选择供应商`,
})
: t("failover.tooltip.disabled", {
app: appLabel,
defaultValue: `启用 ${appLabel} 故障转移\n当当前供应商失败时自动切换`,
defaultValue: `启用 ${appLabel} 故障转移\n将立即切换到队列 P1,并在失败时自动切换到下一个`,
});
return (
+2 -2
View File
@@ -50,8 +50,8 @@ export function ProxyPanel() {
}
}, [globalConfig]);
// 获取所有三个应用类型的故障转移队列(不包含当前供应商)
// 当前供应商始终优先,队列仅用于失败后的备用顺序
// 获取所有三个应用类型的故障转移队列
// 启用自动故障转移后,将按队列优先级(P1→P2→...)选择供应商
const { data: claudeQueue = [] } = useFailoverQueue("claude");
const { data: codexQueue = [] } = useFailoverQueue("codex");
const { data: geminiQueue = [] } = useFailoverQueue("gemini");