Fixed Network connection Issues and added IPAdapter nodes

This commit is contained in:
Jack
2025-02-21 17:06:22 +02:00
parent 7ace0b8196
commit b82ed10f4b
5 changed files with 125 additions and 3 deletions
+5 -1
View File
@@ -15,9 +15,11 @@ from .modules.imageCaptioning import imageCaptioning
from .modules.controlNetCombine import controlNetCombine
from .modules.embeddingSearch import embeddingSearch
from .modules.embeddingsCombine import embeddingsCombine
from .modules.ipAdapter import ipAdapter
from .modules.ipAdapterCombine import ipAdapterCombine
from .modules.vaeSearch import vaeSearch
RUNWARE_COMFYUI_VERSION = "1.0.0 Beta"
RUNWARE_COMFYUI_VERSION = "1.0.2 Beta"
RESET_COLOR = "\033[0m"
BLUE_COLOR = "\033[94m"
@@ -46,6 +48,8 @@ NODE_CLASS_MAPPINGS = {
"Runware API Manager": apiManager,
"Runware Image Caption": imageCaptioning,
"Runware ControlNet Combine": controlNetCombine,
"Runware IPAdapter": ipAdapter,
"Runware IPAdapters Combine": ipAdapterCombine,
}
NODE_DISPLAY_NAME_MAPPINGS = {
+9
View File
@@ -104,6 +104,9 @@ class txt2img:
"Lora": ("RUNWARELORA", {
"tooltip": "Connect a Runware Lora From Lora Search Node Or Lora Combine For Multiple Lora's Together.",
}),
"IPAdapters": ("RUNWAREIPAdapter", {
"tooltip": "Connect a Runware IP Adapter node or IP Adapter Combine node to use reference images for guiding the generation.",
}),
"ControlNet": ("RUNWARECONTROLNET", {
"tooltip": "Connect a Runware ControlNet Guidance Node to help the model generate images that align with the desired structure.",
}),
@@ -147,6 +150,7 @@ class txt2img:
promptWeighting = kwargs.get("Prompt Weighting", "Disabled")
runwareControlNet = kwargs.get("ControlNet", None)
runwareLora = kwargs.get("Lora", None)
runwareIPAdapters = kwargs.get("IPAdapters", None)
runwareRefiner = kwargs.get("Refiner", None)
runwareEmbedding = kwargs.get("Embeddings", None)
runwareVAE = kwargs.get("VAE", None)
@@ -202,6 +206,11 @@ class txt2img:
genConfig[0]["lora"] = runwareLora
elif (isinstance(runwareLora, dict)):
genConfig[0]["lora"] = [runwareLora]
if (runwareIPAdapters is not None):
if (isinstance(runwareIPAdapters, list)):
genConfig[0]["ipAdapters"] = runwareIPAdapters
elif (isinstance(runwareIPAdapters, dict)):
genConfig[0]["ipAdapters"] = [runwareIPAdapters]
if (runwareEmbedding is not None):
if (isinstance(runwareEmbedding, list)):
genConfig[0]["embeddings"] = runwareEmbedding
+50
View File
@@ -0,0 +1,50 @@
from .utils import runwareUtils as rwUtils
class ipAdapter:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"Reference Image": ("IMAGE",),
"Model": ([
"runware:55@1 (IP Adapter SDXL)",
"runware:55@2 (IP Adapter SDXL Plus)",
"runware:55@3 (IP Adapter SDXL Plus Face)",
"runware:55@4 (IP Adapter SDXL Vit-H)",
"runware:55@5 (IP Adapter SD 1.5)",
"runware:55@6 (IP Adapter SD 1.5 Plus)",
"runware:55@7 (IP Adapter SD 1.5 Light)",
"runware:55@8 (IP Adapter SD 1.5 Plus Face)",
"runware:55@9 (IP Adapter SD 1.5 Full Face)",
"runware:55@10 (IP Adapter SD 1.5 Vit-G)"
], {
"tooltip": "Choose IP Adapter model to use for reference-based image generation.",
"default": "runware:55@1 (IP Adapter SDXL)",
}),
"weight": ("FLOAT", {
"default": 1.0,
"min": 0.0,
"max": 1.0,
"step": 0.1,
"tooltip": "Represents the strength or influence of this IP-Adapter in the generation process.\nA value of 0 means no influence, while 1 means maximum influence.",
}),
},
}
RETURN_TYPES = ("RUNWAREIPAdapter",)
RETURN_NAMES = ("IPAdapter",)
FUNCTION = "ipAdapter"
CATEGORY = "Runware"
DESCRIPTION = "IP-Adapters enable image-prompted generation, allowing you to use reference images to guide the style and content of your generations. Multiple IP Adapters can be used simultaneously."
def ipAdapter(self, **kwargs):
refImage = kwargs.get("Reference Image")
Model = kwargs.get("Model")
weight = kwargs.get("weight")
modelAirCode = Model.split(" ")[0]
guideImage = rwUtils.convertTensor2IMG(refImage)
return ({
"model": modelAirCode,
"guideImage": guideImage,
"weight": round(weight, 2),
},)
+37
View File
@@ -0,0 +1,37 @@
class ipAdapterCombine:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"IPAdapter 1": ("RUNWAREIPAdapter", {
"tooltip": "Connect an IPAdapter from Runware IPAdapter node.",
}),
},
"optional": {
"IPAdapter 2": ("RUNWAREIPAdapter", {
"tooltip": "Connect an IPAdapter from Runware IPAdapter node.",
}),
"IPAdapter 3": ("RUNWAREIPAdapter", {
"tooltip": "Connect an IPAdapter from Runware IPAdapter node.",
}),
},
}
DESCRIPTION = "Combine multiple IPAdapters to connect with Runware Image Inference."
FUNCTION = "ipAdapterCombine"
RETURN_TYPES = ("RUNWAREIPAdapter",)
RETURN_NAMES = ("IPAdapters",)
CATEGORY = "Runware"
def ipAdapterCombine(self, **kwargs):
ipAdapter1 = kwargs.get("IPAdapter 1")
ipAdapter2 = kwargs.get("IPAdapter 2", None)
ipAdapter3 = kwargs.get("IPAdapter 3", None)
ipAdapterArray = []
ipAdapterArray.append(ipAdapter1)
if(ipAdapter2):
ipAdapterArray.append(ipAdapter2)
if(ipAdapter3):
ipAdapterArray.append(ipAdapter3)
return (ipAdapterArray,)
+24 -2
View File
@@ -10,6 +10,7 @@ import random
import base64
import torch
import uuid
import time
import os
import io
@@ -23,11 +24,26 @@ RUNWARE_REMBG_OUTPUT_FORMATS = {
}
RUNWARE_API_BASE_URL = "https://api.runware.ai/v1"
MAX_RETRIES = 2
RETRY_COOLDOWN = 2
session = requests.Session()
adapter = HTTPAdapter(pool_connections=10, pool_maxsize=10)
session.mount("http://", adapter)
session.mount("https://", adapter)
def generalRequestWrapper(recaller, *args, **kwargs):
for attempt in range(MAX_RETRIES + 1):
try:
return recaller(*args, **kwargs)
except (requests.exceptions.ConnectionError, requests.exceptions.SSLError) as e:
if attempt == MAX_RETRIES:
raise
else:
time.sleep(RETRY_COOLDOWN)
continue
return False
def getAPIKey():
apiKey = os.getenv("RUNWARE_API_KEY")
if apiKey and isinstance(apiKey, str) and len(apiKey) > 24:
@@ -138,7 +154,10 @@ def checkAPIKey(apiKey):
}]
try:
genResult = session.post(RUNWARE_API_BASE_URL, headers=headers, json=genConfig, timeout=10, allow_redirects=False, stream=True)
def recaller():
return session.post(RUNWARE_API_BASE_URL, headers=headers, json=genConfig, timeout=10, allow_redirects=False, stream=True)
genResult = generalRequestWrapper(recaller)
genResult = genResult.json()
if("errors" in genResult):
return str(genResult["errors"][0]["message"])
@@ -165,7 +184,10 @@ def inferenecRequest(genConfig):
}
try:
genResult = session.post(RUNWARE_API_BASE_URL, headers=headers, json=genConfig, timeout=SESSION_TIMEOUT, allow_redirects=False, stream=True)
def recaller():
return session.post(RUNWARE_API_BASE_URL, headers=headers, json=genConfig, timeout=SESSION_TIMEOUT, allow_redirects=False, stream=True)
genResult = generalRequestWrapper(recaller)
genResult = genResult.json()
if("errors" in genResult):
raise Exception(genResult["errors"][0]["message"])