Prefer streaming for custom image generation

This commit is contained in:
Codex
2026-05-09 05:42:33 +00:00
parent 234da90ac6
commit c8f0c37cd1
2 changed files with 17 additions and 1 deletions

View File

@@ -409,6 +409,15 @@ function extractImagesFromGenerationsResponse(data: Record<string, unknown>): st
} else if (typeof data.image_url === 'string') { } else if (typeof data.image_url === 'string') {
images.push(data.image_url); images.push(data.image_url);
} }
const streamEvents = data.__streamEvents;
if (Array.isArray(streamEvents)) {
for (const event of streamEvents) {
if (!event || typeof event !== 'object' || Array.isArray(event)) continue;
images.push(...extractImagesFromGenerationsResponse(event as Record<string, unknown>));
}
}
return images; return images;
} }
@@ -511,6 +520,7 @@ async function tryEditsWithFormData(
const textFields: Record<string, string> = { const textFields: Record<string, string> = {
model, model,
prompt, prompt,
stream: 'true',
}; };
if (size) textFields.size = size; if (size) textFields.size = size;
if (count > 1) textFields.n = String(count); if (count > 1) textFields.n = String(count);
@@ -700,7 +710,7 @@ async function customApiImageToImage(
const chatUrl = deriveChatCompletionsUrl(endpoint); const chatUrl = deriveChatCompletionsUrl(endpoint);
const chatBody: Record<string, unknown> = { const chatBody: Record<string, unknown> = {
model: customApiConfig.modelName, model: customApiConfig.modelName,
stream: false, stream: true,
messages: [ messages: [
{ {
role: 'user', role: 'user',
@@ -734,6 +744,7 @@ async function customApiImageToImage(
n: count, n: count,
size: size || '1024x1024', size: size || '1024x1024',
response_format: 'b64_json', response_format: 'b64_json',
stream: true,
init_image: rawBase64, init_image: rawBase64,
denoising_strength: denoisingStrength, denoising_strength: denoisingStrength,
}; };
@@ -871,6 +882,7 @@ export async function POST(request: NextRequest) {
n, n,
size: size || '1024x1024', size: size || '1024x1024',
response_format: 'b64_json', response_format: 'b64_json',
stream: true,
}; };
if (negativePrompt) { if (negativePrompt) {
requestBody.negative_prompt = negativePrompt; requestBody.negative_prompt = negativePrompt;
@@ -889,6 +901,7 @@ export async function POST(request: NextRequest) {
'| size:', requestBody.size, '| size:', requestBody.size,
'| n:', requestBody.n, '| n:', requestBody.n,
'| aspect_ratio:', requestBody.aspect_ratio, '| aspect_ratio:', requestBody.aspect_ratio,
'| stream:', requestBody.stream,
'| guidance_scale:', requestBody.guidance_scale, '| guidance_scale:', requestBody.guidance_scale,
'| prompt_length:', prompt.length, '| prompt_length:', prompt.length,
'| augmented_prompt_length:', augmentedPrompt.length); '| augmented_prompt_length:', augmentedPrompt.length);

View File

@@ -273,5 +273,8 @@ export function parseCustomApiError(status: number, rawBody: string): string {
if (status === 413 || /request entity too large|payload too large|content too large/i.test(trimmed)) { if (status === 413 || /request entity too large|payload too large|content too large/i.test(trimmed)) {
return '参考图请求体过大,上游模型服务拒绝接收。平台已自动压缩参考图;如果仍失败,请减少参考图数量、上传更小图片,或让 API 供应商提高图生图上传限制。'; return '参考图请求体过大,上游模型服务拒绝接收。平台已自动压缩参考图;如果仍失败,请减少参考图数量、上传更小图片,或让 API 供应商提高图生图上传限制。';
} }
if (status === 524 || /cloudflare|error code 524|a timeout occurred|origin web server timed out/i.test(trimmed)) {
return '上游 API 同步生图请求超时Cloudflare 524。请确认该供应商已开启流式生图或异步任务接口高分辨率生图不要走会长时间无响应的同步接口。';
}
return trimmed || `HTTP ${status}`; return trimmed || `HTTP ${status}`;
} }