fix(health-check): disable connectivity check for official providers, restore 6s degraded threshold

Official providers (Claude/Codex/Gemini/Claude Desktop) use OAuth with an intentionally empty base_url and connect via the client's default endpoint, so cc-switch has no reliable reachability target. Probing a guessed endpoint either hits the wrong target or returns a meaningless green light. Hide the connectivity button for category === 'official'; reachability stays available for copilot/codex-oauth/third-party/custom providers, which is where the old real-request probe produced false negatives. Revert the official base_url fallback added earlier — resolve_base_url is back to extract-or-error.

The 1500ms degraded threshold was too strict; normal ~1s probe latencies showed as 'slow'. Restore the original 6000ms scale (default + config panel + per-provider range). Keep the reachability-appropriate 8s timeout / 1 retry.
This commit is contained in:
Jason
2026-06-14 15:55:18 +08:00
parent a5903d8600
commit fee354d09e
4 changed files with 36 additions and 130 deletions
+6 -7
View File
@@ -548,13 +548,12 @@ export function ProviderCard({
onEdit={() => onEdit(provider)}
onDuplicate={() => onDuplicate(provider)}
onTest={
// 连通检测对所有供应商开放(官方会回退到客户端实际会连的官方端点),
// 唯独 Claude Desktop 官方除外:它是原生 1P 模式(走 claude.aicc-switch
// 不在请求路径上),没有可靠的探测目标,故隐藏其检测按钮。
onTest &&
!(
appId === "claude-desktop" && provider.category === "official"
)
// 连通检测对第三方/自定义/Copilot/Codex-OAuth 供应商开放(这些正是旧的
// 真实请求探测会误报、而可达性探测能正确处理的对象)。官方供应商
// (category === "official") 一律隐藏:它们 base_url 故意留空、走客户端
// 默认/OAuth 端点,cc-switch 没有可靠的探测目标(尤其 Claude Desktop
// 官方是原生 1P 模式,根本不在请求路径上)。
onTest && provider.category !== "official"
? () => onTest(provider)
: undefined
}
@@ -144,7 +144,7 @@ export function ProviderAdvancedConfig({
id="degraded-threshold"
type="number"
min={100}
max={10000}
max={60000}
value={testConfig.degradedThresholdMs || ""}
onChange={(e) =>
onTestConfigChange({
@@ -154,7 +154,7 @@ export function ProviderAdvancedConfig({
: undefined,
})
}
placeholder="1500"
placeholder="6000"
disabled={!testConfig.enabled}
/>
</div>
@@ -21,7 +21,7 @@ export function ModelTestConfigPanel() {
const [config, setConfig] = useState({
timeoutSecs: "8",
maxRetries: "1",
degradedThresholdMs: "1500",
degradedThresholdMs: "6000",
});
useEffect(() => {
@@ -56,7 +56,7 @@ export function ModelTestConfigPanel() {
const parsed: StreamCheckConfig = {
timeoutSecs: parseNum(config.timeoutSecs, 8),
maxRetries: parseNum(config.maxRetries, 1),
degradedThresholdMs: parseNum(config.degradedThresholdMs, 1500),
degradedThresholdMs: parseNum(config.degradedThresholdMs, 6000),
};
await saveStreamCheckConfig(parsed);
toast.success(t("streamCheck.configSaved"), {
@@ -137,9 +137,9 @@ export function ModelTestConfigPanel() {
<Input
id="degradedThresholdMs"
type="number"
min={200}
max={10000}
step={100}
min={1000}
max={30000}
step={1000}
value={config.degradedThresholdMs}
onChange={(e) =>
setConfig({ ...config, degradedThresholdMs: e.target.value })