add suport for ACE audio model and Recraft V4 image model

This commit is contained in:
Sirshendu Ganguly
2026-02-17 14:33:42 -05:00
parent a854323c08
commit 6772870a8d
11 changed files with 294 additions and 10 deletions
+6
View File
@@ -37,6 +37,7 @@ from .modules.audioInference import RunwareAudioInference
from .modules.audioModelSearch import RunwareAudioModelSearch
from .modules.audioSections import RunwareAudioSections
from .modules.audioInferenceInputs import audioInferenceInputs
from .modules.audioSettings import RunwareAudioSettings
from .modules.providerSettings.elevenlabsProviderSettings import RunwareElevenLabsProviderSettings
from .modules.providerSettings.elevenlabsProviderSettingsSections import RunwareElevenLabsProviderSettingsSections
from .modules.acceleratorOptions import acceleratorOptions
@@ -63,6 +64,8 @@ from .modules.providerSettings.alibabaProviderSettings import RunwareAlibabaProv
from .modules.providerSettings.googleProviderSettings import RunwareGoogleProviderSettings
from .modules.providerSettings.blackForestProviderSettings import RunwareBlackForestProviderSettings
from .modules.providerSettings.xaiProviderSettings import RunwareXAIProviderSettings
from .modules.providerSettings.recraftProviderSettings import RunwareRecraftProviderSettings
from .modules.providerSettings.recraftProviderSettingsColor import RunwareRecraftColor
from .modules.providerSettings.sourcefulProviderSettings import RunwareSourcefulProviderSettings
from .modules.providerSettings.sourcefulProviderSettingsFonts import RunwareSourcefulProviderSettingsFonts
from .modules.ultralyticsInputs import RunwareUltralyticsInputs
@@ -138,6 +141,7 @@ NODE_CLASS_MAPPINGS = {
"Runware Audio Model Search": RunwareAudioModelSearch,
"Runware Audio Sections": RunwareAudioSections,
"Runware Audio Inference Inputs": audioInferenceInputs,
"Runware Audio Settings": RunwareAudioSettings,
"Runware ElevenLabs Provider Settings": RunwareElevenLabsProviderSettings,
"Runware ElevenLabs Provider Settings Sections": RunwareElevenLabsProviderSettingsSections,
"Runware Accelerator Options": acceleratorOptions,
@@ -164,6 +168,8 @@ NODE_CLASS_MAPPINGS = {
"Runware Google Provider Settings": RunwareGoogleProviderSettings,
"Runware BlackForest Labs Provider Settings": RunwareBlackForestProviderSettings,
"Runware xAI Provider Settings": RunwareXAIProviderSettings,
"Runware Recraft Provider Settings": RunwareRecraftProviderSettings,
"Runware Provider Settings Recraft Color": RunwareRecraftColor,
"Runware Sourceful Provider Settings": RunwareSourcefulProviderSettings,
"Runware Sourceful Provider Settings Fonts": RunwareSourcefulProviderSettingsFonts,
"Runware Image Inference Ultralytics": RunwareUltralyticsInputs,
+12
View File
@@ -82,6 +82,7 @@ const RUNWARE_NODE_TYPES = {
AUDIOMODELSEARCH: "Runware Audio Model Search",
AUDIOSECTIONS: "Runware Audio Sections",
AUDIOINFERENCEINPUTS: "Runware Audio Inference Inputs",
AUDIOSETTINGS: "Runware Audio Settings",
PIXVERSEPROVIDERSETTINGS: "Runware Pixverse Provider Settings",
OPENAIPROVIDERSETTINGS: "Runware OpenAI Provider Settings",
BYTEDANCEPROVIDERSETTINGS: "Runware Bytedance Provider Settings",
@@ -109,6 +110,8 @@ const RUNWARE_NODE_TYPES = {
ALIBABAPROVIDERSETTINGS: "Runware Alibaba Provider Settings",
BLACKFORESTPROVIDERSETTINGS: "Runware BlackForest Labs Provider Settings",
XAIPROVIDERSETTINGS: "Runware xAI Provider Settings",
RECRAFTPROVIDERSETTINGS: "Runware Recraft Provider Settings",
RECRAFTCOLOR: "Runware Provider Settings Recraft Color",
SOURCEFULPROVIDERSETTINGS: "Runware Sourceful Provider Settings",
SOURCEFULPROVIDERSETTINGSFONTS: "Runware Sourceful Provider Settings Fonts",
ULTRALYTICSINPUTS: "Runware Image Inference Ultralytics",
@@ -387,6 +390,12 @@ const RUNWARE_NODE_PROPS = {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.RECRAFTPROVIDERSETTINGS]: {
bgColor: DEFAULT_BGCOLOR,
},
[RUNWARE_NODE_TYPES.RECRAFTCOLOR]: {
bgColor: DEFAULT_BGCOLOR,
},
[RUNWARE_NODE_TYPES.SOURCEFULPROVIDERSETTINGS]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
@@ -432,6 +441,9 @@ const RUNWARE_NODE_PROPS = {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.AUDIOSETTINGS]: {
bgColor: DEFAULT_BGCOLOR,
},
[RUNWARE_NODE_TYPES.ACCELERATOROPTIONS]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
+29 -1
View File
@@ -772,6 +772,9 @@ function useParameterToggleHandler(node) {
// Audio Inference
"usePositivePrompt": ["positivePrompt"],
"useSeed": ["seed"],
"useSteps": ["steps"],
"useStrength": ["strength"],
// Accelerator Options
"useCacheDistance": ["cacheDistance"],
@@ -801,6 +804,10 @@ function useParameterToggleHandler(node) {
[RUNWARE_NODE_TYPES.UPSCALER]: {
"useCFGScale": ["CFGScale"],
},
// Audio Inference uses CFGScale (capital C)
[RUNWARE_NODE_TYPES.AUDIOINFERENCE]: {
"useCFGScale": ["CFGScale"],
},
};
// Wait for widgets to be ready
@@ -1031,9 +1038,15 @@ function audioInferenceToggleHandler(audioInferenceNode) {
const sampleRateWidget = audioInferenceNode.widgets.find(w => w.name === "sampleRate");
const useBitrateWidget = audioInferenceNode.widgets.find(w => w.name === "useBitrate");
const bitrateWidget = audioInferenceNode.widgets.find(w => w.name === "bitrate");
const useSeedWidget = audioInferenceNode.widgets.find(w => w.name === "useSeed");
const seedWidget = audioInferenceNode.widgets.find(w => w.name === "seed");
const useStepsWidget = audioInferenceNode.widgets.find(w => w.name === "useSteps");
const stepsWidget = audioInferenceNode.widgets.find(w => w.name === "steps");
const useStrengthWidget = audioInferenceNode.widgets.find(w => w.name === "useStrength");
const strengthWidget = audioInferenceNode.widgets.find(w => w.name === "strength");
const useCFGScaleWidget = audioInferenceNode.widgets.find(w => w.name === "useCFGScale");
const CFGScaleWidget = audioInferenceNode.widgets.find(w => w.name === "CFGScale");
// Helper function to toggle widget enabled state (exact same pattern)
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
@@ -1092,9 +1105,21 @@ function audioInferenceToggleHandler(audioInferenceNode) {
toggleWidgetState(useBitrateWidget, bitrateWidget, "bitrate");
}
if (useSeedWidget && seedWidget) {
toggleWidgetState(useSeedWidget, seedWidget, "seed");
}
if (useStepsWidget && stepsWidget) {
toggleWidgetState(useStepsWidget, stepsWidget, "steps");
}
if (useStrengthWidget && strengthWidget) {
toggleWidgetState(useStrengthWidget, strengthWidget, "strength");
}
if (useCFGScaleWidget && CFGScaleWidget) {
toggleWidgetState(useCFGScaleWidget, CFGScaleWidget, "CFGScale");
}
}
function acceleratorOptionsToggleHandler(acceleratorNode) {
@@ -2574,6 +2599,9 @@ function audioModelSearchFilterHandler(audioModelSearchNode) {
"Mirelo": [
"mirelo:1@1 (Mirelo SFX 1.5)",
],
"Ace": [
"runware:ace-step@0 (ACE Step v1 3.5B)",
],
};
function filterModelList() {
+64 -8
View File
@@ -48,7 +48,7 @@ class RunwareAudioInference:
"tooltip": "Length of generated audio in seconds (10-300)"
}),
"useSampleRate": ("BOOLEAN", {
"default": True,
"default": False,
"tooltip": "Enable/disable sampleRate parameter in API request"
}),
"sampleRate": ("INT", {
@@ -59,7 +59,7 @@ class RunwareAudioInference:
"tooltip": "Sample rate of the generated audio in Hz (8000-48000)"
}),
"useBitrate": ("BOOLEAN", {
"default": True,
"default": False,
"tooltip": "Enable/disable bitrate parameter in API request"
}),
"bitrate": ("INT", {
@@ -83,6 +83,16 @@ class RunwareAudioInference:
"max": 3,
"tooltip": "Number of audio files to generate"
}),
"useSeed": ("BOOLEAN", {
"tooltip": "Enable to include seed parameter in API request for reproducible generation.",
"default": False,
}),
"seed": ("INT", {
"tooltip": "Seed for reproducible audio generation. Only used when 'Use Seed' is enabled.",
"default": 1,
"min": 1,
"max": 2147483647,
}),
"useSteps": ("BOOLEAN", {
"tooltip": "Enable to include steps parameter in API request. Disable if your model doesn't support steps.",
"default": False,
@@ -93,11 +103,36 @@ class RunwareAudioInference:
"min": 1,
"max": 100,
}),
"useStrength": ("BOOLEAN", {
"tooltip": "Enable to include strength parameter in API request. Used for audio-to-audio generation.",
"default": False,
}),
"strength": ("FLOAT", {
"tooltip": "Influence of the input audio in audio-to-audio generation. Lower = more original, higher = more variation. Only used when 'Use Strength' is enabled.",
"default": 0.8,
"min": 0.0,
"max": 1.0,
"step": 0.01,
}),
"useCFGScale": ("BOOLEAN", {
"tooltip": "Enable to include CFGScale parameter in API request. Disable if your model doesn't support CFG scale.",
"default": False,
}),
"CFGScale": ("FLOAT", {
"tooltip": "Classifier-free guidance scale. Higher values adhere more closely to the prompt. Only used when 'Use CFG Scale' is enabled.",
"default": 12.0,
"min": 1.0,
"max": 50.0,
"step": 0.5,
}),
},
"optional": {
"inputs": ("RUNWAREAUDIOINFERENCEINPUTS", {
"tooltip": "Custom inputs for audio generation (e.g., video URL for audio extraction)"
}),
"settings": ("RUNWAREAUDIOSETTINGS", {
"tooltip": "Connect Runware Audio Settings for lyrics, guidanceType, etc."
}),
"providerSettings": ("RUNWAREPROVIDERSETTINGS", {
"tooltip": "Provider-specific configuration settings"
}),
@@ -219,16 +254,23 @@ class RunwareAudioInference:
"duration": kwargs.get("duration", 30),
"useDuration": kwargs.get("useDuration", True),
"sampleRate": kwargs.get("sampleRate", 22050),
"useSampleRate": kwargs.get("useSampleRate", True),
"useSampleRate": kwargs.get("useSampleRate", False),
"bitrate": kwargs.get("bitrate", 32),
"useBitrate": kwargs.get("useBitrate", True),
"useBitrate": kwargs.get("useBitrate", False),
"outputType": kwargs.get("outputType", "URL"),
"outputFormat": kwargs.get("outputFormat", "MP3"),
"negativePrompt": kwargs.get("negativePrompt", ""),
"numberResults": kwargs.get("numberResults", 1),
"seed": kwargs.get("seed", 1),
"useSeed": kwargs.get("useSeed", False),
"steps": kwargs.get("steps", 20),
"useSteps": kwargs.get("useSteps", False),
"strength": kwargs.get("strength", 0.8),
"useStrength": kwargs.get("useStrength", False),
"CFGScale": kwargs.get("CFGScale", 12.0),
"useCFGScale": kwargs.get("useCFGScale", False),
"inputs": kwargs.get("inputs", None),
"settings": kwargs.get("settings", None),
"providerSettings": kwargs.get("providerSettings", None),
}
@@ -290,17 +332,31 @@ class RunwareAudioInference:
else:
print(f"[DEBUG] Skipped duration")
# Add seed parameter only if enabled
if params["useSeed"]:
genConfig[0]["seed"] = params["seed"]
# Add steps parameter only if enabled
if params["useSteps"]:
genConfig[0]["steps"] = params["steps"]
print(f"[DEBUG] Added steps: {params['steps']}")
else:
print(f"[DEBUG] Skipped steps")
# Add strength parameter only if enabled
if params["useStrength"]:
genConfig[0]["strength"] = params["strength"]
# Add CFGScale parameter only if enabled
if params["useCFGScale"]:
genConfig[0]["CFGScale"] = params["CFGScale"]
# Add optional parameters
if params["negativePrompt"]:
genConfig[0]["negativePrompt"] = params["negativePrompt"]
# Handle audio settings (lyrics, guidance_type)
if params["settings"] is not None and isinstance(params["settings"], dict) and len(params["settings"]) > 0:
genConfig[0]["settings"] = params["settings"]
print(f"[DEBUG] Audio settings merged: {rwUtils.sanitize_for_logging(params['settings'])}")
# Handle inputs - merge custom inputs from Audio Inference Inputs node
if params["inputs"] is not None:
# Merge inputs from audio inference inputs node
+4
View File
@@ -14,6 +14,9 @@ class RunwareAudioModelSearch:
"Mirelo": [
"mirelo:1@1 (Mirelo SFX 1.5)",
],
"Ace": [
"runware:ace-step@0 (ACE Step v1 3.5B)",
],
}
MODEL_PROVIDERS = [
@@ -21,6 +24,7 @@ class RunwareAudioModelSearch:
"ElevenLabs",
"KlingAI",
"Mirelo",
"Ace",
]
@classmethod
+68
View File
@@ -0,0 +1,68 @@
"""
Runware Audio Settings Node
Provides lyrics and guidanceType settings for Runware Audio Inference
"""
from typing import Dict, Any
class RunwareAudioSettings:
"""Runware Audio Settings Node"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {},
"optional": {
"useLyrics": ("BOOLEAN", {
"tooltip": "Enable to include lyrics in audio generation settings",
"default": False,
}),
"lyrics": ("STRING", {
"multiline": True,
"default": "",
"placeholder": "[verse] ... [chorus] ... (format like genius.com)",
"tooltip": "Lyrics for the audio generation. Format like lyrics from genius.com with [verse], [chorus], [refrain], etc.",
}),
"useGuidanceType": ("BOOLEAN", {
"tooltip": "Enable to include guidanceType (controls how guidance value is used)",
"default": False,
}),
"guidanceType": (["apg", "cfg"], {
"tooltip": "Controls how the guidance value is used. apg = Adversarial Perceptual Guidance, cfg = Classifier-Free Guidance",
"default": "apg",
}),
}
}
RETURN_TYPES = ("RUNWAREAUDIOSETTINGS",)
RETURN_NAMES = ("settings",)
FUNCTION = "createSettings"
CATEGORY = "Runware/Audio"
DESCRIPTION = "Configure audio generation settings (lyrics, guidanceType) for Runware Audio Inference. Connect to Runware Audio Inference node."
def createSettings(self, **kwargs) -> tuple[Dict[str, Any]]:
"""Create audio settings dict for API"""
use_lyrics = kwargs.get("useLyrics", False)
lyrics = kwargs.get("lyrics", "")
use_guidance_type = kwargs.get("useGuidanceType", False)
guidance_type = kwargs.get("guidanceType", "apg")
settings: Dict[str, Any] = {}
if use_lyrics and lyrics and lyrics.strip():
settings["lyrics"] = lyrics.strip()
if use_guidance_type:
settings["guidanceType"] = guidance_type
return (settings,)
NODE_CLASS_MAPPINGS = {
"RunwareAudioSettings": RunwareAudioSettings,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RunwareAudioSettings": "Runware Audio Settings",
}
+1 -1
View File
@@ -378,7 +378,7 @@ class txt2img:
if isinstance(providerSettings, dict):
# Check if providerSettings already has a provider key (e.g., {"alibaba": {...}})
if any(key in providerSettings for key in ["alibaba", "bytedance", "klingai", "openai", "pixverse",
"bria", "lightricks", "luma", "minimax", "runway", "vidu", "elevenlabs", "bfl", "xai", "sourceful"]):
"bria", "lightricks", "luma", "minimax", "runway", "vidu", "elevenlabs", "bfl", "xai", "recraft", "sourceful"]):
final_provider_settings = providerSettings
else:
# Otherwise, wrap with the extracted provider name
@@ -0,0 +1,68 @@
"""
Runware Recraft Provider Settings Node
IRecraftProviderSettings: styleId, colors (List[IRecraftRGB]), backgroundColor (IRecraftRGB)
"""
from typing import Dict, Any, List
class RunwareRecraftProviderSettings:
"""Runware Recraft Provider Settings Node"""
@classmethod
def INPUT_TYPES(cls):
color_input = ("RUNWARERECRAFTCOLOR", {"tooltip": "IRecraftRGB - connect Runware Recraft Color"})
return {
"required": {},
"optional": {
"useStyleId": ("BOOLEAN", {
"tooltip": "Enable to include styleId parameter",
"default": False,
}),
"styleId": ("STRING", {
"default": "",
"tooltip": "Style ID for Recraft image generation.",
}),
"color1": color_input,
"color2": color_input,
"color3": color_input,
"color4": color_input,
"color5": color_input,
"backgroundColor": color_input,
}
}
RETURN_TYPES = ("RUNWAREPROVIDERSETTINGS",)
RETURN_NAMES = ("Provider Settings",)
FUNCTION = "createProviderSettings"
CATEGORY = "Runware/Provider Settings"
DESCRIPTION = "IRecraftProviderSettings. Connect Runware Recraft Color nodes for colors (palette) and backgroundColor."
def createProviderSettings(self, **kwargs) -> tuple[Dict[str, Any]]:
settings: Dict[str, Any] = {}
if kwargs.get("useStyleId") and (sid := kwargs.get("styleId", "").strip()):
settings["styleId"] = sid
colors: List[Dict[str, List[int]]] = []
for i in range(1, 6):
c = kwargs.get(f"color{i}")
if c and isinstance(c, dict) and "rgb" in c:
colors.append(c)
if colors:
settings["colors"] = colors
bg = kwargs.get("backgroundColor")
if bg and isinstance(bg, dict) and "rgb" in bg:
settings["backgroundColor"] = bg
return (settings,)
NODE_CLASS_MAPPINGS = {
"RunwareRecraftProviderSettings": RunwareRecraftProviderSettings,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RunwareRecraftProviderSettings": "Runware Recraft Provider Settings",
}
@@ -0,0 +1,40 @@
"""
Runware Recraft Color Node - IRecraftRGB
Outputs {rgb: [r, g, b]} for use as palette color or backgroundColor in Recraft Provider Settings
"""
from typing import Dict, List
def _clamp_rgb(value: int) -> int:
return max(0, min(255, int(value)))
class RunwareRecraftColor:
"""Outputs IRecraftRGB {rgb: [r,g,b]} - use for colors palette or backgroundColor"""
@classmethod
def INPUT_TYPES(cls):
rgb = ("INT", {"default": 128, "min": 0, "max": 255})
return {
"required": {},
"optional": {"r": rgb, "g": rgb, "b": rgb}
}
RETURN_TYPES = ("RUNWARERECRAFTCOLOR",)
RETURN_NAMES = ("Color",)
FUNCTION = "create"
CATEGORY = "Runware/Provider Settings"
DESCRIPTION = "IRecraftRGB - use for palette (colors) or backgroundColor. Connect to Runware Recraft Provider Settings."
def create(self, r: int = 128, g: int = 128, b: int = 128) -> tuple[Dict[str, List[int]]]:
return ({"rgb": [_clamp_rgb(r), _clamp_rgb(g), _clamp_rgb(b)]},)
NODE_CLASS_MAPPINGS = {
"RunwareRecraftColor": RunwareRecraftColor,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RunwareRecraftColor": "Runware Provider Settings Recraft Color",
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long