Merge pull request #60 from Runware/feature-GoogleSettings

Add Google Provider Settings feature
This commit is contained in:
Sirshendu Ganguly
2025-12-16 14:29:06 -05:00
committed by GitHub
10 changed files with 348 additions and 1 deletions
+4
View File
@@ -55,6 +55,7 @@ from .modules.providerSettings.runwayProviderSettings import RunwareRunwayProvid
from .modules.providerSettings.lumaProviderSettings import RunwareLumaProviderSettings
from .modules.providerSettings.midjourneyProviderSettings import RunwareMidjourneyProviderSettings
from .modules.providerSettings.alibabaProviderSettings import RunwareAlibabaProviderSettings
from .modules.providerSettings.googleProviderSettings import RunwareGoogleProviderSettings
from .modules.providerSettings.blackForestProviderSettings import RunwareBlackForestProviderSettings
from .modules.providerSettings.syncSegment import RunwareSyncSegment
from .modules.providerSettings.syncProviderSettings import RunwareSyncProviderSettings
@@ -64,6 +65,7 @@ from .modules.videoUpscaler import videoUpscaler
from .modules.videoInputsReferences import videoInputsReferences
from .modules.videoInputsFrame import RunwareVideoInputsFrameImages
from .modules.safetyInputs import safetyInputs
from .modules.settings import RunwareSettings
from .modules.videoAdvancedFeatureInputs import videoAdvancedFeatureInputs
RUNWARE_COMFYUI_VERSION = "1.4.0 Beta"
@@ -134,6 +136,7 @@ NODE_CLASS_MAPPINGS = {
"Runware Runway Provider Settings": RunwareRunwayProviderSettings,
"Runware Midjourney Provider Settings": RunwareMidjourneyProviderSettings,
"Runware Alibaba Provider Settings": RunwareAlibabaProviderSettings,
"Runware Google Provider Settings": RunwareGoogleProviderSettings,
"Runware BlackForest Labs Provider Settings": RunwareBlackForestProviderSettings,
"Runware Sync Segment": RunwareSyncSegment,
"Runware Sync Provider Settings": RunwareSyncProviderSettings,
@@ -143,6 +146,7 @@ NODE_CLASS_MAPPINGS = {
"Runware Video Inputs References": videoInputsReferences,
"Runware Video Inputs Frame Images": RunwareVideoInputsFrameImages,
"Runware Safety Inputs": safetyInputs,
"Runware Settings": RunwareSettings,
"Runware Video Advanced Feature Inputs": videoAdvancedFeatureInputs,
}
+5 -1
View File
@@ -1,6 +1,6 @@
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js";
import { promptEnhanceHandler, syncDimensionsNodeHandler, searchNodeHandler, APIKeyHandler, captionNodeHandler, mediaUUIDHandler, videoTranscriptionHandler, handleCustomErrors, videoInferenceDimensionsHandler, videoModelSearchFilterHandler, audioModelSearchFilterHandler, useParameterToggleHandler, imageInferenceToggleHandler, upscalerToggleHandler, videoUpscalerToggleHandler, audioInferenceToggleHandler, acceleratorOptionsToggleHandler, bytedanceProviderSettingsToggleHandler, openaiProviderSettingsToggleHandler, lightricksProviderSettingsToggleHandler, klingProviderSettingsToggleHandler, lumaProviderSettingsToggleHandler, briaProviderSettingsToggleHandler, pixverseProviderSettingsToggleHandler, alibabaProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler } from "./utils.js";
import { promptEnhanceHandler, syncDimensionsNodeHandler, searchNodeHandler, APIKeyHandler, captionNodeHandler, mediaUUIDHandler, videoTranscriptionHandler, handleCustomErrors, videoInferenceDimensionsHandler, videoModelSearchFilterHandler, audioModelSearchFilterHandler, useParameterToggleHandler, imageInferenceToggleHandler, upscalerToggleHandler, videoUpscalerToggleHandler, audioInferenceToggleHandler, acceleratorOptionsToggleHandler, bytedanceProviderSettingsToggleHandler, openaiProviderSettingsToggleHandler, lightricksProviderSettingsToggleHandler, klingProviderSettingsToggleHandler, lumaProviderSettingsToggleHandler, briaProviderSettingsToggleHandler, pixverseProviderSettingsToggleHandler, alibabaProviderSettingsToggleHandler, googleProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler, settingsToggleHandler } from "./utils.js";
import { RUNWARE_NODE_TYPES, RUNWARE_NODE_PROPS, SEARCH_TERMS } from "./types.js";
const nodeInitList = [];
@@ -73,10 +73,14 @@ app.registerExtension({
pixverseProviderSettingsToggleHandler(node);
} else if(nodeClass === RUNWARE_NODE_TYPES.ALIBABAPROVIDERSETTINGS) {
alibabaProviderSettingsToggleHandler(node);
} else if(nodeClass === RUNWARE_NODE_TYPES.GOOGLEPROVIDERSETTINGS) {
googleProviderSettingsToggleHandler(node);
} else if(nodeClass === RUNWARE_NODE_TYPES.SYNCPROVIDERSETTINGS) {
syncProviderSettingsToggleHandler(node);
} else if(nodeClass === RUNWARE_NODE_TYPES.SYNCSEGMENT) {
syncSegmentToggleHandler(node);
} else if(nodeClass === RUNWARE_NODE_TYPES.SETTINGS) {
settingsToggleHandler(node);
}
if(crNodeProps.colorModeOnly === true) return;
+10
View File
@@ -102,6 +102,7 @@ const RUNWARE_NODE_TYPES = {
LUMAPROVIDERSETTINGS: "Runware Luma Provider Settings",
MIDJOURNEYPROVIDERSETTINGS: "Runware Midjourney Provider Settings",
ALIBABAPROVIDERSETTINGS: "Runware Alibaba Provider Settings",
GOOGLEPROVIDERSETTINGS: "Runware Google Provider Settings",
SYNCSEGMENT: "Runware Sync Segment",
SYNCPROVIDERSETTINGS: "Runware Sync Provider Settings",
VECTORIZE: "Runware Vectorize",
@@ -113,6 +114,7 @@ const RUNWARE_NODE_TYPES = {
VIDEOTRANSCRIPTION: "Runware Video Transcription",
MINIMAXPROVIDERSETTINGS: "Runware MiniMax Provider Settings",
SAFETYINPUTS: "Runware Safety Inputs",
SETTINGS: "Runware Settings",
VIDEOADVANCEDFEATUREINPUTS: "Runware Video Advanced Feature Inputs",
};
@@ -336,6 +338,10 @@ const RUNWARE_NODE_PROPS = {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.GOOGLEPROVIDERSETTINGS]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.SYNCSEGMENT]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
@@ -381,6 +387,10 @@ const RUNWARE_NODE_PROPS = {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.SETTINGS]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.VIDEOADVANCEDFEATUREINPUTS]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
+128
View File
@@ -2466,10 +2466,138 @@ export {
briaProviderSettingsToggleHandler,
pixverseProviderSettingsToggleHandler,
alibabaProviderSettingsToggleHandler,
googleProviderSettingsToggleHandler,
syncProviderSettingsToggleHandler,
syncSegmentToggleHandler,
settingsToggleHandler,
};
function googleProviderSettingsToggleHandler(googleNode) {
// Find all "use" parameter widgets for Google Provider Settings
const useGenerateAudioWidget = googleNode.widgets.find(w => w.name === "useGenerateAudio");
const generateAudioWidget = googleNode.widgets.find(w => w.name === "generateAudio");
const useEnhancePromptWidget = googleNode.widgets.find(w => w.name === "useEnhancePrompt");
const enhancePromptWidget = googleNode.widgets.find(w => w.name === "enhancePrompt");
const useSearchWidget = googleNode.widgets.find(w => w.name === "useSearch");
const searchWidget = googleNode.widgets.find(w => w.name === "search");
// Helper function to toggle widget enabled state
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function toggleEnabled() {
const enabled = useWidget.value === true;
if (paramWidget.inputEl) {
paramWidget.inputEl.disabled = !enabled;
paramWidget.inputEl.style.opacity = enabled ? "1" : "0.5";
paramWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
paramWidget.inputEl.readOnly = !enabled;
}
paramWidget.disabled = !enabled;
if (!paramWidget.inputEl) {
const nodeElement = googleNode.htmlElements?.widgetsContainer || googleNode.htmlElements;
if (nodeElement) {
const input = nodeElement.querySelector(`input[name="${paramName}"], textarea[name="${paramName}"], select[name="${paramName}"]`);
if (input) {
input.disabled = !enabled;
input.style.opacity = enabled ? "1" : "0.5";
input.style.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
googleNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
// Set up toggle handlers
if (useGenerateAudioWidget && generateAudioWidget) {
toggleWidgetState(useGenerateAudioWidget, generateAudioWidget, "generateAudio");
}
if (useEnhancePromptWidget && enhancePromptWidget) {
toggleWidgetState(useEnhancePromptWidget, enhancePromptWidget, "enhancePrompt");
}
if (useSearchWidget && searchWidget) {
toggleWidgetState(useSearchWidget, searchWidget, "search");
}
}
function settingsToggleHandler(settingsNode) {
// Find all "use" parameter widgets for Settings
const useTemperatureWidget = settingsNode.widgets.find(w => w.name === "useTemperature");
const temperatureWidget = settingsNode.widgets.find(w => w.name === "temperature");
const useSystemPromptWidget = settingsNode.widgets.find(w => w.name === "useSystemPrompt");
const systemPromptWidget = settingsNode.widgets.find(w => w.name === "systemPrompt");
const useTopPWidget = settingsNode.widgets.find(w => w.name === "useTopP");
const topPWidget = settingsNode.widgets.find(w => w.name === "topP");
// Helper function to toggle widget enabled state
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function toggleEnabled() {
const enabled = useWidget.value === true;
if (paramWidget.inputEl) {
paramWidget.inputEl.disabled = !enabled;
paramWidget.inputEl.style.opacity = enabled ? "1" : "0.5";
paramWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
paramWidget.inputEl.readOnly = !enabled;
}
paramWidget.disabled = !enabled;
if (!paramWidget.inputEl) {
const nodeElement = settingsNode.htmlElements?.widgetsContainer || settingsNode.htmlElements;
if (nodeElement) {
const input = nodeElement.querySelector(`input[name="${paramName}"], textarea[name="${paramName}"], select[name="${paramName}"]`);
if (input) {
input.disabled = !enabled;
input.style.opacity = enabled ? "1" : "0.5";
input.style.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
settingsNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
// Set up toggle handlers
if (useTemperatureWidget && temperatureWidget) {
toggleWidgetState(useTemperatureWidget, temperatureWidget, "temperature");
}
if (useSystemPromptWidget && systemPromptWidget) {
toggleWidgetState(useSystemPromptWidget, systemPromptWidget, "systemPrompt");
}
if (useTopPWidget && topPWidget) {
toggleWidgetState(useTopPWidget, topPWidget, "topP");
}
}
function syncProviderSettingsToggleHandler(syncNode) {
// Find all "use" parameter widgets for Sync Provider Settings
const useEditRegionWidget = syncNode.widgets.find(w => w.name === "useEditRegion");
+8
View File
@@ -188,6 +188,9 @@ class txt2img:
"safetyInputs": ("RUNWARESAFETYINPUTS", {
"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.",
}),
}
}
@@ -229,6 +232,7 @@ class txt2img:
inputs = kwargs.get("inputs", None)
providerSettings = kwargs.get("providerSettings", None)
safetyInputs = kwargs.get("safetyInputs", None)
settings = kwargs.get("settings", None)
seedImage = kwargs.get("seedImage", None)
seedImageStrength = kwargs.get("strength", 0.8)
maskImage = kwargs.get("maskImage", None)
@@ -386,6 +390,10 @@ class txt2img:
if safetyInputs is not None and isinstance(safetyInputs, dict) and len(safetyInputs) > 0:
genConfig[0]["safety"] = safetyInputs
# Add settings if provided
if settings is not None and isinstance(settings, dict) and len(settings) > 0:
genConfig[0]["settings"] = settings
if (multiInferenceMode):
return (None, genConfig)
else:
@@ -0,0 +1,95 @@
"""
Runware Google Provider Settings Node
Provides Google-specific settings for image/video generation
"""
from typing import Optional, Dict, Any
class RunwareGoogleProviderSettings:
"""Runware Google Provider Settings Node"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {},
"optional": {
"useGenerateAudio": ("BOOLEAN", {
"tooltip": "Enable to include generateAudio parameter in provider settings",
"default": False,
}),
"generateAudio": ("BOOLEAN", {
"tooltip": "Enable audio generation. Only used when 'Use Generate Audio' is enabled.",
"default": False,
"label_on": "Enabled",
"label_off": "Disabled",
}),
"useEnhancePrompt": ("BOOLEAN", {
"tooltip": "Enable to include enhancePrompt parameter in provider settings",
"default": False,
}),
"enhancePrompt": ("BOOLEAN", {
"tooltip": "Enable prompt enhancement for Google generation. Only used when 'Use Enhance Prompt' is enabled.",
"default": False,
"label_on": "Enabled",
"label_off": "Disabled",
}),
"useSearch": ("BOOLEAN", {
"tooltip": "Enable to include search parameter in provider settings",
"default": False,
}),
"search": ("BOOLEAN", {
"tooltip": "Enable search functionality. Only used when 'Use Search' is enabled.",
"default": False,
"label_on": "Enabled",
"label_off": "Disabled",
}),
}
}
RETURN_TYPES = ("RUNWAREPROVIDERSETTINGS",)
RETURN_NAMES = ("Provider Settings",)
FUNCTION = "createProviderSettings"
CATEGORY = "Runware/Provider Settings"
DESCRIPTION = "Configure Google-specific provider settings for image/video generation including audio generation, prompt enhancement, and search."
def createProviderSettings(self, **kwargs) -> tuple[Dict[str, Any]]:
"""Create Google provider settings"""
# Get control parameters
useGenerateAudio = kwargs.get("useGenerateAudio", False)
useEnhancePrompt = kwargs.get("useEnhancePrompt", False)
useSearch = kwargs.get("useSearch", False)
# Get value parameters
generateAudio = kwargs.get("generateAudio", False)
enhancePrompt = kwargs.get("enhancePrompt", False)
search = kwargs.get("search", False)
# Build settings dictionary - only include what is enabled
googleSettings: Dict[str, Any] = {}
# Add parameters only if their use toggles are enabled
if useGenerateAudio:
googleSettings["generateAudio"] = generateAudio
if useEnhancePrompt:
googleSettings["enhancePrompt"] = enhancePrompt
if useSearch:
googleSettings["search"] = search
# Clean up None values
googleSettings = {k: v for k, v in googleSettings.items() if v is not None}
# Return flat dictionary - will be wrapped by inference node with provider name
return (googleSettings,)
# Node class mappings
NODE_CLASS_MAPPINGS = {
"RunwareGoogleProviderSettings": RunwareGoogleProviderSettings,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RunwareGoogleProviderSettings": "Runware Google Provider Settings",
}
+95
View File
@@ -0,0 +1,95 @@
"""
Runware Settings Node
Provides general settings for image generation including temperature, systemPrompt, and topP
"""
from typing import Optional, Dict, Any
class RunwareSettings:
"""Runware Settings Node"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {},
"optional": {
"useTemperature": ("BOOLEAN", {
"tooltip": "Enable to include temperature parameter in API request",
"default": False,
}),
"temperature": ("FLOAT", {
"tooltip": "Temperature value for generation. Only used when 'Use Temperature' is enabled.",
"default": 1.0,
"min": 0.0,
"max": 2.0,
"step": 0.1,
}),
"useSystemPrompt": ("BOOLEAN", {
"tooltip": "Enable to include systemPrompt parameter in API request",
"default": False,
}),
"systemPrompt": ("STRING", {
"multiline": True,
"tooltip": "System prompt for generation. Only used when 'Use System Prompt' is enabled.",
"default": "",
}),
"useTopP": ("BOOLEAN", {
"tooltip": "Enable to include topP parameter in API request",
"default": False,
}),
"topP": ("FLOAT", {
"tooltip": "Top-p (nucleus) sampling parameter. Only used when 'Use Top P' is enabled.",
"default": 1.0,
"min": 0.0,
"max": 1.0,
"step": 0.01,
}),
}
}
RETURN_TYPES = ("RUNWARESETTINGS",)
RETURN_NAMES = ("Settings",)
FUNCTION = "createSettings"
CATEGORY = "Runware"
DESCRIPTION = "Configure general settings for image generation including temperature, system prompt, and top-p sampling."
def createSettings(self, **kwargs) -> tuple[Dict[str, Any]]:
"""Create settings configuration"""
# Get control parameters
useTemperature = kwargs.get("useTemperature", False)
useSystemPrompt = kwargs.get("useSystemPrompt", False)
useTopP = kwargs.get("useTopP", False)
# Get value parameters
temperature = kwargs.get("temperature", 1.0)
systemPrompt = kwargs.get("systemPrompt", "")
topP = kwargs.get("topP", 1.0)
# Build settings dictionary - only include what is enabled
settings: Dict[str, Any] = {}
# Add optional parameters only if enabled
if useTemperature:
settings["temperature"] = float(temperature)
if useSystemPrompt and systemPrompt and systemPrompt.strip():
settings["systemPrompt"] = systemPrompt.strip()
if useTopP:
settings["topP"] = float(topP)
# 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",
}
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