mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2025-01-11 02:15:17 +00:00
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:
|
class CLIPTextEncode:
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
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",)
|
RETURN_TYPES = ("CONDITIONING",)
|
||||||
FUNCTION = "encode"
|
FUNCTION = "encode"
|
||||||
|
|
||||||
|
@ -133,13 +133,14 @@ function onObjectInfo(json) {
|
|||||||
min_height = 1;
|
min_height = 1;
|
||||||
min_width = 1;
|
min_width = 1;
|
||||||
for (let x in inp) {
|
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) {
|
if (inp[x].length > 1) {
|
||||||
default_val = inp[x][1]['default'];
|
default_val = inp[x][1]['default'];
|
||||||
min_val = inp[x][1]['min'];
|
min_val = inp[x][1]['min'];
|
||||||
max_val = inp[x][1]['max'];
|
max_val = inp[x][1]['max'];
|
||||||
step_val = inp[x][1]['step'];
|
step_val = inp[x][1]['step'];
|
||||||
multiline = inp[x][1]['multiline'];
|
multiline = inp[x][1]['multiline'];
|
||||||
|
dynamic_prompt = inp[x][1]['dynamic_prompt'];
|
||||||
}
|
}
|
||||||
|
|
||||||
let type = inp[x][0];
|
let type = inp[x][0];
|
||||||
@ -173,11 +174,21 @@ function onObjectInfo(json) {
|
|||||||
} else if (type == "STRING") {
|
} else if (type == "STRING") {
|
||||||
if (default_val == undefined) default_val = "";
|
if (default_val == undefined) default_val = "";
|
||||||
if (multiline == undefined) multiline = false;
|
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) {
|
if (multiline) {
|
||||||
var w = {
|
var w = {
|
||||||
type: "customtext",
|
type: "customtext",
|
||||||
name: x,
|
name: x,
|
||||||
|
dynamic_prompt: dynamic_prompt,
|
||||||
get value() { return this.input_div.innerText;},
|
get value() { return this.input_div.innerText;},
|
||||||
set value(x) { this.input_div.innerText = x;},
|
set value(x) { this.input_div.innerText = x;},
|
||||||
callback: function(v){console.log(v);},
|
callback: function(v){console.log(v);},
|
||||||
@ -252,6 +263,7 @@ function onObjectInfo(json) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
w = this.addWidget("text", x, default_val, function(v){}, { multiline:false } );
|
w = this.addWidget("text", x, default_val, function(v){}, { multiline:false } );
|
||||||
|
w.dynamic_prompt = dynamic_prompt;
|
||||||
this._widgets += [w];
|
this._widgets += [w];
|
||||||
}
|
}
|
||||||
} else {
|
} 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() {
|
function graphToPrompt() {
|
||||||
let s = graph.serialize();
|
let s = graph.serialize();
|
||||||
let output = {};
|
let output = {};
|
||||||
@ -309,6 +331,45 @@ function graphToPrompt() {
|
|||||||
for (let x in nodes) {
|
for (let x in nodes) {
|
||||||
let n = graph.getNodeById(nodes[x].id);
|
let n = graph.getNodeById(nodes[x].id);
|
||||||
let input_ = {};
|
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) {
|
for (let y in n.widgets) {
|
||||||
input_[n.widgets[y].name] = n.widgets[y].value;
|
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);
|
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
Block a user