fix(models): isModelError 识别「issue with the selected model」→ 触发回退链

线上实测:reviewer 用 fable-5 报「There's an issue with the selected model
(claude-fable-5)」(该档未对当前账号开通),但 isModelError 未命中此措辞 → 不回退 →
复审失败(verdict=null)。补正则后 fable-5 不可用会自动回退 opus 重试,复审正常。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-06-24 23:44:48 +08:00
parent 1bf3fecf42
commit a9c51021aa
2 changed files with 6 additions and 2 deletions
+4 -2
View File
@@ -71,10 +71,12 @@ export function pickClassifierModel(): string {
return process.env[env]?.trim() || fallback;
}
/** 错误信息是否像“模型不可用”(not_found / invalid / permission 等模式 + 提到 model */
/** 错误信息是否像“模型不可用”(not_found / invalid / permission 等模式 + 提到 model
* 含 Claude Code 的「There's an issue with the selected model (X)」——某档模型未对当前账号开通时的报错,
* 必须命中才能触发回退链(如 fable-5 未开通 → 回退 opus)。 */
export function isModelError(msg: string): boolean {
if (!/model/i.test(msg)) return false;
return /not[_\s-]?found|invalid|permission|forbidden|unauthorized|unavailable|unknown|unsupported|does not exist|no access|404|403/i.test(msg);
return /not[_\s-]?found|invalid|permission|forbidden|unauthorized|unavailable|unknown|unsupported|does not exist|no access|issue with (the )?selected model|404|403/i.test(msg);
}
/** 回退链里取失败模型的下一档(循环);未在链上则取首档。 */
+2
View File
@@ -94,6 +94,8 @@ test('isModelError:模型不可用类错误才触发回退', () => {
assert.ok(isModelError('404 model does not exist'));
assert.ok(isModelError('The requested model is unavailable'));
assert.ok(isModelError('unknown model "claude-fable-5"'));
// Claude Code 的「未开通某档模型」报错(线上 fable-5 实测)
assert.ok(isModelError("There's an issue with the selected model (claude-fable-5)"));
// 不应触发
assert.ok(!isModelError('执行超时'));
assert.ok(!isModelError('network connection refused'));