From 0534560f7de7163c883d0d95f4b75823a88ce3ee Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 20 Feb 2026 20:54:26 +0800 Subject: [PATCH] fix(canvas): honor model sort order and hide video models in image mode --- components/canvas/CanvasChatPanel.tsx | 34 ++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index 81b2ed92e..45b782bac 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -1314,6 +1314,7 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF modelId: string; displayName: string; avatarUrl?: string | null; + sortOrder?: number; providerType: string; supportsVision?: boolean; supportsImageGen?: boolean; @@ -1356,12 +1357,21 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF const aiDetailGenerationEnabled = siteSettings?.aiDetailGenerationEnabled === true; const VIDEO_PROVIDER_TYPES = new Set(["volcano-video", "doubao-video", "qianwen-video", "fal-video"]); - const visualModels = - modelsData?.models?.filter( - (model) => - model.modelId !== "volcano-video-master" && - (model.supportsImageGen || VIDEO_PROVIDER_TYPES.has(model.providerType)) - ) || []; + const visualModels = useMemo(() => { + const filtered = + modelsData?.models?.filter( + (model) => + model.modelId !== "volcano-video-master" && + (model.supportsImageGen || VIDEO_PROVIDER_TYPES.has(model.providerType)) + ) || []; + + return [...filtered].sort((a, b) => { + const leftOrder = Number.isFinite(a.sortOrder as number) ? Number(a.sortOrder) : 0; + const rightOrder = Number.isFinite(b.sortOrder as number) ? Number(b.sortOrder) : 0; + if (leftOrder !== rightOrder) return leftOrder - rightOrder; + return String(a.displayName || "").localeCompare(String(b.displayName || ""), "zh-Hans-CN"); + }); + }, [modelsData?.models]); // Agent模式(自动路由)模型选项 const SMART_AUTO_MODEL = { @@ -1369,6 +1379,7 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF modelId: "auto", displayName: "Agent模式", avatarUrl: modelsData?.agentModel?.avatarUrl || null, + sortOrder: -999, providerType: "auto", supportsImageGen: true, imageGenConfig: modelsData?.agentModel?.imageGenConfig || undefined, @@ -1376,6 +1387,13 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF // 所有可选模型(Agent模式 + 可视化模型) const allModels = [SMART_AUTO_MODEL, ...visualModels]; + const imageOnlyModels = useMemo( + () => + visualModels.filter( + (model) => model.supportsImageGen && !VIDEO_PROVIDER_TYPES.has(model.providerType) + ), + [visualModels] + ); const videoOnlyModels = useMemo( () => visualModels.filter((model) => VIDEO_PROVIDER_TYPES.has(model.providerType)), [visualModels] @@ -1389,8 +1407,8 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF if (isVideoModel) { return videoOnlyModels; } - return allModels; - }, [SMART_AUTO_MODEL, allModels, isDetailGenerationMode, isVideoModel, videoOnlyModels]); + return [SMART_AUTO_MODEL, ...imageOnlyModels]; + }, [SMART_AUTO_MODEL, imageOnlyModels, isDetailGenerationMode, isVideoModel, videoOnlyModels]); const modelSelectValue = selectableModels.some((model) => model.id === selectedModelId) ? selectedModelId : selectableModels[0]?.id || selectedModelId;