Merge pull request #37 from Runware/feature-upscaleAndBackgroundRemovalProviderSettings/OviSupport

Add provider settings support and new input nodes for upscale/background removal
This commit is contained in:
Sirshendu Ganguly
2025-10-28 23:11:35 -04:00
committed by GitHub
25 changed files with 468 additions and 65 deletions
+4
View File
@@ -50,6 +50,8 @@ from .modules.vectorize import vectorize
from .modules.videoBgRemoval import videoBgRemoval
from .modules.videoUpscaler import videoUpscaler
from .modules.videoInputsReferences import videoInputsReferences
from .modules.safetyInputs import safetyInputs
from .modules.videoAdvancedFeatureInputs import videoAdvancedFeatureInputs
RUNWARE_COMFYUI_VERSION = "1.4.0 Beta"
@@ -114,6 +116,8 @@ NODE_CLASS_MAPPINGS = {
"Runware Video Background Removal": videoBgRemoval,
"Runware Video Upscaler": videoUpscaler,
"Runware Video Inputs References": videoInputsReferences,
"Runware Safety Inputs": safetyInputs,
"Runware Video Advanced Feature Inputs": videoAdvancedFeatureInputs,
}
NODE_DISPLAY_NAME_MAPPINGS = {
+30
View File
@@ -85,6 +85,7 @@ const RUNWARE_NODE_TYPES = {
PIXVERSEPROVIDERSETTINGS: "Runware Pixverse Provider Settings",
OPENAIPROVIDERSETTINGS: "Runware OpenAI Provider Settings",
BYTEDANCEPROVIDERSETTINGS: "Runware Bytedance Provider Settings",
BRIAPROVIDERSETTINGS: "Runware Bria Provider Settings",
ELEVENLABSPROVIDERSETTINGS: "Runware ElevenLabs Provider Settings",
ELEVENLABSPROVIDERSETTINGSSECTIONS: "Runware ElevenLabs Provider Settings Sections",
VIDUPROVIDERSETTINGS: "Runware Vidu Provider Settings",
@@ -97,6 +98,11 @@ const RUNWARE_NODE_TYPES = {
VIDEOBGREMOVAL: "Runware Video Background Removal",
VIDEOUPSCALER: "Runware Video Upscaler",
VIDEOINPUTSREFERENCES: "Runware Video Inputs References",
ACCELERATOROPTIONS: "Runware Accelerator Options",
VIDEOTRANSCRIPTION: "Runware Video Transcription",
MINIMAXPROVIDERSETTINGS: "Runware MiniMax Provider Settings",
SAFETYINPUTS: "Runware Safety Inputs",
VIDEOADVANCEDFEATUREINPUTS: "Runware Video Advanced Feature Inputs",
};
const RUNWARE_NODE_PROPS = {
@@ -251,6 +257,10 @@ const RUNWARE_NODE_PROPS = {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.BRIAPROVIDERSETTINGS]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.ELEVENLABSPROVIDERSETTINGS]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
@@ -296,6 +306,26 @@ const RUNWARE_NODE_PROPS = {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.ACCELERATOROPTIONS]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.VIDEOTRANSCRIPTION]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.MINIMAXPROVIDERSETTINGS]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.SAFETYINPUTS]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.VIDEOADVANCEDFEATUREINPUTS]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
};
export {
+78 -42
View File
@@ -11,9 +11,13 @@ class acceleratorOptions:
"tooltip": "Enable Frame Buffer Cache for faster generation",
"default": None,
}),
"useCacheDistance": ("BOOLEAN", {
"tooltip": "Enable to include cacheDistance parameter in API request.",
"default": False,
}),
"cacheDistance": ("FLOAT", {
"tooltip": "Cache distance parameter for FBCache",
"default": None,
"default": 0.0,
"min": 0.0,
"max": 1.0,
"step": 0.01,
@@ -24,9 +28,13 @@ class acceleratorOptions:
"tooltip": "Enable TeaCache for transformer-based models (Flux, SD3). Does not work with UNet models like SDXL or SD1.5. Particularly effective for iterative editing workflows.",
"default": None,
}),
"useTeaCacheDistance": ("BOOLEAN", {
"tooltip": "Enable to include teaCacheDistance parameter in API request.",
"default": False,
}),
"teaCacheDistance": ("FLOAT", {
"tooltip": "Controls TeaCache aggressiveness: 0.0 (conservative/quality) to 1.0 (aggressive/speed). Lower values maintain quality, higher values prioritize speed.",
"default": None,
"default": 0.0,
"min": 0.0,
"max": 1.0,
"step": 0.01,
@@ -37,47 +45,65 @@ class acceleratorOptions:
"tooltip": "Enable DeepCache for UNet-based models (SDXL, SD1.5). Not applicable to transformer models. Provides performance improvements for high-throughput scenarios.",
"default": None,
}),
"useDeepCacheOptions": ("BOOLEAN", {
"tooltip": "Enable to include DeepCache options (deepCacheInterval and deepCacheBranchId) in API request.",
"default": False,
}),
"deepCacheInterval": ("INT", {
"tooltip": "Frequency of feature caching - steps between cache operations. Larger values = faster but may impact quality. Smaller values = better quality but slower.",
"default": None,
"default": 1,
"min": 1,
"max": 20,
}),
"deepCacheBranchId": ("INT", {
"tooltip": "Network branch for caching (0=shallowest, deeper=more conservative). Lower IDs = aggressive caching/faster, higher IDs = conservative caching/better quality.",
"default": None,
"default": 0,
"min": 0,
"max": 10,
}),
# Cache step control parameters
# Cache step control parameters (step numbers)
"useCacheSteps": ("BOOLEAN", {
"tooltip": "Enable to include cache step control parameters (step numbers) in API request.",
"default": False,
}),
"cacheStartStep": ("INT", {
"tooltip": "Inference step number where caching begins (0 to total steps). Alternative to cacheStartStepPercentage.",
"default": None,
"tooltip": "Inference step number where caching begins (0 to total steps). Only included when useCacheSteps is enabled and value > 0.",
"default": 0,
"min": 0,
"max": 200,
}),
"cacheEndStep": ("INT", {
"tooltip": "Inference step number where caching stops (must be > cacheStartStep). Only included when useCacheSteps is enabled.",
"default": 1,
"min": 1,
"max": 200,
}),
# Cache step control parameters (percentages)
"useCachePercentageSteps": ("BOOLEAN", {
"tooltip": "Enable to include cache step control parameters (percentages) in API request.",
"default": False,
}),
"cacheStartStepPercentage": ("INT", {
"tooltip": "Percentage of total steps where caching begins (0-99). Alternative to cacheStartStep.",
"default": None,
"tooltip": "Percentage of total steps where caching begins (0-99). Only included when useCachePercentageSteps is enabled and value > 0.",
"default": 0,
"min": 0,
"max": 99,
}),
"cacheEndStep": ("INT", {
"tooltip": "Inference step number where caching stops (must be > cacheStartStep). Alternative to cacheEndStepPercentage.",
"default": None,
"min": 1,
"max": 200,
}),
"cacheEndStepPercentage": ("INT", {
"tooltip": "Percentage of total steps where caching stops (must be > cacheStartStepPercentage). Alternative to cacheEndStep.",
"default": None,
"tooltip": "Percentage of total steps where caching stops (must be > cacheStartStepPercentage). Only included when useCachePercentageSteps is enabled.",
"default": 1,
"min": 1,
"max": 100,
}),
"useCacheMaxConsecutiveSteps": ("BOOLEAN", {
"tooltip": "Enable to include cacheMaxConsecutiveSteps parameter in API request.",
"default": False,
}),
"cacheMaxConsecutiveSteps": ("INT", {
"tooltip": "Max consecutive steps using cached computations before forcing fresh computation. Prevents quality degradation from extended cache reuse.",
"default": None,
"default": 1,
"min": 1,
"max": 5,
}),
@@ -93,51 +119,61 @@ class acceleratorOptions:
def acceleratorOptions(self, **kwargs):
# Get all optional parameters
fbcache = kwargs.get("fbcache")
cacheDistance = kwargs.get("cacheDistance")
useCacheDistance = kwargs.get("useCacheDistance", False)
cacheDistance = kwargs.get("cacheDistance", 0.0)
teaCache = kwargs.get("teaCache")
teaCacheDistance = kwargs.get("teaCacheDistance")
useTeaCacheDistance = kwargs.get("useTeaCacheDistance", False)
teaCacheDistance = kwargs.get("teaCacheDistance", 0.0)
deepCache = kwargs.get("deepCache")
deepCacheInterval = kwargs.get("deepCacheInterval")
deepCacheBranchId = kwargs.get("deepCacheBranchId")
cacheStartStep = kwargs.get("cacheStartStep")
cacheStartStepPercentage = kwargs.get("cacheStartStepPercentage")
cacheEndStep = kwargs.get("cacheEndStep")
cacheEndStepPercentage = kwargs.get("cacheEndStepPercentage")
cacheMaxConsecutiveSteps = kwargs.get("cacheMaxConsecutiveSteps")
# Get toggle and value parameters
useDeepCacheOptions = kwargs.get("useDeepCacheOptions", False)
deepCacheInterval = kwargs.get("deepCacheInterval", 1)
deepCacheBranchId = kwargs.get("deepCacheBranchId", 0)
useCacheSteps = kwargs.get("useCacheSteps", False)
cacheStartStep = kwargs.get("cacheStartStep", 0)
cacheEndStep = kwargs.get("cacheEndStep", 1)
useCachePercentageSteps = kwargs.get("useCachePercentageSteps", False)
cacheStartStepPercentage = kwargs.get("cacheStartStepPercentage", 0)
cacheEndStepPercentage = kwargs.get("cacheEndStepPercentage", 1)
useCacheMaxConsecutiveSteps = kwargs.get("useCacheMaxConsecutiveSteps", False)
cacheMaxConsecutiveSteps = kwargs.get("cacheMaxConsecutiveSteps", 1)
# Build accelerator options dictionary
acceleratorOptions = {}
# FBCache options
if fbcache is not None:
if fbcache is True:
acceleratorOptions["fbcache"] = fbcache
if cacheDistance is not None:
if useCacheDistance:
acceleratorOptions["cacheDistance"] = cacheDistance
# TeaCache options
if teaCache is not None:
if teaCache is True:
acceleratorOptions["teaCache"] = teaCache
if teaCacheDistance is not None:
if useTeaCacheDistance:
acceleratorOptions["teaCacheDistance"] = teaCacheDistance
# DeepCache options
if deepCache is not None:
if deepCache is True:
acceleratorOptions["deepCache"] = deepCache
if deepCacheInterval is not None:
if useDeepCacheOptions:
acceleratorOptions["deepCacheInterval"] = deepCacheInterval
if deepCacheBranchId is not None:
acceleratorOptions["deepCacheBranchId"] = deepCacheBranchId
# Cache step control options
if cacheStartStep is not None:
acceleratorOptions["cacheStartStep"] = cacheStartStep
if cacheStartStepPercentage is not None:
acceleratorOptions["cacheStartStepPercentage"] = cacheStartStepPercentage
if cacheEndStep is not None:
# Cache step control options (step numbers)
if useCacheSteps:
if cacheStartStep > 0:
acceleratorOptions["cacheStartStep"] = cacheStartStep
acceleratorOptions["cacheEndStep"] = cacheEndStep
if cacheEndStepPercentage is not None:
# Cache step control options (percentages)
if useCachePercentageSteps:
if cacheStartStepPercentage > 0:
acceleratorOptions["cacheStartStepPercentage"] = cacheStartStepPercentage
acceleratorOptions["cacheEndStepPercentage"] = cacheEndStepPercentage
if cacheMaxConsecutiveSteps is not None:
if useCacheMaxConsecutiveSteps:
acceleratorOptions["cacheMaxConsecutiveSteps"] = cacheMaxConsecutiveSteps
return (acceleratorOptions,)
+53 -1
View File
@@ -1,9 +1,11 @@
from .utils import runwareUtils as rwUtils
import json
class bgremoval:
RUNWARE_RMBG_MODELS = {
"RemBG 1.4": "runware:109@1",
"Bria RMBG 2.0": "runware:110@1",
"Bria RMBG v2.0": "bria:2@1",
"BiRefNet v1 Base": "runware:112@1",
"BiRefNet v1 Base - COD": "runware:112@2",
"BiRefNet Dis": "runware:112@3",
@@ -64,6 +66,15 @@ class bgremoval:
"min": 1,
"max": 255,
}),
"safetyInputs": ("RUNWARESAFETYINPUTS", {
"tooltip": "Connect Runware Safety Inputs node to configure safety and content moderation settings.",
}),
"Accelerator": ("RUNWAREACCELERATOR", {
"tooltip": "Connect a Runware Accelerator Options Node to configure caching and acceleration settings.",
}),
"providerSettings": ("RUNWAREPROVIDERSETTINGS", {
"tooltip": "Connect a Runware Provider Settings node to configure provider-specific parameters.",
}),
**rwUtils.RUNWARE_REMBG_OUTPUT_FORMATS,
}
}
@@ -83,6 +94,9 @@ class bgremoval:
alphaMattingBackgroundThreshold = kwargs.get("Alpha Matting Background Threshold", 10)
alphaMattingErodeSize = kwargs.get("Alpha Matting Erode Size", 10)
outputFormat = kwargs.get("outputFormat", "WEBP")
safetyInputs = kwargs.get("safetyInputs", None)
runwareAccelerator = kwargs.get("Accelerator", None)
providerSettings = kwargs.get("providerSettings", None)
modelAIR = self.RUNWARE_RMBG_MODELS.get(modelName, "runware:109@1")
includeExtraSettings = postProcessMask or returnOnlyMask or alphaMatting
@@ -113,7 +127,45 @@ class bgremoval:
settings["alphaMattingBackgroundThreshold"] = alphaMattingBackgroundThreshold
settings["alphaMattingErodeSize"] = alphaMattingErodeSize
genConfig["settings"] = settings
# Add safety inputs if provided
if safetyInputs is not None and isinstance(safetyInputs, dict) and len(safetyInputs) > 0:
genConfig["safety"] = safetyInputs
# Add accelerator options if provided
if runwareAccelerator is not None and isinstance(runwareAccelerator, dict) and len(runwareAccelerator) > 0:
genConfig["acceleratorOptions"] = runwareAccelerator
# Handle providerSettings - extract provider name from model and merge with custom settings
if providerSettings is not None:
# Extract provider name from model (e.g., "bria:2@1" -> "bria", "runware:109@1" -> "runware")
provider_name = modelAIR.split(":")[0] if ":" in modelAIR else "runware"
# If providerSettings is a dictionary, create the correct API format
if isinstance(providerSettings, dict):
# Create the providerSettings object with provider name as key
final_provider_settings = {
provider_name: providerSettings
}
genConfig["providerSettings"] = final_provider_settings
print(f"[Debugging] Provider settings: {final_provider_settings}")
else:
# If it's just a string, use it directly
genConfig["providerSettings"] = providerSettings
genResult = rwUtils.inferenecRequest([genConfig])
# Debug: Print the request being sent
print(f"[DEBUG] Sending Background Removal Request:", flush=True)
print(f"[DEBUG] Request Payload: {json.dumps([genConfig], indent=2)}", flush=True)
try:
genResult = rwUtils.inferenecRequest([genConfig])
# Debug: Print the response received
print(f"[DEBUG] Received Background Removal Response:", flush=True)
print(f"[DEBUG] Response: {json.dumps(genResult, indent=2)}", flush=True)
except Exception as e:
print(f"[DEBUG] Error in Background Removal Request: {str(e)}", flush=True)
raise
images = rwUtils.convertImageB64List(genResult)
return (images, )
+13 -2
View File
@@ -14,7 +14,7 @@ class RunwareBriaProviderSettings:
return {
"required": {},
"optional": {
"medium": (["photography", "art"], {
"medium": (["None", "photography", "art"], {
"tooltip": "Select the medium type for image generation",
"default": "photography",
}),
@@ -48,6 +48,12 @@ class RunwareBriaProviderSettings:
"label_on": "Enabled",
"label_off": "Disabled",
}),
"preserveAlpha": ("BOOLEAN", {
"tooltip": "Preserve alpha channel in the image.",
"default": None,
"label_on": "Enabled",
"label_off": "Disabled",
}),
}
}
@@ -67,12 +73,13 @@ class RunwareBriaProviderSettings:
promptContentModeration = kwargs.get("promptContentModeration", True)
contentModeration = kwargs.get("contentModeration", True)
ipSignal = kwargs.get("ipSignal", False)
preserveAlpha = kwargs.get("preserveAlpha", None)
# Build settings dictionary
settings = {}
# Add medium
if medium is not None:
if medium is not None and medium != "None":
settings["medium"] = medium
# Add promptEnhancement
@@ -95,6 +102,10 @@ class RunwareBriaProviderSettings:
if ipSignal is not None:
settings["ipSignal"] = ipSignal
# Add preserveAlpha
if preserveAlpha is not None:
settings["preserveAlpha"] = preserveAlpha
# Clean up None values
settings = {k: v for k, v in settings.items() if v is not None}
+73
View File
@@ -0,0 +1,73 @@
from typing import Optional, Dict, Any
class safetyInputs:
"""Runware Safety Inputs Node"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {},
"optional": {
"mode": (["none", "fast", "full"], {
"tooltip": "Safety moderation mode: none (disable), fast (quick check), or full (comprehensive check).",
"default": "none",
}),
"tolerance": ("BOOLEAN", {
"tooltip": "Safety tolerance setting for content moderation.",
"default": None,
"label_on": "Enabled",
"label_off": "Disabled",
}),
"checkInputs": ("BOOLEAN", {
"tooltip": "Enable checking of input content for safety violations.",
"default": None,
"label_on": "Enabled",
"label_off": "Disabled",
}),
"checkContent": ("BOOLEAN", {
"tooltip": "Enable checking of generated content for safety violations.",
"default": None,
"label_on": "Enabled",
"label_off": "Disabled",
}),
}
}
RETURN_TYPES = ("RUNWARESAFETYINPUTS",)
RETURN_NAMES = ("Safety Inputs",)
FUNCTION = "create_safety_inputs"
CATEGORY = "Runware"
DESCRIPTION = "Configure safety and content moderation settings for Runware tasks."
def create_safety_inputs(self, **kwargs) -> tuple[Dict[str, Any]]:
"""Create safety inputs dictionary"""
# Get parameters
mode = kwargs.get("mode", None)
tolerance = kwargs.get("tolerance", None)
checkInputs = kwargs.get("checkInputs", None)
checkContent = kwargs.get("checkContent", None)
# Build safety inputs dictionary - only include non-None values
safety_inputs = {}
if mode is not None:
safety_inputs["mode"] = mode
if tolerance is not None:
safety_inputs["tolerance"] = tolerance
if checkInputs is not None:
safety_inputs["checkInputs"] = checkInputs
if checkContent is not None:
safety_inputs["checkContent"] = checkContent
return (safety_inputs,)
# Node class mappings
NODE_CLASS_MAPPINGS = {
"RunwareSafetyInputs": safetyInputs,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RunwareSafetyInputs": "Runware Safety Inputs",
}
+53 -2
View File
@@ -1,4 +1,5 @@
from .utils import runwareUtils as rwUtils
import json
class upscaler:
@classmethod
@@ -18,7 +19,7 @@ class upscaler:
},
"optional": {
"model": ("STRING", {
"tooltip": "Model AIR ID (runware:500@1, runware:501@1, runware:502@1, runware:503@1)",
"tooltip": "Model AIR ID (runware:500@1, runware:501@1, runware:502@1, runware:503@1, bria:52@1)",
"default": "",
}),
# Common parameters toggles
@@ -113,6 +114,15 @@ class upscaler:
"min": 0,
"max": 2,
}),
"safetyInputs": ("RUNWARESAFETYINPUTS", {
"tooltip": "Connect Runware Safety Inputs node to configure safety and content moderation settings.",
}),
"Accelerator": ("RUNWAREACCELERATOR", {
"tooltip": "Connect a Runware Accelerator Options Node to configure caching and acceleration settings.",
}),
"providerSettings": ("RUNWAREPROVIDERSETTINGS", {
"tooltip": "Connect a Runware Provider Settings node to configure provider-specific parameters.",
}),
},
}
@@ -147,6 +157,9 @@ class upscaler:
colorFix = kwargs.get("colorFix", False)
tileDiffusion = kwargs.get("tileDiffusion", False)
clipSkip = kwargs.get("clipSkip", 0)
safetyInputs = kwargs.get("safetyInputs", None)
runwareAccelerator = kwargs.get("Accelerator", None)
providerSettings = kwargs.get("providerSettings", None)
# Build the base configuration
genConfig = {
@@ -197,7 +210,45 @@ class upscaler:
# Add settings to config if any settings were specified
if settings:
genConfig["settings"] = settings
# Add safety inputs if provided
if safetyInputs is not None and isinstance(safetyInputs, dict) and len(safetyInputs) > 0:
genConfig["safety"] = safetyInputs
# Add accelerator options if provided
if runwareAccelerator is not None and isinstance(runwareAccelerator, dict) and len(runwareAccelerator) > 0:
genConfig["acceleratorOptions"] = runwareAccelerator
# Handle providerSettings - extract provider name from model and merge with custom settings
if providerSettings is not None:
# Extract provider name from model (e.g., "runware:500@1" -> "runware")
provider_name = model.split(":")[0] if ":" in model and model else "runware"
# If providerSettings is a dictionary, create the correct API format
if isinstance(providerSettings, dict):
# Create the providerSettings object with provider name as key
final_provider_settings = {
provider_name: providerSettings
}
genConfig["providerSettings"] = final_provider_settings
print(f"[Debugging] Provider settings: {final_provider_settings}")
else:
# If it's just a string, use it directly
genConfig["providerSettings"] = providerSettings
genResult = rwUtils.inferenecRequest([genConfig])
# Debug: Print the request being sent
print(f"[DEBUG] Sending Image Upscale Request:", flush=True)
print(f"[DEBUG] Request Payload: {json.dumps([genConfig], indent=2)}", flush=True)
try:
genResult = rwUtils.inferenecRequest([genConfig])
# Debug: Print the response received
print(f"[DEBUG] Received Image Upscale Response:", flush=True)
print(f"[DEBUG] Response: {json.dumps(genResult, indent=2)}", flush=True)
except Exception as e:
print(f"[DEBUG] Error in Image Upscale Request: {str(e)}", flush=True)
raise
images = rwUtils.convertImageB64List(genResult)
return (images, )
+84
View File
@@ -0,0 +1,84 @@
from typing import Optional, Dict, Any
class videoAdvancedFeatureInputs:
"""Runware Video Advanced Feature Inputs Node"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {},
"optional": {
"videoCFGScale": ("FLOAT", {
"tooltip": "CFG scale for video generation.",
"default": None,
"min": 0.0,
"max": 30.0,
"step": 0.1,
}),
"audioCFGScale": ("FLOAT", {
"tooltip": "CFG scale for audio generation.",
"default": None,
"min": 0.0,
"max": 30.0,
"step": 0.1,
}),
"videoNegativePrompt": ("STRING", {
"tooltip": "Negative prompt for video generation.",
"multiline": True,
"default": "",
}),
"audioNegativePrompt": ("STRING", {
"tooltip": "Negative prompt for audio generation.",
"multiline": True,
"default": "",
}),
"slgLayer": ("INT", {
"tooltip": "SLG layer setting.",
"default": None,
"min": 0,
"max": 100,
}),
}
}
RETURN_TYPES = ("RUNWAREVIDEOADVANCEDFEATUREINPUTS",)
RETURN_NAMES = ("Video Advanced Feature Inputs",)
FUNCTION = "create_advanced_feature_inputs"
CATEGORY = "Runware"
DESCRIPTION = "Configure advanced video feature inputs including CFG scales, negative prompts, and SLG layer settings."
def create_advanced_feature_inputs(self, **kwargs) -> tuple[Dict[str, Any]]:
"""Create video advanced feature inputs dictionary"""
# Get parameters
videoCFGScale = kwargs.get("videoCFGScale", None)
audioCFGScale = kwargs.get("audioCFGScale", None)
videoNegativePrompt = kwargs.get("videoNegativePrompt", None)
audioNegativePrompt = kwargs.get("audioNegativePrompt", None)
slgLayer = kwargs.get("slgLayer", None)
# Build advanced feature inputs dictionary - only include non-None values
advanced_inputs = {}
if videoCFGScale is not None:
advanced_inputs["videoCFGScale"] = videoCFGScale
if audioCFGScale is not None:
advanced_inputs["audioCFGScale"] = audioCFGScale
if videoNegativePrompt is not None and videoNegativePrompt.strip() != "":
advanced_inputs["videoNegativePrompt"] = videoNegativePrompt.strip()
if audioNegativePrompt is not None and audioNegativePrompt.strip() != "":
advanced_inputs["audioNegativePrompt"] = audioNegativePrompt.strip()
if slgLayer is not None:
advanced_inputs["slgLayer"] = slgLayer
return (advanced_inputs,)
# Node class mappings
NODE_CLASS_MAPPINGS = {
"RunwareVideoAdvancedFeatureInputs": videoAdvancedFeatureInputs,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RunwareVideoAdvancedFeatureInputs": "Runware Video Advanced Feature Inputs",
}
+50 -4
View File
@@ -42,6 +42,10 @@ class txt2vid:
"max": 1920,
"step": 1,
}),
"useDuration": ("BOOLEAN", {
"tooltip": "Enable to include duration parameter in API request. Disable if your model doesn't support duration.",
"default": True,
}),
"duration": ("INT", {
"tooltip": "The duration of the video in seconds.",
"default": 5,
@@ -72,6 +76,16 @@ class txt2vid:
"min": 1,
"max": 9223372036854776000,
}),
"useSteps": ("BOOLEAN", {
"tooltip": "Enable to include steps parameter in API request. Disable if your model doesn't support steps.",
"default": False,
}),
"steps": ("INT", {
"tooltip": "Number of inference steps for video generation. More steps generally result in higher quality but longer generation time.",
"default": 20,
"min": 1,
"max": 100,
}),
"batchSize": ("INT", {
"tooltip": "The number of videos to generate in a single request.",
"default": 1,
@@ -115,6 +129,15 @@ class txt2vid:
"inputs": ("RUNWAREVIDEOINFERENCEINPUTS", {
"tooltip": "Connect a Runware Video Inference Inputs node to provide custom inputs like image, audio, mask, and parameters for OmniHuman 1.5 and other video models.",
}),
"safetyInputs": ("RUNWARESAFETYINPUTS", {
"tooltip": "Connect Runware Safety Inputs node to configure safety and content moderation settings.",
}),
"videoAdvancedFeatureInputs": ("RUNWAREVIDEOADVANCEDFEATUREINPUTS", {
"tooltip": "Connect Runware Video Advanced Feature Inputs node to configure advanced video features like CFG scales, FPS, negative prompts, and SLG layer settings.",
}),
"Accelerator": ("RUNWAREACCELERATOR", {
"tooltip": "Connect a Runware Accelerator Options Node to configure caching and acceleration settings.",
}),
}
}
@@ -149,9 +172,13 @@ class txt2vid:
speechVoice = kwargs.get("speechVoice", None)
speechText = kwargs.get("speechText", None)
inputs = kwargs.get("inputs", None)
safetyInputs = kwargs.get("safetyInputs", None)
videoAdvancedFeatureInputs = kwargs.get("videoAdvancedFeatureInputs", None)
runwareAccelerator = kwargs.get("Accelerator", None)
useCustomDimensions = kwargs.get("useCustomDimensions", False)
customWidth = kwargs.get("width", 864)
customHeight = kwargs.get("height", 480)
useDuration = kwargs.get("useDuration", True)
duration = kwargs.get("duration", 5)
fps = kwargs.get("fps", 24)
useFps = kwargs.get("useFps", True)
@@ -159,6 +186,8 @@ class txt2vid:
batchSize = kwargs.get("batchSize", 1)
seed = kwargs.get("seed", 1)
useSeed = kwargs.get("useSeed", True)
steps = kwargs.get("steps", 20)
useSteps = kwargs.get("useSteps", False)
# Handle model input - could be dict or string
if isinstance(runwareVideoModel, dict):
@@ -181,14 +210,15 @@ class txt2vid:
{
"taskType": "videoInference",
"taskUUID": rwUtils.genRandUUID(),
"height": height,
"width": width,
"model": model,
"outputFormat": outputFormat,
"numberResults": batchSize,
"includeCost": True,
}
]
if height!=0 and width!=0:
genConfig[0]['height'] = height
genConfig[0]['width'] = width
# Only add positivePrompt if it's not empty
if positivePrompt and positivePrompt.strip() != "":
@@ -199,12 +229,16 @@ class txt2vid:
genConfig[0]["fps"] = fps
# Add duration parameter - unified for all models
genConfig[0]["duration"] = duration
if useDuration:
genConfig[0]["duration"] = duration
# Add seed parameter only if enabled
if useSeed:
genConfig[0]["seed"] = seed
# Add steps parameter only if enabled
if useSteps:
genConfig[0]["steps"] = steps
if (negativePrompt is not None and negativePrompt != ""):
genConfig[0]["negativePrompt"] = negativePrompt
@@ -273,6 +307,18 @@ class txt2vid:
else:
# If it's just a string, use it directly
genConfig[0]["providerSettings"] = providerSettings
# Add safety inputs if provided
if safetyInputs is not None and isinstance(safetyInputs, dict) and len(safetyInputs) > 0:
genConfig[0]["safetyInputs"] = safetyInputs
# Add video advanced feature inputs if provided
if videoAdvancedFeatureInputs is not None and isinstance(videoAdvancedFeatureInputs, dict) and len(videoAdvancedFeatureInputs) > 0:
genConfig[0]["advancedFeatures"] = videoAdvancedFeatureInputs
# Add accelerator options if provided
if runwareAccelerator is not None and isinstance(runwareAccelerator, dict) and len(runwareAccelerator) > 0:
genConfig[0]["acceleratorOptions"] = runwareAccelerator
if (multiInferenceMode):
return (None, genConfig)
+8
View File
@@ -15,6 +15,9 @@ class videoInferenceInputs:
"Mask": ("IMAGE", {
"tooltip": "Mask image to specify a specific subject in the image to speak. Use white/black mask format."
}),
"Frame": ("IMAGE", {
"tooltip": "Frame image for video generation. Connect a Load Image node to provide the frame image."
}),
"References": ("RUNWAREVIDEOINPUTSREFERENCES", {
"tooltip": "Connect the Video Inputs References node to provide reference images."
}),
@@ -31,6 +34,7 @@ class videoInferenceInputs:
image = kwargs.get("Image", None)
audio = kwargs.get("Audio", None)
mask = kwargs.get("Mask", None)
frame = kwargs.get("Frame", None)
references = kwargs.get("References", None)
inputs = {}
@@ -46,6 +50,10 @@ class videoInferenceInputs:
mask_uuid = rwUtils.convertTensor2IMG(mask)
inputs["mask"] = mask_uuid
if frame is not None:
frame_uuid = rwUtils.convertTensor2IMG(frame)
inputs["frame"] = frame_uuid
if references is not None and len(references) > 0:
inputs["references"] = references
+8 -1
View File
@@ -58,6 +58,9 @@ class videoModelSearch:
"lightricks:2@0 (LTX Fast)",
"lightricks:2@1 (LTX Pro)",
],
"Ovi": [
"runware:190@1 (Ovi)",
],
}
# Model dimensions mapping
@@ -118,6 +121,9 @@ class videoModelSearch:
# Lightricks Models
"lightricks:2@0": {"width": 1920, "height": 1080}, # Lightricks v2.0 Fast
"lightricks:2@1": {"width": 1920, "height": 1080}, # Lightricks v2.1 Pro
# Ovi Models
"runware:190@1": {"width": 0, "height": 0}, # Ovi
}
@@ -143,7 +149,8 @@ class videoModelSearch:
"Vidu",
"Wan",
"OpenAI",
"Lightricks"
"Lightricks",
"Ovi"
], {
"tooltip": "Choose Video Model Architecture To Filter Results.",
"default": "KlingAI",
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long