From 6bad214c3d9ee50d965fe86c41f1d90d0cc08a5a Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 18 Feb 2026 19:37:04 +0800 Subject: [PATCH] feat: improve video mode toolbar and agent video analysis --- components/canvas/CanvasChatPanel.tsx | 77 +++-- lib/ai/smart-analyzer.ts | 452 ++++++++++++++++++++++++-- 2 files changed, 486 insertions(+), 43 deletions(-) diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index a49d87218..dcd61eed5 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -1160,8 +1160,28 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF // 所有可选模型(Agent模式 + 可视化模型) const allModels = [SMART_AUTO_MODEL, ...visualModels]; + const videoOnlyModels = useMemo( + () => visualModels.filter((model) => VIDEO_PROVIDER_TYPES.has(model.providerType)), + [visualModels] + ); const currentModel = allModels.find((model) => model.id === selectedModelId); const isVideoModel = Boolean(currentModel && VIDEO_PROVIDER_TYPES.has(currentModel.providerType)); + const selectableModels = useMemo(() => { + if (isDetailGenerationMode) { + return [SMART_AUTO_MODEL]; + } + if (isVideoModel) { + return videoOnlyModels; + } + return allModels; + }, [SMART_AUTO_MODEL, allModels, isDetailGenerationMode, isVideoModel, videoOnlyModels]); + const modelSelectValue = selectableModels.some((model) => model.id === selectedModelId) + ? selectedModelId + : selectableModels[0]?.id || selectedModelId; + const selectDisplayModel = + selectableModels.find((model) => model.id === modelSelectValue) || + currentModel || + SMART_AUTO_MODEL; const videoFrameSlots = useMemo(() => { if (!isVideoModel || !videoParams) return [] as string[]; if (videoParams.mode === "first-last-frame") return ["首帧", "尾帧"] as string[]; @@ -1210,6 +1230,11 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF } }, [aiDetailGenerationEnabled, isDetailGenerationMode]); + useEffect(() => { + if (!modelSelectValue || modelSelectValue === selectedModelId) return; + setSelectedModelId(modelSelectValue); + }, [modelSelectValue, selectedModelId]); + useEffect(() => { if (isDetailGenerationMode) { setAttachments([]); @@ -2845,11 +2870,12 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF ); const shouldShowImageLoading = hasGenerationStart && !hasGenerationEnd && !!currentModel; const loadingImageCount = imageParams.imageCount || 1; + const isDetailEmptyState = isDetailGenerationMode && visibleMessages.length === 0; const renderModelSelectContent = () => (
- {allModels.map((model) => ( + {selectableModels.map((model) => ( {model.displayName} - {selectedModelId === model.id ? ( + {modelSelectValue === model.id ? ( ✓ ) : null} ))} + {selectableModels.length === 0 ? ( +
暂无可用模型
+ ) : null}
); @@ -3000,6 +3029,9 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF {/* 消息列表 */} + {isDetailEmptyState ? ( +
+ ) : (
+ )} {fullscreenPreview && createPortal(
-
+
)} -
- {isVideoModel ? ( - - ) : ( + {isVideoModel ? ( +
+
+ +
+
+ ) : ( +
- )} -
+
+ )}