Added Runware Image Inference Settings and Runware Image Upscaler Settings

This commit is contained in:
Sirshendu Ganguly
2026-04-03 01:41:42 +05:30
parent d71fdad61b
commit 2ab6eccb4e
11 changed files with 389 additions and 29 deletions
+1 -1
View File
@@ -189,7 +189,7 @@ class txt2img:
"tooltip": "Connect Runware Safety Inputs node to configure safety and content moderation settings.",
}),
"settings": ("RUNWARESETTINGS", {
"tooltip": "Connect Runware Settings node to configure temperature, systemPrompt, and topP parameters.",
"tooltip": "Connect Runware Image Inference Settings for temperature, systemPrompt, topP, layers, quality, promptExtend, editRegions (JSON), thinking, sequential, colorPalette (via Color Palette node), etc.",
}),
"ultralytics": ("RUNWAREULTRALYTICSINPUTS", {
"tooltip": "Connect Runware Image Inference Ultralytics node to configure Ultralytics parameters (maskBlur, maskPadding, confidence, prompts, steps, CFGScale, strength).",
@@ -0,0 +1,66 @@
"""
Runware Image Inference Settings Color Palette
Builds settings.colorPalette: list of { "hex": "#...", "ratio": "NN.NN%" } for Runware Image Inference Settings.
"""
from typing import Any, Dict, List, Tuple
def _normalize_hex(raw: str) -> str:
h = raw.strip()
if not h:
return ""
return h if h.startswith("#") else f"#{h}"
class RunwareImageInferenceSettingsColorPalette:
"""Up to 8 hex/ratio pairs; each slot is included only when use_{i} is enabled."""
_SLOTS = 8
@classmethod
def INPUT_TYPES(cls):
optional: Dict[str, tuple] = {}
for i in range(1, cls._SLOTS + 1):
optional[f"use_{i}"] = ("BOOLEAN", {
"default": False,
"label_on": "Enabled",
"label_off": "Disabled",
"tooltip": f"Include swatch {i} in the output colorPalette.",
})
optional[f"hex_{i}"] = ("STRING", {
"default": "",
"tooltip": f"Swatch {i} hex, e.g. #C2D1E6. Required when use_{i} is enabled.",
})
optional[f"ratio_{i}"] = ("STRING", {
"default": "",
"tooltip": f"Swatch {i} ratio, e.g. 23.51%%. Optional.",
})
return {"required": {}, "optional": optional}
RETURN_TYPES = ("RUNWAREIMAGEINFERENCECOLORPALETTE",)
RETURN_NAMES = ("colorPalette",)
FUNCTION = "build_palette"
CATEGORY = "Runware"
DESCRIPTION = (
"Build a colorPalette list for image inference settings (hex + optional ratio per swatch). "
"Enable use_1…use_8 for each swatch to include; connect the output to Runware Image Inference Settings."
)
def build_palette(self, **kwargs) -> Tuple[List[Dict[str, Any]]]:
out: List[Dict[str, Any]] = []
for i in range(1, self._SLOTS + 1):
if not kwargs.get(f"use_{i}", False):
continue
hx = _normalize_hex(str(kwargs.get(f"hex_{i}") or ""))
if not hx or hx == "#":
raise ValueError(
f"use_{i} is enabled but hex_{i} is empty or invalid. "
"Provide a hex color (e.g. #C2D1E6) or disable this swatch."
)
ratio = str(kwargs.get(f"ratio_{i}") or "").strip()
entry: Dict[str, Any] = {"hex": hx}
if ratio:
entry["ratio"] = ratio
out.append(entry)
return (out,)
+61
View File
@@ -0,0 +1,61 @@
"""
Runware Image Upscaler Settings — builds settings (enhanceDetails, realism). Connect to Runware Image Upscaler.
"""
from typing import Any, Dict, Tuple
class RunwareImageUpscalerSettings:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {},
"optional": {
"useEnhanceDetails": ("BOOLEAN", {
"default": False,
"label_on": "Enabled",
"label_off": "Disabled",
"tooltip": "Include settings.enhanceDetails in the upscale request.",
}),
"enhanceDetails": ("BOOLEAN", {
"default": False,
"label_on": "true",
"label_off": "false",
"tooltip": "Enhance fine textures and small details. May increase contrast and introduce minor deviations from the original.",
}),
"useRealism": ("BOOLEAN", {
"default": False,
"label_on": "Enabled",
"label_off": "Disabled",
"tooltip": "Include settings.realism in the upscale request.",
}),
"realism": ("BOOLEAN", {
"default": True,
"label_on": "true",
"label_off": "false",
"tooltip": "Improve realism. May deviate more from the original. Recommended for AI-generated images.",
}),
},
}
RETURN_TYPES = ("RUNWAREIMAGEUPSCALERSETTINGS",)
RETURN_NAMES = ("Upscaler Settings",)
FUNCTION = "build_settings"
CATEGORY = "Runware"
DESCRIPTION = (
"Optional settings.enhanceDetails and settings.realism for image upscale. "
"Connect to Runware Image Upscaler."
)
def build_settings(self, **kwargs) -> Tuple[Dict[str, Any]]:
out: Dict[str, Any] = {}
settings: Dict[str, Any] = {}
if kwargs.get("useEnhanceDetails", False):
settings["enhanceDetails"] = bool(kwargs.get("enhanceDetails", False))
if kwargs.get("useRealism", False):
settings["realism"] = bool(kwargs.get("realism", True))
if settings:
out["settings"] = settings
return (out,)
+67 -15
View File
@@ -1,13 +1,15 @@
"""
Runware Settings Node
Provides general settings for image generation including temperature, systemPrompt, and topP
Runware Image Inference Settings (registered as Runware Settings for workflow compatibility).
Provides settings for image generation including temperature, systemPrompt, topP,
editRegions, thinking, sequential, and colorPalette (from Runware Image Inference Settings Color Palette).
"""
from typing import Optional, Dict, Any
import json
from typing import Any, Dict, List, Optional
class RunwareSettings:
"""Runware Settings Node"""
"""Runware Image Inference Settings node (display name); API registration key remains Runware Settings."""
@classmethod
def INPUT_TYPES(cls):
@@ -84,6 +86,37 @@ class RunwareSettings:
"label_on": "true",
"label_off": "false",
}),
"useEditRegions": ("BOOLEAN", {
"tooltip": "Enable to include editRegions in settings (per-input-image bounding boxes for edit flows).",
"default": False,
}),
"editRegions": ("STRING", {
"multiline": True,
"tooltip": "JSON array: one entry per input image; each entry is a list of boxes [x1,y1,x2,y2]. Example: [[[0,0,12,12],[25,25,100,100]],[],[[10,10,50,50]]]",
"default": "",
}),
"useThinking": ("BOOLEAN", {
"tooltip": "Enable to include thinking (string) in settings.",
"default": False,
}),
"thinking": ("STRING", {
"multiline": True,
"tooltip": "Thinking / reasoning string passed in settings. Only used when 'Use Thinking' is enabled.",
"default": "",
}),
"useSequential": ("BOOLEAN", {
"tooltip": "Enable to include sequential (boolean) in settings.",
"default": False,
}),
"sequential": ("BOOLEAN", {
"tooltip": "Sequential / image-set mode flag. Only used when 'Use Sequential' is enabled.",
"default": False,
"label_on": "true",
"label_off": "false",
}),
"colorPalette": ("RUNWAREIMAGEINFERENCECOLORPALETTE", {
"tooltip": "Connect Runware Image Inference Color Palette. When the palette node outputs at least one swatch, it is merged into settings.colorPalette.",
}),
}
}
@@ -91,7 +124,10 @@ class RunwareSettings:
RETURN_NAMES = ("Settings",)
FUNCTION = "createSettings"
CATEGORY = "Runware"
DESCRIPTION = "Configure general settings for image generation including temperature, system prompt, and top-p sampling."
DESCRIPTION = (
"Configure general settings for image generation: temperature, system prompt, top-p, layers, quality, "
"promptExtend, editRegions (JSON), thinking, sequential, and optional colorPalette from the Color Palette node."
)
def createSettings(self, **kwargs) -> tuple[Dict[str, Any]]:
"""Create settings configuration"""
@@ -105,6 +141,9 @@ class RunwareSettings:
useQuality = kwargs.get("useQuality", False)
usePromptExtend = kwargs.get("usePromptExtend", True)
promptExtend = kwargs.get("promptExtend", True)
useEditRegions = kwargs.get("useEditRegions", False)
useThinking = kwargs.get("useThinking", False)
useSequential = kwargs.get("useSequential", False)
# Get value parameters
temperature = kwargs.get("temperature", 1.0)
@@ -133,18 +172,31 @@ class RunwareSettings:
if usePromptExtend:
settings["promptExtend"] = bool(promptExtend)
if useEditRegions:
raw_er = (kwargs.get("editRegions") or "").strip()
if raw_er:
try:
parsed = json.loads(raw_er)
except json.JSONDecodeError as e:
raise ValueError(f"editRegions must be valid JSON: {e}") from e
if not isinstance(parsed, list):
raise ValueError("editRegions JSON must be an array (one element per input image).")
settings["editRegions"] = parsed
if useThinking:
th = (kwargs.get("thinking") or "").strip()
if th:
settings["thinking"] = th
if useSequential:
settings["sequential"] = bool(kwargs.get("sequential", False))
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
# 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 = {
"RunwareSettings": RunwareSettings,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RunwareSettings": "Runware Settings",
}
+41 -12
View File
@@ -8,13 +8,32 @@ class upscaler:
"Image": ("IMAGE", {
"tooltip": "Specifies the input image to be upscaled."
}),
"useUpscaleFactor": ("BOOLEAN", {
"tooltip": "Include upscaleFactor in the upscale request.",
"default": True,
"label_on": "Enabled",
"label_off": "Disabled",
}),
"upscaleFactor": ("INT", {
"tooltip": "Each level will increase the size of the image by the corresponding factor.",
"tooltip": "Each level will increase the size of the image by the corresponding factor. Only used when 'Use Upscale Factor' is enabled.",
"default": 2,
"min": 1,
"max": 8,
"step": 1,
}),
"useTargetMegapixels": ("BOOLEAN", {
"tooltip": "Enable targetMegapixels (root-level) on the upscale request.",
"default": False,
"label_on": "Enabled",
"label_off": "Disabled",
}),
"targetMegapixels": ("INT", {
"tooltip": "Target resolution in megapixels (1–8). Only used when 'Use Target Megapixels' is enabled.",
"default": 4,
"min": 1,
"max": 8,
"step": 1,
}),
},
"optional": {
"model": ("STRING", {
@@ -113,15 +132,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.",
}),
"imageUpscalerSettings": ("RUNWAREIMAGEUPSCALERSETTINGS", {
"tooltip": "Connect Runware Image Upscaler Settings for settings.enhanceDetails and settings.realism.",
}),
},
}
@@ -133,8 +152,8 @@ class upscaler:
def upscale(self, **kwargs):
image = kwargs.get("Image")
upscaleFactor = int(kwargs.get("upscaleFactor", 2))
useUpscaleFactor = kwargs.get("useUpscaleFactor", True)
# Get toggle parameters
useSteps = kwargs.get("useSteps", False)
useSeed = kwargs.get("useSeed", False)
@@ -157,24 +176,30 @@ 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)
imageUpscalerSettingsBundle = kwargs.get("imageUpscalerSettings", None)
useTargetMegapixels = kwargs.get("useTargetMegapixels", False)
# Build the base configuration
genConfig = {
"taskType": "imageUpscale",
"taskUUID": rwUtils.genRandUUID(),
"inputImage": rwUtils.convertTensor2IMG(image),
"upscaleFactor": int(upscaleFactor),
"outputFormat": rwUtils.OUTPUT_FORMAT,
"outputQuality": rwUtils.OUTPUT_QUALITY,
"outputType": "URL",
}
if useUpscaleFactor:
genConfig["upscaleFactor"] = int(kwargs.get("upscaleFactor", 2))
# Add model if specified
if model:
genConfig["model"] = model
if useTargetMegapixels:
genConfig["targetMegapixels"] = int(kwargs.get("targetMegapixels", 4))
# Add common parameters at top level - only add if their toggle is enabled
if useSteps:
@@ -206,15 +231,19 @@ class upscaler:
# Latent upscaler specific parameters
if useLatentParams:
settings["clipSkip"] = clipSkip
if (
imageUpscalerSettingsBundle is not None
and isinstance(imageUpscalerSettingsBundle, dict)
and "settings" in imageUpscalerSettingsBundle
and isinstance(imageUpscalerSettingsBundle["settings"], dict)
):
settings.update(imageUpscalerSettingsBundle["settings"])
# 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