|
|
@@ -497,6 +497,8 @@ export function clearModelCache() {
|
|
|
* 检查错误是否需要切换供应商
|
|
|
* 调度策略:同 Key 换模型无意义(额度共享),直接切换到下一个供应商
|
|
|
* 优先查找同名/别名模型(canonicalModel),保持模型一致性
|
|
|
+ *
|
|
|
+ * 优化:timeout 类错误直接触发切换(不依赖熔断器),避免卡在死掉的供应商上
|
|
|
*/
|
|
|
function trySwitchModel(currentModelId: string, error: any): string | null {
|
|
|
const errorMessage = error?.message || '';
|
|
|
@@ -516,7 +518,18 @@ function trySwitchModel(currentModelId: string, error: any): string | null {
|
|
|
return switchToNextVendorModel(currentModelId);
|
|
|
}
|
|
|
|
|
|
- // 3. 可恢复错误,直接切换到下一个供应商
|
|
|
+ // 3. 网络/超时错误:直接切换供应商(不等熔断器积累 3 次失败)
|
|
|
+ const NETWORK_ERROR_PATTERNS = [
|
|
|
+ 'timed out', 'timeout', 'request timeout',
|
|
|
+ 'etimedout', 'esockettimedout', 'econnreset', 'econnrefused',
|
|
|
+ 'enotfound', 'fetch failed', 'aborted', 'eai_again',
|
|
|
+ ];
|
|
|
+ if (NETWORK_ERROR_PATTERNS.some(p => errorMessage.toLowerCase().includes(p))) {
|
|
|
+ console.log(`[LLM] 检测到网络/超时错误,立即切换供应商: ${errorMessage.substring(0, 80)}`);
|
|
|
+ return switchToNextVendorModel(currentModelId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 可恢复错误,调用通用判断(限流/余额/服务不可用等)
|
|
|
if (config.models.shouldSwitchModel(errorMessage)) {
|
|
|
return switchToNextVendorModel(currentModelId);
|
|
|
}
|