From dd39678ba5bfe17f42570323bd23bbec4c0fc877 Mon Sep 17 00:00:00 2001 From: Sirshendu Ganguly Date: Thu, 11 Sep 2025 21:19:10 -0400 Subject: [PATCH] feat: Add Bytedance provider settings support - Added provider settings and reference images support to image inference - Created Runware Bytedance Provider Settings node with cameraFixed and maxSequentialImages - Updated image inference to handle provider settings and reference images - Added debug logging for request/response tracking - Increased timeout from 90 to 180 seconds - Fixed parameter handling for conditional inclusion --- .DS_Store | Bin 6148 -> 8196 bytes __init__.py | 4 +- modules/bytedanceImageProviderSettings.py | 65 ++++++++++++++++++ modules/imageInference.py | 38 ++++++++++ modules/utils/runwareUtils.py | 2 +- modules/videoInference.py | 10 +++ ...are_Image_Provider_Settings_Bytedance.json | 1 + 7 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 modules/bytedanceImageProviderSettings.py create mode 100644 workflows/Runware_Image_Provider_Settings_Bytedance.json diff --git a/.DS_Store b/.DS_Store index d2717f3b9c773dd92ce2308d309dc65953a6ab8d..fee792cb588b4947d29dd9d0ccb68602686c9a1b 100644 GIT binary patch literal 8196 zcmeHMTWl0n7(U;$z|27H^a7L}AR|p$qy?8-xhZUK6jDrq?TrGiyE_9+n9kIl*QcV=(&)5m(Fprg)pDW*H9Sh+~hfSX6+!xxok24Tw;D4EcaDOo9327>#lY;WCgF1c%AR1l) zc%yf^2XG%FqN#{Z3d&vSo8tC>$Q98Q1Hzs3Mrckn712pSg*$_AXNX2dbVC6jo%{@L z&X5u`?&A!^8Mr+IVfiR@WA|8roxb({?oZ?#FGt!Ba}$p32g&3&kgBQ|EL-h^zbjif8ghf4=j1By+1#*gl`~pnx90{~+qDYZ!8R>2IW}UurdRIrimvH% z-?UK3imYU`<>$_A+P0(J*u3q0yK!#ErewRZWpl^*^NPH*`TkvpGpC(#*Lz09f@nWr zHM3&7Fn3^%U+NZtRjsH5_H89FMO~~94Uec9t-eIFAD9Si&-I6`f=@J~)%q0W{=DZN zELfp_B=0%Jao5jib@{B5FFM)4>U5m6{g~yC2G*G%d>iwl5 z>Sle&$>uCa(M&N;hq_%KDT&-FTE7tPQXBNqyf;2hA^M7t?a@2+hr?kHWc^@Z!g9kY zO$l8O>Bjt1*@87tCX7Wh+DB5pTqF;jdQCg`V3)yT-m}Kd>L!PwZFr2m1@vs6j0>)FFXZti?LCVGB~|L>KyT5QmV)AdVx4JS?1m zhayTigR^)N7jO~J;d#7_H}EFj!rQovkMRjU#TU4WuQ849@EfkBDG3M=|O3)n7C9aog*``C-o6O$DTl?6YU97Fjwg$diVC-8KrY=2``rVhQ_6< zo7b-2)Uj*N4NwUbR)BXaoH>SPtTD$hFQ!@eo90!eu3S|qqnm{#3T=qMZ=I3D8q^j= z*7vTF3H;iEh;3;lwqIK)*hE{qOogUNoK+LajS7{MRu!>rTZx5W)Ezq&DlDx!Vpr}a zmT@ML=<24=Olk7JN9}v;GW(28v1vl>&+Hd=o&61&u$q8@7LL|7tVaj7VLNu>0rX-o z`mmpHJBT3+V-#bAT9a^l5;h9(5fFAC$0VM>Q+S$?`vP9XOLzsZ;u2nuF#Hj&%tGb< znW)6)bEC49F1U{8o+NDr&odokZoUju2}M(Q|L>ju@Bj0;$MQG>aR%;!44}Fv-P1*Z z%(sC`q%-Jwgr2a4c9Vi~7wSTjP|mO8L~s1Vklu|*mx}15proPppZ_6%{|b%I|9OA4 M#^*oB<=x)>1H@%D-~a#s delta 163 zcmZp1XfcprU|?W$DortDU=RQ@Ie-{MGjUEV6q~50$jG!YU^nAr0~wad$|Ax%N#(@_ zNjdpRKovVC>j@NcOH@}InHlIP7@HVRUMV2W*fsg6fIMUOWCani&1b}{88D)B*$o+(5z=Wd6p&@640=WgI~cU|?imU;)ug5Ep>OHplbKVFm#2$RCIR diff --git a/__init__.py b/__init__.py index cf24c02..0795a11 100644 --- a/__init__.py +++ b/__init__.py @@ -31,8 +31,9 @@ from .modules.frameImages import RunwareFrameImages from .modules.providerSettings import RunwareProviderSettings from .modules.pixverseProviderSettings import RunwarePixverseProviderSettings from .modules.openaiProviderSettings import RunwareOpenAIProviderSettings +from .modules.bytedanceImageProviderSettings import RunwareBytedanceProviderSettings -RUNWARE_COMFYUI_VERSION = "1.4.0 Beta" +RUNWARE_COMFYUI_VERSION = "1.3.0 Beta" RESET_COLOR = "\033[0m" BLUE_COLOR = "\033[94m" @@ -76,6 +77,7 @@ NODE_CLASS_MAPPINGS = { "Runware Provider Settings": RunwareProviderSettings, "Runware Pixverse Provider Settings": RunwarePixverseProviderSettings, "Runware OpenAI Provider Settings": RunwareOpenAIProviderSettings, + "Runware Bytedance Provider Settings": RunwareBytedanceProviderSettings, } NODE_DISPLAY_NAME_MAPPINGS = { diff --git a/modules/bytedanceImageProviderSettings.py b/modules/bytedanceImageProviderSettings.py new file mode 100644 index 0000000..9bf8529 --- /dev/null +++ b/modules/bytedanceImageProviderSettings.py @@ -0,0 +1,65 @@ +""" +Runware Bytedance Image Provider Settings Node +Provides Bytedance-specific settings for image generation +""" + +import torch +from typing import Optional, Dict, Any + +class RunwareBytedanceProviderSettings: + """Runware Bytedance Image Provider Settings Node""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": {}, + "optional": { + "cameraFixed": ("BOOLEAN", { + "tooltip": "Enable to fix camera position during video generation", + "default": False, + }), + "maxSequentialImages": ("INT", { + "tooltip": "Maximum number of sequential images to generate (1-15)", + "default": 1, + "min": 1, + "max": 15, + }), + } + } + + RETURN_TYPES = ("RUNWAREPROVIDERSETTINGS",) + RETURN_NAMES = ("providerSettings",) + FUNCTION = "create_provider_settings" + CATEGORY = "Runware/Provider Settings" + + def create_provider_settings(self, **kwargs) -> tuple[Dict[str, Any]]: + """Create Bytedance provider settings""" + + # Get parameters + cameraFixed = kwargs.get("cameraFixed", False) + maxSequentialImages = kwargs.get("maxSequentialImages", 1) + + # Build settings dictionary + settings = {} + + # Add cameraFixed only if it's true + if cameraFixed is True: + settings["cameraFixed"] = cameraFixed + + # Add maxSequentialImages if provided and valid + if maxSequentialImages is not None and 1 <= maxSequentialImages <= 15: + settings["maxSequentialImages"] = maxSequentialImages + + # 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 = { + "RunwareBytedanceProviderSettings": RunwareBytedanceProviderSettings, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "RunwareBytedanceProviderSettings": "Runware Bytedance Provider Settings", +} diff --git a/modules/imageInference.py b/modules/imageInference.py index 9cbe2c0..603b71c 100644 --- a/modules/imageInference.py +++ b/modules/imageInference.py @@ -1,4 +1,5 @@ from .utils import runwareUtils as rwUtils +import json class txt2img: @@ -153,6 +154,12 @@ class txt2img: "VAE": ("RUNWAREVAE", { "tooltip": "Connect a Runware VAE Node to help the model generate images that align with the desired structure.", }), + "referenceImages": ("RUNWAREREFERENCEIMAGES", { + "tooltip": "Connect a Runware Reference Images Node to provide visual guidance for image generation.", + }), + "providerSettings": ("RUNWAREPROVIDERSETTINGS", { + "tooltip": "Connect a Runware Provider Settings Node to configure provider-specific parameters.", + }), } } @@ -186,6 +193,8 @@ class txt2img: runwareRefiner = kwargs.get("Refiner", None) runwareEmbedding = kwargs.get("Embeddings", None) runwareVAE = kwargs.get("VAE", None) + referenceImages = kwargs.get("referenceImages", None) + providerSettings = kwargs.get("providerSettings", None) seedImage = kwargs.get("seedImage", None) seedImageStrength = kwargs.get("strength", 0.8) maskImage = kwargs.get("maskImage", None) @@ -278,9 +287,38 @@ class txt2img: if (enableMaskMargin): genConfig[0]["maskMargin"] = maskImageMargin + # Handle referenceImages + if referenceImages is not None: + genConfig[0]["referenceImages"] = referenceImages + + # Handle providerSettings - extract provider name from model and merge with custom settings + if providerSettings is not None: + # Extract provider name from model (e.g., "bytedance:1@1" -> "bytedance") + provider_name = runwareModel.split(":")[0] if ":" in runwareModel else runwareModel + + # If providerSettings is a dictionary, create the correct API format + if isinstance(providerSettings, dict): + # Create the providerSettings object with provider name as key + final_provider_settings = { + provider_name: providerSettings + } + genConfig[0]["providerSettings"] = final_provider_settings + else: + # If it's already in the correct format, use it directly + genConfig[0]["providerSettings"] = providerSettings + if (multiInferenceMode): return (None, genConfig) else: + # Debug: Print the request being sent + print(f"[DEBUG] Sending Image Inference Request:") + print(f"[DEBUG] Request Payload: {json.dumps(genConfig, indent=2)}") + genResult = rwUtils.inferenecRequest(genConfig) + + # Debug: Print the response received + print(f"[DEBUG] Received Image Inference Response:") + print(f"[DEBUG] Response: {json.dumps(genResult, indent=2)}") + images = rwUtils.convertImageB64List(genResult) return (images, None) diff --git a/modules/utils/runwareUtils.py b/modules/utils/runwareUtils.py index 851c626..081fb67 100644 --- a/modules/utils/runwareUtils.py +++ b/modules/utils/runwareUtils.py @@ -69,7 +69,7 @@ def getTimeout(): if timeout and timeout.isdigit(): return int(timeout) else: - timeout = 90 + timeout = 180 os.environ["RUNWARE_TIMEOUT"] = str(timeout) return timeout diff --git a/modules/videoInference.py b/modules/videoInference.py index d1c402b..d33c9b7 100644 --- a/modules/videoInference.py +++ b/modules/videoInference.py @@ -1,5 +1,6 @@ from .utils import runwareUtils as rwUtils from .videoModelSearch import videoModelSearch +import json class RunwareFrameImages: @@ -282,7 +283,16 @@ class txt2vid: return (None, genConfig) else: try: + # Debug: Print the request being sent + print(f"[DEBUG] Sending Video Inference Request:") + print(f"[DEBUG] Request Payload: {json.dumps(genConfig, indent=2)}") + genResult = rwUtils.inferenecRequest(genConfig) + + # Debug: Print the response received + print(f"[DEBUG] Received Video Inference Response:") + print(f"[DEBUG] Response: {json.dumps(genResult, indent=2)}") + print(f"[Debugging] Generation config: {genConfig}") except Exception as e: # Check if it's a dimension error and provide helpful information diff --git a/workflows/Runware_Image_Provider_Settings_Bytedance.json b/workflows/Runware_Image_Provider_Settings_Bytedance.json new file mode 100644 index 0000000..b060e7f --- /dev/null +++ b/workflows/Runware_Image_Provider_Settings_Bytedance.json @@ -0,0 +1 @@ +{"id":"5cf854c6-824e-4e51-995c-a2c146c44890","revision":0,"last_node_id":31,"last_link_id":28,"nodes":[{"id":29,"type":"Runware Model Search","pos":[-507.0546569824219,349.93536376953125],"size":[270,154],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"Model Search","name":"Model Search","type":"STRING","widget":{"name":"Model Search"},"link":null},{"localized_name":"Model Architecture","name":"Model Architecture","type":"COMBO","widget":{"name":"Model Architecture"},"link":null},{"localized_name":"ModelType","name":"ModelType","type":"COMBO","widget":{"name":"ModelType"},"link":null},{"localized_name":"ModelList","name":"ModelList","type":"COMBO","widget":{"name":"ModelList"},"link":null},{"localized_name":"Use Search Value","name":"Use Search Value","type":"BOOLEAN","widget":{"name":"Use Search Value"},"link":null}],"outputs":[{"localized_name":"Runware Model","name":"Runware Model","type":"RUNWAREMODEL","links":[26]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"d86e5d73b5dd90b8e8e427b373aba29bbb4ee69c","Node name for S&R":"Runware Model Search"},"widgets_values":["bytedance:5@0","All","Base Model","bytedance:5@0 (Seedream 4.0 4.0)",true],"bgcolor":"#5345bf"},{"id":28,"type":"Runware Bytedance Provider Settings","pos":[-568.9395751953125,606.0645141601562],"size":[336.4712829589844,82],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"cameraFixed","name":"cameraFixed","shape":7,"type":"BOOLEAN","widget":{"name":"cameraFixed"},"link":null},{"localized_name":"maxSequentialImages","name":"maxSequentialImages","shape":7,"type":"INT","widget":{"name":"maxSequentialImages"},"link":null}],"outputs":[{"localized_name":"providerSettings","name":"providerSettings","type":"RUNWAREPROVIDERSETTINGS","links":[25]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"d86e5d73b5dd90b8e8e427b373aba29bbb4ee69c","Node name for S&R":"Runware Bytedance Provider Settings"},"widgets_values":[false,4]},{"id":24,"type":"Runware Image Inference","pos":[-81.83966827392578,274.459228515625],"size":[400,838],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"Model","name":"Model","type":"RUNWAREMODEL","link":26},{"localized_name":"Accelerator","name":"Accelerator","shape":7,"type":"RUNWAREACCELERATOR","link":null},{"localized_name":"Lora","name":"Lora","shape":7,"type":"RUNWARELORA","link":null},{"localized_name":"Outpainting","name":"Outpainting","shape":7,"type":"RUNWAREOUTPAINT","link":null},{"localized_name":"IPAdapters","name":"IPAdapters","shape":7,"type":"RUNWAREIPAdapter","link":null},{"localized_name":"ControlNet","name":"ControlNet","shape":7,"type":"RUNWARECONTROLNET","link":null},{"localized_name":"Refiner","name":"Refiner","shape":7,"type":"RUNWAREREFINER","link":null},{"localized_name":"seedImage","name":"seedImage","shape":7,"type":"IMAGE","link":null},{"localized_name":"maskImage","name":"maskImage","shape":7,"type":"MASK","link":null},{"localized_name":"Embeddings","name":"Embeddings","shape":7,"type":"RUNWAREEMBEDDING","link":null},{"localized_name":"VAE","name":"VAE","shape":7,"type":"RUNWAREVAE","link":null},{"localized_name":"referenceImages","name":"referenceImages","shape":7,"type":"RUNWAREREFERENCEIMAGES","link":null},{"localized_name":"providerSettings","name":"providerSettings","shape":7,"type":"RUNWAREPROVIDERSETTINGS","link":25},{"localized_name":"positivePrompt","name":"positivePrompt","type":"STRING","widget":{"name":"positivePrompt"},"link":null},{"localized_name":"negativePrompt","name":"negativePrompt","type":"STRING","widget":{"name":"negativePrompt"},"link":null},{"localized_name":"Multi Inference Mode","name":"Multi Inference Mode","type":"BOOLEAN","widget":{"name":"Multi Inference Mode"},"link":null},{"localized_name":"Prompt Weighting","name":"Prompt Weighting","type":"COMBO","widget":{"name":"Prompt Weighting"},"link":null},{"localized_name":"dimensions","name":"dimensions","type":"COMBO","widget":{"name":"dimensions"},"link":null},{"localized_name":"width","name":"width","type":"INT","widget":{"name":"width"},"link":null},{"localized_name":"height","name":"height","type":"INT","widget":{"name":"height"},"link":null},{"localized_name":"useSteps","name":"useSteps","type":"BOOLEAN","widget":{"name":"useSteps"},"link":null},{"localized_name":"steps","name":"steps","type":"INT","widget":{"name":"steps"},"link":null},{"localized_name":"useScheduler","name":"useScheduler","type":"BOOLEAN","widget":{"name":"useScheduler"},"link":null},{"localized_name":"scheduler","name":"scheduler","type":"COMBO","widget":{"name":"scheduler"},"link":null},{"localized_name":"useCFGScale","name":"useCFGScale","type":"BOOLEAN","widget":{"name":"useCFGScale"},"link":null},{"localized_name":"cfgScale","name":"cfgScale","type":"FLOAT","widget":{"name":"cfgScale"},"link":null},{"localized_name":"useSeed","name":"useSeed","type":"BOOLEAN","widget":{"name":"useSeed"},"link":null},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"clipSkip","name":"clipSkip","type":"INT","widget":{"name":"clipSkip"},"link":null},{"localized_name":"strength","name":"strength","type":"FLOAT","widget":{"name":"strength"},"link":null},{"localized_name":"Mask Margin","name":"Mask Margin","type":"BOOLEAN","widget":{"name":"Mask Margin"},"link":null},{"localized_name":"maskMargin","name":"maskMargin","type":"INT","widget":{"name":"maskMargin"},"link":null},{"localized_name":"batchSize","name":"batchSize","type":"INT","widget":{"name":"batchSize"},"link":null}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[28]},{"localized_name":"RW-Task","name":"RW-Task","type":"RUNWARETASK","links":null}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"d86e5d73b5dd90b8e8e427b373aba29bbb4ee69c","Node name for S&R":"Runware Image Inference"},"widgets_values":["Generate 4 images of Pickachu wearing a suit","",false,"Disabled","Square HD (1024x1024)",1024,1024,false,4,false,"Default",false,6.5,false,668707240368594,"randomize",0,0.8,false,32,1],"bgcolor":"#5345bf"},{"id":31,"type":"PreviewImage","pos":[408.705810546875,359.56298828125],"size":[346.4169616699219,376.1732177734375],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":28}],"outputs":[],"properties":{"cnr_id":"comfy-core","ver":"0.3.46","Node name for S&R":"PreviewImage"}}],"links":[[25,28,0,24,12,"RUNWAREPROVIDERSETTINGS"],[26,29,0,24,0,"RUNWAREMODEL"],[28,24,0,31,0,"IMAGE"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.6998880220728478,"offset":[973.5689317263433,-201.61361327208994]}},"version":0.4} \ No newline at end of file