Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
ComfyUI
Commits
e2e5c4c5
Commit
e2e5c4c5
authored
Feb 17, 2023
by
m957ymj75urz
Browse files
Add basic dynamic prompting with seeding on CLIPTextEncode node
parent
09f1d76e
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
67 additions
and
2 deletions
+67
-2
nodes.py
nodes.py
+1
-1
webshit/index.html
webshit/index.html
+66
-1
No files found.
nodes.py
View file @
e2e5c4c5
...
...
@@ -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"
...
...
webshit/index.html
View file @
e2e5c4c5
...
...
@@ -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
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment