From 7b3f97129cfa1bfb03ae16fca0c71b4128efdceb Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 18 Dec 2024 10:15:50 +0200 Subject: [PATCH] Hot Patch For loading workflows with custom model, Increased search results to 20, Adjusted strength to be single Precision point, Added Image Captioning workflow --- __init__.py | 2 +- clientlibs/main.js | 6 +++ clientlibs/utils.js | 39 ++++++++++++++++++- modules/bridges/mainRoute.py | 2 +- modules/imageInference.py | 4 +- .../Runware_Image_Inference_Captioning.json | 1 + 6 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 workflows/Runware_Image_Inference_Captioning.json diff --git a/__init__.py b/__init__.py index efd05cc..643926a 100644 --- a/__init__.py +++ b/__init__.py @@ -17,7 +17,7 @@ from .modules.embeddingSearch import embeddingSearch from .modules.embeddingsCombine import embeddingsCombine from .modules.vaeSearch import vaeSearch -RUNWARE_COMFYUI_VERSION = "0.9.2 Beta" +RUNWARE_COMFYUI_VERSION = "0.9.3 Beta" RESET_COLOR = "\033[0m" BLUE_COLOR = "\033[94m" diff --git a/clientlibs/main.js b/clientlibs/main.js index 3b339f4..19702a6 100644 --- a/clientlibs/main.js +++ b/clientlibs/main.js @@ -3,6 +3,7 @@ import { api } from "../../scripts/api.js"; import { promptEnhanceHandler, syncDimensionsNodeHandler, searchNodeHandler, APIKeyHandler, captionNodeHandler, handleCustomErrors } from "./utils.js"; import { RUNWARE_NODE_TYPES, RUNWARE_NODE_PROPS, SEARCH_TERMS } from "./types.js"; +const nodeInitList = []; app.registerExtension({ name: "runware.ai", async setup() { @@ -47,9 +48,14 @@ app.registerExtension({ if(crNodeProps.liveSearch === true) { if(widgetType === "text" && SEARCH_TERMS.includes(widgetName)) { + node.callback = function(){}; searchNodeHandler(node, nodeWidget); + nodeInitList.push(node); } } } + }, + loadedGraphNode(node) { + if(nodeInitList.includes(node)) node.callback(); } }) \ No newline at end of file diff --git a/clientlibs/utils.js b/clientlibs/utils.js index 0dc9d9c..fd6bbfd 100644 --- a/clientlibs/utils.js +++ b/clientlibs/utils.js @@ -333,8 +333,13 @@ async function searchNodeHandler(searchNode, searchInputWidget) { } } - async function searchModels() { - let searchQuery = searchInputWidget.value.trim(); + async function searchModels(exactQuery = null, returnOutput = false) { + let searchQuery; + if(exactQuery) { + searchQuery = exactQuery; + } else { + searchQuery = searchInputWidget.value.trim(); + } searchQuery = shortenAirCode(searchQuery); const modelArchValue = DEFAULT_MODELS_ARCH_LIST[modelArchWidget.value]; if(isControlNet) { @@ -365,9 +370,25 @@ async function searchNodeHandler(searchNode, searchInputWidget) { if(isEmbedding) embeddingTriggerWordsList[modelObj.air] = modelObj.positiveTriggerWords.trim(); modelListArray.push(`${modelObj.air} (${modelObj.name} ${modelObj.version})`); }); + + if(exactQuery) { + const extraSearch = await searchModels(null, true); + if(extraSearch) { + const newModelList = [...new Set([...modelListArray, ...extraSearch])]; + modelListWidget.options.values = newModelList; + return; + } + } + + if(returnOutput) return modelListArray; modelListWidget.options.values = modelListArray; modelListWidget.value = modelListArray[0]; } else { + if(returnOutput) return false; + if(exactQuery) { + notifyUser("Failed To Load Workflow's Model List Value!", "error", "Runware Search"); + return; + } notifyUser(modelSearchResults.error, "error", "Runware Search"); } } @@ -406,6 +427,7 @@ async function searchNodeHandler(searchNode, searchInputWidget) { runwareButton.addEventListener("click", async () => { const chosenLora = modelListWidget.value.split(" ")[0]; + if(!triggerWordsList.hasOwnProperty(chosenLora)) return; const triggerWords = triggerWordsList[chosenLora]; if(triggerWords.length > 0) { const positivePromptWidget = findTargetWidget(searchNode, "positivePrompt"); @@ -434,6 +456,7 @@ async function searchNodeHandler(searchNode, searchInputWidget) { runwareButton.addEventListener("click", async () => { const chosenEmbedding = modelListWidget.value.split(" ")[0]; + if (!embeddingTriggerWordsList.hasOwnProperty(chosenEmbedding)) return; const triggerWords = embeddingTriggerWordsList[chosenEmbedding]; if(triggerWords.length > 0) { const negativePromptWidget = findTargetWidget(searchNode, "negativePrompt"); @@ -480,6 +503,18 @@ async function searchNodeHandler(searchNode, searchInputWidget) { await searchModels(); }); } + + appendWidgetCB(searchNode, async function(...args) { + try { + let modelListValues = modelListWidget.options.values; + if(modelListValues.length <= 0) return; + modelListValues = modelListValues.map(model => model.split(" ")[0]); + const modelListCRValue = modelListWidget.value.split(" ")[0]; + if(!modelListValues.includes(modelListCRValue)) { + searchModels(modelListCRValue); + } + } catch(e) {} + }); } export { diff --git a/modules/bridges/mainRoute.py b/modules/bridges/mainRoute.py index c69a0d6..20401e3 100644 --- a/modules/bridges/mainRoute.py +++ b/modules/bridges/mainRoute.py @@ -66,7 +66,7 @@ async def modelSearch(reqPayload): "taskType": "modelSearch", "taskUUID": rwUtils.genRandUUID(), "category": modelCategory, - "limit": 15, + "limit": 20, "sort": "-downloadCount", }] diff --git a/modules/imageInference.py b/modules/imageInference.py index bd68804..9b60677 100644 --- a/modules/imageInference.py +++ b/modules/imageInference.py @@ -78,10 +78,10 @@ class txt2img: }), "strength": ("FLOAT", { "tooltip": "When doing Image-to-Image or Inpainting, this parameter is used to determine the influence of the seedImage image in the generated output. A lower value results in more influence from the original image, while a higher value allows more creative deviation.", - "default": 0.80, + "default": 0.8, "min": 0.0, "max": 1.0, - "step": 0.05, + "step": 0.1, }), "Mask Margin": ("BOOLEAN", { "tooltip": "Enables Or Disables Mask Margin Feature.", diff --git a/workflows/Runware_Image_Inference_Captioning.json b/workflows/Runware_Image_Inference_Captioning.json new file mode 100644 index 0000000..c89efde --- /dev/null +++ b/workflows/Runware_Image_Inference_Captioning.json @@ -0,0 +1 @@ +{"last_node_id":14,"last_link_id":13,"nodes":[{"id":11,"type":"Runware Image Inference","pos":[831.05029296875,183.88824462890625],"size":[400,602],"flags":{},"order":3,"mode":0,"inputs":[{"name":"Model","type":"RUNWAREMODEL","link":13},{"name":"Lora","type":"RUNWARELORA","link":null,"shape":7},{"name":"ControlNet","type":"RUNWARECONTROLNET","link":null,"shape":7},{"name":"Refiner","type":"RUNWAREREFINER","link":null,"shape":7},{"name":"seedImage","type":"IMAGE","link":null,"shape":7},{"name":"maskImage","type":"MASK","link":null,"shape":7},{"name":"Embeddings","type":"RUNWAREEMBEDDING","link":null,"shape":7},{"name":"VAE","type":"RUNWAREVAE","link":null,"shape":7},{"name":"positivePrompt","type":"STRING","link":11,"widget":{"name":"positivePrompt"}}],"outputs":[{"name":"IMAGE","type":"IMAGE","links":[10],"slot_index":0}],"properties":{"Node name for S&R":"Runware Image Inference"},"widgets_values":["","","Disabled","Square (512x512)",512,512,4,"Default",6.5,229459996454677,"randomize",0,0.9,false,32,1],"bgcolor":"#6c5ce7"},{"id":14,"type":"Runware Model Search","pos":[497.6798095703125,175.9790802001953],"size":[315,130],"flags":{"collapsed":false},"order":0,"mode":0,"inputs":[],"outputs":[{"name":"Runware Model","type":"RUNWAREMODEL","links":[13],"slot_index":0}],"properties":{"Node name for S&R":"Runware Model Search"},"widgets_values":["","All","Base Model","runware:100@1 (Flux Schnell)"],"bgcolor":"#6c5ce7"},{"id":10,"type":"LoadImage","pos":[241.08689880371094,350.3967590332031],"size":[236.30767822265625,325.9602966308594],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[{"name":"IMAGE","type":"IMAGE","links":[12],"slot_index":0},{"name":"MASK","type":"MASK","links":null}],"properties":{"Node name for S&R":"LoadImage"},"widgets_values":["qwd2s.jpg","image"]},{"id":13,"type":"Runware Image Caption","pos":[513.2827758789062,373.235595703125],"size":[278.0941162109375,190.92190551757812],"flags":{},"order":2,"mode":0,"inputs":[{"name":"Image","type":"IMAGE","link":12}],"outputs":[{"name":"IMAGE PROMPT","type":"STRING","links":[11],"slot_index":0}],"properties":{"Node name for S&R":"Runware Image Caption"},"widgets_values":[false,"cartoon girl with a skull on her and a city in the background, profile picture 1024px, 🎀 🧟 🍓 🧚, very short curly hair, comicbook art, icon for an ai app, dressed black hoodie, e-girl, anime colours"],"bgcolor":"#6c5ce7"},{"id":12,"type":"PreviewImage","pos":[1269.0423583984375,236.072021484375],"size":[515.3893432617188,538.380126953125],"flags":{},"order":4,"mode":0,"inputs":[{"name":"images","type":"IMAGE","link":10}],"outputs":[],"properties":{"Node name for S&R":"PreviewImage"},"widgets_values":[]}],"links":[[10,11,0,12,0,"IMAGE"],[11,13,0,11,8,"STRING"],[12,10,0,13,0,"IMAGE"],[13,14,0,11,0,"RUNWAREMODEL"]],"groups":[],"config":{},"extra":{"ds":{"scale":1.026316236461414,"offset":[-218.03843002977476,-95.65528646365456]}},"version":0.4} \ No newline at end of file