/** * Extensions helper thing or class or whatever */ const extensions = { // alwaysOnScriptsData: {}, alwaysOnScripts: false, // softInpaintingEnabled: false, //??? controlNetEnabled: false, controlNetActive: false, controlNetReferenceActive: false, controlNetReferenceFidelity: 0.5, selectedControlNetModel: null, selectedControlNetModule: null, selectedCNReferenceModule: null, controlNetModelCount: 0, dynamicPromptsEnabled: false, dynamicPromptsActive: false, dynamicPromptsAlwaysonScriptName: null, //GRUMBLE GRUMBLE enabledExtensions: [], controlNetModels: null, controlNetModules: null, async getExtensions( controlNetModelAutoComplete, controlNetModuleAutoComplete, controlNetReferenceModuleAutoComplete ) { const allowedExtensions = [ "controlnet", // "none", // "adetailer", // no API, can't verify available models "dynamic prompts", //seriously >:( why put version in the name, now i have to fuzzy match it - just simply enabled or not? no API but so so good //"segment anything", // ... API lets me get model but not processor?!?!?! //"self attention guidance", // no API but useful, just enabled button, scale and threshold sliders? ]; // check http://127.0.0.1:7860/sdapi/v1/scripts for extensions // if any of the allowed extensions are found, add them to the list var url = document.getElementById("host").value + "/sdapi/v1/scripts"; try { const response = await fetch(url); const data = await response.json(); // enable checkboxes for extensions based on existence in data data.img2img .filter((extension) => { return allowedExtensions.some((allowedExtension) => { return extension.toLowerCase().includes(allowedExtension); }); }) .forEach((extension) => { this.enabledExtensions.push(extension); }); } catch (e) { console.warn("[index] Failed to fetch extensions"); console.warn(e); } this.checkForSoftInpainting(); this.checkForDynamicPrompts(); this.checkForControlNet( controlNetModelAutoComplete, controlNetModuleAutoComplete, controlNetReferenceModuleAutoComplete ); //checkForSAM(); //or inpaintAnything or something i dunno //checkForADetailer(); //? this one seems iffy //checkForSAG(); //?? }, async checkForSoftInpainting() { this.alwaysOnScripts = true; //TODO implement, inpaint/img2img only }, async checkForDynamicPrompts() { if ( this.enabledExtensions.filter((e) => e.includes("dynamic prompts")) .length > 0 ) { // Dynamic Prompts found, enable checkbox this.alwaysOnScripts = true; this.dynamicPromptsAlwaysonScriptName = this.enabledExtensions[ this.enabledExtensions.findIndex((e) => e.includes("dynamic prompts")) ]; // this.alwaysOnScriptsData[this.dynamicPromptsAlwaysonScriptName] = {}; this.dynamicPromptsEnabled = true; document.getElementById("cbxDynPrompts").disabled = false; } // basically param 0 is true for on, false for off, that's it }, async checkForControlNet( controlNetModelAutoComplete, controlNetModuleAutoComplete, controlNetReferenceModuleAutoComplete ) { var url = document.getElementById("host").value + "/controlnet/version"; if ( this.enabledExtensions.filter((e) => e.includes("controlnet")).length > 0 ) { try { const response = await fetch(url); const data = await response.json(); if (data.version > 0) { // ControlNet found this.alwaysOnScripts = true; this.controlNetEnabled = true; document.getElementById("cbxControlNet").disabled = false; // ok cool so now we can get the models and modules this.getModels(controlNetModelAutoComplete); this.getModules( controlNetModuleAutoComplete, controlNetReferenceModuleAutoComplete ); } url = document.getElementById("host").value + "/controlnet/settings"; try { const response2 = await fetch(url); const data2 = await response2.json(); if (data2.control_net_max_models_num < 2) { document.getElementById("cbxControlNetReferenceLayer").disabled = "disabled"; console.warn( "[extensions] ControlNet reference layer disabled due to insufficient units enabled in settings - cannot be enabled via API, please increase to at least 2 units manually" ); } } catch (ex) {} } catch (e) { // ?? global.controlnetAPI = false; } } else { global.controlnetAPI = false; } }, async getModels(controlNetModelAutoComplete) { // only worry about inpaint models for now var url = document.getElementById("host").value + "/controlnet/model_list"; try { const response = await fetch(url); const data = await response.json(); this.controlNetModels = data.model_list; } catch (e) { console.warn("[extensions] Failed to fetch controlnet models"); console.warn(e); } let opt = null; opt = this.controlNetModels .filter((m) => m.includes("inpaint")) .map((option) => ({ name: option, value: option, })); controlNetModelAutoComplete.options = opt; }, async getModules( controlNetModuleAutoComplete, controlNetReferenceModuleAutoComplete ) { const allowedModules = ["reference", "inpaint"]; var url = document.getElementById("host").value + "/controlnet/module_list"; try { const response = await fetch(url); const data = await response.json(); this.controlNetModules = data; } catch (e) { console.warn("[extensions] Failed to fetch controlnet modules"); console.warn(e); } let opt = null; opt = this.controlNetModules.module_list .filter((m) => m.includes("inpaint")) // why is there just "inpaint" in the modules if it's not in the ui .map((option) => ({ name: option, value: option, })); opt.push({ name: "inpaint_global_harmonious", value: "inpaint_global_harmonious", // WTF WHY IS THIS ONE NOT LISTED IN MODULES BUT DISTINCT IN THE API CALL?!?!?!??!??! it is slightly different from "inpaint" from what i can tell }); controlNetModuleAutoComplete.options = opt; opt = this.controlNetModules.module_list .filter((m) => m.includes("reference")) .map((option) => ({ name: option, value: option, })); controlNetReferenceModuleAutoComplete.options = opt; }, };