feat(providers): cc-switch 式供应商自动故障转移(同厂商同模型) - #385
Open
coder-hhx wants to merge 3 commits into
Open
Conversation
…viders
Adds automatic provider failover for chat requests, configured per vendor
tab in provider settings and modeled after cc-switch's proxy-side design:
- Failover switches providers, never models: the failed request is re-sent
to the next provider in the queue with the same model id the conversation
was using; queued providers without that model active are skipped.
- Per-target circuit breaker (consecutive-failure threshold, cooldown with
half-open probe) keyed by provider::model, plus an error classifier that
only fails over on provider-fault-class errors (5xx/network/auth/quota),
never on client-request-class errors (context overflow etc.).
- Stream wrapper buffers events until first committed content so consumers
never see output from a discarded attempt; sticky winner keeps follow-up
rounds on the provider that answered, and onSwitched pins the conversation
selection to it.
- Settings: modelFailover is now persisted (it previously round-tripped
through neither the SQLite nor the localStorage channel, so the toggle
and queue silently reset on every settings reopen); queue entries are
provider ids with legacy {customProviderId, model} entries migrated by
collapsing to their provider id.
- UI: failover card under each vendor tab manages an ordered provider
queue with breaker knobs; i18n zh/en updated, {vendor} placeholder now
replaced at every occurrence.
Covered by unit tests for the breaker/stream wrapper, plan builder, and
settings normalization/migration; verified end-to-end in the running app.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
StackCairn
marked this pull request as draft
August 5, 2026 13:11
Contributor
|
PR governance checks passed. Awaiting human review. |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
coder-hhx
marked this pull request as ready for review
August 5, 2026 13:27
Contributor
|
没啥希望通过, 仓库所有者表示希望更简洁的provider, 如有此需求推荐安装一个cc-switch |
Contributor
|
pr可以留着, 之后有插件体系了可以放插件里 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linked issue
Closes #384
Summary
修复自动故障转移设置无法持久化的 bug,并将故障转移重构为 cc-switch 语义的供应商级设计:
modelFailover此前未接入任何持久化通道(SQLite 与 localStorage 均无),退出设置页重进即丢失。现已接入 localStorage 通道(与selectedModel同级),读/写/变更检测三处补齐。provider::model维度的熔断器(连续失败阈值 → 熔断 → 冷却 → 半开探测);错误分类器仅对供应商故障类错误(5xx/网络/鉴权/配额)转移,客户端请求类错误(如上下文超限)不转移;流包装器在首个可见内容前缓冲事件,丢弃的尝试对用户不可见;成功应答的供应商粘性保持并写回对话选择。{vendor}占位符多次出现时只替换首个的问题。Change scope
crates/agent-gui/src/lib/providers/runtime/providerFailover.ts(新增:熔断器 + 错误分类 + 流包装器)crates/agent-gui/src/lib/settings/{index,storage}.ts(队列模型 + 迁移 + 持久化)crates/agent-gui/src/pages/chat/runtime/{providerRuntimeConfig,useSendChatTurn}.ts(每轮 failover 计划)crates/agent-gui/src/lib/chat/runner/agentRunner.ts(候选装配 + withProviderFailover 接入)crates/agent-gui/src/pages/settings/ProvidersSection.tsx+ web 端孪生 + 双端 i18nScreenshots / preview
设置页(Anthropic 标签)——供应商级故障转移队列,退出设置重进后配置保留:
实测转移过程:将 P1 供应商(RightCode sale)的 API key 置为无效后发起对话,状态栏显示「第 1 轮:RightCode(sale)· claude-fable-5 不可用,正在切换到 RightCode · claude-fable-5…」,随后由 P2 供应商以同一模型完成应答,对话选择自动切到应答的供应商。
Verification
cd crates/agent-gui && ./node_modules/.bin/tsc --noEmit✅(web 端同样通过)biome check两端 0 error ✅node --test test/settings/model-failover-normalize.test.mjs test/providers/provider-failover-plan.test.mjs test/providers/provider-failover.test.mjs— 29 项全部通过(熔断器/流包装器 16、计划构建 5、归一化+迁移 8)node --test test/providers/provider-runtime-config.test.mjs test/chat/agent-runner.test.mjs— 上游相关套件 39 项通过node scripts/check-mirror.mjs✅(115 文件)pnpm tauri dev启动桌面端,复现原 bug 路径(退出设置→重进),配置保留;旧数据自动迁移;实际断供触发转移成功(见截图说明)Pre-submit checklist
🤖 Generated with Claude Code