diff --git a/lib/ai/providers/snapgen-image.ts b/lib/ai/providers/snapgen-image.ts index f1d91c6b5..3c55318b3 100644 --- a/lib/ai/providers/snapgen-image.ts +++ b/lib/ai/providers/snapgen-image.ts @@ -374,9 +374,23 @@ function extractErrorMessage(payload: any): string { payload?.detail?.error_message || payload?.detail?.error || payload?.detail?.message || + payload?.detail?.status_desc || + payload?.data?.error_message || + payload?.data?.error?.message || + payload?.data?.error || + payload?.data?.message || + payload?.data?.msg || + payload?.data?.status_desc || + payload?.data?.state_detail || + payload?.data?.err_message || + payload?.data?.err_info || payload?.error_message || payload?.error?.message || payload?.error || + payload?.status_desc || + payload?.state_detail || + payload?.err_message || + payload?.err_info || payload?.message || payload?.msg || "SnapGen 任务执行失败" @@ -808,7 +822,13 @@ async function buildRequestForm({ } } -async function waitForHistoryResult(baseURL: string, apiKey: string, uuid: string, sourceUrls: string[]) { +async function waitForHistoryResult( + baseURL: string, + apiKey: string, + uuid: string, + sourceUrls: string[], + context: { apiFormat: SnapgenApiFormat; model: string } +) { for (let attempt = 1; attempt <= POLL_MAX_ATTEMPTS; attempt++) { const response = await fetch( joinApiPath(baseURL, `/uapi/v1/history/${encodeURIComponent(uuid)}`), @@ -818,7 +838,17 @@ async function waitForHistoryResult(baseURL: string, apiKey: string, uuid: strin if (!response.ok) { if (attempt === POLL_MAX_ATTEMPTS) { - throw new Error(`${extractErrorMessage(payload)} (HTTP ${response.status})`); + const errorMessage = extractErrorMessage(payload); + console.error("[SnapGen Image] History request failed:", { + uuid, + model: context.model, + apiFormat: context.apiFormat, + attempt, + status: response.status, + error: errorMessage, + responseSnippet: compactPayloadSnippet(payload), + }); + throw new Error(`${errorMessage} (HTTP ${response.status})`); } await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS)); continue; @@ -832,9 +862,27 @@ async function waitForHistoryResult(baseURL: string, apiKey: string, uuid: strin const statusCode = extractStatusCode(payload); if (statusCode === 3) { - throw new Error(extractErrorMessage(payload)); + const errorMessage = extractErrorMessage(payload); + console.error("[SnapGen Image] History task failed:", { + uuid, + model: context.model, + apiFormat: context.apiFormat, + attempt, + statusCode, + error: errorMessage, + responseSnippet: compactPayloadSnippet(payload), + }); + throw new Error(errorMessage); } if (statusCode === 2) { + console.error("[SnapGen Image] History task completed without images:", { + uuid, + model: context.model, + apiFormat: context.apiFormat, + attempt, + statusCode, + responseSnippet: compactPayloadSnippet(payload), + }); throw new Error("SnapGen 任务已完成但未返回图片地址"); } @@ -920,10 +968,18 @@ export function createSnapgenImage({ apiKey, baseURL }: SnapgenImageConfig) { formData, }); - let outputUrls: string[] = []; - let base64Images: Array<{ buffer: Buffer; mimeType: string }> = []; const statusCode = extractStatusCode(createPayload); const uuid = extractUuid(createPayload); + console.log("[SnapGen Image] Create task response:", { + model: runtimeModelId, + apiFormat, + statusCode, + uuid: uuid || null, + responseSnippet: compactPayloadSnippet(createPayload), + }); + + let outputUrls: string[] = []; + let base64Images: Array<{ buffer: Buffer; mimeType: string }> = []; if (statusCode === 3) { throw new Error(extractErrorMessage(createPayload)); } @@ -939,7 +995,10 @@ export function createSnapgenImage({ apiKey, baseURL }: SnapgenImageConfig) { `SnapGen 创建任务成功,但未返回 uuid 或图片结果,响应片段: ${compactPayloadSnippet(createPayload)}` ); } - const historyResult = await waitForHistoryResult(baseURL, apiKey, uuid, imageUrls); + const historyResult = await waitForHistoryResult(baseURL, apiKey, uuid, imageUrls, { + apiFormat, + model: runtimeModelId, + }); outputUrls = historyResult.imageUrls; base64Images = historyResult.base64Images; } diff --git a/lib/ai/runtime/model-health.ts b/lib/ai/runtime/model-health.ts index 0d6e2316b..765cf910c 100644 --- a/lib/ai/runtime/model-health.ts +++ b/lib/ai/runtime/model-health.ts @@ -238,6 +238,16 @@ export function classifyAiModelHealthFailure(error: unknown): { export function shouldFailoverAiModelError(error: unknown) { const classification = classifyAiModelHealthFailure(error); const normalized = getErrorMessage(error).toLowerCase(); + const imageProviderTaskFailed = + normalized.includes("image generation failed") || + normalized.includes("snapgen 任务执行失败") || + normalized.includes("snapgen 创建任务成功") || + normalized.includes("snapgen 任务已完成但未返回图片地址") || + normalized.includes("snapgen 未返回可用图片"); + + if (imageProviderTaskFailed) { + return true; + } if (classification.reason === "user_cancelled" || classification.reason === "non_provider_failure") { return false;