├── ,gitignore
├── LICENSE.txt
├── README.md
├── app.py
├── config.json
├── requirements.txt
├── run.sh
├── settings.py
├── tasks.py
├── templates
├── animate_diff
│ └── workflow.json
├── img2img
│ └── launcher.json
├── img2vid
│ └── workflow.json
├── svd
│ └── launcher.json
├── upscale
│ └── launcher.json
└── vid2vid
│ └── launcher.json
└── utils.py
/,gitignore:
--------------------------------------------------------------------------------
1 | # Python bytecode
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # Distribution / packaging
7 | dist/
8 | build/
9 | *.egg-info/
10 | *.egg
11 |
12 | # Virtual environments
13 | venv/
14 | env/
15 | ENV/
16 | .venv/
17 | .env
18 |
19 | # Streamlit specific
20 | .streamlit/secrets.toml
21 | .streamlit/config.toml
22 |
23 | # Project specific
24 | projects/
25 | models/
26 | **/comfyui_temp/
27 | **/comfyui_output/
28 | *.db
29 | *.sqlite3
30 | launcher_state.json
31 | outputs/
32 |
33 | # Development and testing
34 | .coverage
35 | htmlcov/
36 | .pytest_cache/
37 | .mypy_cache/
38 | .tox/
39 | coverage.xml
40 | *.cover
41 |
42 | # Jupyter Notebook
43 | .ipynb_checkpoints
44 |
45 | # IDE specific files
46 | .idea/
47 | .vscode/
48 | *.swp
49 | *.swo
50 | *~
51 | .ropeproject/
52 |
53 | # OS specific files
54 | .DS_Store
55 | Thumbs.db
56 | desktop.ini
57 |
58 | # Logs
59 | *.log
60 | logs/
61 |
62 | # Environment variables
63 | .env
64 | .env.local
65 |
66 | # Dependency lock files
67 | Pipfile.lock
68 |
69 | # Temporary files
70 | *.tmp
71 | tmp/
72 | temp/
73 |
74 | # Config files
75 | config.json
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | GNU AFFERO GENERAL PUBLIC LICENSE
2 | Version 3, 19 November 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU Affero General Public License is a free, copyleft license for
11 | software and other kinds of works, specifically designed to ensure
12 | cooperation with the community in the case of network server software.
13 |
14 | The licenses for most software and other practical works are designed
15 | to take away your freedom to share and change the works. By contrast,
16 | our General Public Licenses are intended to guarantee your freedom to
17 | share and change all versions of a program--to make sure it remains free
18 | software for all its users.
19 |
20 | When we speak of free software, we are referring to freedom, not
21 | price. Our General Public Licenses are designed to make sure that you
22 | have the freedom to distribute copies of free software (and charge for
23 | them if you wish), that you receive source code or can get it if you
24 | want it, that you can change the software or use pieces of it in new
25 | free programs, and that you know you can do these things.
26 |
27 | Developers that use our General Public Licenses protect your rights
28 | with two steps: (1) assert copyright on the software, and (2) offer
29 | you this License which gives you legal permission to copy, distribute
30 | and/or modify the software.
31 |
32 | A secondary benefit of defending all users' freedom is that
33 | improvements made in alternate versions of the program, if they
34 | receive widespread use, become available for other developers to
35 | incorporate. Many developers of free software are heartened and
36 | encouraged by the resulting cooperation. However, in the case of
37 | software used on network servers, this result may fail to come about.
38 | The GNU General Public License permits making a modified version and
39 | letting the public access it on a server without ever releasing its
40 | source code to the public.
41 |
42 | The GNU Affero General Public License is designed specifically to
43 | ensure that, in such cases, the modified source code becomes available
44 | to the community. It requires the operator of a network server to
45 | provide the source code of the modified version running there to the
46 | users of that server. Therefore, public use of a modified version, on
47 | a publicly accessible server, gives the public access to the source
48 | code of the modified version.
49 |
50 | An older license, called the Affero General Public License and
51 | published by Affero, was designed to accomplish similar goals. This is
52 | a different license, not a version of the Affero GPL, but Affero has
53 | released a new version of the Affero GPL which permits relicensing under
54 | this license.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | TERMS AND CONDITIONS
60 |
61 | 0. Definitions.
62 |
63 | "This License" refers to version 3 of the GNU Affero General Public License.
64 |
65 | "Copyright" also means copyright-like laws that apply to other kinds of
66 | works, such as semiconductor masks.
67 |
68 | "The Program" refers to any copyrightable work licensed under this
69 | License. Each licensee is addressed as "you". "Licensees" and
70 | "recipients" may be individuals or organizations.
71 |
72 | To "modify" a work means to copy from or adapt all or part of the work
73 | in a fashion requiring copyright permission, other than the making of an
74 | exact copy. The resulting work is called a "modified version" of the
75 | earlier work or a work "based on" the earlier work.
76 |
77 | A "covered work" means either the unmodified Program or a work based
78 | on the Program.
79 |
80 | To "propagate" a work means to do anything with it that, without
81 | permission, would make you directly or secondarily liable for
82 | infringement under applicable copyright law, except executing it on a
83 | computer or modifying a private copy. Propagation includes copying,
84 | distribution (with or without modification), making available to the
85 | public, and in some countries other activities as well.
86 |
87 | To "convey" a work means any kind of propagation that enables other
88 | parties to make or receive copies. Mere interaction with a user through
89 | a computer network, with no transfer of a copy, is not conveying.
90 |
91 | An interactive user interface displays "Appropriate Legal Notices"
92 | to the extent that it includes a convenient and prominently visible
93 | feature that (1) displays an appropriate copyright notice, and (2)
94 | tells the user that there is no warranty for the work (except to the
95 | extent that warranties are provided), that licensees may convey the
96 | work under this License, and how to view a copy of this License. If
97 | the interface presents a list of user commands or options, such as a
98 | menu, a prominent item in the list meets this criterion.
99 |
100 | 1. Source Code.
101 |
102 | The "source code" for a work means the preferred form of the work
103 | for making modifications to it. "Object code" means any non-source
104 | form of a work.
105 |
106 | A "Standard Interface" means an interface that either is an official
107 | standard defined by a recognized standards body, or, in the case of
108 | interfaces specified for a particular programming language, one that
109 | is widely used among developers working in that language.
110 |
111 | The "System Libraries" of an executable work include anything, other
112 | than the work as a whole, that (a) is included in the normal form of
113 | packaging a Major Component, but which is not part of that Major
114 | Component, and (b) serves only to enable use of the work with that
115 | Major Component, or to implement a Standard Interface for which an
116 | implementation is available to the public in source code form. A
117 | "Major Component", in this context, means a major essential component
118 | (kernel, window system, and so on) of the specific operating system
119 | (if any) on which the executable work runs, or a compiler used to
120 | produce the work, or an object code interpreter used to run it.
121 |
122 | The "Corresponding Source" for a work in object code form means all
123 | the source code needed to generate, install, and (for an executable
124 | work) run the object code and to modify the work, including scripts to
125 | control those activities. However, it does not include the work's
126 | System Libraries, or general-purpose tools or generally available free
127 | programs which are used unmodified in performing those activities but
128 | which are not part of the work. For example, Corresponding Source
129 | includes interface definition files associated with source files for
130 | the work, and the source code for shared libraries and dynamically
131 | linked subprograms that the work is specifically designed to require,
132 | such as by intimate data communication or control flow between those
133 | subprograms and other parts of the work.
134 |
135 | The Corresponding Source need not include anything that users
136 | can regenerate automatically from other parts of the Corresponding
137 | Source.
138 |
139 | The Corresponding Source for a work in source code form is that
140 | same work.
141 |
142 | 2. Basic Permissions.
143 |
144 | All rights granted under this License are granted for the term of
145 | copyright on the Program, and are irrevocable provided the stated
146 | conditions are met. This License explicitly affirms your unlimited
147 | permission to run the unmodified Program. The output from running a
148 | covered work is covered by this License only if the output, given its
149 | content, constitutes a covered work. This License acknowledges your
150 | rights of fair use or other equivalent, as provided by copyright law.
151 |
152 | You may make, run and propagate covered works that you do not
153 | convey, without conditions so long as your license otherwise remains
154 | in force. You may convey covered works to others for the sole purpose
155 | of having them make modifications exclusively for you, or provide you
156 | with facilities for running those works, provided that you comply with
157 | the terms of this License in conveying all material for which you do
158 | not control copyright. Those thus making or running the covered works
159 | for you must do so exclusively on your behalf, under your direction
160 | and control, on terms that prohibit them from making any copies of
161 | your copyrighted material outside their relationship with you.
162 |
163 | Conveying under any other circumstances is permitted solely under
164 | the conditions stated below. Sublicensing is not allowed; section 10
165 | makes it unnecessary.
166 |
167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168 |
169 | No covered work shall be deemed part of an effective technological
170 | measure under any applicable law fulfilling obligations under article
171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
172 | similar laws prohibiting or restricting circumvention of such
173 | measures.
174 |
175 | When you convey a covered work, you waive any legal power to forbid
176 | circumvention of technological measures to the extent such circumvention
177 | is effected by exercising rights under this License with respect to
178 | the covered work, and you disclaim any intention to limit operation or
179 | modification of the work as a means of enforcing, against the work's
180 | users, your or third parties' legal rights to forbid circumvention of
181 | technological measures.
182 |
183 | 4. Conveying Verbatim Copies.
184 |
185 | You may convey verbatim copies of the Program's source code as you
186 | receive it, in any medium, provided that you conspicuously and
187 | appropriately publish on each copy an appropriate copyright notice;
188 | keep intact all notices stating that this License and any
189 | non-permissive terms added in accord with section 7 apply to the code;
190 | keep intact all notices of the absence of any warranty; and give all
191 | recipients a copy of this License along with the Program.
192 |
193 | You may charge any price or no price for each copy that you convey,
194 | and you may offer support or warranty protection for a fee.
195 |
196 | 5. Conveying Modified Source Versions.
197 |
198 | You may convey a work based on the Program, or the modifications to
199 | produce it from the Program, in the form of source code under the
200 | terms of section 4, provided that you also meet all of these conditions:
201 |
202 | a) The work must carry prominent notices stating that you modified
203 | it, and giving a relevant date.
204 |
205 | b) The work must carry prominent notices stating that it is
206 | released under this License and any conditions added under section
207 | 7. This requirement modifies the requirement in section 4 to
208 | "keep intact all notices".
209 |
210 | c) You must license the entire work, as a whole, under this
211 | License to anyone who comes into possession of a copy. This
212 | License will therefore apply, along with any applicable section 7
213 | additional terms, to the whole of the work, and all its parts,
214 | regardless of how they are packaged. This License gives no
215 | permission to license the work in any other way, but it does not
216 | invalidate such permission if you have separately received it.
217 |
218 | d) If the work has interactive user interfaces, each must display
219 | Appropriate Legal Notices; however, if the Program has interactive
220 | interfaces that do not display Appropriate Legal Notices, your
221 | work need not make them do so.
222 |
223 | A compilation of a covered work with other separate and independent
224 | works, which are not by their nature extensions of the covered work,
225 | and which are not combined with it such as to form a larger program,
226 | in or on a volume of a storage or distribution medium, is called an
227 | "aggregate" if the compilation and its resulting copyright are not
228 | used to limit the access or legal rights of the compilation's users
229 | beyond what the individual works permit. Inclusion of a covered work
230 | in an aggregate does not cause this License to apply to the other
231 | parts of the aggregate.
232 |
233 | 6. Conveying Non-Source Forms.
234 |
235 | You may convey a covered work in object code form under the terms
236 | of sections 4 and 5, provided that you also convey the
237 | machine-readable Corresponding Source under the terms of this License,
238 | in one of these ways:
239 |
240 | a) Convey the object code in, or embodied in, a physical product
241 | (including a physical distribution medium), accompanied by the
242 | Corresponding Source fixed on a durable physical medium
243 | customarily used for software interchange.
244 |
245 | b) Convey the object code in, or embodied in, a physical product
246 | (including a physical distribution medium), accompanied by a
247 | written offer, valid for at least three years and valid for as
248 | long as you offer spare parts or customer support for that product
249 | model, to give anyone who possesses the object code either (1) a
250 | copy of the Corresponding Source for all the software in the
251 | product that is covered by this License, on a durable physical
252 | medium customarily used for software interchange, for a price no
253 | more than your reasonable cost of physically performing this
254 | conveying of source, or (2) access to copy the
255 | Corresponding Source from a network server at no charge.
256 |
257 | c) Convey individual copies of the object code with a copy of the
258 | written offer to provide the Corresponding Source. This
259 | alternative is allowed only occasionally and noncommercially, and
260 | only if you received the object code with such an offer, in accord
261 | with subsection 6b.
262 |
263 | d) Convey the object code by offering access from a designated
264 | place (gratis or for a charge), and offer equivalent access to the
265 | Corresponding Source in the same way through the same place at no
266 | further charge. You need not require recipients to copy the
267 | Corresponding Source along with the object code. If the place to
268 | copy the object code is a network server, the Corresponding Source
269 | may be on a different server (operated by you or a third party)
270 | that supports equivalent copying facilities, provided you maintain
271 | clear directions next to the object code saying where to find the
272 | Corresponding Source. Regardless of what server hosts the
273 | Corresponding Source, you remain obligated to ensure that it is
274 | available for as long as needed to satisfy these requirements.
275 |
276 | e) Convey the object code using peer-to-peer transmission, provided
277 | you inform other peers where the object code and Corresponding
278 | Source of the work are being offered to the general public at no
279 | charge under subsection 6d.
280 |
281 | A separable portion of the object code, whose source code is excluded
282 | from the Corresponding Source as a System Library, need not be
283 | included in conveying the object code work.
284 |
285 | A "User Product" is either (1) a "consumer product", which means any
286 | tangible personal property which is normally used for personal, family,
287 | or household purposes, or (2) anything designed or sold for incorporation
288 | into a dwelling. In determining whether a product is a consumer product,
289 | doubtful cases shall be resolved in favor of coverage. For a particular
290 | product received by a particular user, "normally used" refers to a
291 | typical or common use of that class of product, regardless of the status
292 | of the particular user or of the way in which the particular user
293 | actually uses, or expects or is expected to use, the product. A product
294 | is a consumer product regardless of whether the product has substantial
295 | commercial, industrial or non-consumer uses, unless such uses represent
296 | the only significant mode of use of the product.
297 |
298 | "Installation Information" for a User Product means any methods,
299 | procedures, authorization keys, or other information required to install
300 | and execute modified versions of a covered work in that User Product from
301 | a modified version of its Corresponding Source. The information must
302 | suffice to ensure that the continued functioning of the modified object
303 | code is in no case prevented or interfered with solely because
304 | modification has been made.
305 |
306 | If you convey an object code work under this section in, or with, or
307 | specifically for use in, a User Product, and the conveying occurs as
308 | part of a transaction in which the right of possession and use of the
309 | User Product is transferred to the recipient in perpetuity or for a
310 | fixed term (regardless of how the transaction is characterized), the
311 | Corresponding Source conveyed under this section must be accompanied
312 | by the Installation Information. But this requirement does not apply
313 | if neither you nor any third party retains the ability to install
314 | modified object code on the User Product (for example, the work has
315 | been installed in ROM).
316 |
317 | The requirement to provide Installation Information does not include a
318 | requirement to continue to provide support service, warranty, or updates
319 | for a work that has been modified or installed by the recipient, or for
320 | the User Product in which it has been modified or installed. Access to a
321 | network may be denied when the modification itself materially and
322 | adversely affects the operation of the network or violates the rules and
323 | protocols for communication across the network.
324 |
325 | Corresponding Source conveyed, and Installation Information provided,
326 | in accord with this section must be in a format that is publicly
327 | documented (and with an implementation available to the public in
328 | source code form), and must require no special password or key for
329 | unpacking, reading or copying.
330 |
331 | 7. Additional Terms.
332 |
333 | "Additional permissions" are terms that supplement the terms of this
334 | License by making exceptions from one or more of its conditions.
335 | Additional permissions that are applicable to the entire Program shall
336 | be treated as though they were included in this License, to the extent
337 | that they are valid under applicable law. If additional permissions
338 | apply only to part of the Program, that part may be used separately
339 | under those permissions, but the entire Program remains governed by
340 | this License without regard to the additional permissions.
341 |
342 | When you convey a copy of a covered work, you may at your option
343 | remove any additional permissions from that copy, or from any part of
344 | it. (Additional permissions may be written to require their own
345 | removal in certain cases when you modify the work.) You may place
346 | additional permissions on material, added by you to a covered work,
347 | for which you have or can give appropriate copyright permission.
348 |
349 | Notwithstanding any other provision of this License, for material you
350 | add to a covered work, you may (if authorized by the copyright holders of
351 | that material) supplement the terms of this License with terms:
352 |
353 | a) Disclaiming warranty or limiting liability differently from the
354 | terms of sections 15 and 16 of this License; or
355 |
356 | b) Requiring preservation of specified reasonable legal notices or
357 | author attributions in that material or in the Appropriate Legal
358 | Notices displayed by works containing it; or
359 |
360 | c) Prohibiting misrepresentation of the origin of that material, or
361 | requiring that modified versions of such material be marked in
362 | reasonable ways as different from the original version; or
363 |
364 | d) Limiting the use for publicity purposes of names of licensors or
365 | authors of the material; or
366 |
367 | e) Declining to grant rights under trademark law for use of some
368 | trade names, trademarks, or service marks; or
369 |
370 | f) Requiring indemnification of licensors and authors of that
371 | material by anyone who conveys the material (or modified versions of
372 | it) with contractual assumptions of liability to the recipient, for
373 | any liability that these contractual assumptions directly impose on
374 | those licensors and authors.
375 |
376 | All other non-permissive additional terms are considered "further
377 | restrictions" within the meaning of section 10. If the Program as you
378 | received it, or any part of it, contains a notice stating that it is
379 | governed by this License along with a term that is a further
380 | restriction, you may remove that term. If a license document contains
381 | a further restriction but permits relicensing or conveying under this
382 | License, you may add to a covered work material governed by the terms
383 | of that license document, provided that the further restriction does
384 | not survive such relicensing or conveying.
385 |
386 | If you add terms to a covered work in accord with this section, you
387 | must place, in the relevant source files, a statement of the
388 | additional terms that apply to those files, or a notice indicating
389 | where to find the applicable terms.
390 |
391 | Additional terms, permissive or non-permissive, may be stated in the
392 | form of a separately written license, or stated as exceptions;
393 | the above requirements apply either way.
394 |
395 | 8. Termination.
396 |
397 | You may not propagate or modify a covered work except as expressly
398 | provided under this License. Any attempt otherwise to propagate or
399 | modify it is void, and will automatically terminate your rights under
400 | this License (including any patent licenses granted under the third
401 | paragraph of section 11).
402 |
403 | However, if you cease all violation of this License, then your
404 | license from a particular copyright holder is reinstated (a)
405 | provisionally, unless and until the copyright holder explicitly and
406 | finally terminates your license, and (b) permanently, if the copyright
407 | holder fails to notify you of the violation by some reasonable means
408 | prior to 60 days after the cessation.
409 |
410 | Moreover, your license from a particular copyright holder is
411 | reinstated permanently if the copyright holder notifies you of the
412 | violation by some reasonable means, this is the first time you have
413 | received notice of violation of this License (for any work) from that
414 | copyright holder, and you cure the violation prior to 30 days after
415 | your receipt of the notice.
416 |
417 | Termination of your rights under this section does not terminate the
418 | licenses of parties who have received copies or rights from you under
419 | this License. If your rights have been terminated and not permanently
420 | reinstated, you do not qualify to receive new licenses for the same
421 | material under section 10.
422 |
423 | 9. Acceptance Not Required for Having Copies.
424 |
425 | You are not required to accept this License in order to receive or
426 | run a copy of the Program. Ancillary propagation of a covered work
427 | occurring solely as a consequence of using peer-to-peer transmission
428 | to receive a copy likewise does not require acceptance. However,
429 | nothing other than this License grants you permission to propagate or
430 | modify any covered work. These actions infringe copyright if you do
431 | not accept this License. Therefore, by modifying or propagating a
432 | covered work, you indicate your acceptance of this License to do so.
433 |
434 | 10. Automatic Licensing of Downstream Recipients.
435 |
436 | Each time you convey a covered work, the recipient automatically
437 | receives a license from the original licensors, to run, modify and
438 | propagate that work, subject to this License. You are not responsible
439 | for enforcing compliance by third parties with this License.
440 |
441 | An "entity transaction" is a transaction transferring control of an
442 | organization, or substantially all assets of one, or subdividing an
443 | organization, or merging organizations. If propagation of a covered
444 | work results from an entity transaction, each party to that
445 | transaction who receives a copy of the work also receives whatever
446 | licenses to the work the party's predecessor in interest had or could
447 | give under the previous paragraph, plus a right to possession of the
448 | Corresponding Source of the work from the predecessor in interest, if
449 | the predecessor has it or can get it with reasonable efforts.
450 |
451 | You may not impose any further restrictions on the exercise of the
452 | rights granted or affirmed under this License. For example, you may
453 | not impose a license fee, royalty, or other charge for exercise of
454 | rights granted under this License, and you may not initiate litigation
455 | (including a cross-claim or counterclaim in a lawsuit) alleging that
456 | any patent claim is infringed by making, using, selling, offering for
457 | sale, or importing the Program or any portion of it.
458 |
459 | 11. Patents.
460 |
461 | A "contributor" is a copyright holder who authorizes use under this
462 | License of the Program or a work on which the Program is based. The
463 | work thus licensed is called the contributor's "contributor version".
464 |
465 | A contributor's "essential patent claims" are all patent claims
466 | owned or controlled by the contributor, whether already acquired or
467 | hereafter acquired, that would be infringed by some manner, permitted
468 | by this License, of making, using, or selling its contributor version,
469 | but do not include claims that would be infringed only as a
470 | consequence of further modification of the contributor version. For
471 | purposes of this definition, "control" includes the right to grant
472 | patent sublicenses in a manner consistent with the requirements of
473 | this License.
474 |
475 | Each contributor grants you a non-exclusive, worldwide, royalty-free
476 | patent license under the contributor's essential patent claims, to
477 | make, use, sell, offer for sale, import and otherwise run, modify and
478 | propagate the contents of its contributor version.
479 |
480 | In the following three paragraphs, a "patent license" is any express
481 | agreement or commitment, however denominated, not to enforce a patent
482 | (such as an express permission to practice a patent or covenant not to
483 | sue for patent infringement). To "grant" such a patent license to a
484 | party means to make such an agreement or commitment not to enforce a
485 | patent against the party.
486 |
487 | If you convey a covered work, knowingly relying on a patent license,
488 | and the Corresponding Source of the work is not available for anyone
489 | to copy, free of charge and under the terms of this License, through a
490 | publicly available network server or other readily accessible means,
491 | then you must either (1) cause the Corresponding Source to be so
492 | available, or (2) arrange to deprive yourself of the benefit of the
493 | patent license for this particular work, or (3) arrange, in a manner
494 | consistent with the requirements of this License, to extend the patent
495 | license to downstream recipients. "Knowingly relying" means you have
496 | actual knowledge that, but for the patent license, your conveying the
497 | covered work in a country, or your recipient's use of the covered work
498 | in a country, would infringe one or more identifiable patents in that
499 | country that you have reason to believe are valid.
500 |
501 | If, pursuant to or in connection with a single transaction or
502 | arrangement, you convey, or propagate by procuring conveyance of, a
503 | covered work, and grant a patent license to some of the parties
504 | receiving the covered work authorizing them to use, propagate, modify
505 | or convey a specific copy of the covered work, then the patent license
506 | you grant is automatically extended to all recipients of the covered
507 | work and works based on it.
508 |
509 | A patent license is "discriminatory" if it does not include within
510 | the scope of its coverage, prohibits the exercise of, or is
511 | conditioned on the non-exercise of one or more of the rights that are
512 | specifically granted under this License. You may not convey a covered
513 | work if you are a party to an arrangement with a third party that is
514 | in the business of distributing software, under which you make payment
515 | to the third party based on the extent of your activity of conveying
516 | the work, and under which the third party grants, to any of the
517 | parties who would receive the covered work from you, a discriminatory
518 | patent license (a) in connection with copies of the covered work
519 | conveyed by you (or copies made from those copies), or (b) primarily
520 | for and in connection with specific products or compilations that
521 | contain the covered work, unless you entered into that arrangement,
522 | or that patent license was granted, prior to 28 March 2007.
523 |
524 | Nothing in this License shall be construed as excluding or limiting
525 | any implied license or other defenses to infringement that may
526 | otherwise be available to you under applicable patent law.
527 |
528 | 12. No Surrender of Others' Freedom.
529 |
530 | If conditions are imposed on you (whether by court order, agreement or
531 | otherwise) that contradict the conditions of this License, they do not
532 | excuse you from the conditions of this License. If you cannot convey a
533 | covered work so as to satisfy simultaneously your obligations under this
534 | License and any other pertinent obligations, then as a consequence you may
535 | not convey it at all. For example, if you agree to terms that obligate you
536 | to collect a royalty for further conveying from those to whom you convey
537 | the Program, the only way you could satisfy both those terms and this
538 | License would be to refrain entirely from conveying the Program.
539 |
540 | 13. Remote Network Interaction; Use with the GNU General Public License.
541 |
542 | Notwithstanding any other provision of this License, if you modify the
543 | Program, your modified version must prominently offer all users
544 | interacting with it remotely through a computer network (if your version
545 | supports such interaction) an opportunity to receive the Corresponding
546 | Source of your version by providing access to the Corresponding Source
547 | from a network server at no charge, through some standard or customary
548 | means of facilitating copying of software. This Corresponding Source
549 | shall include the Corresponding Source for any work covered by version 3
550 | of the GNU General Public License that is incorporated pursuant to the
551 | following paragraph.
552 |
553 | Notwithstanding any other provision of this License, you have
554 | permission to link or combine any covered work with a work licensed
555 | under version 3 of the GNU General Public License into a single
556 | combined work, and to convey the resulting work. The terms of this
557 | License will continue to apply to the part which is the covered work,
558 | but the work with which it is combined will remain governed by version
559 | 3 of the GNU General Public License.
560 |
561 | 14. Revised Versions of this License.
562 |
563 | The Free Software Foundation may publish revised and/or new versions of
564 | the GNU Affero General Public License from time to time. Such new versions
565 | will be similar in spirit to the present version, but may differ in detail to
566 | address new problems or concerns.
567 |
568 | Each version is given a distinguishing version number. If the
569 | Program specifies that a certain numbered version of the GNU Affero General
570 | Public License "or any later version" applies to it, you have the
571 | option of following the terms and conditions either of that numbered
572 | version or of any later version published by the Free Software
573 | Foundation. If the Program does not specify a version number of the
574 | GNU Affero General Public License, you may choose any version ever published
575 | by the Free Software Foundation.
576 |
577 | If the Program specifies that a proxy can decide which future
578 | versions of the GNU Affero General Public License can be used, that proxy's
579 | public statement of acceptance of a version permanently authorizes you
580 | to choose that version for the Program.
581 |
582 | Later license versions may give you additional or different
583 | permissions. However, no additional obligations are imposed on any
584 | author or copyright holder as a result of your choosing to follow a
585 | later version.
586 |
587 | 15. Disclaimer of Warranty.
588 |
589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597 |
598 | 16. Limitation of Liability.
599 |
600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608 | SUCH DAMAGES.
609 |
610 | 17. Interpretation of Sections 15 and 16.
611 |
612 | If the disclaimer of warranty and limitation of liability provided
613 | above cannot be given local legal effect according to their terms,
614 | reviewing courts shall apply local law that most closely approximates
615 | an absolute waiver of all civil liability in connection with the
616 | Program, unless a warranty or assumption of liability accompanies a
617 | copy of the Program in return for a fee.
618 |
619 | END OF TERMS AND CONDITIONS
620 |
621 | How to Apply These Terms to Your New Programs
622 |
623 | If you develop a new program, and you want it to be of the greatest
624 | possible use to the public, the best way to achieve this is to make it
625 | free software which everyone can redistribute and change under these terms.
626 |
627 | To do so, attach the following notices to the program. It is safest
628 | to attach them to the start of each source file to most effectively
629 | state the exclusion of warranty; and each file should have at least
630 | the "copyright" line and a pointer to where the full notice is found.
631 |
632 |
633 | Copyright (C)
634 |
635 | This program is free software: you can redistribute it and/or modify
636 | it under the terms of the GNU Affero General Public License as published
637 | by the Free Software Foundation, either version 3 of the License, or
638 | (at your option) any later version.
639 |
640 | This program is distributed in the hope that it will be useful,
641 | but WITHOUT ANY WARRANTY; without even the implied warranty of
642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643 | GNU Affero General Public License for more details.
644 |
645 | You should have received a copy of the GNU Affero General Public License
646 | along with this program. If not, see .
647 |
648 | Also add information on how to contact you by electronic and paper mail.
649 |
650 | If your software can interact with users remotely through a computer
651 | network, you should also make sure that it provides a way for users to
652 | get its source. For example, if your program is a web application, its
653 | interface could display a "Source" link that leads users to an archive
654 | of the code. There are many ways you could offer source, and different
655 | solutions will be better for different programs; see section 13 for the
656 | specific requirements.
657 |
658 | You should also get your employer (if you work as a programmer) or school,
659 | if any, to sign a "copyright disclaimer" for the program, if necessary.
660 | For more information on this, and how to apply and follow the GNU AGPL, see
661 | .
662 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ComfyUI Workflow Launcher - Streamlit Edition
2 |
3 | 
4 | 
5 | 
6 | 
7 | 
8 |
9 | 🚀 A user-friendly interface for managing **ComfyUI** projects with **Streamlit**.
10 |
11 | ⚠️ **Work in Progress**: This project is actively being developed. Some features may change or be incomplete.
12 |
13 | ---
14 |
15 | ## ✨ Features
16 |
17 | - **Create workflows** from predefined templates
18 | - **Import workflows** from JSON files
19 | - **Manage projects** (start, stop, delete)
20 | - **Monitor system info** and model details
21 | - **Track workflow status** and port usage
22 | - **Modern, responsive UI** for seamless interaction
23 |
24 | ---
25 |
26 | ## 📦 Installation
27 |
28 | ### 1. Clone the repository
29 |
30 | ```bash
31 | git clone https://github.com/murapadev/ComfyUI-Streamlit-Launcher.git
32 | cd comfyui-launcher/streamlit
33 | ```
34 |
35 | ### 2. Install dependencies
36 |
37 | ```bash
38 | pip install -r requirements.txt
39 | ```
40 |
41 | ---
42 |
43 | ## 🚀 Usage
44 |
45 | ### Start the application
46 |
47 | ```bash
48 | streamlit run app.py
49 | ```
50 |
51 | The app will be available at [http://localhost:8501](http://localhost:8501) by default.
52 |
53 | ### Creating a New Workflow
54 |
55 | 1. Click **"Create New Workflow"** (sidebar or home page)
56 | 2. Enter a **workflow name**
57 | 3. Select a **template**
58 | 4. (Optional) Specify a **fixed port**
59 | 5. Click **"Create Workflow"**
60 |
61 | ### Importing a Workflow
62 |
63 | 1. Click **"Import Workflow"**
64 | 2. Enter a **workflow name**
65 | 3. Upload a **JSON file** or paste JSON content
66 | 4. (Optional) Set a **fixed port** or skip model validation
67 | 5. Click **"Import Workflow"**
68 |
69 | ### Managing Workflows
70 |
71 | From the home page, you can:
72 |
73 | - **Start** ready workflows
74 | - **Open/Stop** running workflows
75 | - **Delete** workflows
76 |
77 | ### ⚙️ Settings
78 |
79 | Access system information and configurations, including:
80 |
81 | - **System & directory info**
82 | - **Port configuration**
83 | - **Model storage details**
84 |
85 | ---
86 |
87 | ## 📂 Directory Structure
88 |
89 | - `projects/` - Created ComfyUI projects
90 | - `models/` - Shared models directory
91 | - `templates/` - Workflow templates
92 |
93 | ---
94 |
95 | ## 📌 Requirements
96 |
97 | - Python **3.8+**
98 | - `streamlit>=1.24.0`
99 | - `requests>=2.28.1`
100 | - `psutil>=5.9.0`
101 | - `tqdm>=4.64.1`
102 | - `pillow>=9.3.0`
103 | - `watchdog>=3.0.0`
104 | - `pandas>=1.5.0`
105 | - `plotly>=5.13.0`
106 | - `streamlit-option-menu>=0.3.2`
107 | - `streamlit-extras>=0.3.0`
108 | - `python-dotenv>=1.0.0`
109 | - `celery`
110 | - *(Optional)* `torch>=2.0.0` (for ML functionality)
111 |
112 | ---
113 |
114 | ## 🤝 Contributing
115 |
116 | Contributions are welcome! To contribute:
117 |
118 | 1. **Fork** the repository
119 | 2. **Create a new branch** (`git checkout -b feature-name`)
120 | 3. **Commit your changes** (`git commit -m "Add feature"`)
121 | 4. **Push to your branch** (`git push origin feature-name`)
122 | 5. **Submit a Pull Request** 🚀
123 |
124 | ---
125 |
126 | ## 📜 License & Attribution
127 |
128 | This project is based on [ComfyUI-Launcher](https://github.com/ComfyWorkflows/ComfyUI-Launcher) ([AGPL-3.0 License](https://github.com/ComfyWorkflows/ComfyUI-Launcher/blob/bb6690462780abecaa733814d02f8ccee1b0a829/server/utils.py)). All derivative work complies with the original license terms.
129 |
130 | 📌 **Star this project** ⭐ if you find it useful!
131 |
132 |
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "credentials": {
3 | "civitai": {
4 | "apikey": ""
5 | }
6 | },
7 | "directories": {
8 | "projects": "./projects",
9 | "models": "./models",
10 | "templates": "./templates"
11 | },
12 | "port_configuration": {
13 | "allow_overridable_ports": true,
14 | "project_min_port": 4001,
15 | "project_max_port": 4100,
16 | "server_port": 8501
17 | }
18 | }
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | streamlit>=1.24.0
2 | requests>=2.28.1
3 | psutil>=5.9.0
4 | tqdm>=4.64.1
5 | pillow>=9.3.0
6 | watchdog>=3.0.0
7 | pandas>=1.5.0
8 | plotly>=5.13.0
9 | streamlit-option-menu>=0.3.2
10 | streamlit-extras>=0.3.0
11 | python-dotenv>=1.0.0
12 | celery
13 | # torch is now optional - install only if needed for ML functionality
14 | # torch>=2.0.0
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This script runs the ComfyUI Launcher Streamlit application
4 |
5 | # Check if Python is installed
6 | if ! command -v python3 &> /dev/null; then
7 | echo "Python 3 is not installed. Please install Python 3 to run this application."
8 | exit 1
9 | fi
10 |
11 | # Check if required packages are installed
12 | if ! python3 -c "import streamlit" &> /dev/null; then
13 | echo "Installing required packages..."
14 | pip install -r requirements.txt
15 | fi
16 |
17 | # Create necessary directories
18 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
19 | mkdir -p "$DIR/projects"
20 | mkdir -p "$DIR/models"
21 | mkdir -p "$DIR/templates"
22 |
23 | # Check if streamlit_patches.py exists
24 | if [ ! -f "$DIR/streamlit_patches.py" ]; then
25 | echo "Warning: streamlit_patches.py not found. Some features may not work correctly."
26 | fi
27 |
28 | # Run the Streamlit application
29 | echo "Starting ComfyUI Launcher Streamlit application..."
30 | streamlit run "$DIR/app.py" "$@"
--------------------------------------------------------------------------------
/settings.py:
--------------------------------------------------------------------------------
1 | import os
2 | import json
3 | import os.path
4 |
5 | # Load configuration from config.json
6 | CONFIG_FILEPATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "config.json")
7 |
8 | def get_config():
9 | """
10 | Load the configuration from config.json file.
11 | If the file doesn't exist, create it with default values.
12 |
13 | Returns:
14 | dict: Configuration dictionary
15 | """
16 | try:
17 | # Ensure the directory exists
18 | os.makedirs(os.path.dirname(CONFIG_FILEPATH), exist_ok=True)
19 |
20 | if os.path.exists(CONFIG_FILEPATH):
21 | with open(CONFIG_FILEPATH, "r") as f:
22 | config = json.load(f)
23 | return config
24 | else:
25 | # Define default configuration
26 | default_config = {
27 | "credentials": {
28 | "civitai": {
29 | "apikey": ""
30 | }
31 | },
32 | "directories": {
33 | "projects": "./projects",
34 | "models": "./models",
35 | "templates": "./templates"
36 | },
37 | "port_configuration": {
38 | "allow_overridable_ports": True,
39 | "project_min_port": 4001,
40 | "project_max_port": 4100,
41 | "server_port": 8501
42 | }
43 | }
44 |
45 | # Create the config file with default values
46 | with open(CONFIG_FILEPATH, "w") as f:
47 | json.dump(default_config, f, indent=2)
48 |
49 | return default_config
50 | except (FileNotFoundError, json.JSONDecodeError, PermissionError) as e:
51 | print(f"Warning: Could not load config file: {e}")
52 | # Return default configuration as fallback
53 | return {
54 | "credentials": {"civitai": {"apikey": ""}},
55 | "directories": {
56 | "projects": "./projects",
57 | "models": "./models",
58 | "templates": "./templates"
59 | },
60 | "port_configuration": {
61 | "allow_overridable_ports": True,
62 | "project_min_port": 4001,
63 | "project_max_port": 4100,
64 | "server_port": 8501
65 | }
66 | }
67 |
68 | # Load configuration
69 | config = get_config()
70 |
71 | # Get directory configurations with environment variable overrides
72 | # Environment variables take precedence over config file values
73 | PROJECTS_DIR = os.environ.get("PROJECTS_DIR", config["directories"]["projects"])
74 | MODELS_DIR = os.environ.get("MODELS_DIR", config["directories"]["models"])
75 | TEMPLATES_DIR = os.environ.get("TEMPLATES_DIR", config["directories"]["templates"])
76 |
77 | # Create directories if they don't exist
78 | os.makedirs(PROJECTS_DIR, exist_ok=True)
79 | os.makedirs(MODELS_DIR, exist_ok=True)
80 | os.makedirs(TEMPLATES_DIR, exist_ok=True)
81 |
82 | # Get port configuration with environment variable overrides
83 | ALLOW_OVERRIDABLE_PORTS_PER_PROJECT = os.environ.get(
84 | "ALLOW_OVERRIDABLE_PORTS_PER_PROJECT",
85 | str(config["port_configuration"]["allow_overridable_ports"])
86 | ).lower() == "true"
87 |
88 | PROJECT_MIN_PORT = int(os.environ.get(
89 | "PROJECT_MIN_PORT",
90 | str(config["port_configuration"]["project_min_port"])
91 | ))
92 |
93 | PROJECT_MAX_PORT = int(os.environ.get(
94 | "PROJECT_MAX_PORT",
95 | str(config["port_configuration"]["project_max_port"])
96 | ))
97 |
98 | SERVER_PORT = int(os.environ.get(
99 | "SERVER_PORT",
100 | str(config["port_configuration"]["server_port"])
101 | ))
--------------------------------------------------------------------------------
/tasks.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 | import shutil
4 | from celery import shared_task
5 | from utils import COMFYUI_REPO_URL, create_symlink, create_virtualenv, install_default_custom_nodes, install_pip_reqs, normalize_model_filepaths_in_workflow_json, run_command, run_command_in_project_venv, set_default_workflow_from_launcher_json, set_launcher_state_data, setup_custom_nodes_from_snapshot, setup_files_from_launcher_json, setup_initial_models_folder
6 |
7 | @shared_task(ignore_result=False)
8 | def create_comfyui_project(
9 | project_folder_path, models_folder_path, id, name, launcher_json=None, port=None, create_project_folder=True
10 | ):
11 | project_folder_path = os.path.abspath(project_folder_path)
12 | models_folder_path = os.path.abspath(models_folder_path)
13 |
14 | try:
15 | if create_project_folder:
16 | assert not os.path.exists(project_folder_path), f"Project folder already exists at {project_folder_path}"
17 | os.makedirs(project_folder_path)
18 | else:
19 | assert os.path.exists(project_folder_path), f"Project folder does not exist at {project_folder_path}"
20 |
21 | set_launcher_state_data(
22 | project_folder_path,
23 | {"id":id,"name":name, "status_message": "Downloading ComfyUI...", "state": "download_comfyui"},
24 | )
25 | # Modify the subprocess.run calls to capture and log the stdout
26 | run_command(
27 | ["git", "clone", COMFYUI_REPO_URL, os.path.join(project_folder_path, 'comfyui')],
28 | )
29 |
30 | if launcher_json:
31 | comfyui_commit_hash = launcher_json["snapshot_json"]["comfyui"]
32 | if comfyui_commit_hash:
33 | run_command(
34 | ["git", "checkout", comfyui_commit_hash],
35 | cwd=os.path.join(project_folder_path, 'comfyui'),
36 | )
37 | launcher_json['workflow_json'] = normalize_model_filepaths_in_workflow_json(launcher_json['workflow_json'])
38 |
39 |
40 | # move the comfyui/web/index.html file to comfyui/web/comfyui_index.html
41 | os.rename(
42 | os.path.join(project_folder_path, "comfyui", "web", "index.html"),
43 | os.path.join(project_folder_path, "comfyui", "web", "comfyui_index.html"),
44 | )
45 |
46 | # copy the web/comfy_frame.html file to comfyui/web/index.html
47 | shutil.copy(
48 | os.path.join("web", "comfy_frame.html"),
49 | os.path.join(project_folder_path, "comfyui", "web", "index.html"),
50 | )
51 |
52 | # remove the models folder that exists in comfyui and symlink the shared_models folder as models
53 | if os.path.exists(os.path.join(project_folder_path, "comfyui", "models")):
54 | shutil.rmtree(
55 | os.path.join(project_folder_path, "comfyui", "models"), ignore_errors=True
56 | )
57 |
58 | if not os.path.exists(models_folder_path):
59 | setup_initial_models_folder(models_folder_path)
60 |
61 | # create a folder in project folder/comfyui/models that is a symlink to the models folder
62 | create_symlink(models_folder_path, os.path.join(project_folder_path, "comfyui", "models"))
63 |
64 | set_launcher_state_data(
65 | project_folder_path,
66 | {"status_message": "Installing ComfyUI...", "state": "install_comfyui"},
67 | )
68 |
69 | # create a new virtualenv in project folder/venv
70 | create_virtualenv(os.path.join(project_folder_path, 'venv'))
71 |
72 | # activate the virtualenv + install comfyui requirements
73 | run_command_in_project_venv(
74 | project_folder_path,
75 | f"pip install -r {os.path.join(project_folder_path, 'comfyui', 'requirements.txt')}",
76 | )
77 |
78 | set_launcher_state_data(
79 | project_folder_path,
80 | {
81 | "status_message": "Installing custom nodes...",
82 | "state": "install_custom_nodes",
83 | },
84 | )
85 |
86 | # install default custom nodes
87 | install_default_custom_nodes(project_folder_path, launcher_json)
88 |
89 | setup_custom_nodes_from_snapshot(project_folder_path, launcher_json)
90 |
91 | # install pip requirements
92 | if launcher_json and "pip_requirements" in launcher_json:
93 | install_pip_reqs(project_folder_path, launcher_json["pip_requirements"])
94 |
95 | # download all necessary files
96 | set_launcher_state_data(
97 | project_folder_path,
98 | {
99 | "status_message": "Downloading models & other files...",
100 | "state": "download_files",
101 | },
102 | )
103 |
104 | setup_files_from_launcher_json(project_folder_path, launcher_json)
105 | set_default_workflow_from_launcher_json(project_folder_path, launcher_json)
106 |
107 | if launcher_json:
108 | with open(os.path.join(project_folder_path, "launcher.json"), "w") as f:
109 | json.dump(launcher_json, f)
110 |
111 | if port is not None:
112 | with open(os.path.join(project_folder_path, "port.txt"), "w") as f:
113 | f.write(str(port))
114 |
115 | set_launcher_state_data(
116 | project_folder_path, {"status_message": "Ready", "state": "ready"}
117 | )
118 | except:
119 | # remove the project folder if an error occurs
120 | shutil.rmtree(project_folder_path, ignore_errors=True)
121 | raise
--------------------------------------------------------------------------------
/templates/animate_diff/workflow.json:
--------------------------------------------------------------------------------
1 | {
2 | "last_node_id": 30,
3 | "last_link_id": 43,
4 | "nodes": [
5 | {
6 | "id": 4,
7 | "type": "CLIPSetLastLayer",
8 | "pos": [
9 | 431.14133986796236,
10 | 184.59417317288003
11 | ],
12 | "size": {
13 | "0": 315,
14 | "1": 58
15 | },
16 | "flags": {},
17 | "order": 6,
18 | "mode": 0,
19 | "inputs": [
20 | {
21 | "name": "clip",
22 | "type": "CLIP",
23 | "link": 33
24 | }
25 | ],
26 | "outputs": [
27 | {
28 | "name": "CLIP",
29 | "type": "CLIP",
30 | "links": [
31 | 2,
32 | 3
33 | ],
34 | "shape": 3,
35 | "slot_index": 0
36 | }
37 | ],
38 | "properties": {
39 | "Node name for S&R": "CLIPSetLastLayer"
40 | },
41 | "widgets_values": [
42 | -2
43 | ]
44 | },
45 | {
46 | "id": 5,
47 | "type": "PrimitiveNode",
48 | "pos": [
49 | 279,
50 | 431
51 | ],
52 | "size": {
53 | "0": 285.6000061035156,
54 | "1": 82
55 | },
56 | "flags": {},
57 | "order": 0,
58 | "mode": 0,
59 | "outputs": [
60 | {
61 | "name": "INT",
62 | "type": "INT",
63 | "links": [
64 | 6,
65 | 16
66 | ],
67 | "slot_index": 0,
68 | "widget": {
69 | "name": "seed"
70 | }
71 | }
72 | ],
73 | "title": "Primitive (I'm using this as seed)",
74 | "properties": {
75 | "Run widget replace on values": false
76 | },
77 | "widgets_values": [
78 | 888888889,
79 | "fixed"
80 | ],
81 | "color": "#2a363b",
82 | "bgcolor": "#3f5159"
83 | },
84 | {
85 | "id": 2,
86 | "type": "VAELoader",
87 | "pos": [
88 | 179,
89 | 326
90 | ],
91 | "size": {
92 | "0": 385.8948669433594,
93 | "1": 58
94 | },
95 | "flags": {},
96 | "order": 1,
97 | "mode": 0,
98 | "outputs": [
99 | {
100 | "name": "VAE",
101 | "type": "VAE",
102 | "links": [
103 | 10,
104 | 23,
105 | 42
106 | ],
107 | "shape": 3,
108 | "slot_index": 0
109 | }
110 | ],
111 | "properties": {
112 | "Node name for S&R": "VAELoader"
113 | },
114 | "widgets_values": [
115 | "vae-ft-mse-840000-ema-pruned.safetensors"
116 | ]
117 | },
118 | {
119 | "id": 6,
120 | "type": "CLIPTextEncode",
121 | "pos": [
122 | 874,
123 | 287
124 | ],
125 | "size": {
126 | "0": 391.23883056640625,
127 | "1": 78.14339447021484
128 | },
129 | "flags": {},
130 | "order": 8,
131 | "mode": 0,
132 | "inputs": [
133 | {
134 | "name": "clip",
135 | "type": "CLIP",
136 | "link": 3
137 | }
138 | ],
139 | "outputs": [
140 | {
141 | "name": "CONDITIONING",
142 | "type": "CONDITIONING",
143 | "links": [
144 | 5,
145 | 25
146 | ],
147 | "shape": 3,
148 | "slot_index": 0
149 | }
150 | ],
151 | "properties": {
152 | "Node name for S&R": "CLIPTextEncode"
153 | },
154 | "widgets_values": [
155 | "(worst quality, low quality: 1.4)"
156 | ],
157 | "color": "#322",
158 | "bgcolor": "#533"
159 | },
160 | {
161 | "id": 25,
162 | "type": "ADE_AnimateDiffUniformContextOptions",
163 | "pos": [
164 | 485,
165 | -298
166 | ],
167 | "size": {
168 | "0": 315,
169 | "1": 154
170 | },
171 | "flags": {},
172 | "order": 2,
173 | "mode": 0,
174 | "outputs": [
175 | {
176 | "name": "CONTEXT_OPTIONS",
177 | "type": "CONTEXT_OPTIONS",
178 | "links": [
179 | 37
180 | ],
181 | "shape": 3,
182 | "slot_index": 0
183 | }
184 | ],
185 | "properties": {
186 | "Node name for S&R": "ADE_AnimateDiffUniformContextOptions"
187 | },
188 | "widgets_values": [
189 | 16,
190 | 1,
191 | 4,
192 | "uniform",
193 | false
194 | ],
195 | "color": "#432",
196 | "bgcolor": "#653"
197 | },
198 | {
199 | "id": 15,
200 | "type": "VAEDecode",
201 | "pos": [
202 | 1771,
203 | 325
204 | ],
205 | "size": {
206 | "0": 210,
207 | "1": 46
208 | },
209 | "flags": {},
210 | "order": 15,
211 | "mode": 0,
212 | "inputs": [
213 | {
214 | "name": "samples",
215 | "type": "LATENT",
216 | "link": 21
217 | },
218 | {
219 | "name": "vae",
220 | "type": "VAE",
221 | "link": 23
222 | }
223 | ],
224 | "outputs": [
225 | {
226 | "name": "IMAGE",
227 | "type": "IMAGE",
228 | "links": [
229 | 39
230 | ],
231 | "shape": 3,
232 | "slot_index": 0
233 | }
234 | ],
235 | "properties": {
236 | "Node name for S&R": "VAEDecode"
237 | }
238 | },
239 | {
240 | "id": 10,
241 | "type": "VAEDecode",
242 | "pos": [
243 | 1759,
244 | -315
245 | ],
246 | "size": {
247 | "0": 210,
248 | "1": 46
249 | },
250 | "flags": {},
251 | "order": 10,
252 | "mode": 0,
253 | "inputs": [
254 | {
255 | "name": "samples",
256 | "type": "LATENT",
257 | "link": 9
258 | },
259 | {
260 | "name": "vae",
261 | "type": "VAE",
262 | "link": 10
263 | }
264 | ],
265 | "outputs": [
266 | {
267 | "name": "IMAGE",
268 | "type": "IMAGE",
269 | "links": [
270 | 40
271 | ],
272 | "shape": 3,
273 | "slot_index": 0
274 | }
275 | ],
276 | "properties": {
277 | "Node name for S&R": "VAEDecode"
278 | }
279 | },
280 | {
281 | "id": 9,
282 | "type": "EmptyLatentImage",
283 | "pos": [
284 | 853,
285 | -45
286 | ],
287 | "size": {
288 | "0": 315,
289 | "1": 106
290 | },
291 | "flags": {},
292 | "order": 3,
293 | "mode": 0,
294 | "outputs": [
295 | {
296 | "name": "LATENT",
297 | "type": "LATENT",
298 | "links": [
299 | 31
300 | ],
301 | "shape": 3,
302 | "slot_index": 0
303 | }
304 | ],
305 | "properties": {
306 | "Node name for S&R": "EmptyLatentImage"
307 | },
308 | "widgets_values": [
309 | 512,
310 | 512,
311 | 120
312 | ]
313 | },
314 | {
315 | "id": 20,
316 | "type": "ADE_AnimateDiffLoaderWithContext",
317 | "pos": [
318 | 866,
319 | -341
320 | ],
321 | "size": {
322 | "0": 315,
323 | "1": 190
324 | },
325 | "flags": {},
326 | "order": 5,
327 | "mode": 0,
328 | "inputs": [
329 | {
330 | "name": "model",
331 | "type": "MODEL",
332 | "link": 34
333 | },
334 | {
335 | "name": "context_options",
336 | "type": "CONTEXT_OPTIONS",
337 | "link": 37
338 | },
339 | {
340 | "name": "motion_lora",
341 | "type": "MOTION_LORA",
342 | "link": null
343 | },
344 | {
345 | "name": "motion_model_settings",
346 | "type": "MOTION_MODEL_SETTINGS",
347 | "link": null
348 | }
349 | ],
350 | "outputs": [
351 | {
352 | "name": "MODEL",
353 | "type": "MODEL",
354 | "links": [
355 | 29,
356 | 30
357 | ],
358 | "shape": 3,
359 | "slot_index": 0
360 | }
361 | ],
362 | "properties": {
363 | "Node name for S&R": "ADE_AnimateDiffLoaderWithContext"
364 | },
365 | "widgets_values": [
366 | "mm_sd_v15_v2.ckpt",
367 | "sqrt_linear (AnimateDiff)",
368 | 1,
369 | false
370 | ],
371 | "color": "#432",
372 | "bgcolor": "#653"
373 | },
374 | {
375 | "id": 14,
376 | "type": "KSampler",
377 | "pos": [
378 | 1390,
379 | 410
380 | ],
381 | "size": [
382 | 315,
383 | 446
384 | ],
385 | "flags": {},
386 | "order": 14,
387 | "mode": 0,
388 | "inputs": [
389 | {
390 | "name": "model",
391 | "type": "MODEL",
392 | "link": 30
393 | },
394 | {
395 | "name": "positive",
396 | "type": "CONDITIONING",
397 | "link": 26
398 | },
399 | {
400 | "name": "negative",
401 | "type": "CONDITIONING",
402 | "link": 25
403 | },
404 | {
405 | "name": "latent_image",
406 | "type": "LATENT",
407 | "link": 17
408 | },
409 | {
410 | "name": "seed",
411 | "type": "INT",
412 | "link": 16,
413 | "widget": {
414 | "name": "seed"
415 | }
416 | }
417 | ],
418 | "outputs": [
419 | {
420 | "name": "LATENT",
421 | "type": "LATENT",
422 | "links": [
423 | 21
424 | ],
425 | "shape": 3,
426 | "slot_index": 0
427 | }
428 | ],
429 | "properties": {
430 | "Node name for S&R": "KSampler"
431 | },
432 | "widgets_values": [
433 | 888888889,
434 | "fixed",
435 | 25,
436 | 8,
437 | "euler",
438 | "normal",
439 | 0.6499999999999997
440 | ]
441 | },
442 | {
443 | "id": 22,
444 | "type": "CheckpointLoaderSimple",
445 | "pos": [
446 | 64,
447 | 163
448 | ],
449 | "size": {
450 | "0": 315,
451 | "1": 98
452 | },
453 | "flags": {},
454 | "order": 4,
455 | "mode": 0,
456 | "outputs": [
457 | {
458 | "name": "MODEL",
459 | "type": "MODEL",
460 | "links": [
461 | 34
462 | ],
463 | "shape": 3,
464 | "slot_index": 0
465 | },
466 | {
467 | "name": "CLIP",
468 | "type": "CLIP",
469 | "links": [
470 | 33
471 | ],
472 | "shape": 3,
473 | "slot_index": 1
474 | },
475 | {
476 | "name": "VAE",
477 | "type": "VAE",
478 | "links": null,
479 | "shape": 3
480 | }
481 | ],
482 | "properties": {
483 | "Node name for S&R": "CheckpointLoaderSimple"
484 | },
485 | "widgets_values": [
486 | "ghostmix_v20Bakedvae.safetensors"
487 | ]
488 | },
489 | {
490 | "id": 3,
491 | "type": "CLIPTextEncode",
492 | "pos": [
493 | 884,
494 | 113
495 | ],
496 | "size": {
497 | "0": 377.7811279296875,
498 | "1": 124.52955627441406
499 | },
500 | "flags": {},
501 | "order": 7,
502 | "mode": 0,
503 | "inputs": [
504 | {
505 | "name": "clip",
506 | "type": "CLIP",
507 | "link": 2
508 | }
509 | ],
510 | "outputs": [
511 | {
512 | "name": "CONDITIONING",
513 | "type": "CONDITIONING",
514 | "links": [
515 | 4,
516 | 26
517 | ],
518 | "shape": 3,
519 | "slot_index": 0
520 | }
521 | ],
522 | "properties": {
523 | "Node name for S&R": "CLIPTextEncode"
524 | },
525 | "widgets_values": [
526 | "(High resolution), close up, front view, female samurai, wearing samurai armor, asymmetrical design, origami, no morphing"
527 | ],
528 | "color": "#232",
529 | "bgcolor": "#353"
530 | },
531 | {
532 | "id": 13,
533 | "type": "LatentUpscaleBy",
534 | "pos": [
535 | 1000,
536 | 470
537 | ],
538 | "size": {
539 | "0": 315,
540 | "1": 82
541 | },
542 | "flags": {},
543 | "order": 11,
544 | "mode": 0,
545 | "inputs": [
546 | {
547 | "name": "samples",
548 | "type": "LATENT",
549 | "link": 15
550 | }
551 | ],
552 | "outputs": [
553 | {
554 | "name": "LATENT",
555 | "type": "LATENT",
556 | "links": [
557 | 17
558 | ],
559 | "shape": 3,
560 | "slot_index": 0
561 | }
562 | ],
563 | "properties": {
564 | "Node name for S&R": "LatentUpscaleBy"
565 | },
566 | "widgets_values": [
567 | "nearest-exact",
568 | 1.5
569 | ]
570 | },
571 | {
572 | "id": 27,
573 | "type": "VHS_VideoCombine",
574 | "pos": [
575 | 2024,
576 | -327
577 | ],
578 | "size": [
579 | 351.06327661132855,
580 | 575.0632766113285
581 | ],
582 | "flags": {},
583 | "order": 13,
584 | "mode": 0,
585 | "inputs": [
586 | {
587 | "name": "images",
588 | "type": "IMAGE",
589 | "link": 40
590 | }
591 | ],
592 | "outputs": [],
593 | "properties": {
594 | "Node name for S&R": "VHS_VideoCombine"
595 | },
596 | "widgets_values": {
597 | "frame_rate": 8,
598 | "loop_count": 0,
599 | "filename_prefix": "AnimateDiff",
600 | "format": "image/gif",
601 | "pingpong": false,
602 | "save_image": true,
603 | "crf": 20,
604 | "save_metadata": true,
605 | "audio_file": "",
606 | "videopreview": {
607 | "hidden": false,
608 | "paused": false,
609 | "params": {
610 | "filename": "AnimateDiff_00020.gif",
611 | "subfolder": "",
612 | "type": "output",
613 | "format": "image/gif"
614 | }
615 | }
616 | },
617 | "color": "#223",
618 | "bgcolor": "#335"
619 | },
620 | {
621 | "id": 7,
622 | "type": "KSampler",
623 | "pos": [
624 | 1400,
625 | -230
626 | ],
627 | "size": [
628 | 326.86632226562506,
629 | 522.0268857421876
630 | ],
631 | "flags": {},
632 | "order": 9,
633 | "mode": 0,
634 | "inputs": [
635 | {
636 | "name": "model",
637 | "type": "MODEL",
638 | "link": 29
639 | },
640 | {
641 | "name": "positive",
642 | "type": "CONDITIONING",
643 | "link": 4
644 | },
645 | {
646 | "name": "negative",
647 | "type": "CONDITIONING",
648 | "link": 5
649 | },
650 | {
651 | "name": "latent_image",
652 | "type": "LATENT",
653 | "link": 31
654 | },
655 | {
656 | "name": "seed",
657 | "type": "INT",
658 | "link": 6,
659 | "widget": {
660 | "name": "seed"
661 | }
662 | }
663 | ],
664 | "outputs": [
665 | {
666 | "name": "LATENT",
667 | "type": "LATENT",
668 | "links": [
669 | 9,
670 | 15,
671 | 41
672 | ],
673 | "shape": 3,
674 | "slot_index": 0
675 | }
676 | ],
677 | "properties": {
678 | "Node name for S&R": "KSampler"
679 | },
680 | "widgets_values": [
681 | 888888889,
682 | "fixed",
683 | 25,
684 | 8,
685 | "euler",
686 | "normal",
687 | 1
688 | ]
689 | },
690 | {
691 | "id": 29,
692 | "type": "VAEDecode",
693 | "pos": [
694 | 1756.866322265625,
695 | -230
696 | ],
697 | "size": {
698 | "0": 210,
699 | "1": 46
700 | },
701 | "flags": {},
702 | "order": 12,
703 | "mode": 0,
704 | "inputs": [
705 | {
706 | "name": "samples",
707 | "type": "LATENT",
708 | "link": 41
709 | },
710 | {
711 | "name": "vae",
712 | "type": "VAE",
713 | "link": 42
714 | }
715 | ],
716 | "outputs": [
717 | {
718 | "name": "IMAGE",
719 | "type": "IMAGE",
720 | "links": [],
721 | "shape": 3
722 | }
723 | ],
724 | "properties": {
725 | "Node name for S&R": "VAEDecode"
726 | }
727 | },
728 | {
729 | "id": 28,
730 | "type": "VHS_VideoCombine",
731 | "pos": [
732 | 2415,
733 | -323
734 | ],
735 | "size": [
736 | 338.0673222656251,
737 | 562.0673222656251
738 | ],
739 | "flags": {},
740 | "order": 16,
741 | "mode": 0,
742 | "inputs": [
743 | {
744 | "name": "images",
745 | "type": "IMAGE",
746 | "link": 39
747 | }
748 | ],
749 | "outputs": [],
750 | "properties": {
751 | "Node name for S&R": "VHS_VideoCombine"
752 | },
753 | "widgets_values": {
754 | "frame_rate": 8,
755 | "loop_count": 0,
756 | "filename_prefix": "AnimateDiff",
757 | "format": "image/gif",
758 | "pingpong": false,
759 | "save_image": true,
760 | "crf": 20,
761 | "save_metadata": true,
762 | "audio_file": "",
763 | "videopreview": {
764 | "hidden": false,
765 | "paused": false,
766 | "params": {
767 | "filename": "AnimateDiff_00021.gif",
768 | "subfolder": "",
769 | "type": "output",
770 | "format": "image/gif"
771 | }
772 | }
773 | },
774 | "color": "#223",
775 | "bgcolor": "#335"
776 | }
777 | ],
778 | "links": [
779 | [
780 | 2,
781 | 4,
782 | 0,
783 | 3,
784 | 0,
785 | "CLIP"
786 | ],
787 | [
788 | 3,
789 | 4,
790 | 0,
791 | 6,
792 | 0,
793 | "CLIP"
794 | ],
795 | [
796 | 4,
797 | 3,
798 | 0,
799 | 7,
800 | 1,
801 | "CONDITIONING"
802 | ],
803 | [
804 | 5,
805 | 6,
806 | 0,
807 | 7,
808 | 2,
809 | "CONDITIONING"
810 | ],
811 | [
812 | 6,
813 | 5,
814 | 0,
815 | 7,
816 | 4,
817 | "INT"
818 | ],
819 | [
820 | 9,
821 | 7,
822 | 0,
823 | 10,
824 | 0,
825 | "LATENT"
826 | ],
827 | [
828 | 10,
829 | 2,
830 | 0,
831 | 10,
832 | 1,
833 | "VAE"
834 | ],
835 | [
836 | 15,
837 | 7,
838 | 0,
839 | 13,
840 | 0,
841 | "LATENT"
842 | ],
843 | [
844 | 16,
845 | 5,
846 | 0,
847 | 14,
848 | 4,
849 | "INT"
850 | ],
851 | [
852 | 17,
853 | 13,
854 | 0,
855 | 14,
856 | 3,
857 | "LATENT"
858 | ],
859 | [
860 | 21,
861 | 14,
862 | 0,
863 | 15,
864 | 0,
865 | "LATENT"
866 | ],
867 | [
868 | 23,
869 | 2,
870 | 0,
871 | 15,
872 | 1,
873 | "VAE"
874 | ],
875 | [
876 | 25,
877 | 6,
878 | 0,
879 | 14,
880 | 2,
881 | "CONDITIONING"
882 | ],
883 | [
884 | 26,
885 | 3,
886 | 0,
887 | 14,
888 | 1,
889 | "CONDITIONING"
890 | ],
891 | [
892 | 29,
893 | 20,
894 | 0,
895 | 7,
896 | 0,
897 | "MODEL"
898 | ],
899 | [
900 | 30,
901 | 20,
902 | 0,
903 | 14,
904 | 0,
905 | "MODEL"
906 | ],
907 | [
908 | 31,
909 | 9,
910 | 0,
911 | 7,
912 | 3,
913 | "LATENT"
914 | ],
915 | [
916 | 33,
917 | 22,
918 | 1,
919 | 4,
920 | 0,
921 | "CLIP"
922 | ],
923 | [
924 | 34,
925 | 22,
926 | 0,
927 | 20,
928 | 0,
929 | "MODEL"
930 | ],
931 | [
932 | 37,
933 | 25,
934 | 0,
935 | 20,
936 | 1,
937 | "CONTEXT_OPTIONS"
938 | ],
939 | [
940 | 39,
941 | 15,
942 | 0,
943 | 28,
944 | 0,
945 | "IMAGE"
946 | ],
947 | [
948 | 40,
949 | 10,
950 | 0,
951 | 27,
952 | 0,
953 | "IMAGE"
954 | ],
955 | [
956 | 41,
957 | 7,
958 | 0,
959 | 29,
960 | 0,
961 | "LATENT"
962 | ],
963 | [
964 | 42,
965 | 2,
966 | 0,
967 | 29,
968 | 1,
969 | "VAE"
970 | ]
971 | ],
972 | "groups": [
973 | {
974 | "title": "Change this to match your model reqs",
975 | "bounding": [
976 | 414,
977 | 101,
978 | 416,
979 | 165
980 | ],
981 | "color": "#3f789e",
982 | "font_size": 24,
983 | "locked": false
984 | },
985 | {
986 | "title": "Animation length determined by Latents passed in",
987 | "bounding": [
988 | 722,
989 | -118,
990 | 550,
991 | 191
992 | ],
993 | "color": "#3f789e",
994 | "font_size": 24,
995 | "locked": false
996 | }
997 | ],
998 | "config": {},
999 | "extra": {},
1000 | "version": 0.4
1001 | }
--------------------------------------------------------------------------------
/templates/img2img/launcher.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0",
3 | "workflow_json": {
4 | "last_node_id": 74,
5 | "last_link_id": 131,
6 | "nodes": [
7 | {
8 | "id": 56,
9 | "type": "IPAdapterModelLoader",
10 | "pos": [
11 | 227,
12 | -142
13 | ],
14 | "size": {
15 | "0": 315,
16 | "1": 58
17 | },
18 | "flags": {},
19 | "order": 0,
20 | "mode": 0,
21 | "outputs": [
22 | {
23 | "name": "IPADAPTER",
24 | "type": "IPADAPTER",
25 | "label": "IPADAPTER",
26 | "links": [
27 | 76
28 | ],
29 | "shape": 3,
30 | "slot_index": 0
31 | }
32 | ],
33 | "properties": {
34 | "Node name for S&R": "IPAdapterModelLoader"
35 | },
36 | "widgets_values": [
37 | "ip-adapter-faceid_sdxl.bin"
38 | ]
39 | },
40 | {
41 | "id": 57,
42 | "type": "CLIPVisionLoader",
43 | "pos": [
44 | 225,
45 | -34
46 | ],
47 | "size": {
48 | "0": 315,
49 | "1": 58
50 | },
51 | "flags": {},
52 | "order": 1,
53 | "mode": 0,
54 | "outputs": [
55 | {
56 | "name": "CLIP_VISION",
57 | "type": "CLIP_VISION",
58 | "label": "CLIP_VISION",
59 | "links": [
60 | 77
61 | ],
62 | "shape": 3,
63 | "slot_index": 0
64 | }
65 | ],
66 | "properties": {
67 | "Node name for S&R": "CLIPVisionLoader"
68 | },
69 | "widgets_values": [
70 | "clip_vision_vit_h.safetensors"
71 | ]
72 | },
73 | {
74 | "id": 14,
75 | "type": "CheckpointLoaderSimple",
76 | "pos": [
77 | -457,
78 | -83
79 | ],
80 | "size": {
81 | "0": 315,
82 | "1": 122
83 | },
84 | "flags": {},
85 | "order": 2,
86 | "mode": 0,
87 | "outputs": [
88 | {
89 | "name": "MODEL",
90 | "type": "MODEL",
91 | "label": "MODEL",
92 | "links": [
93 | 18
94 | ],
95 | "shape": 3,
96 | "slot_index": 0
97 | },
98 | {
99 | "name": "CLIP",
100 | "type": "CLIP",
101 | "label": "CLIP",
102 | "links": [
103 | 19
104 | ],
105 | "shape": 3,
106 | "slot_index": 1
107 | },
108 | {
109 | "name": "VAE",
110 | "type": "VAE",
111 | "label": "VAE",
112 | "links": [
113 | 17
114 | ],
115 | "shape": 3,
116 | "slot_index": 2
117 | }
118 | ],
119 | "properties": {
120 | "Node name for S&R": "CheckpointLoaderSimple"
121 | },
122 | "widgets_values": [
123 | "opendalle_v11.safetensors"
124 | ]
125 | },
126 | {
127 | "id": 58,
128 | "type": "InsightFaceLoader",
129 | "pos": [
130 | 232,
131 | 77
132 | ],
133 | "size": {
134 | "0": 315,
135 | "1": 58
136 | },
137 | "flags": {},
138 | "order": 3,
139 | "mode": 0,
140 | "outputs": [
141 | {
142 | "name": "INSIGHTFACE",
143 | "type": "INSIGHTFACE",
144 | "label": "INSIGHTFACE",
145 | "links": [
146 | 78
147 | ],
148 | "shape": 3,
149 | "slot_index": 0
150 | }
151 | ],
152 | "properties": {
153 | "Node name for S&R": "InsightFaceLoader"
154 | },
155 | "widgets_values": [
156 | "CUDA"
157 | ]
158 | },
159 | {
160 | "id": 10,
161 | "type": "LoadImage",
162 | "pos": [
163 | 93.5603162978168,
164 | 285.73159240416703
165 | ],
166 | "size": {
167 | "0": 315,
168 | "1": 314.0000305175781
169 | },
170 | "flags": {},
171 | "order": 4,
172 | "mode": 0,
173 | "outputs": [
174 | {
175 | "name": "IMAGE",
176 | "type": "IMAGE",
177 | "label": "IMAGE",
178 | "links": [
179 | 79,
180 | 129
181 | ],
182 | "slot_index": 0
183 | },
184 | {
185 | "name": "MASK",
186 | "type": "MASK",
187 | "label": "MASK",
188 | "links": null,
189 | "shape": 3
190 | }
191 | ],
192 | "title": "Upload your image",
193 | "properties": {
194 | "Node name for S&R": "LoadImage"
195 | },
196 | "widgets_values": [
197 | "360_F_258899001_68CalsKTRk6PZQgWH9JhR4heBlncCko9.jpg",
198 | "image"
199 | ]
200 | },
201 | {
202 | "id": 72,
203 | "type": "ControlNetLoader",
204 | "pos": [
205 | 570,
206 | 749
207 | ],
208 | "size": {
209 | "0": 315,
210 | "1": 58
211 | },
212 | "flags": {},
213 | "order": 5,
214 | "mode": 4,
215 | "outputs": [
216 | {
217 | "name": "CONTROL_NET",
218 | "type": "CONTROL_NET",
219 | "links": [
220 | 121
221 | ],
222 | "shape": 3
223 | }
224 | ],
225 | "properties": {
226 | "Node name for S&R": "ControlNetLoader"
227 | },
228 | "widgets_values": [
229 | "control-lora-canny-rank256.safetensors"
230 | ]
231 | },
232 | {
233 | "id": 71,
234 | "type": "ControlNetApplyAdvanced",
235 | "pos": [
236 | 569,
237 | 541
238 | ],
239 | "size": {
240 | "0": 315,
241 | "1": 166
242 | },
243 | "flags": {},
244 | "order": 15,
245 | "mode": 4,
246 | "inputs": [
247 | {
248 | "name": "positive",
249 | "type": "CONDITIONING",
250 | "link": 126
251 | },
252 | {
253 | "name": "negative",
254 | "type": "CONDITIONING",
255 | "link": 125
256 | },
257 | {
258 | "name": "control_net",
259 | "type": "CONTROL_NET",
260 | "link": 121,
261 | "slot_index": 2
262 | },
263 | {
264 | "name": "image",
265 | "type": "IMAGE",
266 | "link": 130
267 | }
268 | ],
269 | "outputs": [
270 | {
271 | "name": "positive",
272 | "type": "CONDITIONING",
273 | "links": [
274 | 127
275 | ],
276 | "shape": 3,
277 | "slot_index": 0
278 | },
279 | {
280 | "name": "negative",
281 | "type": "CONDITIONING",
282 | "links": [
283 | 128
284 | ],
285 | "shape": 3,
286 | "slot_index": 1
287 | }
288 | ],
289 | "properties": {
290 | "Node name for S&R": "ControlNetApplyAdvanced"
291 | },
292 | "widgets_values": [
293 | 1,
294 | 0,
295 | 1
296 | ]
297 | },
298 | {
299 | "id": 66,
300 | "type": "CLIPTextEncode",
301 | "pos": [
302 | 928,
303 | 266
304 | ],
305 | "size": {
306 | "0": 422.84503173828125,
307 | "1": 164.31304931640625
308 | },
309 | "flags": {
310 | "collapsed": true
311 | },
312 | "order": 13,
313 | "mode": 0,
314 | "inputs": [
315 | {
316 | "link": 111,
317 | "name": "clip",
318 | "type": "CLIP",
319 | "label": "clip"
320 | },
321 | {
322 | "link": 110,
323 | "name": "text",
324 | "type": "STRING",
325 | "label": "text",
326 | "widget": {
327 | "name": "text"
328 | },
329 | "slot_index": 1
330 | }
331 | ],
332 | "outputs": [
333 | {
334 | "name": "CONDITIONING",
335 | "type": "CONDITIONING",
336 | "label": "CONDITIONING",
337 | "links": [
338 | 126
339 | ],
340 | "slot_index": 0
341 | }
342 | ],
343 | "properties": {
344 | "Node name for S&R": "CLIPTextEncode"
345 | },
346 | "widgets_values": [
347 | "2d anime style woman, lace mask, short pixie redhead, starship on the background, "
348 | ]
349 | },
350 | {
351 | "id": 70,
352 | "type": "CLIPTextEncode",
353 | "pos": [
354 | 929,
355 | 313
356 | ],
357 | "size": {
358 | "0": 422.84503173828125,
359 | "1": 164.31304931640625
360 | },
361 | "flags": {
362 | "collapsed": true
363 | },
364 | "order": 14,
365 | "mode": 0,
366 | "inputs": [
367 | {
368 | "link": 119,
369 | "name": "clip",
370 | "type": "CLIP",
371 | "label": "clip"
372 | },
373 | {
374 | "link": 118,
375 | "name": "text",
376 | "type": "STRING",
377 | "label": "text",
378 | "widget": {
379 | "name": "text"
380 | },
381 | "slot_index": 1
382 | }
383 | ],
384 | "outputs": [
385 | {
386 | "name": "CONDITIONING",
387 | "type": "CONDITIONING",
388 | "label": "CONDITIONING",
389 | "links": [
390 | 125
391 | ],
392 | "slot_index": 0
393 | }
394 | ],
395 | "properties": {
396 | "Node name for S&R": "CLIPTextEncode"
397 | },
398 | "widgets_values": [
399 | "2d anime style woman, lace mask, short pixie redhead, starship on the background, "
400 | ]
401 | },
402 | {
403 | "id": 3,
404 | "type": "KSampler",
405 | "pos": [
406 | 931,
407 | 521
408 | ],
409 | "size": {
410 | "0": 315,
411 | "1": 262
412 | },
413 | "flags": {},
414 | "order": 16,
415 | "mode": 0,
416 | "inputs": [
417 | {
418 | "link": 81,
419 | "name": "model",
420 | "type": "MODEL",
421 | "label": "model"
422 | },
423 | {
424 | "link": 127,
425 | "name": "positive",
426 | "type": "CONDITIONING",
427 | "label": "positive"
428 | },
429 | {
430 | "link": 128,
431 | "name": "negative",
432 | "type": "CONDITIONING",
433 | "label": "negative"
434 | },
435 | {
436 | "link": 43,
437 | "name": "latent_image",
438 | "type": "LATENT",
439 | "label": "latent_image",
440 | "slot_index": 3
441 | }
442 | ],
443 | "outputs": [
444 | {
445 | "name": "LATENT",
446 | "type": "LATENT",
447 | "label": "LATENT",
448 | "links": [
449 | 7
450 | ],
451 | "slot_index": 0
452 | }
453 | ],
454 | "properties": {
455 | "Node name for S&R": "KSampler"
456 | },
457 | "widgets_values": [
458 | 765566763195824,
459 | "randomize",
460 | 8,
461 | 2,
462 | "dpmpp_sde",
463 | "normal",
464 | 1
465 | ]
466 | },
467 | {
468 | "id": 8,
469 | "type": "VAEDecode",
470 | "pos": [
471 | 935,
472 | 829
473 | ],
474 | "size": {
475 | "0": 300.83819580078125,
476 | "1": 49.89173126220703
477 | },
478 | "flags": {},
479 | "order": 17,
480 | "mode": 0,
481 | "inputs": [
482 | {
483 | "link": 7,
484 | "name": "samples",
485 | "type": "LATENT",
486 | "label": "samples"
487 | },
488 | {
489 | "link": 17,
490 | "name": "vae",
491 | "type": "VAE",
492 | "label": "vae"
493 | }
494 | ],
495 | "outputs": [
496 | {
497 | "name": "IMAGE",
498 | "type": "IMAGE",
499 | "label": "IMAGE",
500 | "links": [
501 | 55
502 | ],
503 | "slot_index": 0
504 | }
505 | ],
506 | "properties": {
507 | "Node name for S&R": "VAEDecode"
508 | }
509 | },
510 | {
511 | "id": 55,
512 | "type": "IPAdapterApplyFaceID",
513 | "pos": [
514 | 680,
515 | -164
516 | ],
517 | "size": {
518 | "0": 315,
519 | "1": 326
520 | },
521 | "flags": {},
522 | "order": 12,
523 | "mode": 0,
524 | "inputs": [
525 | {
526 | "link": 76,
527 | "name": "ipadapter",
528 | "type": "IPADAPTER",
529 | "label": "ipadapter"
530 | },
531 | {
532 | "link": 77,
533 | "name": "clip_vision",
534 | "type": "CLIP_VISION",
535 | "label": "clip_vision"
536 | },
537 | {
538 | "link": 78,
539 | "name": "insightface",
540 | "type": "INSIGHTFACE",
541 | "label": "insightface"
542 | },
543 | {
544 | "link": 79,
545 | "name": "image",
546 | "type": "IMAGE",
547 | "label": "image"
548 | },
549 | {
550 | "link": 80,
551 | "name": "model",
552 | "type": "MODEL",
553 | "label": "model"
554 | },
555 | {
556 | "link": null,
557 | "name": "attn_mask",
558 | "type": "MASK",
559 | "label": "attn_mask"
560 | }
561 | ],
562 | "outputs": [
563 | {
564 | "name": "MODEL",
565 | "type": "MODEL",
566 | "label": "MODEL",
567 | "links": [
568 | 81
569 | ],
570 | "shape": 3,
571 | "slot_index": 0
572 | }
573 | ],
574 | "properties": {
575 | "Node name for S&R": "IPAdapterApplyFaceID"
576 | },
577 | "widgets_values": [
578 | 1,
579 | 0.1,
580 | "channel penalty",
581 | 0,
582 | 1,
583 | false,
584 | 1,
585 | false
586 | ]
587 | },
588 | {
589 | "id": 73,
590 | "type": "Canny",
591 | "pos": [
592 | 568,
593 | 857
594 | ],
595 | "size": {
596 | "0": 315,
597 | "1": 82
598 | },
599 | "flags": {
600 | "collapsed": false
601 | },
602 | "order": 9,
603 | "mode": 4,
604 | "inputs": [
605 | {
606 | "name": "image",
607 | "type": "IMAGE",
608 | "link": 129
609 | }
610 | ],
611 | "outputs": [
612 | {
613 | "name": "IMAGE",
614 | "type": "IMAGE",
615 | "links": [
616 | 130,
617 | 131
618 | ],
619 | "shape": 3,
620 | "slot_index": 0
621 | }
622 | ],
623 | "properties": {
624 | "Node name for S&R": "Canny"
625 | },
626 | "widgets_values": [
627 | 0.01,
628 | 0.99
629 | ]
630 | },
631 | {
632 | "id": 40,
633 | "type": "SaveImage",
634 | "pos": [
635 | 1298,
636 | 129
637 | ],
638 | "size": {
639 | "0": 695.1788330078125,
640 | "1": 859.2650756835938
641 | },
642 | "flags": {},
643 | "order": 18,
644 | "mode": 0,
645 | "inputs": [
646 | {
647 | "link": 55,
648 | "name": "images",
649 | "type": "IMAGE",
650 | "label": "images"
651 | }
652 | ],
653 | "properties": {},
654 | "widgets_values": [
655 | "TensorArt"
656 | ]
657 | },
658 | {
659 | "id": 74,
660 | "type": "PreviewImage",
661 | "pos": [
662 | 94,
663 | 653
664 | ],
665 | "size": [
666 | 310.60825056914086,
667 | 256.2006718931643
668 | ],
669 | "flags": {},
670 | "order": 11,
671 | "mode": 4,
672 | "inputs": [
673 | {
674 | "name": "images",
675 | "type": "IMAGE",
676 | "link": 131
677 | }
678 | ],
679 | "properties": {
680 | "Node name for S&R": "PreviewImage"
681 | }
682 | },
683 | {
684 | "id": 49,
685 | "type": "SDXLPromptStyler",
686 | "pos": [
687 | 477,
688 | 253
689 | ],
690 | "size": {
691 | "0": 400,
692 | "1": 242
693 | },
694 | "flags": {
695 | "collapsed": false
696 | },
697 | "order": 6,
698 | "mode": 0,
699 | "outputs": [
700 | {
701 | "name": "text_positive",
702 | "type": "STRING",
703 | "label": "text_positive",
704 | "links": [
705 | 110
706 | ],
707 | "shape": 3,
708 | "slot_index": 0
709 | },
710 | {
711 | "name": "text_negative",
712 | "type": "STRING",
713 | "label": "text_negative",
714 | "links": [
715 | 118
716 | ],
717 | "shape": 3,
718 | "slot_index": 1
719 | }
720 | ],
721 | "title": "Write your promt",
722 | "properties": {
723 | "Node name for S&R": "SDXLPromptStyler"
724 | },
725 | "widgets_values": [
726 | "a portrait photo of a man, close up",
727 | "",
728 | "sai-line art",
729 | true,
730 | true,
731 | true
732 | ]
733 | },
734 | {
735 | "id": 16,
736 | "type": "LoraLoader",
737 | "pos": [
738 | -453,
739 | 106
740 | ],
741 | "size": {
742 | "0": 315,
743 | "1": 150
744 | },
745 | "flags": {},
746 | "order": 8,
747 | "mode": 0,
748 | "inputs": [
749 | {
750 | "link": 18,
751 | "name": "model",
752 | "type": "MODEL",
753 | "label": "model"
754 | },
755 | {
756 | "link": 19,
757 | "name": "clip",
758 | "type": "CLIP",
759 | "label": "clip"
760 | }
761 | ],
762 | "outputs": [
763 | {
764 | "name": "MODEL",
765 | "type": "MODEL",
766 | "label": "MODEL",
767 | "links": [
768 | 83
769 | ],
770 | "shape": 3,
771 | "slot_index": 0
772 | },
773 | {
774 | "name": "CLIP",
775 | "type": "CLIP",
776 | "label": "CLIP",
777 | "links": [
778 | 84
779 | ],
780 | "shape": 3,
781 | "slot_index": 1
782 | }
783 | ],
784 | "properties": {
785 | "Node name for S&R": "LoraLoader"
786 | },
787 | "widgets_values": [
788 | "lineartSDXL.safetensors",
789 | 0.5,
790 | 0
791 | ]
792 | },
793 | {
794 | "id": 17,
795 | "type": "LoraLoader",
796 | "pos": [
797 | -443,
798 | 320
799 | ],
800 | "size": {
801 | "0": 315,
802 | "1": 150
803 | },
804 | "flags": {},
805 | "order": 10,
806 | "mode": 0,
807 | "inputs": [
808 | {
809 | "link": 83,
810 | "name": "model",
811 | "type": "MODEL",
812 | "label": "model"
813 | },
814 | {
815 | "link": 84,
816 | "name": "clip",
817 | "type": "CLIP",
818 | "label": "clip"
819 | }
820 | ],
821 | "outputs": [
822 | {
823 | "name": "MODEL",
824 | "type": "MODEL",
825 | "label": "MODEL",
826 | "links": [
827 | 80
828 | ],
829 | "shape": 3,
830 | "slot_index": 0
831 | },
832 | {
833 | "name": "CLIP",
834 | "type": "CLIP",
835 | "label": "CLIP",
836 | "links": [
837 | 111,
838 | 119
839 | ],
840 | "shape": 3,
841 | "slot_index": 1
842 | }
843 | ],
844 | "properties": {
845 | "Node name for S&R": "LoraLoader"
846 | },
847 | "widgets_values": [
848 | "ip-adapter-faceid_sdxl_lora.safetensors",
849 | 0.5,
850 | 0
851 | ]
852 | },
853 | {
854 | "id": 30,
855 | "type": "EmptyLatentImage",
856 | "pos": [
857 | 927,
858 | 362
859 | ],
860 | "size": {
861 | "0": 315,
862 | "1": 106
863 | },
864 | "flags": {},
865 | "order": 7,
866 | "mode": 0,
867 | "outputs": [
868 | {
869 | "name": "LATENT",
870 | "type": "LATENT",
871 | "label": "LATENT",
872 | "links": [
873 | 43
874 | ],
875 | "shape": 3
876 | }
877 | ],
878 | "properties": {
879 | "Node name for S&R": "EmptyLatentImage"
880 | },
881 | "widgets_values": [
882 | 1024,
883 | 1024,
884 | 1
885 | ]
886 | }
887 | ],
888 | "links": [
889 | [
890 | 7,
891 | 3,
892 | 0,
893 | 8,
894 | 0,
895 | "LATENT"
896 | ],
897 | [
898 | 17,
899 | 14,
900 | 2,
901 | 8,
902 | 1,
903 | "VAE"
904 | ],
905 | [
906 | 18,
907 | 14,
908 | 0,
909 | 16,
910 | 0,
911 | "MODEL"
912 | ],
913 | [
914 | 19,
915 | 14,
916 | 1,
917 | 16,
918 | 1,
919 | "CLIP"
920 | ],
921 | [
922 | 43,
923 | 30,
924 | 0,
925 | 3,
926 | 3,
927 | "LATENT"
928 | ],
929 | [
930 | 55,
931 | 8,
932 | 0,
933 | 40,
934 | 0,
935 | "IMAGE"
936 | ],
937 | [
938 | 76,
939 | 56,
940 | 0,
941 | 55,
942 | 0,
943 | "IPADAPTER"
944 | ],
945 | [
946 | 77,
947 | 57,
948 | 0,
949 | 55,
950 | 1,
951 | "CLIP_VISION"
952 | ],
953 | [
954 | 78,
955 | 58,
956 | 0,
957 | 55,
958 | 2,
959 | "INSIGHTFACE"
960 | ],
961 | [
962 | 79,
963 | 10,
964 | 0,
965 | 55,
966 | 3,
967 | "IMAGE"
968 | ],
969 | [
970 | 80,
971 | 17,
972 | 0,
973 | 55,
974 | 4,
975 | "MODEL"
976 | ],
977 | [
978 | 81,
979 | 55,
980 | 0,
981 | 3,
982 | 0,
983 | "MODEL"
984 | ],
985 | [
986 | 83,
987 | 16,
988 | 0,
989 | 17,
990 | 0,
991 | "MODEL"
992 | ],
993 | [
994 | 84,
995 | 16,
996 | 1,
997 | 17,
998 | 1,
999 | "CLIP"
1000 | ],
1001 | [
1002 | 110,
1003 | 49,
1004 | 0,
1005 | 66,
1006 | 1,
1007 | "STRING"
1008 | ],
1009 | [
1010 | 111,
1011 | 17,
1012 | 1,
1013 | 66,
1014 | 0,
1015 | "CLIP"
1016 | ],
1017 | [
1018 | 118,
1019 | 49,
1020 | 1,
1021 | 70,
1022 | 1,
1023 | "STRING"
1024 | ],
1025 | [
1026 | 119,
1027 | 17,
1028 | 1,
1029 | 70,
1030 | 0,
1031 | "CLIP"
1032 | ],
1033 | [
1034 | 121,
1035 | 72,
1036 | 0,
1037 | 71,
1038 | 2,
1039 | "CONTROL_NET"
1040 | ],
1041 | [
1042 | 125,
1043 | 70,
1044 | 0,
1045 | 71,
1046 | 1,
1047 | "CONDITIONING"
1048 | ],
1049 | [
1050 | 126,
1051 | 66,
1052 | 0,
1053 | 71,
1054 | 0,
1055 | "CONDITIONING"
1056 | ],
1057 | [
1058 | 127,
1059 | 71,
1060 | 0,
1061 | 3,
1062 | 1,
1063 | "CONDITIONING"
1064 | ],
1065 | [
1066 | 128,
1067 | 71,
1068 | 1,
1069 | 3,
1070 | 2,
1071 | "CONDITIONING"
1072 | ],
1073 | [
1074 | 129,
1075 | 10,
1076 | 0,
1077 | 73,
1078 | 0,
1079 | "IMAGE"
1080 | ],
1081 | [
1082 | 130,
1083 | 73,
1084 | 0,
1085 | 71,
1086 | 3,
1087 | "IMAGE"
1088 | ],
1089 | [
1090 | 131,
1091 | 73,
1092 | 0,
1093 | 74,
1094 | 0,
1095 | "IMAGE"
1096 | ]
1097 | ],
1098 | "groups": [
1099 | {
1100 | "title": "The essentials",
1101 | "bounding": [
1102 | 44,
1103 | 191,
1104 | 860,
1105 | 769
1106 | ],
1107 | "color": "#8A8",
1108 | "font_size": 40
1109 | }
1110 | ],
1111 | "config": {},
1112 | "extra": {},
1113 | "version": 0.4
1114 | },
1115 | "snapshot_json": {
1116 | "comfyui": null,
1117 | "git_custom_nodes": {
1118 | "https://github.com/cubiq/ComfyUI_IPAdapter_plus": {
1119 | "hash": null,
1120 | "disabled": false
1121 | },
1122 | "https://github.com/hylarucoder/ComfyUI-Eagle-PNGInfo": {
1123 | "hash": null,
1124 | "disabled": false
1125 | },
1126 | "https://github.com/sipherxyz/comfyui-art-venture": {
1127 | "hash": null,
1128 | "disabled": false
1129 | },
1130 | "https://github.com/twri/sdxl_prompt_styler": {
1131 | "hash": null,
1132 | "disabled": false
1133 | }
1134 | }
1135 | },
1136 | "files": [
1137 | [
1138 | {
1139 | "download_url": "https://comfyworkflows.com/api/comfyui-launcher/files/h/44131596/download",
1140 | "dest_relative_path": "models/ipadapter/ip-adapter-faceid_sdxl.bin",
1141 | "sha256_checksum": "f455fed24e207c878ec1e0466b34a969d37bab857c5faa4e8d259a0b4ff63d7e",
1142 | "size": 1071149741
1143 | }
1144 | ],
1145 | [
1146 | {
1147 | "download_url": "https://comfyworkflows.com/api/comfyui-launcher/files/h/2714420/download",
1148 | "dest_relative_path": "models/clip_vision/clip_vision_vit_h.safetensors",
1149 | "sha256_checksum": "9a11c14945fb98c7ac9a54fab5e498885731a0780260dad7adf41f6f59655ee5",
1150 | "size": 1972298538
1151 | }
1152 | ],
1153 | [
1154 | {
1155 | "download_url": "https://comfyworkflows.com/api/comfyui-launcher/files/h/271469/download",
1156 | "dest_relative_path": "models/checkpoints/opendalle_v11.safetensors",
1157 | "sha256_checksum": "673887ace8a5c56388a10e8d576d08f609393d981ea4938511179b50f09bdcc4",
1158 | "size": 6939232042
1159 | },
1160 | {
1161 | "download_url": "https://comfyworkflows.com/api/comfyui-launcher/files/c/17944/download",
1162 | "dest_relative_path": "models/checkpoints/opendalle_v11.safetensors",
1163 | "sha256_checksum": "673887ace8a5c56388a10e8d576d08f609393d981ea4938511179b50f09bdcc4",
1164 | "size": 6939228160
1165 | }
1166 | ],
1167 | [
1168 | {
1169 | "download_url": "https://comfyworkflows.com/api/comfyui-launcher/files/c/71125/download",
1170 | "dest_relative_path": "models/loras/lineartSDXL.safetensors",
1171 | "sha256_checksum": "b747719129049ec50c9ac05ab207b8418e24bc2e12ee81036b9a157d422b99ab",
1172 | "size": 228453376
1173 | }
1174 | ],
1175 | [
1176 | {
1177 | "download_url": "https://comfyworkflows.com/api/comfyui-launcher/files/h/274966/download",
1178 | "dest_relative_path": "models/loras/ip-adapter-faceid_sdxl_lora.safetensors",
1179 | "sha256_checksum": "4fcf93d6e8dc8dd18f5f9e51c8306f369486ed0aa0780ade9961308aff7f0d64",
1180 | "size": 371842896
1181 | }
1182 | ],
1183 | [
1184 | {
1185 | "download_url" : "https://t3.ftcdn.net/jpg/02/58/89/90/360_F_258899001_68CalsKTRk6PZQgWH9JhR4heBlncCko9.jpg",
1186 | "dest_relative_path": "input/360_F_258899001_68CalsKTRk6PZQgWH9JhR4heBlncCko9.jpg",
1187 | "sha256_checksum": "3bf2316058abe90fb0fcf76e46ccb0fee433a1eaac36359222cdf401f513bc54",
1188 | "size" : 20474
1189 | }
1190 | ]
1191 | ],
1192 | "pip_requirements": [
1193 | "insightface",
1194 | "onnxruntime",
1195 | "segment_anything",
1196 | "omegaconf"
1197 | ],
1198 | "os": {},
1199 | "python_version": {}
1200 | }
--------------------------------------------------------------------------------
/templates/img2vid/workflow.json:
--------------------------------------------------------------------------------
1 | {
2 | "last_node_id": 60,
3 | "last_link_id": 103,
4 | "nodes": [
5 | {
6 | "id": 8,
7 | "type": "VAEDecode",
8 | "pos": [
9 | 1990.130282335937,
10 | 333.6667562822272
11 | ],
12 | "size": {
13 | "0": 210,
14 | "1": 46
15 | },
16 | "flags": {},
17 | "order": 10,
18 | "mode": 0,
19 | "inputs": [
20 | {
21 | "name": "samples",
22 | "type": "LATENT",
23 | "link": 79
24 | },
25 | {
26 | "name": "vae",
27 | "type": "VAE",
28 | "link": 57
29 | }
30 | ],
31 | "outputs": [
32 | {
33 | "name": "IMAGE",
34 | "type": "IMAGE",
35 | "links": [
36 | 42,
37 | 88
38 | ],
39 | "slot_index": 0
40 | }
41 | ],
42 | "properties": {
43 | "Node name for S&R": "VAEDecode"
44 | }
45 | },
46 | {
47 | "id": 53,
48 | "type": "ImageUpscaleWithModel",
49 | "pos": [
50 | 1990.130282335937,
51 | 773.6667562822275
52 | ],
53 | "size": {
54 | "0": 241.79998779296875,
55 | "1": 46
56 | },
57 | "flags": {},
58 | "order": 12,
59 | "mode": 2,
60 | "inputs": [
61 | {
62 | "name": "upscale_model",
63 | "type": "UPSCALE_MODEL",
64 | "link": 87
65 | },
66 | {
67 | "name": "image",
68 | "type": "IMAGE",
69 | "link": 88
70 | }
71 | ],
72 | "outputs": [
73 | {
74 | "name": "IMAGE",
75 | "type": "IMAGE",
76 | "links": [
77 | 89
78 | ],
79 | "shape": 3,
80 | "slot_index": 0
81 | }
82 | ],
83 | "properties": {
84 | "Node name for S&R": "ImageUpscaleWithModel"
85 | }
86 | },
87 | {
88 | "id": 47,
89 | "type": "VHS_VideoCombine",
90 | "pos": [
91 | 2300.130282335937,
92 | 773.6667562822275
93 | ],
94 | "size": [
95 | 315,
96 | 174
97 | ],
98 | "flags": {},
99 | "order": 13,
100 | "mode": 2,
101 | "inputs": [
102 | {
103 | "name": "images",
104 | "type": "IMAGE",
105 | "link": 89
106 | },
107 | {
108 | "name": "frame_rate",
109 | "type": "INT",
110 | "link": 84,
111 | "widget": {
112 | "name": "frame_rate"
113 | }
114 | }
115 | ],
116 | "outputs": [],
117 | "properties": {
118 | "Node name for S&R": "VHS_VideoCombine"
119 | },
120 | "widgets_values": {
121 | "frame_rate": 6,
122 | "loop_count": 0,
123 | "filename_prefix": "img2vid",
124 | "format": "video/h264-mp4",
125 | "pingpong": false,
126 | "save_image": false,
127 | "videopreview": {
128 | "hidden": false,
129 | "paused": false,
130 | "params": {
131 | "filename": "img2vid_00017_.mp4",
132 | "subfolder": "",
133 | "type": "temp",
134 | "format": "video/h264-mp4"
135 | }
136 | }
137 | }
138 | },
139 | {
140 | "id": 14,
141 | "type": "VideoLinearCFGGuidance",
142 | "pos": [
143 | 1240.1302823359367,
144 | 263.66675628222686
145 | ],
146 | "size": {
147 | "0": 315,
148 | "1": 58
149 | },
150 | "flags": {},
151 | "order": 6,
152 | "mode": 0,
153 | "inputs": [
154 | {
155 | "name": "model",
156 | "type": "MODEL",
157 | "link": 23
158 | }
159 | ],
160 | "outputs": [
161 | {
162 | "name": "MODEL",
163 | "type": "MODEL",
164 | "links": [
165 | 39
166 | ],
167 | "shape": 3,
168 | "slot_index": 0
169 | }
170 | ],
171 | "properties": {
172 | "Node name for S&R": "VideoLinearCFGGuidance"
173 | },
174 | "widgets_values": [
175 | 1
176 | ]
177 | },
178 | {
179 | "id": 15,
180 | "type": "ImageOnlyCheckpointLoader",
181 | "pos": [
182 | 820.1302823359363,
183 | 263.66675628222686
184 | ],
185 | "size": {
186 | "0": 369.6000061035156,
187 | "1": 98
188 | },
189 | "flags": {},
190 | "order": 0,
191 | "mode": 0,
192 | "outputs": [
193 | {
194 | "name": "MODEL",
195 | "type": "MODEL",
196 | "links": [
197 | 23
198 | ],
199 | "shape": 3,
200 | "slot_index": 0
201 | },
202 | {
203 | "name": "CLIP_VISION",
204 | "type": "CLIP_VISION",
205 | "links": [
206 | 24
207 | ],
208 | "shape": 3,
209 | "slot_index": 1
210 | },
211 | {
212 | "name": "VAE",
213 | "type": "VAE",
214 | "links": [
215 | 25
216 | ],
217 | "shape": 3,
218 | "slot_index": 2
219 | }
220 | ],
221 | "properties": {
222 | "Node name for S&R": "ImageOnlyCheckpointLoader"
223 | },
224 | "widgets_values": [
225 | "svd_xt.safetensors"
226 | ]
227 | },
228 | {
229 | "id": 24,
230 | "type": "VHS_VideoCombine",
231 | "pos": [
232 | 2300.130282335937,
233 | 333.6667562822272
234 | ],
235 | "size": [
236 | 315,
237 | 338.3125
238 | ],
239 | "flags": {},
240 | "order": 11,
241 | "mode": 0,
242 | "inputs": [
243 | {
244 | "name": "images",
245 | "type": "IMAGE",
246 | "link": 42
247 | },
248 | {
249 | "name": "frame_rate",
250 | "type": "INT",
251 | "link": 59,
252 | "widget": {
253 | "name": "frame_rate"
254 | }
255 | }
256 | ],
257 | "outputs": [],
258 | "properties": {
259 | "Node name for S&R": "VHS_VideoCombine"
260 | },
261 | "widgets_values": {
262 | "frame_rate": 6,
263 | "loop_count": 0,
264 | "filename_prefix": "img2vid",
265 | "format": "image/gif",
266 | "pingpong": false,
267 | "save_image": false,
268 | "videopreview": {
269 | "hidden": false,
270 | "paused": false,
271 | "params": {
272 | "filename": "img2vid_00003_.gif",
273 | "subfolder": "",
274 | "type": "temp",
275 | "format": "image/gif"
276 | }
277 | }
278 | }
279 | },
280 | {
281 | "id": 34,
282 | "type": "ImageOnlyCheckpointLoader",
283 | "pos": [
284 | 1590.364006835938,
285 | 190.14003784179684
286 | ],
287 | "size": {
288 | "0": 370,
289 | "1": 100
290 | },
291 | "flags": {},
292 | "order": 1,
293 | "mode": 0,
294 | "outputs": [
295 | {
296 | "name": "MODEL",
297 | "type": "MODEL",
298 | "links": null,
299 | "shape": 3
300 | },
301 | {
302 | "name": "CLIP_VISION",
303 | "type": "CLIP_VISION",
304 | "links": null,
305 | "shape": 3
306 | },
307 | {
308 | "name": "VAE",
309 | "type": "VAE",
310 | "links": [
311 | 57
312 | ],
313 | "shape": 3,
314 | "slot_index": 2
315 | }
316 | ],
317 | "properties": {
318 | "Node name for S&R": "ImageOnlyCheckpointLoader"
319 | },
320 | "widgets_values": [
321 | "svd_xt_image_decoder.safetensors"
322 | ]
323 | },
324 | {
325 | "id": 3,
326 | "type": "KSampler",
327 | "pos": [
328 | 1650.1302823359374,
329 | 333.6667562822272
330 | ],
331 | "size": {
332 | "0": 310,
333 | "1": 262
334 | },
335 | "flags": {},
336 | "order": 9,
337 | "mode": 0,
338 | "inputs": [
339 | {
340 | "name": "model",
341 | "type": "MODEL",
342 | "link": 39
343 | },
344 | {
345 | "name": "positive",
346 | "type": "CONDITIONING",
347 | "link": 40
348 | },
349 | {
350 | "name": "negative",
351 | "type": "CONDITIONING",
352 | "link": 17
353 | },
354 | {
355 | "name": "latent_image",
356 | "type": "LATENT",
357 | "link": 18
358 | }
359 | ],
360 | "outputs": [
361 | {
362 | "name": "LATENT",
363 | "type": "LATENT",
364 | "links": [
365 | 79
366 | ],
367 | "slot_index": 0
368 | }
369 | ],
370 | "properties": {
371 | "Node name for S&R": "KSampler"
372 | },
373 | "widgets_values": [
374 | 1337,
375 | "fixed",
376 | 35,
377 | 2.5,
378 | "euler_ancestral",
379 | "karras",
380 | 1
381 | ]
382 | },
383 | {
384 | "id": 12,
385 | "type": "SVD_img2vid_Conditioning",
386 | "pos": [
387 | 1240.1302823359367,
388 | 353.6667562822272
389 | ],
390 | "size": [
391 | 315,
392 | 218
393 | ],
394 | "flags": {},
395 | "order": 8,
396 | "mode": 0,
397 | "inputs": [
398 | {
399 | "name": "clip_vision",
400 | "type": "CLIP_VISION",
401 | "link": 24
402 | },
403 | {
404 | "name": "init_image",
405 | "type": "IMAGE",
406 | "link": 103,
407 | "slot_index": 1
408 | },
409 | {
410 | "name": "vae",
411 | "type": "VAE",
412 | "link": 25
413 | },
414 | {
415 | "name": "fps",
416 | "type": "INT",
417 | "link": 58,
418 | "widget": {
419 | "name": "fps"
420 | }
421 | },
422 | {
423 | "name": "width",
424 | "type": "INT",
425 | "link": 101,
426 | "widget": {
427 | "name": "width"
428 | }
429 | },
430 | {
431 | "name": "height",
432 | "type": "INT",
433 | "link": 102,
434 | "widget": {
435 | "name": "height"
436 | }
437 | }
438 | ],
439 | "outputs": [
440 | {
441 | "name": "positive",
442 | "type": "CONDITIONING",
443 | "links": [
444 | 40
445 | ],
446 | "shape": 3,
447 | "slot_index": 0
448 | },
449 | {
450 | "name": "negative",
451 | "type": "CONDITIONING",
452 | "links": [
453 | 17
454 | ],
455 | "shape": 3,
456 | "slot_index": 1
457 | },
458 | {
459 | "name": "latent",
460 | "type": "LATENT",
461 | "links": [
462 | 18
463 | ],
464 | "shape": 3,
465 | "slot_index": 2
466 | }
467 | ],
468 | "properties": {
469 | "Node name for S&R": "SVD_img2vid_Conditioning"
470 | },
471 | "widgets_values": [
472 | 1024,
473 | 576,
474 | 25,
475 | 32,
476 | 6,
477 | 0
478 | ]
479 | },
480 | {
481 | "id": 50,
482 | "type": "UpscaleModelLoader",
483 | "pos": [
484 | 1910.3640068359373,
485 | 680.1400378417969
486 | ],
487 | "size": {
488 | "0": 320,
489 | "1": 60
490 | },
491 | "flags": {},
492 | "order": 2,
493 | "mode": 2,
494 | "outputs": [
495 | {
496 | "name": "UPSCALE_MODEL",
497 | "type": "UPSCALE_MODEL",
498 | "links": [
499 | 87
500 | ],
501 | "shape": 3,
502 | "slot_index": 0
503 | }
504 | ],
505 | "properties": {
506 | "Node name for S&R": "UpscaleModelLoader"
507 | },
508 | "widgets_values": [
509 | "4xLSDIRDAT.pth"
510 | ]
511 | },
512 | {
513 | "id": 58,
514 | "type": "Note",
515 | "pos": [
516 | 2011.3640068359373,
517 | 865.1400378417969
518 | ],
519 | "size": [
520 | 220,
521 | 90
522 | ],
523 | "flags": {},
524 | "order": 3,
525 | "mode": 0,
526 | "title": "Upsampling Notes",
527 | "properties": {
528 | "text": ""
529 | },
530 | "widgets_values": [
531 | "Upsampling is disabled by default. Once you have a base generation you're happy with, select the 3 grayed out nodes and do CTRL+M to \"unmute\" them."
532 | ],
533 | "color": "#432",
534 | "bgcolor": "#653"
535 | },
536 | {
537 | "id": 35,
538 | "type": "PrimitiveNode",
539 | "pos": [
540 | 1240,
541 | 610
542 | ],
543 | "size": {
544 | "0": 210,
545 | "1": 82
546 | },
547 | "flags": {},
548 | "order": 4,
549 | "mode": 0,
550 | "outputs": [
551 | {
552 | "name": "INT",
553 | "type": "INT",
554 | "links": [
555 | 58,
556 | 59,
557 | 84
558 | ],
559 | "slot_index": 0,
560 | "widget": {
561 | "name": "fps"
562 | }
563 | }
564 | ],
565 | "title": "FPS",
566 | "properties": {},
567 | "widgets_values": [
568 | 6,
569 | "fixed"
570 | ]
571 | },
572 | {
573 | "id": 60,
574 | "type": "ImageGenResolutionFromImage",
575 | "pos": [
576 | 824,
577 | 753
578 | ],
579 | "size": {
580 | "0": 355.20001220703125,
581 | "1": 46
582 | },
583 | "flags": {},
584 | "order": 7,
585 | "mode": 0,
586 | "inputs": [
587 | {
588 | "name": "image",
589 | "type": "IMAGE",
590 | "link": 100,
591 | "slot_index": 0
592 | }
593 | ],
594 | "outputs": [
595 | {
596 | "name": "IMAGE_GEN_WIDTH (INT)",
597 | "type": "INT",
598 | "links": [
599 | 101
600 | ],
601 | "shape": 3,
602 | "slot_index": 0
603 | },
604 | {
605 | "name": "IMAGE_GEN_HEIGHT (INT)",
606 | "type": "INT",
607 | "links": [
608 | 102
609 | ],
610 | "shape": 3,
611 | "slot_index": 1
612 | }
613 | ],
614 | "properties": {
615 | "Node name for S&R": "ImageGenResolutionFromImage"
616 | }
617 | },
618 | {
619 | "id": 59,
620 | "type": "LoadImage",
621 | "pos": [
622 | 849,
623 | 404
624 | ],
625 | "size": [
626 | 315,
627 | 314.0000305175781
628 | ],
629 | "flags": {},
630 | "order": 5,
631 | "mode": 0,
632 | "outputs": [
633 | {
634 | "name": "IMAGE",
635 | "type": "IMAGE",
636 | "links": [
637 | 100,
638 | 103
639 | ],
640 | "shape": 3,
641 | "slot_index": 0
642 | },
643 | {
644 | "name": "MASK",
645 | "type": "MASK",
646 | "links": null,
647 | "shape": 3
648 | }
649 | ],
650 | "properties": {
651 | "Node name for S&R": "LoadImage"
652 | },
653 | "widgets_values": [
654 | "maxresdefault-1605111824-hq-width-1024px.jpg",
655 | "image"
656 | ]
657 | }
658 | ],
659 | "links": [
660 | [
661 | 17,
662 | 12,
663 | 1,
664 | 3,
665 | 2,
666 | "CONDITIONING"
667 | ],
668 | [
669 | 18,
670 | 12,
671 | 2,
672 | 3,
673 | 3,
674 | "LATENT"
675 | ],
676 | [
677 | 23,
678 | 15,
679 | 0,
680 | 14,
681 | 0,
682 | "MODEL"
683 | ],
684 | [
685 | 24,
686 | 15,
687 | 1,
688 | 12,
689 | 0,
690 | "CLIP_VISION"
691 | ],
692 | [
693 | 25,
694 | 15,
695 | 2,
696 | 12,
697 | 2,
698 | "VAE"
699 | ],
700 | [
701 | 39,
702 | 14,
703 | 0,
704 | 3,
705 | 0,
706 | "MODEL"
707 | ],
708 | [
709 | 40,
710 | 12,
711 | 0,
712 | 3,
713 | 1,
714 | "CONDITIONING"
715 | ],
716 | [
717 | 42,
718 | 8,
719 | 0,
720 | 24,
721 | 0,
722 | "IMAGE"
723 | ],
724 | [
725 | 57,
726 | 34,
727 | 2,
728 | 8,
729 | 1,
730 | "VAE"
731 | ],
732 | [
733 | 58,
734 | 35,
735 | 0,
736 | 12,
737 | 3,
738 | "INT"
739 | ],
740 | [
741 | 59,
742 | 35,
743 | 0,
744 | 24,
745 | 1,
746 | "INT"
747 | ],
748 | [
749 | 79,
750 | 3,
751 | 0,
752 | 8,
753 | 0,
754 | "LATENT"
755 | ],
756 | [
757 | 84,
758 | 35,
759 | 0,
760 | 47,
761 | 1,
762 | "INT"
763 | ],
764 | [
765 | 87,
766 | 50,
767 | 0,
768 | 53,
769 | 0,
770 | "UPSCALE_MODEL"
771 | ],
772 | [
773 | 88,
774 | 8,
775 | 0,
776 | 53,
777 | 1,
778 | "IMAGE"
779 | ],
780 | [
781 | 89,
782 | 53,
783 | 0,
784 | 47,
785 | 0,
786 | "IMAGE"
787 | ],
788 | [
789 | 100,
790 | 59,
791 | 0,
792 | 60,
793 | 0,
794 | "IMAGE"
795 | ],
796 | [
797 | 101,
798 | 60,
799 | 0,
800 | 12,
801 | 4,
802 | "INT"
803 | ],
804 | [
805 | 102,
806 | 60,
807 | 1,
808 | 12,
809 | 5,
810 | "INT"
811 | ],
812 | [
813 | 103,
814 | 59,
815 | 0,
816 | 12,
817 | 1,
818 | "IMAGE"
819 | ]
820 | ],
821 | "groups": [
822 | {
823 | "title": "img2vid",
824 | "bounding": [
825 | 800,
826 | 97,
827 | 1824,
828 | 1028
829 | ],
830 | "color": "#a1309b",
831 | "font_size": 24
832 | }
833 | ],
834 | "config": {},
835 | "extra": {},
836 | "version": 0.4
837 | }
--------------------------------------------------------------------------------
/templates/upscale/launcher.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0",
3 | "workflow_json": {
4 | "last_node_id": 1098,
5 | "last_link_id": 2130,
6 | "nodes": [
7 | {
8 | "id": 1070,
9 | "type": "VAELoader",
10 | "pos": [
11 | 0,
12 | 590
13 | ],
14 | "size": {
15 | "0": 400,
16 | "1": 60
17 | },
18 | "flags": {},
19 | "order": 0,
20 | "mode": 0,
21 | "outputs": [
22 | {
23 | "name": "VAE",
24 | "type": "VAE",
25 | "links": [
26 | 2106,
27 | 2122,
28 | 2126
29 | ],
30 | "shape": 3,
31 | "label": "Vae"
32 | }
33 | ],
34 | "properties": {
35 | "Node name for S&R": "VAELoader"
36 | },
37 | "widgets_values": [
38 | "sdxl_vae.safetensors"
39 | ],
40 | "color": "#222",
41 | "bgcolor": "#000"
42 | },
43 | {
44 | "id": 1081,
45 | "type": "UpscaleModelLoader",
46 | "pos": [
47 | 0,
48 | 940
49 | ],
50 | "size": [
51 | 400,
52 | 60
53 | ],
54 | "flags": {},
55 | "order": 1,
56 | "mode": 0,
57 | "outputs": [
58 | {
59 | "name": "UPSCALE_MODEL",
60 | "type": "UPSCALE_MODEL",
61 | "links": [
62 | 2109
63 | ],
64 | "shape": 3,
65 | "label": "Upscale Model"
66 | }
67 | ],
68 | "properties": {
69 | "Node name for S&R": "UpscaleModelLoader"
70 | },
71 | "widgets_values": [
72 | "4x-UltraSharp.pth"
73 | ],
74 | "color": "#222",
75 | "bgcolor": "#000"
76 | },
77 | {
78 | "id": 1078,
79 | "type": "EmptyLatentImage",
80 | "pos": [
81 | 0,
82 | 790
83 | ],
84 | "size": [
85 | 400,
86 | 110
87 | ],
88 | "flags": {},
89 | "order": 2,
90 | "mode": 0,
91 | "outputs": [
92 | {
93 | "name": "LATENT",
94 | "type": "LATENT",
95 | "links": [
96 | 2104
97 | ],
98 | "shape": 3,
99 | "label": "Latent",
100 | "slot_index": 0
101 | }
102 | ],
103 | "properties": {
104 | "Node name for S&R": "EmptyLatentImage"
105 | },
106 | "widgets_values": [
107 | 1344,
108 | 768,
109 | 1
110 | ],
111 | "color": "#222",
112 | "bgcolor": "#000"
113 | },
114 | {
115 | "id": 1065,
116 | "type": "PrimitiveNode",
117 | "pos": [
118 | 0,
119 | 30
120 | ],
121 | "size": {
122 | "0": 400,
123 | "1": 170
124 | },
125 | "flags": {},
126 | "order": 3,
127 | "mode": 0,
128 | "outputs": [
129 | {
130 | "name": "STRING",
131 | "type": "STRING",
132 | "links": [
133 | 2093
134 | ],
135 | "widget": {
136 | "name": "text"
137 | },
138 | "label": "+"
139 | }
140 | ],
141 | "title": "Positive Prompt",
142 | "properties": {
143 | "Run widget replace on values": false
144 | },
145 | "widgets_values": [
146 | "Fallen Angle"
147 | ],
148 | "color": "#222",
149 | "bgcolor": "#000"
150 | },
151 | {
152 | "id": 1066,
153 | "type": "PrimitiveNode",
154 | "pos": [
155 | 0,
156 | 240
157 | ],
158 | "size": {
159 | "0": 400,
160 | "1": 160
161 | },
162 | "flags": {},
163 | "order": 4,
164 | "mode": 0,
165 | "outputs": [
166 | {
167 | "name": "STRING",
168 | "type": "STRING",
169 | "links": [
170 | 2098
171 | ],
172 | "widget": {
173 | "name": "text"
174 | },
175 | "label": "-",
176 | "slot_index": 0
177 | }
178 | ],
179 | "title": "Negative Prompt",
180 | "properties": {
181 | "Run widget replace on values": false
182 | },
183 | "widgets_values": [
184 | ""
185 | ],
186 | "color": "#222",
187 | "bgcolor": "#000"
188 | },
189 | {
190 | "id": 1064,
191 | "type": "CLIPTextEncode",
192 | "pos": [
193 | 420,
194 | 30
195 | ],
196 | "size": [
197 | 400,
198 | 50
199 | ],
200 | "flags": {
201 | "collapsed": false
202 | },
203 | "order": 10,
204 | "mode": 0,
205 | "inputs": [
206 | {
207 | "name": "clip",
208 | "type": "CLIP",
209 | "link": 2097,
210 | "label": "Clip"
211 | },
212 | {
213 | "name": "text",
214 | "type": "STRING",
215 | "link": 2093,
216 | "widget": {
217 | "name": "text"
218 | },
219 | "slot_index": 1,
220 | "label": "+"
221 | }
222 | ],
223 | "outputs": [
224 | {
225 | "name": "CONDITIONING",
226 | "type": "CONDITIONING",
227 | "links": [
228 | 2101,
229 | 2116
230 | ],
231 | "shape": 3,
232 | "label": "+",
233 | "slot_index": 0
234 | }
235 | ],
236 | "title": "Clip Encode",
237 | "properties": {
238 | "Node name for S&R": "CLIPTextEncode"
239 | },
240 | "widgets_values": [
241 | "Fallen Angle"
242 | ],
243 | "color": "#222",
244 | "bgcolor": "#000"
245 | },
246 | {
247 | "id": 1067,
248 | "type": "CLIPTextEncode",
249 | "pos": [
250 | 420,
251 | 120
252 | ],
253 | "size": [
254 | 400,
255 | 50
256 | ],
257 | "flags": {
258 | "collapsed": false
259 | },
260 | "order": 9,
261 | "mode": 0,
262 | "inputs": [
263 | {
264 | "name": "clip",
265 | "type": "CLIP",
266 | "link": 2096,
267 | "label": "Clip"
268 | },
269 | {
270 | "name": "text",
271 | "type": "STRING",
272 | "link": 2098,
273 | "widget": {
274 | "name": "text"
275 | },
276 | "slot_index": 1,
277 | "label": "-"
278 | }
279 | ],
280 | "outputs": [
281 | {
282 | "name": "CONDITIONING",
283 | "type": "CONDITIONING",
284 | "links": [
285 | 2102,
286 | 2117
287 | ],
288 | "shape": 3,
289 | "label": "-",
290 | "slot_index": 0
291 | }
292 | ],
293 | "title": "Clip Encode",
294 | "properties": {
295 | "Node name for S&R": "CLIPTextEncode"
296 | },
297 | "widgets_values": [
298 | ""
299 | ],
300 | "color": "#222",
301 | "bgcolor": "#000"
302 | },
303 | {
304 | "id": 1073,
305 | "type": "ControlNetLoader",
306 | "pos": [
307 | 0,
308 | 690
309 | ],
310 | "size": {
311 | "0": 400,
312 | "1": 60
313 | },
314 | "flags": {},
315 | "order": 5,
316 | "mode": 0,
317 | "outputs": [
318 | {
319 | "name": "CONTROL_NET",
320 | "type": "CONTROL_NET",
321 | "links": [
322 | 2120
323 | ],
324 | "shape": 3,
325 | "label": "ControlNet",
326 | "slot_index": 0
327 | }
328 | ],
329 | "properties": {
330 | "Node name for S&R": "ControlNetLoader"
331 | },
332 | "widgets_values": [
333 | "control-lora-depth-rank256.safetensors"
334 | ],
335 | "color": "#222",
336 | "bgcolor": "#000"
337 | },
338 | {
339 | "id": 1097,
340 | "type": "VAEDecode",
341 | "pos": [
342 | 840,
343 | 750
344 | ],
345 | "size": {
346 | "0": 400,
347 | "1": 50
348 | },
349 | "flags": {},
350 | "order": 21,
351 | "mode": 0,
352 | "inputs": [
353 | {
354 | "name": "samples",
355 | "type": "LATENT",
356 | "link": 2125,
357 | "label": "Latent"
358 | },
359 | {
360 | "name": "vae",
361 | "type": "VAE",
362 | "link": 2126,
363 | "label": "Vae",
364 | "slot_index": 1
365 | }
366 | ],
367 | "outputs": [
368 | {
369 | "name": "IMAGE",
370 | "type": "IMAGE",
371 | "links": [
372 | 2127
373 | ],
374 | "shape": 3,
375 | "label": "Image",
376 | "slot_index": 0
377 | }
378 | ],
379 | "properties": {
380 | "Node name for S&R": "VAEDecode"
381 | },
382 | "color": "#222",
383 | "bgcolor": "#000"
384 | },
385 | {
386 | "id": 1096,
387 | "type": "VAEEncode",
388 | "pos": [
389 | 840,
390 | 30
391 | ],
392 | "size": [
393 | 400,
394 | 50
395 | ],
396 | "flags": {},
397 | "order": 16,
398 | "mode": 0,
399 | "inputs": [
400 | {
401 | "name": "pixels",
402 | "type": "IMAGE",
403 | "link": 2121,
404 | "label": "Image"
405 | },
406 | {
407 | "name": "vae",
408 | "type": "VAE",
409 | "link": 2122,
410 | "label": "Vae",
411 | "slot_index": 1
412 | }
413 | ],
414 | "outputs": [
415 | {
416 | "name": "LATENT",
417 | "type": "LATENT",
418 | "links": [
419 | 2123
420 | ],
421 | "shape": 3,
422 | "label": "Latent",
423 | "slot_index": 0
424 | }
425 | ],
426 | "properties": {
427 | "Node name for S&R": "VAEEncode"
428 | },
429 | "color": "#222",
430 | "bgcolor": "#000"
431 | },
432 | {
433 | "id": 1086,
434 | "type": "VAEDecode",
435 | "pos": [
436 | 420,
437 | 520
438 | ],
439 | "size": [
440 | 400,
441 | 50
442 | ],
443 | "flags": {},
444 | "order": 12,
445 | "mode": 0,
446 | "inputs": [
447 | {
448 | "name": "samples",
449 | "type": "LATENT",
450 | "link": 2105,
451 | "label": "Latent"
452 | },
453 | {
454 | "name": "vae",
455 | "type": "VAE",
456 | "link": 2106,
457 | "label": "Vae",
458 | "slot_index": 1
459 | }
460 | ],
461 | "outputs": [
462 | {
463 | "name": "IMAGE",
464 | "type": "IMAGE",
465 | "links": [
466 | 2108
467 | ],
468 | "shape": 3,
469 | "label": "Image",
470 | "slot_index": 0
471 | }
472 | ],
473 | "properties": {
474 | "Node name for S&R": "VAEDecode"
475 | },
476 | "color": "#222",
477 | "bgcolor": "#000"
478 | },
479 | {
480 | "id": 1087,
481 | "type": "ImageUpscaleWithModel",
482 | "pos": [
483 | 420,
484 | 610
485 | ],
486 | "size": [
487 | 400,
488 | 60
489 | ],
490 | "flags": {},
491 | "order": 13,
492 | "mode": 0,
493 | "inputs": [
494 | {
495 | "name": "upscale_model",
496 | "type": "UPSCALE_MODEL",
497 | "link": 2109,
498 | "label": "Upscale Model",
499 | "slot_index": 0
500 | },
501 | {
502 | "name": "image",
503 | "type": "IMAGE",
504 | "link": 2108,
505 | "label": "Image"
506 | }
507 | ],
508 | "outputs": [
509 | {
510 | "name": "IMAGE",
511 | "type": "IMAGE",
512 | "links": [
513 | 2110
514 | ],
515 | "shape": 3,
516 | "label": "Image",
517 | "slot_index": 0
518 | }
519 | ],
520 | "properties": {
521 | "Node name for S&R": "ImageUpscaleWithModel"
522 | },
523 | "color": "#222",
524 | "bgcolor": "#000"
525 | },
526 | {
527 | "id": 1090,
528 | "type": "PreviewImage",
529 | "pos": [
530 | 420,
531 | 840
532 | ],
533 | "size": [
534 | 400,
535 | 460
536 | ],
537 | "flags": {},
538 | "order": 15,
539 | "mode": 0,
540 | "inputs": [
541 | {
542 | "name": "images",
543 | "type": "IMAGE",
544 | "link": 2111,
545 | "label": "Image"
546 | }
547 | ],
548 | "properties": {
549 | "Node name for S&R": "PreviewImage"
550 | },
551 | "color": "#222",
552 | "bgcolor": "#000"
553 | },
554 | {
555 | "id": 1083,
556 | "type": "Note",
557 | "pos": [
558 | 0,
559 | 1040
560 | ],
561 | "size": [
562 | 400,
563 | 260
564 | ],
565 | "flags": {},
566 | "order": 6,
567 | "mode": 0,
568 | "properties": {
569 | "text": ""
570 | },
571 | "widgets_values": [
572 | "→ CRTL-M to Mute Nodes\n\n→ CRTL-B to Bypass Nodes\n\n→ Ratios: \n 21 : 9 1536 x 640\n 19 : 9 1472 x 704\n 16 : 9 1344 x 768\n 3 : 2 1216 x 832\n 7 : 5 1176 x 840\n 4 : 3 1152 x 896\n 1 : 1 1024 x 1024\n\n "
573 | ],
574 | "color": "#222",
575 | "bgcolor": "#000"
576 | },
577 | {
578 | "id": 1085,
579 | "type": "KSampler",
580 | "pos": [
581 | 420,
582 | 210
583 | ],
584 | "size": [
585 | 400,
586 | 270
587 | ],
588 | "flags": {},
589 | "order": 11,
590 | "mode": 0,
591 | "inputs": [
592 | {
593 | "name": "model",
594 | "type": "MODEL",
595 | "link": 2107,
596 | "label": "Model"
597 | },
598 | {
599 | "name": "positive",
600 | "type": "CONDITIONING",
601 | "link": 2101,
602 | "label": "+"
603 | },
604 | {
605 | "name": "negative",
606 | "type": "CONDITIONING",
607 | "link": 2102,
608 | "label": "-"
609 | },
610 | {
611 | "name": "latent_image",
612 | "type": "LATENT",
613 | "link": 2104,
614 | "label": "Latent"
615 | }
616 | ],
617 | "outputs": [
618 | {
619 | "name": "LATENT",
620 | "type": "LATENT",
621 | "links": [
622 | 2105
623 | ],
624 | "shape": 3,
625 | "label": "Latent",
626 | "slot_index": 0
627 | }
628 | ],
629 | "properties": {
630 | "Node name for S&R": "KSampler"
631 | },
632 | "widgets_values": [
633 | 736246290988511,
634 | "fixed",
635 | 50,
636 | 8,
637 | "dpmpp_2m_sde_gpu",
638 | "karras",
639 | 1
640 | ],
641 | "color": "#222",
642 | "bgcolor": "#000"
643 | },
644 | {
645 | "id": 1095,
646 | "type": "KSampler",
647 | "pos": [
648 | 840,
649 | 450
650 | ],
651 | "size": {
652 | "0": 400,
653 | "1": 260
654 | },
655 | "flags": {},
656 | "order": 20,
657 | "mode": 0,
658 | "inputs": [
659 | {
660 | "name": "model",
661 | "type": "MODEL",
662 | "link": 2115,
663 | "label": "Model"
664 | },
665 | {
666 | "name": "positive",
667 | "type": "CONDITIONING",
668 | "link": 2118,
669 | "label": "+"
670 | },
671 | {
672 | "name": "negative",
673 | "type": "CONDITIONING",
674 | "link": 2119,
675 | "label": "-"
676 | },
677 | {
678 | "name": "latent_image",
679 | "type": "LATENT",
680 | "link": 2123,
681 | "label": "Latent"
682 | }
683 | ],
684 | "outputs": [
685 | {
686 | "name": "LATENT",
687 | "type": "LATENT",
688 | "links": [
689 | 2125
690 | ],
691 | "shape": 3,
692 | "label": "Latent",
693 | "slot_index": 0
694 | }
695 | ],
696 | "properties": {
697 | "Node name for S&R": "KSampler"
698 | },
699 | "widgets_values": [
700 | 736246290988511,
701 | "fixed",
702 | 30,
703 | 8,
704 | "dpmpp_2m_sde_gpu",
705 | "karras",
706 | 0.65
707 | ],
708 | "color": "#222",
709 | "bgcolor": "#000"
710 | },
711 | {
712 | "id": 1094,
713 | "type": "ControlNetApplyAdvanced",
714 | "pos": [
715 | 840,
716 | 240
717 | ],
718 | "size": [
719 | 400,
720 | 170
721 | ],
722 | "flags": {},
723 | "order": 18,
724 | "mode": 0,
725 | "inputs": [
726 | {
727 | "name": "positive",
728 | "type": "CONDITIONING",
729 | "link": 2116,
730 | "label": "+"
731 | },
732 | {
733 | "name": "negative",
734 | "type": "CONDITIONING",
735 | "link": 2117,
736 | "label": "-"
737 | },
738 | {
739 | "name": "control_net",
740 | "type": "CONTROL_NET",
741 | "link": 2120,
742 | "label": "ControlNet"
743 | },
744 | {
745 | "name": "image",
746 | "type": "IMAGE",
747 | "link": 2128,
748 | "label": "LineartImage"
749 | }
750 | ],
751 | "outputs": [
752 | {
753 | "name": "positive",
754 | "type": "CONDITIONING",
755 | "links": [
756 | 2118
757 | ],
758 | "shape": 3,
759 | "label": "+",
760 | "slot_index": 0
761 | },
762 | {
763 | "name": "negative",
764 | "type": "CONDITIONING",
765 | "links": [
766 | 2119
767 | ],
768 | "shape": 3,
769 | "label": "-",
770 | "slot_index": 1
771 | }
772 | ],
773 | "properties": {
774 | "Node name for S&R": "ControlNetApplyAdvanced"
775 | },
776 | "widgets_values": [
777 | 0.85,
778 | 0,
779 | 0.75
780 | ],
781 | "color": "#222",
782 | "bgcolor": "#000"
783 | },
784 | {
785 | "id": 1068,
786 | "type": "CheckpointLoaderSimple",
787 | "pos": [
788 | 0,
789 | 440
790 | ],
791 | "size": {
792 | "0": 400,
793 | "1": 100
794 | },
795 | "flags": {},
796 | "order": 8,
797 | "mode": 0,
798 | "inputs": [
799 | {
800 | "name": "ckpt_name",
801 | "type": "COMBO",
802 | "link": 2095,
803 | "widget": {
804 | "name": "ckpt_name"
805 | },
806 | "slot_index": 0,
807 | "label": "Ckpt Name"
808 | }
809 | ],
810 | "outputs": [
811 | {
812 | "name": "MODEL",
813 | "type": "MODEL",
814 | "links": [
815 | 2107,
816 | 2115
817 | ],
818 | "shape": 3,
819 | "label": "Model",
820 | "slot_index": 0
821 | },
822 | {
823 | "name": "CLIP",
824 | "type": "CLIP",
825 | "links": [
826 | 2096,
827 | 2097
828 | ],
829 | "shape": 3,
830 | "label": "Clip",
831 | "slot_index": 1
832 | },
833 | {
834 | "name": "VAE",
835 | "type": "VAE",
836 | "links": null,
837 | "shape": 3,
838 | "label": "Vae"
839 | }
840 | ],
841 | "properties": {
842 | "Node name for S&R": "CheckpointLoaderSimple"
843 | },
844 | "widgets_values": [
845 | "juggernautXL_v9Rundiffusionphoto2.safetensors"
846 | ],
847 | "color": "#222",
848 | "bgcolor": "#000"
849 | },
850 | {
851 | "id": 1069,
852 | "type": "PrimitiveNode",
853 | "pos": [
854 | 0,
855 | 440
856 | ],
857 | "size": [
858 | 400,
859 | 110
860 | ],
861 | "flags": {
862 | "collapsed": false
863 | },
864 | "order": 7,
865 | "mode": 0,
866 | "outputs": [
867 | {
868 | "name": "COMBO",
869 | "type": "COMBO",
870 | "links": [
871 | 2095
872 | ],
873 | "widget": {
874 | "name": "ckpt_name"
875 | },
876 | "label": "Ckpt Name"
877 | }
878 | ],
879 | "title": "Checkpoint Name ",
880 | "properties": {
881 | "Run widget replace on values": false
882 | },
883 | "widgets_values": [
884 | "juggernautXL_v9Rundiffusionphoto2.safetensors",
885 | "fixed",
886 | "v"
887 | ],
888 | "color": "#222",
889 | "bgcolor": "#000"
890 | },
891 | {
892 | "id": 1093,
893 | "type": "PreviewImage",
894 | "pos": [
895 | 840,
896 | 840
897 | ],
898 | "size": [
899 | 400,
900 | 460
901 | ],
902 | "flags": {},
903 | "order": 19,
904 | "mode": 0,
905 | "inputs": [
906 | {
907 | "name": "images",
908 | "type": "IMAGE",
909 | "link": 2129,
910 | "label": "Image",
911 | "slot_index": 0
912 | }
913 | ],
914 | "properties": {
915 | "Node name for S&R": "PreviewImage"
916 | },
917 | "color": "#222",
918 | "bgcolor": "#000"
919 | },
920 | {
921 | "id": 1098,
922 | "type": "SaveImage",
923 | "pos": [
924 | 1260,
925 | 30
926 | ],
927 | "size": [
928 | 1290,
929 | 1270
930 | ],
931 | "flags": {},
932 | "order": 22,
933 | "mode": 0,
934 | "inputs": [
935 | {
936 | "name": "images",
937 | "type": "IMAGE",
938 | "link": 2127,
939 | "slot_index": 0,
940 | "label": "Iamge"
941 | }
942 | ],
943 | "properties": {},
944 | "widgets_values": [
945 | "%date:MM-dd hh mm ss% - Model-%CheckpointLoaderSimple.ckpt_name%"
946 | ],
947 | "color": "#222",
948 | "bgcolor": "#000"
949 | },
950 | {
951 | "id": 1092,
952 | "type": "Canny",
953 | "pos": [
954 | 839,
955 | 120
956 | ],
957 | "size": [
958 | 400,
959 | 80
960 | ],
961 | "flags": {},
962 | "order": 17,
963 | "mode": 0,
964 | "inputs": [
965 | {
966 | "name": "image",
967 | "type": "IMAGE",
968 | "link": 2130,
969 | "label": "Image"
970 | }
971 | ],
972 | "outputs": [
973 | {
974 | "name": "IMAGE",
975 | "type": "IMAGE",
976 | "links": [
977 | 2128,
978 | 2129
979 | ],
980 | "shape": 3,
981 | "slot_index": 0,
982 | "label": "LineartImage"
983 | }
984 | ],
985 | "properties": {
986 | "Node name for S&R": "Canny"
987 | },
988 | "widgets_values": [
989 | 0.15,
990 | 0.4
991 | ],
992 | "color": "#222",
993 | "bgcolor": "#000"
994 | },
995 | {
996 | "id": 1089,
997 | "type": "ImageScaleBy",
998 | "pos": [
999 | 420,
1000 | 710
1001 | ],
1002 | "size": [
1003 | 400,
1004 | 90
1005 | ],
1006 | "flags": {},
1007 | "order": 14,
1008 | "mode": 0,
1009 | "inputs": [
1010 | {
1011 | "name": "image",
1012 | "type": "IMAGE",
1013 | "link": 2110,
1014 | "label": "Image"
1015 | }
1016 | ],
1017 | "outputs": [
1018 | {
1019 | "name": "IMAGE",
1020 | "type": "IMAGE",
1021 | "links": [
1022 | 2111,
1023 | 2121,
1024 | 2130
1025 | ],
1026 | "shape": 3,
1027 | "label": "Image",
1028 | "slot_index": 0
1029 | }
1030 | ],
1031 | "properties": {
1032 | "Node name for S&R": "ImageScaleBy"
1033 | },
1034 | "widgets_values": [
1035 | "nearest-exact",
1036 | 0.5
1037 | ],
1038 | "color": "#222",
1039 | "bgcolor": "#000"
1040 | }
1041 | ],
1042 | "links": [
1043 | [
1044 | 2093,
1045 | 1065,
1046 | 0,
1047 | 1064,
1048 | 1,
1049 | "STRING"
1050 | ],
1051 | [
1052 | 2095,
1053 | 1069,
1054 | 0,
1055 | 1068,
1056 | 0,
1057 | "COMBO"
1058 | ],
1059 | [
1060 | 2096,
1061 | 1068,
1062 | 1,
1063 | 1067,
1064 | 0,
1065 | "CLIP"
1066 | ],
1067 | [
1068 | 2097,
1069 | 1068,
1070 | 1,
1071 | 1064,
1072 | 0,
1073 | "CLIP"
1074 | ],
1075 | [
1076 | 2098,
1077 | 1066,
1078 | 0,
1079 | 1067,
1080 | 1,
1081 | "STRING"
1082 | ],
1083 | [
1084 | 2101,
1085 | 1064,
1086 | 0,
1087 | 1085,
1088 | 1,
1089 | "CONDITIONING"
1090 | ],
1091 | [
1092 | 2102,
1093 | 1067,
1094 | 0,
1095 | 1085,
1096 | 2,
1097 | "CONDITIONING"
1098 | ],
1099 | [
1100 | 2104,
1101 | 1078,
1102 | 0,
1103 | 1085,
1104 | 3,
1105 | "LATENT"
1106 | ],
1107 | [
1108 | 2105,
1109 | 1085,
1110 | 0,
1111 | 1086,
1112 | 0,
1113 | "LATENT"
1114 | ],
1115 | [
1116 | 2106,
1117 | 1070,
1118 | 0,
1119 | 1086,
1120 | 1,
1121 | "VAE"
1122 | ],
1123 | [
1124 | 2107,
1125 | 1068,
1126 | 0,
1127 | 1085,
1128 | 0,
1129 | "MODEL"
1130 | ],
1131 | [
1132 | 2108,
1133 | 1086,
1134 | 0,
1135 | 1087,
1136 | 1,
1137 | "IMAGE"
1138 | ],
1139 | [
1140 | 2109,
1141 | 1081,
1142 | 0,
1143 | 1087,
1144 | 0,
1145 | "UPSCALE_MODEL"
1146 | ],
1147 | [
1148 | 2110,
1149 | 1087,
1150 | 0,
1151 | 1089,
1152 | 0,
1153 | "IMAGE"
1154 | ],
1155 | [
1156 | 2111,
1157 | 1089,
1158 | 0,
1159 | 1090,
1160 | 0,
1161 | "IMAGE"
1162 | ],
1163 | [
1164 | 2115,
1165 | 1068,
1166 | 0,
1167 | 1095,
1168 | 0,
1169 | "MODEL"
1170 | ],
1171 | [
1172 | 2116,
1173 | 1064,
1174 | 0,
1175 | 1094,
1176 | 0,
1177 | "CONDITIONING"
1178 | ],
1179 | [
1180 | 2117,
1181 | 1067,
1182 | 0,
1183 | 1094,
1184 | 1,
1185 | "CONDITIONING"
1186 | ],
1187 | [
1188 | 2118,
1189 | 1094,
1190 | 0,
1191 | 1095,
1192 | 1,
1193 | "CONDITIONING"
1194 | ],
1195 | [
1196 | 2119,
1197 | 1094,
1198 | 1,
1199 | 1095,
1200 | 2,
1201 | "CONDITIONING"
1202 | ],
1203 | [
1204 | 2120,
1205 | 1073,
1206 | 0,
1207 | 1094,
1208 | 2,
1209 | "CONTROL_NET"
1210 | ],
1211 | [
1212 | 2121,
1213 | 1089,
1214 | 0,
1215 | 1096,
1216 | 0,
1217 | "IMAGE"
1218 | ],
1219 | [
1220 | 2122,
1221 | 1070,
1222 | 0,
1223 | 1096,
1224 | 1,
1225 | "VAE"
1226 | ],
1227 | [
1228 | 2123,
1229 | 1096,
1230 | 0,
1231 | 1095,
1232 | 3,
1233 | "LATENT"
1234 | ],
1235 | [
1236 | 2125,
1237 | 1095,
1238 | 0,
1239 | 1097,
1240 | 0,
1241 | "LATENT"
1242 | ],
1243 | [
1244 | 2126,
1245 | 1070,
1246 | 0,
1247 | 1097,
1248 | 1,
1249 | "VAE"
1250 | ],
1251 | [
1252 | 2127,
1253 | 1097,
1254 | 0,
1255 | 1098,
1256 | 0,
1257 | "IMAGE"
1258 | ],
1259 | [
1260 | 2128,
1261 | 1092,
1262 | 0,
1263 | 1094,
1264 | 3,
1265 | "IMAGE"
1266 | ],
1267 | [
1268 | 2129,
1269 | 1092,
1270 | 0,
1271 | 1093,
1272 | 0,
1273 | "IMAGE"
1274 | ],
1275 | [
1276 | 2130,
1277 | 1089,
1278 | 0,
1279 | 1092,
1280 | 0,
1281 | "IMAGE"
1282 | ]
1283 | ],
1284 | "groups": [],
1285 | "config": {},
1286 | "extra": {},
1287 | "version": 0.4
1288 | },
1289 | "snapshot_json": {
1290 | "comfyui": null,
1291 | "git_custom_nodes": {}
1292 | },
1293 | "files": [
1294 | [
1295 | {
1296 | "download_url": "https://comfyworkflows.com/api/comfyui-launcher/files/h/51672212/download",
1297 | "dest_relative_path": "models/vae/sdxl_vae.safetensors",
1298 | "sha256_checksum": "235745af8d86bf4a4c1b5b4f529868b37019a10f7c0b2e79ad0abca3a22bc6e1",
1299 | "size": 334641162
1300 | },
1301 | {
1302 | "download_url": "https://comfyworkflows.com/api/comfyui-launcher/files/c/4238398/download",
1303 | "dest_relative_path": "models/vae/sdxl_vae.safetensors",
1304 | "sha256_checksum": "63aeecb90ff7bc1c115395962d3e803571385b61938377bc7089b36e81e92e2e",
1305 | "size": 334641152
1306 | }
1307 | ],
1308 | [
1309 | {
1310 | "download_url": "https://comfyworkflows.com/api/comfyui-launcher/files/h/1106255/download",
1311 | "dest_relative_path": "models/upscale_models/4x-UltraSharp.pth",
1312 | "sha256_checksum": "a5812231fc936b42af08a5edba784195495d303d5b3248c24489ef0c4021fe01",
1313 | "size": 66961958
1314 | }
1315 | ],
1316 | [
1317 | {
1318 | "download_url": "https://comfyworkflows.com/api/comfyui-launcher/files/h/1133434/download",
1319 | "dest_relative_path": "models/controlnet/control-lora-depth-rank256.safetensors",
1320 | "sha256_checksum": "559d2468951bf254c13bacd9c5d05d01ad67b060f6a73e8131d26ebf459c1c79",
1321 | "size": 774445779
1322 | }
1323 | ],
1324 | [
1325 | {
1326 | "download_url": "https://comfyworkflows.com/api/comfyui-launcher/files/h/49467957/download",
1327 | "dest_relative_path": "models/checkpoints/juggernautXL_v9Rundiffusionphoto2.safetensors",
1328 | "sha256_checksum": "c9e3e68f89b8e38689e1097d4be4573cf308de4e3fd044c64ca697bdb4aa8bca",
1329 | "size": 7105348188
1330 | },
1331 | {
1332 | "download_url": "https://comfyworkflows.com/api/comfyui-launcher/files/c/3913898/download",
1333 | "dest_relative_path": "models/checkpoints/juggernautXL_v9Rundiffusionphoto2.safetensors",
1334 | "sha256_checksum": "c9e3e68f89b8e38689e1097d4be4573cf308de4e3fd044c64ca697bdb4aa8bca",
1335 | "size": 7105351680
1336 | }
1337 | ]
1338 | ],
1339 | "pip_requirements": [],
1340 | "os": {},
1341 | "python_version": {}
1342 | }
1343 |
--------------------------------------------------------------------------------
/utils.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 | import shutil
4 | import socket
5 | import requests
6 | import hashlib
7 | import unicodedata
8 | import re
9 | import subprocess
10 | import threading
11 | from tqdm import tqdm
12 | from urllib.parse import urlparse
13 | from settings import PROJECT_MAX_PORT, PROJECT_MIN_PORT, PROJECTS_DIR, CONFIG_FILEPATH
14 |
15 | def check_url_structure(url):
16 | # Check for huggingface.co URL structure
17 | huggingface_pattern = r'^https://huggingface\.co/[\w-]+/[\w-]+/blob/[\w-]+\.(safetensors|bin|ckpt)$'
18 | if re.match(huggingface_pattern, url):
19 | return True
20 |
21 | # Check for civitai.com URL structure
22 | civitai_pattern = r'^https://civitai\.com/models/\d+$'
23 | if re.match(civitai_pattern, url):
24 | return True
25 |
26 | return False
27 |
28 | def slugify(value, allow_unicode=False):
29 | """
30 | Taken from https://github.com/django/django/blob/master/django/utils/text.py
31 | Convert to ASCII if 'allow_unicode' is False. Convert spaces or repeated
32 | dashes to single dashes. Remove characters that aren't alphanumerics,
33 | underscores, or hyphens. Convert to lowercase. Also strip leading and
34 | trailing whitespace, dashes, and underscores.
35 | """
36 | value = str(value)
37 | if allow_unicode:
38 | value = unicodedata.normalize('NFKC', value)
39 | else:
40 | value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii')
41 | value = re.sub(r'[^\w\s-]', '', value.lower())
42 | return re.sub(r'[-\s]+', '-', value).strip('-_')
43 |
44 |
45 | COMFYUI_REPO_URL = "https://github.com/comfyanonymous/ComfyUI.git"
46 |
47 | MAX_DOWNLOAD_ATTEMPTS = 3
48 |
49 | CUSTOM_NODES_TO_IGNORE_FROM_SNAPSHOTS = ["ComfyUI-ComfyWorkflows", "ComfyUI-Manager"]
50 |
51 | CW_ENDPOINT = os.environ.get("CW_ENDPOINT", "https://comfyworkflows.com")
52 |
53 | # Use the already defined CONFIG_FILEPATH from settings.py
54 | # CONFIG_FILEPATH is now imported from settings.py
55 |
56 | # Define the default configuration with all settings
57 | DEFAULT_CONFIG = {
58 | "credentials": {
59 | "civitai": {
60 | "apikey": ""
61 | }
62 | },
63 | "directories": {
64 | "projects": "./projects",
65 | "models": "./models",
66 | "templates": "./templates"
67 | },
68 | "port_configuration": {
69 | "allow_overridable_ports": True,
70 | "project_min_port": 4001,
71 | "project_max_port": 4100,
72 | "server_port": 8501
73 | }
74 | }
75 |
76 | import os
77 | from typing import List, Dict, Optional, Union
78 | import json
79 |
80 | class ModelFileWithNodeInfo:
81 | def __init__(self, filename: str, original_filepath: str, normalized_filepath: str):
82 | self.filename = filename
83 | self.original_filepath = original_filepath
84 | self.normalized_filepath = normalized_filepath
85 |
86 | def convert_to_unix_path(path: str) -> str:
87 | return path.replace("\\\\", "/").replace("\\", "/")
88 |
89 | def convert_to_windows_path(path: str) -> str:
90 | return path.replace("/", "\\")
91 |
92 | def extract_model_file_names_with_node_info(json_data: Union[Dict, List], is_windows: bool = False) -> List[ModelFileWithNodeInfo]:
93 | file_names = []
94 | model_filename_extensions = {'.safetensors', '.ckpt', '.pt', '.pth', '.bin'}
95 |
96 | def recursive_search(data: Union[Dict, List, str], in_nodes: bool, node_type: Optional[str]):
97 | if isinstance(data, dict):
98 | for key, value in data.items():
99 | type_ = value.get('type') if isinstance(value, dict) else None
100 | recursive_search(value, key == 'nodes' if not in_nodes else in_nodes, type_ if in_nodes and not node_type else node_type)
101 | elif isinstance(data, list):
102 | for item in data:
103 | type_ = item.get('type') if isinstance(item, dict) else None
104 | recursive_search(item, in_nodes, type_ if in_nodes and not node_type else node_type)
105 | elif isinstance(data, str) and '.' in data:
106 | original_filepath = data
107 | normalized_filepath = convert_to_windows_path(original_filepath) if is_windows else convert_to_unix_path(original_filepath)
108 | filename = os.path.basename(data)
109 |
110 | if '.' + original_filepath.split('.')[-1] in model_filename_extensions:
111 | file_names.append(ModelFileWithNodeInfo(filename, original_filepath, normalized_filepath))
112 |
113 | recursive_search(json_data, False, None)
114 | return file_names
115 |
116 |
117 | def print_process_output(process):
118 | for line in iter(process.stdout.readline, b''):
119 | print(line.decode(), end='')
120 | process.stdout.close()
121 |
122 | def run_command(cmd: List[str], cwd: Optional[str] = None, bg: bool = False) -> None:
123 | process = subprocess.Popen(" ".join(cmd), cwd=cwd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
124 |
125 | if bg:
126 | # Create a separate thread to handle the printing of the process's output
127 | threading.Thread(target=print_process_output, args=(process,), daemon=True).start()
128 | return process.pid
129 | else:
130 | print_process_output(process)
131 | assert process.wait() == 0
132 |
133 | def get_ckpt_names_with_node_info(workflow_json: Union[Dict, List], is_windows: bool) -> List[ModelFileWithNodeInfo]:
134 | ckpt_names = []
135 | if isinstance(workflow_json, dict):
136 | ckpt_names = extract_model_file_names_with_node_info(workflow_json, is_windows)
137 | elif isinstance(workflow_json, list):
138 | for item in workflow_json:
139 | ckpt_names.extend(get_ckpt_names_with_node_info(item, is_windows))
140 | return ckpt_names
141 |
142 | def normalize_model_filepaths_in_workflow_json(workflow_json: dict) -> dict:
143 | is_windows = os.name == "nt"
144 | ckpt_names = get_ckpt_names_with_node_info(workflow_json, is_windows)
145 | for ckpt_name in ckpt_names:
146 | workflow_json = json.dumps(workflow_json).replace(ckpt_name.original_filepath.replace("\\", "\\\\"), ckpt_name.normalized_filepath.replace("\\", "\\\\"))
147 | workflow_json = json.loads(workflow_json)
148 | return workflow_json
149 |
150 |
151 | def run_command_in_project_venv(project_folder_path, command):
152 | if os.name == "nt": # Check if running on Windows
153 | venv_activate = os.path.join(project_folder_path, "venv", "Scripts", "activate.bat")
154 | else:
155 | venv_activate = os.path.join(project_folder_path, "venv", "bin", "activate")
156 |
157 | assert os.path.exists(venv_activate), f"Virtualenv does not exist in project folder: {project_folder_path}"
158 |
159 | if os.name == "nt":
160 | command = ["call", venv_activate, "&&", command]
161 | else:
162 | command = [".", venv_activate, "&&", command]
163 |
164 | # Run the command using subprocess and capture stdout
165 | run_command(command)
166 |
167 | def run_command_in_project_comfyui_venv(project_folder_path, command, in_bg=False):
168 | venv_activate = os.path.join(project_folder_path, "venv", "Scripts", "activate.bat") if os.name == "nt" else os.path.join(project_folder_path, "venv", "bin", "activate")
169 | comfyui_dir = os.path.join(project_folder_path, "comfyui")
170 |
171 | assert os.path.exists(venv_activate), f"Virtualenv does not exist in project folder: {project_folder_path}"
172 |
173 | if os.name == "nt":
174 | return run_command([venv_activate, "&&", "cd", comfyui_dir, "&&", command], bg=in_bg)
175 | else:
176 | return run_command([".", venv_activate, "&&", "cd", comfyui_dir, "&&", command], bg=in_bg)
177 |
178 |
179 | def install_default_custom_nodes(project_folder_path, launcher_json=None):
180 | # install default custom nodes
181 | # comfyui-manager
182 | run_command(["git", "clone", f"https://github.com/ltdrdata/ComfyUI-Manager", os.path.join(project_folder_path, 'comfyui', 'custom_nodes', 'ComfyUI-Manager')])
183 |
184 | # pip install comfyui-manager
185 | run_command_in_project_venv(
186 | project_folder_path,
187 | f"pip install -r {os.path.join(project_folder_path, 'comfyui', 'custom_nodes', 'ComfyUI-Manager', 'requirements.txt')}",
188 | )
189 |
190 | run_command(["git", "clone", f"https://github.com/thecooltechguy/ComfyUI-ComfyWorkflows", os.path.join(project_folder_path, 'comfyui', 'custom_nodes', 'ComfyUI-ComfyWorkflows')])
191 |
192 | # pip install comfyui-comfyworkflows
193 | run_command_in_project_venv(
194 | project_folder_path,
195 | f"pip install -r {os.path.join(project_folder_path, 'comfyui', 'custom_nodes', 'ComfyUI-ComfyWorkflows', 'requirements.txt')}",
196 | )
197 |
198 | def setup_initial_models_folder(models_folder_path):
199 | assert not os.path.exists(
200 | models_folder_path
201 | ), f"Models folder already exists: {models_folder_path}"
202 |
203 | tmp_dir = os.path.join(os.path.dirname(models_folder_path), "tmp_comfyui")
204 | run_command(["git", "clone", COMFYUI_REPO_URL, tmp_dir])
205 |
206 | shutil.move(os.path.join(tmp_dir, "models"), models_folder_path)
207 | shutil.rmtree(tmp_dir)
208 |
209 |
210 | def is_launcher_json_format(import_json):
211 | if "format" in import_json and import_json["format"] == "comfyui_launcher":
212 | return True
213 | return False
214 |
215 | def setup_custom_nodes_from_snapshot(project_folder_path, launcher_json):
216 | if not launcher_json:
217 | return
218 | for custom_node_repo_url, custom_node_repo_info in launcher_json["snapshot_json"][
219 | "git_custom_nodes"
220 | ].items():
221 | if any(
222 | [
223 | custom_node_to_ignore in custom_node_repo_url
224 | for custom_node_to_ignore in CUSTOM_NODES_TO_IGNORE_FROM_SNAPSHOTS
225 | ]
226 | ):
227 | continue
228 |
229 | custom_node_hash = custom_node_repo_info["hash"]
230 | custom_node_disabled = custom_node_repo_info["disabled"]
231 | if custom_node_disabled:
232 | continue
233 | custom_node_name = custom_node_repo_url.split("/")[-1].replace(".git", "")
234 | custom_node_path = os.path.join(
235 | project_folder_path, "comfyui", "custom_nodes", custom_node_name
236 | )
237 |
238 | # Clone the custom node repository
239 | run_command(["git", "clone", custom_node_repo_url, custom_node_path, "--recursive"])
240 |
241 | if custom_node_hash:
242 | # Checkout the specific hash
243 | run_command(["git", "checkout", custom_node_hash], cwd=custom_node_path)
244 |
245 | pip_requirements_path = os.path.join(custom_node_path, "requirements.txt")
246 | if os.path.exists(pip_requirements_path):
247 | run_command_in_project_venv(
248 | project_folder_path,
249 | f"pip install -r {os.path.join(custom_node_path, 'requirements.txt')}",
250 | )
251 |
252 | pip_requirements_post_path = os.path.join(custom_node_path, "requirements_post.txt")
253 | if os.path.exists(pip_requirements_post_path):
254 | run_command_in_project_venv(
255 | project_folder_path,
256 | f"pip install -r {os.path.join(custom_node_path, 'requirements_post.txt')}",
257 | )
258 |
259 | install_script_path = os.path.join(custom_node_path, "install.py")
260 | if os.path.exists(install_script_path):
261 | run_command_in_project_venv(project_folder_path, f"python {install_script_path}")
262 |
263 | # for ComfyUI-CLIPSeg, we need to separately copy the clipseg.py file from ComfyUI-CLIPSeg/custom_nodes into `project_folder_path/comfyui/custom_nodes
264 | if custom_node_name == "ComfyUI-CLIPSeg":
265 | clipseg_custom_node_file_path = os.path.join(custom_node_path, "custom_nodes", "clipseg.py")
266 | shutil.copy(clipseg_custom_node_file_path, os.path.join(project_folder_path, "comfyui", "custom_nodes", "clipseg.py"))
267 |
268 | def compute_sha256_checksum(file_path):
269 | buf_size = 1024
270 | sha256 = hashlib.sha256()
271 | with open(file_path, "rb") as f:
272 | while True:
273 | data = f.read(buf_size)
274 | if not data:
275 | break
276 | sha256.update(data)
277 | return sha256.hexdigest().lower()
278 |
279 | def get_config():
280 | """
281 | Get the configuration from config.json, creating it with default values if it doesn't exist.
282 |
283 | Returns:
284 | dict: The configuration dictionary
285 | """
286 | try:
287 | # Ensure the directory exists
288 | os.makedirs(os.path.dirname(CONFIG_FILEPATH), exist_ok=True)
289 |
290 | if os.path.exists(CONFIG_FILEPATH):
291 | with open(CONFIG_FILEPATH, "r") as f:
292 | config = json.load(f)
293 | return config
294 | else:
295 | # If file doesn't exist, create with defaults and return defaults
296 | with open(CONFIG_FILEPATH, "w") as f:
297 | json.dump(DEFAULT_CONFIG, f, indent=2)
298 | return DEFAULT_CONFIG.copy()
299 | except (FileNotFoundError, json.JSONDecodeError, PermissionError) as e:
300 | print(f"Warning: Could not load config file: {e}")
301 | # Create with defaults as fallback
302 | try:
303 | with open(CONFIG_FILEPATH, "w") as f:
304 | json.dump(DEFAULT_CONFIG, f, indent=2)
305 | except Exception as e:
306 | print(f"Error: Could not create config file: {e}")
307 | return DEFAULT_CONFIG.copy()
308 |
309 | def update_config(config_update):
310 | """
311 | Update the configuration, merging with existing values
312 |
313 | Args:
314 | config_update (dict): Dictionary containing configuration updates
315 |
316 | Returns:
317 | dict: The updated configuration dictionary
318 | """
319 | try:
320 | config = get_config()
321 | except Exception:
322 | config = DEFAULT_CONFIG.copy()
323 |
324 | # Deep merge the update with existing config
325 | def deep_merge(base, update):
326 | for key, value in update.items():
327 | if key in base and isinstance(base[key], dict) and isinstance(value, dict):
328 | deep_merge(base[key], value)
329 | else:
330 | base[key] = value
331 |
332 | deep_merge(config, config_update)
333 | set_config(config)
334 | return config
335 |
336 | def set_config(config):
337 | """
338 | Save the configuration to config.json
339 |
340 | Args:
341 | config (dict): The configuration dictionary to save
342 | """
343 | try:
344 | # Ensure the directory exists
345 | os.makedirs(os.path.dirname(CONFIG_FILEPATH), exist_ok=True)
346 | with open(CONFIG_FILEPATH, "w") as f:
347 | json.dump(config, f, indent=2)
348 | except Exception as e:
349 | print(f"Error: Could not save config file: {e}")
350 |
351 | def setup_files_from_launcher_json(project_folder_path, launcher_json):
352 | if not launcher_json:
353 | return
354 |
355 | missing_download_files = set()
356 | config = get_config()
357 |
358 | # download all necessary files
359 | for file_infos in launcher_json["files"]:
360 | downloaded_file = False
361 | # try each source for the file until one works
362 | for file_info in file_infos:
363 | if downloaded_file:
364 | break
365 | cw_file_download_url = file_info["download_url"]
366 | dest_relative_path = file_info["dest_relative_path"]
367 | sha256_checksum = file_info["sha256_checksum"].lower()
368 |
369 | if not cw_file_download_url:
370 | print(f"WARNING: Could not find download URL for: {dest_relative_path}")
371 | missing_download_files.add(dest_relative_path)
372 | continue
373 |
374 | dest_path = os.path.join(project_folder_path, "comfyui", dest_relative_path)
375 | if os.path.exists(dest_path):
376 | if compute_sha256_checksum(dest_path) != sha256_checksum:
377 | old_dest_filename = os.path.basename(dest_path)
378 | new_dest_path = generate_incrementing_filename(dest_path)
379 | print(f"WARNING: File '{dest_relative_path}' already exists and has a different checksum, so renaming new file to: {new_dest_path}")
380 | dest_path = new_dest_path
381 | new_dest_filename = os.path.basename(new_dest_path)
382 | # we auto-rename the file in the launcher json to match the new filename, so that the user doesn't have to manually update the launcher/workflow json
383 | # TODO: Later, we need to update this to only replace the filename within its specific node type (since multiple nodes can refer to a common filename, but they would be different files)
384 | rename_file_in_launcher_json(launcher_json, old_dest_filename, new_dest_filename)
385 | else:
386 | print(f"File already exists: {dest_path}, so skipping download.")
387 | downloaded_file = True
388 | break
389 |
390 | os.makedirs(os.path.dirname(dest_path), exist_ok=True)
391 |
392 | num_attempts = 0
393 | download_successful = False
394 |
395 | print(f"Downloading file for: {dest_path}")
396 |
397 | if "/comfyui-launcher/" in cw_file_download_url:
398 | response = requests.get(cw_file_download_url)
399 | response.raise_for_status()
400 | response_json = response.json()
401 | download_urls = response_json["urls"]
402 | else:
403 | download_urls = [cw_file_download_url,]
404 |
405 | for download_url in download_urls:
406 | if download_successful:
407 | break
408 | num_attempts = 0
409 | while num_attempts < MAX_DOWNLOAD_ATTEMPTS:
410 | try:
411 | headers = {}
412 |
413 | # parse the url to get the host using
414 | hostname = urlparse(download_url).hostname
415 | if hostname == "civitai.com":
416 | headers["Authorization"] = f"Bearer {config['credentials']['civitai']['apikey']}"
417 |
418 | with requests.get(
419 | download_url, headers=headers, allow_redirects=True, stream=True
420 | ) as response:
421 | total_size = int(response.headers.get("content-length", 0))
422 | with tqdm(total=total_size, unit="B", unit_scale=True) as pb:
423 | with open(dest_path, "wb") as f:
424 | for chunk in response.iter_content(chunk_size=10 * 1024):
425 | pb.update(len(chunk))
426 | if chunk:
427 | f.write(chunk)
428 | if compute_sha256_checksum(dest_path) == sha256_checksum:
429 | download_successful = True
430 | if dest_relative_path in missing_download_files:
431 | missing_download_files.remove(dest_relative_path)
432 | break
433 | if os.path.exists(dest_path):
434 | os.remove(dest_path)
435 | except Exception as e:
436 | import traceback
437 | traceback.print_exc()
438 | if os.path.exists(dest_path):
439 | os.remove(dest_path)
440 | num_attempts += 1
441 |
442 | if not download_successful:
443 | print(f"WARNING: Failed to download file for: {dest_relative_path}")
444 | missing_download_files.add(dest_relative_path)
445 | continue
446 |
447 | downloaded_file = True
448 | break
449 |
450 | if not downloaded_file:
451 | print(f"WARNING: Failed to download file: {dest_relative_path}")
452 | missing_download_files.add(dest_relative_path)
453 | else:
454 | print(f"SUCCESS: Downloaded: {dest_relative_path}")
455 | return missing_download_files
456 |
457 |
458 | def get_launcher_json_for_workflow_json(workflow_json, resolved_missing_models, skip_model_validation):
459 | response = requests.post(
460 | f"{CW_ENDPOINT}/api/comfyui-launcher/setup_workflow_json?skipModelValidation={skip_model_validation}",
461 | json={"workflow": workflow_json, "isWindows": os.name == "nt", "resolved_missing_models": resolved_missing_models},
462 | )
463 | assert (
464 | response.status_code == 200 or response.status_code == 400
465 | ), f"Failed to get launcher json for workflow json: {workflow_json}"
466 | return response.json()
467 |
468 | def generate_incrementing_filename(filepath):
469 | filename, file_extension = os.path.splitext(filepath)
470 | counter = 1
471 | while os.path.exists(filepath):
472 | filepath = f"{filename} ({counter}){file_extension}"
473 | counter += 1
474 | return filepath
475 |
476 | def rename_file_in_workflow_json(workflow_json, old_filename, new_filename):
477 | workflow_json_str = json.dumps(workflow_json)
478 | workflow_json_str = workflow_json_str.replace(old_filename, new_filename)
479 | return json.loads(workflow_json_str)
480 |
481 | def rename_file_in_launcher_json(launcher_json, old_filename, new_filename):
482 | workflow_json = launcher_json["workflow_json"]
483 | workflow_json_str = json.dumps(workflow_json)
484 | workflow_json_str = workflow_json_str.replace(old_filename, new_filename)
485 | workflow_json = json.loads(workflow_json_str)
486 | launcher_json["workflow_json"] = workflow_json
487 |
488 |
489 | def set_default_workflow_from_launcher_json(project_folder_path, launcher_json):
490 | if not launcher_json:
491 | return
492 | workflow_json = launcher_json["workflow_json"]
493 | with open(
494 | os.path.join(
495 | project_folder_path, "comfyui", "web", "scripts", "defaultGraph.js"
496 | ),
497 | "w",
498 | ) as f:
499 | f.write(f"export const defaultGraph = {json.dumps(workflow_json, indent=2)};")
500 |
501 | with open(
502 | os.path.join(
503 | project_folder_path, "comfyui", "custom_nodes", "ComfyUI-ComfyWorkflows", "current_graph.json"
504 | ),
505 | "w",
506 | ) as f:
507 | json.dump(workflow_json, f)
508 |
509 |
510 | def get_launcher_state(project_folder_path):
511 | state = {}
512 | launcher_folder_path = os.path.join(project_folder_path, ".launcher")
513 | os.makedirs(launcher_folder_path, exist_ok=True)
514 |
515 | state_path = os.path.join(launcher_folder_path, "state.json")
516 |
517 | if os.path.exists(state_path):
518 | with open(state_path, "r") as f:
519 | state = json.load(f)
520 |
521 | return state, state_path
522 |
523 |
524 | def set_launcher_state_data(project_folder_path, data: dict):
525 | launcher_folder_path = os.path.join(project_folder_path, ".launcher")
526 | os.makedirs(launcher_folder_path, exist_ok=True)
527 |
528 | existing_state, existing_state_path = get_launcher_state(project_folder_path)
529 | existing_state.update(data)
530 |
531 | with open(existing_state_path, "w") as f:
532 | json.dump(existing_state, f)
533 |
534 | def install_pip_reqs(project_folder_path, pip_reqs):
535 | if not pip_reqs:
536 | return
537 | print("Installing pip requirements...")
538 | with open(os.path.join(project_folder_path, "requirements.txt"), "w") as f:
539 | for req in pip_reqs:
540 | if isinstance(req, str):
541 | f.write(req + "\n")
542 | elif isinstance(req, dict):
543 | f.write(f"{req['_key']}=={req['_version']}\n")
544 | run_command_in_project_venv(
545 | project_folder_path,
546 | f"pip install -r {os.path.join(project_folder_path, 'requirements.txt')}",
547 | )
548 |
549 | def get_project_port(id):
550 | project_path = os.path.join(PROJECTS_DIR, id)
551 | if os.path.exists(os.path.join(project_path, "port.txt")):
552 | with open(os.path.join(project_path, "port.txt"), "r") as f:
553 | return int(f.read().strip())
554 | return find_free_port(PROJECT_MIN_PORT, PROJECT_MAX_PORT)
555 |
556 | def is_port_in_use(port: int) -> bool:
557 | import socket
558 | with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
559 | return s.connect_ex(('localhost', port)) == 0
560 |
561 | def find_free_port(start_port, end_port):
562 | for port in range(start_port, end_port + 1):
563 | with socket.socket() as s:
564 | try:
565 | s.bind(('', port))
566 | return port
567 | except OSError:
568 | pass # Port is already in use, try the next one
569 | return None # No free port found in the range
570 |
571 | def create_symlink(source, target):
572 | if os.name == 'nt': # Check if running on Windows
573 | run_command(['mklink', '/D', target, source])
574 | else:
575 | os.symlink(source, target, target_is_directory=True)
576 |
577 | def create_virtualenv(venv_path):
578 | run_command(['python', '-m', 'venv', venv_path])
--------------------------------------------------------------------------------