feat(health-check): replace real-LLM probe with HTTP reachability check

The provider panel health check sent a real streaming model request, which many third-party providers block (401/403/WAF), causing false negatives while only stable official endpoints passed. Replace it with a lightweight reachability probe: GET the provider base_url and treat any HTTP response (200/4xx/5xx) as reachable; only DNS/connect/TLS/timeout count as failure. Latency is the probe's TTFB.

Backend (services/stream_check.rs): rewrite ~2200 -> ~350 lines, dropping real-request building, format conversion, auth and API-path resolution while keeping per-app base_url extraction. Defaults: 8s timeout, 1 retry, 1500ms degraded threshold.

Failover invariant: the reachability check must never reset the circuit breaker (reachable != usable; a 403 host is reachable but broken for real traffic). Remove the resetCircuitBreaker call from useStreamCheck; failover failure detection stays driven solely by real proxy traffic (forwarder/circuit_breaker untouched). useResetCircuitBreaker is kept dormant for a future manual-recovery entry.

Open the check to all providers: drop the official/copilot/codex-oauth/third-party gating and the 'sends a real request' confirm dialog. For official providers whose base_url is intentionally empty, fall back to the endpoint the client actually uses (Claude -> api.anthropic.com, Codex -> chatgpt.com/backend-api/codex, Gemini -> generativelanguage). Non-official providers with a missing base_url still error to avoid a false green light. Claude Desktop Official is native 1P mode (talks to claude.ai, cc-switch not in the request path, no reliable endpoint) so its button stays hidden.

Slim StreamCheckConfig and per-provider testConfig to timeout/threshold/retries (drop test model + prompt); sync zh/en/ja/zh-TW. Retain the now-unused anthropic_to_openai/anthropic_to_gemini transform utilities and their test suites.
This commit is contained in:
Jason
2026-06-14 15:15:34 +08:00
parent b7ad1c4bf8
commit a5903d8600
18 changed files with 542 additions and 2402 deletions
+7 -10
View File
@@ -1,18 +1,18 @@
import { invoke } from "@tauri-apps/api/core";
import type { AppId } from "./types";
// ===== 流式健康检查类型 =====
// ===== 连通性检查类型 =====
// 注意:本检查只探测 base_url 是否可达,不发真实大模型请求,也不触碰故障转移熔断器。
export type HealthStatus = "operational" | "degraded" | "failed";
export interface StreamCheckConfig {
/** 单次探测超时(秒) */
timeoutSecs: number;
/** 超时类失败的最大重试次数 */
maxRetries: number;
/** 降级阈值(毫秒):可达但 TTFB 超过该值判定为"较慢" */
degradedThresholdMs: number;
claudeModel: string;
codexModel: string;
geminiModel: string;
testPrompt: string;
}
export interface StreamCheckResult {
@@ -21,17 +21,14 @@ export interface StreamCheckResult {
message: string;
responseTimeMs?: number;
httpStatus?: number;
modelUsed: string;
testedAt: number;
retryCount: number;
/** 细粒度错误分类,如 "modelNotFound" */
errorCategory?: string;
}
// ===== 流式健康检查 API =====
// ===== 连通性检查 API =====
/**
* 流式健康检查(单个供应商)
* 连通性检查(单个供应商)
*/
export async function streamCheckProvider(
appType: AppId,