diff --git a/frontend/src/components/DownloadDialog.tsx b/frontend/src/components/DownloadDialog.tsx index d94362e8..7a5ffd16 100644 --- a/frontend/src/components/DownloadDialog.tsx +++ b/frontend/src/components/DownloadDialog.tsx @@ -9,11 +9,11 @@ import { DialogTitle, } from "./ui/dialog"; import { Progress } from "./ui/progress"; -import { PIPELINES } from "../data/pipelines"; -import type { PipelineId, DownloadProgress } from "../types"; +import type { PipelineId, DownloadProgress, PipelineInfo } from "../types"; interface DownloadDialogProps { open: boolean; + pipelines: Record | null; pipelineId: PipelineId; onClose: () => void; onDownload: () => void; @@ -23,13 +23,14 @@ interface DownloadDialogProps { export function DownloadDialog({ open, + pipelines, pipelineId, onClose, onDownload, isDownloading = false, progress = null, }: DownloadDialogProps) { - const pipelineInfo = PIPELINES[pipelineId]; + const pipelineInfo = pipelines?.[pipelineId]; if (!pipelineInfo) return null; return ( diff --git a/frontend/src/components/InputAndControlsPanel.tsx b/frontend/src/components/InputAndControlsPanel.tsx index ca3a0e06..67ef39ac 100644 --- a/frontend/src/components/InputAndControlsPanel.tsx +++ b/frontend/src/components/InputAndControlsPanel.tsx @@ -14,8 +14,7 @@ import { Upload, ArrowUp } from "lucide-react"; import { LabelWithTooltip } from "./ui/label-with-tooltip"; import type { VideoSourceMode } from "../hooks/useVideoSource"; import type { PromptItem, PromptTransition } from "../lib/api"; -import type { InputMode } from "../types"; -import { pipelineIsMultiMode } from "../data/pipelines"; +import type { InputMode, PipelineInfo } from "../types"; import { PromptInput } from "./PromptInput"; import { TimelinePromptEditor } from "./TimelinePromptEditor"; import type { TimelinePrompt } from "./PromptTimeline"; @@ -24,6 +23,7 @@ import { Button } from "./ui/button"; interface InputAndControlsPanelProps { className?: string; + pipelines: Record | null; localStream: MediaStream | null; isInitializing: boolean; error: string | null; @@ -73,6 +73,7 @@ interface InputAndControlsPanelProps { export function InputAndControlsPanel({ className = "", + pipelines, localStream, isInitializing, error, @@ -128,7 +129,8 @@ export function InputAndControlsPanel({ const videoRef = useRef(null); // Check if this pipeline supports multiple input modes - const isMultiMode = pipelineIsMultiMode(pipelineId); + const pipeline = pipelines?.[pipelineId]; + const isMultiMode = (pipeline?.supportedModes?.length ?? 0) > 1; useEffect(() => { if (videoRef.current && localStream) { @@ -329,6 +331,11 @@ export function InputAndControlsPanel({ // The Input can have two states: Append (default) and Edit (when a prompt is selected and the video is paused) const isEditMode = selectedTimelinePrompt && isVideoPaused; + // Hide prompts section if pipeline doesn't support prompts + if (pipeline?.supportsPrompts === false) { + return null; + } + return (
@@ -358,7 +365,6 @@ export function InputAndControlsPanel({ onPromptsSubmit={onPromptsSubmit} onTransitionSubmit={onTransitionSubmit} disabled={ - pipelineId === "passthrough" || (_isTimelinePlaying && !isVideoPaused && !isAtEndOfTimeline()) || diff --git a/frontend/src/components/SettingsPanel.tsx b/frontend/src/components/SettingsPanel.tsx index 83c31e40..b21d592b 100644 --- a/frontend/src/components/SettingsPanel.tsx +++ b/frontend/src/components/SettingsPanel.tsx @@ -20,11 +20,6 @@ import { Button } from "./ui/button"; import { Toggle } from "./ui/toggle"; import { SliderWithInput } from "./ui/slider-with-input"; import { Hammer, Info, Minus, Plus, RotateCcw } from "lucide-react"; -import { - PIPELINES, - pipelineSupportsLoRA, - pipelineSupportsVACE, -} from "../data/pipelines"; import { PARAMETER_METADATA } from "../data/parameterMetadata"; import { DenoisingStepsSlider } from "./DenoisingStepsSlider"; import { @@ -38,13 +33,16 @@ import type { LoraMergeStrategy, SettingsState, InputMode, + PipelineInfo, } from "../types"; import { LoRAManager } from "./LoRAManager"; -const MIN_DIMENSION = 16; +// Minimum dimension for most pipelines (will be overridden by pipeline-specific minDimension from schema) +const DEFAULT_MIN_DIMENSION = 1; interface SettingsPanelProps { className?: string; + pipelines: Record | null; pipelineId: PipelineId; onPipelineIdChange?: (pipelineId: PipelineId) => void; isStreaming?: boolean; @@ -93,6 +91,7 @@ interface SettingsPanelProps { export function SettingsPanel({ className = "", + pipelines, pipelineId, onPipelineIdChange, isStreaming = false, @@ -154,7 +153,7 @@ export function SettingsPanel({ : null; const handlePipelineIdChange = (value: string) => { - if (value in PIPELINES) { + if (pipelines && value in pipelines) { onPipelineIdChange?.(value as PipelineId); } }; @@ -163,13 +162,9 @@ export function SettingsPanel({ dimension: "height" | "width", value: number ) => { - const minValue = - pipelineId === "longlive" || - pipelineId === "streamdiffusionv2" || - pipelineId === "krea-realtime-video" || - pipelineId === "reward-forcing" - ? MIN_DIMENSION - : 1; + // Get min dimension from pipeline schema, fallback to default + const currentPipeline = pipelines?.[pipelineId]; + const minValue = currentPipeline?.minDimension ?? DEFAULT_MIN_DIMENSION; const maxValue = 2048; // Validate and set error state @@ -208,13 +203,9 @@ export function SettingsPanel({ }; const decrementResolution = (dimension: "height" | "width") => { - const minValue = - pipelineId === "longlive" || - pipelineId === "streamdiffusionv2" || - pipelineId === "krea-realtime-video" || - pipelineId === "reward-forcing" - ? MIN_DIMENSION - : 1; + // Get min dimension from pipeline schema, fallback to default + const currentPipeline = pipelines?.[pipelineId]; + const minValue = currentPipeline?.minDimension ?? DEFAULT_MIN_DIMENSION; const newValue = Math.max(minValue, resolution[dimension] - 1); handleResolutionChange(dimension, newValue); }; @@ -248,7 +239,7 @@ export function SettingsPanel({ handleSeedChange(newValue); }; - const currentPipeline = PIPELINES[pipelineId]; + const currentPipeline = pipelines?.[pipelineId]; return ( @@ -267,11 +258,12 @@ export function SettingsPanel({ - {Object.keys(PIPELINES).map(id => ( - - {id} - - ))} + {pipelines && + Object.keys(pipelines).map(id => ( + + {id} + + ))}
@@ -350,7 +342,7 @@ export function SettingsPanel({ )} {/* VACE Toggle */} - {pipelineSupportsVACE(pipelineId) && ( + {currentPipeline?.supportsVACE && (
)} - {pipelineSupportsLoRA(pipelineId) && ( + {currentPipeline?.supportsLoRA && (
)} - {(pipelineId === "longlive" || - pipelineId === "streamdiffusionv2" || - pipelineId === "krea-realtime-video" || - pipelineId === "reward-forcing") && ( + {/* Resolution controls - shown for pipelines that support quantization (implies they need resolution config) */} + {pipelines?.[pipelineId]?.supportsQuantization && (
@@ -446,7 +436,10 @@ export function SettingsPanel({ }} disabled={isStreaming} className="text-center border-0 focus-visible:ring-0 focus-visible:ring-offset-0 h-8 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" - min={MIN_DIMENSION} + min={ + pipelines?.[pipelineId]?.minDimension ?? + DEFAULT_MIN_DIMENSION + } max={2048} />