Add basic dynamic prompting with seeding on CLIPTextEncode node
This commit is contained in:
parent
09f1d76ed8
commit
e2e5c4c5b0
2
nodes.py
2
nodes.py
|
@ -44,7 +44,7 @@ def filter_files_extensions(files, extensions):
|
|||
class CLIPTextEncode:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {"required": {"text": ("STRING", {"multiline": True}), "clip": ("CLIP", )}}
|
||||
return {"required": {"text": ("STRING", {"multiline": True, "dynamic_prompt": True}), "clip": ("CLIP", )}}
|
||||
RETURN_TYPES = ("CONDITIONING",)
|
||||
FUNCTION = "encode"
|
||||
|
||||
|
|
|
@ -133,13 +133,14 @@ function onObjectInfo(json) {
|
|||
min_height = 1;
|
||||
min_width = 1;
|
||||
for (let x in inp) {
|
||||
let default_val = min_val = max_val = step_val = multiline = undefined;
|
||||
let default_val = min_val = max_val = step_val = multiline = dynamic_prompt = undefined;
|
||||
if (inp[x].length > 1) {
|
||||
default_val = inp[x][1]['default'];
|
||||
min_val = inp[x][1]['min'];
|
||||
max_val = inp[x][1]['max'];
|
||||
step_val = inp[x][1]['step'];
|
||||
multiline = inp[x][1]['multiline'];
|
||||
dynamic_prompt = inp[x][1]['dynamic_prompt'];
|
||||
}
|
||||
|
||||
let type = inp[x][0];
|
||||
|
@ -173,11 +174,21 @@ function onObjectInfo(json) {
|
|||
} else if (type == "STRING") {
|
||||
if (default_val == undefined) default_val = "";
|
||||
if (multiline == undefined) multiline = false;
|
||||
if (dynamic_prompt == undefined) dynamic_prompt = false;
|
||||
|
||||
if (dynamic_prompt)
|
||||
{
|
||||
w1 = this.addWidget("number", "seed", 0, function(v){let s = this.options.step / 10;this.value = Math.round( v / s ) * s;}, { min: min_val, max: max_val, step: 10.0 * step_val} );
|
||||
w2 = this.addWidget("toggle", "Random seed after every gen", true, function(v){}, { on: "enabled", off:"disabled"} );
|
||||
w2.to_randomize = w1;
|
||||
this._widgets += [w1, w2];
|
||||
}
|
||||
|
||||
if (multiline) {
|
||||
var w = {
|
||||
type: "customtext",
|
||||
name: x,
|
||||
dynamic_prompt: dynamic_prompt,
|
||||
get value() { return this.input_div.innerText;},
|
||||
set value(x) { this.input_div.innerText = x;},
|
||||
callback: function(v){console.log(v);},
|
||||
|
@ -252,6 +263,7 @@ function onObjectInfo(json) {
|
|||
}
|
||||
} else {
|
||||
w = this.addWidget("text", x, default_val, function(v){}, { multiline:false } );
|
||||
w.dynamic_prompt = dynamic_prompt;
|
||||
this._widgets += [w];
|
||||
}
|
||||
} else {
|
||||
|
@ -300,6 +312,16 @@ graph.onNodeRemoved = function(n) {
|
|||
}
|
||||
}
|
||||
|
||||
// from https://stackoverflow.com/a/47593316
|
||||
function rng_mulberry32(a) {
|
||||
return function() {
|
||||
var t = a += 0x6D2B79F5;
|
||||
t = Math.imul(t ^ t >>> 15, t | 1);
|
||||
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
||||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||||
}
|
||||
}
|
||||
|
||||
function graphToPrompt() {
|
||||
let s = graph.serialize();
|
||||
let output = {};
|
||||
|
@ -309,6 +331,45 @@ function graphToPrompt() {
|
|||
for (let x in nodes) {
|
||||
let n = graph.getNodeById(nodes[x].id);
|
||||
let input_ = {};
|
||||
|
||||
// dynamic prompts handling
|
||||
if (n.widgets && n.widgets.length > 0) {
|
||||
// find widgets declared as supporting dynamic prompting
|
||||
var supportedWidgets = n.widgets.filter(e => e.dynamic_prompt === true);
|
||||
if (supportedWidgets.length > 0) {
|
||||
// find the seed widget to use for this node
|
||||
var seed = n.widgets.filter(e => e.name === "seed")[0].value;
|
||||
var rng = rng_mulberry32(seed);
|
||||
|
||||
// resolve dynamic prompts for all widgets supporting it in this node
|
||||
for (let i in supportedWidgets)
|
||||
{
|
||||
var widget = supportedWidgets[i];
|
||||
|
||||
// store the unresolved prompt to restore it after sending the resolved prompt to the backend
|
||||
// use of .innerText which keep \n symbols in order to not break multilines support
|
||||
widget.value_initial = widget.input_div.innerText;
|
||||
|
||||
// resolve the string
|
||||
var prompt = widget.input_div.textContent;
|
||||
while (prompt.includes('{') && prompt.includes('}')) {
|
||||
const startIndex = prompt.indexOf('{');
|
||||
const endIndex = prompt.indexOf('}');
|
||||
|
||||
const optionsString = prompt.substring(startIndex + 1, endIndex);
|
||||
const options = optionsString.split('|');
|
||||
|
||||
const randomIndex = Math.floor(rng() * (options.length));
|
||||
const randomOption = options[randomIndex];
|
||||
|
||||
prompt = prompt.substring(0, startIndex) + randomOption + prompt.substring(endIndex + 1);
|
||||
}
|
||||
|
||||
widget.value = prompt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let y in n.widgets) {
|
||||
input_[n.widgets[y].name] = n.widgets[y].value;
|
||||
}
|
||||
|
@ -378,6 +439,10 @@ function promptPosted(data)
|
|||
wid.to_randomize.value = Math.floor(Math.random() * 1125899906842624);
|
||||
}
|
||||
}
|
||||
|
||||
// restore initial values replaced by dynamic prompting
|
||||
if (wid.dynamic_prompt && wid.dynamic_prompt === true)
|
||||
wid.value = wid.value_initial;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue