Merge branch 'main' into feature-syncUpdateVideoInference
This commit is contained in:
@@ -78,7 +78,7 @@ class RunwareAudioInference:
|
||||
"default": "URL",
|
||||
"tooltip": "Output type for the generated audio"
|
||||
}),
|
||||
"outputFormat": (["MP3", "MP4"], {
|
||||
"outputFormat": (["MP3", "MP4", "WAV", "FLAC", "OGG"], {
|
||||
"default": "MP3",
|
||||
"tooltip": "Format of the output audio"
|
||||
}),
|
||||
|
||||
@@ -14,20 +14,6 @@ class RunwareAudioInferenceSpeech:
|
||||
"calm", "fluent", "whisper",
|
||||
]
|
||||
|
||||
SPEECH_LANGUAGES = [
|
||||
"Auto",
|
||||
"Chinese",
|
||||
"English",
|
||||
"Japanese",
|
||||
"Korean",
|
||||
"German",
|
||||
"French",
|
||||
"Russian",
|
||||
"Portuguese",
|
||||
"Spanish",
|
||||
"Italian",
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@@ -50,7 +36,7 @@ class RunwareAudioInferenceSpeech:
|
||||
"default": "",
|
||||
"tooltip": "Voice identifier.",
|
||||
}),
|
||||
"useSpeed": ("BOOLEAN", {"default": True, "tooltip": "Include speed (speech.speed)"}),
|
||||
"useSpeed": ("BOOLEAN", {"default": False, "tooltip": "Include speed (speech.speed)"}),
|
||||
"speed": ("FLOAT", {
|
||||
"default": 1.0,
|
||||
"min": 0.5,
|
||||
@@ -58,7 +44,7 @@ class RunwareAudioInferenceSpeech:
|
||||
"step": 0.01,
|
||||
"tooltip": "Speech rate multiplier (speech.speed)",
|
||||
}),
|
||||
"useVolume": ("BOOLEAN", {"default": True, "tooltip": "Include volume (speech.volume)"}),
|
||||
"useVolume": ("BOOLEAN", {"default": False, "tooltip": "Include volume (speech.volume)"}),
|
||||
"volume": ("FLOAT", {
|
||||
"default": 1.0,
|
||||
"min": 1.0,
|
||||
@@ -87,9 +73,12 @@ class RunwareAudioInferenceSpeech:
|
||||
"default": False,
|
||||
"tooltip": "Enable to include language (speech.language).",
|
||||
}),
|
||||
"language": (cls.SPEECH_LANGUAGES, {
|
||||
"language": ("STRING", {
|
||||
"default": "Auto",
|
||||
"tooltip": "Language of the input text. Options: Auto, Chinese, English, Japanese, Korean, German, French, Russian, Portuguese, Spanish, Italian. Applies to all variants. Only used when 'Use Language' is enabled.",
|
||||
"tooltip": "Language of the input text (for example: en-US). Applies to all variants. Only used when 'Use Language' is enabled.",
|
||||
}),
|
||||
"voices": ("RUNWAREAUDIOINFERENCESPEECHVOICES", {
|
||||
"tooltip": "Optional multi-speaker voices array (speech.voices[]). If provided, it takes precedence over speech.voice.",
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -108,9 +97,9 @@ class RunwareAudioInferenceSpeech:
|
||||
text = (kwargs.get("text") or "").strip()
|
||||
voice = (kwargs.get("voice") or "").strip()
|
||||
use_voice = kwargs.get("useVoice", False)
|
||||
use_speed = kwargs.get("useSpeed", True)
|
||||
use_speed = kwargs.get("useSpeed", False)
|
||||
speed = float(kwargs.get("speed", 1.0))
|
||||
use_volume = kwargs.get("useVolume", True)
|
||||
use_volume = kwargs.get("useVolume", False)
|
||||
volume = float(kwargs.get("volume", 1.0))
|
||||
use_pitch = kwargs.get("usePitch", False)
|
||||
pitch = float(kwargs.get("pitch", 0.0))
|
||||
@@ -119,10 +108,13 @@ class RunwareAudioInferenceSpeech:
|
||||
use_tone = kwargs.get("useTone", False)
|
||||
tone_str = kwargs.get("tone", "") or ""
|
||||
use_language = kwargs.get("useLanguage", False)
|
||||
language = kwargs.get("language", "Auto")
|
||||
language = (kwargs.get("language") or "Auto").strip()
|
||||
voices = kwargs.get("voices")
|
||||
|
||||
speech: Dict[str, Any] = {"text": text}
|
||||
if use_voice:
|
||||
if isinstance(voices, list) and len(voices) > 0:
|
||||
speech["voices"] = voices
|
||||
elif use_voice:
|
||||
speech["voice"] = voice
|
||||
if use_speed:
|
||||
speech["speed"] = speed
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
"""
|
||||
Runware Audio Inference Speech Voices node:
|
||||
Builds speech.voices[] for multi-speaker audio inference speech payloads.
|
||||
"""
|
||||
|
||||
import re
|
||||
from typing import Dict, List
|
||||
|
||||
|
||||
class RunwareAudioInferenceSpeechVoices:
|
||||
"""Build speech.voices[] list for Runware Audio Inference."""
|
||||
|
||||
MAX_VOICES = 4
|
||||
_SPEAKER_ALIAS_PATTERN = re.compile(r"^[A-Za-z0-9]+$")
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
optional_inputs = {}
|
||||
for i in range(1, cls.MAX_VOICES + 1):
|
||||
optional_inputs[f"useVoice{i}"] = ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": f"Enable to include speaker/voice pair #{i} in speech.voices.",
|
||||
})
|
||||
optional_inputs[f"speaker{i}"] = ("STRING", {
|
||||
"default": f"Speaker{i}",
|
||||
"tooltip": "Unique alphanumeric speaker alias (speech.voices[].speaker).",
|
||||
})
|
||||
optional_inputs[f"voice{i}"] = ("STRING", {
|
||||
"default": "",
|
||||
"tooltip": "Voice name for this speaker (speech.voices[].voice).",
|
||||
})
|
||||
|
||||
return {
|
||||
"required": {},
|
||||
"optional": optional_inputs,
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("RUNWAREAUDIOINFERENCESPEECHVOICES",)
|
||||
RETURN_NAMES = ("voices",)
|
||||
FUNCTION = "createVoices"
|
||||
CATEGORY = "Runware/Audio"
|
||||
DESCRIPTION = (
|
||||
"Build speech.voices[] for multi-speaker synthesis. "
|
||||
"Each item contains speaker (unique alphanumeric alias) and voice name."
|
||||
)
|
||||
|
||||
def createVoices(self, **kwargs) -> tuple[list[dict[str, str]],]:
|
||||
voices: list[dict[str, str]] = []
|
||||
seen_speakers = set()
|
||||
|
||||
for i in range(1, self.MAX_VOICES + 1):
|
||||
use_voice = bool(kwargs.get(f"useVoice{i}", False))
|
||||
if not use_voice:
|
||||
continue
|
||||
|
||||
speaker = (kwargs.get(f"speaker{i}") or "").strip()
|
||||
voice = (kwargs.get(f"voice{i}") or "").strip()
|
||||
|
||||
if not speaker or not voice:
|
||||
raise Exception(
|
||||
f"Voice #{i} is enabled, but speaker{i} and voice{i} must both be provided."
|
||||
)
|
||||
if not self._SPEAKER_ALIAS_PATTERN.match(speaker):
|
||||
raise Exception(
|
||||
f"speaker{i} must be alphanumeric only (got: '{speaker}')."
|
||||
)
|
||||
if speaker in seen_speakers:
|
||||
raise Exception(
|
||||
f"Duplicate speaker alias '{speaker}'. Each speaker must be unique."
|
||||
)
|
||||
|
||||
seen_speakers.add(speaker)
|
||||
voices.append({
|
||||
"speaker": speaker,
|
||||
"voice": voice,
|
||||
})
|
||||
|
||||
return (voices,)
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"RunwareAudioInferenceSpeechVoices": RunwareAudioInferenceSpeechVoices,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"RunwareAudioInferenceSpeechVoices": "Runware Audio Inference Speech Voices",
|
||||
}
|
||||
@@ -40,6 +40,9 @@ class RunwareAudioModelSearch:
|
||||
"inworld:tts@1.5-mini (Inworld TTS-1.5 Mini)",
|
||||
"inworld:tts@1.5-max (Inworld TTS-1.5 Max)",
|
||||
],
|
||||
"Google": [
|
||||
"google:gemini@3.1-flash-tts (Gemini 3.1 Flash TTS)",
|
||||
],
|
||||
}
|
||||
|
||||
MODEL_PROVIDERS = [
|
||||
@@ -53,6 +56,7 @@ class RunwareAudioModelSearch:
|
||||
"xAI",
|
||||
"MiniMax",
|
||||
"Inworld",
|
||||
"Google",
|
||||
]
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
from typing import List
|
||||
|
||||
|
||||
class referenceAudios:
|
||||
"""Reference Audios node for configuring reference audio inputs"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {},
|
||||
"optional": {
|
||||
"Audio1": ("STRING", {
|
||||
"default": "",
|
||||
"tooltip": "MediaUUID for the first reference audio from Runware Media Upload node.",
|
||||
}),
|
||||
"Audio2": ("STRING", {
|
||||
"default": "",
|
||||
"tooltip": "MediaUUID for the second reference audio from Runware Media Upload node.",
|
||||
}),
|
||||
"Audio3": ("STRING", {
|
||||
"default": "",
|
||||
"tooltip": "MediaUUID for the third reference audio from Runware Media Upload node.",
|
||||
}),
|
||||
"Audio4": ("STRING", {
|
||||
"default": "",
|
||||
"tooltip": "MediaUUID for the fourth reference audio from Runware Media Upload node.",
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
DESCRIPTION = "Configure multiple reference audios (mediaUUIDs) for video inference inputs."
|
||||
FUNCTION = "createReferenceAudios"
|
||||
RETURN_TYPES = ("RUNWAREINPUTAUDIOS",)
|
||||
RETURN_NAMES = ("Reference Audios",)
|
||||
CATEGORY = "Runware"
|
||||
|
||||
def createReferenceAudios(self, **kwargs) -> tuple[List[str]]:
|
||||
"""Create list of reference audio UUIDs from provided parameters"""
|
||||
audioList = []
|
||||
|
||||
for i in range(1, 5):
|
||||
audioKey = f"Audio{i}"
|
||||
audioUuid = kwargs.get(audioKey)
|
||||
|
||||
if audioUuid and audioUuid.strip() != "":
|
||||
audioList.append(audioUuid.strip())
|
||||
|
||||
return (audioList,)
|
||||
+3
-3
@@ -35,7 +35,7 @@ class RunwareSave3D:
|
||||
FUNCTION = "save_3d"
|
||||
OUTPUT_NODE = True
|
||||
CATEGORY = "Runware"
|
||||
DESCRIPTION = "Save 3D model files (GLB/PLY) from Runware 3D Inference to the output folder."
|
||||
DESCRIPTION = "Save 3D model files (GLB/PLY/FBX) from Runware 3D Inference to the output folder."
|
||||
|
||||
def save_3d(self, filenamePrefix="ComfyUI", **kwargs):
|
||||
"""Save 3D file from URL"""
|
||||
@@ -55,8 +55,8 @@ class RunwareSave3D:
|
||||
url_without_params = file_url.split('?')[0]
|
||||
extension = url_without_params.split('.')[-1].lower()
|
||||
|
||||
if extension not in ["glb", "ply"]:
|
||||
raise Exception(f"Unsupported 3D file extension '{extension}' from URL. Expected .glb or .ply.")
|
||||
if extension not in ["glb", "ply", "fbx"]:
|
||||
raise Exception(f"Unsupported 3D file extension '{extension}' from URL. Expected .glb, .ply, or .fbx.")
|
||||
|
||||
# Sanitize filenamePrefix to prevent path traversal or arbitrary subdir creation
|
||||
prefix_basename = os.path.basename(
|
||||
|
||||
+17
-3
@@ -1,7 +1,9 @@
|
||||
"""
|
||||
Runware Image Inference Settings (registered as Runware Settings for workflow compatibility).
|
||||
Provides settings for image generation including temperature, systemPrompt, topP,
|
||||
editRegions, thinking (boolean), thinkingLevel (high/medium/low), sequential, and colorPalette (from Runware Image Inference Settings Color Palette).
|
||||
Provides settings for image generation including temperature, systemPrompt, topP, layers,
|
||||
quality, background, promptExtend, editRegions, thinking (boolean),
|
||||
thinkingLevel (high/medium/low), sequential, and colorPalette
|
||||
(from Runware Image Inference Settings Color Palette).
|
||||
"""
|
||||
|
||||
import json
|
||||
@@ -126,6 +128,14 @@ class RunwareSettings:
|
||||
"default": "high",
|
||||
"tooltip": "Reasoning level for visual understanding. Only used when 'Use Thinking Level' is enabled.",
|
||||
}),
|
||||
"useBackground": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include background style in API request",
|
||||
"default": False,
|
||||
}),
|
||||
"background": (["auto", "transparent", "opaque"], {
|
||||
"default": "auto",
|
||||
"tooltip": "Background style for the generated image. Only used when 'Use Background' is enabled.",
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +144,7 @@ class RunwareSettings:
|
||||
FUNCTION = "createSettings"
|
||||
CATEGORY = "Runware"
|
||||
DESCRIPTION = (
|
||||
"Configure general settings for image generation: temperature, system prompt, top-p, layers, quality, "
|
||||
"Configure general settings for image generation: temperature, system prompt, top-p, layers, quality, background, "
|
||||
"promptExtend, editRegions (JSON), thinking (boolean), thinkingLevel (high/medium/low), sequential, and optional colorPalette from the Color Palette node."
|
||||
)
|
||||
|
||||
@@ -148,6 +158,7 @@ class RunwareSettings:
|
||||
useLayers = kwargs.get("useLayers", False)
|
||||
useTrueCFGScale = kwargs.get("useTrueCFGScale", False)
|
||||
useQuality = kwargs.get("useQuality", False)
|
||||
useBackground = kwargs.get("useBackground", False)
|
||||
usePromptExtend = kwargs.get("usePromptExtend", False)
|
||||
promptExtend = kwargs.get("promptExtend", False)
|
||||
useEditRegions = kwargs.get("useEditRegions", False)
|
||||
@@ -162,6 +173,7 @@ class RunwareSettings:
|
||||
layers = kwargs.get("layers")
|
||||
trueCFGScale = kwargs.get("trueCFGScale")
|
||||
quality = kwargs.get("quality", "medium")
|
||||
background = kwargs.get("background", "auto")
|
||||
|
||||
# Build settings dictionary - only include what is enabled
|
||||
settings: Dict[str, Any] = {}
|
||||
@@ -179,6 +191,8 @@ class RunwareSettings:
|
||||
settings["true_cfg_scale"] = float(trueCFGScale)
|
||||
if useQuality:
|
||||
settings["quality"] = quality
|
||||
if useBackground:
|
||||
settings["background"] = background
|
||||
if usePromptExtend:
|
||||
settings["promptExtend"] = bool(promptExtend)
|
||||
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
from typing import Any, Dict, Tuple
|
||||
import json
|
||||
from typing import Any, Dict, List, Tuple
|
||||
|
||||
|
||||
class RunwareTextInferenceSettings:
|
||||
"""Optional generation controls for Runware Text Inference (flat task.settings per API)."""
|
||||
|
||||
_MAX_SYSTEM_CHARS = 200000
|
||||
_MAX_TOKENS_CAP = 196608
|
||||
_MAX_TOKENS_CAP = 131072
|
||||
_MAX_TOP_K = 100647
|
||||
_MAX_STOP_ITEMS = 5
|
||||
_MAX_STOP_ITEM_CHARS = 50
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
@@ -16,17 +20,17 @@ class RunwareTextInferenceSettings:
|
||||
"default": False,
|
||||
"tooltip": "Include systemPrompt in settings.",
|
||||
}),
|
||||
"system": ("STRING", {
|
||||
"systemPrompt": ("STRING", {
|
||||
"multiline": True,
|
||||
"default": "",
|
||||
"tooltip": "System instruction (max 200,000 characters). Sent as systemPrompt.",
|
||||
"tooltip": "System instruction (max 200,000 chars).",
|
||||
}),
|
||||
"useMaxTokens": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Include maxTokens in settings.",
|
||||
}),
|
||||
"maxTokens": ("INT", {
|
||||
"default": 32768,
|
||||
"default": 4096,
|
||||
"min": 1,
|
||||
"max": cls._MAX_TOKENS_CAP,
|
||||
"step": 1,
|
||||
@@ -38,21 +42,21 @@ class RunwareTextInferenceSettings:
|
||||
}),
|
||||
"temperature": ("FLOAT", {
|
||||
"default": 1.0,
|
||||
"min": 0.01,
|
||||
"min": 0.0,
|
||||
"max": 1.0,
|
||||
"step": 0.01,
|
||||
"tooltip": "Sampling temperature on (0, 1].",
|
||||
"tooltip": "Sampling temperature (0.0–1.0).",
|
||||
}),
|
||||
"useTopP": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Include topP in settings.",
|
||||
}),
|
||||
"topP": ("FLOAT", {
|
||||
"default": 0.95,
|
||||
"min": 0.0,
|
||||
"default": 1.0,
|
||||
"min": 0.01,
|
||||
"max": 1.0,
|
||||
"step": 0.01,
|
||||
"tooltip": "Nucleus sampling (0.0–1.0).",
|
||||
"tooltip": "Nucleus sampling (0.01–1.0).",
|
||||
}),
|
||||
"useTopK": ("BOOLEAN", {
|
||||
"default": False,
|
||||
@@ -61,13 +65,63 @@ class RunwareTextInferenceSettings:
|
||||
"topK": ("INT", {
|
||||
"default": 40,
|
||||
"min": 1,
|
||||
"max": 128,
|
||||
"max": cls._MAX_TOP_K,
|
||||
"step": 1,
|
||||
"tooltip": "Top-k sampling (1–128).",
|
||||
"tooltip": f"Top-k sampling (1–{cls._MAX_TOP_K}).",
|
||||
}),
|
||||
"thinkingLevel": (["off", "minimal", "low", "medium", "high"], {
|
||||
"default": "off",
|
||||
"tooltip": "thinkingLevel in settings (omit when off).",
|
||||
# Keep this in the original slot to avoid shifting legacy widgets_values.
|
||||
"thinkingLevel": (["none", "low", "medium", "high"], {
|
||||
"default": "none",
|
||||
"tooltip": "Extended reasoning level: none, low, medium, high.",
|
||||
}),
|
||||
"useStopSequences": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Include stopSequences in settings.",
|
||||
}),
|
||||
"stopSequences": ("STRING", {
|
||||
"multiline": True,
|
||||
"default": "",
|
||||
"tooltip": "Stop sequences: one per line (max 5 items, 50 chars each).",
|
||||
}),
|
||||
"usePresencePenalty": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Include presencePenalty in settings.",
|
||||
}),
|
||||
"presencePenalty": ("FLOAT", {
|
||||
"default": 0.0,
|
||||
"min": -2.0,
|
||||
"max": 2.0,
|
||||
"step": 0.01,
|
||||
"tooltip": "Presence penalty (-2.0 to 2.0).",
|
||||
}),
|
||||
"useFrequencyPenalty": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Include frequencyPenalty in settings.",
|
||||
}),
|
||||
"frequencyPenalty": ("FLOAT", {
|
||||
"default": 0.0,
|
||||
"min": -2.0,
|
||||
"max": 2.0,
|
||||
"step": 0.01,
|
||||
"tooltip": "Frequency penalty (-2.0 to 2.0).",
|
||||
}),
|
||||
"useTools": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Include tools in settings.",
|
||||
}),
|
||||
"tools": ("STRING", {
|
||||
"multiline": True,
|
||||
"default": "[]",
|
||||
"tooltip": "JSON array for tools.",
|
||||
}),
|
||||
"useToolChoice": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Include toolChoice in settings.",
|
||||
}),
|
||||
"toolChoice": ("STRING", {
|
||||
"multiline": True,
|
||||
"default": "{}",
|
||||
"tooltip": "JSON object for toolChoice.",
|
||||
}),
|
||||
},
|
||||
}
|
||||
@@ -77,34 +131,115 @@ class RunwareTextInferenceSettings:
|
||||
FUNCTION = "create_settings"
|
||||
CATEGORY = "Runware/Text"
|
||||
DESCRIPTION = (
|
||||
"Optional text inference settings (flat: systemPrompt, maxTokens, temperature, topP, topK, thinkingLevel). "
|
||||
"Optional text inference settings (systemPrompt, maxTokens, temperature, topP, topK, "
|
||||
"stopSequences, presencePenalty, frequencyPenalty, tools, toolChoice, thinkingLevel). "
|
||||
"Connect to Runware Text Inference."
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _parse_json_setting(raw: Any, expected_type: type, field_name: str) -> Any:
|
||||
if isinstance(raw, expected_type):
|
||||
return raw
|
||||
if raw is None:
|
||||
return expected_type()
|
||||
|
||||
text = str(raw).strip()
|
||||
if not text:
|
||||
return expected_type()
|
||||
|
||||
try:
|
||||
parsed = json.loads(text)
|
||||
except Exception as exc:
|
||||
raise Exception(f"{field_name} must be valid JSON.") from exc
|
||||
|
||||
if not isinstance(parsed, expected_type):
|
||||
expected = "array" if expected_type is list else "object"
|
||||
raise Exception(f"{field_name} must be a JSON {expected}.")
|
||||
return parsed
|
||||
|
||||
def _parse_stop_sequences(self, raw: Any) -> List[str]:
|
||||
if raw is None:
|
||||
return []
|
||||
|
||||
items: List[str] = []
|
||||
if isinstance(raw, (list, tuple)):
|
||||
for item in raw:
|
||||
text = str(item).strip()
|
||||
if text:
|
||||
items.append(text)
|
||||
else:
|
||||
text = str(raw).strip()
|
||||
if text:
|
||||
normalized = text.replace("\r\n", "\n").replace(",", "\n")
|
||||
items = [segment.strip() for segment in normalized.split("\n") if segment.strip()]
|
||||
|
||||
if len(items) > self._MAX_STOP_ITEMS:
|
||||
raise Exception(f"stopSequences supports up to {self._MAX_STOP_ITEMS} items.")
|
||||
for idx, item in enumerate(items, start=1):
|
||||
if len(item) > self._MAX_STOP_ITEM_CHARS:
|
||||
raise Exception(
|
||||
f"stopSequences item {idx} exceeds {self._MAX_STOP_ITEM_CHARS} characters."
|
||||
)
|
||||
return items
|
||||
|
||||
@staticmethod
|
||||
def _normalize_thinking_level(raw: Any) -> str:
|
||||
value = str(raw or "none").strip().lower()
|
||||
# Backward compatibility with older workflows.
|
||||
aliases = {
|
||||
"off": "none",
|
||||
"minimal": "low",
|
||||
}
|
||||
value = aliases.get(value, value)
|
||||
if value not in ("none", "low", "medium", "high"):
|
||||
return "none"
|
||||
return value
|
||||
|
||||
def create_settings(self, **kwargs) -> Tuple[Dict[str, Any], ...]:
|
||||
out: Dict[str, Any] = {}
|
||||
|
||||
if kwargs.get("useSystemPrompt", False):
|
||||
sys_text = (kwargs.get("system") or "").strip()
|
||||
sys_text = (kwargs.get("systemPrompt") or kwargs.get("system") or "").strip()
|
||||
if sys_text:
|
||||
if len(sys_text) > self._MAX_SYSTEM_CHARS:
|
||||
sys_text = sys_text[: self._MAX_SYSTEM_CHARS]
|
||||
out["systemPrompt"] = sys_text
|
||||
|
||||
if kwargs.get("useMaxTokens", False):
|
||||
out["maxTokens"] = int(kwargs.get("maxTokens", 32768))
|
||||
out["maxTokens"] = int(kwargs.get("maxTokens", 4096))
|
||||
|
||||
if kwargs.get("useTemperature", False):
|
||||
out["temperature"] = float(kwargs.get("temperature", 1.0))
|
||||
|
||||
if kwargs.get("useTopP", False):
|
||||
out["topP"] = float(kwargs.get("topP", 0.95))
|
||||
out["topP"] = float(kwargs.get("topP", 1.0))
|
||||
|
||||
if kwargs.get("useTopK", False):
|
||||
out["topK"] = int(kwargs.get("topK", 40))
|
||||
|
||||
tl = kwargs.get("thinkingLevel", "off")
|
||||
if tl != "off":
|
||||
if kwargs.get("useStopSequences", False):
|
||||
parsed_stop = self._parse_stop_sequences(kwargs.get("stopSequences", ""))
|
||||
if parsed_stop:
|
||||
out["stopSequences"] = parsed_stop
|
||||
|
||||
if kwargs.get("usePresencePenalty", False):
|
||||
out["presencePenalty"] = float(kwargs.get("presencePenalty", 0.0))
|
||||
|
||||
if kwargs.get("useFrequencyPenalty", False):
|
||||
out["frequencyPenalty"] = float(kwargs.get("frequencyPenalty", 0.0))
|
||||
|
||||
if kwargs.get("useTools", False):
|
||||
parsed_tools = self._parse_json_setting(kwargs.get("tools"), list, "tools")
|
||||
if parsed_tools:
|
||||
out["tools"] = parsed_tools
|
||||
|
||||
if kwargs.get("useToolChoice", False):
|
||||
parsed_choice = self._parse_json_setting(kwargs.get("toolChoice"), dict, "toolChoice")
|
||||
if parsed_choice:
|
||||
out["toolChoice"] = parsed_choice
|
||||
|
||||
tl = self._normalize_thinking_level(kwargs.get("thinkingLevel", "none"))
|
||||
if tl != "none":
|
||||
out["thinkingLevel"] = tl
|
||||
|
||||
if not out:
|
||||
|
||||
@@ -16,6 +16,9 @@ class RunwareTextModelSearch:
|
||||
"Google": [
|
||||
"google:gemini@3-flash (Gemini 3 Flash)",
|
||||
],
|
||||
"Zai": [
|
||||
"zai-glm-5-1 (ZAI GLM 5.1)",
|
||||
],
|
||||
}
|
||||
|
||||
MODEL_PROVIDERS = [
|
||||
@@ -23,6 +26,7 @@ class RunwareTextModelSearch:
|
||||
"Google",
|
||||
"MiniMax",
|
||||
"OpenAI",
|
||||
"Zai",
|
||||
]
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -15,7 +15,7 @@ class threeDInference:
|
||||
}
|
||||
|
||||
# Output formats
|
||||
OUTPUT_FORMATS = ["GLB", "PLY"]
|
||||
OUTPUT_FORMATS = ["GLB", "PLY", "FBX"]
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
|
||||
@@ -41,14 +41,14 @@ class videoInferenceInputs:
|
||||
"Background": ("IMAGE", {
|
||||
"tooltip": "Background image for video generation. Connect a Load Image node to provide the background.",
|
||||
}),
|
||||
"References": ("RUNWAREVIDEOINPUTSREFERENCEIMAGES", {
|
||||
"tooltip": "Connect the Video Inputs References node to provide reference images."
|
||||
"References Images": ("RUNWAREVIDEOINPUTSREFERENCEIMAGES", {
|
||||
"tooltip": "Connect the Runware Video Inference Inputs Reference Images node to provide reference images."
|
||||
}),
|
||||
"Reference Videos": ("RUNWAREREFERENCEVIDEOS", {
|
||||
"tooltip": "Connect the Reference Videos node to provide reference video mediaUUIDs."
|
||||
"tooltip": "Connect the Runware Video Inference Inputs Reference Videos node to provide reference video mediaUUIDs."
|
||||
}),
|
||||
"Reference Voices": ("RUNWAREREFERENCEVOICES", {
|
||||
"tooltip": "Connect the Reference Voices node to provide reference voice URLs or mediaUUIDs."
|
||||
"tooltip": "Connect the Runware Video Inference Inputs Reference Voices node to provide reference voice URLs or mediaUUIDs."
|
||||
}),
|
||||
"draftId": ("STRING", {
|
||||
"default": "",
|
||||
@@ -63,6 +63,9 @@ class videoInferenceInputs:
|
||||
"Elements": ("RUNWAREVIDEOINFERENCEELEMENTS", {
|
||||
"tooltip": "Connect Runware Video Inference Elements (one element) or Runware Video Inference Elements Combine (several) for inputs.elements (Kling, etc.).",
|
||||
}),
|
||||
"Reference Audios": ("RUNWAREINPUTAUDIOS", {
|
||||
"tooltip": "Connect the Runware Video Inference Inputs Reference Audios node to provide reference audio mediaUUIDs."
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,8 +89,9 @@ class videoInferenceInputs:
|
||||
frame = kwargs.get("Frame", None)
|
||||
background = kwargs.get("Background", None)
|
||||
frameImages = kwargs.get("Frame Images", None)
|
||||
references = kwargs.get("References", None)
|
||||
references = kwargs.get("References Images", kwargs.get("References", None))
|
||||
referenceVideos = kwargs.get("Reference Videos", None)
|
||||
referenceAudios = kwargs.get("Reference Audios", None)
|
||||
referenceVoices = kwargs.get("Reference Voices", None)
|
||||
draftId = kwargs.get("draftId", "")
|
||||
videoId = kwargs.get("videoId", "")
|
||||
@@ -143,6 +147,9 @@ class videoInferenceInputs:
|
||||
if referenceVideos is not None and len(referenceVideos) > 0:
|
||||
inputs["referenceVideos"] = referenceVideos
|
||||
|
||||
if referenceAudios is not None and len(referenceAudios) > 0:
|
||||
inputs["referenceAudios"] = referenceAudios
|
||||
|
||||
if referenceVoices is not None and len(referenceVoices) > 0:
|
||||
inputs["referenceVoices"] = referenceVoices
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import List, Dict, Any
|
||||
class videoInputsReferences:
|
||||
"""Video Inputs References node for configuring reference images with types"""
|
||||
|
||||
MAX_REFERENCES = 4
|
||||
MAX_REFERENCES = 10
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
@@ -63,5 +63,5 @@ NODE_CLASS_MAPPINGS = {
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"RunwareVideoInputsReferences": "Runware Video Inputs Reference Images",
|
||||
"RunwareVideoInputsReferences": "Runware Video Inference Inputs Reference Images",
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ class videoModelSearch:
|
||||
"bytedance:5@1 (OmniHuman 1)",
|
||||
"bytedance:5@2 (OmniHuman 1.5)",
|
||||
"bytedance:seedance@1.5-pro (Seedance 1.5 Pro)",
|
||||
"bytedance:seedance@2.0-fast (Seedance 2.0 Fast)",
|
||||
"bytedance:seedance@2.0 (Seedance 2.0)",
|
||||
],
|
||||
"MiniMax": [
|
||||
"minimax:1@1 (MiniMax 01 Base)",
|
||||
@@ -172,6 +174,8 @@ class videoModelSearch:
|
||||
"bytedance:5@1": {"width": 1024, "height": 1024},
|
||||
"bytedance:5@2": {"width": 1024, "height": 1024},
|
||||
"bytedance:seedance@1.5-pro": {"width": 864, "height": 496},
|
||||
"bytedance:seedance@2.0-fast": {"width": 864, "height": 496},
|
||||
"bytedance:seedance@2.0": {"width": 864, "height": 496},
|
||||
|
||||
# MiniMax Models
|
||||
"minimax:1@1": {"width": 1366, "height": 768},
|
||||
@@ -304,6 +308,8 @@ class videoModelSearch:
|
||||
"bytedance:5@1": None, # No resolution support (fixed 1024x1024)
|
||||
"bytedance:5@2": None, # No resolution support (fixed 1024x1024)
|
||||
"bytedance:seedance@1.5-pro": "480p",
|
||||
"bytedance:seedance@2.0-fast": "480p",
|
||||
"bytedance:seedance@2.0": "480p",
|
||||
|
||||
# MiniMax Models (support both 768p and 720p, using 768p as primary)
|
||||
"minimax:1@1": "768p",
|
||||
|
||||
@@ -26,21 +26,21 @@ class RunwareVideoSettings:
|
||||
}),
|
||||
"useAudio": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include audio (save video with audio) in video inference settings.",
|
||||
"default": True,
|
||||
"default": False,
|
||||
}),
|
||||
"audio": ("BOOLEAN", {
|
||||
"tooltip": "Save the video with audio. Only used when 'Use Audio' is enabled.",
|
||||
"default": True,
|
||||
"default": False,
|
||||
"label_on": "Enabled",
|
||||
"label_off": "Disabled",
|
||||
}),
|
||||
"usePromptUpsampling": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include promptUpsampling (enhance prompt automatically) in video inference settings.",
|
||||
"default": True,
|
||||
"default": False,
|
||||
}),
|
||||
"promptUpsampling": ("BOOLEAN", {
|
||||
"tooltip": "Enhance prompt automatically for better results. Only used when 'Use Prompt Upsampling' is enabled.",
|
||||
"default": True,
|
||||
"default": False,
|
||||
"label_on": "Enabled",
|
||||
"label_off": "Disabled",
|
||||
}),
|
||||
@@ -193,10 +193,10 @@ class RunwareVideoSettings:
|
||||
"""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)
|
||||
use_audio = kwargs.get("useAudio", False)
|
||||
audio = kwargs.get("audio", False)
|
||||
use_prompt_upsampling = kwargs.get("usePromptUpsampling", False)
|
||||
prompt_upsampling = kwargs.get("promptUpsampling", False)
|
||||
use_background_color = kwargs.get("useBackgroundColor", False)
|
||||
background_color = (kwargs.get("backgroundColor") or "").strip()
|
||||
use_remove_background = kwargs.get("useRemoveBackground", False)
|
||||
|
||||
Reference in New Issue
Block a user