easydiffusion/ui/plugins/ui/lora-prompt-parser.plugin.js
JeLuF b89d152540
Support lora models in subfolders when scanning the <lora> tag (#1521)
* Recursive lora search

* Support lora models in subfolders when scanning the <lora> tag
2023-08-29 10:48:57 +05:30

95 lines
3.7 KiB
JavaScript

/*
LoRA Prompt Parser 1.0
by Patrice
Copying and pasting a prompt with a LoRA tag will automatically select the corresponding option in the Easy Diffusion dropdown and remove the LoRA tag from the prompt. The LoRA must be already available in the corresponding Easy Diffusion dropdown (this is not a LoRA downloader).
*/
(function() {
"use strict"
promptField.addEventListener('input', function(e) {
let loraExtractSetting = document.getElementById("extract_lora_from_prompt")
if (!loraExtractSetting.checked) {
return
}
const { LoRA, prompt } = extractLoraTags(e.target.value);
//console.log('e.target: ' + JSON.stringify(LoRA));
if (LoRA !== null && LoRA.length > 0) {
promptField.value = prompt.replace(/,+$/, ''); // remove any trailing ,
if (testDiffusers?.checked === false) {
showToast("LoRA's are only supported with diffusers. Just stripping the LoRA tag from the prompt.")
}
}
if (LoRA !== null && LoRA.length > 0 && testDiffusers?.checked) {
let modelNames = LoRA.map(e => e.lora_model_0)
let modelWeights = LoRA.map(e => e.lora_alpha_0)
loraModelField.value = {modelNames: modelNames, modelWeights: modelWeights}
showToast("Prompt successfully processed")
}
//promptField.dispatchEvent(new Event('change'));
});
// extract LoRA tags from strings
function extractLoraTags(prompt) {
// Define the regular expression for the tags
const regex = /<(?:lora|lyco):([^:>]+)(?::([^:>]*))?(?::([^:>]*))?>/gi
// Initialize an array to hold the matches
let matches = []
// Iterate over the string, finding matches
for (const match of prompt.matchAll(regex)) {
const modelFileName = match[1].trim()
const loraPathes = getAllModelPathes("lora", modelFileName)
if (loraPathes.length > 0) {
const loraPath = loraPathes[0]
// Initialize an object to hold a match
let loraTag = {
lora_model_0: loraPath,
}
//console.log("Model:" + modelFileName);
// If weight is provided, add it to the loraTag object
if (match[2] !== undefined && match[2] !== '') {
loraTag.lora_alpha_0 = parseFloat(match[2].trim())
}
else
{
loraTag.lora_alpha_0 = 0.5
}
// If blockweights are provided, add them to the loraTag object
if (match[3] !== undefined && match[3] !== '') {
loraTag.blockweights = match[3].trim()
}
// Add the loraTag object to the array of matches
matches.push(loraTag);
//console.log(JSON.stringify(matches));
}
else
{
showToast("LoRA not found: " + match[1].trim(), 5000, true)
}
}
// Clean up the prompt string, e.g. from "apple, banana, <lora:...>, orange, <lora:...> , pear <lora:...>, <lora:...>" to "apple, banana, orange, pear"
let cleanedPrompt = prompt.replace(regex, '').replace(/(\s*,\s*(?=\s*,|$))|(^\s*,\s*)|\s+/g, ' ').trim();
//console.log('Matches: ' + JSON.stringify(matches));
// Return the array of matches and cleaned prompt string
return {
LoRA: matches,
prompt: cleanedPrompt
}
}
})()