26 lines
2.5 KiB
TypeScript
26 lines
2.5 KiB
TypeScript
import { agentModelFault, type AgentModelFault } from "./agent-model-failover";
|
||
|
||
export function agentImageFailurePolicy(error: unknown): { retry: boolean; pause: AgentModelFault | null } {
|
||
const value = error as { message?: string; providerOutcomeUnknown?: boolean; status?: number; statusCode?: number } | null;
|
||
const message = String(value?.message || "").toLowerCase();
|
||
// A submitted image job may still succeed. Retain its task and reconcile it;
|
||
// never submit another paid job just because a poll/connection timed out.
|
||
const unknown = value?.providerOutcomeUnknown || /request_outcome_unknown|may still be running|outcome.unknown|timed out|timeout|超时|fetch failed|econnreset|socket hang up/.test(message);
|
||
if (unknown && !/task failed|task.*(?:failed|cancelled|canceled)|任务.*(?:失败|取消)/.test(message)) return { retry: false, pause: null };
|
||
if (/content.?policy|moderation|safety|违规|敏感|积分不足|本月.*配额|user cancel|user abort/.test(message)) return { retry: false, pause: null };
|
||
const status = Number(value?.statusCode || value?.status) || Number(message.match(/(?:http[\s::]*|status(?:code)?[\s:=]*|api request failed[\s::]*)([45]\d{2})/i)?.[1]) || null;
|
||
if (/unauthorized|invalid[ _]?(?:api[ _]?)?key|authentication/.test(message)) return { retry: true, pause: { reason: "authentication", status } };
|
||
if (/forbidden|access denied/.test(message)) return { retry: true, pause: { reason: "access_denied", status } };
|
||
if (/quota|insufficient.*(?:balance|credit)|credits? insufficient|余额|额度|配额|rate.?limit|too many requests/.test(message))
|
||
return { retry: true, pause: { reason: "rate_or_quota", status } };
|
||
// Rejected image parameters can be valid on another provider. Keep the
|
||
// requested parameters and try a compatible alternate without banning the
|
||
// rejected model; these are not evidence of a model outage.
|
||
if (status && [400, 413, 415, 422].includes(status)) return { retry: true, pause: null };
|
||
const fault = agentModelFault(status ? { message, status } : error);
|
||
if (fault) return { retry: true, pause: fault };
|
||
if (/task failed|image generation failed|生成失败|任务.*失败|未返回.*图片|no images? (?:in|url)|no valid data|response body is null|empty.result|empty.response|provider.error|上游.*错误|模型.*维护|internal.server.error|service.unavailable|bad.gateway|server.busy|系统繁忙/.test(message))
|
||
return { retry: true, pause: { reason: "image_generation_failed", status: Number(value?.statusCode || value?.status) || null } };
|
||
return { retry: false, pause: null };
|
||
}
|