Add RELEASING.md, and sync README to the current templates

RELEASING.md documents the repeatable update flow this repo has actually used
five times now: bump the version in the four places nothing keeps in sync
automatically, commit and tag here, watch the publish workflow, bump the
monorepo submodule pointer, then verify against the live Registry API and the
real published archive rather than trusting a green check. Two past releases
looked correct in CI and still shipped wrong — model-download metadata in the
wrong JSON key, and thumbnails in a format custom node packs don't read — and
both only surfaced by inspecting what ComfyUI actually saw. That's the reason
step 7 exists instead of stopping at "the workflow succeeded." Also notes the
Flagged-then-clears pattern seen on every version so far, and that
custom-node-list.json in ComfyUI-Manager is a second, unsynced listing.

README gains: mention that Apply/sampler plumbing nodes ship collapsed (already
true in the generated templates), that Apply's node body is where to read the
composed prompt, and the FLUX guidance/sections troubleshooting tip that was
already on the canvas note, now also in the doc someone reads before opening
ComfyUI at all.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Behzad
2026-07-30 00:26:11 +02:00
co-authored by Claude Sonnet 5
parent ebb9c06df7
commit 4862b286a6
14 changed files with 1843 additions and 2570 deletions
+34 -2
View File
@@ -121,13 +121,42 @@ templates load a Renaissance tempera style. Swap either for any slug from the
[gallery](https://styleref.io/gallery); these are starting points, not
limits.
Every template is built to read at a glance on open: the on-canvas notes say
what the template produces and where the model comes from, and the plumbing
between Apply and the sampler (the text encoder, the zeroed conditioning, VAE
Decode) ships **collapsed** — nothing in there is yours to edit. Expand any of
them if you want to rewire.
**Neither FLUX nor Z-Image takes a negative prompt.** Both are guidance
distilled and run at CFG 1.0, where the negative branch is multiplied out
entirely — so neither set carries a negative encoder, and the sampler's
negative input gets a zeroed conditioning. StyleRef still compiles
the negative and previews it on the canvas; fold anything you need from it into
negative input gets a zeroed conditioning. StyleRef still compiles the negative
and returns it on Apply's `negative` output; fold anything you need from it into
`subject` on Apply as a positive phrase. Raising CFG does not bring it back.
Apply prints the prompt it composed, and its token estimate, in its own node
body after a queue — that is where to read what StyleRef actually sent the
sampler.
### Style not coming through strongly enough?
FLUX has a confident house look and drifts back to it. Two dials, in the order
worth trying:
1. **`Flux guidance`** (3.5 in the templates, FLUX's default) is the blunt one.
4–5 makes the style bite harder; past that the subject starts losing to it,
and a dark style can go to pure black.
2. **Narrow `sections` on StyleRef Apply** to the parts that define this style.
For a period or painterly style that is usually
`artistic_mediums,references,surface_material,colors` — the sections naming
the medium, the era and the finish. Left empty, every section is sent, and the
identity-carrying ones render last, so a long style can read as generic. For a
geometric or layout-led style keep `shape_language` and `spatial_hierarchy`
instead. Queue the Facets template to see what a style actually carries.
Sampler defaults, for reference: FLUX 20 steps, Z-Image Turbo 8, both at CFG 1.0
with euler/simple, seeds randomizing on every queue.
## Signing in
Add the **StyleRef Login** node and click **Sign in (browser)** — no queueing
@@ -180,6 +209,9 @@ python scripts/build_workflows.py # regenerate workflow templates
The workflow templates are generated — edit
[`scripts/build_workflows.py`](scripts/build_workflows.py), not the JSON.
Shipping a change to users — a version bump, a Registry publish, updating the
monorepo pointer — is [`RELEASING.md`](RELEASING.md).
The nodes are a thin client over StyleRef's public
[REST API v1](https://docs.styleref.io/for-ai-agents/rest-api/overview-and-authentication)
([OpenAPI](https://styleref.io/api/v1/openapi.json)). All prompt compilation
+148
View File
@@ -0,0 +1,148 @@
# Releasing an update
For an agent or contributor picking this up cold: this is the repeatable flow
for shipping a change to users — a node fix, a new workflow template, updated
artwork, anything. It is distinct from [the one-time steps](../../internal-docs/connectors-repo-graduation.md)
that stood this repo up in the first place (those live in the private
monorepo and don't apply again).
If this repo reached you as a git submodule inside `StyleRef-Webapp`, work
**here**, in the submodule — not by editing a plain copy of these files
somewhere else. A commit made outside this repo publishes nothing.
## 1. Make the change
Edit the source. If you touched a workflow's *shape* (nodes, links, layout,
subjects, the style it loads) rather than hand-editing JSON, regenerate:
```bash
python scripts/build_workflows.py
```
The committed `workflows/*.json` files must match the generator's output —
CI fails the build otherwise, and a hand-edit to the JSON will just be
overwritten the next time someone runs the script.
## 2. Bump the version — four places, together
There is no tooling for this step; it is easy to update three and miss the
fourth, so check all four:
| File | What to change |
| --- | --- |
| `pyproject.toml` | `version = "x.y.z"` |
| `__init__.py` | `_FALLBACK_VERSION = "x.y.z"` |
| `styleref_api.py` | `USER_AGENT = "styleref-comfyui/x.y.z (...)"` |
| `README.md` | The `[StyleRef] vx.y.z — 5 nodes registered` line in **Install** |
`tests/test_api.py::test_version_strings_agree_with_pyproject` fails if the
first three disagree — trust it, but it can't see the README line, so check
that one by eye.
Use semver. The publish workflow (`.github/workflows/publish.yml`) rejects a
tag that doesn't exactly match `pyproject.toml`'s version.
## 3. Verify locally
```bash
ruff check .
pytest tests/ -q
```
If the change touches `web/styleref.js`, at minimum run `node --check
web/styleref.js` — there is no JS test harness, so a syntax check is the only
automated signal before it reaches a real ComfyUI frontend.
## 4. Commit and push, in this repo
```bash
git add -A
git commit -m "..."
git push origin main
```
## 5. Tag the commit you just pushed
```bash
git tag -a vX.Y.Z -m "..."
git push origin vX.Y.Z
```
The tag push fires **Publish to Comfy Registry**
(`.github/workflows/publish.yml`): it re-checks the tag against
`pyproject.toml`, lints, runs the test suite, then calls
`Comfy-Org/publish-node-action` with the `REGISTRY_ACCESS_TOKEN` secret.
Watch it in the Actions tab or with `gh run watch`.
**A branch-protection ruleset on `main` requires 3 status checks** that a
direct push can't have satisfied yet (see the [public-repo branch ruleset
convention](../../internal-docs/connectors-repo-graduation.md)). The push
above will report "Bypassed rule violations" — that's expected, not an
error, as long as the account pushing is on the bypass list.
## 6. Bump the pointer in the monorepo
A tag and a Registry publish are invisible to `StyleRef-Webapp` until its
submodule pointer moves. Back in the monorepo root:
```bash
git add connectors/styleref-comfyui
git commit -m "chore(comfyui): bump connector to vX.Y.Z (<why>)"
git push origin main
```
Skipping this step is the easy mistake — nothing errors, the monorepo just
quietly keeps pointing at the old commit. `git status` in the monorepo shows
a moved submodule as a one-line change; `git diff --submodule` shows which
commits moved.
## 7. Confirm the release actually landed — don't trust a green check alone
A successful publish workflow proves the *build* succeeded, not that the
*Registry* did the right thing with it, and not that ComfyUI reads what you
shipped the way you assumed. Check the real state:
```bash
# Per-version status (Pending → Active is normal and can take a while;
# Flagged sometimes clears on its own — see the note below)
curl -s https://api.comfy.org/nodes/styleref-comfyui/versions | python3 -m json.tool
# Node-level: which version is actually live for install
curl -s https://api.comfy.org/nodes/styleref-comfyui | python3 -m json.tool
```
If the change affects what's inside the shipped package (thumbnails, a new
file, `.comfyignore`), download and inspect the **actual published archive**
rather than trusting what you intended to ship:
```bash
curl -sL "https://cdn.comfy.org/styleref/styleref-comfyui/X.Y.Z/node.zip" -o node.zip
unzip -l node.zip
```
This caught two real bugs in past releases: model-download metadata that was
declared in the wrong JSON location (present in the repo, silently ignored
by ComfyUI), and template thumbnails shipped as `.webp` when custom node
packs are only read as `.jpg` — both looked correct in CI and in the archive
listing, and only showing up wrong in a running ComfyUI proved it.
## On `NodeVersionStatusFlagged`
Comfy's scanner has flagged every version of this pack at some point,
including versions identical to ones that were flagged and later cleared on
their own — this looks like a transient state in their pipeline, not a
verdict on the code. Don't rush to change anything or re-publish in response
to a flag by itself. Give it time and re-check; if it's still flagged after
a day or two with no `NodeVersionStatusActive` version anywhere, that's when
it's worth asking in the Comfy Discord (icon in the registry.comfy.org
header) rather than guessing at a code change.
## If the ComfyUI-Manager listing needs updating too
`custom-node-list.json` in
[`Comfy-Org/ComfyUI-Manager`](https://github.com/Comfy-Org/ComfyUI-Manager)
is a **second, separate** listing from the Comfy Registry — Manager's
"default channel," predating the Registry and not auto-synced from it. A
Registry publish does not update it. If this pack's entry there
(`id: "styleref-comfyui"`) ever needs a description or metadata change, that
is its own PR against that repo, not something this release flow touches.
+155 -163
View File
@@ -7,15 +7,16 @@ link ids, and slot indices across all of them — the kind of bookkeeping that i
silently wrong until someone drags the file onto a canvas. This builds them from
a description instead, so the ids are correct by construction.
Layout policy: node positions are never guessed. Every node's height
is estimated from its widget count, and nodes stack per column with a fixed
vertical gap — so no template can ship with overlapping nodes at default sizes.
A test asserts that invariant on the committed files.
Layout policy: node positions are never guessed. Every node's height is the
*measured* minimum for its type (see `MIN_H`), and nodes stack per column with a
fixed vertical gap — so no template can ship with overlapping nodes. A test
asserts that invariant on the committed files.
Instruction policy: user-facing instructions live in visible core
`Note` nodes on the canvas. `extra.styleref.notes` carries only a one-line
provenance string — ComfyUI never renders it, so it must not carry anything a
user needs to read.
`Note` nodes on the canvas, and they stay **short** — a note is a signpost, not
a manual. Anything longer belongs in the README or docs.styleref.io.
`extra.styleref.notes` carries only a one-line provenance string — ComfyUI never
renders it, so it must not carry anything a user needs to read.
Run after changing a node's inputs or outputs:
@@ -94,23 +95,66 @@ INPUTS = {
# ── layout constants ─────────────────────────────────────────────────────────
NODE_WIDTH = 320
HEADER_H = 60 # title bar
SLOT_H = 24 # one input/output slot row
WIDGET_ROW_H = 28 # one single-line widget
MULTILINE_H = 90 # one multiline text widget
V_GAP = 48 # vertical gap between stacked nodes
V_GAP = 56 # vertical gap between stacked nodes
COL_W = 380 # column pitch; > NODE_WIDTH so columns never touch
COLLAPSED_H = 40 # a collapsed node renders as a title bar only
# Widgets that render multiline per node type (by widget index).
MULTILINE_WIDGETS = {
"StyleRefApply": {0, 2}, # subject, extra_negative
"CLIPTextEncode": {0},
"Note": {0},
# Minimum on-canvas height per node type, **measured** in the ComfyUI frontend
# (1.45.x) by declaring each node deliberately too small and reading back the
# size the frontend clamped it to.
#
# This table replaced an estimate built from widget counts, which is worth
# knowing about because of how it failed. The frontend clamps a node *up* to its
# own minimum on load, so under-estimating a height does not produce a small
# node — it produces a node that grows on open and swallows whatever the layout
# parked below it. StyleRefLoad (estimated 248, actually 348) is why the loader
# and the Load node overlapped in every template.
#
# Re-measure after adding or removing a widget on a StyleRef node.
MIN_H = {
"CheckpointLoaderSimple": 128,
"UNETLoader": 108,
"CLIPLoader": 140,
"VAELoader": 80,
"CLIPTextEncode": 116,
"ConditioningZeroOut": 48,
"FluxGuidance": 80,
"EmptySD3LatentImage": 144,
"EmptyLatentImage": 144,
"KSampler": 312,
"VAEDecode": 72,
"SaveImage": 84,
"PreviewImage": 48,
"PreviewAny": 152,
"LoadImage": 128,
"Note": 92,
"StyleRefLoad": 348,
"StyleRefApply": 380,
"StyleRefFacets": 624,
"StyleRefReferenceImages": 128,
"StyleRefLogin": 156,
}
# Node types shipped collapsed. Each is plumbing the user never edits: the text
# encoder is driven by a link (its own text widget is not even used), the
# zero-out has no widgets at all, and VAE Decode is a two-wire junction. Left
# expanded they are three tall boxes of nothing between Apply and the sampler.
#
# The layout reserves only COLLAPSED_H for these, so expanding one on the canvas
# can overlap the node beneath it — the right trade for a canvas that reads
# clearly on open, which is the state every user starts in.
COLLAPSED = {"CLIPTextEncode", "ConditioningZeroOut", "VAEDecode"}
# Node titles longer than this truncate in both frontends.
MAX_TITLE = 28
# Hard cap on a Note node's text. Notes had grown into essays — model setup, a
# no-negative explanation, a guidance-tuning tip — which made the brown box the
# largest thing on the canvas and buried the one or two lines a first-time user
# actually needs. A note now says what the template produces and how to get the
# model; everything else lives in the README and docs.styleref.io.
MAX_NOTE = 340
# The gallery style each set loads. Deliberately different per model, because
# "which style demos well" is a property of the pair, not of the style.
#
@@ -221,17 +265,28 @@ MODEL_ZIMAGE_VAE = {
MODELS_ZIMAGE = [MODEL_ZIMAGE_UNET, MODEL_ZIMAGE_CLIP, MODEL_ZIMAGE_VAE]
def node_height(node_type: str, widgets: list[Any]) -> int:
def node_height(node_type: str) -> int:
"""
Estimated on-canvas height: header + one row per input/output
slot + one row per widget. The slot term matters for wide-output nodes —
Facets alone has dozens of outputs.
The height a node actually occupies: its measured minimum. Anything smaller
is overwritten by the frontend on load; anything larger is empty space.
"""
slots = max(len(INPUTS.get(node_type, [])), len(OUTPUTS.get(node_type, [])))
multiline = MULTILINE_WIDGETS.get(node_type, set())
rows = sum(1 for i in range(len(widgets)) if i not in multiline)
tall = sum(1 for i in range(len(widgets)) if i in multiline)
return HEADER_H + slots * SLOT_H + rows * WIDGET_ROW_H + tall * MULTILINE_H
if node_type not in MIN_H:
raise KeyError(f"no measured height for {node_type} — add it to MIN_H")
return MIN_H[node_type]
def effective_size(node: dict[str, Any]) -> tuple[int, int]:
"""
The box a node occupies on canvas as opened, which is what "do these two
nodes overlap" has to be asked about. A collapsed node draws as a title bar
regardless of the `size` it carries for when it is expanded.
Shared with the layout test so both answer the question the same way.
"""
if node.get("flags", {}).get("collapsed"):
return NODE_WIDTH, COLLAPSED_H
width, height = node["size"]
return width, height
class Graph:
@@ -263,10 +318,13 @@ class Graph:
raise ValueError(f"title longer than {MAX_TITLE} chars truncates: {title!r}")
widgets = widgets or []
h = height if height is not None else node_height(node_type, widgets)
h = height if height is not None else node_height(node_type)
collapsed = node_type in COLLAPSED
x = 40 + col * COL_W
y = self._cursor.get(col, 60)
self._cursor[col] = y + h + V_GAP
# Collapsed nodes only ever draw a title bar, so that is all the column
# spends on them.
self._cursor[col] = y + (COLLAPSED_H if collapsed else h) + V_GAP
self._node_id += 1
node: dict[str, Any] = {
@@ -274,7 +332,7 @@ class Graph:
"type": node_type,
"pos": [x, y],
"size": [NODE_WIDTH, h],
"flags": {},
"flags": {"collapsed": True} if collapsed else {},
"order": len(self.nodes),
"mode": 0,
"inputs": [
@@ -301,10 +359,23 @@ class Graph:
self.nodes.append(node)
return self._node_id
# A note wraps at roughly this many characters at NODE_WIDTH.
NOTE_WRAP = 46
def note(self, col: int, text: str, title: str = "Read me") -> int:
"""A visible core Note node — the instruction channel."""
# Height scales with the text so long notes don't clip at default size.
h = HEADER_H + 30 + 18 * (text.count("\n") + len(text) // 55)
"""
A visible core Note node — the instruction channel, and deliberately a
small one. `MAX_NOTE` caps the text; the height is sized to the wrapped
line count so the note is exactly as tall as it needs to be.
"""
if len(text) > MAX_NOTE:
raise ValueError(
f"note is {len(text)} chars, over the {MAX_NOTE}-char cap — say what "
f"this template does and how to get a model, and put the rest in "
f"the README:\n{text}"
)
lines = sum(max(1, -(-len(line) // self.NOTE_WRAP)) for line in text.split("\n"))
h = max(MIN_H["Note"], 46 + 20 * lines)
return self.place("Note", col, [text], title=title, height=h)
def link(self, src: int, src_slot: int, dst: int, dst_slot: int) -> None:
@@ -445,16 +516,12 @@ def _facet_board(graph: Graph, load: int, col: int) -> int:
return facets
def _preview(graph: Graph, apply_node: int, col: int, suffix: str = "") -> None:
"""
Compiled prompts made visible, in every template: Preview Any on Apply's
positive and negative kills the "empty text box on the encoder looks
broken" perception and teaches what StyleRef actually produces.
"""
pos = graph.place("PreviewAny", col, [], title=f"Compiled positive{suffix}")
neg = graph.place("PreviewAny", col, [], title=f"Compiled negative{suffix}")
graph.link(apply_node, 0, pos, 0)
graph.link(apply_node, 1, neg, 0)
# No template attaches Preview Any nodes to Apply's compiled prompts. They were
# there to prove StyleRef produced something, but Apply prints the composed
# prompt and its token estimate in its own node body (`ui.text`) after a queue —
# so the previews duplicated that, and in the consistency grid they duplicated it
# six times, two tall boxes per subject. Preview Any survives only in the Facets
# templates, where the strings have nowhere else to be read.
def zimage_sampler_widgets() -> list[Any]:
@@ -530,69 +597,29 @@ def _zimage_tail(
graph.link(decode, 0, save, 0)
# One line each on where the model comes from — the only setup fact a note has
# to carry, because it is the only one that stops a first queue from working.
# Sampler defaults, the no-negative story and the style-strength dials are in the
# README (github.com/StyleRef/styleref-comfyui) and docs.styleref.io.
_ZIMAGE_SETUP_NOTE = (
"Z-Image Turbo (S3-DiT). Three model files download on first use: the UNET "
"(diffusion_models/), the Qwen text encoder (text_encoders/), and the VAE "
"(vae/).\n"
"Sampler defaults are turbo: 8 steps, CFG 1.0, euler/simple.\n"
"Z-Image takes no negative prompt. The model runs without classifier-free "
"guidance, so there is no negative encoder on this canvas — the sampler's "
"negative input gets a zeroed conditioning. StyleRef still compiles the "
"negative and previews it; put anything you need from it into `subject` on "
"Apply as a positive phrase (\"fully clothed\", \"no text or watermark\"). "
"Raising CFG does not bring the negative back.\n"
"Style prompts use the `diffusion` target — Z-Image reads the same "
"tag-weighted output SDXL/SD1.5 use."
"First queue downloads 3 files: UNET, Qwen text encoder, VAE."
)
_FLUX_STYLE_TIP = (
"Style not coming through strongly enough?\n"
"FLUX has a confident house look and will drift back to it. Two dials, in "
"the order worth trying:\n"
"1. `Flux guidance` (3.5 here, FLUX's default) is the blunt dial. 4–5 makes "
"the style bite harder; past that the subject starts losing to it, and a "
"dark style can go to pure black.\n"
"2. Narrow `sections` on StyleRef Apply to the parts that define this "
"style. For a period or painterly style that is usually "
"`artistic_mediums,references,surface_material,colors` — the sections "
"naming the medium, the era and the finish. Leaving it empty sends every "
"section, and the identity-carrying ones render last, so a long style can "
"read as generic.\n"
"Which sections matter depends on the style: for a geometric or layout-led "
"style keep `shape_language` and `spatial_hierarchy` instead. Queue the "
"Facets template to see what a style actually carries."
)
_FLUX_SETUP_NOTE = (
"FLUX.1 dev (fp8 all-in-one). The checkpoint downloads on first use "
"into checkpoints/ — one ~16 GB file containing the UNET, the T5 text "
"encoder and the VAE.\n"
"Sampler defaults: 20 steps, CFG 1.0, euler/simple. Prompt strength is "
"the FluxGuidance node (3.5), not CFG.\n"
"FLUX takes no negative prompt. It is guidance distilled and runs at "
"CFG 1.0, so there is no negative encoder on this canvas — the sampler's "
"negative input gets a zeroed conditioning. StyleRef still compiles the "
"negative and previews it; put anything you need from it into `subject` "
"on Apply as a positive phrase (\"fully clothed\", \"no text or "
"watermark\"). Raising CFG does not bring the negative back.\n"
"Style prompts use the `flux` target — FLUX reads prose with T5, so the "
"whole style fits instead of being truncated at ~77 tokens the way an "
"SDXL CLIP encoder would.\n\n"
+ _FLUX_STYLE_TIP
"First queue downloads FLUX.1 dev fp8 (~16 GB) to checkpoints/."
)
_MORE = "Sampler tips + stronger styles: see the README."
def workflow_zimage_01_quickstart() -> dict[str, Any]:
"""Z-Image quickstart: Load a gallery style → Apply → generate."""
g = Graph()
g.note(
0,
"Z-Image quickstart — no account needed.\n"
"1. Queue — the three Z-Image files download on first run.\n"
"2. Change `subject` on StyleRef Apply and queue again (seeds randomize).\n"
"Swap `style_ref` on StyleRef Load for any gallery slug.\n\n" + _ZIMAGE_SETUP_NOTE,
"One gallery style, one image, on Z-Image Turbo. No account needed.\n"
"Queue it. Then edit `subject` on Apply — or swap `style_ref` on Load "
"for any gallery slug — and queue again.\n" + _ZIMAGE_SETUP_NOTE,
title="Z-Image quickstart",
)
load = g.place(
@@ -603,7 +630,6 @@ def workflow_zimage_01_quickstart() -> dict[str, Any]:
"StyleRefApply", 1, apply_widgets(DEMO_SUBJECT, "diffusion")
)
g.link(load, 0, apply_node, 0)
_preview(g, apply_node, 1)
_zimage_tail(g, apply_node, unet, clip, vae, col=2)
return g.to_json(models=MODELS_ZIMAGE)
@@ -614,10 +640,9 @@ def workflow_zimage_02_consistency() -> dict[str, Any]:
g = Graph()
g.note(
0,
"Z-Image consistency grid — no account needed.\n"
"One style feeds three Apply nodes with three subjects; each renders "
"through its own Z-Image sampler. Queue once and compare: one style, "
"many subjects, a coherent set within this model.\n\n" + _ZIMAGE_SETUP_NOTE,
"One style, three subjects, three Z-Image samplers. No account needed.\n"
"Queue once and compare the set. Edit any subject, or swap the style on "
"Load, and queue again.\n" + _ZIMAGE_SETUP_NOTE,
title="Z-Image consistency",
)
load = g.place("StyleRefLoad", 0, load_widgets(ZIMAGE_STYLE_REF))
@@ -629,7 +654,6 @@ def workflow_zimage_02_consistency() -> dict[str, Any]:
"StyleRefApply", 1, apply_widgets(subject, "diffusion"), title=f"Subject {index + 1}"
)
g.link(load, 0, apply_node, 0)
_preview(g, apply_node, 1, suffix=f" {index + 1}")
_zimage_tail(g, apply_node, unet, clip, vae, col=2)
return g.to_json(models=MODELS_ZIMAGE)
@@ -640,13 +664,11 @@ def workflow_zimage_03_your_own_style() -> dict[str, Any]:
g = Graph()
g.note(
0,
"Use your own style on Z-Image.\n"
"Extract a style from any image at https://styleref.io, then load it "
"here by its share slug or id.\n"
"1. Queue the StyleRef Login node alone first (use its Sign in button).\n"
"2. Put your style's id in `style_ref` on StyleRef Load, or pick it\n"
" with the Search styles… button.\n"
"3. Queue.\n\n" + _ZIMAGE_SETUP_NOTE,
"Your own style on Z-Image. Extract one from any image at styleref.io.\n"
"1. Sign in with the Login node's button.\n"
"2. Put your style's id in `style_ref` on Load, or pick it with "
"Search styles….\n"
"3. Queue.\n" + _ZIMAGE_SETUP_NOTE,
title="Z-Image — your style",
)
login = g.place("StyleRefLogin", 0, [], title="Login — check status")
@@ -659,7 +681,6 @@ def workflow_zimage_03_your_own_style() -> dict[str, Any]:
"StyleRefApply", 1, apply_widgets(DEMO_SUBJECT, "diffusion")
)
g.link(load, 0, apply_node, 0)
_preview(g, apply_node, 1)
_zimage_tail(g, apply_node, unet, clip, vae, col=2)
return g.to_json(models=MODELS_ZIMAGE)
@@ -670,13 +691,10 @@ def workflow_zimage_04_reference_images() -> dict[str, Any]:
g = Graph()
g.note(
0,
"Z-Image — style prompt and reference images together.\n"
"StyleRef Apply drives the Z-Image sampler with the style's prompt; "
"StyleRef Reference Images pulls the style's inspiration images out as "
"a batch, previewed alongside. The prompt says how the style reads; the "
"images show how it looks — wire the images into IPAdapter or a "
"reference-only ControlNet to combine both.\n"
"Use a gallery style that has inspiration images.\n\n" + _ZIMAGE_SETUP_NOTE,
"The style's prompt and its own inspiration images, together.\n"
"Apply drives the sampler; Reference Images pulls the images out as a "
"batch — preview them, or wire them into IPAdapter or ControlNet.\n"
"Needs a gallery style that has inspiration images.\n" + _ZIMAGE_SETUP_NOTE,
title="Z-Image + references",
)
load = g.place(
@@ -693,7 +711,6 @@ def workflow_zimage_04_reference_images() -> dict[str, Any]:
"StyleRefApply", 1, apply_widgets(DEMO_SUBJECT, "diffusion")
)
g.link(load, 0, apply_node, 0)
_preview(g, apply_node, 1)
_zimage_tail(g, apply_node, unet, clip, vae, col=2)
return g.to_json(models=MODELS_ZIMAGE)
@@ -704,13 +721,12 @@ def workflow_01_quickstart() -> dict[str, Any]:
g = Graph()
g.note(
0,
"Quickstart — no account needed.\n"
"1. Queue — the FLUX checkpoint downloads on first run.\n"
"2. Seeds randomize, so every queue is a fresh image.\n"
"3. Change `subject` on StyleRef Apply and queue again.\n"
"Swap `style_ref` on StyleRef Load for any slug from "
"https://styleref.io/gallery — or use the Search styles… button.\n\n"
+ _FLUX_SETUP_NOTE,
"One gallery style, one image, on FLUX.1 dev. No account needed.\n"
"Queue it. Then edit `subject` on Apply — or swap `style_ref` on Load "
"for any gallery slug — and queue again.\n"
+ _FLUX_SETUP_NOTE
+ "\n"
+ _MORE,
title="Quickstart",
)
load = g.place(
@@ -723,7 +739,6 @@ def workflow_01_quickstart() -> dict[str, Any]:
apply_node = g.place(
"StyleRefApply", 1, apply_widgets(DEMO_SUBJECT, "flux")
)
_preview(g, apply_node, 1)
g.link(load, 0, apply_node, 0)
_flux_tail(g, apply_node, checkpoint, col=2)
@@ -741,11 +756,9 @@ def workflow_02_consistency() -> dict[str, Any]:
g = Graph()
g.note(
0,
"Consistency grid — no account needed.\n"
"One style feeds three Apply nodes with three different subjects; each "
"renders through its own sampler. Queue once and compare: one style, "
"many subjects, a coherent set within this model.\n"
"Change any subject, or swap the style on StyleRef Load, and queue again.",
"One style, three subjects, three FLUX samplers. No account needed.\n"
"Queue once and compare the set. Edit any subject, or swap the style on "
"Load, and queue again.\n" + _FLUX_SETUP_NOTE,
title="Consistency grid",
)
load = g.place("StyleRefLoad", 0, load_widgets(FLUX_STYLE_REF))
@@ -757,7 +770,6 @@ def workflow_02_consistency() -> dict[str, Any]:
"StyleRefApply", 1, apply_widgets(subject, "flux"), title=f"Subject {index + 1}"
)
g.link(load, 0, apply_node, 0)
_preview(g, apply_node, 1, suffix=f" {index + 1}")
_flux_tail(g, apply_node, checkpoint, col=2)
return g.to_json(models=[MODEL_FLUX])
@@ -768,15 +780,11 @@ def workflow_03_your_own_style() -> dict[str, Any]:
g = Graph()
g.note(
0,
"Use your own style.\n"
"Extract a style from any image at https://styleref.io — it appears in "
"your library — then load it here by its share slug or id.\n"
"1. Queue the StyleRef Login node alone first (Queue runs every node, "
"so an empty workflow is the clean way). If status says signed out, "
"set action to `sign in` and queue again.\n"
"2. Put your style's id in `style_ref` on StyleRef Load, or pick it\n"
" with the Search styles… button.\n"
"3. Queue.\n\n" + _FLUX_SETUP_NOTE,
"Your own style on FLUX. Extract one from any image at styleref.io.\n"
"1. Sign in with the Login node's button.\n"
"2. Put your style's id in `style_ref` on Load, or pick it with "
"Search styles….\n"
"3. Queue.\n" + _FLUX_SETUP_NOTE,
title="Your own style",
)
login = g.place("StyleRefLogin", 0, [], title="Login — check status")
@@ -792,25 +800,16 @@ def workflow_03_your_own_style() -> dict[str, Any]:
"StyleRefApply", 1, apply_widgets(DEMO_SUBJECT, "flux")
)
g.link(load, 0, apply_node, 0)
_preview(g, apply_node, 1)
_flux_tail(g, apply_node, checkpoint, col=2)
return g.to_json(models=[MODEL_FLUX])
_FACETS_NOTE = (
"Inside the style — the Facets node.\n"
"Apply gives you one prompt string. Facets gives you the style's sections "
"one output at a time — 24 of them, exactly the sections you see on the "
"style board at styleref.io, plus the six custom items.\n"
"Six are previewed here so you can read them. Every other output is on the "
"node too; drag any of them into a text input.\n"
"They are plain STRINGs, so they go anywhere text goes: a second CLIP "
"encoder for regional conditioning, an IPAdapter or ControlNet prompt, a "
"LoRA trigger line, or your own nodes. That is the escape hatch — use the "
"palette without taking the whole prompt.\n"
"The render alongside is the paved road (Apply), so you can compare the "
"assembled prompt against the parts it was built from."
"Inside a style: Facets emits each of its 24 sections as its own STRING.\n"
"Six are previewed here; drag any output into any text input — a second "
"encoder, an IPAdapter prompt, a LoRA trigger.\n"
"Apply and the sampler alongside render the whole assembled prompt."
)
@@ -819,14 +818,10 @@ def workflow_04_reference_images() -> dict[str, Any]:
g = Graph()
g.note(
0,
"Style prompt and reference images together.\n"
"StyleRef Apply drives the sampler with the style's prompt; StyleRef "
"Reference Images pulls the style's inspiration images out as a batch, "
"previewed alongside. The prompt says how the style reads; the images "
"show how it looks — wire the images into IPAdapter or a "
"reference-only ControlNet to combine both.\n"
"Use a gallery style that has inspiration images.\n"
"\n" + _FLUX_SETUP_NOTE,
"The style's prompt and its own inspiration images, together.\n"
"Apply drives the sampler; Reference Images pulls the images out as a "
"batch — preview them, or wire them into IPAdapter or ControlNet.\n"
"Needs a gallery style that has inspiration images.\n" + _FLUX_SETUP_NOTE,
title="FLUX + references",
)
load = g.place(
@@ -843,7 +838,6 @@ def workflow_04_reference_images() -> dict[str, Any]:
"StyleRefApply", 1, apply_widgets(DEMO_SUBJECT, "flux")
)
g.link(load, 0, apply_node, 0)
_preview(g, apply_node, 1)
_flux_tail(g, apply_node, checkpoint, col=2)
return g.to_json(models=[MODEL_FLUX])
@@ -867,7 +861,6 @@ def workflow_05_facets() -> dict[str, Any]:
"StyleRefApply", 3, apply_widgets(DEMO_SUBJECT, "flux")
)
g.link(load, 0, apply_node, 0)
_preview(g, apply_node, 3)
_flux_tail(g, apply_node, checkpoint, col=4)
return g.to_json(models=[MODEL_FLUX])
@@ -876,7 +869,7 @@ def workflow_05_facets() -> dict[str, Any]:
def workflow_zimage_05_facets() -> dict[str, Any]:
"""The Facets story on the Z-Image loader stack."""
g = Graph()
g.note(0, _FACETS_NOTE + "\n\n" + _ZIMAGE_SETUP_NOTE, title="Facets on Z-Image")
g.note(0, _FACETS_NOTE + "\n" + _ZIMAGE_SETUP_NOTE, title="Facets on Z-Image")
load = g.place(
"StyleRefLoad",
0,
@@ -891,7 +884,6 @@ def workflow_zimage_05_facets() -> dict[str, Any]:
"StyleRefApply", 3, apply_widgets(DEMO_SUBJECT, "diffusion")
)
g.link(load, 0, apply_node, 0)
_preview(g, apply_node, 3)
_zimage_tail(g, apply_node, unet, clip, vae, col=4)
return g.to_json(models=MODELS_ZIMAGE)
+76 -9
View File
@@ -16,7 +16,17 @@ import os
import pytest
from scripts.build_workflows import FACET_SHOWCASE, INPUTS, MAX_TITLE, OUTPUTS, WORKFLOWS
from scripts.build_workflows import (
COLLAPSED,
FACET_SHOWCASE,
INPUTS,
MAX_NOTE,
MAX_TITLE,
MIN_H,
OUTPUTS,
WORKFLOWS,
effective_size,
)
from styleref_nodes.facets import StyleRefFacets
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -142,10 +152,16 @@ def test_link_ids_are_unique_and_registered_on_both_ends(path):
@pytest.mark.parametrize("path", FILES, ids=[_relpath(p) for p in FILES])
def test_no_nodes_overlap_at_default_sizes(path):
"""Overlapping nodes read as a broken template — layout is math,
not guesses, so this must hold for every template."""
"""
Overlapping nodes read as a broken template — layout is math, not guesses, so
this must hold for every template.
Boxes come from `effective_size`, the generator's own answer, so a collapsed
node is measured as the title bar it actually draws rather than the size it
carries for when someone expands it.
"""
nodes = _load(path)["nodes"]
boxes = [(n["id"], *n["pos"], *n["size"]) for n in nodes]
boxes = [(n["id"], *n["pos"], *effective_size(n)) for n in nodes]
for i, (id_a, ax, ay, aw, ah) in enumerate(boxes):
for id_b, bx, by, bw, bh in boxes[i + 1 :]:
separated = ax + aw <= bx or bx + bw <= ax or ay + ah <= by or by + bh <= ay
@@ -323,11 +339,62 @@ def test_consistency_template_shows_one_style_many_subjects():
assert len(subjects) == 3, "the subjects must actually differ"
def test_prompt_previews_exist_where_promised():
"""Templates 01 and 05 make the compiled prompts visible."""
for name in ("01-quickstart.json", "05-facets.json"):
graph = _load(os.path.join(WORKFLOW_DIR, name))
assert any(n["type"] == "PreviewAny" for n in graph["nodes"]), name
@pytest.mark.parametrize("path", FILES, ids=[_relpath(p) for p in FILES])
def test_no_template_previews_the_compiled_prompts(path):
"""
Apply prints the composed prompt and its token estimate in its own node body,
so a Preview Any on `positive`/`negative` is a second copy of something
already on screen — and in the consistency grid it was six of them. The only
Preview Any nodes left are the Facets sections, whose strings have nowhere
else to be read.
"""
graph = _load(path)
apply_ids = {n["id"] for n in graph["nodes"] if n["type"] == "StyleRefApply"}
nodes = {n["id"]: n for n in graph["nodes"]}
for _lid, src, _ss, dst, _ds, _k in graph["links"]:
assert not (src in apply_ids and nodes[dst]["type"] == "PreviewAny"), (
"Apply's compiled prompt is already visible in the node body"
)
@pytest.mark.parametrize("path", FILES, ids=[_relpath(p) for p in FILES])
def test_notes_stay_short(path):
"""
A note is a signpost, not a manual: what this template produces, and how to
get the model. Longer guidance belongs in the README, where it does not
dominate the canvas.
"""
for node in _load(path)["nodes"]:
if node["type"] == "Note":
text = str(node["widgets_values"][0])
assert len(text) <= MAX_NOTE, f"note is {len(text)} chars: {text[:80]}…"
@pytest.mark.parametrize("path", FILES, ids=[_relpath(p) for p in FILES])
def test_plumbing_nodes_ship_collapsed(path):
"""
The text encoder, the zero-out and VAE Decode carry nothing a user edits.
Shipped expanded they are tall empty boxes between Apply and the sampler.
"""
for node in _load(path)["nodes"]:
if node["type"] in COLLAPSED:
assert node["flags"].get("collapsed") is True, node["type"]
@pytest.mark.parametrize("path", FILES, ids=[_relpath(p) for p in FILES])
def test_declared_heights_are_never_below_the_measured_minimum(path):
"""
The frontend clamps a node up to its own minimum on load. A template that
declares less does not get a smaller node — it gets a node that grows on open
and covers whatever sits below it, which is exactly how the loaders came to
overlap the Load node.
"""
for node in _load(path)["nodes"]:
minimum = MIN_H.get(node["type"])
assert minimum, f"{node['type']} has no measured height in MIN_H"
assert node["size"][1] >= minimum, (
f"{node['type']} declares {node['size'][1]}px, under its {minimum}px minimum"
)
def test_consistency_template_makes_no_cross_tool_claim():
+99 -168
View File
@@ -1,6 +1,6 @@
{
"last_node_id": 13,
"last_link_id": 14,
"last_node_id": 11,
"last_link_id": 12,
"nodes": [
{
"id": 1,
@@ -11,7 +11,7 @@
],
"size": [
320,
1008
226
],
"flags": {},
"order": 0,
@@ -22,7 +22,7 @@
"Node name for S&R": "Note"
},
"widgets_values": [
"Quickstart \u2014 no account needed.\n1. Queue \u2014 the FLUX checkpoint downloads on first run.\n2. Seeds randomize, so every queue is a fresh image.\n3. Change `subject` on StyleRef Apply and queue again.\nSwap `style_ref` on StyleRef Load for any slug from https://styleref.io/gallery \u2014 or use the Search styles\u2026 button.\n\nFLUX.1 dev (fp8 all-in-one). The checkpoint downloads on first use into checkpoints/ \u2014 one ~16 GB file containing the UNET, the T5 text encoder and the VAE.\nSampler defaults: 20 steps, CFG 1.0, euler/simple. Prompt strength is the FluxGuidance node (3.5), not CFG.\nFLUX takes no negative prompt. It is guidance distilled and runs at CFG 1.0, so there is no negative encoder on this canvas \u2014 the sampler's negative input gets a zeroed conditioning. StyleRef still compiles the negative and previews it; put anything you need from it into `subject` on Apply as a positive phrase (\"fully clothed\", \"no text or watermark\"). Raising CFG does not bring the negative back.\nStyle prompts use the `flux` target \u2014 FLUX reads prose with T5, so the whole style fits instead of being truncated at ~77 tokens the way an SDXL CLIP encoder would.\n\nStyle not coming through strongly enough?\nFLUX has a confident house look and will drift back to it. Two dials, in the order worth trying:\n1. `Flux guidance` (3.5 here, FLUX's default) is the blunt dial. 4\u20135 makes the style bite harder; past that the subject starts losing to it, and a dark style can go to pure black.\n2. Narrow `sections` on StyleRef Apply to the parts that define this style. For a period or painterly style that is usually `artistic_mediums,references,surface_material,colors` \u2014 the sections naming the medium, the era and the finish. Leaving it empty sends every section, and the identity-carrying ones render last, so a long style can read as generic.\nWhich sections matter depends on the style: for a geometric or layout-led style keep `shape_language` and `spatial_hierarchy` instead. Queue the Facets template to see what a style actually carries."
"One gallery style, one image, on FLUX.1 dev. No account needed.\nQueue it. Then edit `subject` on Apply \u2014 or swap `style_ref` on Load for any gallery slug \u2014 and queue again.\nFirst queue downloads FLUX.1 dev fp8 (~16 GB) to checkpoints/.\nSampler tips + stronger styles: see the README."
],
"title": "Quickstart"
},
@@ -31,11 +31,11 @@
"type": "StyleRefLoad",
"pos": [
40,
1116
342
],
"size": [
320,
248
348
],
"flags": {},
"order": 1,
@@ -46,7 +46,7 @@
"name": "style",
"type": "STYLEREF_STYLE",
"links": [
3
1
],
"slot_index": 0
},
@@ -74,11 +74,11 @@
"type": "CheckpointLoaderSimple",
"pos": [
40,
1412
746
],
"size": [
320,
160
128
],
"flags": {},
"order": 2,
@@ -89,7 +89,7 @@
"name": "MODEL",
"type": "MODEL",
"links": [
8
6
],
"slot_index": 0
},
@@ -97,7 +97,7 @@
"name": "CLIP",
"type": "CLIP",
"links": [
5
3
],
"slot_index": 1
},
@@ -105,7 +105,7 @@
"name": "VAE",
"type": "VAE",
"links": [
13
11
],
"slot_index": 2
}
@@ -133,7 +133,7 @@
],
"size": [
320,
424
380
],
"flags": {},
"order": 3,
@@ -142,7 +142,7 @@
{
"name": "style",
"type": "STYLEREF_STYLE",
"link": 3
"link": 1
}
],
"outputs": [
@@ -150,17 +150,14 @@
"name": "positive",
"type": "STRING",
"links": [
1,
4
2
],
"slot_index": 0
},
{
"name": "negative",
"type": "STRING",
"links": [
2
],
"links": [],
"slot_index": 1
},
{
@@ -184,62 +181,6 @@
},
{
"id": 5,
"type": "PreviewAny",
"pos": [
420,
532
],
"size": [
320,
84
],
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 1
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled positive"
},
{
"id": 6,
"type": "PreviewAny",
"pos": [
420,
664
],
"size": [
320,
84
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 2
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled negative"
},
{
"id": 7,
"type": "CLIPTextEncode",
"pos": [
800,
@@ -247,21 +188,23 @@
],
"size": [
320,
198
116
],
"flags": {},
"order": 6,
"flags": {
"collapsed": true
},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "clip",
"type": "CLIP",
"link": 5
"link": 3
},
{
"name": "text",
"type": "STRING",
"link": 4
"link": 2
}
],
"outputs": [
@@ -269,8 +212,8 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
6,
7
4,
5
],
"slot_index": 0
}
@@ -284,24 +227,24 @@
"title": "Positive (from StyleRef)"
},
{
"id": 8,
"id": 6,
"type": "FluxGuidance",
"pos": [
800,
306
156
],
"size": [
320,
112
80
],
"flags": {},
"order": 7,
"order": 5,
"mode": 0,
"inputs": [
{
"name": "conditioning",
"type": "CONDITIONING",
"link": 6
"link": 4
}
],
"outputs": [
@@ -309,7 +252,7 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
9
7
],
"slot_index": 0
}
@@ -323,24 +266,26 @@
"title": "Flux guidance"
},
{
"id": 9,
"id": 7,
"type": "ConditioningZeroOut",
"pos": [
800,
466
292
],
"size": [
320,
84
48
],
"flags": {},
"order": 8,
"flags": {
"collapsed": true
},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "conditioning",
"type": "CONDITIONING",
"link": 7
"link": 5
}
],
"outputs": [
@@ -348,7 +293,7 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
10
8
],
"slot_index": 0
}
@@ -360,18 +305,18 @@
"title": "FLUX has no negative"
},
{
"id": 10,
"id": 8,
"type": "EmptySD3LatentImage",
"pos": [
800,
598
388
],
"size": [
320,
168
144
],
"flags": {},
"order": 9,
"order": 7,
"mode": 0,
"inputs": [],
"outputs": [
@@ -379,7 +324,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
11
9
],
"slot_index": 0
}
@@ -394,7 +339,7 @@
]
},
{
"id": 11,
"id": 9,
"type": "KSampler",
"pos": [
1180,
@@ -402,31 +347,31 @@
],
"size": [
320,
352
312
],
"flags": {},
"order": 10,
"order": 8,
"mode": 0,
"inputs": [
{
"name": "model",
"type": "MODEL",
"link": 8
"link": 6
},
{
"name": "positive",
"type": "CONDITIONING",
"link": 9
"link": 7
},
{
"name": "negative",
"type": "CONDITIONING",
"link": 10
"link": 8
},
{
"name": "latent_image",
"type": "LATENT",
"link": 11
"link": 9
}
],
"outputs": [
@@ -434,7 +379,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
12
10
],
"slot_index": 0
}
@@ -453,7 +398,7 @@
]
},
{
"id": 12,
"id": 10,
"type": "VAEDecode",
"pos": [
1560,
@@ -461,21 +406,23 @@
],
"size": [
320,
108
72
],
"flags": {},
"order": 11,
"flags": {
"collapsed": true
},
"order": 9,
"mode": 0,
"inputs": [
{
"name": "samples",
"type": "LATENT",
"link": 12
"link": 10
},
{
"name": "vae",
"type": "VAE",
"link": 13
"link": 11
}
],
"outputs": [
@@ -483,7 +430,7 @@
"name": "IMAGE",
"type": "IMAGE",
"links": [
14
12
],
"slot_index": 0
}
@@ -494,24 +441,24 @@
"widgets_values": []
},
{
"id": 13,
"id": 11,
"type": "SaveImage",
"pos": [
1560,
216
156
],
"size": [
320,
112
84
],
"flags": {},
"order": 12,
"order": 10,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 14
"link": 12
}
],
"outputs": [],
@@ -526,22 +473,6 @@
"links": [
[
1,
4,
0,
5,
0,
"STRING"
],
[
2,
4,
1,
6,
0,
"STRING"
],
[
3,
2,
0,
4,
@@ -549,90 +480,90 @@
"STYLEREF_STYLE"
],
[
4,
2,
4,
0,
7,
5,
1,
"STRING"
],
[
5,
3,
3,
1,
7,
5,
0,
"CLIP"
],
[
4,
5,
0,
6,
7,
0,
8,
0,
"CONDITIONING"
],
[
7,
7,
5,
5,
0,
9,
7,
0,
"CONDITIONING"
],
[
8,
6,
3,
0,
11,
9,
0,
"MODEL"
],
[
9,
8,
7,
6,
0,
11,
9,
1,
"CONDITIONING"
],
[
10,
9,
8,
7,
0,
11,
9,
2,
"CONDITIONING"
],
[
11,
9,
8,
0,
9,
3,
"LATENT"
],
[
10,
9,
0,
10,
0,
11,
3,
"LATENT"
],
[
12,
11,
0,
12,
0,
"LATENT"
],
[
13,
3,
2,
12,
10,
1,
"VAE"
],
[
14,
12,
10,
0,
13,
11,
0,
"IMAGE"
]
File diff suppressed because it is too large Load Diff
+96 -165
View File
@@ -1,6 +1,6 @@
{
"last_node_id": 14,
"last_link_id": 14,
"last_node_id": 12,
"last_link_id": 12,
"nodes": [
{
"id": 1,
@@ -11,7 +11,7 @@
],
"size": [
320,
1062
206
],
"flags": {},
"order": 0,
@@ -22,7 +22,7 @@
"Node name for S&R": "Note"
},
"widgets_values": [
"Use your own style.\nExtract a style from any image at https://styleref.io \u2014 it appears in your library \u2014 then load it here by its share slug or id.\n1. Queue the StyleRef Login node alone first (Queue runs every node, so an empty workflow is the clean way). If status says signed out, set action to `sign in` and queue again.\n2. Put your style's id in `style_ref` on StyleRef Load, or pick it\n with the Search styles\u2026 button.\n3. Queue.\n\nFLUX.1 dev (fp8 all-in-one). The checkpoint downloads on first use into checkpoints/ \u2014 one ~16 GB file containing the UNET, the T5 text encoder and the VAE.\nSampler defaults: 20 steps, CFG 1.0, euler/simple. Prompt strength is the FluxGuidance node (3.5), not CFG.\nFLUX takes no negative prompt. It is guidance distilled and runs at CFG 1.0, so there is no negative encoder on this canvas \u2014 the sampler's negative input gets a zeroed conditioning. StyleRef still compiles the negative and previews it; put anything you need from it into `subject` on Apply as a positive phrase (\"fully clothed\", \"no text or watermark\"). Raising CFG does not bring the negative back.\nStyle prompts use the `flux` target \u2014 FLUX reads prose with T5, so the whole style fits instead of being truncated at ~77 tokens the way an SDXL CLIP encoder would.\n\nStyle not coming through strongly enough?\nFLUX has a confident house look and will drift back to it. Two dials, in the order worth trying:\n1. `Flux guidance` (3.5 here, FLUX's default) is the blunt dial. 4\u20135 makes the style bite harder; past that the subject starts losing to it, and a dark style can go to pure black.\n2. Narrow `sections` on StyleRef Apply to the parts that define this style. For a period or painterly style that is usually `artistic_mediums,references,surface_material,colors` \u2014 the sections naming the medium, the era and the finish. Leaving it empty sends every section, and the identity-carrying ones render last, so a long style can read as generic.\nWhich sections matter depends on the style: for a geometric or layout-led style keep `shape_language` and `spatial_hierarchy` instead. Queue the Facets template to see what a style actually carries."
"Your own style on FLUX. Extract one from any image at styleref.io.\n1. Sign in with the Login node's button.\n2. Put your style's id in `style_ref` on Load, or pick it with Search styles\u2026.\n3. Queue.\nFirst queue downloads FLUX.1 dev fp8 (~16 GB) to checkpoints/."
],
"title": "Your own style"
},
@@ -31,11 +31,11 @@
"type": "StyleRefLogin",
"pos": [
40,
1170
322
],
"size": [
320,
84
156
],
"flags": {},
"order": 1,
@@ -60,11 +60,11 @@
"type": "StyleRefLoad",
"pos": [
40,
1302
534
],
"size": [
320,
248
348
],
"flags": {},
"order": 2,
@@ -103,11 +103,11 @@
"type": "CheckpointLoaderSimple",
"pos": [
40,
1598
938
],
"size": [
320,
160
128
],
"flags": {},
"order": 3,
@@ -118,7 +118,7 @@
"name": "MODEL",
"type": "MODEL",
"links": [
8
6
],
"slot_index": 0
},
@@ -126,7 +126,7 @@
"name": "CLIP",
"type": "CLIP",
"links": [
5
3
],
"slot_index": 1
},
@@ -134,7 +134,7 @@
"name": "VAE",
"type": "VAE",
"links": [
13
11
],
"slot_index": 2
}
@@ -162,7 +162,7 @@
],
"size": [
320,
424
380
],
"flags": {},
"order": 4,
@@ -179,17 +179,14 @@
"name": "positive",
"type": "STRING",
"links": [
2,
4
2
],
"slot_index": 0
},
{
"name": "negative",
"type": "STRING",
"links": [
3
],
"links": [],
"slot_index": 1
},
{
@@ -213,62 +210,6 @@
},
{
"id": 6,
"type": "PreviewAny",
"pos": [
420,
532
],
"size": [
320,
84
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 2
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled positive"
},
{
"id": 7,
"type": "PreviewAny",
"pos": [
420,
664
],
"size": [
320,
84
],
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 3
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled negative"
},
{
"id": 8,
"type": "CLIPTextEncode",
"pos": [
800,
@@ -276,21 +217,23 @@
],
"size": [
320,
198
116
],
"flags": {},
"order": 7,
"flags": {
"collapsed": true
},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "clip",
"type": "CLIP",
"link": 5
"link": 3
},
{
"name": "text",
"type": "STRING",
"link": 4
"link": 2
}
],
"outputs": [
@@ -298,8 +241,8 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
6,
7
4,
5
],
"slot_index": 0
}
@@ -313,24 +256,24 @@
"title": "Positive (from StyleRef)"
},
{
"id": 9,
"id": 7,
"type": "FluxGuidance",
"pos": [
800,
306
156
],
"size": [
320,
112
80
],
"flags": {},
"order": 8,
"order": 6,
"mode": 0,
"inputs": [
{
"name": "conditioning",
"type": "CONDITIONING",
"link": 6
"link": 4
}
],
"outputs": [
@@ -338,7 +281,7 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
9
7
],
"slot_index": 0
}
@@ -352,24 +295,26 @@
"title": "Flux guidance"
},
{
"id": 10,
"id": 8,
"type": "ConditioningZeroOut",
"pos": [
800,
466
292
],
"size": [
320,
84
48
],
"flags": {},
"order": 9,
"flags": {
"collapsed": true
},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "conditioning",
"type": "CONDITIONING",
"link": 7
"link": 5
}
],
"outputs": [
@@ -377,7 +322,7 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
10
8
],
"slot_index": 0
}
@@ -389,18 +334,18 @@
"title": "FLUX has no negative"
},
{
"id": 11,
"id": 9,
"type": "EmptySD3LatentImage",
"pos": [
800,
598
388
],
"size": [
320,
168
144
],
"flags": {},
"order": 10,
"order": 8,
"mode": 0,
"inputs": [],
"outputs": [
@@ -408,7 +353,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
11
9
],
"slot_index": 0
}
@@ -423,7 +368,7 @@
]
},
{
"id": 12,
"id": 10,
"type": "KSampler",
"pos": [
1180,
@@ -431,31 +376,31 @@
],
"size": [
320,
352
312
],
"flags": {},
"order": 11,
"order": 9,
"mode": 0,
"inputs": [
{
"name": "model",
"type": "MODEL",
"link": 8
"link": 6
},
{
"name": "positive",
"type": "CONDITIONING",
"link": 9
"link": 7
},
{
"name": "negative",
"type": "CONDITIONING",
"link": 10
"link": 8
},
{
"name": "latent_image",
"type": "LATENT",
"link": 11
"link": 9
}
],
"outputs": [
@@ -463,7 +408,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
12
10
],
"slot_index": 0
}
@@ -482,7 +427,7 @@
]
},
{
"id": 13,
"id": 11,
"type": "VAEDecode",
"pos": [
1560,
@@ -490,21 +435,23 @@
],
"size": [
320,
108
72
],
"flags": {},
"order": 12,
"flags": {
"collapsed": true
},
"order": 10,
"mode": 0,
"inputs": [
{
"name": "samples",
"type": "LATENT",
"link": 12
"link": 10
},
{
"name": "vae",
"type": "VAE",
"link": 13
"link": 11
}
],
"outputs": [
@@ -512,7 +459,7 @@
"name": "IMAGE",
"type": "IMAGE",
"links": [
14
12
],
"slot_index": 0
}
@@ -523,24 +470,24 @@
"widgets_values": []
},
{
"id": 14,
"id": 12,
"type": "SaveImage",
"pos": [
1560,
216
156
],
"size": [
320,
112
84
],
"flags": {},
"order": 13,
"order": 11,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 14
"link": 12
}
],
"outputs": [],
@@ -566,102 +513,86 @@
5,
0,
6,
0,
1,
"STRING"
],
[
3,
5,
1,
7,
0,
"STRING"
],
[
4,
5,
0,
8,
1,
"STRING"
],
[
5,
4,
1,
8,
6,
0,
"CLIP"
],
[
4,
6,
8,
0,
9,
0,
"CONDITIONING"
],
[
7,
8,
0,
10,
0,
"CONDITIONING"
],
[
5,
6,
0,
8,
0,
"CONDITIONING"
],
[
6,
4,
0,
12,
10,
0,
"MODEL"
],
[
9,
9,
7,
7,
0,
12,
10,
1,
"CONDITIONING"
],
[
10,
10,
8,
8,
0,
12,
10,
2,
"CONDITIONING"
],
[
11,
11,
9,
9,
0,
12,
10,
3,
"LATENT"
],
[
12,
12,
10,
10,
0,
13,
11,
0,
"LATENT"
],
[
13,
11,
4,
2,
13,
11,
1,
"VAE"
],
[
14,
13,
12,
11,
0,
14,
12,
0,
"IMAGE"
]
+98 -167
View File
@@ -1,6 +1,6 @@
{
"last_node_id": 15,
"last_link_id": 16,
"last_node_id": 13,
"last_link_id": 14,
"nodes": [
{
"id": 1,
@@ -11,7 +11,7 @@
],
"size": [
320,
1008
226
],
"flags": {},
"order": 0,
@@ -22,7 +22,7 @@
"Node name for S&R": "Note"
},
"widgets_values": [
"Style prompt and reference images together.\nStyleRef Apply drives the sampler with the style's prompt; StyleRef Reference Images pulls the style's inspiration images out as a batch, previewed alongside. The prompt says how the style reads; the images show how it looks \u2014 wire the images into IPAdapter or a reference-only ControlNet to combine both.\nUse a gallery style that has inspiration images.\n\nFLUX.1 dev (fp8 all-in-one). The checkpoint downloads on first use into checkpoints/ \u2014 one ~16 GB file containing the UNET, the T5 text encoder and the VAE.\nSampler defaults: 20 steps, CFG 1.0, euler/simple. Prompt strength is the FluxGuidance node (3.5), not CFG.\nFLUX takes no negative prompt. It is guidance distilled and runs at CFG 1.0, so there is no negative encoder on this canvas \u2014 the sampler's negative input gets a zeroed conditioning. StyleRef still compiles the negative and previews it; put anything you need from it into `subject` on Apply as a positive phrase (\"fully clothed\", \"no text or watermark\"). Raising CFG does not bring the negative back.\nStyle prompts use the `flux` target \u2014 FLUX reads prose with T5, so the whole style fits instead of being truncated at ~77 tokens the way an SDXL CLIP encoder would.\n\nStyle not coming through strongly enough?\nFLUX has a confident house look and will drift back to it. Two dials, in the order worth trying:\n1. `Flux guidance` (3.5 here, FLUX's default) is the blunt dial. 4\u20135 makes the style bite harder; past that the subject starts losing to it, and a dark style can go to pure black.\n2. Narrow `sections` on StyleRef Apply to the parts that define this style. For a period or painterly style that is usually `artistic_mediums,references,surface_material,colors` \u2014 the sections naming the medium, the era and the finish. Leaving it empty sends every section, and the identity-carrying ones render last, so a long style can read as generic.\nWhich sections matter depends on the style: for a geometric or layout-led style keep `shape_language` and `spatial_hierarchy` instead. Queue the Facets template to see what a style actually carries."
"The style's prompt and its own inspiration images, together.\nApply drives the sampler; Reference Images pulls the images out as a batch \u2014 preview them, or wire them into IPAdapter or ControlNet.\nNeeds a gallery style that has inspiration images.\nFirst queue downloads FLUX.1 dev fp8 (~16 GB) to checkpoints/."
],
"title": "FLUX + references"
},
@@ -31,11 +31,11 @@
"type": "StyleRefLoad",
"pos": [
40,
1116
342
],
"size": [
320,
248
348
],
"flags": {},
"order": 1,
@@ -75,11 +75,11 @@
"type": "CheckpointLoaderSimple",
"pos": [
40,
1412
746
],
"size": [
320,
160
128
],
"flags": {},
"order": 2,
@@ -90,7 +90,7 @@
"name": "MODEL",
"type": "MODEL",
"links": [
10
8
],
"slot_index": 0
},
@@ -98,7 +98,7 @@
"name": "CLIP",
"type": "CLIP",
"links": [
7
5
],
"slot_index": 1
},
@@ -106,7 +106,7 @@
"name": "VAE",
"type": "VAE",
"links": [
15
13
],
"slot_index": 2
}
@@ -134,7 +134,7 @@
],
"size": [
320,
136
128
],
"flags": {},
"order": 3,
@@ -179,7 +179,7 @@
],
"size": [
320,
84
48
],
"flags": {},
"order": 4,
@@ -203,11 +203,11 @@
"type": "StyleRefApply",
"pos": [
420,
376
348
],
"size": [
320,
424
380
],
"flags": {},
"order": 5,
@@ -224,17 +224,14 @@
"name": "positive",
"type": "STRING",
"links": [
4,
6
4
],
"slot_index": 0
},
{
"name": "negative",
"type": "STRING",
"links": [
5
],
"links": [],
"slot_index": 1
},
{
@@ -258,62 +255,6 @@
},
{
"id": 7,
"type": "PreviewAny",
"pos": [
420,
848
],
"size": [
320,
84
],
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 4
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled positive"
},
{
"id": 8,
"type": "PreviewAny",
"pos": [
420,
980
],
"size": [
320,
84
],
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 5
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled negative"
},
{
"id": 9,
"type": "CLIPTextEncode",
"pos": [
800,
@@ -321,21 +262,23 @@
],
"size": [
320,
198
116
],
"flags": {},
"order": 8,
"flags": {
"collapsed": true
},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "clip",
"type": "CLIP",
"link": 7
"link": 5
},
{
"name": "text",
"type": "STRING",
"link": 6
"link": 4
}
],
"outputs": [
@@ -343,8 +286,8 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
8,
9
6,
7
],
"slot_index": 0
}
@@ -358,24 +301,24 @@
"title": "Positive (from StyleRef)"
},
{
"id": 10,
"id": 8,
"type": "FluxGuidance",
"pos": [
800,
306
156
],
"size": [
320,
112
80
],
"flags": {},
"order": 9,
"order": 7,
"mode": 0,
"inputs": [
{
"name": "conditioning",
"type": "CONDITIONING",
"link": 8
"link": 6
}
],
"outputs": [
@@ -383,7 +326,7 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
11
9
],
"slot_index": 0
}
@@ -397,24 +340,26 @@
"title": "Flux guidance"
},
{
"id": 11,
"id": 9,
"type": "ConditioningZeroOut",
"pos": [
800,
466
292
],
"size": [
320,
84
48
],
"flags": {},
"order": 10,
"flags": {
"collapsed": true
},
"order": 8,
"mode": 0,
"inputs": [
{
"name": "conditioning",
"type": "CONDITIONING",
"link": 9
"link": 7
}
],
"outputs": [
@@ -422,7 +367,7 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
12
10
],
"slot_index": 0
}
@@ -434,18 +379,18 @@
"title": "FLUX has no negative"
},
{
"id": 12,
"id": 10,
"type": "EmptySD3LatentImage",
"pos": [
800,
598
388
],
"size": [
320,
168
144
],
"flags": {},
"order": 11,
"order": 9,
"mode": 0,
"inputs": [],
"outputs": [
@@ -453,7 +398,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
13
11
],
"slot_index": 0
}
@@ -468,7 +413,7 @@
]
},
{
"id": 13,
"id": 11,
"type": "KSampler",
"pos": [
1180,
@@ -476,31 +421,31 @@
],
"size": [
320,
352
312
],
"flags": {},
"order": 12,
"order": 10,
"mode": 0,
"inputs": [
{
"name": "model",
"type": "MODEL",
"link": 10
"link": 8
},
{
"name": "positive",
"type": "CONDITIONING",
"link": 11
"link": 9
},
{
"name": "negative",
"type": "CONDITIONING",
"link": 12
"link": 10
},
{
"name": "latent_image",
"type": "LATENT",
"link": 13
"link": 11
}
],
"outputs": [
@@ -508,7 +453,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
14
12
],
"slot_index": 0
}
@@ -527,7 +472,7 @@
]
},
{
"id": 14,
"id": 12,
"type": "VAEDecode",
"pos": [
1560,
@@ -535,21 +480,23 @@
],
"size": [
320,
108
72
],
"flags": {},
"order": 13,
"flags": {
"collapsed": true
},
"order": 11,
"mode": 0,
"inputs": [
{
"name": "samples",
"type": "LATENT",
"link": 14
"link": 12
},
{
"name": "vae",
"type": "VAE",
"link": 15
"link": 13
}
],
"outputs": [
@@ -557,7 +504,7 @@
"name": "IMAGE",
"type": "IMAGE",
"links": [
16
14
],
"slot_index": 0
}
@@ -568,24 +515,24 @@
"widgets_values": []
},
{
"id": 15,
"id": 13,
"type": "SaveImage",
"pos": [
1560,
216
156
],
"size": [
320,
112
84
],
"flags": {},
"order": 14,
"order": 12,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 16
"link": 14
}
],
"outputs": [],
@@ -627,102 +574,86 @@
6,
0,
7,
0,
1,
"STRING"
],
[
5,
6,
1,
8,
0,
"STRING"
],
[
6,
6,
0,
9,
1,
"STRING"
],
[
7,
3,
1,
9,
7,
0,
"CLIP"
],
[
6,
7,
0,
8,
9,
0,
10,
0,
"CONDITIONING"
],
[
9,
9,
7,
7,
0,
11,
9,
0,
"CONDITIONING"
],
[
10,
8,
3,
0,
13,
11,
0,
"MODEL"
],
[
11,
10,
9,
8,
0,
13,
11,
1,
"CONDITIONING"
],
[
12,
11,
10,
9,
0,
13,
11,
2,
"CONDITIONING"
],
[
13,
11,
10,
0,
11,
3,
"LATENT"
],
[
12,
11,
0,
12,
0,
13,
3,
"LATENT"
],
[
14,
13,
0,
14,
0,
"LATENT"
],
[
15,
3,
2,
14,
12,
1,
"VAE"
],
[
16,
14,
12,
0,
15,
13,
0,
"IMAGE"
]
+107 -176
View File
@@ -1,6 +1,6 @@
{
"last_node_id": 20,
"last_link_id": 21,
"last_node_id": 18,
"last_link_id": 19,
"nodes": [
{
"id": 1,
@@ -11,7 +11,7 @@
],
"size": [
320,
396
186
],
"flags": {},
"order": 0,
@@ -22,7 +22,7 @@
"Node name for S&R": "Note"
},
"widgets_values": [
"Inside the style \u2014 the Facets node.\nApply gives you one prompt string. Facets gives you the style's sections one output at a time \u2014 24 of them, exactly the sections you see on the style board at styleref.io, plus the six custom items.\nSix are previewed here so you can read them. Every other output is on the node too; drag any of them into a text input.\nThey are plain STRINGs, so they go anywhere text goes: a second CLIP encoder for regional conditioning, an IPAdapter or ControlNet prompt, a LoRA trigger line, or your own nodes. That is the escape hatch \u2014 use the palette without taking the whole prompt.\nThe render alongside is the paved road (Apply), so you can compare the assembled prompt against the parts it was built from."
"Inside a style: Facets emits each of its 24 sections as its own STRING.\nSix are previewed here; drag any output into any text input \u2014 a second encoder, an IPAdapter prompt, a LoRA trigger.\nApply and the sampler alongside render the whole assembled prompt."
],
"title": "Facets"
},
@@ -31,11 +31,11 @@
"type": "StyleRefLoad",
"pos": [
40,
504
302
],
"size": [
320,
248
348
],
"flags": {},
"order": 1,
@@ -75,11 +75,11 @@
"type": "CheckpointLoaderSimple",
"pos": [
40,
800
706
],
"size": [
320,
160
128
],
"flags": {},
"order": 2,
@@ -90,7 +90,7 @@
"name": "MODEL",
"type": "MODEL",
"links": [
15
13
],
"slot_index": 0
},
@@ -98,7 +98,7 @@
"name": "CLIP",
"type": "CLIP",
"links": [
12
10
],
"slot_index": 1
},
@@ -106,7 +106,7 @@
"name": "VAE",
"type": "VAE",
"links": [
20
18
],
"slot_index": 2
}
@@ -134,7 +134,7 @@
],
"size": [
320,
636
624
],
"flags": {},
"order": 3,
@@ -319,7 +319,7 @@
],
"size": [
320,
84
152
],
"flags": {},
"order": 4,
@@ -343,11 +343,11 @@
"type": "PreviewAny",
"pos": [
800,
192
268
],
"size": [
320,
84
152
],
"flags": {},
"order": 5,
@@ -371,11 +371,11 @@
"type": "PreviewAny",
"pos": [
800,
324
476
],
"size": [
320,
84
152
],
"flags": {},
"order": 6,
@@ -399,11 +399,11 @@
"type": "PreviewAny",
"pos": [
800,
456
684
],
"size": [
320,
84
152
],
"flags": {},
"order": 7,
@@ -427,11 +427,11 @@
"type": "PreviewAny",
"pos": [
800,
588
892
],
"size": [
320,
84
152
],
"flags": {},
"order": 8,
@@ -455,11 +455,11 @@
"type": "PreviewAny",
"pos": [
800,
720
1100
],
"size": [
320,
84
152
],
"flags": {},
"order": 9,
@@ -487,7 +487,7 @@
],
"size": [
320,
424
380
],
"flags": {},
"order": 10,
@@ -504,17 +504,14 @@
"name": "positive",
"type": "STRING",
"links": [
9,
11
9
],
"slot_index": 0
},
{
"name": "negative",
"type": "STRING",
"links": [
10
],
"links": [],
"slot_index": 1
},
{
@@ -538,62 +535,6 @@
},
{
"id": 12,
"type": "PreviewAny",
"pos": [
1180,
532
],
"size": [
320,
84
],
"flags": {},
"order": 11,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 9
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled positive"
},
{
"id": 13,
"type": "PreviewAny",
"pos": [
1180,
664
],
"size": [
320,
84
],
"flags": {},
"order": 12,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 10
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled negative"
},
{
"id": 14,
"type": "CLIPTextEncode",
"pos": [
1560,
@@ -601,21 +542,23 @@
],
"size": [
320,
198
116
],
"flags": {},
"order": 13,
"flags": {
"collapsed": true
},
"order": 11,
"mode": 0,
"inputs": [
{
"name": "clip",
"type": "CLIP",
"link": 12
"link": 10
},
{
"name": "text",
"type": "STRING",
"link": 11
"link": 9
}
],
"outputs": [
@@ -623,8 +566,8 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
13,
14
11,
12
],
"slot_index": 0
}
@@ -638,24 +581,24 @@
"title": "Positive (from StyleRef)"
},
{
"id": 15,
"id": 13,
"type": "FluxGuidance",
"pos": [
1560,
306
156
],
"size": [
320,
112
80
],
"flags": {},
"order": 14,
"order": 12,
"mode": 0,
"inputs": [
{
"name": "conditioning",
"type": "CONDITIONING",
"link": 13
"link": 11
}
],
"outputs": [
@@ -663,7 +606,7 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
16
14
],
"slot_index": 0
}
@@ -677,24 +620,26 @@
"title": "Flux guidance"
},
{
"id": 16,
"id": 14,
"type": "ConditioningZeroOut",
"pos": [
1560,
466
292
],
"size": [
320,
84
48
],
"flags": {},
"order": 15,
"flags": {
"collapsed": true
},
"order": 13,
"mode": 0,
"inputs": [
{
"name": "conditioning",
"type": "CONDITIONING",
"link": 14
"link": 12
}
],
"outputs": [
@@ -702,7 +647,7 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
17
15
],
"slot_index": 0
}
@@ -714,18 +659,18 @@
"title": "FLUX has no negative"
},
{
"id": 17,
"id": 15,
"type": "EmptySD3LatentImage",
"pos": [
1560,
598
388
],
"size": [
320,
168
144
],
"flags": {},
"order": 16,
"order": 14,
"mode": 0,
"inputs": [],
"outputs": [
@@ -733,7 +678,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
18
16
],
"slot_index": 0
}
@@ -748,7 +693,7 @@
]
},
{
"id": 18,
"id": 16,
"type": "KSampler",
"pos": [
1940,
@@ -756,31 +701,31 @@
],
"size": [
320,
352
312
],
"flags": {},
"order": 17,
"order": 15,
"mode": 0,
"inputs": [
{
"name": "model",
"type": "MODEL",
"link": 15
"link": 13
},
{
"name": "positive",
"type": "CONDITIONING",
"link": 16
"link": 14
},
{
"name": "negative",
"type": "CONDITIONING",
"link": 17
"link": 15
},
{
"name": "latent_image",
"type": "LATENT",
"link": 18
"link": 16
}
],
"outputs": [
@@ -788,7 +733,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
19
17
],
"slot_index": 0
}
@@ -807,7 +752,7 @@
]
},
{
"id": 19,
"id": 17,
"type": "VAEDecode",
"pos": [
2320,
@@ -815,21 +760,23 @@
],
"size": [
320,
108
72
],
"flags": {},
"order": 18,
"flags": {
"collapsed": true
},
"order": 16,
"mode": 0,
"inputs": [
{
"name": "samples",
"type": "LATENT",
"link": 19
"link": 17
},
{
"name": "vae",
"type": "VAE",
"link": 20
"link": 18
}
],
"outputs": [
@@ -837,7 +784,7 @@
"name": "IMAGE",
"type": "IMAGE",
"links": [
21
19
],
"slot_index": 0
}
@@ -848,24 +795,24 @@
"widgets_values": []
},
{
"id": 20,
"id": 18,
"type": "SaveImage",
"pos": [
2320,
216
156
],
"size": [
320,
112
84
],
"flags": {},
"order": 19,
"order": 17,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 21
"link": 19
}
],
"outputs": [],
@@ -947,102 +894,86 @@
11,
0,
12,
0,
1,
"STRING"
],
[
10,
11,
1,
13,
0,
"STRING"
],
[
11,
11,
0,
14,
1,
"STRING"
],
[
12,
3,
1,
14,
12,
0,
"CLIP"
],
[
11,
12,
0,
13,
14,
0,
15,
0,
"CONDITIONING"
],
[
14,
14,
12,
12,
0,
16,
14,
0,
"CONDITIONING"
],
[
15,
13,
3,
0,
18,
16,
0,
"MODEL"
],
[
16,
15,
14,
13,
0,
18,
16,
1,
"CONDITIONING"
],
[
17,
16,
15,
14,
0,
18,
16,
2,
"CONDITIONING"
],
[
18,
16,
15,
0,
16,
3,
"LATENT"
],
[
17,
16,
0,
17,
0,
18,
3,
"LATENT"
],
[
19,
18,
0,
19,
0,
"LATENT"
],
[
20,
3,
2,
19,
17,
1,
"VAE"
],
[
21,
19,
17,
0,
20,
18,
0,
"IMAGE"
]
+94 -163
View File
@@ -1,6 +1,6 @@
{
"last_node_id": 14,
"last_link_id": 13,
"last_node_id": 12,
"last_link_id": 11,
"nodes": [
{
"id": 1,
@@ -11,7 +11,7 @@
],
"size": [
320,
540
186
],
"flags": {},
"order": 0,
@@ -22,7 +22,7 @@
"Node name for S&R": "Note"
},
"widgets_values": [
"Z-Image quickstart \u2014 no account needed.\n1. Queue \u2014 the three Z-Image files download on first run.\n2. Change `subject` on StyleRef Apply and queue again (seeds randomize).\nSwap `style_ref` on StyleRef Load for any gallery slug.\n\nZ-Image Turbo (S3-DiT). Three model files download on first use: the UNET (diffusion_models/), the Qwen text encoder (text_encoders/), and the VAE (vae/).\nSampler defaults are turbo: 8 steps, CFG 1.0, euler/simple.\nZ-Image takes no negative prompt. The model runs without classifier-free guidance, so there is no negative encoder on this canvas \u2014 the sampler's negative input gets a zeroed conditioning. StyleRef still compiles the negative and previews it; put anything you need from it into `subject` on Apply as a positive phrase (\"fully clothed\", \"no text or watermark\"). Raising CFG does not bring the negative back.\nStyle prompts use the `diffusion` target \u2014 Z-Image reads the same tag-weighted output SDXL/SD1.5 use."
"One gallery style, one image, on Z-Image Turbo. No account needed.\nQueue it. Then edit `subject` on Apply \u2014 or swap `style_ref` on Load for any gallery slug \u2014 and queue again.\nFirst queue downloads 3 files: UNET, Qwen text encoder, VAE."
],
"title": "Z-Image quickstart"
},
@@ -31,11 +31,11 @@
"type": "StyleRefLoad",
"pos": [
40,
648
302
],
"size": [
320,
248
348
],
"flags": {},
"order": 1,
@@ -74,11 +74,11 @@
"type": "UNETLoader",
"pos": [
40,
944
706
],
"size": [
320,
140
108
],
"flags": {},
"order": 2,
@@ -89,7 +89,7 @@
"name": "MODEL",
"type": "MODEL",
"links": [
6
4
],
"slot_index": 0
}
@@ -115,11 +115,11 @@
"type": "CLIPLoader",
"pos": [
40,
1132
870
],
"size": [
320,
168
140
],
"flags": {},
"order": 3,
@@ -130,7 +130,7 @@
"name": "CLIP",
"type": "CLIP",
"links": [
5
3
],
"slot_index": 0
}
@@ -157,11 +157,11 @@
"type": "VAELoader",
"pos": [
40,
1348
1066
],
"size": [
320,
112
80
],
"flags": {},
"order": 4,
@@ -172,7 +172,7 @@
"name": "VAE",
"type": "VAE",
"links": [
12
10
],
"slot_index": 0
}
@@ -201,7 +201,7 @@
],
"size": [
320,
424
380
],
"flags": {},
"order": 5,
@@ -218,17 +218,14 @@
"name": "positive",
"type": "STRING",
"links": [
2,
4
2
],
"slot_index": 0
},
{
"name": "negative",
"type": "STRING",
"links": [
3
],
"links": [],
"slot_index": 1
},
{
@@ -252,62 +249,6 @@
},
{
"id": 7,
"type": "PreviewAny",
"pos": [
420,
532
],
"size": [
320,
84
],
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 2
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled positive"
},
{
"id": 8,
"type": "PreviewAny",
"pos": [
420,
664
],
"size": [
320,
84
],
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 3
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled negative"
},
{
"id": 9,
"type": "CLIPTextEncode",
"pos": [
800,
@@ -315,21 +256,23 @@
],
"size": [
320,
198
116
],
"flags": {},
"order": 8,
"flags": {
"collapsed": true
},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "clip",
"type": "CLIP",
"link": 5
"link": 3
},
{
"name": "text",
"type": "STRING",
"link": 4
"link": 2
}
],
"outputs": [
@@ -337,8 +280,8 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
7,
8
5,
6
],
"slot_index": 0
}
@@ -352,24 +295,26 @@
"title": "Positive (from StyleRef)"
},
{
"id": 10,
"id": 8,
"type": "ConditioningZeroOut",
"pos": [
800,
306
156
],
"size": [
320,
84
48
],
"flags": {},
"order": 9,
"flags": {
"collapsed": true
},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "conditioning",
"type": "CONDITIONING",
"link": 8
"link": 6
}
],
"outputs": [
@@ -377,7 +322,7 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
9
7
],
"slot_index": 0
}
@@ -389,18 +334,18 @@
"title": "Z-Image has no negative"
},
{
"id": 11,
"id": 9,
"type": "EmptySD3LatentImage",
"pos": [
800,
438
252
],
"size": [
320,
168
144
],
"flags": {},
"order": 10,
"order": 8,
"mode": 0,
"inputs": [],
"outputs": [
@@ -408,7 +353,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
10
8
],
"slot_index": 0
}
@@ -423,7 +368,7 @@
]
},
{
"id": 12,
"id": 10,
"type": "KSampler",
"pos": [
1180,
@@ -431,31 +376,31 @@
],
"size": [
320,
352
312
],
"flags": {},
"order": 11,
"order": 9,
"mode": 0,
"inputs": [
{
"name": "model",
"type": "MODEL",
"link": 6
"link": 4
},
{
"name": "positive",
"type": "CONDITIONING",
"link": 7
"link": 5
},
{
"name": "negative",
"type": "CONDITIONING",
"link": 9
"link": 7
},
{
"name": "latent_image",
"type": "LATENT",
"link": 10
"link": 8
}
],
"outputs": [
@@ -463,7 +408,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
11
9
],
"slot_index": 0
}
@@ -482,7 +427,7 @@
]
},
{
"id": 13,
"id": 11,
"type": "VAEDecode",
"pos": [
1560,
@@ -490,21 +435,23 @@
],
"size": [
320,
108
72
],
"flags": {},
"order": 12,
"flags": {
"collapsed": true
},
"order": 10,
"mode": 0,
"inputs": [
{
"name": "samples",
"type": "LATENT",
"link": 11
"link": 9
},
{
"name": "vae",
"type": "VAE",
"link": 12
"link": 10
}
],
"outputs": [
@@ -512,7 +459,7 @@
"name": "IMAGE",
"type": "IMAGE",
"links": [
13
11
],
"slot_index": 0
}
@@ -523,24 +470,24 @@
"widgets_values": []
},
{
"id": 14,
"id": 12,
"type": "SaveImage",
"pos": [
1560,
216
156
],
"size": [
320,
112
84
],
"flags": {},
"order": 13,
"order": 11,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 13
"link": 11
}
],
"outputs": [],
@@ -566,94 +513,78 @@
6,
0,
7,
0,
1,
"STRING"
],
[
3,
6,
1,
8,
0,
"STRING"
],
[
4,
6,
0,
9,
1,
"STRING"
],
[
5,
4,
0,
9,
7,
0,
"CLIP"
],
[
6,
4,
3,
0,
12,
10,
0,
"MODEL"
],
[
5,
7,
9,
0,
12,
10,
1,
"CONDITIONING"
],
[
6,
7,
0,
8,
0,
"CONDITIONING"
],
[
7,
8,
0,
10,
2,
"CONDITIONING"
],
[
8,
9,
0,
10,
0,
"CONDITIONING"
3,
"LATENT"
],
[
9,
10,
0,
12,
2,
"CONDITIONING"
11,
0,
"LATENT"
],
[
10,
11,
0,
12,
3,
"LATENT"
],
[
11,
12,
0,
13,
0,
"LATENT"
],
[
12,
5,
0,
13,
11,
1,
"VAE"
],
[
13,
13,
11,
11,
0,
14,
12,
0,
"IMAGE"
]
File diff suppressed because it is too large Load Diff
+97 -166
View File
@@ -1,6 +1,6 @@
{
"last_node_id": 15,
"last_link_id": 13,
"last_node_id": 13,
"last_link_id": 11,
"nodes": [
{
"id": 1,
@@ -11,7 +11,7 @@
],
"size": [
320,
594
206
],
"flags": {},
"order": 0,
@@ -22,7 +22,7 @@
"Node name for S&R": "Note"
},
"widgets_values": [
"Use your own style on Z-Image.\nExtract a style from any image at https://styleref.io, then load it here by its share slug or id.\n1. Queue the StyleRef Login node alone first (use its Sign in button).\n2. Put your style's id in `style_ref` on StyleRef Load, or pick it\n with the Search styles\u2026 button.\n3. Queue.\n\nZ-Image Turbo (S3-DiT). Three model files download on first use: the UNET (diffusion_models/), the Qwen text encoder (text_encoders/), and the VAE (vae/).\nSampler defaults are turbo: 8 steps, CFG 1.0, euler/simple.\nZ-Image takes no negative prompt. The model runs without classifier-free guidance, so there is no negative encoder on this canvas \u2014 the sampler's negative input gets a zeroed conditioning. StyleRef still compiles the negative and previews it; put anything you need from it into `subject` on Apply as a positive phrase (\"fully clothed\", \"no text or watermark\"). Raising CFG does not bring the negative back.\nStyle prompts use the `diffusion` target \u2014 Z-Image reads the same tag-weighted output SDXL/SD1.5 use."
"Your own style on Z-Image. Extract one from any image at styleref.io.\n1. Sign in with the Login node's button.\n2. Put your style's id in `style_ref` on Load, or pick it with Search styles\u2026.\n3. Queue.\nFirst queue downloads 3 files: UNET, Qwen text encoder, VAE."
],
"title": "Z-Image \u2014 your style"
},
@@ -31,11 +31,11 @@
"type": "StyleRefLogin",
"pos": [
40,
702
322
],
"size": [
320,
84
156
],
"flags": {},
"order": 1,
@@ -60,11 +60,11 @@
"type": "StyleRefLoad",
"pos": [
40,
834
534
],
"size": [
320,
248
348
],
"flags": {},
"order": 2,
@@ -103,11 +103,11 @@
"type": "UNETLoader",
"pos": [
40,
1130
938
],
"size": [
320,
140
108
],
"flags": {},
"order": 3,
@@ -118,7 +118,7 @@
"name": "MODEL",
"type": "MODEL",
"links": [
6
4
],
"slot_index": 0
}
@@ -144,11 +144,11 @@
"type": "CLIPLoader",
"pos": [
40,
1318
1102
],
"size": [
320,
168
140
],
"flags": {},
"order": 4,
@@ -159,7 +159,7 @@
"name": "CLIP",
"type": "CLIP",
"links": [
5
3
],
"slot_index": 0
}
@@ -186,11 +186,11 @@
"type": "VAELoader",
"pos": [
40,
1534
1298
],
"size": [
320,
112
80
],
"flags": {},
"order": 5,
@@ -201,7 +201,7 @@
"name": "VAE",
"type": "VAE",
"links": [
12
10
],
"slot_index": 0
}
@@ -230,7 +230,7 @@
],
"size": [
320,
424
380
],
"flags": {},
"order": 6,
@@ -247,17 +247,14 @@
"name": "positive",
"type": "STRING",
"links": [
2,
4
2
],
"slot_index": 0
},
{
"name": "negative",
"type": "STRING",
"links": [
3
],
"links": [],
"slot_index": 1
},
{
@@ -281,62 +278,6 @@
},
{
"id": 8,
"type": "PreviewAny",
"pos": [
420,
532
],
"size": [
320,
84
],
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 2
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled positive"
},
{
"id": 9,
"type": "PreviewAny",
"pos": [
420,
664
],
"size": [
320,
84
],
"flags": {},
"order": 8,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 3
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled negative"
},
{
"id": 10,
"type": "CLIPTextEncode",
"pos": [
800,
@@ -344,21 +285,23 @@
],
"size": [
320,
198
116
],
"flags": {},
"order": 9,
"flags": {
"collapsed": true
},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "clip",
"type": "CLIP",
"link": 5
"link": 3
},
{
"name": "text",
"type": "STRING",
"link": 4
"link": 2
}
],
"outputs": [
@@ -366,8 +309,8 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
7,
8
5,
6
],
"slot_index": 0
}
@@ -381,24 +324,26 @@
"title": "Positive (from StyleRef)"
},
{
"id": 11,
"id": 9,
"type": "ConditioningZeroOut",
"pos": [
800,
306
156
],
"size": [
320,
84
48
],
"flags": {},
"order": 10,
"flags": {
"collapsed": true
},
"order": 8,
"mode": 0,
"inputs": [
{
"name": "conditioning",
"type": "CONDITIONING",
"link": 8
"link": 6
}
],
"outputs": [
@@ -406,7 +351,7 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
9
7
],
"slot_index": 0
}
@@ -418,18 +363,18 @@
"title": "Z-Image has no negative"
},
{
"id": 12,
"id": 10,
"type": "EmptySD3LatentImage",
"pos": [
800,
438
252
],
"size": [
320,
168
144
],
"flags": {},
"order": 11,
"order": 9,
"mode": 0,
"inputs": [],
"outputs": [
@@ -437,7 +382,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
10
8
],
"slot_index": 0
}
@@ -452,7 +397,7 @@
]
},
{
"id": 13,
"id": 11,
"type": "KSampler",
"pos": [
1180,
@@ -460,31 +405,31 @@
],
"size": [
320,
352
312
],
"flags": {},
"order": 12,
"order": 10,
"mode": 0,
"inputs": [
{
"name": "model",
"type": "MODEL",
"link": 6
"link": 4
},
{
"name": "positive",
"type": "CONDITIONING",
"link": 7
"link": 5
},
{
"name": "negative",
"type": "CONDITIONING",
"link": 9
"link": 7
},
{
"name": "latent_image",
"type": "LATENT",
"link": 10
"link": 8
}
],
"outputs": [
@@ -492,7 +437,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
11
9
],
"slot_index": 0
}
@@ -511,7 +456,7 @@
]
},
{
"id": 14,
"id": 12,
"type": "VAEDecode",
"pos": [
1560,
@@ -519,21 +464,23 @@
],
"size": [
320,
108
72
],
"flags": {},
"order": 13,
"flags": {
"collapsed": true
},
"order": 11,
"mode": 0,
"inputs": [
{
"name": "samples",
"type": "LATENT",
"link": 11
"link": 9
},
{
"name": "vae",
"type": "VAE",
"link": 12
"link": 10
}
],
"outputs": [
@@ -541,7 +488,7 @@
"name": "IMAGE",
"type": "IMAGE",
"links": [
13
11
],
"slot_index": 0
}
@@ -552,24 +499,24 @@
"widgets_values": []
},
{
"id": 15,
"id": 13,
"type": "SaveImage",
"pos": [
1560,
216
156
],
"size": [
320,
112
84
],
"flags": {},
"order": 14,
"order": 12,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 13
"link": 11
}
],
"outputs": [],
@@ -595,94 +542,78 @@
7,
0,
8,
0,
1,
"STRING"
],
[
3,
7,
1,
9,
0,
"STRING"
],
[
4,
7,
0,
10,
1,
"STRING"
],
[
5,
5,
0,
10,
8,
0,
"CLIP"
],
[
6,
4,
4,
0,
13,
11,
0,
"MODEL"
],
[
7,
10,
5,
8,
0,
13,
11,
1,
"CONDITIONING"
],
[
6,
8,
0,
9,
0,
"CONDITIONING"
],
[
7,
9,
0,
11,
2,
"CONDITIONING"
],
[
8,
10,
0,
11,
0,
"CONDITIONING"
3,
"LATENT"
],
[
9,
11,
0,
13,
2,
"CONDITIONING"
12,
0,
"LATENT"
],
[
10,
12,
0,
13,
3,
"LATENT"
],
[
11,
13,
0,
14,
0,
"LATENT"
],
[
12,
6,
0,
14,
12,
1,
"VAE"
],
[
13,
14,
11,
12,
0,
15,
13,
0,
"IMAGE"
]
+97 -166
View File
@@ -1,6 +1,6 @@
{
"last_node_id": 16,
"last_link_id": 15,
"last_node_id": 14,
"last_link_id": 13,
"nodes": [
{
"id": 1,
@@ -11,7 +11,7 @@
],
"size": [
320,
576
226
],
"flags": {},
"order": 0,
@@ -22,7 +22,7 @@
"Node name for S&R": "Note"
},
"widgets_values": [
"Z-Image \u2014 style prompt and reference images together.\nStyleRef Apply drives the Z-Image sampler with the style's prompt; StyleRef Reference Images pulls the style's inspiration images out as a batch, previewed alongside. The prompt says how the style reads; the images show how it looks \u2014 wire the images into IPAdapter or a reference-only ControlNet to combine both.\nUse a gallery style that has inspiration images.\n\nZ-Image Turbo (S3-DiT). Three model files download on first use: the UNET (diffusion_models/), the Qwen text encoder (text_encoders/), and the VAE (vae/).\nSampler defaults are turbo: 8 steps, CFG 1.0, euler/simple.\nZ-Image takes no negative prompt. The model runs without classifier-free guidance, so there is no negative encoder on this canvas \u2014 the sampler's negative input gets a zeroed conditioning. StyleRef still compiles the negative and previews it; put anything you need from it into `subject` on Apply as a positive phrase (\"fully clothed\", \"no text or watermark\"). Raising CFG does not bring the negative back.\nStyle prompts use the `diffusion` target \u2014 Z-Image reads the same tag-weighted output SDXL/SD1.5 use."
"The style's prompt and its own inspiration images, together.\nApply drives the sampler; Reference Images pulls the images out as a batch \u2014 preview them, or wire them into IPAdapter or ControlNet.\nNeeds a gallery style that has inspiration images.\nFirst queue downloads 3 files: UNET, Qwen text encoder, VAE."
],
"title": "Z-Image + references"
},
@@ -31,11 +31,11 @@
"type": "StyleRefLoad",
"pos": [
40,
684
342
],
"size": [
320,
248
348
],
"flags": {},
"order": 1,
@@ -75,11 +75,11 @@
"type": "UNETLoader",
"pos": [
40,
980
746
],
"size": [
320,
140
108
],
"flags": {},
"order": 2,
@@ -90,7 +90,7 @@
"name": "MODEL",
"type": "MODEL",
"links": [
8
6
],
"slot_index": 0
}
@@ -116,11 +116,11 @@
"type": "CLIPLoader",
"pos": [
40,
1168
910
],
"size": [
320,
168
140
],
"flags": {},
"order": 3,
@@ -131,7 +131,7 @@
"name": "CLIP",
"type": "CLIP",
"links": [
7
5
],
"slot_index": 0
}
@@ -158,11 +158,11 @@
"type": "VAELoader",
"pos": [
40,
1384
1106
],
"size": [
320,
112
80
],
"flags": {},
"order": 4,
@@ -173,7 +173,7 @@
"name": "VAE",
"type": "VAE",
"links": [
14
12
],
"slot_index": 0
}
@@ -202,7 +202,7 @@
],
"size": [
320,
136
128
],
"flags": {},
"order": 5,
@@ -247,7 +247,7 @@
],
"size": [
320,
84
48
],
"flags": {},
"order": 6,
@@ -271,11 +271,11 @@
"type": "StyleRefApply",
"pos": [
420,
376
348
],
"size": [
320,
424
380
],
"flags": {},
"order": 7,
@@ -292,17 +292,14 @@
"name": "positive",
"type": "STRING",
"links": [
4,
6
4
],
"slot_index": 0
},
{
"name": "negative",
"type": "STRING",
"links": [
5
],
"links": [],
"slot_index": 1
},
{
@@ -326,62 +323,6 @@
},
{
"id": 9,
"type": "PreviewAny",
"pos": [
420,
848
],
"size": [
320,
84
],
"flags": {},
"order": 8,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 4
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled positive"
},
{
"id": 10,
"type": "PreviewAny",
"pos": [
420,
980
],
"size": [
320,
84
],
"flags": {},
"order": 9,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 5
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled negative"
},
{
"id": 11,
"type": "CLIPTextEncode",
"pos": [
800,
@@ -389,21 +330,23 @@
],
"size": [
320,
198
116
],
"flags": {},
"order": 10,
"flags": {
"collapsed": true
},
"order": 8,
"mode": 0,
"inputs": [
{
"name": "clip",
"type": "CLIP",
"link": 7
"link": 5
},
{
"name": "text",
"type": "STRING",
"link": 6
"link": 4
}
],
"outputs": [
@@ -411,8 +354,8 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
9,
10
7,
8
],
"slot_index": 0
}
@@ -426,24 +369,26 @@
"title": "Positive (from StyleRef)"
},
{
"id": 12,
"id": 10,
"type": "ConditioningZeroOut",
"pos": [
800,
306
156
],
"size": [
320,
84
48
],
"flags": {},
"order": 11,
"flags": {
"collapsed": true
},
"order": 9,
"mode": 0,
"inputs": [
{
"name": "conditioning",
"type": "CONDITIONING",
"link": 10
"link": 8
}
],
"outputs": [
@@ -451,7 +396,7 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
11
9
],
"slot_index": 0
}
@@ -463,18 +408,18 @@
"title": "Z-Image has no negative"
},
{
"id": 13,
"id": 11,
"type": "EmptySD3LatentImage",
"pos": [
800,
438
252
],
"size": [
320,
168
144
],
"flags": {},
"order": 12,
"order": 10,
"mode": 0,
"inputs": [],
"outputs": [
@@ -482,7 +427,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
12
10
],
"slot_index": 0
}
@@ -497,7 +442,7 @@
]
},
{
"id": 14,
"id": 12,
"type": "KSampler",
"pos": [
1180,
@@ -505,31 +450,31 @@
],
"size": [
320,
352
312
],
"flags": {},
"order": 13,
"order": 11,
"mode": 0,
"inputs": [
{
"name": "model",
"type": "MODEL",
"link": 8
"link": 6
},
{
"name": "positive",
"type": "CONDITIONING",
"link": 9
"link": 7
},
{
"name": "negative",
"type": "CONDITIONING",
"link": 11
"link": 9
},
{
"name": "latent_image",
"type": "LATENT",
"link": 12
"link": 10
}
],
"outputs": [
@@ -537,7 +482,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
13
11
],
"slot_index": 0
}
@@ -556,7 +501,7 @@
]
},
{
"id": 15,
"id": 13,
"type": "VAEDecode",
"pos": [
1560,
@@ -564,21 +509,23 @@
],
"size": [
320,
108
72
],
"flags": {},
"order": 14,
"flags": {
"collapsed": true
},
"order": 12,
"mode": 0,
"inputs": [
{
"name": "samples",
"type": "LATENT",
"link": 13
"link": 11
},
{
"name": "vae",
"type": "VAE",
"link": 14
"link": 12
}
],
"outputs": [
@@ -586,7 +533,7 @@
"name": "IMAGE",
"type": "IMAGE",
"links": [
15
13
],
"slot_index": 0
}
@@ -597,24 +544,24 @@
"widgets_values": []
},
{
"id": 16,
"id": 14,
"type": "SaveImage",
"pos": [
1560,
216
156
],
"size": [
320,
112
84
],
"flags": {},
"order": 15,
"order": 13,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 15
"link": 13
}
],
"outputs": [],
@@ -656,94 +603,78 @@
8,
0,
9,
0,
1,
"STRING"
],
[
5,
8,
1,
10,
0,
"STRING"
],
[
6,
8,
0,
11,
1,
"STRING"
],
[
7,
4,
0,
11,
9,
0,
"CLIP"
],
[
8,
6,
3,
0,
14,
12,
0,
"MODEL"
],
[
7,
9,
11,
0,
14,
12,
1,
"CONDITIONING"
],
[
8,
9,
0,
10,
0,
"CONDITIONING"
],
[
9,
10,
0,
12,
2,
"CONDITIONING"
],
[
10,
11,
0,
12,
0,
"CONDITIONING"
3,
"LATENT"
],
[
11,
12,
0,
14,
2,
"CONDITIONING"
13,
0,
"LATENT"
],
[
12,
13,
0,
14,
3,
"LATENT"
],
[
13,
14,
0,
15,
0,
"LATENT"
],
[
14,
5,
0,
15,
13,
1,
"VAE"
],
[
15,
15,
13,
13,
0,
16,
14,
0,
"IMAGE"
]
+106 -175
View File
@@ -1,6 +1,6 @@
{
"last_node_id": 21,
"last_link_id": 20,
"last_node_id": 19,
"last_link_id": 18,
"nodes": [
{
"id": 1,
@@ -11,7 +11,7 @@
],
"size": [
320,
720
226
],
"flags": {},
"order": 0,
@@ -22,7 +22,7 @@
"Node name for S&R": "Note"
},
"widgets_values": [
"Inside the style \u2014 the Facets node.\nApply gives you one prompt string. Facets gives you the style's sections one output at a time \u2014 24 of them, exactly the sections you see on the style board at styleref.io, plus the six custom items.\nSix are previewed here so you can read them. Every other output is on the node too; drag any of them into a text input.\nThey are plain STRINGs, so they go anywhere text goes: a second CLIP encoder for regional conditioning, an IPAdapter or ControlNet prompt, a LoRA trigger line, or your own nodes. That is the escape hatch \u2014 use the palette without taking the whole prompt.\nThe render alongside is the paved road (Apply), so you can compare the assembled prompt against the parts it was built from.\n\nZ-Image Turbo (S3-DiT). Three model files download on first use: the UNET (diffusion_models/), the Qwen text encoder (text_encoders/), and the VAE (vae/).\nSampler defaults are turbo: 8 steps, CFG 1.0, euler/simple.\nZ-Image takes no negative prompt. The model runs without classifier-free guidance, so there is no negative encoder on this canvas \u2014 the sampler's negative input gets a zeroed conditioning. StyleRef still compiles the negative and previews it; put anything you need from it into `subject` on Apply as a positive phrase (\"fully clothed\", \"no text or watermark\"). Raising CFG does not bring the negative back.\nStyle prompts use the `diffusion` target \u2014 Z-Image reads the same tag-weighted output SDXL/SD1.5 use."
"Inside a style: Facets emits each of its 24 sections as its own STRING.\nSix are previewed here; drag any output into any text input \u2014 a second encoder, an IPAdapter prompt, a LoRA trigger.\nApply and the sampler alongside render the whole assembled prompt.\nFirst queue downloads 3 files: UNET, Qwen text encoder, VAE."
],
"title": "Facets on Z-Image"
},
@@ -31,11 +31,11 @@
"type": "StyleRefLoad",
"pos": [
40,
828
342
],
"size": [
320,
248
348
],
"flags": {},
"order": 1,
@@ -75,11 +75,11 @@
"type": "UNETLoader",
"pos": [
40,
1124
746
],
"size": [
320,
140
108
],
"flags": {},
"order": 2,
@@ -90,7 +90,7 @@
"name": "MODEL",
"type": "MODEL",
"links": [
13
11
],
"slot_index": 0
}
@@ -116,11 +116,11 @@
"type": "CLIPLoader",
"pos": [
40,
1312
910
],
"size": [
320,
168
140
],
"flags": {},
"order": 3,
@@ -131,7 +131,7 @@
"name": "CLIP",
"type": "CLIP",
"links": [
12
10
],
"slot_index": 0
}
@@ -158,11 +158,11 @@
"type": "VAELoader",
"pos": [
40,
1528
1106
],
"size": [
320,
112
80
],
"flags": {},
"order": 4,
@@ -173,7 +173,7 @@
"name": "VAE",
"type": "VAE",
"links": [
19
17
],
"slot_index": 0
}
@@ -202,7 +202,7 @@
],
"size": [
320,
636
624
],
"flags": {},
"order": 5,
@@ -387,7 +387,7 @@
],
"size": [
320,
84
152
],
"flags": {},
"order": 6,
@@ -411,11 +411,11 @@
"type": "PreviewAny",
"pos": [
800,
192
268
],
"size": [
320,
84
152
],
"flags": {},
"order": 7,
@@ -439,11 +439,11 @@
"type": "PreviewAny",
"pos": [
800,
324
476
],
"size": [
320,
84
152
],
"flags": {},
"order": 8,
@@ -467,11 +467,11 @@
"type": "PreviewAny",
"pos": [
800,
456
684
],
"size": [
320,
84
152
],
"flags": {},
"order": 9,
@@ -495,11 +495,11 @@
"type": "PreviewAny",
"pos": [
800,
588
892
],
"size": [
320,
84
152
],
"flags": {},
"order": 10,
@@ -523,11 +523,11 @@
"type": "PreviewAny",
"pos": [
800,
720
1100
],
"size": [
320,
84
152
],
"flags": {},
"order": 11,
@@ -555,7 +555,7 @@
],
"size": [
320,
424
380
],
"flags": {},
"order": 12,
@@ -572,17 +572,14 @@
"name": "positive",
"type": "STRING",
"links": [
9,
11
9
],
"slot_index": 0
},
{
"name": "negative",
"type": "STRING",
"links": [
10
],
"links": [],
"slot_index": 1
},
{
@@ -606,62 +603,6 @@
},
{
"id": 14,
"type": "PreviewAny",
"pos": [
1180,
532
],
"size": [
320,
84
],
"flags": {},
"order": 13,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 9
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled positive"
},
{
"id": 15,
"type": "PreviewAny",
"pos": [
1180,
664
],
"size": [
320,
84
],
"flags": {},
"order": 14,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 10
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"title": "Compiled negative"
},
{
"id": 16,
"type": "CLIPTextEncode",
"pos": [
1560,
@@ -669,21 +610,23 @@
],
"size": [
320,
198
116
],
"flags": {},
"order": 15,
"flags": {
"collapsed": true
},
"order": 13,
"mode": 0,
"inputs": [
{
"name": "clip",
"type": "CLIP",
"link": 12
"link": 10
},
{
"name": "text",
"type": "STRING",
"link": 11
"link": 9
}
],
"outputs": [
@@ -691,8 +634,8 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
14,
15
12,
13
],
"slot_index": 0
}
@@ -706,24 +649,26 @@
"title": "Positive (from StyleRef)"
},
{
"id": 17,
"id": 15,
"type": "ConditioningZeroOut",
"pos": [
1560,
306
156
],
"size": [
320,
84
48
],
"flags": {},
"order": 16,
"flags": {
"collapsed": true
},
"order": 14,
"mode": 0,
"inputs": [
{
"name": "conditioning",
"type": "CONDITIONING",
"link": 15
"link": 13
}
],
"outputs": [
@@ -731,7 +676,7 @@
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
16
14
],
"slot_index": 0
}
@@ -743,18 +688,18 @@
"title": "Z-Image has no negative"
},
{
"id": 18,
"id": 16,
"type": "EmptySD3LatentImage",
"pos": [
1560,
438
252
],
"size": [
320,
168
144
],
"flags": {},
"order": 17,
"order": 15,
"mode": 0,
"inputs": [],
"outputs": [
@@ -762,7 +707,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
17
15
],
"slot_index": 0
}
@@ -777,7 +722,7 @@
]
},
{
"id": 19,
"id": 17,
"type": "KSampler",
"pos": [
1940,
@@ -785,31 +730,31 @@
],
"size": [
320,
352
312
],
"flags": {},
"order": 18,
"order": 16,
"mode": 0,
"inputs": [
{
"name": "model",
"type": "MODEL",
"link": 13
"link": 11
},
{
"name": "positive",
"type": "CONDITIONING",
"link": 14
"link": 12
},
{
"name": "negative",
"type": "CONDITIONING",
"link": 16
"link": 14
},
{
"name": "latent_image",
"type": "LATENT",
"link": 17
"link": 15
}
],
"outputs": [
@@ -817,7 +762,7 @@
"name": "LATENT",
"type": "LATENT",
"links": [
18
16
],
"slot_index": 0
}
@@ -836,7 +781,7 @@
]
},
{
"id": 20,
"id": 18,
"type": "VAEDecode",
"pos": [
2320,
@@ -844,21 +789,23 @@
],
"size": [
320,
108
72
],
"flags": {},
"order": 19,
"flags": {
"collapsed": true
},
"order": 17,
"mode": 0,
"inputs": [
{
"name": "samples",
"type": "LATENT",
"link": 18
"link": 16
},
{
"name": "vae",
"type": "VAE",
"link": 19
"link": 17
}
],
"outputs": [
@@ -866,7 +813,7 @@
"name": "IMAGE",
"type": "IMAGE",
"links": [
20
18
],
"slot_index": 0
}
@@ -877,24 +824,24 @@
"widgets_values": []
},
{
"id": 21,
"id": 19,
"type": "SaveImage",
"pos": [
2320,
216
156
],
"size": [
320,
112
84
],
"flags": {},
"order": 20,
"order": 18,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 20
"link": 18
}
],
"outputs": [],
@@ -976,94 +923,78 @@
13,
0,
14,
0,
1,
"STRING"
],
[
10,
13,
1,
15,
0,
"STRING"
],
[
11,
13,
0,
16,
1,
"STRING"
],
[
12,
4,
0,
16,
14,
0,
"CLIP"
],
[
13,
11,
3,
0,
19,
17,
0,
"MODEL"
],
[
12,
14,
16,
0,
19,
17,
1,
"CONDITIONING"
],
[
13,
14,
0,
15,
0,
"CONDITIONING"
],
[
14,
15,
0,
17,
2,
"CONDITIONING"
],
[
15,
16,
0,
17,
0,
"CONDITIONING"
3,
"LATENT"
],
[
16,
17,
0,
19,
2,
"CONDITIONING"
18,
0,
"LATENT"
],
[
17,
18,
0,
19,
3,
"LATENT"
],
[
18,
19,
0,
20,
0,
"LATENT"
],
[
19,
5,
0,
20,
18,
1,
"VAE"
],
[
20,
20,
18,
18,
0,
21,
19,
0,
"IMAGE"
]