From 2f8ff5fd12122bb9aae95ae8e462023b0dc5c353 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 20 Feb 2026 17:24:05 +0800 Subject: [PATCH] fix: sync model max image count config to frontend controls --- app/(chat)/api/models/route.ts | 1 + components/canvas/CanvasChatPanel.tsx | 9 +++++++++ components/chat.tsx | 9 +++++++++ components/home/lovart-home.tsx | 9 +++++++++ components/multimodal-input.tsx | 21 +++++++++++++++++++++ 5 files changed, 49 insertions(+) diff --git a/app/(chat)/api/models/route.ts b/app/(chat)/api/models/route.ts index cec284614..35f80da1f 100644 --- a/app/(chat)/api/models/route.ts +++ b/app/(chat)/api/models/route.ts @@ -39,6 +39,7 @@ export async function GET() { isSubModel: model.isSubModel, parentModelId: model.parentModelId, capabilities: model.capabilities, // 🆕 返回子模型的能力配置 + imageGenConfig: model.imageGenConfig, })); const resolvedDefaultModelId = diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index 87187dca8..4af9599fa 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -1302,6 +1302,14 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF supportsVision?: boolean; supportsImageGen?: boolean; capabilities?: string[] | null; + imageGenConfig?: { + maxImages?: number; + supportsSize?: boolean; + supportsPromptExtend?: boolean; + supportsNegativePrompt?: boolean; + supportsWatermark?: boolean; + supportsSeed?: boolean; + } | null; }>; agentModel?: { id: string; @@ -5362,6 +5370,7 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF onParamsChange={handleImageParamsChange} inline={true} providerType={currentModel?.providerType} + imageGenConfig={currentModel?.imageGenConfig || undefined} /> )} diff --git a/components/chat.tsx b/components/chat.tsx index ad9d09f7c..1ef4b5bcf 100644 --- a/components/chat.tsx +++ b/components/chat.tsx @@ -369,6 +369,14 @@ export function Chat({ providerType: string; supportsVision?: boolean; supportsImageGen?: boolean; + imageGenConfig?: { + maxImages?: number; + supportsSize?: boolean; + supportsPromptExtend?: boolean; + supportsNegativePrompt?: boolean; + supportsWatermark?: boolean; + supportsSeed?: boolean; + } | null; }>; }>("/api/models", fetcher); @@ -1914,6 +1922,7 @@ export function Chat({ imageParams={imageParams} onImageParamsChange={handleImageParamsChange} imageProviderType={currentModel?.providerType} + imageGenConfig={currentModel?.imageGenConfig || undefined} /> )} diff --git a/components/home/lovart-home.tsx b/components/home/lovart-home.tsx index 3d08d5a39..b593192df 100644 --- a/components/home/lovart-home.tsx +++ b/components/home/lovart-home.tsx @@ -96,6 +96,14 @@ type ModelOption = { avatarUrl?: string | null; providerType: string; supportsImageGen?: boolean; + imageGenConfig?: { + maxImages?: number; + supportsSize?: boolean; + supportsPromptExtend?: boolean; + supportsNegativePrompt?: boolean; + supportsWatermark?: boolean; + supportsSeed?: boolean; + } | null; }; type NavLink = { @@ -1704,6 +1712,7 @@ export function LovartHome({ onParamsChange={handleImageParamsChange} inline providerType={triggerComposerModel?.providerType} + imageGenConfig={triggerComposerModel?.imageGenConfig || undefined} hideImageCount /> diff --git a/components/multimodal-input.tsx b/components/multimodal-input.tsx index 355e899e5..fb69b3fba 100644 --- a/components/multimodal-input.tsx +++ b/components/multimodal-input.tsx @@ -17,6 +17,14 @@ type DynamicModel = { isSubModel?: boolean; // 🆕 是否为子模型 parentModelId?: string | null; // 🆕 父模型ID capabilities?: any; // 🆕 模型能力配置 + imageGenConfig?: { + maxImages?: number; + supportsSize?: boolean; + supportsPromptExtend?: boolean; + supportsNegativePrompt?: boolean; + supportsWatermark?: boolean; + supportsSeed?: boolean; + } | null; }; const fetcher = (url: string) => fetch(url).then((res) => res.json()); @@ -93,6 +101,7 @@ function PureMultimodalInput({ imageParams, onImageParamsChange, imageProviderType, + imageGenConfig, }: { chatId: string; input: string; @@ -119,6 +128,14 @@ function PureMultimodalInput({ imageParams?: ImageGenerationParams | null; onImageParamsChange?: (params: ImageGenerationParams) => void; imageProviderType?: string; // 🆕 图片模型提供商类型 + imageGenConfig?: { + maxImages?: number; + supportsSize?: boolean; + supportsPromptExtend?: boolean; + supportsNegativePrompt?: boolean; + supportsWatermark?: boolean; + supportsSeed?: boolean; + } | null; }) { // 🔍 调试日志:检查图片模型相关props console.log('[MultimodalInput] Render - isImageModel:', isImageModel); @@ -1051,6 +1068,7 @@ function PureMultimodalInput({ onParamsChange={onImageParamsChange} inline={true} providerType={imageProviderType} + imageGenConfig={imageGenConfig || undefined} /> )} @@ -1108,6 +1126,9 @@ export const MultimodalInput = memo( if (!equal(prevProps.imageParams, nextProps.imageParams)) { return false; } + if (!equal(prevProps.imageGenConfig, nextProps.imageGenConfig)) { + return false; + } return true; }