diff --git a/components/image-params-bar.tsx b/components/image-params-bar.tsx index 9a0e7fbb1..5e025f216 100644 --- a/components/image-params-bar.tsx +++ b/components/image-params-bar.tsx @@ -102,13 +102,18 @@ export function ImageParamsBar({ // Gemini:1~2 张 return [1, 2]; }; + const supportsSize = imageGenConfig?.supportsSize !== false; const clampParamsByProvider = (raw: ImageGenerationParams): ImageGenerationParams => { const options = getImageCountOptions(); const fallbackCount = options[0] ?? 1; const imageCount = options.includes(raw.imageCount || fallbackCount) ? (raw.imageCount || fallbackCount) : fallbackCount; + const imageSize = supportsSize + ? (raw.imageSize || "2K") + : "2K"; return { ...raw, + imageSize, imageCount, }; }; @@ -204,26 +209,37 @@ export function ImageParamsBar({ {/* 分辨率 */} - - - - - - {IMAGE_SIZE_OPTIONS.map((option) => ( - updateParam("imageSize", option.value)} - className="focus-visible:ring-0 focus-visible:ring-offset-0 focus:outline-none focus:ring-0" - > - - {option.label} - - ))} - - + {supportsSize ? ( + + + + + + {IMAGE_SIZE_OPTIONS.map((option) => ( + updateParam("imageSize", option.value)} + className="focus-visible:ring-0 focus-visible:ring-offset-0 focus:outline-none focus:ring-0" + > + + {option.label} + + ))} + + + ) : ( + + )} {showImageCountSelector && ( diff --git a/lib/ai/providers/volcano-vision.ts b/lib/ai/providers/volcano-vision.ts index 57d71f413..4ec5d2cba 100644 --- a/lib/ai/providers/volcano-vision.ts +++ b/lib/ai/providers/volcano-vision.ts @@ -18,6 +18,7 @@ let cachedRewriteConfig: VolcanoUrlRewriteConfig | null | undefined; const VOLCANO_IMAGE_FETCH_TIMEOUT_MS = 20_000; const VOLCANO_INLINE_MAX_SIDE = 1024; const DEFAULT_VOLCANO_IMAGE_SIZE = "2K"; +const SEEDREAM_MODEL_ID_PATTERN = /doubao-seedream-4-5/i; function normalizeVolcanoImageSize(imageSize?: string): "1K" | "2K" | "4K" { const normalized = String(imageSize || "").trim().toUpperCase(); @@ -27,6 +28,23 @@ function normalizeVolcanoImageSize(imageSize?: string): "1K" | "2K" | "4K" { return DEFAULT_VOLCANO_IMAGE_SIZE; } +function resolveVolcanoImageSizeForModel( + modelId: string, + imageSize?: string +): "1K" | "2K" | "4K" { + const normalized = normalizeVolcanoImageSize(imageSize); + if (SEEDREAM_MODEL_ID_PATTERN.test(modelId)) { + // doubao-seedream-4-5 在当前链路下 1K 会返回 InvalidParameter,强制回落到 2K + if (normalized === "1K") { + console.log( + `[Volcano Vision] Size normalized for ${modelId}: 1K -> 2K (model constraint)` + ); + return "2K"; + } + } + return normalized; +} + function guessImageMimeTypeFromUrl(url: string): string { const cleanUrl = url.split("?")[0]?.toLowerCase() || ""; if (cleanUrl.endsWith(".png")) return "image/png"; @@ -478,7 +496,7 @@ async function sendVolcanoRequest( console.log("[Volcano Vision] Image count:", image ? (Array.isArray(image) ? image.length : 1) : 0); // 构建请求体 - const normalizedSize = normalizeVolcanoImageSize(imageSize); + const normalizedSize = resolveVolcanoImageSizeForModel(modelId, imageSize); const requestBody: any = { model: modelId, prompt, @@ -711,7 +729,10 @@ export function createVolcanoVision({ apiKey, baseURL }: VolcanoVisionConfig) { const activeModelId = options.overrideModelId || modelId; console.log("[Volcano Vision] Using modelId:", activeModelId); console.log("[Volcano Vision] Image params from options:", options.imageParams); - const imageSize = normalizeVolcanoImageSize(options.imageParams?.imageSize); + const imageSize = resolveVolcanoImageSizeForModel( + activeModelId, + options.imageParams?.imageSize + ); // 🆕 优先使用用户选择的图片数量,其次是 maxImages 参数,默认 1 张 const imageCount = options.imageParams?.imageCount || options.maxImages || 1; @@ -772,7 +793,10 @@ export function createVolcanoVision({ apiKey, baseURL }: VolcanoVisionConfig) { const allImages: Array<{ thumbnail: string; original: string }> = []; // 使用流式请求 - const imageSize = normalizeVolcanoImageSize(options.imageParams?.imageSize); + const imageSize = resolveVolcanoImageSizeForModel( + modelId, + options.imageParams?.imageSize + ); for await (const event of sendVolcanoStreamRequest(baseURL, apiKey, options.messages, modelId, imageSize)) { if (event.type === "image_generation.partial_succeeded" && event.url) { // 每张图片生成完成后立即上传并发送