From bcc98f1269cd5cd677fa0108fe8280f8f623bd46 Mon Sep 17 00:00:00 2001 From: Sirshendu Ganguly Date: Wed, 25 Feb 2026 15:35:21 -0500 Subject: [PATCH 1/4] add optimizePromptMode Bytedance --- __init__.py | 4 +- clientlibs/utils.js | 12 + ...derSettings.py => briaProviderSettings.py} | 553 +++++++++--------- ...ttings.py => bytedanceProviderSettings.py} | 250 ++++---- 4 files changed, 422 insertions(+), 397 deletions(-) rename modules/providerSettings/{briaImageProviderSettings.py => briaProviderSettings.py} (96%) rename modules/providerSettings/{bytedanceImageProviderSettings.py => bytedanceProviderSettings.py} (80%) diff --git a/__init__.py b/__init__.py index 9d0c733..87bf8b3 100644 --- a/__init__.py +++ b/__init__.py @@ -30,8 +30,8 @@ from .modules.videoModelSearch import videoModelSearch from .modules.frameImages import RunwareFrameImages from .modules.providerSettings.pixverseProviderSettings import RunwarePixverseProviderSettings from .modules.providerSettings.openaiProviderSettings import RunwareOpenAIProviderSettings -from .modules.providerSettings.bytedanceImageProviderSettings import RunwareBytedanceProviderSettings -from .modules.providerSettings.briaImageProviderSettings import RunwareBriaProviderSettings +from .modules.providerSettings.bytedanceProviderSettings import RunwareBytedanceProviderSettings +from .modules.providerSettings.briaProviderSettings import RunwareBriaProviderSettings from .modules.providerSettings.briaProviderMask import RunwareBriaProviderMask from .modules.audioInference import RunwareAudioInference from .modules.audioModelSearch import RunwareAudioModelSearch diff --git a/clientlibs/utils.js b/clientlibs/utils.js index 1f5d70f..2b0b0c0 100644 --- a/clientlibs/utils.js +++ b/clientlibs/utils.js @@ -1223,6 +1223,8 @@ function bytedanceProviderSettingsToggleHandler(bytedanceNode) { const audioWidget = bytedanceNode.widgets.find(w => w.name === "audio"); const useDraftWidget = bytedanceNode.widgets.find(w => w.name === "useDraft"); const draftWidget = bytedanceNode.widgets.find(w => w.name === "draft"); + const useOptimizePromptModeWidget = bytedanceNode.widgets.find(w => w.name === "useOptimizePromptMode"); + const optimizePromptModeWidget = bytedanceNode.widgets.find(w => w.name === "optimizePromptMode"); // Helper function to toggle widget enabled state (exact same pattern) function toggleWidgetState(useWidget, paramWidget, paramName) { @@ -1239,6 +1241,12 @@ function bytedanceProviderSettingsToggleHandler(bytedanceNode) { } paramWidget.disabled = !enabled; + if (paramWidget.options && paramWidget.options.element) { + paramWidget.options.element.disabled = !enabled; + paramWidget.options.element.style.opacity = enabled ? "1" : "0.5"; + paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none"; + } + if (!paramWidget.inputEl) { const nodeElement = bytedanceNode.htmlElements?.widgetsContainer || bytedanceNode.htmlElements; if (nodeElement) { @@ -1285,6 +1293,10 @@ function bytedanceProviderSettingsToggleHandler(bytedanceNode) { if (useDraftWidget && draftWidget) { toggleWidgetState(useDraftWidget, draftWidget, "draft"); } + + if (useOptimizePromptModeWidget && optimizePromptModeWidget) { + toggleWidgetState(useOptimizePromptModeWidget, optimizePromptModeWidget, "optimizePromptMode"); + } } function ultralyticsProviderSettingsToggleHandler(ultralyticsNode) { diff --git a/modules/providerSettings/briaImageProviderSettings.py b/modules/providerSettings/briaProviderSettings.py similarity index 96% rename from modules/providerSettings/briaImageProviderSettings.py rename to modules/providerSettings/briaProviderSettings.py index a90ea01..d982f08 100644 --- a/modules/providerSettings/briaImageProviderSettings.py +++ b/modules/providerSettings/briaProviderSettings.py @@ -1,277 +1,276 @@ -""" -Runware Bria Image Provider Settings Node -Provides Bria-specific settings for image generation -""" - -import torch -from typing import Optional, Dict, Any - -class RunwareBriaProviderSettings: - """Runware Bria Image Provider Settings Node""" - - @classmethod - def INPUT_TYPES(cls): - return { - "required": {}, - "optional": { - "useMedium": ("BOOLEAN", { - "tooltip": "Enable to include medium parameter in API request. Disable if not needed.", - "default": False, - }), - "medium": (["None", "photography", "art"], { - "tooltip": "Select the medium type for image generation. Only used when 'Use Medium' is enabled.", - "default": "photography", - }), - "usePromptEnhancement": ("BOOLEAN", { - "tooltip": "Enable to include promptEnhancement parameter in API request.", - "default": False, - }), - "promptEnhancement": ("BOOLEAN", { - "tooltip": "When set to true, enhances the provided prompt by generating additional, more descriptive variations, resulting in more diverse and creative output images. Note that turning this flag on may result in a few additional seconds to the inference time. Only used when 'Use Prompt Enhancement' is enabled.", - "default": False, - "label_on": "Enabled", - "label_off": "Disabled", - }), - "useEnhanceImage": ("BOOLEAN", { - "tooltip": "Enable to include enhanceImage parameter in API request.", - "default": False, - }), - "enhanceImage": ("BOOLEAN", { - "tooltip": "When set to true, generates images with richer details, sharper textures, and enhanced clarity. Slightly increases generation time per image. Only used when 'Use Enhance Image' is enabled.", - "default": False, - "label_on": "Enabled", - "label_off": "Disabled", - }), - "usePromptContentModeration": ("BOOLEAN", { - "tooltip": "Enable to include promptContentModeration parameter in API request.", - "default": False, - }), - "promptContentModeration": ("BOOLEAN", { - "tooltip": "When enabled (default: true), the input prompt is scanned for NSFW or ethically restricted terms before image generation. If the prompt violates Bria's ethical guidelines, the request will be rejected with a 408 error. Only used when 'Use Prompt Content Moderation' is enabled.", - "default": True, - "label_on": "Enabled", - "label_off": "Disabled", - }), - "useContentModeration": ("BOOLEAN", { - "tooltip": "Enable to include contentModeration parameter in API request.", - "default": False, - }), - "contentModeration": ("BOOLEAN", { - "tooltip": "When enabled, applies content moderation to both input visuals and generated outputs. Only used when 'Use Content Moderation' is enabled.", - "default": True, - "label_on": "Enabled", - "label_off": "Disabled", - }), - "useIpSignal": ("BOOLEAN", { - "tooltip": "Enable to include ipSignal parameter in API request.", - "default": False, - }), - "ipSignal": ("BOOLEAN", { - "tooltip": "Flags prompts with potential IP content. If detected, a warning will be included in the response. Only used when 'Use IP Signal' is enabled.", - "default": False, - "label_on": "Enabled", - "label_off": "Disabled", - }), - "usePreserveAlpha": ("BOOLEAN", { - "tooltip": "Enable to include preserveAlpha parameter in API request.", - "default": False, - }), - "preserveAlpha": ("BOOLEAN", { - "tooltip": "Preserve alpha channel in the image. Only used when 'Use Preserve Alpha' is enabled.", - "default": False, - "label_on": "Enabled", - "label_off": "Disabled", - }), - "useMode": ("BOOLEAN", { - "tooltip": "Enable to include mode parameter in API request for Background Replace.", - "default": False, - }), - "mode": (["None", "base", "high_control", "fast"], { - "tooltip": "Selects the background-generation mode for Background Replace. Base: clean, high quality backgrounds. High_control: stronger prompt adherence and scene context, finer control over layout and details. Fast: same core capabilities as base, optimal speed and quality balance. Only used when 'Use Mode' is enabled.", - "default": "base", - }), - "useEnhanceReferenceImages": ("BOOLEAN", { - "tooltip": "Enable to include enhanceReferenceImages parameter in API request.", - "default": False, - }), - "enhanceReferenceImages": ("BOOLEAN", { - "tooltip": "When set to true, additional logic processes the included reference image to make adjustments for optimal results. Only used when 'Use Enhance Reference Images' is enabled.", - "default": True, - "label_on": "Enabled", - "label_off": "Disabled", - }), - "useRefinePrompt": ("BOOLEAN", { - "tooltip": "Enable to include refinePrompt parameter in API request.", - "default": False, - }), - "refinePrompt": ("BOOLEAN", { - "tooltip": "When true, an additional logic takes the prompt that was included and adjusts it to achieve optimal results. Only used when 'Use Refine Prompt' is enabled.", - "default": True, - "label_on": "Enabled", - "label_off": "Disabled", - }), - "useOriginalQuality": ("BOOLEAN", { - "tooltip": "Enable to include originalQuality parameter in API request.", - "default": False, - }), - "originalQuality": ("BOOLEAN", { - "tooltip": "When true, the output image retains the original input image's size; otherwise, the image is scaled to 1 megapixel (1MP) while preserving its aspect ratio. Only used when 'Use Original Quality' is enabled.", - "default": True, - "label_on": "Enabled", - "label_off": "Disabled", - }), - "useForceBackgroundDetection": ("BOOLEAN", { - "tooltip": "Enable to include forceBackgroundDetection parameter in API request.", - "default": False, - }), - "forceBackgroundDetection": ("BOOLEAN", { - "tooltip": "When true, forces background detection and removal, even if the original image already contains an alpha channel. Useful for refining existing foreground/background separation or ignoring unnecessary alpha channels. Only used when 'Use Force Background Detection' is enabled.", - "default": False, - "label_on": "Enabled", - "label_off": "Disabled", - }), - "usePreserveAudio": ("BOOLEAN", { - "tooltip": "Enable to include preserveAudio parameter in API request.", - "default": False, - }), - "preserveAudio": ("BOOLEAN", { - "tooltip": "Whether to keep the original audio track. Only used when 'Use Preserve Audio' is enabled.", - "default": True, - "label_on": "Enabled", - "label_off": "Disabled", - }), - "useAutoTrim": ("BOOLEAN", { - "tooltip": "Enable to include autoTrim parameter in API request.", - "default": False, - }), - "autoTrim": ("BOOLEAN", { - "tooltip": "If true, videos longer than 5 seconds are trimmed to the first 5 seconds. If false, videos longer than 5 seconds are rejected. Only used when 'Use Auto Trim' is enabled.", - "default": False, - "label_on": "Enabled", - "label_off": "Disabled", - }), - "Bria Provider Setting Mask": ("RUNWAREBRIAPROVIDERMASK", { - "tooltip": "Connect Runware Bria Provider Mask node to provide mask configuration for video eraser operations.", - }), - } - } - - RETURN_TYPES = ("RUNWAREPROVIDERSETTINGS",) - RETURN_NAMES = ("providerSettings",) - FUNCTION = "create_provider_settings" - CATEGORY = "Runware/Provider Settings" - DESCRIPTION = "Configure Bria-specific provider settings for image generation and background replacement including medium type, prompt enhancement, image enhancement, content moderation options, and background replace mode settings." - - def create_provider_settings(self, **kwargs) -> tuple[Dict[str, Any]]: - """Create Bria provider settings""" - - # Get use parameters - useMedium = kwargs.get("useMedium", False) - usePromptEnhancement = kwargs.get("usePromptEnhancement", False) - useEnhanceImage = kwargs.get("useEnhanceImage", False) - usePromptContentModeration = kwargs.get("usePromptContentModeration", False) - useContentModeration = kwargs.get("useContentModeration", False) - useIpSignal = kwargs.get("useIpSignal", False) - usePreserveAlpha = kwargs.get("usePreserveAlpha", False) - useMode = kwargs.get("useMode", False) - useEnhanceReferenceImages = kwargs.get("useEnhanceReferenceImages", False) - useRefinePrompt = kwargs.get("useRefinePrompt", False) - useOriginalQuality = kwargs.get("useOriginalQuality", False) - useForceBackgroundDetection = kwargs.get("useForceBackgroundDetection", False) - usePreserveAudio = kwargs.get("usePreserveAudio", False) - useAutoTrim = kwargs.get("useAutoTrim", False) - - # Get actual parameters - medium = kwargs.get("medium", "photography") - promptEnhancement = kwargs.get("promptEnhancement", False) - enhanceImage = kwargs.get("enhanceImage", False) - promptContentModeration = kwargs.get("promptContentModeration", True) - contentModeration = kwargs.get("contentModeration", True) - ipSignal = kwargs.get("ipSignal", False) - preserveAlpha = kwargs.get("preserveAlpha", False) - mode = kwargs.get("mode", "base") - enhanceReferenceImages = kwargs.get("enhanceReferenceImages", True) - refinePrompt = kwargs.get("refinePrompt", True) - originalQuality = kwargs.get("originalQuality", True) - forceBackgroundDetection = kwargs.get("forceBackgroundDetection", False) - preserveAudio = kwargs.get("preserveAudio", True) - autoTrim = kwargs.get("autoTrim", False) - mask = kwargs.get("Bria Provider Setting Mask", None) - - # Build settings dictionary - settings = {} - - # Add medium only if useMedium is enabled - if useMedium and medium is not None and medium != "None": - settings["medium"] = medium - - # Add promptEnhancement only if usePromptEnhancement is enabled - if usePromptEnhancement: - settings["promptEnhancement"] = promptEnhancement - - # Add enhanceImage only if useEnhanceImage is enabled - if useEnhanceImage: - settings["enhanceImage"] = enhanceImage - - # Add promptContentModeration only if usePromptContentModeration is enabled - if usePromptContentModeration: - settings["promptContentModeration"] = promptContentModeration - - # Add contentModeration only if useContentModeration is enabled - if useContentModeration: - settings["contentModeration"] = contentModeration - - # Add ipSignal only if useIpSignal is enabled - if useIpSignal: - settings["ipSignal"] = ipSignal - - # Add preserveAlpha only if usePreserveAlpha is enabled - if usePreserveAlpha: - settings["preserveAlpha"] = preserveAlpha - - # Add mode only if useMode is enabled (for Background Replace) - if useMode and mode is not None and mode != "None": - settings["mode"] = mode - - # Add enhanceReferenceImages only if useEnhanceReferenceImages is enabled - if useEnhanceReferenceImages: - settings["enhanceReferenceImages"] = enhanceReferenceImages - - # Add refinePrompt only if useRefinePrompt is enabled - if useRefinePrompt: - settings["refinePrompt"] = refinePrompt - - # Add originalQuality only if useOriginalQuality is enabled - if useOriginalQuality: - settings["originalQuality"] = originalQuality - - # Add forceBackgroundDetection only if useForceBackgroundDetection is enabled - if useForceBackgroundDetection: - settings["forceBackgroundDetection"] = forceBackgroundDetection - - # Add preserveAudio only if usePreserveAudio is enabled - if usePreserveAudio: - settings["preserveAudio"] = preserveAudio - - # Add autoTrim only if useAutoTrim is enabled - if useAutoTrim: - settings["autoTrim"] = autoTrim - - # Add mask if provided from Mask node - if mask is not None and isinstance(mask, dict) and len(mask) > 0: - settings["mask"] = mask - - # Clean up None values - settings = {k: v for k, v in settings.items() if v is not None} - - return (settings,) - -# Node class mappings -NODE_CLASS_MAPPINGS = { - "RunwareBriaProviderSettings": RunwareBriaProviderSettings, -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "RunwareBriaProviderSettings": "Runware Bria Provider Settings", -} - +""" +Runware Bria Provider Settings Node +Provides Bria-specific settings for image/video generation +""" + +import torch +from typing import Optional, Dict, Any + +class RunwareBriaProviderSettings: + """Runware Bria Provider Settings Node""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": {}, + "optional": { + "useMedium": ("BOOLEAN", { + "tooltip": "Enable to include medium parameter in API request. Disable if not needed.", + "default": False, + }), + "medium": (["None", "photography", "art"], { + "tooltip": "Select the medium type for image generation. Only used when 'Use Medium' is enabled.", + "default": "photography", + }), + "usePromptEnhancement": ("BOOLEAN", { + "tooltip": "Enable to include promptEnhancement parameter in API request.", + "default": False, + }), + "promptEnhancement": ("BOOLEAN", { + "tooltip": "When set to true, enhances the provided prompt by generating additional, more descriptive variations, resulting in more diverse and creative output images. Note that turning this flag on may result in a few additional seconds to the inference time. Only used when 'Use Prompt Enhancement' is enabled.", + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "useEnhanceImage": ("BOOLEAN", { + "tooltip": "Enable to include enhanceImage parameter in API request.", + "default": False, + }), + "enhanceImage": ("BOOLEAN", { + "tooltip": "When set to true, generates images with richer details, sharper textures, and enhanced clarity. Slightly increases generation time per image. Only used when 'Use Enhance Image' is enabled.", + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "usePromptContentModeration": ("BOOLEAN", { + "tooltip": "Enable to include promptContentModeration parameter in API request.", + "default": False, + }), + "promptContentModeration": ("BOOLEAN", { + "tooltip": "When enabled (default: true), the input prompt is scanned for NSFW or ethically restricted terms before image generation. If the prompt violates Bria's ethical guidelines, the request will be rejected with a 408 error. Only used when 'Use Prompt Content Moderation' is enabled.", + "default": True, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "useContentModeration": ("BOOLEAN", { + "tooltip": "Enable to include contentModeration parameter in API request.", + "default": False, + }), + "contentModeration": ("BOOLEAN", { + "tooltip": "When enabled, applies content moderation to both input visuals and generated outputs. Only used when 'Use Content Moderation' is enabled.", + "default": True, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "useIpSignal": ("BOOLEAN", { + "tooltip": "Enable to include ipSignal parameter in API request.", + "default": False, + }), + "ipSignal": ("BOOLEAN", { + "tooltip": "Flags prompts with potential IP content. If detected, a warning will be included in the response. Only used when 'Use IP Signal' is enabled.", + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "usePreserveAlpha": ("BOOLEAN", { + "tooltip": "Enable to include preserveAlpha parameter in API request.", + "default": False, + }), + "preserveAlpha": ("BOOLEAN", { + "tooltip": "Preserve alpha channel in the image. Only used when 'Use Preserve Alpha' is enabled.", + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "useMode": ("BOOLEAN", { + "tooltip": "Enable to include mode parameter in API request for Background Replace.", + "default": False, + }), + "mode": (["None", "base", "high_control", "fast"], { + "tooltip": "Selects the background-generation mode for Background Replace. Base: clean, high quality backgrounds. High_control: stronger prompt adherence and scene context, finer control over layout and details. Fast: same core capabilities as base, optimal speed and quality balance. Only used when 'Use Mode' is enabled.", + "default": "base", + }), + "useEnhanceReferenceImages": ("BOOLEAN", { + "tooltip": "Enable to include enhanceReferenceImages parameter in API request.", + "default": False, + }), + "enhanceReferenceImages": ("BOOLEAN", { + "tooltip": "When set to true, additional logic processes the included reference image to make adjustments for optimal results. Only used when 'Use Enhance Reference Images' is enabled.", + "default": True, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "useRefinePrompt": ("BOOLEAN", { + "tooltip": "Enable to include refinePrompt parameter in API request.", + "default": False, + }), + "refinePrompt": ("BOOLEAN", { + "tooltip": "When true, an additional logic takes the prompt that was included and adjusts it to achieve optimal results. Only used when 'Use Refine Prompt' is enabled.", + "default": True, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "useOriginalQuality": ("BOOLEAN", { + "tooltip": "Enable to include originalQuality parameter in API request.", + "default": False, + }), + "originalQuality": ("BOOLEAN", { + "tooltip": "When true, the output image retains the original input image's size; otherwise, the image is scaled to 1 megapixel (1MP) while preserving its aspect ratio. Only used when 'Use Original Quality' is enabled.", + "default": True, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "useForceBackgroundDetection": ("BOOLEAN", { + "tooltip": "Enable to include forceBackgroundDetection parameter in API request.", + "default": False, + }), + "forceBackgroundDetection": ("BOOLEAN", { + "tooltip": "When true, forces background detection and removal, even if the original image already contains an alpha channel. Useful for refining existing foreground/background separation or ignoring unnecessary alpha channels. Only used when 'Use Force Background Detection' is enabled.", + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "usePreserveAudio": ("BOOLEAN", { + "tooltip": "Enable to include preserveAudio parameter in API request.", + "default": False, + }), + "preserveAudio": ("BOOLEAN", { + "tooltip": "Whether to keep the original audio track. Only used when 'Use Preserve Audio' is enabled.", + "default": True, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "useAutoTrim": ("BOOLEAN", { + "tooltip": "Enable to include autoTrim parameter in API request.", + "default": False, + }), + "autoTrim": ("BOOLEAN", { + "tooltip": "If true, videos longer than 5 seconds are trimmed to the first 5 seconds. If false, videos longer than 5 seconds are rejected. Only used when 'Use Auto Trim' is enabled.", + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "Bria Provider Setting Mask": ("RUNWAREBRIAPROVIDERMASK", { + "tooltip": "Connect Runware Bria Provider Mask node to provide mask configuration for video eraser operations.", + }), + } + } + + RETURN_TYPES = ("RUNWAREPROVIDERSETTINGS",) + RETURN_NAMES = ("providerSettings",) + FUNCTION = "create_provider_settings" + CATEGORY = "Runware/Provider Settings" + DESCRIPTION = "Configure Bria-specific provider settings for image generation, background replacement, and video operations including medium type, prompt enhancement, content moderation, and background replace mode." + + def create_provider_settings(self, **kwargs) -> tuple[Dict[str, Any]]: + """Create Bria provider settings""" + + # Get use parameters + useMedium = kwargs.get("useMedium", False) + usePromptEnhancement = kwargs.get("usePromptEnhancement", False) + useEnhanceImage = kwargs.get("useEnhanceImage", False) + usePromptContentModeration = kwargs.get("usePromptContentModeration", False) + useContentModeration = kwargs.get("useContentModeration", False) + useIpSignal = kwargs.get("useIpSignal", False) + usePreserveAlpha = kwargs.get("usePreserveAlpha", False) + useMode = kwargs.get("useMode", False) + useEnhanceReferenceImages = kwargs.get("useEnhanceReferenceImages", False) + useRefinePrompt = kwargs.get("useRefinePrompt", False) + useOriginalQuality = kwargs.get("useOriginalQuality", False) + useForceBackgroundDetection = kwargs.get("useForceBackgroundDetection", False) + usePreserveAudio = kwargs.get("usePreserveAudio", False) + useAutoTrim = kwargs.get("useAutoTrim", False) + + # Get actual parameters + medium = kwargs.get("medium", "photography") + promptEnhancement = kwargs.get("promptEnhancement", False) + enhanceImage = kwargs.get("enhanceImage", False) + promptContentModeration = kwargs.get("promptContentModeration", True) + contentModeration = kwargs.get("contentModeration", True) + ipSignal = kwargs.get("ipSignal", False) + preserveAlpha = kwargs.get("preserveAlpha", False) + mode = kwargs.get("mode", "base") + enhanceReferenceImages = kwargs.get("enhanceReferenceImages", True) + refinePrompt = kwargs.get("refinePrompt", True) + originalQuality = kwargs.get("originalQuality", True) + forceBackgroundDetection = kwargs.get("forceBackgroundDetection", False) + preserveAudio = kwargs.get("preserveAudio", True) + autoTrim = kwargs.get("autoTrim", False) + mask = kwargs.get("Bria Provider Setting Mask", None) + + # Build settings dictionary + settings = {} + + # Add medium only if useMedium is enabled + if useMedium and medium is not None and medium != "None": + settings["medium"] = medium + + # Add promptEnhancement only if usePromptEnhancement is enabled + if usePromptEnhancement: + settings["promptEnhancement"] = promptEnhancement + + # Add enhanceImage only if useEnhanceImage is enabled + if useEnhanceImage: + settings["enhanceImage"] = enhanceImage + + # Add promptContentModeration only if usePromptContentModeration is enabled + if usePromptContentModeration: + settings["promptContentModeration"] = promptContentModeration + + # Add contentModeration only if useContentModeration is enabled + if useContentModeration: + settings["contentModeration"] = contentModeration + + # Add ipSignal only if useIpSignal is enabled + if useIpSignal: + settings["ipSignal"] = ipSignal + + # Add preserveAlpha only if usePreserveAlpha is enabled + if usePreserveAlpha: + settings["preserveAlpha"] = preserveAlpha + + # Add mode only if useMode is enabled (for Background Replace) + if useMode and mode is not None and mode != "None": + settings["mode"] = mode + + # Add enhanceReferenceImages only if useEnhanceReferenceImages is enabled + if useEnhanceReferenceImages: + settings["enhanceReferenceImages"] = enhanceReferenceImages + + # Add refinePrompt only if useRefinePrompt is enabled + if useRefinePrompt: + settings["refinePrompt"] = refinePrompt + + # Add originalQuality only if useOriginalQuality is enabled + if useOriginalQuality: + settings["originalQuality"] = originalQuality + + # Add forceBackgroundDetection only if useForceBackgroundDetection is enabled + if useForceBackgroundDetection: + settings["forceBackgroundDetection"] = forceBackgroundDetection + + # Add preserveAudio only if usePreserveAudio is enabled + if usePreserveAudio: + settings["preserveAudio"] = preserveAudio + + # Add autoTrim only if useAutoTrim is enabled + if useAutoTrim: + settings["autoTrim"] = autoTrim + + # Add mask if provided from Mask node + if mask is not None and isinstance(mask, dict) and len(mask) > 0: + settings["mask"] = mask + + # Clean up None values + settings = {k: v for k, v in settings.items() if v is not None} + + return (settings,) + +# Node class mappings +NODE_CLASS_MAPPINGS = { + "RunwareBriaProviderSettings": RunwareBriaProviderSettings, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "RunwareBriaProviderSettings": "Runware Bria Provider Settings", +} diff --git a/modules/providerSettings/bytedanceImageProviderSettings.py b/modules/providerSettings/bytedanceProviderSettings.py similarity index 80% rename from modules/providerSettings/bytedanceImageProviderSettings.py rename to modules/providerSettings/bytedanceProviderSettings.py index e8da86f..f42c967 100644 --- a/modules/providerSettings/bytedanceImageProviderSettings.py +++ b/modules/providerSettings/bytedanceProviderSettings.py @@ -1,118 +1,132 @@ -""" -Runware Bytedance Image Provider Settings Node -Provides Bytedance-specific settings for image generation -""" - -from typing import Optional, Dict, Any - -class RunwareBytedanceProviderSettings: - """Runware Bytedance Image Provider Settings Node""" - - @classmethod - def INPUT_TYPES(cls): - return { - "required": {}, - "optional": { - "useCameraFixed": ("BOOLEAN", { - "tooltip": "Enable to include cameraFixed parameter in provider settings", - "default": False, - }), - "cameraFixed": ("BOOLEAN", { - "tooltip": "Enable to fix camera position during video generation", - "default": False, - }), - "useMaxSequentialImages": ("BOOLEAN", { - "tooltip": "Enable to include maxSequentialImages parameter in provider settings", - "default": False, - }), - "maxSequentialImages": ("INT", { - "tooltip": "Maximum number of sequential images to generate (1-15)", - "default": 1, - "min": 1, - "max": 15, - }), - "useFastMode": ("BOOLEAN", { - "tooltip": "Enable to include fastMode parameter in provider settings", - "default": False, - }), - "fastMode": ("BOOLEAN", { - "tooltip": "When enabled, speeds up generation by sacrificing some effects. Default: false. RTF: 25-28 (fast) vs 35 (normal). Supported by OmniHuman 1.5.", - "default": False, - }), - "useAudio": ("BOOLEAN", { - "tooltip": "Enable to include audio parameter in provider settings.", - "default": False, - }), - "audio": ("BOOLEAN", { - "tooltip": "Enable audio generation support when available.", - "default": False, - }), - "useDraft": ("BOOLEAN", { - "tooltip": "Enable to include draft parameter in provider settings", - "default": False, - }), - "draft": ("BOOLEAN", { - "tooltip": "Enable draft mode for Bytedance provider", - "default": False, - }), - } - } - - RETURN_TYPES = ("RUNWAREPROVIDERSETTINGS",) - RETURN_NAMES = ("providerSettings",) - FUNCTION = "create_provider_settings" - CATEGORY = "Runware/Provider Settings" - - def create_provider_settings(self, **kwargs) -> tuple[Dict[str, Any]]: - """Create Bytedance provider settings""" - - # Get control parameters - useCameraFixed = kwargs.get("useCameraFixed", False) - useMaxSequentialImages = kwargs.get("useMaxSequentialImages", False) - useFastMode = kwargs.get("useFastMode", False) - useAudio = kwargs.get("useAudio", False) - useDraft = kwargs.get("useDraft", False) - - # Get value parameters - cameraFixed = kwargs.get("cameraFixed", False) - maxSequentialImages = kwargs.get("maxSequentialImages", 1) - fastMode = kwargs.get("fastMode", False) - audio = kwargs.get("audio", False) - draft = kwargs.get("draft", False) - - # Build settings dictionary - only include what is enabled - settings = {} - - # Add cameraFixed only if useCameraFixed is enabled - if useCameraFixed: - settings["cameraFixed"] = cameraFixed - - # Add maxSequentialImages only if useMaxSequentialImages is enabled - if useMaxSequentialImages: - settings["maxSequentialImages"] = maxSequentialImages - - # Add fastMode only if useFastMode is enabled - if useFastMode: - settings["fastMode"] = fastMode - - # Add audio only if useAudio is enabled - if useAudio: - settings["audio"] = audio - - # Add draft only if useDraft is enabled - if useDraft: - settings["draft"] = draft - - # Clean up None values - settings = {k: v for k, v in settings.items() if v is not None} - - return (settings,) - -# Node class mappings -NODE_CLASS_MAPPINGS = { - "RunwareBytedanceProviderSettings": RunwareBytedanceProviderSettings, -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "RunwareBytedanceProviderSettings": "Runware Bytedance Provider Settings", -} +""" +Runware Bytedance Provider Settings Node +Provides Bytedance-specific settings for image/video generation +""" + +from typing import Optional, Dict, Any + +class RunwareBytedanceProviderSettings: + """Runware Bytedance Provider Settings Node""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": {}, + "optional": { + "useCameraFixed": ("BOOLEAN", { + "tooltip": "Enable to include cameraFixed parameter in provider settings", + "default": False, + }), + "cameraFixed": ("BOOLEAN", { + "tooltip": "Enable to fix camera position during video generation", + "default": False, + }), + "useMaxSequentialImages": ("BOOLEAN", { + "tooltip": "Enable to include maxSequentialImages parameter in provider settings", + "default": False, + }), + "maxSequentialImages": ("INT", { + "tooltip": "Maximum number of sequential images to generate (1-15)", + "default": 1, + "min": 1, + "max": 15, + }), + "useFastMode": ("BOOLEAN", { + "tooltip": "Enable to include fastMode parameter in provider settings", + "default": False, + }), + "fastMode": ("BOOLEAN", { + "tooltip": "When enabled, speeds up generation by sacrificing some effects. Default: false. RTF: 25-28 (fast) vs 35 (normal). Supported by OmniHuman 1.5.", + "default": False, + }), + "useAudio": ("BOOLEAN", { + "tooltip": "Enable to include audio parameter in provider settings.", + "default": False, + }), + "audio": ("BOOLEAN", { + "tooltip": "Enable audio generation support when available.", + "default": False, + }), + "useDraft": ("BOOLEAN", { + "tooltip": "Enable to include draft parameter in provider settings", + "default": False, + }), + "draft": ("BOOLEAN", { + "tooltip": "Enable draft mode for Bytedance provider", + "default": False, + }), + "useOptimizePromptMode": ("BOOLEAN", { + "tooltip": "Enable to include optimizePromptMode parameter in provider settings", + "default": False, + }), + "optimizePromptMode": (["standard", "fast"], { + "tooltip": "Prompt optimization mode. standard: higher quality, longer time. fast: faster generation, average quality.", + "default": "standard", + }), + } + } + + RETURN_TYPES = ("RUNWAREPROVIDERSETTINGS",) + RETURN_NAMES = ("providerSettings",) + FUNCTION = "create_provider_settings" + CATEGORY = "Runware/Provider Settings" + + def create_provider_settings(self, **kwargs) -> tuple[Dict[str, Any]]: + """Create Bytedance provider settings""" + + # Get control parameters + useCameraFixed = kwargs.get("useCameraFixed", False) + useMaxSequentialImages = kwargs.get("useMaxSequentialImages", False) + useFastMode = kwargs.get("useFastMode", False) + useAudio = kwargs.get("useAudio", False) + useDraft = kwargs.get("useDraft", False) + useOptimizePromptMode = kwargs.get("useOptimizePromptMode", False) + + # Get value parameters + cameraFixed = kwargs.get("cameraFixed", False) + maxSequentialImages = kwargs.get("maxSequentialImages", 1) + fastMode = kwargs.get("fastMode", False) + audio = kwargs.get("audio", False) + draft = kwargs.get("draft", False) + optimizePromptMode = kwargs.get("optimizePromptMode", "standard") + + # Build settings dictionary - only include what is enabled + settings = {} + + # Add cameraFixed only if useCameraFixed is enabled + if useCameraFixed: + settings["cameraFixed"] = cameraFixed + + # Add maxSequentialImages only if useMaxSequentialImages is enabled + if useMaxSequentialImages: + settings["maxSequentialImages"] = maxSequentialImages + + # Add fastMode only if useFastMode is enabled + if useFastMode: + settings["fastMode"] = fastMode + + # Add audio only if useAudio is enabled + if useAudio: + settings["audio"] = audio + + # Add draft only if useDraft is enabled + if useDraft: + settings["draft"] = draft + + # Add optimizePromptMode only if useOptimizePromptMode is enabled + if useOptimizePromptMode: + settings["optimizePromptMode"] = optimizePromptMode + + # Clean up None values + settings = {k: v for k, v in settings.items() if v is not None} + + return (settings,) + +# Node class mappings +NODE_CLASS_MAPPINGS = { + "RunwareBytedanceProviderSettings": RunwareBytedanceProviderSettings, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "RunwareBytedanceProviderSettings": "Runware Bytedance Provider Settings", +} From 9a68ddeba1f2fcda6788918ccfb60f5012ecae27 Mon Sep 17 00:00:00 2001 From: Sirshendu Ganguly Date: Wed, 25 Feb 2026 15:50:44 -0500 Subject: [PATCH 2/4] fixes --- .../providerSettings/briaProviderSettings.py | 85 ++++++++++++++++++- 1 file changed, 81 insertions(+), 4 deletions(-) diff --git a/modules/providerSettings/briaProviderSettings.py b/modules/providerSettings/briaProviderSettings.py index d982f08..03367c2 100644 --- a/modules/providerSettings/briaProviderSettings.py +++ b/modules/providerSettings/briaProviderSettings.py @@ -1,13 +1,13 @@ """ -Runware Bria Provider Settings Node -Provides Bria-specific settings for image/video generation +Runware Bria Image Provider Settings Node +Provides Bria-specific settings for image generation """ import torch from typing import Optional, Dict, Any class RunwareBriaProviderSettings: - """Runware Bria Provider Settings Node""" + """Runware Bria Image Provider Settings Node""" @classmethod def INPUT_TYPES(cls): @@ -150,6 +150,52 @@ class RunwareBriaProviderSettings: "label_on": "Enabled", "label_off": "Disabled", }), + "useSeason": ("BOOLEAN", { + "tooltip": "Enable to include season parameter (maps to /reseason).", + "default": False, + }), + "season": (["spring", "summer", "autumn", "winter"], { + "tooltip": "Desired season. Maps to /reseason.", + "default": "spring", + }), + "useEdit": ("BOOLEAN", { + "tooltip": "Enable to include edit parameter.", + "default": False, + }), + "edit": (["colorize", "relight", "restore", "blend", "reseason", "sketch_to_image"], { + "tooltip": "Edit mode: colorize, relight, restore, blend, reseason, sketch_to_image.", + "default": "restore", + }), + "useColor": ("BOOLEAN", { + "tooltip": "Enable to include color parameter (maps to /colorize).", + "default": False, + }), + "color": (["contemporary color", "vivid color", "black and white colors", "sepia vintage"], { + "tooltip": "Restoration/color style. Maps to /colorize.", + "default": "contemporary color", + }), + "useLightDirection": ("BOOLEAN", { + "tooltip": "Enable to include lightDirection parameter (maps to /relight).", + "default": False, + }), + "lightDirection": (["front", "side", "bottom", "top-down"], { + "tooltip": "Direction of light. Maps to /relight.", + "default": "front", + }), + "useLightType": ("BOOLEAN", { + "tooltip": "Enable to include lightType parameter (maps to /relight).", + "default": False, + }), + "lightType": ([ + "midday", "blue hour light", "low-angle sunlight", "sunrise light", + "spotlight on subject, keep background settings", "overcast light", + "soft overcast daylight lighting", "cloud-filtered lighting", "fog-diffused lighting", + "moonlight lighting", "starlight lighting nighttime", "soft bokeh lighting", + "harsh studio lighting keep background setting", + ], { + "tooltip": "Type of lighting. Maps to /relight.", + "default": "midday", + }), "Bria Provider Setting Mask": ("RUNWAREBRIAPROVIDERMASK", { "tooltip": "Connect Runware Bria Provider Mask node to provide mask configuration for video eraser operations.", }), @@ -160,7 +206,7 @@ class RunwareBriaProviderSettings: RETURN_NAMES = ("providerSettings",) FUNCTION = "create_provider_settings" CATEGORY = "Runware/Provider Settings" - DESCRIPTION = "Configure Bria-specific provider settings for image generation, background replacement, and video operations including medium type, prompt enhancement, content moderation, and background replace mode." + DESCRIPTION = "Configure Bria-specific provider settings for image generation and background replacement including medium type, prompt enhancement, image enhancement, content moderation options, and background replace mode settings." def create_provider_settings(self, **kwargs) -> tuple[Dict[str, Any]]: """Create Bria provider settings""" @@ -180,6 +226,11 @@ class RunwareBriaProviderSettings: useForceBackgroundDetection = kwargs.get("useForceBackgroundDetection", False) usePreserveAudio = kwargs.get("usePreserveAudio", False) useAutoTrim = kwargs.get("useAutoTrim", False) + useSeason = kwargs.get("useSeason", False) + useEdit = kwargs.get("useEdit", False) + useColor = kwargs.get("useColor", False) + useLightDirection = kwargs.get("useLightDirection", False) + useLightType = kwargs.get("useLightType", False) # Get actual parameters medium = kwargs.get("medium", "photography") @@ -196,6 +247,11 @@ class RunwareBriaProviderSettings: forceBackgroundDetection = kwargs.get("forceBackgroundDetection", False) preserveAudio = kwargs.get("preserveAudio", True) autoTrim = kwargs.get("autoTrim", False) + season = kwargs.get("season", "spring") + edit = kwargs.get("edit", "restore") + color = kwargs.get("color", "contemporary color") + lightDirection = kwargs.get("lightDirection", "front") + lightType = kwargs.get("lightType", "midday") mask = kwargs.get("Bria Provider Setting Mask", None) # Build settings dictionary @@ -257,6 +313,26 @@ class RunwareBriaProviderSettings: if useAutoTrim: settings["autoTrim"] = autoTrim + # Add season only if useSeason is enabled (maps to /reseason) + if useSeason: + settings["season"] = season + + # Add edit only if useEdit is enabled + if useEdit: + settings["edit"] = edit + + # Add color only if useColor is enabled (maps to /colorize) + if useColor: + settings["color"] = color + + # Add lightDirection only if useLightDirection is enabled (maps to /relight + if useLightDirection: + settings["lightDirection"] = lightDirection + + # Add lightType only if useLightType is enabled (maps to /relight) + if useLightType: + settings["lightType"] = lightType + # Add mask if provided from Mask node if mask is not None and isinstance(mask, dict) and len(mask) > 0: settings["mask"] = mask @@ -274,3 +350,4 @@ NODE_CLASS_MAPPINGS = { NODE_DISPLAY_NAME_MAPPINGS = { "RunwareBriaProviderSettings": "Runware Bria Provider Settings", } + From bc7b906bbd06830f4ff61683889d27e4f3c47ff1 Mon Sep 17 00:00:00 2001 From: Sirshendu Ganguly Date: Wed, 25 Feb 2026 22:35:30 -0500 Subject: [PATCH 3/4] add workflows, etc --- __init__.py | 2 + clientlibs/main.js | 7 +- clientlibs/types.js | 5 + clientlibs/utils.js | 141 +++++++++++- modules/saveImage.py | 24 ++- modules/vectorize.py | 204 ++++++++++++++---- modules/videoInference.py | 8 + modules/videoModelSearch.py | 16 +- modules/videoSettings.py | 83 +++++++ .../Runware_Image_Inference_Seedream_5.json | 1 + workflows/Runware_Vectorize_Recraft.json | 1 + .../Runware_Video_Inference_Pruna_Video.json | 1 + 12 files changed, 445 insertions(+), 48 deletions(-) create mode 100644 modules/videoSettings.py create mode 100644 workflows/Runware_Image_Inference_Seedream_5.json create mode 100644 workflows/Runware_Vectorize_Recraft.json create mode 100644 workflows/Runware_Video_Inference_Pruna_Video.json diff --git a/__init__.py b/__init__.py index 942fcf9..2ba9aac 100644 --- a/__init__.py +++ b/__init__.py @@ -27,6 +27,7 @@ from .modules.referenceImages import referenceImages from .modules.imageInferenceInputs import imageInferenceInputs from .modules.videoInference import txt2vid from .modules.videoModelSearch import videoModelSearch +from .modules.videoSettings import RunwareVideoSettings from .modules.frameImages import RunwareFrameImages from .modules.providerSettings.pixverseProviderSettings import RunwarePixverseProviderSettings from .modules.providerSettings.openaiProviderSettings import RunwareOpenAIProviderSettings @@ -159,6 +160,7 @@ NODE_CLASS_MAPPINGS = { "Runware Reference Videos": referenceVideos, "Runware Reference Voices": referenceVoices, "Runware Video Inference Inputs": videoInferenceInputs, + "Runware Video Inference Settings": RunwareVideoSettings, "Runware Lightricks Provider Settings": RunwareLightricksProviderSettings, "Runware MiniMax Provider Settings": RunwareMiniMaxProviderSettings, "Runware Luma Provider Settings": RunwareLumaProviderSettings, diff --git a/clientlibs/main.js b/clientlibs/main.js index 44cc6f3..6a8d6a1 100644 --- a/clientlibs/main.js +++ b/clientlibs/main.js @@ -1,6 +1,6 @@ import { app } from "../../scripts/app.js"; import { api } from "../../scripts/api.js"; -import { promptEnhanceHandler, syncDimensionsNodeHandler, searchNodeHandler, APIKeyHandler, captionNodeHandler, mediaUUIDHandler, save3DFilepathHandler, videoTranscriptionHandler, videoOutputsHandler, handleCustomErrors, videoInferenceDimensionsHandler, videoModelSearchFilterHandler, audioModelSearchFilterHandler, useParameterToggleHandler, imageInferenceToggleHandler, upscalerToggleHandler, videoUpscalerToggleHandler, audioInferenceToggleHandler, audioInferenceSpeechToggleHandler, audioSettingsToggleHandler, acceleratorOptionsToggleHandler, bytedanceProviderSettingsToggleHandler, xaiProviderSettingsToggleHandler, viduProviderSettingsToggleHandler, sourcefulProviderSettingsToggleHandler, sourcefulProviderSettingsFontsToggleHandler, threeDInferenceToggleHandler, threeDInferenceSettingsToggleHandler, threeDInferenceSettingsLatToggleHandler, ultralyticsProviderSettingsToggleHandler, openaiProviderSettingsToggleHandler, lightricksProviderSettingsToggleHandler, klingProviderSettingsToggleHandler, lumaProviderSettingsToggleHandler, briaProviderSettingsToggleHandler, pixverseProviderSettingsToggleHandler, alibabaProviderSettingsToggleHandler, mireloProviderSettingsToggleHandler, googleProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler, settingsToggleHandler, audioInputToggleHandler, speechInputToggleHandler, briaProviderMaskToggleHandler, wanAnimateAdvancedFeatureSettingsToggleHandler, videoAdvancedFeatureInputsToggleHandler, audioInferenceInputsToggleHandler } from "./utils.js"; +import { promptEnhanceHandler, syncDimensionsNodeHandler, searchNodeHandler, APIKeyHandler, captionNodeHandler, mediaUUIDHandler, save3DFilepathHandler, videoTranscriptionHandler, videoOutputsHandler, handleCustomErrors, videoInferenceDimensionsHandler, videoModelSearchFilterHandler, audioModelSearchFilterHandler, vectorizeModelSearchFilterHandler, vectorizeToggleHandler, useParameterToggleHandler, imageInferenceToggleHandler, upscalerToggleHandler, videoUpscalerToggleHandler, audioInferenceToggleHandler, audioInferenceSpeechToggleHandler, audioSettingsToggleHandler, videoSettingsToggleHandler, acceleratorOptionsToggleHandler, bytedanceProviderSettingsToggleHandler, xaiProviderSettingsToggleHandler, viduProviderSettingsToggleHandler, sourcefulProviderSettingsToggleHandler, sourcefulProviderSettingsFontsToggleHandler, threeDInferenceToggleHandler, threeDInferenceSettingsToggleHandler, threeDInferenceSettingsLatToggleHandler, ultralyticsProviderSettingsToggleHandler, openaiProviderSettingsToggleHandler, lightricksProviderSettingsToggleHandler, klingProviderSettingsToggleHandler, lumaProviderSettingsToggleHandler, briaProviderSettingsToggleHandler, pixverseProviderSettingsToggleHandler, alibabaProviderSettingsToggleHandler, mireloProviderSettingsToggleHandler, googleProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler, settingsToggleHandler, audioInputToggleHandler, speechInputToggleHandler, briaProviderMaskToggleHandler, wanAnimateAdvancedFeatureSettingsToggleHandler, videoAdvancedFeatureInputsToggleHandler, audioInferenceInputsToggleHandler } from "./utils.js"; import { RUNWARE_NODE_TYPES, RUNWARE_NODE_PROPS, SEARCH_TERMS } from "./types.js"; const nodeInitList = []; @@ -82,6 +82,8 @@ app.registerExtension({ audioInferenceSpeechToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.AUDIOSETTINGS) { audioSettingsToggleHandler(node); + } else if(nodeClass === RUNWARE_NODE_TYPES.VIDEOSETTINGS) { + videoSettingsToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.ACCELERATOROPTIONS) { acceleratorOptionsToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.BYTEDANCEPROVIDERSETTINGS) { @@ -149,6 +151,9 @@ app.registerExtension({ videoModelSearchFilterHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.AUDIOMODELSEARCH) { audioModelSearchFilterHandler(node); + } else if(nodeClass === RUNWARE_NODE_TYPES.VECTORIZE) { + vectorizeModelSearchFilterHandler(node); + vectorizeToggleHandler(node); } for(const nodeWidget of nodeWidgets) { diff --git a/clientlibs/types.js b/clientlibs/types.js index f33d7b0..c31fb86 100644 --- a/clientlibs/types.js +++ b/clientlibs/types.js @@ -101,6 +101,7 @@ const RUNWARE_NODE_TYPES = { REFERENCEVIDEOS: "Runware Reference Videos", REFERENCEVOICES: "Runware Reference Voices", VIDEOINFERENCEINPUTS: "Runware Video Inference Inputs", + VIDEOSETTINGS: "Runware Video Inference Settings", LIGHTRICKSPROVIDERSETTINGS: "Runware Lightricks Provider Settings", KLINGPROVIDERSETTINGS: "Runware KlingAI Provider Settings", KLINGMULTIPROMPTSEGMENT: "Runware Kling MultiPrompt Segment", @@ -427,6 +428,7 @@ const RUNWARE_NODE_PROPS = { }, [RUNWARE_NODE_TYPES.VECTORIZE]: { bgColor: DEFAULT_BGCOLOR, + liveDimensions: true, }, [RUNWARE_NODE_TYPES.VIDEOBGREMOVAL]: { bgColor: DEFAULT_BGCOLOR, @@ -452,6 +454,9 @@ const RUNWARE_NODE_PROPS = { [RUNWARE_NODE_TYPES.AUDIOSETTINGSVOICEMODIFY]: { bgColor: DEFAULT_BGCOLOR, }, + [RUNWARE_NODE_TYPES.VIDEOSETTINGS]: { + bgColor: DEFAULT_BGCOLOR, + }, [RUNWARE_NODE_TYPES.ACCELERATOROPTIONS]: { bgColor: DEFAULT_BGCOLOR, colorModeOnly: true, diff --git a/clientlibs/utils.js b/clientlibs/utils.js index 23b03c3..1a02fea 100644 --- a/clientlibs/utils.js +++ b/clientlibs/utils.js @@ -419,8 +419,9 @@ async function syncDimensionsNodeHandler(node, dimensionsWidget) { appendWidgetCB(dimensionsWidget, function(...args) { const chosenDimension = args[0]; - if(chosenDimension === "Custom") return; + if(chosenDimension === "Custom" || chosenDimension === "None") return; const dimensionValue = DEFAULT_DIMENSIONS_LIST[chosenDimension]; + if(!dimensionValue) return; const [width, height] = dimensionValue.split("x"); widthWidget.callback(width, "customSetOperation"); heightWidget.callback(height, "customSetOperation"); @@ -1162,6 +1163,37 @@ function audioSettingsToggleHandler(settingsNode) { if (useTurboWidget && turboWidget) toggleWidgetState(useTurboWidget, turboWidget, "turbo"); } +function videoSettingsToggleHandler(settingsNode) { + if (!settingsNode?.widgets) return; + + const useDraftWidget = settingsNode.widgets.find(w => w && w.name === "useDraft"); + const draftWidget = settingsNode.widgets.find(w => w && w.name === "draft"); + const useAudioWidget = settingsNode.widgets.find(w => w && w.name === "useAudio"); + const audioWidget = settingsNode.widgets.find(w => w && w.name === "audio"); + const usePromptUpsamplingWidget = settingsNode.widgets.find(w => w && w.name === "usePromptUpsampling"); + const promptUpsamplingWidget = settingsNode.widgets.find(w => w && w.name === "promptUpsampling"); + + function toggleWidgetState(useWidget, paramWidget, paramName) { + if (!useWidget || !paramWidget) return; + function applyState() { + const enabled = useWidget.value === true; + toggleWidgetEnabled(paramWidget, enabled, settingsNode); + if (paramWidget.options && paramWidget.options.element) { + paramWidget.options.element.disabled = !enabled; + paramWidget.options.element.style.opacity = enabled ? "1" : "0.5"; + paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none"; + } + settingsNode.setDirtyCanvas(true); + } + setTimeout(applyState, 100); + appendWidgetCB(useWidget, () => setTimeout(applyState, 50)); + } + + if (useDraftWidget && draftWidget) toggleWidgetState(useDraftWidget, draftWidget, "draft"); + if (useAudioWidget && audioWidget) toggleWidgetState(useAudioWidget, audioWidget, "audio"); + if (usePromptUpsamplingWidget && promptUpsamplingWidget) toggleWidgetState(usePromptUpsamplingWidget, promptUpsamplingWidget, "promptUpsampling"); +} + function audioInferenceSpeechToggleHandler(speechNode) { if (!speechNode?.widgets) return; @@ -2323,6 +2355,9 @@ function videoModelSearchFilterHandler(videoModelSearchNode) { "VEED": [ "veed:fabric@1.0 (VEED Fabric 1.0)", ], + "Pruna": [ + "prunaai:p-video@0 (P-Video)", + ], }; const MODEL_DIMENSIONS = { @@ -2402,6 +2437,7 @@ function videoModelSearchFilterHandler(videoModelSearchNode) { "runware:210@1": {"width": 512, "height": 512}, "xai:grok-imagine@video": {"width": 480, "height": 480}, "veed:fabric@1.0": {"width": 1280, "height": 720}, + "prunaai:p-video@0": {"width": 1280, "height": 720}, }; const MODEL_RESOLUTIONS = { @@ -2481,6 +2517,7 @@ function videoModelSearchFilterHandler(videoModelSearchNode) { "runware:210@1": null, // No resolution support (fixed 512x512) "xai:grok-imagine@video": "480p", "veed:fabric@1.0": "720p", + "prunaai:p-video@0": "720p", }; const DEFAULT_DIMENSIONS = {"width": 1024, "height": 576}; @@ -2728,6 +2765,105 @@ function audioModelSearchFilterHandler(audioModelSearchNode) { filterModelList(); } +function vectorizeModelSearchFilterHandler(vectorizeNode) { + const modelArchWidget = vectorizeNode.widgets.find(w => w.name === "Model Architecture"); + const vectorListWidget = vectorizeNode.widgets.find(w => w.name === "Vector Model List"); + + if (!modelArchWidget || !vectorListWidget) return; + + const VECTORIZE_MODELS = { + "Recraft": [ + "recraft:1@1 (Recraft 1)", + "recraft:v4-pro@vector (Recraft V4 Pro Vector)", + "recraft:v4@vector (Recraft V4 Vector)", + ], + "Picsart": [ + "picsart:1@1 (Picsart 1)", + ], + }; + + function filterModelList() { + const selectedArch = modelArchWidget.value; + let filteredModels = []; + + if (selectedArch === "All") { + Object.values(VECTORIZE_MODELS).forEach(models => filteredModels.push(...models)); + } else if (VECTORIZE_MODELS[selectedArch]) { + filteredModels = VECTORIZE_MODELS[selectedArch]; + } + + if (filteredModels.length > 0) { + const currentValue = vectorListWidget.value; + vectorListWidget.options.values = filteredModels; + + if (!filteredModels.includes(currentValue)) { + vectorListWidget.value = filteredModels[0]; + } + + vectorizeNode.setDirtyCanvas(true); + } + } + + appendWidgetCB(modelArchWidget, filterModelList); + filterModelList(); +} + +function vectorizeToggleHandler(vectorizeNode) { + const usePositivePromptWidget = vectorizeNode.widgets.find(w => w.name === "Use Positive Prompt"); + const positivePromptWidget = vectorizeNode.widgets.find(w => w.name === "positivePrompt"); + const dimensionsWidget = vectorizeNode.widgets.find(w => w.name === "dimensions"); + const widthWidget = vectorizeNode.widgets.find(w => w.name === "width"); + const heightWidget = vectorizeNode.widgets.find(w => w.name === "height"); + + function toggleWidgetState(useWidget, paramWidget, paramName) { + if (!useWidget || !paramWidget) return; + function applyState() { + const enabled = useWidget.value === true; + if (paramWidget.inputEl) { + paramWidget.inputEl.disabled = !enabled; + paramWidget.inputEl.style.opacity = enabled ? "1" : "0.5"; + paramWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed"; + } + } + applyState(); + appendWidgetCB(useWidget, applyState); + } + + if (usePositivePromptWidget && positivePromptWidget) { + toggleWidgetState(usePositivePromptWidget, positivePromptWidget, "positivePrompt"); + } + + // Disable width/height when dimensions is "None" (same as image inference) + if (dimensionsWidget && widthWidget && heightWidget) { + function toggleDimensionsState() { + const dimensionsValue = dimensionsWidget.value; + const enabled = dimensionsValue !== "None"; + + if (widthWidget.inputEl) { + widthWidget.inputEl.disabled = !enabled; + widthWidget.inputEl.style.opacity = enabled ? "1" : "0.5"; + widthWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed"; + widthWidget.inputEl.readOnly = !enabled; + } + widthWidget.disabled = !enabled; + + if (heightWidget.inputEl) { + heightWidget.inputEl.disabled = !enabled; + heightWidget.inputEl.style.opacity = enabled ? "1" : "0.5"; + heightWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed"; + heightWidget.inputEl.readOnly = !enabled; + } + heightWidget.disabled = !enabled; + + vectorizeNode.setDirtyCanvas(true); + } + appendWidgetCB(dimensionsWidget, () => { + setTimeout(toggleDimensionsState, 50); + }); + setTimeout(toggleDimensionsState, 100); + } +} + function klingProviderSettingsToggleHandler(klingNode) { // Find all "use" parameter widgets for KlingAI Provider Settings (EXACT same pattern as imageInferenceToggleHandler) const useCameraControlWidget = klingNode.widgets.find(w => w.name === "useCameraControl"); @@ -3794,6 +3930,8 @@ export { videoInferenceDimensionsHandler, videoModelSearchFilterHandler, audioModelSearchFilterHandler, + vectorizeModelSearchFilterHandler, + vectorizeToggleHandler, useParameterToggleHandler, imageInferenceToggleHandler, upscalerToggleHandler, @@ -3801,6 +3939,7 @@ export { audioInferenceToggleHandler, audioInferenceSpeechToggleHandler, audioSettingsToggleHandler, + videoSettingsToggleHandler, acceleratorOptionsToggleHandler, bytedanceProviderSettingsToggleHandler, xaiProviderSettingsToggleHandler, diff --git a/modules/saveImage.py b/modules/saveImage.py index bc139c6..b3ac596 100644 --- a/modules/saveImage.py +++ b/modules/saveImage.py @@ -8,13 +8,25 @@ from PIL import Image from datetime import datetime +def _is_svg_url(url: str) -> bool: + """True if URL points to SVG (e.g. from Runware Vectorize).""" + u = (url or "").split("?")[0].lower() + return u.endswith(".svg") + + def _bytes_to_image_tensor(img_data: bytes): - """Decode image bytes to ComfyUI IMAGE tensor [1, H, W, C] float32 0-1.""" + """Decode image bytes to ComfyUI IMAGE tensor [1, H, W, C] float32 0-1. Fails on SVG (use placeholder for SVG).""" pil = Image.open(io.BytesIO(img_data)).convert("RGB") arr = np.array(pil).astype(np.float32) / 255.0 return torch.from_numpy(arr).unsqueeze(0) +def _placeholder_image_tensor(): + """Return a 1x1 RGB placeholder tensor [1, 1, 1, 3] for non-raster outputs (e.g. SVG from Vectorize).""" + arr = np.ones((1, 1, 3), dtype=np.float32) * 0.5 # grey + return torch.from_numpy(arr).unsqueeze(0) + + class RunwareSaveImage: """Runware Save Image: download from URL(s), save/preview to disk, and forward as IMAGE for chaining.""" @@ -23,7 +35,7 @@ class RunwareSaveImage: return { "required": { "Images": ("STRING", { - "tooltip": "Image URL(s) from Runware Image Inference node. For multiple images, URLs should be comma-separated." + "tooltip": "Image URL(s) from Runware Image Inference or Runware Vectorize node. For multiple images, URLs should be comma-separated. SVG URLs (e.g. from Vectorize) are saved as .svg files; a placeholder tensor is passed for the IMAGE output." }), "filenamePrefix": ("STRING", { "default": "ComfyUI", @@ -69,10 +81,14 @@ class RunwareSaveImage: response.raise_for_status() img_data = response.content - tensors.append(_bytes_to_image_tensor(img_data)) + # SVG (e.g. from Runware Vectorize) cannot be opened by PIL; save as file and use placeholder tensor + if _is_svg_url(image_url): + tensors.append(_placeholder_image_tensor()) + else: + tensors.append(_bytes_to_image_tensor(img_data)) url_without_params = image_url.split("?")[0] - ext = url_without_params.split(".")[-1].lstrip(".") or "png" + ext = url_without_params.split(".")[-1].lstrip(".").lower() or "png" extension = "." + ext if len(image_urls) > 1: filename = f"{filenamePrefix}_{timestamp}_{i+1:03}{extension}" diff --git a/modules/vectorize.py b/modules/vectorize.py index 9b22a28..6dc200a 100644 --- a/modules/vectorize.py +++ b/modules/vectorize.py @@ -1,24 +1,97 @@ +import re + from .utils import runwareUtils as rwUtils class vectorize: """Vectorize node for converting images to vector format""" - - RUNWARE_VECTORIZE_MODELS = { - "recraft:1@1": "recraft:1@1", - "picsart:1@1": "picsart:1@1", + + # Models grouped by architecture (provider), same pattern as video model search + VECTORIZE_MODELS = { + "Recraft": [ + "recraft:1@1 (Recraft 1)", + "recraft:v4-pro@vector (Recraft V4 Pro Vector)", + "recraft:v4@vector (Recraft V4 Vector)", + ], + "Picsart": [ + "picsart:1@1 (Picsart 1)", + ], } - + + MODEL_ARCHITECTURES = [ + "All", + "Recraft", + "Picsart", + ] + + @classmethod + def _getAllModels(cls): + """Get all models from all architectures""" + all_models = [] + for models in cls.VECTORIZE_MODELS.values(): + all_models.extend(models) + return all_models + @classmethod def INPUT_TYPES(cls): + all_models = cls._getAllModels() + default_model = all_models[0] if all_models else "recraft:1@1 (Recraft 1)" return { "required": { - "Image": ("IMAGE", { - "tooltip": "Input image to be vectorized." + "Model Search": ("STRING", { + "tooltip": "Search for a vectorization model by name or AIR code (e.g. recraft, picsart).", }), - "Model": (list(cls.RUNWARE_VECTORIZE_MODELS.keys()), { - "tooltip": "Select the vectorization model to use.", - "default": "recraft:1@1", + "Model Architecture": (cls.MODEL_ARCHITECTURES, { + "tooltip": "Choose model architecture to filter the model list.", + "default": "Recraft", + }), + "Vector Model List": (all_models, { + "tooltip": "Select the vectorization model. Filter by Model Architecture above.", + "default": default_model, + }), + "Use Search Value": ("BOOLEAN", { + "tooltip": "When enabled, the value in Model Search is used as the model AIR code instead of the list selection.", + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + }), + }, + "optional": { + "Image": ("IMAGE", { + "tooltip": "Optional input image to be vectorized." + }), + "dimensions": ([ + "None", "Square HD (1024x1024)", "Custom" + ], { + "default": "None", + "tooltip": "Output dimensions preset. Select 'None' for model default, or a preset to set width/height. Use 'Custom' with width/height inputs.", + }), + "width": ("INT", { + "tooltip": "Width in pixels. Used when dimensions is not 'None' (or with Custom).", + "default": 1024, + "min": 128, + "max": 6048, + "step": 1, + }), + "height": ("INT", { + "tooltip": "Height in pixels. Used when dimensions is not 'None' (or with Custom).", + "default": 1024, + "min": 128, + "max": 6048, + "step": 1, + }), + "Use positivePrompt": ("BOOLEAN", { + "tooltip": "When enabled, include positivePrompt in the vectorize request.", + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "positivePrompt": ("STRING", { + "multiline": True, + "tooltip": "Optional text prompt for vectorization. Only sent when Use Positive Prompt is enabled.", + }), + "providerSettings": ("RUNWAREPROVIDERSETTINGS", { + "tooltip": "Connect a Runware Provider Settings Node to configure provider-specific parameters (e.g. Recraft, Picsart).", }), }, } @@ -29,51 +102,104 @@ class vectorize: RETURN_NAMES = ("IMAGE",) CATEGORY = "Runware" + @classmethod + def VALIDATE_INPUTS(cls, **kwargs): + return True + def vectorizeImage(self, **kwargs): """Vectorize image and return SVG URL""" image = kwargs.get("Image") - modelName = kwargs.get("Model", "recraft:1@1") - - model = self.RUNWARE_VECTORIZE_MODELS.get(modelName, "recraft:1@1") - imageUuid = rwUtils.convertTensor2IMG(image) - - genConfig = self._buildGenConfig(model, imageUuid) - + use_search_value = kwargs.get("Use Search Value", False) + search_input = kwargs.get("Model Search", "") + current_model = kwargs.get("Vector Model List", "recraft:1@1 (Recraft 1)") + + if use_search_value and search_input and str(search_input).strip(): + model_air_code = str(search_input).strip() + else: + # Extract AIR code from "airId (Display Name)" format + model_air_code = current_model.split(" (")[0].strip() + + image_uuid = rwUtils.convertTensor2IMG(image) if image is not None else None + width = kwargs.get("width") + height = kwargs.get("height") + dimensions = kwargs.get("dimensions", "None") + use_positive_prompt = kwargs.get("Use positivePrompt", False) + positive_prompt = kwargs.get("positivePrompt") + provider_settings = kwargs.get("providerSettings") + gen_config = self._buildGenConfig( + model_air_code, image_uuid, + width=width, height=height, dimensions=dimensions, + use_positive_prompt=use_positive_prompt, positive_prompt=positive_prompt, + provider_settings=provider_settings, + ) + print(f"[DEBUG] Sending Vectorize Request:") - print(f"[DEBUG] Request Payload: {rwUtils.safe_json_dumps(genConfig, indent=2)}") - - genResult = rwUtils.inferenecRequest(genConfig) - + print(f"[DEBUG] Request Payload: {rwUtils.safe_json_dumps(gen_config, indent=2)}") + + gen_result = rwUtils.inferenecRequest(gen_config) print(f"[DEBUG] Received Vectorize Response:") - print(f"[DEBUG] Response: {rwUtils.safe_json_dumps(genResult, indent=2)}") - - self._validateResponse(genResult) - - svg_url = rwUtils.extractImageURLs(genResult) - + print(f"[DEBUG] Response: {rwUtils.safe_json_dumps(gen_result, indent=2)}") + + self._validateResponse(gen_result) + svg_url = rwUtils.extractImageURLs(gen_result) return (svg_url,) - def _buildGenConfig(self, model, imageUuid): - """Build generation configuration for API request""" - return [{ + @staticmethod + def _parseDimensionsPreset(dimensions): + """Parse 'Label (WxH)' to (width, height) or None if not a preset.""" + if not dimensions or dimensions in ("None", "Custom"): + return None, None + m = re.search(r"\((\d+)x(\d+)\)", dimensions) + if m: + return int(m.group(1)), int(m.group(2)) + return None, None + + def _buildGenConfig(self, model, image_uuid, width=None, height=None, dimensions="None", + use_positive_prompt=False, positive_prompt=None, provider_settings=None): + """Build generation configuration for API request. image_uuid, width, height, positivePrompt, providerSettings are optional.""" + inputs = {} + if image_uuid is not None: + inputs["image"] = image_uuid + payload = { "taskType": "vectorize", "taskUUID": rwUtils.genRandUUID(), "model": model, - "inputs": { - "image": imageUuid - }, + "inputs": inputs, "outputType": "URL", "outputFormat": "svg", - }] + } + if dimensions and dimensions != "None": + w, h = width, height + if w is None or h is None: + pw, ph = self._parseDimensionsPreset(dimensions) + if pw is not None and ph is not None: + w, h = pw, ph + if w is not None and h is not None: + payload["width"] = w + payload["height"] = h + if use_positive_prompt and positive_prompt is not None and str(positive_prompt).strip(): + payload["positivePrompt"] = str(positive_prompt).strip() + # Handle providerSettings - extract provider name from model and merge (same as image inference) + if provider_settings is not None: + provider_name = model.split(":")[0] if ":" in model else model + if isinstance(provider_settings, dict): + if any(key in provider_settings for key in ["alibaba", "bytedance", "klingai", "openai", "pixverse", + "bria", "lightricks", "luma", "minimax", "runway", "vidu", + "elevenlabs", "bfl", "xai", "recraft", "picsart", "sourceful"]): + payload["providerSettings"] = provider_settings + else: + payload["providerSettings"] = {provider_name: provider_settings} + else: + payload["providerSettings"] = provider_settings + return [payload] - def _validateResponse(self, genResult): + def _validateResponse(self, gen_result): """Validate API response""" - if "errors" in genResult: - errorMessage = genResult["errors"][0]["message"] - raise Exception(f"Vectorization failed: {errorMessage}") + if "errors" in gen_result: + error_message = gen_result["errors"][0]["message"] + raise Exception(f"Vectorization failed: {error_message}") -# Node class mappings NODE_CLASS_MAPPINGS = { "RunwareVectorize": vectorize, } diff --git a/modules/videoInference.py b/modules/videoInference.py index 39b0db2..378c0a2 100644 --- a/modules/videoInference.py +++ b/modules/videoInference.py @@ -144,6 +144,9 @@ class txt2vid: "Accelerator": ("RUNWAREACCELERATOR", { "tooltip": "Connect a Runware Accelerator Options Node to configure caching and acceleration settings.", }), + "settings": ("RUNWAREVIDEOSETTINGS", { + "tooltip": "Connect a Runware Video Inference Settings node to configure draft, audio, and promptUpsampling.", + }), } } @@ -181,6 +184,7 @@ class txt2vid: safetyInputs = kwargs.get("safetyInputs", None) videoAdvancedFeatureInputs = kwargs.get("videoAdvancedFeatureInputs", None) runwareAccelerator = kwargs.get("Accelerator", None) + settings = kwargs.get("settings", None) useDuration = kwargs.get("useDuration", True) duration = kwargs.get("duration", 5) fps = kwargs.get("fps", 24) @@ -350,6 +354,10 @@ class txt2vid: # Add accelerator options if provided if runwareAccelerator is not None and isinstance(runwareAccelerator, dict) and len(runwareAccelerator) > 0: genConfig[0]["acceleratorOptions"] = runwareAccelerator + + # Add settings if provided (draft, audio, promptUpsampling) + if settings is not None and isinstance(settings, dict) and len(settings) > 0: + genConfig[0]["settings"] = settings # Add acceleration if not "none" if acceleration and acceleration != "none": diff --git a/modules/videoModelSearch.py b/modules/videoModelSearch.py index e289a38..b286cdd 100644 --- a/modules/videoModelSearch.py +++ b/modules/videoModelSearch.py @@ -117,6 +117,9 @@ class videoModelSearch: "VEED": [ "veed:fabric@1.0 (VEED Fabric 1.0)", ], + "Pruna": [ + "prunaai:p-video@0 (P-Video)", + ], } # Model dimensions mapping @@ -234,6 +237,9 @@ class videoModelSearch: # VEED Models (preserves input aspect ratio; resolution = shorter side) "veed:fabric@1.0": {"width": 1280, "height": 720}, + + # Pruna Models (720p) + "prunaai:p-video@0": {"width": 1280, "height": 720}, } # Model resolutions mapping @@ -349,10 +355,13 @@ class videoModelSearch: # xAI Models "xai:grok-imagine@video": "480p", - # VEED Models + # VEED Models "veed:fabric@1.0": "720p", + + # Pruna Models + "prunaai:p-video@0": "720p", } - + MODEL_ARCHITECTURES = [ "All", "KlingAI", @@ -373,7 +382,8 @@ class videoModelSearch: "Hunyuan", "Kandinsky", "xAI", - "VEED" + "VEED", + "Pruna", ] DEFAULT_DIMENSIONS = {"width": 1024, "height": 576} diff --git a/modules/videoSettings.py b/modules/videoSettings.py new file mode 100644 index 0000000..3c2e713 --- /dev/null +++ b/modules/videoSettings.py @@ -0,0 +1,83 @@ +""" +Runware Video Inference Settings Node +Provides settings (draft, audio, promptUpsampling) for Runware Video Inference. +""" + +from typing import Dict, Any + + +class RunwareVideoSettings: + """Runware Video Inference Settings Node""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": {}, + "optional": { + "useDraft": ("BOOLEAN", { + "tooltip": "Enable to include draft (lower-quality preview mode) in video inference settings.", + "default": False, + }), + "draft": ("BOOLEAN", { + "tooltip": "Draft mode for lower-quality preview. Only used when 'Use Draft' is enabled.", + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "useAudio": ("BOOLEAN", { + "tooltip": "Enable to include audio (save video with audio) in video inference settings.", + "default": True, + }), + "audio": ("BOOLEAN", { + "tooltip": "Save the video with audio. Only used when 'Use Audio' is enabled.", + "default": True, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "usePromptUpsampling": ("BOOLEAN", { + "tooltip": "Enable to include promptUpsampling (enhance prompt automatically) in video inference settings.", + "default": True, + }), + "promptUpsampling": ("BOOLEAN", { + "tooltip": "Enhance prompt automatically for better results. Only used when 'Use Prompt Upsampling' is enabled.", + "default": True, + "label_on": "Enabled", + "label_off": "Disabled", + }), + } + } + + RETURN_TYPES = ("RUNWAREVIDEOSETTINGS",) + RETURN_NAMES = ("settings",) + FUNCTION = "createSettings" + CATEGORY = "Runware" + DESCRIPTION = "Configure video inference settings (draft, audio, promptUpsampling) for Runware Video Inference. Connect to Runware Video Inference node." + + def createSettings(self, **kwargs) -> tuple: + """Create settings dict for Video Inference API""" + use_draft = kwargs.get("useDraft", False) + draft = kwargs.get("draft", False) + use_audio = kwargs.get("useAudio", True) + audio = kwargs.get("audio", True) + use_prompt_upsampling = kwargs.get("usePromptUpsampling", True) + prompt_upsampling = kwargs.get("promptUpsampling", True) + + settings: Dict[str, Any] = {} + + if use_draft: + settings["draft"] = bool(draft) + if use_audio: + settings["audio"] = bool(audio) + if use_prompt_upsampling: + settings["promptUpsampling"] = bool(prompt_upsampling) + + return (settings,) + + +NODE_CLASS_MAPPINGS = { + "RunwareVideoSettings": RunwareVideoSettings, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "RunwareVideoSettings": "Runware Video Inference Settings", +} diff --git a/workflows/Runware_Image_Inference_Seedream_5.json b/workflows/Runware_Image_Inference_Seedream_5.json new file mode 100644 index 0000000..5234b84 --- /dev/null +++ b/workflows/Runware_Image_Inference_Seedream_5.json @@ -0,0 +1 @@ +{"id":"dd7adc3e-fe0d-482b-b9f2-214fbd2d73e0","revision":0,"last_node_id":5,"last_link_id":3,"nodes":[{"id":4,"type":"Runware Save Image","pos":[534.8482666015625,588.608642578125],"size":[270,318],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"Images","name":"Images","type":"STRING","widget":{"name":"Images"},"link":1},{"localized_name":"filenamePrefix","name":"filenamePrefix","type":"STRING","widget":{"name":"filenamePrefix"},"link":null},{"localized_name":"saveImage","name":"saveImage","type":"BOOLEAN","widget":{"name":"saveImage"},"link":null}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":null}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"dee0949f78f02adb54037e1df1cc2bf7df7b4bfe","Node name for S&R":"Runware Save Image"},"widgets_values":["","ComfyUI",true],"bgcolor":"#5345bf"},{"id":2,"type":"Runware Model Search","pos":[-332.40582275390625,567.2559204101562],"size":[270,154],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"Model Search","name":"Model Search","type":"STRING","widget":{"name":"Model Search"},"link":null},{"localized_name":"Model Architecture","name":"Model Architecture","type":"COMBO","widget":{"name":"Model Architecture"},"link":null},{"localized_name":"ModelType","name":"ModelType","type":"COMBO","widget":{"name":"ModelType"},"link":null},{"localized_name":"ModelList","name":"ModelList","type":"COMBO","widget":{"name":"ModelList"},"link":null},{"localized_name":"Use Search Value","name":"Use Search Value","type":"BOOLEAN","widget":{"name":"Use Search Value"},"link":null}],"outputs":[{"localized_name":"Runware Model","name":"Runware Model","type":"RUNWAREMODEL","links":[2]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"dee0949f78f02adb54037e1df1cc2bf7df7b4bfe","Node name for S&R":"Runware Model Search"},"widgets_values":["bytedance:seedream@5.0-lite","All","Base Model","bytedance:seedream@5.0-lite (Seedream 5.0 Lite 5.0)",false],"bgcolor":"#5345bf"},{"id":5,"type":"Runware Bytedance Provider Settings","pos":[-380.7424011230469,825.67919921875],"size":[336.4712829589844,322],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"useCameraFixed","name":"useCameraFixed","shape":7,"type":"BOOLEAN","widget":{"name":"useCameraFixed"},"link":null},{"localized_name":"cameraFixed","name":"cameraFixed","shape":7,"type":"BOOLEAN","widget":{"name":"cameraFixed"},"link":null},{"localized_name":"useMaxSequentialImages","name":"useMaxSequentialImages","shape":7,"type":"BOOLEAN","widget":{"name":"useMaxSequentialImages"},"link":null},{"localized_name":"maxSequentialImages","name":"maxSequentialImages","shape":7,"type":"INT","widget":{"name":"maxSequentialImages"},"link":null},{"localized_name":"useFastMode","name":"useFastMode","shape":7,"type":"BOOLEAN","widget":{"name":"useFastMode"},"link":null},{"localized_name":"fastMode","name":"fastMode","shape":7,"type":"BOOLEAN","widget":{"name":"fastMode"},"link":null},{"localized_name":"useAudio","name":"useAudio","shape":7,"type":"BOOLEAN","widget":{"name":"useAudio"},"link":null},{"localized_name":"audio","name":"audio","shape":7,"type":"BOOLEAN","widget":{"name":"audio"},"link":null},{"localized_name":"useDraft","name":"useDraft","shape":7,"type":"BOOLEAN","widget":{"name":"useDraft"},"link":null},{"localized_name":"draft","name":"draft","shape":7,"type":"BOOLEAN","widget":{"name":"draft"},"link":null},{"localized_name":"useOptimizePromptMode","name":"useOptimizePromptMode","shape":7,"type":"BOOLEAN","widget":{"name":"useOptimizePromptMode"},"link":null},{"localized_name":"optimizePromptMode","name":"optimizePromptMode","shape":7,"type":"COMBO","widget":{"name":"optimizePromptMode"},"link":null}],"outputs":[{"localized_name":"providerSettings","name":"providerSettings","type":"RUNWAREPROVIDERSETTINGS","links":[3]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"dee0949f78f02adb54037e1df1cc2bf7df7b4bfe","Node name for S&R":"Runware Bytedance Provider Settings"},"widgets_values":[false,false,false,1,false,false,false,false,false,false,true,"standard"],"bgcolor":"#5345bf"},{"id":1,"type":"Runware Image Inference","pos":[25.71064567565918,523.72021484375],"size":[400,1038],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"Model","name":"Model","type":"RUNWAREMODEL","link":2},{"localized_name":"Accelerator","name":"Accelerator","shape":7,"type":"RUNWAREACCELERATOR","link":null},{"localized_name":"Lora","name":"Lora","shape":7,"type":"RUNWARELORA","link":null},{"localized_name":"Outpainting","name":"Outpainting","shape":7,"type":"RUNWAREOUTPAINT","link":null},{"localized_name":"IPAdapters","name":"IPAdapters","shape":7,"type":"RUNWAREIPAdapter","link":null},{"localized_name":"ControlNet","name":"ControlNet","shape":7,"type":"RUNWARECONTROLNET","link":null},{"localized_name":"Refiner","name":"Refiner","shape":7,"type":"RUNWAREREFINER","link":null},{"localized_name":"seedImage","name":"seedImage","shape":7,"type":"IMAGE","link":null},{"localized_name":"maskImage","name":"maskImage","shape":7,"type":"MASK","link":null},{"localized_name":"Embeddings","name":"Embeddings","shape":7,"type":"RUNWAREEMBEDDING","link":null},{"localized_name":"VAE","name":"VAE","shape":7,"type":"RUNWAREVAE","link":null},{"localized_name":"referenceImages","name":"referenceImages","shape":7,"type":"RUNWAREREFERENCEIMAGES","link":null},{"localized_name":"inputs","name":"inputs","shape":7,"type":"RUNWAREIMAGEINFERENCEINPUTS","link":null},{"localized_name":"providerSettings","name":"providerSettings","shape":7,"type":"RUNWAREPROVIDERSETTINGS","link":3},{"localized_name":"safetyInputs","name":"safetyInputs","shape":7,"type":"RUNWARESAFETYINPUTS","link":null},{"localized_name":"settings","name":"settings","shape":7,"type":"RUNWARESETTINGS","link":null},{"localized_name":"ultralytics","name":"ultralytics","shape":7,"type":"RUNWAREULTRALYTICSINPUTS","link":null},{"localized_name":"positivePrompt","name":"positivePrompt","type":"STRING","widget":{"name":"positivePrompt"},"link":null},{"localized_name":"negativePrompt","name":"negativePrompt","type":"STRING","widget":{"name":"negativePrompt"},"link":null},{"localized_name":"Multi Inference Mode","name":"Multi Inference Mode","type":"BOOLEAN","widget":{"name":"Multi Inference Mode"},"link":null},{"localized_name":"Prompt Weighting","name":"Prompt Weighting","type":"COMBO","widget":{"name":"Prompt Weighting"},"link":null},{"localized_name":"dimensions","name":"dimensions","type":"COMBO","widget":{"name":"dimensions"},"link":null},{"localized_name":"width","name":"width","type":"INT","widget":{"name":"width"},"link":null},{"localized_name":"height","name":"height","type":"INT","widget":{"name":"height"},"link":null},{"localized_name":"useResolution","name":"useResolution","type":"BOOLEAN","widget":{"name":"useResolution"},"link":null},{"localized_name":"resolution","name":"resolution","type":"COMBO","widget":{"name":"resolution"},"link":null},{"localized_name":"useSteps","name":"useSteps","type":"BOOLEAN","widget":{"name":"useSteps"},"link":null},{"localized_name":"steps","name":"steps","type":"INT","widget":{"name":"steps"},"link":null},{"localized_name":"useScheduler","name":"useScheduler","type":"BOOLEAN","widget":{"name":"useScheduler"},"link":null},{"localized_name":"scheduler","name":"scheduler","type":"COMBO","widget":{"name":"scheduler"},"link":null},{"localized_name":"useCFGScale","name":"useCFGScale","type":"BOOLEAN","widget":{"name":"useCFGScale"},"link":null},{"localized_name":"cfgScale","name":"cfgScale","type":"FLOAT","widget":{"name":"cfgScale"},"link":null},{"localized_name":"useSeed","name":"useSeed","type":"BOOLEAN","widget":{"name":"useSeed"},"link":null},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"useClipSkip","name":"useClipSkip","type":"BOOLEAN","widget":{"name":"useClipSkip"},"link":null},{"localized_name":"clipSkip","name":"clipSkip","type":"INT","widget":{"name":"clipSkip"},"link":null},{"localized_name":"strength","name":"strength","type":"FLOAT","widget":{"name":"strength"},"link":null},{"localized_name":"Mask Margin","name":"Mask Margin","type":"BOOLEAN","widget":{"name":"Mask Margin"},"link":null},{"localized_name":"maskMargin","name":"maskMargin","type":"INT","widget":{"name":"maskMargin"},"link":null},{"localized_name":"outputFormat","name":"outputFormat","type":"COMBO","widget":{"name":"outputFormat"},"link":null},{"localized_name":"batchSize","name":"batchSize","type":"INT","widget":{"name":"batchSize"},"link":null},{"localized_name":"acceleration","name":"acceleration","type":"COMBO","widget":{"name":"acceleration"},"link":null}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"STRING","links":[1]},{"localized_name":"RW-Task","name":"RW-Task","type":"RUNWARETASK","links":null}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"dee0949f78f02adb54037e1df1cc2bf7df7b4bfe","Node name for S&R":"Runware Image Inference"},"widgets_values":["A selfie of a cat, with the cat as the protagonist. The setting is twilight at the Eiffel Tower. The cat is happy, holding a piece of baklava in its paw. The photo has a slight motion blur and is slightly overexposed. From a selfie angle, with a bit of motion blur, the overall image presents a sense of calm madness. The text \\\"Seedream 5.0-lite is on runware\\\" should be written on the picture at the top in clearly visible font and crisp lettering. The image has a 4:3 aspect ratio","",false,"Disabled","Custom",2048,2048,false,"1k",false,4,false,"Default",false,6.5,false,2023295130,"randomize",true,0,0.8,false,32,"WEBP",1,"none"],"bgcolor":"#5345bf"}],"links":[[1,1,0,4,0,"STRING"],[2,2,0,1,0,"RUNWAREMODEL"],[3,5,0,1,13,"RUNWAREPROVIDERSETTINGS"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.638832468260247,"offset":[757.8341248546785,-491.73265096778175]}},"version":0.4} \ No newline at end of file diff --git a/workflows/Runware_Vectorize_Recraft.json b/workflows/Runware_Vectorize_Recraft.json new file mode 100644 index 0000000..220e241 --- /dev/null +++ b/workflows/Runware_Vectorize_Recraft.json @@ -0,0 +1 @@ +{"id":"993f4b88-acb5-4f70-968f-e3a2c9c1c5b4","revision":0,"last_node_id":19,"last_link_id":17,"nodes":[{"id":9,"type":"Runware Save Image","pos":[541.6531372070312,656.4539184570312],"size":[270,318],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"Images","name":"Images","type":"STRING","widget":{"name":"Images"},"link":15},{"localized_name":"filenamePrefix","name":"filenamePrefix","type":"STRING","widget":{"name":"filenamePrefix"},"link":null},{"localized_name":"saveImage","name":"saveImage","type":"BOOLEAN","widget":{"name":"saveImage"},"link":null}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":null}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"91646ada844167e36188b535ff60063735d10ca3","Node name for S&R":"Runware Save Image"},"widgets_values":["","ComfyUI",true],"bgcolor":"#5345bf"},{"id":19,"type":"Runware Provider Settings Recraft Color","pos":[-305.0177001953125,914.2234497070312],"size":[352.7818298339844,106],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"r","name":"r","shape":7,"type":"INT","widget":{"name":"r"},"link":null},{"localized_name":"g","name":"g","shape":7,"type":"INT","widget":{"name":"g"},"link":null},{"localized_name":"b","name":"b","shape":7,"type":"INT","widget":{"name":"b"},"link":null}],"outputs":[{"localized_name":"Color","name":"Color","type":"RUNWARERECRAFTCOLOR","links":[16]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"dee0949f78f02adb54037e1df1cc2bf7df7b4bfe","Node name for S&R":"Runware Provider Settings Recraft Color"},"widgets_values":[0,0,128],"bgcolor":"#5345bf"},{"id":18,"type":"Runware Recraft Provider Settings","pos":[-282.6740417480469,646.2836303710938],"size":[315.4371032714844,182],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"color1","name":"color1","shape":7,"type":"RUNWARERECRAFTCOLOR","link":null},{"localized_name":"color2","name":"color2","shape":7,"type":"RUNWARERECRAFTCOLOR","link":null},{"localized_name":"color3","name":"color3","shape":7,"type":"RUNWARERECRAFTCOLOR","link":null},{"localized_name":"color4","name":"color4","shape":7,"type":"RUNWARERECRAFTCOLOR","link":null},{"localized_name":"color5","name":"color5","shape":7,"type":"RUNWARERECRAFTCOLOR","link":null},{"localized_name":"backgroundColor","name":"backgroundColor","shape":7,"type":"RUNWARERECRAFTCOLOR","link":16},{"localized_name":"useStyleId","name":"useStyleId","shape":7,"type":"BOOLEAN","widget":{"name":"useStyleId"},"link":null},{"localized_name":"styleId","name":"styleId","shape":7,"type":"STRING","widget":{"name":"styleId"},"link":null}],"outputs":[{"localized_name":"Provider Settings","name":"Provider Settings","type":"RUNWAREPROVIDERSETTINGS","links":[17]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"dee0949f78f02adb54037e1df1cc2bf7df7b4bfe","Node name for S&R":"Runware Recraft Provider Settings"},"widgets_values":[false,""],"bgcolor":"#5345bf"},{"id":17,"type":"Runware Vectorize","pos":[72.84228515625,650.274658203125],"size":[400,300],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"Image","name":"Image","shape":7,"type":"IMAGE","link":null},{"localized_name":"providerSettings","name":"providerSettings","shape":7,"type":"RUNWAREPROVIDERSETTINGS","link":17},{"localized_name":"Model Search","name":"Model Search","type":"STRING","widget":{"name":"Model Search"},"link":null},{"localized_name":"Model Architecture","name":"Model Architecture","type":"COMBO","widget":{"name":"Model Architecture"},"link":null},{"localized_name":"Vector Model List","name":"Vector Model List","type":"COMBO","widget":{"name":"Vector Model List"},"link":null},{"localized_name":"Use Search Value","name":"Use Search Value","type":"BOOLEAN","widget":{"name":"Use Search Value"},"link":null},{"localized_name":"dimensions","name":"dimensions","shape":7,"type":"COMBO","widget":{"name":"dimensions"},"link":null},{"localized_name":"width","name":"width","shape":7,"type":"INT","widget":{"name":"width"},"link":null},{"localized_name":"height","name":"height","shape":7,"type":"INT","widget":{"name":"height"},"link":null},{"localized_name":"Use positivePrompt","name":"Use positivePrompt","shape":7,"type":"BOOLEAN","widget":{"name":"Use positivePrompt"},"link":null},{"localized_name":"positivePrompt","name":"positivePrompt","shape":7,"type":"STRING","widget":{"name":"positivePrompt"},"link":null}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"STRING","links":[15]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"dee0949f78f02adb54037e1df1cc2bf7df7b4bfe","Node name for S&R":"Runware Vectorize"},"widgets_values":["","Recraft","recraft:v4@vector (Recraft V4 Vector)",false,"Square HD (1024x1024)",1024,1024,true,"Retro 1970s style poster with the text 'Recraft V4'"],"bgcolor":"#5345bf"}],"links":[[15,17,0,9,0,"STRING"],[16,19,0,18,5,"RUNWARERECRAFTCOLOR"],[17,18,0,17,1,"RUNWAREPROVIDERSETTINGS"]],"groups":[],"config":{},"extra":{"ds":{"scale":1.02884607845781,"offset":[484.37043720120533,-463.73196868190934]}},"version":0.4} \ No newline at end of file diff --git a/workflows/Runware_Video_Inference_Pruna_Video.json b/workflows/Runware_Video_Inference_Pruna_Video.json new file mode 100644 index 0000000..b999498 --- /dev/null +++ b/workflows/Runware_Video_Inference_Pruna_Video.json @@ -0,0 +1 @@ +{"id":"afea0ddc-60ea-4dcc-ba99-8179aec77dd1","revision":0,"last_node_id":8,"last_link_id":6,"nodes":[{"id":3,"type":"Runware Video Model Search","pos":[-433.2157287597656,676.550048828125],"size":[287.380859375,250],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"Model Search","name":"Model Search","type":"STRING","widget":{"name":"Model Search"},"link":null},{"localized_name":"Model Architecture","name":"Model Architecture","type":"COMBO","widget":{"name":"Model Architecture"},"link":null},{"localized_name":"VideoList","name":"VideoList","type":"COMBO","widget":{"name":"VideoList"},"link":null},{"localized_name":"Use Search Value","name":"Use Search Value","type":"BOOLEAN","widget":{"name":"Use Search Value"},"link":null},{"localized_name":"useCustomDimensions","name":"useCustomDimensions","type":"COMBO","widget":{"name":"useCustomDimensions"},"link":null},{"localized_name":"Width","name":"Width","type":"INT","widget":{"name":"Width"},"link":null},{"localized_name":"Height","name":"Height","type":"INT","widget":{"name":"Height"},"link":null},{"localized_name":"useResolution","name":"useResolution","type":"BOOLEAN","widget":{"name":"useResolution"},"link":null},{"localized_name":"resolution","name":"resolution","type":"COMBO","widget":{"name":"resolution"},"link":null}],"outputs":[{"localized_name":"Runware Video Model","name":"Runware Video Model","type":"RUNWAREVIDEOMODEL","links":[1]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"dee0949f78f02adb54037e1df1cc2bf7df7b4bfe","Node name for S&R":"Runware Video Model Search"},"widgets_values":["","Pruna","prunaai:p-video@0 (P-Video)",false,"Model Default",1280,720,false,"1080p"],"bgcolor":"#5345bf"},{"id":4,"type":"SaveVideo","pos":[470.9870910644531,750.4152221679688],"size":[270,503],"flags":{},"order":5,"mode":0,"inputs":[{"localized_name":"video","name":"video","type":"VIDEO","link":2},{"localized_name":"filename_prefix","name":"filename_prefix","type":"STRING","widget":{"name":"filename_prefix"},"link":null},{"localized_name":"format","name":"format","type":"COMBO","widget":{"name":"format"},"link":null},{"localized_name":"codec","name":"codec","type":"COMBO","widget":{"name":"codec"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfy-core","ver":"0.3.46","Node name for S&R":"SaveVideo"},"widgets_values":["video/ComfyUI","auto","auto"]},{"id":8,"type":"LoadImage","pos":[-760.1270751953125,764.8264770507812],"size":[274.080078125,314],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"image","name":"image","type":"COMBO","widget":{"name":"image"},"link":null},{"localized_name":"choose file to upload","name":"upload","type":"IMAGEUPLOAD","widget":{"name":"upload"},"link":null}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[5]},{"localized_name":"MASK","name":"MASK","type":"MASK","links":null}],"properties":{"cnr_id":"comfy-core","ver":"0.3.46","Node name for S&R":"LoadImage"},"widgets_values":["woman-by-car.jpg","image"]},{"id":7,"type":"Runware Video Inputs Frame Images","pos":[-775.2938232421875,1166.427490234375],"size":[331.5357360839844,190],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"image1","name":"image1","shape":7,"type":"IMAGE","link":5},{"localized_name":"image2","name":"image2","shape":7,"type":"IMAGE","link":null},{"localized_name":"image3","name":"image3","shape":7,"type":"IMAGE","link":null},{"localized_name":"image4","name":"image4","shape":7,"type":"IMAGE","link":null},{"localized_name":"frame1 position","name":"frame1 position","shape":7,"type":"STRING","widget":{"name":"frame1 position"},"link":null},{"localized_name":"frame2 position","name":"frame2 position","shape":7,"type":"STRING","widget":{"name":"frame2 position"},"link":null},{"localized_name":"frame3 position","name":"frame3 position","shape":7,"type":"STRING","widget":{"name":"frame3 position"},"link":null},{"localized_name":"frame4 position","name":"frame4 position","shape":7,"type":"STRING","widget":{"name":"frame4 position"},"link":null}],"outputs":[{"localized_name":"Video Inputs Frame Images","name":"Video Inputs Frame Images","type":"RUNWAREVIDEOINPUTSFRAMEIMAGES","links":[3]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"dee0949f78f02adb54037e1df1cc2bf7df7b4bfe","Node name for S&R":"Runware Video Inputs Frame Images"},"widgets_values":["","","",""],"bgcolor":"#5345bf"},{"id":6,"type":"Runware Video Inference Inputs","pos":[-410.7387390136719,994.8055419921875],"size":[320.0390625,290],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"Image","name":"Image","shape":7,"type":"IMAGE","link":null},{"localized_name":"Frame Images","name":"Frame Images","shape":7,"type":"RUNWAREVIDEOINPUTSFRAMEIMAGES","link":3},{"localized_name":"Audio Inputs","name":"Audio Inputs","shape":7,"type":"RUNWAREAUDIOINPUT","link":null},{"localized_name":"Speech Inputs","name":"Speech Inputs","shape":7,"type":"RUNWARESPEECHINPUT","link":null},{"localized_name":"Mask","name":"Mask","shape":7,"type":"IMAGE","link":null},{"localized_name":"Frame","name":"Frame","shape":7,"type":"IMAGE","link":null},{"localized_name":"References","name":"References","shape":7,"type":"RUNWAREVIDEOINPUTSREFERENCEIMAGES","link":null},{"localized_name":"Reference Videos","name":"Reference Videos","shape":7,"type":"RUNWAREREFERENCEVIDEOS","link":null},{"localized_name":"Reference Voices","name":"Reference Voices","shape":7,"type":"RUNWAREREFERENCEVOICES","link":null},{"localized_name":"Audio","name":"Audio","shape":7,"type":"STRING","widget":{"name":"Audio"},"link":null},{"localized_name":"Video","name":"Video","shape":7,"type":"STRING","widget":{"name":"Video"},"link":null},{"localized_name":"draftId","name":"draftId","shape":7,"type":"STRING","widget":{"name":"draftId"},"link":null},{"localized_name":"videoId","name":"videoId","shape":7,"type":"STRING","widget":{"name":"videoId"},"link":null}],"outputs":[{"localized_name":"Video Inference Inputs","name":"Video Inference Inputs","type":"RUNWAREVIDEOINFERENCEINPUTS","links":[6]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"dee0949f78f02adb54037e1df1cc2bf7df7b4bfe","Node name for S&R":"Runware Video Inference Inputs"},"widgets_values":["","","",""],"bgcolor":"#5345bf"},{"id":1,"type":"Runware Video Inference","pos":[-64.3003158569336,610.6160278320312],"size":[400,876],"flags":{},"order":4,"mode":0,"inputs":[{"localized_name":"Model","name":"Model","type":"RUNWAREVIDEOMODEL","link":1},{"localized_name":"frameImages","name":"frameImages","shape":7,"type":"RUNWAREFRAMEIMAGES","link":null},{"localized_name":"referenceImages","name":"referenceImages","shape":7,"type":"RUNWAREREFERENCEIMAGES","link":null},{"localized_name":"providerSettings","name":"providerSettings","shape":7,"type":"RUNWAREPROVIDERSETTINGS","link":null},{"localized_name":"inputAudios","name":"inputAudios","shape":7,"type":"RUNWAREINPUTAUDIOS","link":null},{"localized_name":"referenceVideos","name":"referenceVideos","shape":7,"type":"RUNWAREREFERENCEVIDEOS","link":null},{"localized_name":"inputs","name":"inputs","shape":7,"type":"RUNWAREVIDEOINFERENCEINPUTS","link":6},{"localized_name":"safetyInputs","name":"safetyInputs","shape":7,"type":"RUNWARESAFETYINPUTS","link":null},{"localized_name":"videoAdvancedFeatureInputs","name":"videoAdvancedFeatureInputs","shape":7,"type":"RUNWAREVIDEOADVANCEDFEATUREINPUTS","link":null},{"localized_name":"Accelerator","name":"Accelerator","shape":7,"type":"RUNWAREACCELERATOR","link":null},{"localized_name":"settings","name":"settings","shape":7,"type":"RUNWAREVIDEOSETTINGS","link":null},{"localized_name":"Multi Inference Mode","name":"Multi Inference Mode","type":"BOOLEAN","widget":{"name":"Multi Inference Mode"},"link":null},{"localized_name":"Prompt Weighting","name":"Prompt Weighting","type":"COMBO","widget":{"name":"Prompt Weighting"},"link":null},{"localized_name":"useDuration","name":"useDuration","type":"BOOLEAN","widget":{"name":"useDuration"},"link":null},{"localized_name":"duration","name":"duration","type":"INT","widget":{"name":"duration"},"link":null},{"localized_name":"useFps","name":"useFps","type":"BOOLEAN","widget":{"name":"useFps"},"link":null},{"localized_name":"fps","name":"fps","type":"INT","widget":{"name":"fps"},"link":null},{"localized_name":"outputFormat","name":"outputFormat","type":"COMBO","widget":{"name":"outputFormat"},"link":null},{"localized_name":"useSeed","name":"useSeed","type":"BOOLEAN","widget":{"name":"useSeed"},"link":null},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"useSteps","name":"useSteps","type":"BOOLEAN","widget":{"name":"useSteps"},"link":null},{"localized_name":"steps","name":"steps","type":"INT","widget":{"name":"steps"},"link":null},{"localized_name":"useBatchSize","name":"useBatchSize","type":"BOOLEAN","widget":{"name":"useBatchSize"},"link":null},{"localized_name":"batchSize","name":"batchSize","type":"INT","widget":{"name":"batchSize"},"link":null},{"localized_name":"useSchedulers","name":"useSchedulers","type":"BOOLEAN","widget":{"name":"useSchedulers"},"link":null},{"localized_name":"scheduler","name":"scheduler","type":"COMBO","widget":{"name":"scheduler"},"link":null},{"localized_name":"useCFGScale","name":"useCFGScale","type":"BOOLEAN","widget":{"name":"useCFGScale"},"link":null},{"localized_name":"cfgScale","name":"cfgScale","type":"FLOAT","widget":{"name":"cfgScale"},"link":null},{"localized_name":"acceleration","name":"acceleration","type":"COMBO","widget":{"name":"acceleration"},"link":null},{"localized_name":"positivePrompt","name":"positivePrompt","shape":7,"type":"STRING","widget":{"name":"positivePrompt"},"link":null},{"localized_name":"negativePrompt","name":"negativePrompt","shape":7,"type":"STRING","widget":{"name":"negativePrompt"},"link":null},{"localized_name":"speechVoice","name":"speechVoice","shape":7,"type":"STRING","widget":{"name":"speechVoice"},"link":null},{"localized_name":"speechText","name":"speechText","shape":7,"type":"STRING","widget":{"name":"speechText"},"link":null}],"outputs":[{"localized_name":"VIDEO","name":"VIDEO","type":"VIDEO","links":[2]},{"localized_name":"RW-Task","name":"RW-Task","type":"RUNWARETASK","links":null},{"localized_name":"OUTPUT","name":"OUTPUT","type":"RUNWARETASK","links":null}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"dee0949f78f02adb54037e1df1cc2bf7df7b4bfe","Node name for S&R":"Runware Video Inference"},"widgets_values":[false,"Disabled",true,5,true,24,"mp4",true,1266538428,"randomize",false,20,false,1,false,"euler",false,5,"none","The character in the image turns their head and smiles warmly at the camera.","","",""],"bgcolor":"#5345bf"}],"links":[[1,3,0,1,0,"RUNWAREVIDEOMODEL"],[2,1,0,4,0,"VIDEO"],[3,7,0,6,1,"RUNWAREVIDEOINPUTSFRAMEIMAGES"],[5,8,0,7,0,"IMAGE"],[6,6,0,1,6,"RUNWAREVIDEOINFERENCEINPUTS"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.5596026867057808,"offset":[1236.3994579579808,-363.06274955379973]}},"version":0.4} \ No newline at end of file From 51c36f40ac7a58065706eae18e495f3da6d17b9d Mon Sep 17 00:00:00 2001 From: Sirshendu Ganguly Date: Wed, 25 Feb 2026 22:42:26 -0500 Subject: [PATCH 4/4] quick fixes --- clientlibs/utils.js | 2 +- modules/videoSettings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clientlibs/utils.js b/clientlibs/utils.js index 1a02fea..75cd952 100644 --- a/clientlibs/utils.js +++ b/clientlibs/utils.js @@ -2809,7 +2809,7 @@ function vectorizeModelSearchFilterHandler(vectorizeNode) { } function vectorizeToggleHandler(vectorizeNode) { - const usePositivePromptWidget = vectorizeNode.widgets.find(w => w.name === "Use Positive Prompt"); + const usePositivePromptWidget = vectorizeNode.widgets.find(w => w.name === "Use positivePrompt"); const positivePromptWidget = vectorizeNode.widgets.find(w => w.name === "positivePrompt"); const dimensionsWidget = vectorizeNode.widgets.find(w => w.name === "dimensions"); const widthWidget = vectorizeNode.widgets.find(w => w.name === "width"); diff --git a/modules/videoSettings.py b/modules/videoSettings.py index 3c2e713..fd2c40d 100644 --- a/modules/videoSettings.py +++ b/modules/videoSettings.py @@ -53,7 +53,7 @@ class RunwareVideoSettings: CATEGORY = "Runware" DESCRIPTION = "Configure video inference settings (draft, audio, promptUpsampling) for Runware Video Inference. Connect to Runware Video Inference node." - def createSettings(self, **kwargs) -> tuple: + def createSettings(self, **kwargs) -> tuple[Dict[str, Any]]: """Create settings dict for Video Inference API""" use_draft = kwargs.get("useDraft", False) draft = kwargs.get("draft", False)