Adjust image model failover timing
This commit is contained in:
parent
d24eedc578
commit
1b79f788b5
@ -25,6 +25,7 @@ interface UploadedImage {
|
|||||||
|
|
||||||
const DEFAULT_IMAGE_SIZE = "2K";
|
const DEFAULT_IMAGE_SIZE = "2K";
|
||||||
const DEFAULT_TIMEOUT_MS = 300000;
|
const DEFAULT_TIMEOUT_MS = 300000;
|
||||||
|
const LONG_RUNNING_COMFLY_TIMEOUT_MS = 590000;
|
||||||
const OPENAI_IMAGE_MIN_TOTAL_PIXELS = 3_686_400;
|
const OPENAI_IMAGE_MIN_TOTAL_PIXELS = 3_686_400;
|
||||||
const OPENAI_IMAGE_DIMENSION_MULTIPLE = 16;
|
const OPENAI_IMAGE_DIMENSION_MULTIPLE = 16;
|
||||||
const BLTCY_HOST_REGEX = /(^|\.)bltcy\.ai$/i;
|
const BLTCY_HOST_REGEX = /(^|\.)bltcy\.ai$/i;
|
||||||
@ -216,6 +217,13 @@ function resolveProviderImageSize(
|
|||||||
return resolveOpenAISize(aspectRatio, imageSize);
|
return resolveOpenAISize(aspectRatio, imageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveRequestTimeoutMs(baseURL: string, imageSize?: "1K" | "2K" | "4K") {
|
||||||
|
if (isComflyBaseURL(baseURL) && imageSize === "4K") {
|
||||||
|
return LONG_RUNNING_COMFLY_TIMEOUT_MS;
|
||||||
|
}
|
||||||
|
return DEFAULT_TIMEOUT_MS;
|
||||||
|
}
|
||||||
|
|
||||||
function normalizeQuality(value?: string) {
|
function normalizeQuality(value?: string) {
|
||||||
const normalized = String(value || "").trim().toLowerCase();
|
const normalized = String(value || "").trim().toLowerCase();
|
||||||
if (normalized === "low" || normalized === "medium" || normalized === "high") {
|
if (normalized === "low" || normalized === "medium" || normalized === "high") {
|
||||||
@ -453,9 +461,10 @@ async function requestOpenAIImageGeneration(params: {
|
|||||||
typeof aspectRatio === "string" && aspectRatio.trim() && aspectRatio !== "auto"
|
typeof aspectRatio === "string" && aspectRatio.trim() && aspectRatio !== "auto"
|
||||||
? aspectRatio.trim()
|
? aspectRatio.trim()
|
||||||
: undefined;
|
: undefined;
|
||||||
|
const timeoutMs = resolveRequestTimeoutMs(baseURL, imageSizeLabel);
|
||||||
|
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);
|
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (imageUrls.length > 0) {
|
if (imageUrls.length > 0) {
|
||||||
@ -588,6 +597,7 @@ export function createOpenAIImage({ apiKey, baseURL }: OpenAIImageConfig) {
|
|||||||
promptAspectRatio: promptAspectRatio || undefined,
|
promptAspectRatio: promptAspectRatio || undefined,
|
||||||
imageSize,
|
imageSize,
|
||||||
resolutionMode: isComflyBaseURL(baseURL) ? "longest-edge" : "pixel-area",
|
resolutionMode: isComflyBaseURL(baseURL) ? "longest-edge" : "pixel-area",
|
||||||
|
timeoutMs: resolveRequestTimeoutMs(baseURL, imageSize),
|
||||||
useBltcyImageCompatParams: shouldUseBltcyImageCompatParams(baseURL),
|
useBltcyImageCompatParams: shouldUseBltcyImageCompatParams(baseURL),
|
||||||
imageCount: imageUrls.length,
|
imageCount: imageUrls.length,
|
||||||
baseURL: normalizeBaseURL(baseURL),
|
baseURL: normalizeBaseURL(baseURL),
|
||||||
|
|||||||
@ -89,6 +89,22 @@ export function classifyAiModelHealthFailure(error: unknown): {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
normalized.includes("fetch failed") ||
|
||||||
|
normalized.includes("econnreset") ||
|
||||||
|
normalized.includes("econnrefused") ||
|
||||||
|
normalized.includes("socket hang up") ||
|
||||||
|
normalized.includes("networkerror") ||
|
||||||
|
normalized.includes("network error")
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
eventType: "unavailable",
|
||||||
|
severity: "warning",
|
||||||
|
counted: false,
|
||||||
|
reason: "transport_failure_no_provider_response",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
normalized.includes("model not exist") ||
|
normalized.includes("model not exist") ||
|
||||||
normalized.includes("model_not_found") ||
|
normalized.includes("model_not_found") ||
|
||||||
@ -133,9 +149,9 @@ export function classifyAiModelHealthFailure(error: unknown): {
|
|||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
eventType: "timeout",
|
eventType: "timeout",
|
||||||
severity: "critical",
|
severity: "warning",
|
||||||
counted: true,
|
counted: false,
|
||||||
reason: "timeout",
|
reason: "timeout_without_provider_response",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,8 +166,7 @@ export function classifyAiModelHealthFailure(error: unknown): {
|
|||||||
normalized.includes("no available channel") ||
|
normalized.includes("no available channel") ||
|
||||||
normalized.includes("no supported channel") ||
|
normalized.includes("no supported channel") ||
|
||||||
normalized.includes("service unavailable") ||
|
normalized.includes("service unavailable") ||
|
||||||
normalized.includes("fetch failed") ||
|
normalized.includes("temporarily unavailable")
|
||||||
normalized.includes("econnreset")
|
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
eventType: "unavailable",
|
eventType: "unavailable",
|
||||||
@ -184,7 +199,32 @@ export function classifyAiModelHealthFailure(error: unknown): {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function shouldFailoverAiModelError(error: unknown) {
|
export function shouldFailoverAiModelError(error: unknown) {
|
||||||
return classifyAiModelHealthFailure(error).counted;
|
const classification = classifyAiModelHealthFailure(error);
|
||||||
|
if (!classification.counted) return false;
|
||||||
|
|
||||||
|
const normalized = getErrorMessage(error).toLowerCase();
|
||||||
|
if (classification.eventType === "timeout" || classification.eventType === "download_error") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (classification.eventType === "invalid_model" || classification.eventType === "quota") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (classification.eventType === "unavailable") {
|
||||||
|
return (
|
||||||
|
/(?:^|\D)(?:429|500|502|503|504)(?:\D|$)/.test(normalized) ||
|
||||||
|
normalized.includes("no available channel") ||
|
||||||
|
normalized.includes("no supported channel") ||
|
||||||
|
normalized.includes("service unavailable") ||
|
||||||
|
normalized.includes("temporarily unavailable") ||
|
||||||
|
normalized.includes("model maintenance") ||
|
||||||
|
normalized.includes("maintenance") ||
|
||||||
|
normalized.includes("修复中") ||
|
||||||
|
normalized.includes("系统繁忙") ||
|
||||||
|
normalized.includes("无可用渠道")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return /(?:^|\D)[45]\d\d(?:\D|$)/.test(normalized);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildMetadata(value?: Record<string, unknown>) {
|
function buildMetadata(value?: Record<string, unknown>) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user