|
@@ -59,13 +59,17 @@ function shouldSwitchModel(error: any): boolean {
|
|
|
if (nonSwitchablePatterns.some(p => message.includes(p))) return false;
|
|
if (nonSwitchablePatterns.some(p => message.includes(p))) return false;
|
|
|
if (status === 401) return false; // 认证失败
|
|
if (status === 401) return false; // 认证失败
|
|
|
|
|
|
|
|
- // 可切换的错误:限流、余额不足、服务不可用、模型不存在
|
|
|
|
|
|
|
+ // 可切换的错误:限流、余额不足、服务不可用、模型不存在、网络/超时
|
|
|
const switchablePatterns = [
|
|
const switchablePatterns = [
|
|
|
'rate limit', 'rate_limit', 'too many requests', '请求过于频繁',
|
|
'rate limit', 'rate_limit', 'too many requests', '请求过于频繁',
|
|
|
'quota', 'balance', 'insufficient', 'usage limit',
|
|
'quota', 'balance', 'insufficient', 'usage limit',
|
|
|
'model not found', 'model not support', 'does not exist', 'invalid model',
|
|
'model not found', 'model not support', 'does not exist', 'invalid model',
|
|
|
'service unavailable', 'bad gateway', 'gateway timeout',
|
|
'service unavailable', 'bad gateway', 'gateway timeout',
|
|
|
'internal server error',
|
|
'internal server error',
|
|
|
|
|
+ // 网络/超时错误 - 切换供应商是唯一恢复手段
|
|
|
|
|
+ 'timed out', 'timeout', 'request timeout',
|
|
|
|
|
+ 'etimedout', 'esockettimedout', 'econnreset', 'econnrefused',
|
|
|
|
|
+ 'enotfound', 'fetch failed', 'aborted', 'eai_again',
|
|
|
];
|
|
];
|
|
|
if (switchablePatterns.some(p => message.includes(p))) return true;
|
|
if (switchablePatterns.some(p => message.includes(p))) return true;
|
|
|
|
|
|