ai-chatbot/lib/ai/runtime/image-generation-error.ts

31 lines
2.5 KiB
TypeScript

/** Only adapters with an explicit rejection of the submission may use this.
* Polling, result downloads and storage failures are not submission refusals. */
export class ImageSubmissionRejectedError extends Error {
constructor(message: string, readonly status: number) { super(message); }
}
export class AgentImageGenerationError extends Error {
constructor(message: string, readonly confirmedNoResult: boolean) { super(message); }
}
/** Preserve outcome evidence when replacing upstream diagnostics with safe UI text. */
export function agentImageGenerationError(error: unknown, mode: "auto" | "pinned") {
const rejected = error instanceof ImageSubmissionRejectedError;
const message = error instanceof Error ? error.message : "";
const suffix = mode === "pinned" ? "系统未自动切换。你希望切换生图模型,还是稍后重试?切换前请在模型选择器中选择其他模型或自动选择。" : "请稍后重试或联系管理员处理生图通道。";
if (rejected && /余额|insufficient.*(?:balance|credit)|credits? insufficient/i.test(message))
return new AgentImageGenerationError(`生图通道余额不足,本次未生成图片。${suffix}`, true);
if (rejected && error.status === 429)
return new AgentImageGenerationError(`生图通道额度不足或请求过多,本次未生成图片。${suffix}`, true);
if (rejected && [401, 403].includes(error.status))
return new AgentImageGenerationError(`生图通道鉴权或权限未通过,本次未生成图片。${suffix}`, true);
if (/content.?policy|moderation|safety|违规|敏感/i.test(message))
return new AgentImageGenerationError("当前图片内容无法处理,请调整描述或参考图后重试。", rejected);
if ((error as { providerOutcomeUnknown?: boolean })?.providerOutcomeUnknown || /may still be running|仍在处理|outcome.unknown|timed out|timeout|超时|fetch failed|econnreset/i.test(message))
return new AgentImageGenerationError("图片任务的结果暂未确认,已保留任务记录,请先确认原任务结果,避免重复生成。", false);
if (rejected) return new AgentImageGenerationError(`生图通道拒绝了本次请求,未生成图片。${suffix}`, true);
return new AgentImageGenerationError(mode === "pinned"
? "你指定的生图模型本次未能完成,请稍后重试或手动更换模型;系统未自动切换。"
: "暂时未能完成本次出图,请检查描述、参考图或稍后继续;已有结果会保留。", rejected);
}