A small SwarmUI extension that lets you keep writing prompts the way the Automatic1111 and Forge Dynamic Prompts extension taught you.
Type {red|blue|green} and __colors__ as before. The extension rewrites them into SwarmUI's own <random:...> and <wildcard:...> tags a moment before SwarmUI parses the prompt, so SwarmUI does all the actual picking, seeding and file lookup.
It does not port the Dynamic Prompts extension. It only covers the everyday syntax listed below. A companion script converts prompt and wildcard files offline with the same rules, see Offline conversion.
From your SwarmUI folder:
git clone https://github.com/aoleg/DynamicPromptTranslator src/Extensions/DynamicPromptTranslatorRestart SwarmUI. It compiles the extension on startup. The log shows a line starting with [DynamicPromptTranslator] Enabled when it is active.
To remove it, delete the folder and restart.
Wildcard files live where SwarmUI keeps them, in Data/Wildcards under your SwarmUI folder, one option per line. You can create and edit them in the Wildcards tab at the bottom of the Generate page. Copying your existing .txt files from Automatic1111 or Forge into that folder works too, including subfolders.
Lines inside wildcard files may themselves contain {a|b} variants and __other__ references. Lines starting with # are comments.
| You write | What it means | SwarmUI sees |
|---|---|---|
{red|blue|green} |
pick one | <random:red|blue|green> |
{red|blue|} |
pick one, and one of the options is empty | <random:red|blue|> |
{2$$red|blue|green} |
pick two different options, joined with a comma | <random[2,]:red|blue|green> |
{0-2$$red|blue|green} |
pick between zero and two options, joined with a comma | <random[0-2,]:red|blue|green> |
{-2$$red|blue|green} |
pick one or two options | <random[1-2,]:red|blue|green> |
{2-$$red|blue|green} |
pick two or more options, up to all of them | <random[2-3,]:red|blue|green> |
{2$$ $$red|blue|green} |
pick two, joined with a space instead of a comma | <random[2]:red|blue|green> |
{3::red|blue|green} |
red is three times as likely as blue or green | <random:red|red|red|blue|green> |
{0.5::red|0.25::blue} |
decimal weights work too | <random:red|red|blue> |
{~red|blue} |
the explicit random sampler, which is the default anyway | <random:red|blue> |
__colors__ |
one line from Data/Wildcards/colors.txt |
<wildcard:colors> |
__/somefolder/colors__ |
one line from Data/Wildcards/somefolder/colors.txt |
<wildcard:somefolder/colors> |
__~colors__ |
the explicit random sampler on a wildcard | <wildcard:colors> |
{2$$__colors__} |
two different lines from one file | <wildcard[2,]:colors> |
{red|blue|__somefolder/colors__} |
a wildcard as one of the options | <random:red|blue|<wildcard:somefolder/colors>> |
{red|{light|dark} blue} |
nested variants | <random:red|<random:light|dark> blue> |
A few notes on behavior:
- Options are trimmed, so
{ red | blue }is the same as{red|blue}. - Options may contain commas, such as
{red, shiny|blue, matte}. - Multi-pick never repeats an option unless you ask for more picks than there are options.
- SwarmUI leaves a trailing comma after a comma-joined multi-pick, so
{2$$red|blue|green} carbecomesred, blue, car. Models ignore it. Use{2$$ $$red|blue|green}for a space joiner with no trailing character. - Weights are turned into repeated entries. A weight of
0removes the option. - Everything is seeded by SwarmUI's normal seed, exactly like SwarmUI's own
<random>and<wildcard>tags. Use the Wildcard Seed parameter to vary the picks independently of the image seed. - The prompt you typed is kept in the image metadata as the original prompt, next to the expanded one.
- The syntax also works inside the negative prompt, and inside SwarmUI tags such as
<segment:...>. - Turning off Parse Alternative Prompt Syntaxes in your User Settings turns this extension off as well.
These forms are converted to the nearest thing SwarmUI can do. Each one adds a warning to the SwarmUI log and to the image metadata, under parser warnings, so you can see what changed.
| You write | What Dynamic Prompts did | What happens instead |
|---|---|---|
{@red|blue} or __@colors__ |
cycled through the options in order, one per image | Picks at random. |
__colors(shade=dark)__ |
passed arguments to a template | The arguments are dropped and colors.txt is used as is. |
{2$$ and $$red|blue} |
joined the picks with a custom word | Joined with a comma. Only a space or a comma is possible. |
{1000::red|blue} |
very lopsided or very fine-grained odds | Rounded so the option list stays under about a hundred entries. |
These are left in the prompt untouched, so the model sees the raw text. Use the SwarmUI equivalent where one exists.
| You write | What Dynamic Prompts did | What to use instead |
|---|---|---|
__colors*__ or __artists/**__ |
picked from every file matching the pattern | Name one file, or merge the files. A warning is logged. |
${season=summer} and ${season} |
set and reused a variable | SwarmUI's <setvar[season,false]:summer> and <var:season>. The offline script converts these for you. |
${season=!__seasons__} |
evaluated a wildcard once and reused the result | <setvar[season,false]:<wildcard:seasons>> then <var:season>. The offline script converts these too. |
{% if ... %} and {# ... #} |
Jinja templates | No equivalent. A warning is logged. |
__colors__ where the file is missing |
error | SwarmUI logs a warning and drops the tag. |
| Prompt magic, attention grabber, I'm Feeling Lucky | various | No equivalent. |
Two more things to know:
- A single option that looks like a number range, such as
{1-5|red}, is treated by SwarmUI as "any number from 1 to 5" rather than the literal text. - Braces that are not variants, such as
{value}or{just text}, are left alone. A group only counts as a variant when it contains|,$$or::.
Automatic1111 weighting such as (red:1.3), [a|b] alternation and [a:b:0.5] prompt editing are handled by SwarmUI itself, not by this extension, and keep working inside variants and wildcard lines.
script/dynprompts_to_swarm.py converts a prompt or a whole wildcard file to SwarmUI syntax without running SwarmUI. It uses the same rules as the extension and produces the same output, so a file converted once behaves the same as one the extension converts at generation time. It needs Python 3 and nothing else.
python script/dynprompts_to_swarm.py input.txt output.txtWith no arguments it reads standard input and writes standard output. Warnings go to standard error, one per line. Run it with --test to check it against its built-in cases.
Unlike the extension, the script also converts ${...} variables into SwarmUI's <setvar>, <var>, <setmacro> and <macro> tags. The ${name:default} form has no SwarmUI equivalent and becomes a plain reference with a warning.
See docs/technical.md for how the extension hooks into SwarmUI, the exact translation rules, how the script is kept in step with the extension, and how to run the tests.
MIT. See LICENSE.