diff --git a/__init__.py b/__init__.py index e3cdd81..368c579 100644 --- a/__init__.py +++ b/__init__.py @@ -108,6 +108,7 @@ from .modules.videoInputsFrame import RunwareVideoInputsFrameImages from .modules.safetyInputs import safetyInputs from .modules.settings import RunwareSettings from .modules.imageInferenceSettingsColorPalette import RunwareImageInferenceSettingsColorPalette +from .modules.imageInferenceSettingsMoodboards import RunwareImageInferenceSettingsMoodboards from .modules.videoAdvancedFeatureInputs import videoAdvancedFeatureInputs from .modules.advancedFeatureSettings.wanAnimateAdvancedFeatureSettings import RunwareWanAnimateAdvancedFeatureSettings from .modules.saveImage import RunwareSaveImage @@ -245,6 +246,7 @@ NODE_CLASS_MAPPINGS = { "Runware Safety Inputs": safetyInputs, "Runware Settings": RunwareSettings, "Runware Image Inference Settings Color Palette": RunwareImageInferenceSettingsColorPalette, + "Runware Image Inference Settings Moodboards": RunwareImageInferenceSettingsMoodboards, "Runware Video Advanced Feature Inputs": videoAdvancedFeatureInputs, "Runware Wan Animate Advanced Feature Settings": RunwareWanAnimateAdvancedFeatureSettings, "Runware Save Image": RunwareSaveImage, diff --git a/clientlibs/main.js b/clientlibs/main.js index ed97d78..7cb4f4c 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, saveTextHandler, mediaUUIDHandler, save3DFilepathHandler, videoTranscriptionHandler, videoOutputsHandler, handleCustomErrors, videoInferenceDimensionsHandler, videoModelSearchFilterHandler, audioModelSearchFilterHandler, textModelSearchFilterHandler, vectorizeModelSearchFilterHandler, vectorizeToggleHandler, useParameterToggleHandler, imageInferenceToggleHandler, imageInferenceAdvancedFeaturesToggleHandler, watermarkAdvancedFeatureToggleHandler, videoInferenceSpeechInputToggleHandler, regionalPromptingRegionsToggleHandler, upscalerToggleHandler, imageUpscalerSettingsToggleHandler, videoUpscalerToggleHandler, audioInferenceToggleHandler, audioInferenceSpeechToggleHandler, audioSettingsToggleHandler, textInferenceSettingsToggleHandler, videoSettingsToggleHandler, videoInferenceSettingsTtsToggleHandler, videoInferenceSettingsActiveSpeakerDetectionToggleHandler, videoInferenceSettingsActiveSpeakerBoundingBoxesToggleHandler, videoInferenceSettingsSegmentsToggleHandler, acceleratorOptionsToggleHandler, bytedanceProviderSettingsToggleHandler, xaiProviderSettingsToggleHandler, viduProviderSettingsToggleHandler, sourcefulProviderSettingsToggleHandler, sourcefulProviderSettingsFontsToggleHandler, threeDInferenceToggleHandler, threeDInferenceSettingsToggleHandler, threeDInferenceSettingsLatToggleHandler, ultralyticsProviderSettingsToggleHandler, openaiProviderSettingsToggleHandler, lightricksProviderSettingsToggleHandler, klingProviderSettingsToggleHandler, lumaProviderSettingsToggleHandler, briaProviderSettingsToggleHandler, pixverseProviderSettingsToggleHandler, alibabaProviderSettingsToggleHandler, mireloProviderSettingsToggleHandler, googleProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler, settingsToggleHandler, outpaintSettingsToggleHandler, safetyInputsToggleHandler, imageInferenceSettingsColorPaletteToggleHandler, audioInputToggleHandler, speechInputToggleHandler, briaProviderMaskToggleHandler, wanAnimateAdvancedFeatureSettingsToggleHandler, videoAdvancedFeatureInputsToggleHandler, audioInferenceInputsToggleHandler, audioInferenceSpeechVoicesToggleHandler, referenceVideosToggleHandler } from "./utils.js"; +import { promptEnhanceHandler, syncDimensionsNodeHandler, searchNodeHandler, APIKeyHandler, captionNodeHandler, saveTextHandler, mediaUUIDHandler, save3DFilepathHandler, videoTranscriptionHandler, videoOutputsHandler, handleCustomErrors, videoInferenceDimensionsHandler, videoModelSearchFilterHandler, audioModelSearchFilterHandler, textModelSearchFilterHandler, vectorizeModelSearchFilterHandler, vectorizeToggleHandler, useParameterToggleHandler, imageInferenceToggleHandler, imageInferenceAdvancedFeaturesToggleHandler, watermarkAdvancedFeatureToggleHandler, videoInferenceSpeechInputToggleHandler, regionalPromptingRegionsToggleHandler, upscalerToggleHandler, imageUpscalerSettingsToggleHandler, videoUpscalerToggleHandler, audioInferenceToggleHandler, audioInferenceSpeechToggleHandler, audioSettingsToggleHandler, textInferenceSettingsToggleHandler, videoSettingsToggleHandler, videoInferenceSettingsTtsToggleHandler, videoInferenceSettingsActiveSpeakerDetectionToggleHandler, videoInferenceSettingsActiveSpeakerBoundingBoxesToggleHandler, videoInferenceSettingsSegmentsToggleHandler, acceleratorOptionsToggleHandler, bytedanceProviderSettingsToggleHandler, xaiProviderSettingsToggleHandler, viduProviderSettingsToggleHandler, sourcefulProviderSettingsToggleHandler, sourcefulProviderSettingsFontsToggleHandler, threeDInferenceToggleHandler, threeDInferenceSettingsToggleHandler, threeDInferenceSettingsLatToggleHandler, ultralyticsProviderSettingsToggleHandler, openaiProviderSettingsToggleHandler, lightricksProviderSettingsToggleHandler, klingProviderSettingsToggleHandler, lumaProviderSettingsToggleHandler, briaProviderSettingsToggleHandler, pixverseProviderSettingsToggleHandler, alibabaProviderSettingsToggleHandler, mireloProviderSettingsToggleHandler, googleProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler, settingsToggleHandler, outpaintSettingsToggleHandler, safetyInputsToggleHandler, imageInferenceSettingsColorPaletteToggleHandler, imageInferenceSettingsMoodboardsToggleHandler, audioInputToggleHandler, speechInputToggleHandler, briaProviderMaskToggleHandler, wanAnimateAdvancedFeatureSettingsToggleHandler, videoAdvancedFeatureInputsToggleHandler, audioInferenceInputsToggleHandler, audioInferenceSpeechVoicesToggleHandler, referenceVideosToggleHandler } from "./utils.js"; import { RUNWARE_NODE_TYPES, RUNWARE_NODE_PROPS, SEARCH_TERMS } from "./types.js"; const nodeInitList = []; @@ -151,6 +151,8 @@ app.registerExtension({ safetyInputsToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.IMAGEINFERENCESETTINGSCOLORPALETTE) { imageInferenceSettingsColorPaletteToggleHandler(node); + } else if(nodeClass === RUNWARE_NODE_TYPES.IMAGEINFERENCESETTINGSMOODBOARDS) { + imageInferenceSettingsMoodboardsToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.AUDIOINPUT) { audioInputToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.SPEECHINPUT) { diff --git a/clientlibs/types.js b/clientlibs/types.js index 12443e7..e1cc897 100644 --- a/clientlibs/types.js +++ b/clientlibs/types.js @@ -157,6 +157,7 @@ const RUNWARE_NODE_TYPES = { SAFETYINPUTS: "Runware Safety Inputs", SETTINGS: "Runware Settings", IMAGEINFERENCESETTINGSCOLORPALETTE: "Runware Image Inference Settings Color Palette", + IMAGEINFERENCESETTINGSMOODBOARDS: "Runware Image Inference Settings Moodboards", VIDEOADVANCEDFEATUREINPUTS: "Runware Video Advanced Feature Inputs", WANANIMATEADVANCEDFEATURESETTINGS: "Runware Wan Animate Advanced Feature Settings", SAVEIMAGE: "Runware Save Image", @@ -621,6 +622,10 @@ const RUNWARE_NODE_PROPS = { bgColor: DEFAULT_BGCOLOR, colorModeOnly: true, }, + [RUNWARE_NODE_TYPES.IMAGEINFERENCESETTINGSMOODBOARDS]: { + bgColor: DEFAULT_BGCOLOR, + colorModeOnly: true, + }, [RUNWARE_NODE_TYPES.VIDEOADVANCEDFEATUREINPUTS]: { bgColor: DEFAULT_BGCOLOR, colorModeOnly: true, diff --git a/clientlibs/utils.js b/clientlibs/utils.js index 8b75b27..f615388 100644 --- a/clientlibs/utils.js +++ b/clientlibs/utils.js @@ -5052,6 +5052,7 @@ export { outpaintSettingsToggleHandler, safetyInputsToggleHandler, imageInferenceSettingsColorPaletteToggleHandler, + imageInferenceSettingsMoodboardsToggleHandler, audioInputToggleHandler, speechInputToggleHandler, briaProviderMaskToggleHandler, @@ -5450,6 +5451,25 @@ function imageInferenceSettingsColorPaletteToggleHandler(paletteNode) { } } +function imageInferenceSettingsMoodboardsToggleHandler(moodboardsNode) { + if (!moodboardsNode?.widgets) return; + + const useStrengthWidget = moodboardsNode.widgets.find((w) => w && w.name === "useStrength"); + const strengthWidget = moodboardsNode.widgets.find((w) => w && w.name === "strength"); + if (!useStrengthWidget || !strengthWidget) return; + + function toggleStrengthState() { + const enabled = useStrengthWidget.value === true; + toggleWidgetEnabled(strengthWidget, enabled, moodboardsNode); + moodboardsNode.setDirtyCanvas(true); + } + + appendWidgetCB(useStrengthWidget, () => { + setTimeout(toggleStrengthState, 50); + }); + setTimeout(toggleStrengthState, 100); +} + function syncProviderSettingsToggleHandler(syncNode) { // Find all "use" parameter widgets for Sync Provider Settings const useEditRegionWidget = syncNode.widgets.find(w => w.name === "useEditRegion"); diff --git a/modules/imageInferenceSettingsMoodboards.py b/modules/imageInferenceSettingsMoodboards.py new file mode 100644 index 0000000..8d1631b --- /dev/null +++ b/modules/imageInferenceSettingsMoodboards.py @@ -0,0 +1,112 @@ +""" +Runware Image Inference Settings Moodboards +Builds settings.moodboards: list of { "id": "", "strength": }. +""" + +from typing import Any, Dict, List, Tuple + + +class RunwareImageInferenceSettingsMoodboards: + """Build moodboards list for image inference settings.""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "id": ("STRING", { + "default": "", + "tooltip": "Moodboard UUID (settings.moodboards[].id).", + }), + }, + "optional": { + "useStrength": ("BOOLEAN", { + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + "tooltip": "Include strength in moodboards entry.", + }), + "strength": ("FLOAT", { + "default": 0.35, + "min": -0.5, + "max": 1.5, + "step": 0.01, + "tooltip": "Moodboard strength (-0.5 to 1.5). Only used when useStrength is enabled.", + }), + }, + } + + RETURN_TYPES = ("RUNWAREIMAGEINFERENCEMOODBOARDS",) + RETURN_NAMES = ("moodboards",) + FUNCTION = "build_moodboards" + CATEGORY = "Runware" + DESCRIPTION = ( + "Build settings.moodboards for image inference settings. " + "Outputs one-element array with required id and optional strength." + ) + + def build_moodboards(self, **kwargs) -> Tuple[List[Dict[str, Any]]]: + moodboard_id = str(kwargs.get("id") or "").strip() + if not moodboard_id: + return ([],) + + entry: Dict[str, Any] = {"id": moodboard_id} + if kwargs.get("useStrength", False): + entry["strength"] = float(kwargs.get("strength", 0.35)) + + return ([entry],) +""" +Runware Image Inference Settings Moodboards +Builds settings.moodboards: list of { "id": "", "strength": }. +""" + +from typing import Any, Dict, List, Tuple + + +class RunwareImageInferenceSettingsMoodboards: + """Build moodboards list for image inference settings.""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "id": ("STRING", { + "default": "", + "tooltip": "Moodboard UUID (settings.moodboards[].id).", + }), + }, + "optional": { + "useStrength": ("BOOLEAN", { + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + "tooltip": "Include strength in moodboards entry.", + }), + "strength": ("FLOAT", { + "default": 0.35, + "min": -0.5, + "max": 1.5, + "step": 0.01, + "tooltip": "Moodboard strength (-0.5 to 1.5). Only used when 'Use Strength' is enabled.", + }), + }, + } + + RETURN_TYPES = ("RUNWAREIMAGEINFERENCEMOODBOARDS",) + RETURN_NAMES = ("moodboards",) + FUNCTION = "build_moodboards" + CATEGORY = "Runware" + DESCRIPTION = ( + "Build settings.moodboards for image inference settings. " + "Outputs one-element array with required id and optional strength." + ) + + def build_moodboards(self, **kwargs) -> Tuple[List[Dict[str, Any]]]: + moodboard_id = str(kwargs.get("id") or "").strip() + if not moodboard_id: + return ([],) + + entry: Dict[str, Any] = {"id": moodboard_id} + if kwargs.get("useStrength", False): + entry["strength"] = float(kwargs.get("strength", 0.35)) + + return ([entry],) diff --git a/modules/settings.py b/modules/settings.py index 157d344..8361ae0 100644 --- a/modules/settings.py +++ b/modules/settings.py @@ -3,7 +3,8 @@ Runware Image Inference Settings (registered as Runware Settings for workflow co Provides settings for image generation including temperature, systemPrompt, topP, layers, quality, background, style, search, promptExtend, editRegions, thinking (boolean), thinkingLevel (high/medium/low), sequential, renderingSpeed (TURBO/DEFAULT/QUALITY), -magicPrompt (AUTO/ON/OFF), autoCrop, dilatePixels, creativity (raw/low/medium/high), and colorPalette +magicPrompt (AUTO/ON/OFF), autoCrop, dilatePixels, creativity (raw/low/medium/high), colorPalette, +and moodboards (from Runware Image Inference Settings Color Palette). """ @@ -121,6 +122,9 @@ class RunwareSettings: "colorPalette": ("RUNWAREIMAGEINFERENCECOLORPALETTE", { "tooltip": "Connect Runware Image Inference Color Palette. When the palette node outputs at least one swatch, it is merged into settings.colorPalette.", }), + "moodboards": ("RUNWAREIMAGEINFERENCEMOODBOARDS", { + "tooltip": "Connect Runware Image Inference Settings Moodboards. When connected with at least one entry, it is merged into settings.moodboards.", + }), "useThinkingLevel": ("BOOLEAN", { "tooltip": "Enable to include thinkingLevel (string) in settings.", "default": False, @@ -211,7 +215,8 @@ class RunwareSettings: DESCRIPTION = ( "Configure general settings for image generation: temperature, system prompt, top-p, layers, quality, background, style, search, " "promptExtend, editRegions (JSON), thinking (boolean), thinkingLevel (high/medium/low), sequential, " - "renderingSpeed (TURBO/DEFAULT/QUALITY), magicPrompt (AUTO/ON/OFF), autoCrop, dilatePixels, creativity (raw/low/medium/high), and optional colorPalette from the Color Palette node." + "renderingSpeed (TURBO/DEFAULT/QUALITY), magicPrompt (AUTO/ON/OFF), autoCrop, dilatePixels, " + "creativity (raw/low/medium/high), and optional colorPalette and moodboards from dedicated settings nodes." ) def createSettings(self, **kwargs) -> tuple[Dict[str, Any]]: @@ -300,6 +305,9 @@ class RunwareSettings: palette: Optional[List[Dict[str, Any]]] = kwargs.get("colorPalette") if palette is not None and isinstance(palette, list) and len(palette) > 0: settings["colorPalette"] = palette + moodboards: Optional[List[Dict[str, Any]]] = kwargs.get("moodboards") + if moodboards is not None and isinstance(moodboards, list) and len(moodboards) > 0: + settings["moodboards"] = moodboards if useRenderingSpeed: settings["renderingSpeed"] = str(renderingSpeed) diff --git a/modules/utils/runwareUtils.py b/modules/utils/runwareUtils.py index 0c97b0f..75ba920 100644 --- a/modules/utils/runwareUtils.py +++ b/modules/utils/runwareUtils.py @@ -158,7 +158,7 @@ def getCustomEndpoint(): custom_endpoint = os.getenv("RUNWARE_CUSTOM_ENDPOINT") if custom_endpoint and isinstance(custom_endpoint, str): return custom_endpoint - return "https://api.runware.ai/v1" + return "https://api.runware.dev/v1" SESSION_TIMEOUT = getTimeout() RUNWARE_API_KEY = getAPIKey()