diff --git a/docs/src/content/docs/features/krea-2.mdx b/docs/src/content/docs/features/krea-2.mdx
index 4346c935142..ae3432f1fe7 100644
--- a/docs/src/content/docs/features/krea-2.mdx
+++ b/docs/src/content/docs/features/krea-2.mdx
@@ -1,7 +1,7 @@
---
title: Krea-2
-description: Generate images with the Krea-2 text-to-image models (Turbo and Raw), including the GGUF / single-file workflow and the conditioning enhancers.
-lastUpdated: 2026-07-30
+description: Generate images with the Krea-2 text-to-image models (Turbo and Raw), including the GGUF / single-file workflow, the conditioning enhancers and training-free style reference.
+lastUpdated: 2026-08-20
sidebar:
order: 5
---
@@ -91,6 +91,35 @@ Reducing image resolution or disabling regional prompting is the practical fallb
is skipped on unsupported hardware and cannot exercise every GPU/backend combination.
:::
+## Style reference
+
+Krea-2 can transfer the *look* of a reference image — palette, texture, rendering — while the prompt keeps
+driving the content. There is **no adapter model and no LoRA**: the reference's attention keys and values
+are spliced into the target's, so it works with any Krea-2 checkpoint out of the box.
+
+On the canvas, add a **Reference Image** while a Krea-2 model is selected, pick an image, and set **Style
+Strength**. In the workflow editor the same thing is the **Style Reference - Krea-2** node, feeding the
+**Style Reference** input of **Denoise - Krea-2**.
+
+- **Style Strength** is the one knob you need. `1.0` is the recommended setting; the slider goes to `2.0`
+ for a heavier effect. `0` disables the reference entirely and costs nothing.
+- The remaining node inputs (block range, key/value scaling, AdaIN strengths) are for tuning and should be
+ left at their defaults. Style Strength already modulates several of them.
+- Style Strength is recorded in image metadata, so you can see what a given image was generated with. It has
+ no recall button of its own — the reference image itself is not part of the metadata.
+
+:::caution[One reference, matching size, roughly 2x runtime]
+- **Exactly one** reference image is used. If several are enabled on the canvas, only the first is applied
+ and the others are flagged with a warning.
+- The reference must be encoded at **the same width and height as the denoise node** — its image tokens are
+ appended to the target's. On the canvas this is wired up for you. In the workflow editor, set the same
+ width and height on both nodes, or the denoise node will refuse the reference.
+- Every step runs **one extra transformer pass** for the reference, so generation takes roughly **twice as
+ long**.
+- The reference's keys and values are retained for the whole step: about **0.5 GB at 1024²** and **1.7 GB at
+ 2560×1440**. At 1440p that no longer fits on a 24 GB card alongside the model.
+:::
+
## LoRA
Krea-2 LoRAs (diffusers PEFT format) are supported and apply to both the transformer and — where the
diff --git a/invokeai/app/invocations/fields.py b/invokeai/app/invocations/fields.py
index 3826a340012..659e6aa4640 100644
--- a/invokeai/app/invocations/fields.py
+++ b/invokeai/app/invocations/fields.py
@@ -1,5 +1,5 @@
from enum import Enum
-from typing import Any, Callable, Optional, Tuple
+from typing import Any, Callable, Literal, Optional, Tuple
from pydantic import BaseModel, ConfigDict, Field, RootModel, TypeAdapter
from pydantic.fields import _Unset
@@ -398,6 +398,42 @@ class Krea2ConditioningField(BaseModel):
)
+class Krea2StyleReferenceField(BaseModel):
+ """Style-reference conditioning for Krea-2 shared-KV reference attention.
+
+ Carries the VAE-encoded reference latents plus the tuning parameters that shape how strongly, and in
+ which frequency bands, the reference influences the target. The reference must be encoded at exactly
+ the denoise node's resolution, so the dims travel with it for an early, legible mismatch error.
+
+ Only ``style_strength`` is meant for everyday use; it modulates several of the others. The remainder
+ are exposed for tuning and should be left at their defaults.
+ """
+
+ reference_latents_name: str = Field(description="Name of the saved [1, 16, 1, H/8, W/8] reference latents.")
+ width: int = Field(description="Image width the reference was encoded at (must match denoise width).")
+ height: int = Field(description="Image height the reference was encoded at (must match denoise height).")
+ style_strength: float = Field(
+ default=1.0,
+ description="Overall style strength. 0 makes the denoise node skip the reference entirely.",
+ )
+ blocks: str = Field(default="7-27", description="Transformer blocks the reference is injected into.")
+ ref_k_strength: float = Field(default=1.06, description="Multiplier on the reference key path.")
+ adain_strength: float = Field(default=0.85, description="Reference statistics applied to the target Q/K.")
+ value_mode: Literal["target", "raw_reference", "ref_mean", "target_adain", "target_adain_plus_ref"] = Field(
+ default="target_adain_plus_ref", description="How the reference value vectors are constructed."
+ )
+ value_adain_strength: float = Field(
+ default=0.65,
+ description="Reference statistics applied to the target value path. Has no effect while ref_value_mix is 1.0.",
+ )
+ ref_value_mix: float = Field(default=1.0, description="How much raw reference value signal is kept.")
+ high_scale_start: float = Field(default=1.04, description="High-frequency reference key scale at step 0.")
+ high_scale_end: float = Field(default=0.0, description="High-frequency reference key scale at the last step.")
+ low_scale_start: float = Field(default=1.0, description="Low-frequency reference key scale at step 0.")
+ low_scale_end: float = Field(default=1.10, description="Low-frequency reference key scale at the last step.")
+ beta: float = Field(default=2.5, description="Exponent of the high-to-low frequency falloff curve.")
+
+
class AnimaConditioningField(BaseModel):
"""An Anima conditioning tensor primitive value.
diff --git a/invokeai/app/invocations/krea2_denoise.py b/invokeai/app/invocations/krea2_denoise.py
index 466568d5050..eacc6cc6633 100644
--- a/invokeai/app/invocations/krea2_denoise.py
+++ b/invokeai/app/invocations/krea2_denoise.py
@@ -1,8 +1,8 @@
import json
import math
-from contextlib import ExitStack
+from contextlib import ExitStack, nullcontext
from pathlib import Path
-from typing import Callable, Iterator, Optional
+from typing import Any, Callable, Iterator, Optional
import torch
import torchvision.transforms as tv_transforms
@@ -18,6 +18,7 @@
Input,
InputField,
Krea2ConditioningField,
+ Krea2StyleReferenceField,
LatentsField,
WithBoard,
WithMetadata,
@@ -42,6 +43,7 @@
prepare_position_ids,
unpack_latents,
)
+from invokeai.backend.krea2.style_reference_extension import Krea2StyleReferenceExtension
from invokeai.backend.model_manager.taxonomy import BaseModelType, ModelFormat
from invokeai.backend.patches.layer_patcher import LayerPatcher, PatchSpec
from invokeai.backend.patches.lora_conversions.krea2_lora_constants import KREA2_LORA_TRANSFORMER_PREFIX
@@ -60,7 +62,7 @@
title="Denoise - Krea-2",
tags=["image", "krea2", "krea-2"],
category="image",
- version="1.2.0",
+ version="1.3.0",
classification=Classification.Prototype,
)
class Krea2DenoiseInvocation(BaseInvocation, WithMetadata, WithBoard):
@@ -97,6 +99,23 @@ class Krea2DenoiseInvocation(BaseInvocation, WithMetadata, WithBoard):
description="Override the resolution-aware timestep shift (mu). Leave unset to use the model default "
"(mu=1.15 for the distilled Turbo checkpoint).",
)
+ style_reference: Optional[Krea2StyleReferenceField] = InputField(
+ default=None,
+ description="Training-free style reference. Adds one reference forward per step, so generation "
+ "takes roughly twice as long, and retains the reference's attention keys/values for the whole "
+ "step (~0.5 GB at 1024x1024, ~1.7 GB at 2560x1440). At 1440p the combined footprint no longer "
+ "fits a 24 GB card alongside the model. A style_strength of 0 is ignored entirely and costs "
+ "nothing.",
+ input=Input.Connection,
+ title="Style Reference",
+ )
+ style_reference_conditioning: Optional[Krea2ConditioningField] = InputField(
+ default=None,
+ description="Prompt for the style-reference pass. Leave unconnected to reuse the positive prompt; "
+ "a short neutral prompt describing the reference can give a purer style transfer.",
+ input=Input.Connection,
+ title="Style Reference Prompt",
+ )
@field_validator("cfg_scale")
@classmethod
@@ -397,6 +416,43 @@ def _run_diffusion(self, context: InvocationContext):
init_latents=init_latents, inpaint_mask=inpaint_mask, noise=noise
)
+ # Style reference: load + validate before the transformer is placed, so a size mismatch fails
+ # before we have spent anything on the model.
+ style_extension: Krea2StyleReferenceExtension | None = None
+ style_ref_prompt_embeds = None
+ style_ref_position_ids = None
+ # A style strength of 0 is documented as disabling the reference, so treat it as if nothing were
+ # connected: no latents load, no K/V cache, no capture pass, no working-memory reservation. Running
+ # the machinery for a mix of 0 would roughly double generation time for no visible effect.
+ if self.style_reference is not None and self.style_reference.style_strength > 0:
+ style_extension = Krea2StyleReferenceExtension.from_field(
+ context,
+ self.style_reference,
+ denoise_width=self.width,
+ denoise_height=self.height,
+ dtype=inference_dtype,
+ device=device,
+ )
+ if self.style_reference_conditioning is not None:
+ style_ref_extension = self._load_text_conditioning(
+ context,
+ self.style_reference_conditioning,
+ grid_height,
+ grid_width,
+ inference_dtype,
+ device,
+ )
+ style_ref_prompt_embeds = style_ref_extension.regional_text_conditioning.prompt_embeds
+ style_ref_position_ids = prepare_position_ids(
+ style_ref_prompt_embeds.shape[1], grid_height, grid_width, device
+ )
+ else:
+ # Reusing the positive conditioning costs nothing and needs no extra encode. A dedicated,
+ # neutral reference prompt is exposed as an override because it measurably changes how much
+ # of the reference's *subject* bleeds into the style.
+ style_ref_prompt_embeds = pos_prompt_embeds
+ style_ref_position_ids = position_ids
+
step_callback = self._build_step_callback(context)
step_callback(
PipelineIntermediateState(
@@ -428,6 +484,9 @@ def _run_diffusion(self, context: InvocationContext):
regional_attention_mask_bytes=self._regional_attention_mask_bytes(
pos_extension, neg_extension, inference_dtype
),
+ style_reference_kv_bytes=(
+ style_extension.kv_cache_bytes(inference_dtype) if style_extension is not None else 0
+ ),
)
with ExitStack() as exit_stack:
@@ -435,15 +494,9 @@ def _run_diffusion(self, context: InvocationContext):
transformer_info.model_on_device(working_mem_bytes=estimated_working_memory)
)
- # Krea-2 uses grouped-query attention (48 query / 12 KV heads). The stock attention processor asks
- # SDPA for enable_gqa=True, which PyTorch only supports on the math backend — that materializes the
- # full O(seq^2) score matrix (~5.7 GB per attention at 1280x720, ~40 GB at 2560x1440) and OOMs. Swap
- # in a memory-efficient processor that expands the KV heads and uses the O(seq) SDPA kernel instead.
- regional_prompting_state = Krea2RegionalPromptingState()
- transformer.set_attn_processor(build_krea2_attention_processors(transformer, regional_prompting_state))
- # The processors remain installed on the cached transformer after this invocation. Do not let them
- # retain a potentially multi-GB regional mask between generations, including when denoising raises.
- exit_stack.callback(regional_prompting_state.set_attention_mask, None)
+ attention_state = self._install_attention_processors(transformer, exit_stack)
+ if style_extension is not None:
+ self._install_style_reference_processors(transformer, exit_stack, attention_state, style_extension)
exit_stack.enter_context(
LayerPatcher.apply_smart_model_patches(
@@ -456,38 +509,67 @@ def _run_diffusion(self, context: InvocationContext):
)
)
- pos_regional_attention_mask = pos_extension.get_attention_mask()
- neg_regional_attention_mask = neg_extension.get_attention_mask() if neg_extension is not None else None
+ pos_attention_payload = self._build_attention_payload(pos_extension, inference_dtype)
+ neg_attention_payload = (
+ self._build_attention_payload(neg_extension, inference_dtype) if neg_extension is not None else None
+ )
+
+ if style_extension is not None:
+ # Built after the LoRA patcher so the reference trajectory is anchored to the same weights
+ # the sampler will use.
+ style_extension.prepare([sigma.item() for sigma in sigmas_sched[:total_steps]])
for step_idx, t in enumerate(tqdm(timesteps_sched)):
# The pipeline passes timestep / num_train_timesteps to the transformer.
timestep = (t / num_train_timesteps).expand(latents.shape[0]).to(inference_dtype)
- regional_prompting_state.set_attention_mask(pos_regional_attention_mask)
- noise_pred_cond = transformer(
- hidden_states=latents,
- encoder_hidden_states=pos_prompt_embeds,
- encoder_attention_mask=None,
- timestep=timestep,
- position_ids=position_ids,
- return_dict=False,
- )[0]
-
- if self._should_apply_cfg_for_step(
- cfg_scale[step_idx], has_negative_conditioning=neg_prompt_embeds is not None
- ):
- regional_prompting_state.set_attention_mask(neg_regional_attention_mask)
- noise_pred_uncond = transformer(
+ style_pass = nullcontext()
+ if style_extension is not None:
+ # Pass A: run the reference alone and stash its image-token K/V. It never sees the
+ # target, so this is equivalent to upstream's doubled batch — see style_reference.py.
+ self._install_attention_payload(attention_state, None)
+ with style_extension.capture():
+ transformer(
+ hidden_states=style_extension.reference_latents_for_step(step_idx),
+ encoder_hidden_states=style_ref_prompt_embeds,
+ encoder_attention_mask=None,
+ timestep=timestep,
+ position_ids=style_ref_position_ids,
+ return_dict=False,
+ )
+ style_pass = style_extension.inject(
+ Krea2StyleReferenceExtension.progress_for_step(step_idx, total_steps)
+ )
+
+ # Pass B: the target. CFG runs inside the same injection — styling only the conditional
+ # pass would make CFG amplify (styled_cond - plain_uncond), which overshoots badly above
+ # cfg ~4. The single reference pass above is shared by both.
+ with style_pass:
+ self._install_attention_payload(attention_state, pos_attention_payload)
+ noise_pred_cond = transformer(
hidden_states=latents,
- encoder_hidden_states=neg_prompt_embeds,
+ encoder_hidden_states=pos_prompt_embeds,
encoder_attention_mask=None,
timestep=timestep,
- position_ids=neg_position_ids,
+ position_ids=position_ids,
return_dict=False,
)[0]
- noise_pred = noise_pred_uncond + cfg_scale[step_idx] * (noise_pred_cond - noise_pred_uncond)
- else:
- noise_pred = noise_pred_cond
+
+ if self._should_apply_cfg_for_step(
+ cfg_scale[step_idx], has_negative_conditioning=neg_prompt_embeds is not None
+ ):
+ self._install_attention_payload(attention_state, neg_attention_payload)
+ noise_pred_uncond = transformer(
+ hidden_states=latents,
+ encoder_hidden_states=neg_prompt_embeds,
+ encoder_attention_mask=None,
+ timestep=timestep,
+ position_ids=neg_position_ids,
+ return_dict=False,
+ )[0]
+ noise_pred = noise_pred_uncond + cfg_scale[step_idx] * (noise_pred_cond - noise_pred_uncond)
+ else:
+ noise_pred = noise_pred_cond
# Euler step using the (possibly clipped) sigma schedule.
sigma_curr = sigmas_sched[step_idx]
@@ -519,6 +601,86 @@ def _run_diffusion(self, context: InvocationContext):
latents = latents.unsqueeze(2)
return latents
+ def _install_attention_processors(
+ self, transformer: torch.nn.Module, exit_stack: ExitStack
+ ) -> Krea2RegionalPromptingState:
+ """Swap in the memory-efficient attention processors and return the state they share.
+
+ Krea-2 uses grouped-query attention (48 query / 12 KV heads). The stock attention processor asks
+ SDPA for enable_gqa=True, which PyTorch only supports on the math backend — that materializes the
+ full O(seq^2) score matrix (~5.7 GB per attention at 1280x720, ~40 GB at 2560x1440) and OOMs. The
+ replacement expands the KV heads and uses the O(seq) SDPA kernel instead.
+
+ Extension point: subclasses may install their own processors and a richer state object here, as
+ long as the state still carries the attention mask this node installs per pass.
+
+ The signature is part of that contract — style reference deliberately does *not* extend it, and
+ installs itself in ``_install_style_reference_processors`` instead.
+ """
+ state = Krea2RegionalPromptingState()
+ transformer.set_attn_processor(build_krea2_attention_processors(transformer, state))
+ # The processors remain installed on the cached transformer after this invocation. Do not let them
+ # retain a potentially multi-GB regional mask between generations, including when denoising raises.
+ exit_stack.callback(self._clear_attention_state, state)
+ return state
+
+ def _install_style_reference_processors(
+ self,
+ transformer: torch.nn.Module,
+ exit_stack: ExitStack,
+ attention_state: Krea2RegionalPromptingState,
+ style_extension: Krea2StyleReferenceExtension,
+ ) -> None:
+ """Re-install the processors so the styled blocks also carry the style-reference state.
+
+ Kept out of ``_install_attention_processors`` on purpose. Subclasses (the prompt-weighting node
+ pack, for one) override that seam with their own state type and their own processors; widening
+ its signature would break every generation they run, style reference or not.
+
+ Because this replaces whatever that seam installed, it is only valid when the seam has *not* been
+ overridden — hence the explicit refusal below rather than silently discarding the subclass's
+ processors.
+ """
+ if type(self)._install_attention_processors is not Krea2DenoiseInvocation._install_attention_processors:
+ raise ValueError(
+ f"'{type(self).__name__}' installs its own Krea-2 attention processors, which style reference "
+ "would replace. Use the stock 'Denoise - Krea-2' node for style reference."
+ )
+
+ style_state = style_extension.build_state(transformer)
+ transformer.set_attn_processor(
+ build_krea2_attention_processors(
+ transformer,
+ attention_state,
+ style_reference_state=style_state,
+ style_reference_blocks=style_extension.block_indices,
+ )
+ )
+ # Same hazard as the regional mask, an order of magnitude larger: the captured reference K/V run
+ # to ~1.7 GiB at 2560x1440 and would otherwise stay on the cached transformer.
+ exit_stack.callback(style_state.clear)
+
+ @staticmethod
+ def _clear_attention_state(state: Krea2RegionalPromptingState) -> None:
+ """Drop every tensor the shared attention state retains. Override alongside the state object."""
+ state.set_attention_mask(None)
+
+ def _build_attention_payload(self, extension: Krea2RegionalPromptingExtension, inference_dtype: torch.dtype) -> Any:
+ """Build the per-conditioning attention payload once, before the denoise loop.
+
+ Returns the regional attention mask (or None). Subclasses may return a richer payload; whatever
+ comes back is handed straight to ``_install_attention_payload`` before the matching pass.
+ """
+ return extension.get_attention_mask()
+
+ @staticmethod
+ def _install_attention_payload(state: Krea2RegionalPromptingState, payload: Any) -> None:
+ """Install one conditioning's payload for the upcoming transformer call.
+
+ Called separately for the conditional and unconditional pass, so nothing leaks between them.
+ """
+ state.set_attention_mask(payload)
+
@staticmethod
def _regional_attention_mask_bytes(
pos_extension: Krea2RegionalPromptingExtension,
@@ -542,6 +704,7 @@ def _estimate_working_memory(
do_cfg: bool,
num_loras: int,
regional_attention_mask_bytes: int = 0,
+ style_reference_kv_bytes: int = 0,
) -> int:
"""Estimate peak transformer activation memory (bytes) so the model cache reserves enough headroom.
@@ -571,6 +734,17 @@ def _estimate_working_memory(
# transient buffers warrant a modest bump.
estimated = int(estimated * 1.1)
estimated += regional_attention_mask_bytes
+ if style_reference_kv_bytes > 0:
+ # The captured reference K/V stay resident for the whole target pass: two tensors per styled
+ # block, at the pre-expansion KV head count (12, not 48 — see style_reference.py). ~0.5 GiB at
+ # 1024x1024, ~1.7 GiB at 2560x1440. On top of that the styled attention runs with a key
+ # sequence of S + image_seq_len, and the reference forward briefly holds its own activations.
+ # Measured at 1024x1024 (8 steps, cfg 1.0): peak VRAM rises ~1.6 GiB over the unstyled run, of
+ # which ~0.5 GiB is the cache itself — so the activation term needs ~35%, not the 20% the
+ # arithmetic alone suggested. The captured K/V are an exact, known size, so they are added
+ # after the multiplier rather than scaled by it.
+ estimated = int(estimated * 1.35)
+ estimated += style_reference_kv_bytes
if num_loras > 0:
estimated += int(0.5 * num_loras * GB)
return estimated
diff --git a/invokeai/app/invocations/krea2_style_reference.py b/invokeai/app/invocations/krea2_style_reference.py
new file mode 100644
index 00000000000..3ee2d408fa3
--- /dev/null
+++ b/invokeai/app/invocations/krea2_style_reference.py
@@ -0,0 +1,230 @@
+"""VAE-encode a reference image into Krea-2 style-reference conditioning.
+
+Training-free style transfer: the reference image's attention keys/values are spliced into the target's
+in a band of transformer blocks, so the generation picks up the reference's palette, texture and
+rendering without picking up its content. Ported from
+https://github.com/nkxx188/ComfyUI-Krea2-StyleTransfer (MIT).
+
+The reference is encoded at exactly the denoise node's resolution -- its image tokens are appended to the
+target's and share the target's rotary embedding, so the token counts have to match.
+"""
+
+from typing import Literal
+
+import einops
+import torch
+from PIL import Image as PILImage
+
+from invokeai.app.invocations.baseinvocation import BaseInvocation, Classification, invocation
+from invokeai.app.invocations.fields import (
+ FieldDescriptions,
+ ImageField,
+ Input,
+ InputField,
+ Krea2StyleReferenceField,
+)
+from invokeai.app.invocations.model import VAEField
+from invokeai.app.invocations.primitives import Krea2StyleReferenceOutput
+from invokeai.app.invocations.qwen_image_image_to_latents import QwenImageImageToLatentsInvocation
+from invokeai.app.services.shared.invocation_context import InvocationContext
+from invokeai.backend.krea2.style_reference import KREA2_DEFAULT_STYLE_BLOCKS, KREA2_NUM_BLOCKS, parse_block_spec
+from invokeai.backend.stable_diffusion.diffusers_pipeline import image_resized_to_grid_as_tensor
+from invokeai.backend.util.devices import TorchDevice
+
+Krea2StyleReferenceFit = Literal["crop", "contain", "stretch"]
+
+
+def fit_image_to_box(image: PILImage.Image, width: int, height: int, fit: Krea2StyleReferenceFit) -> PILImage.Image:
+ """Resize a reference image to exactly ``width`` x ``height``.
+
+ ``crop`` scales to cover and center-crops (upstream's default -- it never introduces synthetic pixels,
+ which matters because everything in the reference feeds the style statistics). ``contain`` scales to
+ fit and letterboxes on white. ``stretch`` ignores the aspect ratio.
+ """
+ image = image.convert("RGB")
+ source_width, source_height = image.size
+ if source_width <= 0 or source_height <= 0:
+ raise ValueError("The style reference image has invalid dimensions.")
+
+ if fit == "stretch":
+ return image.resize((width, height), resample=PILImage.LANCZOS)
+
+ if fit == "crop":
+ scale = max(width / source_width, height / source_height)
+ scaled = image.resize(
+ (max(width, round(source_width * scale)), max(height, round(source_height * scale))),
+ resample=PILImage.LANCZOS,
+ )
+ left = (scaled.width - width) // 2
+ top = (scaled.height - height) // 2
+ return scaled.crop((left, top, left + width, top + height))
+
+ scale = min(width / source_width, height / source_height)
+ scaled = image.resize(
+ (max(1, min(width, round(source_width * scale))), max(1, min(height, round(source_height * scale)))),
+ resample=PILImage.LANCZOS,
+ )
+ canvas = PILImage.new("RGB", (width, height), (255, 255, 255))
+ canvas.paste(scaled, ((width - scaled.width) // 2, (height - scaled.height) // 2))
+ return canvas
+
+
+@invocation(
+ "krea2_style_reference",
+ title="Style Reference - Krea-2",
+ tags=["image", "conditioning", "krea2", "krea-2", "style"],
+ category="conditioning",
+ version="1.0.0",
+ classification=Classification.Prototype,
+)
+class Krea2StyleReferenceInvocation(BaseInvocation):
+ """Encode a reference image into Krea-2 style-reference conditioning.
+
+ Transfers the *look* of the reference image -- palette, texture, rendering -- while the prompt keeps
+ driving the content. No adapter model or LoRA is involved.
+
+ ``width`` and ``height`` must match the Krea-2 denoise node. Everything below ``style_strength`` is
+ for tuning and should be left at its default; ``style_strength`` already modulates several of them.
+ """
+
+ image: ImageField = InputField(description="Reference image whose style should be transferred.")
+ vae: VAEField = InputField(description=FieldDescriptions.vae, input=Input.Connection, title="VAE")
+ width: int = InputField(
+ default=1024,
+ gt=0,
+ multiple_of=16,
+ description="Width to encode the reference at (must match the denoise node's width).",
+ )
+ height: int = InputField(
+ default=1024,
+ gt=0,
+ multiple_of=16,
+ description="Height to encode the reference at (must match the denoise node's height).",
+ )
+ fit: Krea2StyleReferenceFit = InputField(
+ default="crop",
+ description="How to reconcile the reference's aspect ratio with the target size. 'crop' scales to "
+ "cover and center-crops, 'contain' letterboxes on white, 'stretch' distorts.",
+ )
+ style_strength: float = InputField(
+ default=1.0,
+ ge=0.0,
+ le=2.0,
+ description="Overall style strength. 1.0 is the recommended setting. 0 makes the denoise node ignore "
+ "the reference entirely - no capture pass, no retained keys/values - though this node still encodes "
+ "it; disconnect the node to skip that too.",
+ )
+ blocks: str = InputField(
+ default=KREA2_DEFAULT_STYLE_BLOCKS,
+ description="Transformer blocks to inject the reference into, e.g. '7-27'. Styling the earliest "
+ "blocks damages composition.",
+ ui_order=10,
+ )
+ ref_k_strength: float = InputField(
+ default=1.06,
+ ge=0.0,
+ le=5.0,
+ description="Multiplier on the reference key path. This is the knob that makes the style visible "
+ "without raising low_scale_end (which would also let reference content leak in).",
+ ui_order=11,
+ )
+ adain_strength: float = InputField(
+ default=0.85,
+ ge=0.0,
+ le=1.0,
+ description="How strongly the reference's query/key statistics are applied to the target.",
+ ui_order=12,
+ )
+ value_mode: Literal["target", "raw_reference", "ref_mean", "target_adain", "target_adain_plus_ref"] = InputField(
+ default="target_adain_plus_ref",
+ description="How the reference value vectors are built.",
+ ui_order=13,
+ )
+ value_adain_strength: float = InputField(
+ default=0.65,
+ ge=0.0,
+ le=1.5,
+ description="Reference statistics applied to the target value path. Has no effect while ref_value_mix is 1.0.",
+ ui_order=14,
+ )
+ ref_value_mix: float = InputField(
+ default=1.0,
+ ge=0.0,
+ le=1.0,
+ description="How much raw reference value signal is kept. Higher usually preserves style material.",
+ ui_order=15,
+ )
+ high_scale_start: float = InputField(
+ default=1.04,
+ description="Scale on the reference key's high-frequency bands at the first step.",
+ ui_order=16,
+ )
+ high_scale_end: float = InputField(
+ default=0.0,
+ description="Scale on the reference key's high-frequency bands at the last step. 0 decays them "
+ "away, which is what keeps reference content from leaking in.",
+ ui_order=17,
+ )
+ low_scale_start: float = InputField(
+ default=1.0,
+ description="Scale on the reference key's low-frequency bands at the first step.",
+ ui_order=18,
+ )
+ low_scale_end: float = InputField(
+ default=1.10,
+ description="Scale on the reference key's low-frequency bands at the last step. Raising this "
+ "strengthens the style but also invites content leakage and quality loss.",
+ ui_order=19,
+ )
+ beta: float = InputField(
+ default=2.5,
+ gt=0.0,
+ le=20.0,
+ description="Exponent of the high-to-low frequency falloff curve.",
+ ui_order=20,
+ )
+
+ @torch.no_grad()
+ def invoke(self, context: InvocationContext) -> Krea2StyleReferenceOutput:
+ # Fail on a malformed block spec here rather than several nodes later in the denoise loop.
+ parse_block_spec(self.blocks, KREA2_NUM_BLOCKS)
+
+ image = context.images.get_pil(self.image.image_name, "RGB")
+ image = fit_image_to_box(image, self.width, self.height, self.fit)
+
+ # multiple_of=16 keeps the post-VAE latents even, which the transformer's 2x2 patch packing needs.
+ # width/height are already multiples of 16, so this only converts and normalizes to [-1, 1].
+ image_tensor = image_resized_to_grid_as_tensor(image, multiple_of=16)
+ if image_tensor.dim() == 3:
+ image_tensor = einops.rearrange(image_tensor, "c h w -> 1 c h w")
+
+ vae_info = context.models.load(self.vae.vae)
+ context.util.signal_progress("VAE-encoding style reference")
+ # Reuse the Qwen-Image encoder: Krea-2 shares its VAE, and this already applies the per-channel
+ # latents_mean/latents_std normalization the transformer expects.
+ latents = QwenImageImageToLatentsInvocation.vae_encode(vae_info=vae_info, image_tensor=image_tensor)
+
+ latents = latents.detach().to("cpu")
+ # Release the encode intermediates before the denoise node partial-loads the transformer.
+ TorchDevice.empty_cache()
+ name = context.tensors.save(tensor=latents)
+
+ return Krea2StyleReferenceOutput.build(
+ Krea2StyleReferenceField(
+ reference_latents_name=name,
+ width=self.width,
+ height=self.height,
+ style_strength=self.style_strength,
+ blocks=self.blocks,
+ ref_k_strength=self.ref_k_strength,
+ adain_strength=self.adain_strength,
+ value_mode=self.value_mode,
+ value_adain_strength=self.value_adain_strength,
+ ref_value_mix=self.ref_value_mix,
+ high_scale_start=self.high_scale_start,
+ high_scale_end=self.high_scale_end,
+ low_scale_start=self.low_scale_start,
+ low_scale_end=self.low_scale_end,
+ beta=self.beta,
+ )
+ )
diff --git a/invokeai/app/invocations/krea2_text_encoder.py b/invokeai/app/invocations/krea2_text_encoder.py
index 40c1763ac8a..3207154020c 100644
--- a/invokeai/app/invocations/krea2_text_encoder.py
+++ b/invokeai/app/invocations/krea2_text_encoder.py
@@ -14,12 +14,7 @@
from invokeai.app.invocations.model import Qwen3VLEncoderField
from invokeai.app.invocations.primitives import Krea2ConditioningOutput
from invokeai.app.services.shared.invocation_context import InvocationContext
-from invokeai.backend.krea2.sampling_utils import (
- KREA2_MAX_SEQ_LEN,
- KREA2_NUM_SUFFIX_TOKENS,
- KREA2_SELECT_LAYERS,
- KREA2_START_IDX,
-)
+from invokeai.backend.krea2.text_encoding import encode_krea2_prompt
from invokeai.backend.model_manager.load.model_cache.utils import get_effective_device
from invokeai.backend.patches.layer_patcher import LayerPatcher, PatchSpec
from invokeai.backend.patches.lora_conversions.krea2_lora_constants import KREA2_LORA_QWEN3VL_PREFIX
@@ -30,15 +25,6 @@
)
from invokeai.backend.util.devices import TorchDevice
-# Prompt template from diffusers Krea2Pipeline.get_text_hidden_states. The prefix (a system turn that
-# instructs the model to describe the image) is the same "generate" template used by Qwen-Image, which
-# is why the first KREA2_START_IDX (34) tokens are dropped from the encoder output.
-_KREA2_PREFIX = (
- "<|im_start|>system\nDescribe the image by detailing the color, shape, size, texture, quantity, text, "
- "spatial relationships of the objects and background:<|im_end|>\n<|im_start|>user\n"
-)
-_KREA2_SUFFIX = "<|im_end|>\n<|im_start|>assistant\n"
-
@invocation(
"krea2_text_encoder",
@@ -84,14 +70,6 @@ def _encode(self, context: InvocationContext) -> tuple[torch.Tensor, torch.Tenso
tokenizer_info = context.models.load(self.qwen3_vl_encoder.tokenizer)
text_encoder_info = context.models.load(self.qwen3_vl_encoder.text_encoder)
- # diffusers tokenizes (prefix + prompt) and the assistant-turn suffix separately, then
- # concatenates - so the suffix always survives truncation. Building one string and truncating it
- # (right-truncation) drops the suffix for long (>~500-token) prompts, corrupting the trained token
- # layout that the fixed prefix-drop (KREA2_START_IDX) and suffix accounting depend on.
- body_text = _KREA2_PREFIX + self.prompt
- # Reserve room for the suffix (diffusers: max_sequence_length + start_idx - num_suffix_tokens).
- body_max_length = KREA2_MAX_SEQ_LEN + KREA2_START_IDX - KREA2_NUM_SUFFIX_TOKENS
-
context.util.signal_progress("Running Qwen3-VL text encoder")
with ExitStack() as exit_stack:
@@ -111,51 +89,7 @@ def _encode(self, context: InvocationContext) -> tuple[torch.Tensor, torch.Tenso
)
)
- body_inputs = tokenizer(
- body_text,
- max_length=body_max_length,
- truncation=True,
- padding="max_length",
- return_tensors="pt",
- )
- # Append the suffix AFTER truncation so it can never be cut, matching the reference layout.
- suffix_inputs = tokenizer(_KREA2_SUFFIX, return_tensors="pt")
- input_ids = torch.cat([body_inputs.input_ids, suffix_inputs.input_ids], dim=1).to(device=device)
- attention_mask = torch.cat([body_inputs.attention_mask, suffix_inputs.attention_mask], dim=1).to(
- device=device, dtype=torch.bool
- )
- # Padding sits between the prompt body and assistant suffix. Count only valid tokens when
- # assigning positions so the suffix receives the same mRoPE phase as it did during training.
- position_ids = (attention_mask.long().cumsum(dim=-1) - 1).clamp(min=0)
- position_ids = position_ids.unsqueeze(0).expand(3, -1, -1)
-
- outputs = text_encoder(
- input_ids=input_ids,
- attention_mask=attention_mask,
- position_ids=position_ids,
- output_hidden_states=True,
- use_cache=False,
- return_dict=True,
- )
-
- # Some VL models nest the language-model output; fall back to that if needed.
- hidden_states_tuple = getattr(outputs, "hidden_states", None)
- if hidden_states_tuple is None:
- lm_output = getattr(outputs, "language_model_outputs", None)
- hidden_states_tuple = getattr(lm_output, "hidden_states", None)
- if hidden_states_tuple is None:
- raise RuntimeError("Qwen3-VL encoder did not return hidden_states; cannot build Krea-2 conditioning.")
-
- # Stack the selected layers along a new layer axis: (B, seq, 12, hidden).
- stacked = torch.stack([hidden_states_tuple[i] for i in KREA2_SELECT_LAYERS], dim=2)
-
- # Drop the system-prompt prefix tokens.
- prompt_embeds = stacked[:, KREA2_START_IDX:]
- prompt_mask = attention_mask[:, KREA2_START_IDX:].bool()
-
- # Match the device-safe compute dtype used by the denoise loop (falls back from bf16 to
- # fp16/fp32 on devices without bf16 support) rather than forcing bfloat16.
- prompt_embeds = prompt_embeds.to(dtype=TorchDevice.choose_bfloat16_safe_dtype(device))
+ prompt_embeds, prompt_mask, _ = encode_krea2_prompt(self.prompt, tokenizer, text_encoder)
return prompt_embeds, prompt_mask
diff --git a/invokeai/app/invocations/primitives.py b/invokeai/app/invocations/primitives.py
index dfe44d0e6e9..3659981a377 100644
--- a/invokeai/app/invocations/primitives.py
+++ b/invokeai/app/invocations/primitives.py
@@ -26,6 +26,7 @@
Input,
InputField,
Krea2ConditioningField,
+ Krea2StyleReferenceField,
LatentsField,
OutputField,
QwenImageConditioningField,
@@ -588,6 +589,20 @@ def build(
)
+@invocation_output("krea2_style_reference_output")
+class Krea2StyleReferenceOutput(BaseInvocationOutput):
+ """Output of a Krea-2 style-reference encoder."""
+
+ style_reference: Krea2StyleReferenceField = OutputField(
+ description="Style-reference conditioning for Krea-2.",
+ title="Style Reference",
+ )
+
+ @classmethod
+ def build(cls, style_reference: Krea2StyleReferenceField) -> "Krea2StyleReferenceOutput":
+ return cls(style_reference=style_reference)
+
+
@invocation_output("conditioning_output")
class ConditioningOutput(BaseInvocationOutput):
"""Base class for nodes that output a single conditioning tensor"""
diff --git a/invokeai/backend/krea2/attention.py b/invokeai/backend/krea2/attention.py
index b7f96cd93f9..b79a9a4ef0a 100644
--- a/invokeai/backend/krea2/attention.py
+++ b/invokeai/backend/krea2/attention.py
@@ -15,13 +15,20 @@
import re
from dataclasses import dataclass
-from typing import Protocol
+from typing import Iterable, Protocol
import torch
import torch.nn.functional as F
from diffusers.models.embeddings import apply_rotary_emb
from torch.nn.attention import SDPBackend, sdpa_kernel
+from invokeai.backend.krea2.style_reference import (
+ Krea2StyleReferenceMode,
+ Krea2StyleReferenceState,
+ apply_style_reference,
+ capture_style_reference,
+)
+
# Prefer the memory-efficient kernel; fall back to flash (if the build has it) then math so we never hard-fail.
_KREA2_SDPA_BACKENDS = [SDPBackend.EFFICIENT_ATTENTION, SDPBackend.FLASH_ATTENTION, SDPBackend.MATH]
@@ -39,8 +46,17 @@ def set_attention_mask(self, attention_mask: torch.Tensor | None) -> None:
class Krea2MemoryEfficientAttnProcessor:
"""Drop-in replacement for ``Krea2AttnProcessor`` that avoids the ``enable_gqa`` math fallback."""
- def __init__(self, regional_prompting_state: Krea2RegionalPromptingState | None = None) -> None:
+ def __init__(
+ self,
+ regional_prompting_state: Krea2RegionalPromptingState | None = None,
+ style_reference_state: Krea2StyleReferenceState | None = None,
+ block_index: int | None = None,
+ ) -> None:
self.regional_prompting_state = regional_prompting_state
+ # Only set on blocks selected for style reference; None everywhere else, so an inactive block costs
+ # nothing beyond the identity check below.
+ self.style_reference_state = style_reference_state
+ self.block_index = block_index
def __call__(
self,
@@ -77,14 +93,48 @@ def __call__(
key = key.transpose(1, 2)
value = value.transpose(1, 2)
- # Expand K/V heads to the query head count so we can drop enable_gqa (which forces the math backend).
- if attn.num_heads != attn.num_kv_heads:
- repeats = attn.num_heads // attn.num_kv_heads
- key = key.repeat_interleave(repeats, dim=1)
- value = value.repeat_interleave(repeats, dim=1)
-
- with sdpa_kernel(_KREA2_SDPA_BACKENDS):
- hidden_states = F.scaled_dot_product_attention(query, key, value, attn_mask=attention_mask)
+ # Style reference hooks in here: after RoPE (so the captured keys carry their rotation) but before
+ # the GQA head expansion, which keeps the retained cache 4x smaller. See style_reference.py.
+ style_state = self.style_reference_state
+ style_mode = Krea2StyleReferenceMode.OFF if style_state is None else style_state.mode
+ injection = None
+ if style_state is not None and self.block_index is not None:
+ if style_mode is Krea2StyleReferenceMode.CAPTURE:
+ capture_style_reference(style_state, self.block_index, query, key, value)
+ elif style_mode is Krea2StyleReferenceMode.INJECT:
+ injection = apply_style_reference(style_state, self.block_index, query, key, value)
+
+ def attend(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor, mask: torch.Tensor | None) -> torch.Tensor:
+ # Expand K/V heads to the query head count so we can drop enable_gqa (which forces the math backend).
+ if attn.num_heads != attn.num_kv_heads:
+ repeats = attn.num_heads // attn.num_kv_heads
+ k = k.repeat_interleave(repeats, dim=1)
+ v = v.repeat_interleave(repeats, dim=1)
+ with sdpa_kernel(_KREA2_SDPA_BACKENDS):
+ return F.scaled_dot_product_attention(q, k, v, attn_mask=mask)
+
+ if injection is None:
+ hidden_states = attend(query, key, value, attention_mask)
+ else:
+ # The reference keys/values are appended along the token axis, so a regional mask has to grow
+ # with them.
+ hidden_states = attend(
+ injection.query,
+ injection.key,
+ injection.value,
+ style_state.pad_attention_mask(attention_mask),
+ )
+ if injection.attention_mix < 1.0:
+ # Blend against the same (AdaIN'd) query/key attending to the target's own tokens only.
+ # At the default style_strength of 1.0 this branch is dead and the second attention is skipped.
+ sequence_length = injection.query.shape[2]
+ native = attend(
+ injection.query,
+ injection.key[:, :, :sequence_length, :],
+ injection.value[:, :, :sequence_length, :],
+ attention_mask,
+ )
+ hidden_states = native * (1.0 - injection.attention_mix) + hidden_states * injection.attention_mix
# [B, H, S, D] -> [B, S, H, D] -> [B, S, H*D], matching Krea2AttnProcessor's output layout.
hidden_states = hidden_states.transpose(1, 2).flatten(2, 3)
@@ -100,13 +150,33 @@ def attn_processors(self) -> dict[str, object]: ...
def build_krea2_attention_processors(
transformer: _Krea2AttentionProcessorContainer,
regional_prompting_state: Krea2RegionalPromptingState,
+ style_reference_state: Krea2StyleReferenceState | None = None,
+ style_reference_blocks: Iterable[int] | None = None,
) -> dict[str, Krea2MemoryEfficientAttnProcessor]:
- """Build processors that apply regional masks to alternating main transformer blocks only."""
+ """Build processors that apply regional masks to alternating main transformer blocks only.
+
+ Style reference runs over its own, independent band of blocks (upstream's default is 7-27, i.e. both
+ parities), so it gets a second state object rather than sharing the regional one. Leaving both style
+ arguments unset reproduces the pre-style behaviour exactly.
+
+ The text-fusion blocks do not match the main-block pattern, so they never receive either state. That is
+ correct: they only ever see text tokens.
+ """
+ style_blocks = frozenset(style_reference_blocks or ())
processors: dict[str, Krea2MemoryEfficientAttnProcessor] = {}
for name in transformer.attn_processors:
match = re.fullmatch(r"transformer_blocks\.(\d+)\.attn\.processor", name)
block_index = int(match.group(1)) if match is not None else None
- state = regional_prompting_state if block_index is not None and block_index % 2 == 0 else None
- processors[name] = Krea2MemoryEfficientAttnProcessor(regional_prompting_state=state)
+ regional = regional_prompting_state if block_index is not None and block_index % 2 == 0 else None
+ style = (
+ style_reference_state
+ if style_reference_state is not None and block_index is not None and block_index in style_blocks
+ else None
+ )
+ processors[name] = Krea2MemoryEfficientAttnProcessor(
+ regional_prompting_state=regional,
+ style_reference_state=style,
+ block_index=block_index,
+ )
return processors
diff --git a/invokeai/backend/krea2/style_reference.py b/invokeai/backend/krea2/style_reference.py
new file mode 100644
index 00000000000..df15a1c20b0
--- /dev/null
+++ b/invokeai/backend/krea2/style_reference.py
@@ -0,0 +1,462 @@
+"""Training-free style reference (shared-KV reference attention) for Krea-2.
+
+Ported from https://github.com/nkxx188/ComfyUI-Krea2-StyleTransfer (MIT). The technique transfers the
+*look* of a reference image without transferring its content, and without any extra weights: the
+reference image is run through the transformer alongside the target, and in a band of transformer blocks
+the target queries additionally attend to the reference's image-token keys/values.
+
+InvokeAI runs this as **two passes** rather than upstream's doubled batch:
+
+1. ``CAPTURE`` -- the reference latent goes through the transformer alone. The processors of the styled
+ blocks stash the post-RoPE image-token K/V (plus Q/K token statistics).
+2. ``INJECT`` -- the target pass splices those K/V onto its own.
+
+This is mathematically identical: upstream's reference rows never attend to the target (its ``out_ref``
+uses only reference q/k/v), the cross-batch AdaIN writes only into the target rows, and no reduction
+spans both batch halves. Splitting the passes also sidesteps a real problem -- ``krea2_denoise`` *strips*
+padded text tokens instead of masking them, so the target and reference prompts have different sequence
+lengths and could not be batch-concatenated without re-padding both.
+
+Two deliberate deviations from upstream, both verified equivalent:
+
+* K/V are captured **before** the GQA head expansion (12 kv heads, not 48). ``repeat_interleave``
+ duplicates each head, so per-``(head, dim)`` token statistics are identical across a group, and the
+ frequency scale vector is per-``dim`` and therefore head-invariant. This is 4x smaller -- at 2560x1440
+ it is the difference between 1.7 GiB and 6.9 GiB of retained cache.
+* The RoPE axis dims come from ``transformer.config.axes_dims_rope`` rather than being re-derived from
+ the head dim by a heuristic. For Krea-2 both give ``(32, 48, 48)``.
+"""
+
+from __future__ import annotations
+
+from dataclasses import dataclass, field
+from enum import Enum
+from typing import Literal, Sequence
+
+import torch
+
+# Krea-2's transformer has 28 main blocks. Styling the earliest ones destroys structure, so upstream's
+# default band starts at 7.
+KREA2_NUM_BLOCKS = 28
+KREA2_DEFAULT_STYLE_BLOCKS = "7-27"
+
+Krea2StyleValueMode = Literal["target", "raw_reference", "ref_mean", "target_adain", "target_adain_plus_ref"]
+
+_ADAIN_EPS = 1e-6
+
+
+class Krea2StyleReferenceMode(Enum):
+ """Which side of the two-pass scheme the shared state is currently driving."""
+
+ OFF = "off"
+ CAPTURE = "capture"
+ INJECT = "inject"
+
+
+@dataclass(frozen=True)
+class Krea2StyleReferenceSettings:
+ """Upstream's ``recommended`` preset, the only combination its README claims is stable.
+
+ ``style_strength`` is a master knob rather than a plain mix: upstream pulls ``high_scale_start``,
+ ``low_scale_end`` and ``adain_strength`` toward neutral as it drops, *and* uses it as the
+ native/styled attention mix. See :func:`resolve_effective_settings`.
+
+ Note that at the recommended values ``value_adain_strength`` has no effect: ``value_mode`` is
+ ``target_adain_plus_ref`` and ``ref_value_mix`` is 1.0, so the reference value path returns the raw
+ reference values and discards the AdaIN'd blend it would otherwise mix in. It stays exposed because it
+ becomes live as soon as ``ref_value_mix`` is lowered.
+ """
+
+ style_strength: float = 1.0
+ ref_k_strength: float = 1.06
+ adain_strength: float = 0.85
+ value_mode: Krea2StyleValueMode = "target_adain_plus_ref"
+ value_adain_strength: float = 0.65
+ ref_value_mix: float = 1.0
+ high_scale_start: float = 1.04
+ high_scale_end: float = 0.0
+ low_scale_start: float = 1.0
+ low_scale_end: float = 1.10
+ beta: float = 2.5
+
+
+@dataclass(frozen=True)
+class Krea2StyleReferenceEffectiveSettings:
+ """:class:`Krea2StyleReferenceSettings` after ``style_strength`` has been folded in."""
+
+ ref_k_strength: float
+ adain_strength: float
+ value_mode: Krea2StyleValueMode
+ value_adain_strength: float
+ ref_value_mix: float
+ high_scale_start: float
+ high_scale_end: float
+ low_scale_start: float
+ low_scale_end: float
+ beta: float
+ attention_mix: float
+
+
+def resolve_effective_settings(settings: Krea2StyleReferenceSettings) -> Krea2StyleReferenceEffectiveSettings:
+ """Fold ``style_strength`` into the parameters it modulates.
+
+ Mirrors upstream exactly, including its asymmetry: only ``high_scale_start`` and ``low_scale_end`` are
+ modulated (not their ``*_end`` / ``*_start`` counterparts), and each factor saturates at a different
+ point. At ``style_strength == 1.0`` every effective value equals its configured value.
+ """
+ strength = max(0.0, float(settings.style_strength))
+ return Krea2StyleReferenceEffectiveSettings(
+ ref_k_strength=max(0.0, float(settings.ref_k_strength)),
+ adain_strength=max(0.0, min(1.0, float(settings.adain_strength) * min(strength, 1.25))),
+ value_mode=settings.value_mode,
+ value_adain_strength=max(0.0, min(1.5, float(settings.value_adain_strength))),
+ ref_value_mix=max(0.0, min(1.0, float(settings.ref_value_mix))),
+ high_scale_start=1.0 + (float(settings.high_scale_start) - 1.0) * min(strength, 1.5),
+ high_scale_end=float(settings.high_scale_end),
+ low_scale_start=float(settings.low_scale_start),
+ low_scale_end=1.0 + (float(settings.low_scale_end) - 1.0) * strength,
+ beta=float(settings.beta),
+ attention_mix=max(0.0, min(1.0, strength)),
+ )
+
+
+def parse_block_spec(spec: str, num_blocks: int = KREA2_NUM_BLOCKS) -> frozenset[int]:
+ """Parse a block selection like ``"7-27"``, ``"7-27,3"`` or ``"5"`` into block indices.
+
+ Unlike upstream this validates against the real block count, so a typo fails at graph time instead of
+ silently styling nothing.
+ """
+ active: set[int] = set()
+ for raw_part in str(spec or "").replace(";", ",").split(","):
+ part = raw_part.strip()
+ if not part:
+ continue
+ if "-" in part:
+ start_str, _, end_str = part.partition("-")
+ try:
+ start, end = int(start_str.strip()), int(end_str.strip())
+ except ValueError as exc:
+ raise ValueError(f"Invalid Krea-2 style block range {part!r}.") from exc
+ if end < start:
+ raise ValueError(f"Invalid Krea-2 style block range {part!r}: end is before start.")
+ active.update(range(start, end + 1))
+ else:
+ try:
+ active.add(int(part))
+ except ValueError as exc:
+ raise ValueError(f"Invalid Krea-2 style block index {part!r}.") from exc
+
+ if not active:
+ raise ValueError(f"Krea-2 style block spec {spec!r} selects no blocks.")
+ out_of_range = sorted(index for index in active if index < 0 or index >= num_blocks)
+ if out_of_range:
+ raise ValueError(
+ f"Krea-2 style block spec {spec!r} selects blocks {out_of_range}, but the transformer only has "
+ f"{num_blocks} blocks (0-{num_blocks - 1})."
+ )
+ return frozenset(active)
+
+
+def lerp_scales(settings: Krea2StyleReferenceEffectiveSettings, progress: float) -> tuple[float, float]:
+ """Interpolate the high/low frequency scales for a point in the sampling schedule."""
+ progress = max(0.0, min(1.0, float(progress)))
+ high = settings.high_scale_start + (settings.high_scale_end - settings.high_scale_start) * progress
+ low = settings.low_scale_start + (settings.low_scale_end - settings.low_scale_start) * progress
+ return high, low
+
+
+def build_rope_scale_vector(
+ axes_dims: Sequence[int],
+ high_scale: float,
+ low_scale: float,
+ beta: float,
+ device: torch.device,
+ dtype: torch.dtype,
+) -> torch.Tensor:
+ """Per-head-dim multiplier applied to the reference keys, shaped by the RoPE frequency layout.
+
+ ``Krea2RotaryPosEmbed`` builds its embedding by concatenating one ``get_1d_rotary_pos_embed`` block
+ per position axis with ``repeat_interleave_real=True``. Within an axis the *first* pair is therefore
+ the highest frequency, and each frequency occupies two consecutive dims -- hence the curve over pair
+ index from ``high_scale`` to ``low_scale``, and the ``repeat_interleave(2)``.
+
+ Axis 0 is the temporal axis. Every Krea-2 token sits at t=0, so its rotation is the identity and there
+ is no frequency structure to shape; it is held flat at ``low_scale``.
+
+ With the default ``high_scale_end=0.0`` the highest-frequency bands of the reference key decay to zero
+ across the schedule, which is what makes the reference contribute position-agnostic style rather than
+ spatially-located content.
+ """
+ head_dim = int(sum(int(dim) for dim in axes_dims))
+ if head_dim <= 0:
+ raise ValueError(f"axes_dims must sum to a positive head dim, got {list(axes_dims)}.")
+
+ def curve(pairs: int) -> torch.Tensor:
+ if pairs <= 1:
+ x = torch.zeros(max(pairs, 1), device=device, dtype=torch.float32)
+ else:
+ x = torch.linspace(0.0, 1.0, pairs, device=device, dtype=torch.float32)
+ return float(high_scale) + (float(low_scale) - float(high_scale)) * x.pow(float(beta))
+
+ pieces: list[torch.Tensor] = []
+ has_temporal_axis = len(axes_dims) >= 2
+ for axis_index, axis_dim in enumerate(int(dim) for dim in axes_dims):
+ pairs = axis_dim // 2
+ if pairs <= 0:
+ pieces.append(torch.ones(axis_dim, device=device, dtype=dtype))
+ continue
+ if has_temporal_axis and axis_index == 0:
+ pair_scales = torch.full((pairs,), float(low_scale), device=device, dtype=torch.float32)
+ else:
+ pair_scales = curve(pairs)
+ pieces.append(pair_scales.to(dtype=dtype).repeat_interleave(2))
+ if axis_dim % 2:
+ pieces.append(torch.ones(1, device=device, dtype=dtype))
+
+ return torch.cat(pieces, dim=0)[:head_dim]
+
+
+def _token_mean_std(x: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
+ """Mean/std over the token axis of a ``[B, H, L, D]`` tensor, with the variance accumulated in fp32."""
+ mean = x.mean(dim=2, keepdim=True)
+ std = x.float().var(dim=2, keepdim=True, unbiased=False).add(_ADAIN_EPS).sqrt().to(x.dtype)
+ return mean, std
+
+
+def _adain_to_stats(
+ target: torch.Tensor, style_mean: torch.Tensor, style_std: torch.Tensor, strength: float
+) -> torch.Tensor:
+ """Blend ``target`` toward the given per-``(head, dim)`` style statistics over the token axis."""
+ alpha = max(0.0, min(1.0, float(strength)))
+ if alpha <= 0.0:
+ return target
+ target_mean, target_std = _token_mean_std(target)
+ styled = (target - target_mean) / target_std * style_std + style_mean
+ if alpha >= 1.0:
+ return styled
+ return target * (1.0 - alpha) + styled * alpha
+
+
+def _build_reference_value(
+ target_value: torch.Tensor,
+ reference_value: torch.Tensor,
+ settings: Krea2StyleReferenceEffectiveSettings,
+) -> torch.Tensor:
+ """Construct the value vectors the reference keys are paired with.
+
+ At the recommended settings (``target_adain_plus_ref`` with ``ref_value_mix=1.0``) this is exactly
+ ``reference_value``; the other modes exist for tuning.
+ """
+ mode = settings.value_mode
+ if mode == "raw_reference":
+ return reference_value
+ if mode == "target":
+ base = target_value
+ elif mode == "ref_mean":
+ base = reference_value.mean(dim=2, keepdim=True).expand_as(reference_value)
+ else:
+ reference_mean, reference_std = _token_mean_std(reference_value)
+ base = _adain_to_stats(target_value, reference_mean, reference_std, settings.value_adain_strength)
+ if mode == "target_adain_plus_ref":
+ mix = settings.ref_value_mix
+ return base * (1.0 - mix) + reference_value * mix
+ return base
+
+
+@dataclass
+class Krea2StyleReferenceBlockCache:
+ """One styled block's captured reference tensors.
+
+ ``reference_key`` / ``reference_value`` are ``[B, kv_heads, image_seq_len, head_dim]`` and are the
+ dominant memory cost. The statistics are ``[B, heads, 1, head_dim]`` and negligible.
+ """
+
+ reference_key: torch.Tensor
+ reference_value: torch.Tensor
+ query_mean: torch.Tensor
+ query_std: torch.Tensor
+ key_mean: torch.Tensor
+ key_std: torch.Tensor
+
+
+@dataclass
+class Krea2StyleInjection:
+ """What the processor should attend with, and how to blend it with the unstyled result."""
+
+ query: torch.Tensor
+ key: torch.Tensor
+ value: torch.Tensor
+ attention_mix: float
+
+
+@dataclass
+class Krea2StyleReferenceState:
+ """Mutable state shared between the denoise loop and the styled blocks' attention processors.
+
+ It lives on the attention processors, which stay installed on the *cached* transformer after the
+ invocation ends -- so :meth:`clear` must be wired to the denoise node's exit stack.
+ """
+
+ settings: Krea2StyleReferenceEffectiveSettings
+ image_seq_len: int
+ axes_dims_rope: tuple[int, ...]
+ mode: Krea2StyleReferenceMode = Krea2StyleReferenceMode.OFF
+ progress: float = 0.0
+ _cache: dict[int, Krea2StyleReferenceBlockCache] = field(default_factory=dict, repr=False)
+ _scale_vector: torch.Tensor | None = field(default=None, repr=False)
+ _padded_masks: list[tuple[torch.Tensor, torch.Tensor]] = field(default_factory=list, repr=False)
+
+ def begin_capture(self) -> None:
+ self._cache.clear()
+ self.mode = Krea2StyleReferenceMode.CAPTURE
+
+ def begin_inject(self, progress: float) -> None:
+ if not self._cache:
+ raise RuntimeError("Krea-2 style reference: inject requested before any reference pass was captured.")
+ self.progress = max(0.0, min(1.0, float(progress)))
+ self._scale_vector = None
+ self.mode = Krea2StyleReferenceMode.INJECT
+
+ def disable(self) -> None:
+ self.mode = Krea2StyleReferenceMode.OFF
+
+ def clear(self) -> None:
+ """Drop every retained tensor. Wired to the denoise node's exit stack."""
+ self.mode = Krea2StyleReferenceMode.OFF
+ self._cache.clear()
+ self._scale_vector = None
+ self._padded_masks.clear()
+
+ def store(self, block_index: int, cache: Krea2StyleReferenceBlockCache) -> None:
+ self._cache[block_index] = cache
+
+ def get(self, block_index: int) -> Krea2StyleReferenceBlockCache:
+ try:
+ return self._cache[block_index]
+ except KeyError:
+ raise RuntimeError(
+ f"Krea-2 style reference: block {block_index} was not captured during the reference pass. "
+ "The reference and target passes must run over the same set of styled blocks."
+ ) from None
+
+ def scale_vector(self, device: torch.device, dtype: torch.dtype) -> torch.Tensor:
+ """The frequency scale vector for the current ``progress``, built once per injected step."""
+ if self._scale_vector is None or self._scale_vector.device != device or self._scale_vector.dtype != dtype:
+ high, low = lerp_scales(self.settings, self.progress)
+ self._scale_vector = build_rope_scale_vector(
+ self.axes_dims_rope, high, low, self.settings.beta, device, dtype
+ )
+ return self._scale_vector
+
+ def pad_attention_mask(self, attention_mask: torch.Tensor | None) -> torch.Tensor | None:
+ """Widen a ``(S, S)`` regional mask to ``(S, S + image_seq_len)`` for the appended reference keys.
+
+ The appended columns are all ``True``: every target query -- text and image alike, in every region
+ -- may see the reference. Upstream sidesteps this by skipping style entirely whenever a mask is
+ present; padding instead lets regional prompting and style reference coexist.
+
+ Cached per source mask, because at high resolution this tensor is large enough that rebuilding it
+ for each of the ~21 styled blocks would be a real cost.
+ """
+ if attention_mask is None:
+ return None
+ for source, padded in self._padded_masks:
+ if source is attention_mask:
+ return padded
+ pad = attention_mask.new_ones((attention_mask.shape[0], self.image_seq_len))
+ padded = torch.cat([attention_mask, pad], dim=-1)
+ # Only the conditional and unconditional masks are ever live at the same time.
+ if len(self._padded_masks) >= 2:
+ self._padded_masks.pop(0)
+ self._padded_masks.append((attention_mask, padded))
+ return padded
+
+
+def _image_token_start(state: Krea2StyleReferenceState, seq_len: int) -> int:
+ """Krea-2 concatenates ``[text, image]``, so the image tokens are the tail of the sequence."""
+ start = int(seq_len) - int(state.image_seq_len)
+ if start < 0:
+ raise ValueError(
+ f"Krea-2 style reference: image_seq_len={state.image_seq_len} exceeds the transformer sequence "
+ f"length {seq_len}."
+ )
+ return start
+
+
+def capture_style_reference(
+ state: Krea2StyleReferenceState,
+ block_index: int,
+ query: torch.Tensor,
+ key: torch.Tensor,
+ value: torch.Tensor,
+) -> None:
+ """Stash one block's reference image-token K/V and Q/K statistics.
+
+ All tensors are ``[B, heads, seq, head_dim]``, post-RoPE and **pre** GQA head expansion. The slices
+ are cloned so the (much larger) full-sequence tensors can be freed with the rest of the reference pass.
+ """
+ image_start = _image_token_start(state, query.shape[2])
+ reference_key = key[:, :, image_start:, :].clone()
+ reference_value = value[:, :, image_start:, :].clone()
+ query_mean, query_std = _token_mean_std(query[:, :, image_start:, :])
+ key_mean, key_std = _token_mean_std(reference_key)
+ state.store(
+ block_index,
+ Krea2StyleReferenceBlockCache(
+ reference_key=reference_key,
+ reference_value=reference_value,
+ query_mean=query_mean,
+ query_std=query_std,
+ key_mean=key_mean,
+ key_std=key_std,
+ ),
+ )
+
+
+def apply_style_reference(
+ state: Krea2StyleReferenceState,
+ block_index: int,
+ query: torch.Tensor,
+ key: torch.Tensor,
+ value: torch.Tensor,
+) -> Krea2StyleInjection:
+ """Build the styled Q/K/V for one block of the target pass.
+
+ Steps, in upstream's order: AdaIN the target's image-token Q and K toward the reference statistics,
+ scale the reference keys by the frequency vector and ``ref_k_strength``, build the paired reference
+ values, then append both to the target's own keys/values.
+
+ The AdaIN happens *before* the native/styled split, so the returned ``query`` is used for both
+ branches -- the ``attention_mix`` blend is between "AdaIN'd, target-only K/V" and "AdaIN'd,
+ reference-appended K/V", not between styled and untouched.
+ """
+ cache = state.get(block_index)
+ settings = state.settings
+ image_start = _image_token_start(state, query.shape[2])
+
+ if cache.reference_key.shape[2] != state.image_seq_len:
+ raise RuntimeError(
+ f"Krea-2 style reference: the captured reference has {cache.reference_key.shape[2]} image tokens "
+ f"but the target pass has {state.image_seq_len}. The reference must be encoded at the target size."
+ )
+
+ if settings.adain_strength > 0.0:
+ query = query.clone()
+ key = key.clone()
+ query[:, :, image_start:, :] = _adain_to_stats(
+ query[:, :, image_start:, :], cache.query_mean, cache.query_std, settings.adain_strength
+ )
+ key[:, :, image_start:, :] = _adain_to_stats(
+ key[:, :, image_start:, :], cache.key_mean, cache.key_std, settings.adain_strength
+ )
+
+ scale_vector = state.scale_vector(key.device, key.dtype).view(1, 1, 1, -1)
+ reference_key = cache.reference_key * scale_vector * settings.ref_k_strength
+ reference_value = _build_reference_value(value[:, :, image_start:, :], cache.reference_value, settings)
+
+ return Krea2StyleInjection(
+ query=query,
+ key=torch.cat([key, reference_key], dim=2),
+ value=torch.cat([value, reference_value], dim=2),
+ attention_mix=settings.attention_mix,
+ )
diff --git a/invokeai/backend/krea2/style_reference_extension.py b/invokeai/backend/krea2/style_reference_extension.py
new file mode 100644
index 00000000000..04b985b4173
--- /dev/null
+++ b/invokeai/backend/krea2/style_reference_extension.py
@@ -0,0 +1,186 @@
+"""Orchestration for Krea-2 style reference: latents in, capture/inject lifecycle out.
+
+Keeps the denoise node free of style-reference bookkeeping. The attention-side math lives in
+``style_reference.py`` and the noising schedule in ``style_reference_rf.py``.
+"""
+
+from __future__ import annotations
+
+from contextlib import contextmanager
+from typing import Iterator, Sequence
+
+import torch
+
+from invokeai.app.invocations.constants import LATENT_SCALE_FACTOR
+from invokeai.app.invocations.fields import Krea2StyleReferenceField
+from invokeai.app.services.shared.invocation_context import InvocationContext
+from invokeai.backend.krea2.sampling_utils import pack_latents
+from invokeai.backend.krea2.style_reference import (
+ KREA2_NUM_BLOCKS,
+ Krea2StyleReferenceSettings,
+ Krea2StyleReferenceState,
+ parse_block_spec,
+ resolve_effective_settings,
+)
+from invokeai.backend.krea2.style_reference_rf import build_linear_reference_latents
+
+# Krea-2 latent channels (Qwen-Image VAE z_dim); mirrors KREA2_LATENT_CHANNELS in krea2_denoise.py.
+_KREA2_LATENT_CHANNELS = 16
+
+# Krea2Transformer2DModel defaults. Needed for the working-memory estimate, which runs *before* the model
+# is on device and therefore cannot read transformer.config. Asserted against the real config in
+# build_state() once the transformer is available.
+KREA2_NUM_KV_HEADS = 12
+KREA2_HEAD_DIM = 128
+KREA2_AXES_DIMS_ROPE = (32, 48, 48)
+
+
+class Krea2StyleReferenceExtension:
+ """Holds the reference latents and drives the two-pass capture/inject lifecycle."""
+
+ def __init__(
+ self,
+ reference_latents: torch.Tensor,
+ settings: Krea2StyleReferenceSettings,
+ block_indices: frozenset[int],
+ image_seq_len: int,
+ ) -> None:
+ self._reference_latents = reference_latents
+ self._settings = settings
+ self._block_indices = block_indices
+ self._image_seq_len = image_seq_len
+ self._schedule: list[torch.Tensor] | None = None
+ self._state: Krea2StyleReferenceState | None = None
+
+ @property
+ def block_indices(self) -> frozenset[int]:
+ return self._block_indices
+
+ @property
+ def state(self) -> Krea2StyleReferenceState:
+ if self._state is None:
+ raise RuntimeError("Krea-2 style reference: build_state() must be called before the state is used.")
+ return self._state
+
+ @classmethod
+ def from_field(
+ cls,
+ context: InvocationContext,
+ field: Krea2StyleReferenceField,
+ *,
+ denoise_width: int,
+ denoise_height: int,
+ dtype: torch.dtype,
+ device: torch.device,
+ ) -> "Krea2StyleReferenceExtension":
+ """Load and pack the reference latents, validating them against the denoise resolution.
+
+ The reference has to occupy exactly as many image tokens as the target -- its keys are appended to
+ the target's along the token axis and share the target's rotary embedding. Checking here, against
+ the dims the encoder recorded, gives a message that names both sides instead of a shape error deep
+ inside attention.
+ """
+ if field.width != denoise_width or field.height != denoise_height:
+ raise ValueError(
+ f"Krea-2 style reference was encoded at {field.width}x{field.height} but denoise is set to "
+ f"{denoise_width}x{denoise_height}. Set the same width and height on both nodes."
+ )
+
+ latents = context.tensors.load(field.reference_latents_name).to(device=device, dtype=dtype)
+ # The Qwen-Image VAE emits (B, C, frames, H, W); style reference is a single frame.
+ if latents.dim() == 5:
+ latents = latents.squeeze(2)
+ if latents.dim() != 4:
+ raise ValueError(f"Krea-2 style reference latents must be 4D or 5D, got shape {tuple(latents.shape)}.")
+
+ latent_height = denoise_height // LATENT_SCALE_FACTOR
+ latent_width = denoise_width // LATENT_SCALE_FACTOR
+ if latents.shape[-2:] != (latent_height, latent_width):
+ raise ValueError(
+ f"Krea-2 style reference latents are {tuple(latents.shape[-2:])} but denoise expects "
+ f"({latent_height}, {latent_width}). Re-encode the reference at the denoise resolution."
+ )
+
+ settings = Krea2StyleReferenceSettings(
+ style_strength=field.style_strength,
+ ref_k_strength=field.ref_k_strength,
+ adain_strength=field.adain_strength,
+ value_mode=field.value_mode,
+ value_adain_strength=field.value_adain_strength,
+ ref_value_mix=field.ref_value_mix,
+ high_scale_start=field.high_scale_start,
+ high_scale_end=field.high_scale_end,
+ low_scale_start=field.low_scale_start,
+ low_scale_end=field.low_scale_end,
+ beta=field.beta,
+ )
+ block_indices = parse_block_spec(field.blocks, KREA2_NUM_BLOCKS)
+
+ packed = pack_latents(latents, 1, _KREA2_LATENT_CHANNELS, latent_height, latent_width)
+ return cls(
+ reference_latents=packed,
+ settings=settings,
+ block_indices=block_indices,
+ image_seq_len=packed.shape[1],
+ )
+
+ def build_state(self, transformer: torch.nn.Module) -> Krea2StyleReferenceState:
+ """Create the shared state, taking the RoPE axis layout from the real transformer config."""
+ config = getattr(transformer, "config", None)
+ axes_dims = tuple(int(dim) for dim in getattr(config, "axes_dims_rope", KREA2_AXES_DIMS_ROPE))
+ num_blocks = int(getattr(config, "num_layers", KREA2_NUM_BLOCKS))
+ out_of_range = sorted(index for index in self._block_indices if index >= num_blocks)
+ if out_of_range:
+ raise ValueError(
+ f"Krea-2 style reference targets blocks {out_of_range}, but this transformer has {num_blocks} blocks."
+ )
+ self._state = Krea2StyleReferenceState(
+ settings=resolve_effective_settings(self._settings),
+ image_seq_len=self._image_seq_len,
+ axes_dims_rope=axes_dims,
+ )
+ return self._state
+
+ def prepare(self, sigmas: Sequence[float]) -> None:
+ """Build the reference's noise trajectory over the active sigma schedule."""
+ self._schedule = build_linear_reference_latents(self._reference_latents, sigmas)
+
+ def reference_latents_for_step(self, step_index: int) -> torch.Tensor:
+ if self._schedule is None:
+ raise RuntimeError("Krea-2 style reference: prepare() must be called before the denoise loop.")
+ return self._schedule[step_index]
+
+ @staticmethod
+ def progress_for_step(step_index: int, total_steps: int) -> float:
+ """Position in the schedule, used to interpolate the frequency scales.
+
+ Defined over the *active* window, so an img2img run that starts at ``denoising_start > 0`` sweeps
+ the full 0..1 curve across the steps it actually takes rather than starting mid-curve.
+ """
+ return step_index / max(total_steps - 1, 1)
+
+ def kv_cache_bytes(self, dtype: torch.dtype) -> int:
+ """Bytes of reference K/V retained across the target pass, for the working-memory estimate.
+
+ One key and one value per styled block, at the pre-expansion KV head count.
+ """
+ element_size = torch.empty((), dtype=dtype).element_size()
+ return len(self._block_indices) * 2 * KREA2_NUM_KV_HEADS * self._image_seq_len * KREA2_HEAD_DIM * element_size
+
+ @contextmanager
+ def capture(self) -> Iterator[None]:
+ """Run the enclosed reference forward in capture mode."""
+ self.state.begin_capture()
+ try:
+ yield
+ finally:
+ self.state.disable()
+
+ @contextmanager
+ def inject(self, progress: float) -> Iterator[None]:
+ """Run the enclosed target forward(s) with the captured reference spliced in."""
+ self.state.begin_inject(progress)
+ try:
+ yield
+ finally:
+ self.state.disable()
diff --git a/invokeai/backend/krea2/style_reference_rf.py b/invokeai/backend/krea2/style_reference_rf.py
new file mode 100644
index 00000000000..a523c07abe8
--- /dev/null
+++ b/invokeai/backend/krea2/style_reference_rf.py
@@ -0,0 +1,56 @@
+"""Reference-latent noising schedules for Krea-2 style reference.
+
+The styled attention needs the reference image at the *same* noise level as the target at every step,
+so the reference latent has to be walked along a trajectory that matches the sampler's sigma schedule.
+
+``linear`` is the rectified-flow forward process, ``z(sigma) = (1 - sigma) * ref + sigma * eps``. Note
+that upstream draws ``eps`` **once** and reuses it for every sigma -- the reference travels a single
+straight line rather than being re-noised independently at each step. Re-sampling per sigma would make
+the reference features jitter between steps and defeat the point.
+
+Upstream's default is instead ``flowturbo_pc``, a predictor-corrector that integrates the model's own
+velocity field and blends the result back toward the linear prior by ``gamma``. That costs roughly two
+extra transformer forwards per schedule point up front, and with ``gamma=0.5`` it stays half-anchored to
+the linear prior anyway, so it is deferred until the cheap path has been measured.
+"""
+
+from __future__ import annotations
+
+from typing import Sequence
+
+import torch
+
+# Upstream fixes the reference noise seed so a given reference image always produces the same trajectory,
+# independent of the generation seed. Keeping that makes style reference reproducible on its own terms.
+KREA2_STYLE_REFERENCE_NOISE_SEED = 42
+
+
+def build_linear_reference_latents(
+ reference_latents: torch.Tensor,
+ sigmas: Sequence[float],
+ seed: int = KREA2_STYLE_REFERENCE_NOISE_SEED,
+) -> list[torch.Tensor]:
+ """Noise ``reference_latents`` to each sigma along one straight rectified-flow trajectory.
+
+ Returns one latent per entry in ``sigmas``, in the same order. ``reference_latents`` may be packed or
+ unpacked; the noise simply matches its shape.
+
+ The noise is drawn on the CPU, matching ``Krea2DenoiseInvocation._get_noise``, so the trajectory does
+ not change between CPU and CUDA runs.
+ """
+ if len(sigmas) == 0:
+ raise ValueError("Krea-2 style reference: the sigma schedule is empty.")
+
+ generator = torch.Generator(device="cpu").manual_seed(int(seed))
+ noise = torch.randn(
+ reference_latents.shape,
+ device="cpu",
+ dtype=torch.float32,
+ generator=generator,
+ ).to(device=reference_latents.device, dtype=reference_latents.dtype)
+
+ latents: list[torch.Tensor] = []
+ for sigma in sigmas:
+ value = max(0.0, min(1.0, float(sigma)))
+ latents.append((1.0 - value) * reference_latents + value * noise)
+ return latents
diff --git a/invokeai/backend/krea2/text_encoding.py b/invokeai/backend/krea2/text_encoding.py
new file mode 100644
index 00000000000..5f7640e32d6
--- /dev/null
+++ b/invokeai/backend/krea2/text_encoding.py
@@ -0,0 +1,126 @@
+"""Qwen3-VL text encoding for Krea-2.
+
+Extracted from the prompt node so alternative encoders (node packs, experiments) can reuse the exact
+token layout instead of restating it. The prompt template is copied from diffusers
+``Krea2Pipeline.get_text_hidden_states``: the prefix is a system turn instructing the model to describe
+an image (the same "generate" template Qwen-Image uses), which is why the first ``KREA2_START_IDX``
+tokens are dropped from the encoder output.
+"""
+
+from __future__ import annotations
+
+from typing import Callable
+
+import torch
+
+from invokeai.backend.krea2.sampling_utils import (
+ KREA2_MAX_SEQ_LEN,
+ KREA2_NUM_SUFFIX_TOKENS,
+ KREA2_SELECT_LAYERS,
+ KREA2_START_IDX,
+)
+from invokeai.backend.model_manager.load.model_cache.utils import get_effective_device
+from invokeai.backend.util.devices import TorchDevice
+
+KREA2_PREFIX = (
+ "<|im_start|>system\nDescribe the image by detailing the color, shape, size, texture, quantity, text, "
+ "spatial relationships of the objects and background:<|im_end|>\n<|im_start|>user\n"
+)
+KREA2_SUFFIX = "<|im_end|>\n<|im_start|>assistant\n"
+
+# Reserve room for the suffix (diffusers: max_sequence_length + start_idx - num_suffix_tokens).
+KREA2_BODY_MAX_LENGTH = KREA2_MAX_SEQ_LEN + KREA2_START_IDX - KREA2_NUM_SUFFIX_TOKENS
+
+BuildTokenValues = Callable[[torch.Tensor], "torch.Tensor | None"]
+"""Callback receiving the body's ``(body_len, 2)`` offset mapping and returning a ``(body_len,)`` vector."""
+
+
+def encode_krea2_prompt(
+ prompt: str,
+ tokenizer,
+ text_encoder,
+ build_token_values: BuildTokenValues | None = None,
+) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor | None]:
+ """Encode a prompt into Krea-2 conditioning.
+
+ Returns ``(prompt_embeds, prompt_mask, token_values)`` with shapes ``(1, 512, 12, hidden)``,
+ ``(1, 512)`` and ``(1, 512)``.
+
+ ``build_token_values`` is an optional extension point for callers that need a per-token vector
+ aligned with the conditioning — for example per-token prompt weights. It is handed the tokenizer's
+ offset mapping for the prompt body and returns one value per body token; the result is extended over
+ the suffix with 1.0 and sliced by the same prefix drop the embeddings and mask get, so it stays
+ aligned by construction. Requires a fast tokenizer; ``None`` is returned when the callback yields
+ nothing. Callers that do not need this leave it unset, and the tokenizer call is unchanged.
+ """
+ device = get_effective_device(text_encoder)
+
+ # diffusers tokenizes (prefix + prompt) and the assistant-turn suffix separately, then concatenates -
+ # so the suffix always survives truncation. Building one string and truncating it (right-truncation)
+ # drops the suffix for long (>~500-token) prompts, corrupting the trained token layout that the fixed
+ # prefix-drop (KREA2_START_IDX) and suffix accounting depend on.
+ body_text = KREA2_PREFIX + prompt
+
+ want_values = build_token_values is not None
+ # Only ask for offsets when they will be used, so the common path makes the exact same call it always did.
+ offset_kwargs = {"return_offsets_mapping": True} if want_values else {}
+ body_inputs = tokenizer(
+ body_text,
+ max_length=KREA2_BODY_MAX_LENGTH,
+ truncation=True,
+ padding="max_length",
+ return_tensors="pt",
+ **offset_kwargs,
+ )
+ # Append the suffix AFTER truncation so it can never be cut, matching the reference layout.
+ suffix_inputs = tokenizer(KREA2_SUFFIX, return_tensors="pt")
+ input_ids = torch.cat([body_inputs.input_ids, suffix_inputs.input_ids], dim=1).to(device=device)
+ attention_mask = torch.cat([body_inputs.attention_mask, suffix_inputs.attention_mask], dim=1).to(
+ device=device, dtype=torch.bool
+ )
+ # Padding sits between the prompt body and assistant suffix. Count only valid tokens when assigning
+ # positions so the suffix receives the same mRoPE phase as it did during training.
+ position_ids = (attention_mask.long().cumsum(dim=-1) - 1).clamp(min=0)
+ position_ids = position_ids.unsqueeze(0).expand(3, -1, -1)
+
+ outputs = text_encoder(
+ input_ids=input_ids,
+ attention_mask=attention_mask,
+ position_ids=position_ids,
+ output_hidden_states=True,
+ use_cache=False,
+ return_dict=True,
+ )
+
+ # Some VL models nest the language-model output; fall back to that if needed.
+ hidden_states_tuple = getattr(outputs, "hidden_states", None)
+ if hidden_states_tuple is None:
+ lm_output = getattr(outputs, "language_model_outputs", None)
+ hidden_states_tuple = getattr(lm_output, "hidden_states", None)
+ if hidden_states_tuple is None:
+ raise RuntimeError("Qwen3-VL encoder did not return hidden_states; cannot build Krea-2 conditioning.")
+
+ # Stack the selected layers along a new layer axis: (B, seq, 12, hidden).
+ stacked = torch.stack([hidden_states_tuple[i] for i in KREA2_SELECT_LAYERS], dim=2)
+
+ # Drop the system-prompt prefix tokens.
+ prompt_embeds = stacked[:, KREA2_START_IDX:]
+ prompt_mask = attention_mask[:, KREA2_START_IDX:].bool()
+
+ # Match the device-safe compute dtype used by the denoise loop (falls back from bf16 to fp16/fp32 on
+ # devices without bf16 support) rather than forcing bfloat16.
+ prompt_embeds = prompt_embeds.to(dtype=TorchDevice.choose_bfloat16_safe_dtype(device))
+
+ token_values = None
+ if want_values:
+ assert build_token_values is not None
+ body_values = build_token_values(body_inputs.offset_mapping[0])
+ if body_values is not None:
+ # The suffix is never weighted, so extend to the full 546-token layout before applying the
+ # same prefix drop the embeddings and mask get. `new_ones` inherits the callback's device and
+ # dtype - the callback is an extension seam, so it may well return a CUDA tensor, and a CPU
+ # suffix would make the concat fail.
+ suffix_values = body_values.new_ones(suffix_inputs.input_ids.shape[1])
+ token_values = torch.cat([body_values, suffix_values])[KREA2_START_IDX:].unsqueeze(0)
+
+ return prompt_embeds, prompt_mask, token_values
diff --git a/invokeai/frontend/web/openapi.json b/invokeai/frontend/web/openapi.json
index 6de4b71d542..1e94966fb4d 100644
--- a/invokeai/frontend/web/openapi.json
+++ b/invokeai/frontend/web/openapi.json
@@ -35135,6 +35135,9 @@
{
"$ref": "#/components/schemas/Krea2SeedVarianceInvocation"
},
+ {
+ "$ref": "#/components/schemas/Krea2StyleReferenceInvocation"
+ },
{
"$ref": "#/components/schemas/Krea2TextEncoderInvocation"
},
@@ -35798,6 +35801,9 @@
{
"$ref": "#/components/schemas/Krea2ModelLoaderOutput"
},
+ {
+ "$ref": "#/components/schemas/Krea2StyleReferenceOutput"
+ },
{
"$ref": "#/components/schemas/LatentsCollectionOutput"
},
@@ -43670,6 +43676,9 @@
{
"$ref": "#/components/schemas/Krea2SeedVarianceInvocation"
},
+ {
+ "$ref": "#/components/schemas/Krea2StyleReferenceInvocation"
+ },
{
"$ref": "#/components/schemas/Krea2TextEncoderInvocation"
},
@@ -44290,6 +44299,9 @@
{
"$ref": "#/components/schemas/Krea2ModelLoaderOutput"
},
+ {
+ "$ref": "#/components/schemas/Krea2StyleReferenceOutput"
+ },
{
"$ref": "#/components/schemas/LatentsCollectionOutput"
},
@@ -45018,6 +45030,9 @@
{
"$ref": "#/components/schemas/Krea2SeedVarianceInvocation"
},
+ {
+ "$ref": "#/components/schemas/Krea2StyleReferenceInvocation"
+ },
{
"$ref": "#/components/schemas/Krea2TextEncoderInvocation"
},
@@ -45987,6 +46002,9 @@
"krea2_seed_variance": {
"$ref": "#/components/schemas/Krea2ConditioningOutput"
},
+ "krea2_style_reference": {
+ "$ref": "#/components/schemas/Krea2StyleReferenceOutput"
+ },
"krea2_text_encoder": {
"$ref": "#/components/schemas/Krea2ConditioningOutput"
},
@@ -46582,6 +46600,7 @@
"krea2_lora_loader",
"krea2_model_loader",
"krea2_seed_variance",
+ "krea2_style_reference",
"krea2_text_encoder",
"l2i",
"latents",
@@ -47279,6 +47298,9 @@
{
"$ref": "#/components/schemas/Krea2SeedVarianceInvocation"
},
+ {
+ "$ref": "#/components/schemas/Krea2StyleReferenceInvocation"
+ },
{
"$ref": "#/components/schemas/Krea2TextEncoderInvocation"
},
@@ -48336,6 +48358,9 @@
{
"$ref": "#/components/schemas/Krea2SeedVarianceInvocation"
},
+ {
+ "$ref": "#/components/schemas/Krea2StyleReferenceInvocation"
+ },
{
"$ref": "#/components/schemas/Krea2TextEncoderInvocation"
},
@@ -51117,6 +51142,40 @@
"orig_required": false,
"title": "Shift"
},
+ "style_reference": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/Krea2StyleReferenceField"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Training-free style reference. Adds one reference forward per step, so generation takes roughly twice as long, and retains the reference's attention keys/values for the whole step (~0.5 GB at 1024x1024, ~1.7 GB at 2560x1440). At 1440p the combined footprint no longer fits a 24 GB card alongside the model.",
+ "field_kind": "input",
+ "input": "connection",
+ "orig_default": null,
+ "orig_required": false,
+ "title": "Style Reference"
+ },
+ "style_reference_conditioning": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/Krea2ConditioningField"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Prompt for the style-reference pass. Leave unconnected to reuse the positive prompt; a short neutral prompt describing the reference can give a purer style transfer.",
+ "field_kind": "input",
+ "input": "connection",
+ "orig_default": null,
+ "orig_required": false,
+ "title": "Style Reference Prompt"
+ },
"type": {
"const": "krea2_denoise",
"default": "krea2_denoise",
@@ -51129,7 +51188,7 @@
"tags": ["image", "krea2", "krea-2"],
"title": "Denoise - Krea-2",
"type": "object",
- "version": "1.2.0",
+ "version": "1.3.0",
"output": {
"$ref": "#/components/schemas/LatentsOutput"
}
@@ -51625,6 +51684,383 @@
"$ref": "#/components/schemas/Krea2ConditioningOutput"
}
},
+ "Krea2StyleReferenceField": {
+ "description": "Style-reference conditioning for Krea-2 shared-KV reference attention.\n\nCarries the VAE-encoded reference latents plus the tuning parameters that shape how strongly, and in\nwhich frequency bands, the reference influences the target. The reference must be encoded at exactly\nthe denoise node's resolution, so the dims travel with it for an early, legible mismatch error.\n\nOnly ``style_strength`` is meant for everyday use; it modulates several of the others. The remainder\nare exposed for tuning and should be left at their defaults.",
+ "properties": {
+ "reference_latents_name": {
+ "description": "Name of the saved [1, 16, 1, H/8, W/8] reference latents.",
+ "title": "Reference Latents Name",
+ "type": "string"
+ },
+ "width": {
+ "description": "Image width the reference was encoded at (must match denoise width).",
+ "title": "Width",
+ "type": "integer"
+ },
+ "height": {
+ "description": "Image height the reference was encoded at (must match denoise height).",
+ "title": "Height",
+ "type": "integer"
+ },
+ "style_strength": {
+ "default": 1.0,
+ "description": "Overall style strength. 0 disables the reference.",
+ "title": "Style Strength",
+ "type": "number"
+ },
+ "blocks": {
+ "default": "7-27",
+ "description": "Transformer blocks the reference is injected into.",
+ "title": "Blocks",
+ "type": "string"
+ },
+ "ref_k_strength": {
+ "default": 1.06,
+ "description": "Multiplier on the reference key path.",
+ "title": "Ref K Strength",
+ "type": "number"
+ },
+ "adain_strength": {
+ "default": 0.85,
+ "description": "Reference statistics applied to the target Q/K.",
+ "title": "Adain Strength",
+ "type": "number"
+ },
+ "value_mode": {
+ "default": "target_adain_plus_ref",
+ "description": "How the reference value vectors are constructed.",
+ "enum": ["target", "raw_reference", "ref_mean", "target_adain", "target_adain_plus_ref"],
+ "title": "Value Mode",
+ "type": "string"
+ },
+ "value_adain_strength": {
+ "default": 0.65,
+ "description": "Reference statistics applied to the target value path. Has no effect while ref_value_mix is 1.0.",
+ "title": "Value Adain Strength",
+ "type": "number"
+ },
+ "ref_value_mix": {
+ "default": 1.0,
+ "description": "How much raw reference value signal is kept.",
+ "title": "Ref Value Mix",
+ "type": "number"
+ },
+ "high_scale_start": {
+ "default": 1.04,
+ "description": "High-frequency reference key scale at step 0.",
+ "title": "High Scale Start",
+ "type": "number"
+ },
+ "high_scale_end": {
+ "default": 0.0,
+ "description": "High-frequency reference key scale at the last step.",
+ "title": "High Scale End",
+ "type": "number"
+ },
+ "low_scale_start": {
+ "default": 1.0,
+ "description": "Low-frequency reference key scale at step 0.",
+ "title": "Low Scale Start",
+ "type": "number"
+ },
+ "low_scale_end": {
+ "default": 1.1,
+ "description": "Low-frequency reference key scale at the last step.",
+ "title": "Low Scale End",
+ "type": "number"
+ },
+ "beta": {
+ "default": 2.5,
+ "description": "Exponent of the high-to-low frequency falloff curve.",
+ "title": "Beta",
+ "type": "number"
+ }
+ },
+ "required": ["reference_latents_name", "width", "height"],
+ "title": "Krea2StyleReferenceField",
+ "type": "object"
+ },
+ "Krea2StyleReferenceInvocation": {
+ "category": "conditioning",
+ "class": "invocation",
+ "classification": "prototype",
+ "description": "Encode a reference image into Krea-2 style-reference conditioning.\n\nTransfers the *look* of the reference image -- palette, texture, rendering -- while the prompt keeps\ndriving the content. No adapter model or LoRA is involved.\n\n``width`` and ``height`` must match the Krea-2 denoise node. Everything below ``style_strength`` is\nfor tuning and should be left at its default; ``style_strength`` already modulates several of them.",
+ "node_pack": "invokeai",
+ "properties": {
+ "id": {
+ "description": "The id of this instance of an invocation. Must be unique among all instances of invocations.",
+ "field_kind": "node_attribute",
+ "title": "Id",
+ "type": "string"
+ },
+ "is_intermediate": {
+ "default": false,
+ "description": "Whether or not this is an intermediate invocation.",
+ "field_kind": "node_attribute",
+ "input": "direct",
+ "orig_required": true,
+ "title": "Is Intermediate",
+ "type": "boolean",
+ "ui_hidden": false,
+ "ui_type": "IsIntermediate"
+ },
+ "use_cache": {
+ "default": true,
+ "description": "Whether or not to use the cache",
+ "field_kind": "node_attribute",
+ "title": "Use Cache",
+ "type": "boolean"
+ },
+ "image": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/ImageField"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Reference image whose style should be transferred.",
+ "field_kind": "input",
+ "input": "any",
+ "orig_required": true
+ },
+ "vae": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/VAEField"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "VAE",
+ "field_kind": "input",
+ "input": "connection",
+ "orig_required": true,
+ "title": "VAE"
+ },
+ "width": {
+ "default": 1024,
+ "description": "Width to encode the reference at (must match the denoise node's width).",
+ "exclusiveMinimum": 0,
+ "field_kind": "input",
+ "input": "any",
+ "multipleOf": 16,
+ "orig_default": 1024,
+ "orig_required": false,
+ "title": "Width",
+ "type": "integer"
+ },
+ "height": {
+ "default": 1024,
+ "description": "Height to encode the reference at (must match the denoise node's height).",
+ "exclusiveMinimum": 0,
+ "field_kind": "input",
+ "input": "any",
+ "multipleOf": 16,
+ "orig_default": 1024,
+ "orig_required": false,
+ "title": "Height",
+ "type": "integer"
+ },
+ "fit": {
+ "default": "crop",
+ "description": "How to reconcile the reference's aspect ratio with the target size. 'crop' scales to cover and center-crops, 'contain' letterboxes on white, 'stretch' distorts.",
+ "enum": ["crop", "contain", "stretch"],
+ "field_kind": "input",
+ "input": "any",
+ "orig_default": "crop",
+ "orig_required": false,
+ "title": "Fit",
+ "type": "string"
+ },
+ "style_strength": {
+ "default": 1.0,
+ "description": "Overall style strength. 0 disables the reference; 1.0 is the recommended setting.",
+ "field_kind": "input",
+ "input": "any",
+ "maximum": 2.0,
+ "minimum": 0.0,
+ "orig_default": 1.0,
+ "orig_required": false,
+ "title": "Style Strength",
+ "type": "number"
+ },
+ "blocks": {
+ "default": "7-27",
+ "description": "Transformer blocks to inject the reference into, e.g. '7-27'. Styling the earliest blocks damages composition.",
+ "field_kind": "input",
+ "input": "any",
+ "orig_default": "7-27",
+ "orig_required": false,
+ "title": "Blocks",
+ "type": "string",
+ "ui_order": 10
+ },
+ "ref_k_strength": {
+ "default": 1.06,
+ "description": "Multiplier on the reference key path. This is the knob that makes the style visible without raising low_scale_end (which would also let reference content leak in).",
+ "field_kind": "input",
+ "input": "any",
+ "maximum": 5.0,
+ "minimum": 0.0,
+ "orig_default": 1.06,
+ "orig_required": false,
+ "title": "Ref K Strength",
+ "type": "number",
+ "ui_order": 11
+ },
+ "adain_strength": {
+ "default": 0.85,
+ "description": "How strongly the reference's query/key statistics are applied to the target.",
+ "field_kind": "input",
+ "input": "any",
+ "maximum": 1.0,
+ "minimum": 0.0,
+ "orig_default": 0.85,
+ "orig_required": false,
+ "title": "Adain Strength",
+ "type": "number",
+ "ui_order": 12
+ },
+ "value_mode": {
+ "default": "target_adain_plus_ref",
+ "description": "How the reference value vectors are built.",
+ "enum": ["target", "raw_reference", "ref_mean", "target_adain", "target_adain_plus_ref"],
+ "field_kind": "input",
+ "input": "any",
+ "orig_default": "target_adain_plus_ref",
+ "orig_required": false,
+ "title": "Value Mode",
+ "type": "string",
+ "ui_order": 13
+ },
+ "value_adain_strength": {
+ "default": 0.65,
+ "description": "Reference statistics applied to the target value path. Has no effect while ref_value_mix is 1.0.",
+ "field_kind": "input",
+ "input": "any",
+ "maximum": 1.5,
+ "minimum": 0.0,
+ "orig_default": 0.65,
+ "orig_required": false,
+ "title": "Value Adain Strength",
+ "type": "number",
+ "ui_order": 14
+ },
+ "ref_value_mix": {
+ "default": 1.0,
+ "description": "How much raw reference value signal is kept. Higher usually preserves style material.",
+ "field_kind": "input",
+ "input": "any",
+ "maximum": 1.0,
+ "minimum": 0.0,
+ "orig_default": 1.0,
+ "orig_required": false,
+ "title": "Ref Value Mix",
+ "type": "number",
+ "ui_order": 15
+ },
+ "high_scale_start": {
+ "default": 1.04,
+ "description": "Scale on the reference key's high-frequency bands at the first step.",
+ "field_kind": "input",
+ "input": "any",
+ "orig_default": 1.04,
+ "orig_required": false,
+ "title": "High Scale Start",
+ "type": "number",
+ "ui_order": 16
+ },
+ "high_scale_end": {
+ "default": 0.0,
+ "description": "Scale on the reference key's high-frequency bands at the last step. 0 decays them away, which is what keeps reference content from leaking in.",
+ "field_kind": "input",
+ "input": "any",
+ "orig_default": 0.0,
+ "orig_required": false,
+ "title": "High Scale End",
+ "type": "number",
+ "ui_order": 17
+ },
+ "low_scale_start": {
+ "default": 1.0,
+ "description": "Scale on the reference key's low-frequency bands at the first step.",
+ "field_kind": "input",
+ "input": "any",
+ "orig_default": 1.0,
+ "orig_required": false,
+ "title": "Low Scale Start",
+ "type": "number",
+ "ui_order": 18
+ },
+ "low_scale_end": {
+ "default": 1.1,
+ "description": "Scale on the reference key's low-frequency bands at the last step. Raising this strengthens the style but also invites content leakage and quality loss.",
+ "field_kind": "input",
+ "input": "any",
+ "orig_default": 1.1,
+ "orig_required": false,
+ "title": "Low Scale End",
+ "type": "number",
+ "ui_order": 19
+ },
+ "beta": {
+ "default": 2.5,
+ "description": "Exponent of the high-to-low frequency falloff curve.",
+ "exclusiveMinimum": 0.0,
+ "field_kind": "input",
+ "input": "any",
+ "maximum": 20.0,
+ "orig_default": 2.5,
+ "orig_required": false,
+ "title": "Beta",
+ "type": "number",
+ "ui_order": 20
+ },
+ "type": {
+ "const": "krea2_style_reference",
+ "default": "krea2_style_reference",
+ "field_kind": "node_attribute",
+ "title": "type",
+ "type": "string"
+ }
+ },
+ "required": ["type", "id"],
+ "tags": ["image", "conditioning", "krea2", "krea-2", "style"],
+ "title": "Style Reference - Krea-2",
+ "type": "object",
+ "version": "1.0.0",
+ "output": {
+ "$ref": "#/components/schemas/Krea2StyleReferenceOutput"
+ }
+ },
+ "Krea2StyleReferenceOutput": {
+ "class": "output",
+ "description": "Output of a Krea-2 style-reference encoder.",
+ "properties": {
+ "style_reference": {
+ "$ref": "#/components/schemas/Krea2StyleReferenceField",
+ "description": "Style-reference conditioning for Krea-2.",
+ "field_kind": "output",
+ "title": "Style Reference",
+ "ui_hidden": false
+ },
+ "type": {
+ "const": "krea2_style_reference_output",
+ "default": "krea2_style_reference_output",
+ "field_kind": "node_attribute",
+ "title": "type",
+ "type": "string"
+ }
+ },
+ "required": ["output_meta", "style_reference", "type", "type"],
+ "title": "Krea2StyleReferenceOutput",
+ "type": "object"
+ },
"Krea2TextEncoderInvocation": {
"category": "conditioning",
"class": "invocation",
diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json
index 6c87e0477aa..6ccb0ef9ebc 100644
--- a/invokeai/frontend/web/public/locales/en.json
+++ b/invokeai/frontend/web/public/locales/en.json
@@ -2854,6 +2854,7 @@
}
},
"controlLayers": {
+ "krea2StyleStrength": "Style Strength",
"regional": "Regional",
"global": "Global",
"canvas": "Canvas",
@@ -3137,6 +3138,7 @@
"rgNoPromptsOrIPAdapters": "no text prompts or Reference Images",
"rgNegativePromptNotSupported": "Negative Prompt not supported for selected base model",
"rgReferenceImagesNotSupported": "regional Reference Images not supported for selected base model",
+ "krea2OnlyOneReferenceImage": "Krea-2 style reference uses only one image — this one is ignored",
"rgAutoNegativeNotSupported": "Auto-Negative not supported for selected base model",
"rgNoRegion": "no region drawn",
"ideogram4Txt2ImgOnly": "Ideogram 4 is text-to-image only; raster layers and inpaint masks are not supported",
diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts
index fb7f9ee8434..52572202abc 100644
--- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts
+++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts
@@ -43,6 +43,7 @@ import {
getEntityIdentifier,
isAspectRatioID,
isFlux2ReferenceImageConfig,
+ isKrea2ReferenceImageConfig,
isQwenImageReferenceImageConfig,
isWanReferenceImageConfig,
} from 'features/controlLayers/store/types';
@@ -51,6 +52,7 @@ import {
initialFluxKontextReferenceImage,
initialFLUXRedux,
initialIPAdapter,
+ initialKrea2ReferenceImage,
initialQwenImageReferenceImage,
initialWanReferenceImage,
} from 'features/controlLayers/store/util';
@@ -500,6 +502,21 @@ export const addModelSelectedListener = (startAppListening: AppStartListening) =
continue;
}
+ if (newBase === 'krea-2') {
+ // Switching TO Krea-2 - convert any non-krea2 configs to krea2_reference_image. Krea-2
+ // transfers style training-free, so there is no adapter model to carry over.
+ if (!isKrea2ReferenceImageConfig(entity.config)) {
+ dispatch(
+ refImageConfigChanged({
+ id: entity.id,
+ config: { ...initialKrea2ReferenceImage },
+ })
+ );
+ modelsUpdatedDisabledOrCleared += 1;
+ }
+ continue;
+ }
+
if (isFlux2ReferenceImageConfig(entity.config)) {
// Switching AWAY from FLUX.2 - convert flux2_reference_image to the appropriate config type
let newConfig;
@@ -571,6 +588,29 @@ export const addModelSelectedListener = (startAppListening: AppStartListening) =
continue;
}
+ if (isKrea2ReferenceImageConfig(entity.config)) {
+ // Switching AWAY from Krea-2 - convert to the appropriate config type for the new base.
+ let newConfig;
+ if (newGlobalRefImageModel) {
+ const parsedModel = zModelIdentifierField.parse(newGlobalRefImageModel);
+ if (newModel.base === 'flux' && newModel.name.toLowerCase().includes('kontext')) {
+ newConfig = { ...initialFluxKontextReferenceImage, model: parsedModel };
+ } else if (newGlobalRefImageModel.type === 'flux_redux') {
+ newConfig = { ...initialFLUXRedux, model: parsedModel };
+ } else {
+ newConfig = { ...initialIPAdapter, model: parsedModel };
+ if (parsedModel.base === 'flux') {
+ newConfig.clipVisionModel = 'ViT-L';
+ }
+ }
+ } else {
+ newConfig = { ...initialIPAdapter };
+ }
+ dispatch(refImageConfigChanged({ id: entity.id, config: newConfig }));
+ modelsUpdatedDisabledOrCleared += 1;
+ continue;
+ }
+
// Standard handling for non-flux2 configs
const shouldUpdateModel =
(entity.config.model && entity.config.model.base !== newBase) ||
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/RefImage/Krea2StyleStrength.tsx b/invokeai/frontend/web/src/features/controlLayers/components/RefImage/Krea2StyleStrength.tsx
new file mode 100644
index 00000000000..d98e7f80ebd
--- /dev/null
+++ b/invokeai/frontend/web/src/features/controlLayers/components/RefImage/Krea2StyleStrength.tsx
@@ -0,0 +1,56 @@
+import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
+import { memo } from 'react';
+import { useTranslation } from 'react-i18next';
+
+// Krea-2's style reference has no adapter model and no begin/end step range - style strength is the one
+// knob. It is a master control: besides mixing the styled attention it also pulls the reference key's
+// frequency scaling and the AdaIN strength back toward neutral. At 0 the graph builder omits the style
+// node altogether, so the bypass is free rather than merely invisible.
+const CONSTRAINTS = {
+ initial: 1,
+ min: 0,
+ max: 2,
+ fineStep: 0.01,
+ coarseStep: 0.05,
+};
+
+type Props = {
+ styleStrength: number;
+ onChange: (styleStrength: number) => void;
+};
+
+const formatValue = (v: number) => v.toFixed(2);
+const marks = [0, 1, 2];
+
+export const Krea2StyleStrength = memo(({ styleStrength, onChange }: Props) => {
+ const { t } = useTranslation();
+
+ return (
+
+ {t('controlLayers.krea2StyleStrength')}
+
+
+
+ );
+});
+
+Krea2StyleStrength.displayName = 'Krea2StyleStrength';
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImageHeader.tsx b/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImageHeader.tsx
index 7f1d43c1b4c..51fba8a37ff 100644
--- a/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImageHeader.tsx
+++ b/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImageHeader.tsx
@@ -8,9 +8,10 @@ import { selectMainModelConfig } from 'features/controlLayers/store/paramsSlice'
import {
refImageDeleted,
refImageIsEnabledToggled,
+ selectReferenceImageEntities,
selectRefImageEntityIds,
} from 'features/controlLayers/store/refImagesSlice';
-import { getGlobalReferenceImageWarnings } from 'features/controlLayers/store/validators';
+import { getGlobalReferenceImageWarningsInContext } from 'features/controlLayers/store/validators';
import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { PiCircleBold, PiCircleFill, PiTrashBold, PiWarningBold } from 'react-icons/pi';
@@ -36,9 +37,10 @@ export const RefImageHeader = memo(() => {
const entity = useRefImageEntity(id);
const mainModelConfig = useAppSelector(selectMainModelConfig);
+ const allRefImages = useAppSelector(selectReferenceImageEntities);
const warnings = useMemo(() => {
- return getGlobalReferenceImageWarnings(entity, mainModelConfig);
- }, [entity, mainModelConfig]);
+ return getGlobalReferenceImageWarningsInContext(entity, allRefImages, mainModelConfig);
+ }, [entity, allRefImages, mainModelConfig]);
const deleteRefImage = useCallback(() => {
dispatch(refImageDeleted({ id }));
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImagePreview.tsx b/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImagePreview.tsx
index 95ed74a3145..05738f8944f 100644
--- a/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImagePreview.tsx
+++ b/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImagePreview.tsx
@@ -10,10 +10,11 @@ import { selectMainModelConfig } from 'features/controlLayers/store/paramsSlice'
import {
refImageSelected,
selectIsRefImagePanelOpen,
+ selectReferenceImageEntities,
selectSelectedRefEntityId,
} from 'features/controlLayers/store/refImagesSlice';
import { isIPAdapterConfig } from 'features/controlLayers/store/types';
-import { getGlobalReferenceImageWarnings } from 'features/controlLayers/store/validators';
+import { getGlobalReferenceImageWarningsInContext } from 'features/controlLayers/store/validators';
import { DndListDropIndicator } from 'features/dnd/DndListDropIndicator';
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
@@ -111,9 +112,10 @@ export const RefImagePreview = memo(() => {
};
}, [entity.config, isExternalModel]);
+ const allRefImages = useAppSelector(selectReferenceImageEntities);
const warnings = useMemo(() => {
- return getGlobalReferenceImageWarnings(entity, mainModelConfig);
- }, [entity, mainModelConfig]);
+ return getGlobalReferenceImageWarningsInContext(entity, allRefImages, mainModelConfig);
+ }, [entity, allRefImages, mainModelConfig]);
const onClick = useCallback(() => {
dispatch(refImageSelected({ id }));
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImageSettings.tsx b/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImageSettings.tsx
index 3edf9594b79..8e924bee3aa 100644
--- a/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImageSettings.tsx
+++ b/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImageSettings.tsx
@@ -7,6 +7,7 @@ import { IPAdapterCLIPVisionModel } from 'features/controlLayers/components/comm
import { PullBboxIntoRefImageIconButton } from 'features/controlLayers/components/common/PullBboxIntoRefImageIconButton';
import { Weight } from 'features/controlLayers/components/common/Weight';
import { IPAdapterMethod } from 'features/controlLayers/components/RefImage/IPAdapterMethod';
+import { Krea2StyleStrength } from 'features/controlLayers/components/RefImage/Krea2StyleStrength';
import { RefImageModel } from 'features/controlLayers/components/RefImage/RefImageModel';
import { RefImageNoImageState } from 'features/controlLayers/components/RefImage/RefImageNoImageState';
import { RefImageNoImageStateWithCanvasOptions } from 'features/controlLayers/components/RefImage/RefImageNoImageStateWithCanvasOptions';
@@ -23,6 +24,7 @@ import {
refImageIPAdapterCLIPVisionModelChanged,
refImageIPAdapterMethodChanged,
refImageIPAdapterWeightChanged,
+ refImageKrea2StyleStrengthChanged,
refImageModelChanged,
selectRefImageEntity,
selectRefImageEntityOrThrow,
@@ -38,6 +40,7 @@ import {
isFlux2ReferenceImageConfig,
isFLUXReduxConfig,
isIPAdapterConfig,
+ isKrea2ReferenceImageConfig,
isQwenImageReferenceImageConfig,
isWanReferenceImageConfig,
} from 'features/controlLayers/store/types';
@@ -97,6 +100,13 @@ const RefImageSettingsContent = memo(() => {
[dispatch, id]
);
+ const onChangeKrea2StyleStrength = useCallback(
+ (styleStrength: number) => {
+ dispatch(refImageKrea2StyleStrengthChanged({ id, styleStrength }));
+ },
+ [dispatch, id]
+ );
+
const onChangeModel = useCallback(
(modelConfig: IPAdapterModelConfig | FLUXReduxModelConfig | ChatGPT4oModelConfig | FLUXKontextModelConfig) => {
dispatch(refImageModelChanged({ id, modelConfig }));
@@ -130,11 +140,13 @@ const RefImageSettingsContent = memo(() => {
const isFLUX = useAppSelector(selectIsFLUX);
const isExternalModel = !!mainModelConfig && isExternalApiModelConfig(mainModelConfig);
- // FLUX.2 Klein, Qwen Image Edit, Wan 2.2 and external API models do not require a ref image model selection.
+ // FLUX.2 Klein, Qwen Image Edit, Wan 2.2, Krea-2 and external API models do not require a ref image
+ // model selection.
const showModelSelector =
!isFlux2ReferenceImageConfig(config) &&
!isQwenImageReferenceImageConfig(config) &&
!isWanReferenceImageConfig(config) &&
+ !isKrea2ReferenceImageConfig(config) &&
!isExternalModel;
return (
@@ -170,6 +182,11 @@ const RefImageSettingsContent = memo(() => {
)}
+ {isKrea2ReferenceImageConfig(config) && (
+
+
+
+ )}
{isFLUXReduxConfig(config) && !isExternalModel && (
{
+ | WanReferenceImageConfig
+ | Krea2ReferenceImageConfig => {
const state = getState();
const mainModelConfig = selectMainModelConfig(state);
@@ -110,6 +113,11 @@ export const getDefaultRefImageConfig = (
return deepClone(initialWanReferenceImage);
}
+ // Krea-2 transfers style training-free via shared-KV reference attention - no adapter model needed
+ if (base === 'krea-2') {
+ return deepClone(initialKrea2ReferenceImage);
+ }
+
if (base === 'flux' && mainModelConfig?.name?.toLowerCase().includes('kontext')) {
const config = deepClone(initialFluxKontextReferenceImage);
config.model = zModelIdentifierField.parse(mainModelConfig);
diff --git a/invokeai/frontend/web/src/features/controlLayers/store/paramsSlice.test.ts b/invokeai/frontend/web/src/features/controlLayers/store/paramsSlice.test.ts
index e2a2713aa41..2be7b2d4cfa 100644
--- a/invokeai/frontend/web/src/features/controlLayers/store/paramsSlice.test.ts
+++ b/invokeai/frontend/web/src/features/controlLayers/store/paramsSlice.test.ts
@@ -88,6 +88,14 @@ describe('paramsSlice selectors for external models', () => {
expect(selectModelSupportsRefImages.resultFunc(model, config)).toBe(false);
});
+ it('supports reference images on Krea-2, which uses training-free style reference', () => {
+ // Krea-2 has no ref-image adapter model, so the panel is gated purely on the base being listed in
+ // SUPPORTS_REF_IMAGES_BASE_MODELS.
+ const model = { key: 'krea2', hash: 'hash', name: 'Krea-2 Turbo', base: 'krea-2', type: 'main' } as never;
+
+ expect(selectModelSupportsRefImages.resultFunc(model, null)).toBe(true);
+ });
+
it('returns false for guidance support on external models', () => {
const config = createExternalConfig({
modes: ['txt2img'],
diff --git a/invokeai/frontend/web/src/features/controlLayers/store/refImagesSlice.ts b/invokeai/frontend/web/src/features/controlLayers/store/refImagesSlice.ts
index 6c364e51e88..59f9701c376 100644
--- a/invokeai/frontend/web/src/features/controlLayers/store/refImagesSlice.ts
+++ b/invokeai/frontend/web/src/features/controlLayers/store/refImagesSlice.ts
@@ -22,6 +22,7 @@ import {
isFlux2ReferenceImageConfig,
isFLUXReduxConfig,
isIPAdapterConfig,
+ isKrea2ReferenceImageConfig,
isQwenImageReferenceImageConfig,
isWanReferenceImageConfig,
zRefImagesState,
@@ -145,11 +146,13 @@ const slice = createSlice({
return;
}
- // FLUX.2, Qwen Image Edit and Wan reference images don't have a model field - they use built-in support
+ // FLUX.2, Qwen Image Edit, Wan and Krea-2 reference images don't have a model field - they use
+ // built-in support
if (
isFlux2ReferenceImageConfig(entity.config) ||
isQwenImageReferenceImageConfig(entity.config) ||
- isWanReferenceImageConfig(entity.config)
+ isWanReferenceImageConfig(entity.config) ||
+ isKrea2ReferenceImageConfig(entity.config)
) {
return;
}
@@ -233,6 +236,17 @@ const slice = createSlice({
}
entity.config.weight = weight;
},
+ refImageKrea2StyleStrengthChanged: (state, action: PayloadActionWithId<{ styleStrength: number }>) => {
+ const { id, styleStrength } = action.payload;
+ const entity = selectRefImageEntity(state, id);
+ if (!entity) {
+ return;
+ }
+ if (!isKrea2ReferenceImageConfig(entity.config)) {
+ return;
+ }
+ entity.config.styleStrength = styleStrength;
+ },
refImageIPAdapterBeginEndStepPctChanged: (
state,
action: PayloadActionWithId<{ beginEndStepPct: [number, number] }>
@@ -323,6 +337,7 @@ export const {
refImageIPAdapterWeightChanged,
refImageIPAdapterBeginEndStepPctChanged,
refImageFLUXReduxImageInfluenceChanged,
+ refImageKrea2StyleStrengthChanged,
refImageIsEnabledToggled,
refImagesRecalled,
refImagesReordered,
diff --git a/invokeai/frontend/web/src/features/controlLayers/store/types.ts b/invokeai/frontend/web/src/features/controlLayers/store/types.ts
index 2143e58f997..663f2b53a37 100644
--- a/invokeai/frontend/web/src/features/controlLayers/store/types.ts
+++ b/invokeai/frontend/web/src/features/controlLayers/store/types.ts
@@ -438,6 +438,16 @@ const zWanReferenceImageConfig = z.object({
});
export type WanReferenceImageConfig = z.infer;
+// Krea-2 transfers style training-free, by splicing the reference's attention keys/values into the
+// target's - no adapter model needed. styleStrength is the only knob surfaced here; the rest of the
+// tuning parameters live on the krea2_style_reference node and keep their defaults.
+const zKrea2ReferenceImageConfig = z.object({
+ type: z.literal('krea2_reference_image'),
+ image: zCroppableImageWithDims.nullable(),
+ styleStrength: z.number().gte(0).lte(2).default(1),
+});
+export type Krea2ReferenceImageConfig = z.infer;
+
const zCanvasEntityBase = z.object({
id: zId,
name: zName,
@@ -455,6 +465,7 @@ export const zRefImageState = z.object({
zFlux2ReferenceImageConfig,
zQwenImageReferenceImageConfig,
zWanReferenceImageConfig,
+ zKrea2ReferenceImageConfig,
]),
});
export type RefImageState = z.infer;
@@ -479,6 +490,9 @@ export const isQwenImageReferenceImageConfig = (
export const isWanReferenceImageConfig = (config: RefImageState['config']): config is WanReferenceImageConfig =>
config.type === 'wan_reference_image';
+export const isKrea2ReferenceImageConfig = (config: RefImageState['config']): config is Krea2ReferenceImageConfig =>
+ config.type === 'krea2_reference_image';
+
const zFillStyle = z.enum(['solid', 'grid', 'crosshatch', 'diagonal', 'horizontal', 'vertical']);
export type FillStyle = z.infer;
export const isFillStyle = (v: unknown): v is FillStyle => zFillStyle.safeParse(v).success;
diff --git a/invokeai/frontend/web/src/features/controlLayers/store/util.ts b/invokeai/frontend/web/src/features/controlLayers/store/util.ts
index a0dae2145d0..b4a4ce75bfd 100644
--- a/invokeai/frontend/web/src/features/controlLayers/store/util.ts
+++ b/invokeai/frontend/web/src/features/controlLayers/store/util.ts
@@ -16,6 +16,7 @@ import type {
FLUXReduxConfig,
ImageWithDims,
IPAdapterConfig,
+ Krea2ReferenceImageConfig,
QwenImageReferenceImageConfig,
RasterLayerAdjustments,
RefImageState,
@@ -128,6 +129,11 @@ export const initialWanReferenceImage: WanReferenceImageConfig = {
type: 'wan_reference_image',
image: null,
};
+export const initialKrea2ReferenceImage: Krea2ReferenceImageConfig = {
+ type: 'krea2_reference_image',
+ image: null,
+ styleStrength: 1,
+};
export const initialT2IAdapter: T2IAdapterConfig = {
type: 't2i_adapter',
model: null,
diff --git a/invokeai/frontend/web/src/features/controlLayers/store/validators.krea2.test.ts b/invokeai/frontend/web/src/features/controlLayers/store/validators.krea2.test.ts
new file mode 100644
index 00000000000..7d0f826c215
--- /dev/null
+++ b/invokeai/frontend/web/src/features/controlLayers/store/validators.krea2.test.ts
@@ -0,0 +1,81 @@
+import type { RefImageState } from 'features/controlLayers/store/types';
+import { getGlobalReferenceImageWarningsInContext } from 'features/controlLayers/store/validators';
+import type { MainOrExternalModelConfig } from 'services/api/types';
+import { describe, expect, it } from 'vitest';
+
+const krea2Model = { base: 'krea-2', type: 'main' } as MainOrExternalModelConfig;
+const sdxlModel = { base: 'sdxl', type: 'main' } as MainOrExternalModelConfig;
+
+const image = { original: { image: { image_name: 'a.png' }, width: 64, height: 64 } };
+
+const krea2Entity = (id: string, overrides: Partial = {}): RefImageState =>
+ ({
+ id,
+ isEnabled: true,
+ config: { type: 'krea2_reference_image', styleStrength: 1, image },
+ ...overrides,
+ }) as RefImageState;
+
+describe('getGlobalReferenceImageWarningsInContext', () => {
+ it('does not warn about a single Krea-2 reference image', () => {
+ const entities = [krea2Entity('a')];
+ expect(getGlobalReferenceImageWarningsInContext(entities[0]!, entities, krea2Model)).toEqual([]);
+ });
+
+ it('warns on every Krea-2 reference image after the first', () => {
+ // The graph builder consumes exactly one; dropping the rest silently reads as "all are being used".
+ const entities = [krea2Entity('a'), krea2Entity('b'), krea2Entity('c')];
+
+ expect(getGlobalReferenceImageWarningsInContext(entities[0]!, entities, krea2Model)).toEqual([]);
+ for (const entity of [entities[1]!, entities[2]!]) {
+ expect(getGlobalReferenceImageWarningsInContext(entity, entities, krea2Model)).toContain(
+ 'controlLayers.warnings.krea2OnlyOneReferenceImage'
+ );
+ }
+ });
+
+ it('ignores disabled and image-less entries when deciding which one is used', () => {
+ // A disabled entity is not a candidate, so the first *usable* one must stay warning-free.
+ const entities = [
+ krea2Entity('disabled', { isEnabled: false }),
+ krea2Entity('noimage', { config: { type: 'krea2_reference_image', styleStrength: 1, image: null } as never }),
+ krea2Entity('used'),
+ krea2Entity('extra'),
+ ];
+
+ expect(getGlobalReferenceImageWarningsInContext(entities[2]!, entities, krea2Model)).toEqual([]);
+ expect(getGlobalReferenceImageWarningsInContext(entities[3]!, entities, krea2Model)).toContain(
+ 'controlLayers.warnings.krea2OnlyOneReferenceImage'
+ );
+ });
+
+ it('treats a strength of 0 as disabled when deciding which one is used', () => {
+ // 0 is a full bypass - the graph builder skips the entity, so the next one is the one actually used.
+ const entities = [
+ krea2Entity('bypassed', { config: { type: 'krea2_reference_image', styleStrength: 0, image } as never }),
+ krea2Entity('used'),
+ ];
+
+ expect(getGlobalReferenceImageWarningsInContext(entities[1]!, entities, krea2Model)).not.toContain(
+ 'controlLayers.warnings.krea2OnlyOneReferenceImage'
+ );
+ expect(getGlobalReferenceImageWarningsInContext(entities[0]!, entities, krea2Model)).not.toContain(
+ 'controlLayers.warnings.krea2OnlyOneReferenceImage'
+ );
+ });
+
+ it('does not warn when a disabled entity is the extra one', () => {
+ const entities = [krea2Entity('used'), krea2Entity('off', { isEnabled: false })];
+ expect(getGlobalReferenceImageWarningsInContext(entities[1]!, entities, krea2Model)).not.toContain(
+ 'controlLayers.warnings.krea2OnlyOneReferenceImage'
+ );
+ });
+
+ it('leaves other bases alone', () => {
+ // SDXL chains multiple IP-Adapters, so several reference images are legitimate there.
+ const entities = [krea2Entity('a'), krea2Entity('b')];
+ expect(getGlobalReferenceImageWarningsInContext(entities[1]!, entities, sdxlModel)).not.toContain(
+ 'controlLayers.warnings.krea2OnlyOneReferenceImage'
+ );
+ });
+});
diff --git a/invokeai/frontend/web/src/features/controlLayers/store/validators.ts b/invokeai/frontend/web/src/features/controlLayers/store/validators.ts
index 80da5a9cc5c..e008cd2e24f 100644
--- a/invokeai/frontend/web/src/features/controlLayers/store/validators.ts
+++ b/invokeai/frontend/web/src/features/controlLayers/store/validators.ts
@@ -5,6 +5,7 @@ import type {
CanvasRegionalGuidanceState,
RefImageState,
} from 'features/controlLayers/store/types';
+import { isKrea2ReferenceImageConfig } from 'features/controlLayers/store/types';
import type { ModelIdentifierField } from 'features/nodes/types/common';
import {
type AnyModelConfigWithExternal,
@@ -28,6 +29,7 @@ const WARNINGS = {
CONTROL_ADAPTER_NO_CONTROL: 'controlLayers.warnings.controlAdapterNoControl',
FLUX_FILL_NO_WORKY_WITH_CONTROL_LORA: 'controlLayers.warnings.fluxFillIncompatibleWithControlLoRA',
CONTROL_ADAPTER_DUPLICATE_ANIMA_LLLITE_MODEL: 'controlLayers.warnings.controlAdapterDuplicateAnimaLLLiteModel',
+ KREA2_ONLY_ONE_REFERENCE_IMAGE: 'controlLayers.warnings.krea2OnlyOneReferenceImage',
} as const;
type WarningTKey = (typeof WARNINGS)[keyof typeof WARNINGS];
@@ -194,11 +196,12 @@ export const getGlobalReferenceImageWarnings = (
const { config } = entity;
- // FLUX.2, Qwen Image Edit and Wan reference images don't require a model - it's built-in
+ // FLUX.2, Qwen Image Edit, Wan and Krea-2 reference images don't require a model - it's built-in
if (
config.type !== 'flux2_reference_image' &&
config.type !== 'qwen_image_reference_image' &&
- config.type !== 'wan_reference_image'
+ config.type !== 'wan_reference_image' &&
+ config.type !== 'krea2_reference_image'
) {
if (!('model' in config) || !config.model) {
// No model selected
@@ -222,6 +225,38 @@ export const getGlobalReferenceImageWarnings = (
return warnings;
};
+/**
+ * Warnings that depend on the *other* reference images, not just this one.
+ *
+ * Krea-2's style reference splices a single reference's attention keys/values into the target, so the
+ * graph builder consumes exactly one image. Without this the extra entities would be dropped silently,
+ * which reads as "all of them are being used".
+ *
+ * Deliberately separate from `getGlobalReferenceImageWarnings`: the graph builder filters its candidates
+ * on that function returning no warnings, and folding this in would exclude the one image we *do* use.
+ */
+export const getGlobalReferenceImageWarningsInContext = (
+ entity: RefImageState,
+ allEntities: RefImageState[],
+ model: MainOrExternalModelConfig | null | undefined
+): string[] => {
+ const warnings: string[] = [...getGlobalReferenceImageWarnings(entity, model)];
+
+ if (model?.base === 'krea-2') {
+ // Mirrors the graph builder's candidate filter, including the strength-0 bypass: a reference at 0 is
+ // skipped entirely, so the next one becomes the one that is used and must not be flagged as extra.
+ const usable = allEntities.filter(
+ (e) => e.isEnabled && isKrea2ReferenceImageConfig(e.config) && e.config.image && e.config.styleStrength > 0
+ );
+ const isUsable = usable.some((e) => e.id === entity.id);
+ if (isUsable && usable.length > 1 && usable[0]?.id !== entity.id) {
+ warnings.push(WARNINGS.KREA2_ONLY_ONE_REFERENCE_IMAGE);
+ }
+ }
+
+ return warnings;
+};
+
export const getControlLayerWarnings = (
entity: CanvasControlLayerState,
model: MainOrExternalModelConfig | null | undefined,
diff --git a/invokeai/frontend/web/src/features/modelManagerV2/models.ts b/invokeai/frontend/web/src/features/modelManagerV2/models.ts
index 3c9d4a128e8..12d8b095178 100644
--- a/invokeai/frontend/web/src/features/modelManagerV2/models.ts
+++ b/invokeai/frontend/web/src/features/modelManagerV2/models.ts
@@ -343,7 +343,15 @@ export const MODEL_FORMAT_TO_LONG_NAME: Record = {
export const SUPPORTS_OPTIMIZED_DENOISING_BASE_MODELS: BaseModelType[] = ['flux', 'sd-3'];
-export const SUPPORTS_REF_IMAGES_BASE_MODELS: BaseModelType[] = ['sd-1', 'sdxl', 'flux', 'flux2', 'qwen-image', 'wan'];
+export const SUPPORTS_REF_IMAGES_BASE_MODELS: BaseModelType[] = [
+ 'sd-1',
+ 'sdxl',
+ 'flux',
+ 'flux2',
+ 'qwen-image',
+ 'wan',
+ 'krea-2',
+];
export const SUPPORTS_NEGATIVE_PROMPT_BASE_MODELS: BaseModelType[] = [
'sd-1',
diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildKrea2Graph.regions.test.ts b/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildKrea2Graph.regions.test.ts
index 99852aa8276..d954f280f5d 100644
--- a/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildKrea2Graph.regions.test.ts
+++ b/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildKrea2Graph.regions.test.ts
@@ -47,6 +47,17 @@ vi.mock('features/controlLayers/store/paramsSlice', () => ({
selectParamsSlice: vi.fn(() => params),
}));
+let refImageEntities: unknown[] = [];
+vi.mock('features/controlLayers/store/refImagesSlice', async () => {
+ const actual = await vi.importActual('features/controlLayers/store/refImagesSlice');
+ return { ...actual, selectRefImagesSlice: vi.fn(() => ({ entities: refImageEntities })) };
+});
+
+vi.mock('features/controlLayers/store/validators', async () => {
+ const actual = await vi.importActual('features/controlLayers/store/validators');
+ return { ...actual, getGlobalReferenceImageWarnings: vi.fn(() => []) };
+});
+
vi.mock('features/controlLayers/store/selectors', () => ({
selectCanvasMetadata: vi.fn(() => ({})),
selectCanvasSlice: vi.fn(() => ({
@@ -139,6 +150,7 @@ const sourceOf = (g: BuiltGraph, nodeId: string, field: string) =>
describe('buildKrea2Graph - regional guidance (composed)', () => {
afterEach(() => {
nextId = 0;
+ refImageEntities = [];
params = { ...defaultParams };
regions = [];
loraState.loras = [];
diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildKrea2Graph.test.ts b/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildKrea2Graph.test.ts
index ab25a78f909..75df629aca1 100644
--- a/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildKrea2Graph.test.ts
+++ b/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildKrea2Graph.test.ts
@@ -43,6 +43,17 @@ vi.mock('features/controlLayers/store/paramsSlice', () => ({
selectParamsSlice: vi.fn(() => params),
}));
+let refImageEntities: unknown[] = [];
+vi.mock('features/controlLayers/store/refImagesSlice', async () => {
+ const actual = await vi.importActual('features/controlLayers/store/refImagesSlice');
+ return { ...actual, selectRefImagesSlice: vi.fn(() => ({ entities: refImageEntities })) };
+});
+
+vi.mock('features/controlLayers/store/validators', async () => {
+ const actual = await vi.importActual('features/controlLayers/store/validators');
+ return { ...actual, getGlobalReferenceImageWarnings: vi.fn(() => []) };
+});
+
vi.mock('features/controlLayers/store/selectors', () => ({
selectCanvasMetadata: vi.fn(() => ({})),
selectCanvasSlice: vi.fn(() => ({
@@ -55,16 +66,33 @@ vi.mock('features/metadata/util/modelFetchingHelpers', () => ({
fetchModelConfigWithTypeGuard: vi.fn(() => Promise.resolve(model)),
}));
+// The real mode helpers are what assign the denoise dimensions - anything the builder reads off `denoise`
+// before they run is `undefined`. The mocks mirror that so ordering bugs are visible here (review 4977240290).
+let scaledSize = { width: 1024, height: 1024 };
+const applyScaledSize = (denoise: { width?: number; height?: number }) => {
+ denoise.width = scaledSize.width;
+ denoise.height = scaledSize.height;
+};
+
vi.mock('features/nodes/util/graph/generation/addImageToImage', () => ({
- addImageToImage: vi.fn(({ l2i }) => Promise.resolve(l2i)),
+ addImageToImage: vi.fn(({ denoise, l2i }) => {
+ applyScaledSize(denoise);
+ return Promise.resolve(l2i);
+ }),
}));
vi.mock('features/nodes/util/graph/generation/addInpaint', () => ({
- addInpaint: vi.fn(({ l2i }) => Promise.resolve(l2i)),
+ addInpaint: vi.fn(({ denoise, l2i }) => {
+ applyScaledSize(denoise);
+ return Promise.resolve(l2i);
+ }),
}));
vi.mock('features/nodes/util/graph/generation/addOutpaint', () => ({
- addOutpaint: vi.fn(({ l2i }) => Promise.resolve(l2i)),
+ addOutpaint: vi.fn(({ denoise, l2i }) => {
+ applyScaledSize(denoise);
+ return Promise.resolve(l2i);
+ }),
}));
vi.mock('features/nodes/util/graph/generation/addRegions', () => ({
@@ -84,7 +112,10 @@ vi.mock('features/nodes/util/graph/generation/addWatermarker', () => ({
}));
vi.mock('features/nodes/util/graph/generation/addTextToImage', () => ({
- addTextToImage: vi.fn(({ l2i }) => l2i),
+ addTextToImage: vi.fn(({ denoise, l2i }) => {
+ applyScaledSize(denoise);
+ return l2i;
+ }),
}));
vi.mock('features/nodes/util/graph/graphBuilderUtils', () => ({
@@ -141,6 +172,8 @@ describe('buildKrea2Graph', () => {
afterEach(() => {
vi.clearAllMocks();
nextId = 0;
+ refImageEntities = [];
+ scaledSize = { width: 1024, height: 1024 };
params = { ...defaultParams };
model = { ...baseModel };
});
@@ -386,4 +419,149 @@ describe('buildKrea2Graph', () => {
expect(metadata.negative_prompt).toBeUndefined();
});
});
+ describe('style reference', () => {
+ const styleRefEntity = (overrides: Record = {}) => ({
+ id: 'ref-1',
+ isEnabled: true,
+ config: {
+ type: 'krea2_reference_image',
+ styleStrength: 1,
+ image: { original: { image: { image_name: 'style.png' }, width: 512, height: 512 } },
+ ...overrides,
+ },
+ });
+
+ const styleReferenceNode = (g: BuiltGraph) =>
+ Object.values(g.getGraph().nodes).find((n) => n.type === 'krea2_style_reference');
+
+ it('adds no style reference node when there is no reference image', async () => {
+ const { g } = await buildTxt2Img();
+ expect(styleReferenceNode(g)).toBeUndefined();
+ });
+
+ it('wires the style reference between the VAE and denoise', async () => {
+ refImageEntities = [styleRefEntity()];
+ const { g } = await buildTxt2Img();
+
+ const styleReference = styleReferenceNode(g) as unknown as Record;
+ expect(styleReference).toBeDefined();
+ expect(styleReference.image).toEqual({ image_name: 'style.png' });
+
+ const edges = g.getGraph().edges;
+ expect(edges.some((e) => e.destination.node_id === styleReference.id && e.destination.field === 'vae')).toBe(
+ true
+ );
+ expect(
+ edges.some((e) => e.source.node_id === styleReference.id && e.destination.field === 'style_reference')
+ ).toBe(true);
+ });
+
+ // The reference's image tokens are appended to the target's, so a size mismatch is a hard error in the
+ // denoise node. The generation-mode helper is what assigns the denoise dimensions, so the style node has
+ // to be built after it - reading them earlier yields `undefined`, which JSON drops, silently leaving the
+ // node on its 1024x1024 backend default (review 4977240290).
+ it.each([
+ ['1024x1024', { width: 1024, height: 1024 }],
+ ['768x1024', { width: 768, height: 1024 }],
+ ['1152x896', { width: 1152, height: 896 }],
+ ])('encodes the reference at the denoise resolution (%s, txt2img)', async (_label, size) => {
+ scaledSize = size;
+ refImageEntities = [styleRefEntity()];
+ const { g } = await buildTxt2Img();
+
+ const styleReference = styleReferenceNode(g) as unknown as Record;
+ const denoise = Object.values(g.getGraph().nodes).find((n) => n.type === 'krea2_denoise') as unknown as Record<
+ string,
+ unknown
+ >;
+ expect(denoise.width).toBe(size.width);
+ expect(styleReference.width).toBe(size.width);
+ expect(styleReference.height).toBe(size.height);
+ expect(styleReference.width).toBe(denoise.width);
+ expect(styleReference.height).toBe(denoise.height);
+ });
+
+ it.each(['img2img', 'inpaint', 'outpaint'] as const)(
+ 'encodes the reference at the denoise resolution (%s)',
+ async (generationMode) => {
+ scaledSize = { width: 768, height: 1024 };
+ refImageEntities = [styleRefEntity()];
+ const { g } = await buildCanvasMode(generationMode);
+
+ const styleReference = styleReferenceNode(g) as unknown as Record;
+ expect(styleReference.width).toBe(768);
+ expect(styleReference.height).toBe(1024);
+ }
+ );
+
+ // 0 is documented as a full bypass. Emitting the node anyway costs a VAE encode, a capture pass per step
+ // and a retained K/V cache for no visible effect.
+ it('adds no style reference node when the strength is 0', async () => {
+ refImageEntities = [styleRefEntity({ styleStrength: 0 })];
+ const { g } = await buildTxt2Img();
+
+ expect(styleReferenceNode(g)).toBeUndefined();
+ expect((g.getMetadataNode() as unknown as Record).krea2_style_strength).toBeUndefined();
+ });
+
+ it('falls through to the next reference when the first has a strength of 0', async () => {
+ refImageEntities = [
+ styleRefEntity({ styleStrength: 0 }),
+ { ...styleRefEntity({ styleStrength: 0.5 }), id: 'ref-2' },
+ ];
+ const { g } = await buildTxt2Img();
+
+ const styleReference = styleReferenceNode(g) as unknown as Record;
+ expect(styleReference.style_strength).toBe(0.5);
+ });
+
+ it('prefers the cropped image when one exists', async () => {
+ refImageEntities = [
+ styleRefEntity({
+ image: {
+ original: { image: { image_name: 'style.png' }, width: 512, height: 512 },
+ crop: { image: { image_name: 'style-cropped.png' }, width: 256, height: 256 },
+ },
+ }),
+ ];
+ const { g } = await buildTxt2Img();
+
+ const styleReference = styleReferenceNode(g) as unknown as Record;
+ expect(styleReference.image).toEqual({ image_name: 'style-cropped.png' });
+ });
+
+ it('carries the style strength onto the node and into metadata', async () => {
+ refImageEntities = [styleRefEntity({ styleStrength: 0.6 })];
+ const { g } = await buildTxt2Img();
+
+ const styleReference = styleReferenceNode(g) as unknown as Record;
+ expect(styleReference.style_strength).toBe(0.6);
+ expect((g.getMetadataNode() as unknown as Record).krea2_style_strength).toBe(0.6);
+ });
+
+ it('ignores disabled reference images and ones without an image', async () => {
+ refImageEntities = [{ ...styleRefEntity(), isEnabled: false }, styleRefEntity({ image: null })];
+ const { g } = await buildTxt2Img();
+ expect(styleReferenceNode(g)).toBeUndefined();
+ });
+
+ it('uses only the first valid reference image', async () => {
+ // The technique supports exactly one reference; the panel allows several.
+ refImageEntities = [
+ styleRefEntity({ styleStrength: 0.25 }),
+ { ...styleRefEntity({ styleStrength: 0.75 }), id: 'ref-2' },
+ ];
+ const { g } = await buildTxt2Img();
+
+ const styleReferenceNodes = Object.values(g.getGraph().nodes).filter((n) => n.type === 'krea2_style_reference');
+ expect(styleReferenceNodes).toHaveLength(1);
+ expect((styleReferenceNodes[0] as unknown as Record).style_strength).toBe(0.25);
+ });
+
+ it('ignores reference images belonging to another base', async () => {
+ refImageEntities = [{ id: 'ref-1', isEnabled: true, config: { type: 'wan_reference_image', image: {} } }];
+ const { g } = await buildTxt2Img();
+ expect(styleReferenceNode(g)).toBeUndefined();
+ });
+ });
});
diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildKrea2Graph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildKrea2Graph.ts
index e8b5287d81e..8f34040dff0 100644
--- a/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildKrea2Graph.ts
+++ b/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildKrea2Graph.ts
@@ -1,8 +1,12 @@
import { logger } from 'app/logging/logger';
import { getPrefixedId } from 'features/controlLayers/konva/util';
import { selectMainModelConfig, selectParamsSlice } from 'features/controlLayers/store/paramsSlice';
+import { selectRefImagesSlice } from 'features/controlLayers/store/refImagesSlice';
import { selectCanvasMetadata, selectCanvasSlice } from 'features/controlLayers/store/selectors';
+import { isKrea2ReferenceImageConfig } from 'features/controlLayers/store/types';
+import { getGlobalReferenceImageWarnings } from 'features/controlLayers/store/validators';
import { fetchModelConfigWithTypeGuard } from 'features/metadata/util/modelFetchingHelpers';
+import { zImageField } from 'features/nodes/types/common';
import { addImageToImage } from 'features/nodes/util/graph/generation/addImageToImage';
import { addInpaint } from 'features/nodes/util/graph/generation/addInpaint';
import { addKrea2LoRAs } from 'features/nodes/util/graph/generation/addKrea2LoRAs';
@@ -184,7 +188,8 @@ export const buildKrea2Graph = async (arg: GraphBuilderArg): Promise>(false);
}
+ // Global style reference: training-free style transfer via shared-KV reference attention. There is no
+ // adapter model, and the technique supports exactly one reference, so consume the first valid entity.
+ //
+ // Must run *after* the generation-mode helper above: that is what assigns the denoise dimensions, and the
+ // reference has to be encoded at exactly those dimensions. Reading them earlier yields `undefined`, which
+ // JSON drops, leaving the node on its 1024x1024 default and failing every other resolution.
+ const styleRefEntity = selectRefImagesSlice(state).entities.find(
+ (entity) =>
+ entity.isEnabled &&
+ isKrea2ReferenceImageConfig(entity.config) &&
+ entity.config.image !== null &&
+ // A strength of 0 is a full bypass, and the whole reference pipeline (VAE encode, per-step capture
+ // pass, retained K/V cache) is skipped rather than run for no effect.
+ entity.config.styleStrength > 0 &&
+ getGlobalReferenceImageWarnings(entity, model).length === 0
+ );
+ if (styleRefEntity && isKrea2ReferenceImageConfig(styleRefEntity.config) && styleRefEntity.config.image) {
+ const { image, styleStrength } = styleRefEntity.config;
+ assert(
+ denoise.width !== undefined && denoise.height !== undefined,
+ 'Krea-2 denoise dimensions must be set before the style reference is encoded'
+ );
+ const styleReference = g.addNode({
+ type: 'krea2_style_reference',
+ id: getPrefixedId('krea2_style_reference'),
+ image: zImageField.parse(image.crop?.image ?? image.original.image),
+ // The reference's image tokens are appended to the target's, so both must be the same size.
+ width: denoise.width,
+ height: denoise.height,
+ style_strength: styleStrength,
+ });
+ g.addEdge(modelLoader, 'vae', styleReference, 'vae');
+ g.addEdge(styleReference, 'style_reference', denoise, 'style_reference');
+ g.upsertMetadata({ krea2_style_strength: styleStrength });
+ }
+
if (state.system.shouldUseNSFWChecker) {
canvasOutput = addNSFWChecker(g, canvasOutput);
}
diff --git a/invokeai/frontend/web/src/services/api/schema.ts b/invokeai/frontend/web/src/services/api/schema.ts
index f1779d9814e..ab5beb6e672 100644
--- a/invokeai/frontend/web/src/services/api/schema.ts
+++ b/invokeai/frontend/web/src/services/api/schema.ts
@@ -14508,7 +14508,7 @@ export type components = {
* @description The nodes in this graph
*/
nodes?: {
- [key: string]: components["schemas"]["AddInvocation"] | components["schemas"]["AlibabaCloudImageGenerationInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["AnimaDenoiseInvocation"] | components["schemas"]["AnimaImageToLatentsInvocation"] | components["schemas"]["AnimaLLLiteInvocation"] | components["schemas"]["AnimaLatentsToImageInvocation"] | components["schemas"]["AnimaLoRACollectionLoader"] | components["schemas"]["AnimaLoRALoaderInvocation"] | components["schemas"]["AnimaModelLoaderInvocation"] | components["schemas"]["AnimaTextEncoderInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CallSavedWorkflowInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasOutputInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DecodeInvisibleWatermarkInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ErnieImageDenoiseInvocation"] | components["schemas"]["ErnieImageModelLoaderInvocation"] | components["schemas"]["ErnieImagePromptEnhancerInvocation"] | components["schemas"]["ErnieImageTextEncoderInvocation"] | components["schemas"]["ErnieImageVaeDecodeInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["ExtractVideoRangeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["Flux2DenoiseInvocation"] | components["schemas"]["Flux2DevLoRACollectionLoader"] | components["schemas"]["Flux2DevLoRALoaderInvocation"] | components["schemas"]["Flux2DevModelLoaderInvocation"] | components["schemas"]["Flux2DevTextEncoderInvocation"] | components["schemas"]["Flux2KleinLoRACollectionLoader"] | components["schemas"]["Flux2KleinLoRALoaderInvocation"] | components["schemas"]["Flux2KleinModelLoaderInvocation"] | components["schemas"]["Flux2KleinTextEncoderInvocation"] | components["schemas"]["Flux2PiDDecodeInvocation"] | components["schemas"]["Flux2VaeDecodeInvocation"] | components["schemas"]["Flux2VaeEncodeInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxPiDDecodeInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GeminiImageGenerationInvocation"] | components["schemas"]["Gemma2EncoderLoaderInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["Ideogram4CaptionBuilderInvocation"] | components["schemas"]["Ideogram4DenoiseInvocation"] | components["schemas"]["Ideogram4LatentsToImageInvocation"] | components["schemas"]["Ideogram4ModelLoaderInvocation"] | components["schemas"]["Ideogram4TextEncoderInvocation"] | components["schemas"]["IfInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["Krea2ConditioningRebalanceInvocation"] | components["schemas"]["Krea2DenoiseInvocation"] | components["schemas"]["Krea2LoRACollectionLoader"] | components["schemas"]["Krea2LoRALoaderInvocation"] | components["schemas"]["Krea2ModelLoaderInvocation"] | components["schemas"]["Krea2SeedVarianceInvocation"] | components["schemas"]["Krea2TextEncoderInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["OklabUnsharpMaskInvocation"] | components["schemas"]["OklchImageHueAdjustmentInvocation"] | components["schemas"]["OpenAIImageGenerationInvocation"] | components["schemas"]["PBRMapsInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDDecoderLoaderInvocation"] | components["schemas"]["PiDUpscaleInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptTemplateInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["QwenImageDenoiseInvocation"] | components["schemas"]["QwenImageImageToLatentsInvocation"] | components["schemas"]["QwenImageLatentsToImageInvocation"] | components["schemas"]["QwenImageLoRACollectionLoader"] | components["schemas"]["QwenImageLoRALoaderInvocation"] | components["schemas"]["QwenImageModelLoaderInvocation"] | components["schemas"]["QwenImagePiDDecodeInvocation"] | components["schemas"]["QwenImageTextEncoderInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SD3PiDDecodeInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLPiDDecodeInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["SaveImageToFileInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SeedreamImageGenerationInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TextLLMInvocation"] | components["schemas"]["TextLLMWithPresetInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"] | components["schemas"]["VideoConcatInvocation"] | components["schemas"]["VideoFrameExtractInvocation"] | components["schemas"]["VideoInvocation"] | components["schemas"]["WanDenoiseInvocation"] | components["schemas"]["WanI2VIdealDimensionsInvocation"] | components["schemas"]["WanImageToLatentsInvocation"] | components["schemas"]["WanLatentsToImageInvocation"] | components["schemas"]["WanLatentsToVideoInvocation"] | components["schemas"]["WanLoRACollectionLoader"] | components["schemas"]["WanLoRALoaderInvocation"] | components["schemas"]["WanModelLoaderInvocation"] | components["schemas"]["WanRefImageEncoderInvocation"] | components["schemas"]["WanTI2VIdealDimensionsInvocation"] | components["schemas"]["WanTextEncoderInvocation"] | components["schemas"]["WanVideoDenoiseInvocation"] | components["schemas"]["WorkflowReturnGetInvocation"] | components["schemas"]["WorkflowReturnInvocation"] | components["schemas"]["WorkflowReturnValueInvocation"] | components["schemas"]["ZImageControlInvocation"] | components["schemas"]["ZImageDenoiseInvocation"] | components["schemas"]["ZImageDenoiseMetaInvocation"] | components["schemas"]["ZImageImageToLatentsInvocation"] | components["schemas"]["ZImageLatentsToImageInvocation"] | components["schemas"]["ZImageLoRACollectionLoader"] | components["schemas"]["ZImageLoRALoaderInvocation"] | components["schemas"]["ZImageModelLoaderInvocation"] | components["schemas"]["ZImagePiDDecodeInvocation"] | components["schemas"]["ZImageSeedVarianceEnhancerInvocation"] | components["schemas"]["ZImageTextEncoderInvocation"];
+ [key: string]: components["schemas"]["AddInvocation"] | components["schemas"]["AlibabaCloudImageGenerationInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["AnimaDenoiseInvocation"] | components["schemas"]["AnimaImageToLatentsInvocation"] | components["schemas"]["AnimaLLLiteInvocation"] | components["schemas"]["AnimaLatentsToImageInvocation"] | components["schemas"]["AnimaLoRACollectionLoader"] | components["schemas"]["AnimaLoRALoaderInvocation"] | components["schemas"]["AnimaModelLoaderInvocation"] | components["schemas"]["AnimaTextEncoderInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CallSavedWorkflowInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasOutputInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DecodeInvisibleWatermarkInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ErnieImageDenoiseInvocation"] | components["schemas"]["ErnieImageModelLoaderInvocation"] | components["schemas"]["ErnieImagePromptEnhancerInvocation"] | components["schemas"]["ErnieImageTextEncoderInvocation"] | components["schemas"]["ErnieImageVaeDecodeInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["ExtractVideoRangeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["Flux2DenoiseInvocation"] | components["schemas"]["Flux2DevLoRACollectionLoader"] | components["schemas"]["Flux2DevLoRALoaderInvocation"] | components["schemas"]["Flux2DevModelLoaderInvocation"] | components["schemas"]["Flux2DevTextEncoderInvocation"] | components["schemas"]["Flux2KleinLoRACollectionLoader"] | components["schemas"]["Flux2KleinLoRALoaderInvocation"] | components["schemas"]["Flux2KleinModelLoaderInvocation"] | components["schemas"]["Flux2KleinTextEncoderInvocation"] | components["schemas"]["Flux2PiDDecodeInvocation"] | components["schemas"]["Flux2VaeDecodeInvocation"] | components["schemas"]["Flux2VaeEncodeInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxPiDDecodeInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GeminiImageGenerationInvocation"] | components["schemas"]["Gemma2EncoderLoaderInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["Ideogram4CaptionBuilderInvocation"] | components["schemas"]["Ideogram4DenoiseInvocation"] | components["schemas"]["Ideogram4LatentsToImageInvocation"] | components["schemas"]["Ideogram4ModelLoaderInvocation"] | components["schemas"]["Ideogram4TextEncoderInvocation"] | components["schemas"]["IfInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["Krea2ConditioningRebalanceInvocation"] | components["schemas"]["Krea2DenoiseInvocation"] | components["schemas"]["Krea2LoRACollectionLoader"] | components["schemas"]["Krea2LoRALoaderInvocation"] | components["schemas"]["Krea2ModelLoaderInvocation"] | components["schemas"]["Krea2SeedVarianceInvocation"] | components["schemas"]["Krea2StyleReferenceInvocation"] | components["schemas"]["Krea2TextEncoderInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["OklabUnsharpMaskInvocation"] | components["schemas"]["OklchImageHueAdjustmentInvocation"] | components["schemas"]["OpenAIImageGenerationInvocation"] | components["schemas"]["PBRMapsInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDDecoderLoaderInvocation"] | components["schemas"]["PiDUpscaleInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptTemplateInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["QwenImageDenoiseInvocation"] | components["schemas"]["QwenImageImageToLatentsInvocation"] | components["schemas"]["QwenImageLatentsToImageInvocation"] | components["schemas"]["QwenImageLoRACollectionLoader"] | components["schemas"]["QwenImageLoRALoaderInvocation"] | components["schemas"]["QwenImageModelLoaderInvocation"] | components["schemas"]["QwenImagePiDDecodeInvocation"] | components["schemas"]["QwenImageTextEncoderInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SD3PiDDecodeInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLPiDDecodeInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["SaveImageToFileInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SeedreamImageGenerationInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TextLLMInvocation"] | components["schemas"]["TextLLMWithPresetInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"] | components["schemas"]["VideoConcatInvocation"] | components["schemas"]["VideoFrameExtractInvocation"] | components["schemas"]["VideoInvocation"] | components["schemas"]["WanDenoiseInvocation"] | components["schemas"]["WanI2VIdealDimensionsInvocation"] | components["schemas"]["WanImageToLatentsInvocation"] | components["schemas"]["WanLatentsToImageInvocation"] | components["schemas"]["WanLatentsToVideoInvocation"] | components["schemas"]["WanLoRACollectionLoader"] | components["schemas"]["WanLoRALoaderInvocation"] | components["schemas"]["WanModelLoaderInvocation"] | components["schemas"]["WanRefImageEncoderInvocation"] | components["schemas"]["WanTI2VIdealDimensionsInvocation"] | components["schemas"]["WanTextEncoderInvocation"] | components["schemas"]["WanVideoDenoiseInvocation"] | components["schemas"]["WorkflowReturnGetInvocation"] | components["schemas"]["WorkflowReturnInvocation"] | components["schemas"]["WorkflowReturnValueInvocation"] | components["schemas"]["ZImageControlInvocation"] | components["schemas"]["ZImageDenoiseInvocation"] | components["schemas"]["ZImageDenoiseMetaInvocation"] | components["schemas"]["ZImageImageToLatentsInvocation"] | components["schemas"]["ZImageLatentsToImageInvocation"] | components["schemas"]["ZImageLoRACollectionLoader"] | components["schemas"]["ZImageLoRALoaderInvocation"] | components["schemas"]["ZImageModelLoaderInvocation"] | components["schemas"]["ZImagePiDDecodeInvocation"] | components["schemas"]["ZImageSeedVarianceEnhancerInvocation"] | components["schemas"]["ZImageTextEncoderInvocation"];
};
/**
* Edges
@@ -14545,7 +14545,7 @@ export type components = {
* @description The results of node executions
*/
results: {
- [key: string]: components["schemas"]["AnimaConditioningOutput"] | components["schemas"]["AnimaLLLiteOutput"] | components["schemas"]["AnimaLoRALoaderOutput"] | components["schemas"]["AnimaModelLoaderOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["BooleanOutput"] | components["schemas"]["BoundingBoxCollectionOutput"] | components["schemas"]["BoundingBoxOutput"] | components["schemas"]["CLIPOutput"] | components["schemas"]["CLIPSkipInvocationOutput"] | components["schemas"]["CalculateImageTilesOutput"] | components["schemas"]["CogView4ConditioningOutput"] | components["schemas"]["CogView4ModelLoaderOutput"] | components["schemas"]["CollectInvocationOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["ErnieImageConditioningOutput"] | components["schemas"]["ErnieImageModelLoaderOutput"] | components["schemas"]["ExtractVideoRangeOutput"] | components["schemas"]["FaceMaskOutput"] | components["schemas"]["FaceOffOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["FloatGeneratorOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["Flux2DevLoRALoaderOutput"] | components["schemas"]["Flux2DevModelLoaderOutput"] | components["schemas"]["Flux2KleinLoRALoaderOutput"] | components["schemas"]["Flux2KleinModelLoaderOutput"] | components["schemas"]["FluxConditioningCollectionOutput"] | components["schemas"]["FluxConditioningOutput"] | components["schemas"]["FluxControlLoRALoaderOutput"] | components["schemas"]["FluxControlNetOutput"] | components["schemas"]["FluxFillOutput"] | components["schemas"]["FluxKontextOutput"] | components["schemas"]["FluxLoRALoaderOutput"] | components["schemas"]["FluxModelLoaderOutput"] | components["schemas"]["FluxReduxOutput"] | components["schemas"]["Gemma2EncoderOutput"] | components["schemas"]["GradientMaskOutput"] | components["schemas"]["IPAdapterOutput"] | components["schemas"]["IdealSizeOutput"] | components["schemas"]["Ideogram4ConditioningOutput"] | components["schemas"]["Ideogram4ModelLoaderOutput"] | components["schemas"]["IfInvocationOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["ImageGeneratorOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["ImagePanelCoordinateOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["IntegerGeneratorOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["Krea2ConditioningOutput"] | components["schemas"]["Krea2LoRALoaderOutput"] | components["schemas"]["Krea2ModelLoaderOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["LatentsMetaOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["LoRALoaderOutput"] | components["schemas"]["LoRASelectorOutput"] | components["schemas"]["MDControlListOutput"] | components["schemas"]["MDIPAdapterListOutput"] | components["schemas"]["MDT2IAdapterListOutput"] | components["schemas"]["MaskOutput"] | components["schemas"]["MetadataItemOutput"] | components["schemas"]["MetadataOutput"] | components["schemas"]["MetadataToLorasCollectionOutput"] | components["schemas"]["MetadataToModelOutput"] | components["schemas"]["MetadataToSDXLModelOutput"] | components["schemas"]["ModelIdentifierOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["PBRMapsOutput"] | components["schemas"]["PairTileImageOutput"] | components["schemas"]["PiDDecoderOutput"] | components["schemas"]["PromptTemplateOutput"] | components["schemas"]["QwenImageConditioningOutput"] | components["schemas"]["QwenImageLoRALoaderOutput"] | components["schemas"]["QwenImageModelLoaderOutput"] | components["schemas"]["SD3ConditioningOutput"] | components["schemas"]["SDXLLoRALoaderOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["Sd3ModelLoaderOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["String2Output"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["StringGeneratorOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["StringPosNegOutput"] | components["schemas"]["T2IAdapterOutput"] | components["schemas"]["TileToPropertiesOutput"] | components["schemas"]["UNetOutput"] | components["schemas"]["VAEOutput"] | components["schemas"]["VideoOutput"] | components["schemas"]["WanConditioningOutput"] | components["schemas"]["WanLoRALoaderOutput"] | components["schemas"]["WanModelLoaderOutput"] | components["schemas"]["WanRefImageOutput"] | components["schemas"]["WorkflowReturnGetOutput"] | components["schemas"]["WorkflowReturnOutput"] | components["schemas"]["WorkflowReturnValueOutput"] | components["schemas"]["ZImageConditioningOutput"] | components["schemas"]["ZImageControlOutput"] | components["schemas"]["ZImageLoRALoaderOutput"] | components["schemas"]["ZImageModelLoaderOutput"];
+ [key: string]: components["schemas"]["AnimaConditioningOutput"] | components["schemas"]["AnimaLLLiteOutput"] | components["schemas"]["AnimaLoRALoaderOutput"] | components["schemas"]["AnimaModelLoaderOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["BooleanOutput"] | components["schemas"]["BoundingBoxCollectionOutput"] | components["schemas"]["BoundingBoxOutput"] | components["schemas"]["CLIPOutput"] | components["schemas"]["CLIPSkipInvocationOutput"] | components["schemas"]["CalculateImageTilesOutput"] | components["schemas"]["CogView4ConditioningOutput"] | components["schemas"]["CogView4ModelLoaderOutput"] | components["schemas"]["CollectInvocationOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["ErnieImageConditioningOutput"] | components["schemas"]["ErnieImageModelLoaderOutput"] | components["schemas"]["ExtractVideoRangeOutput"] | components["schemas"]["FaceMaskOutput"] | components["schemas"]["FaceOffOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["FloatGeneratorOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["Flux2DevLoRALoaderOutput"] | components["schemas"]["Flux2DevModelLoaderOutput"] | components["schemas"]["Flux2KleinLoRALoaderOutput"] | components["schemas"]["Flux2KleinModelLoaderOutput"] | components["schemas"]["FluxConditioningCollectionOutput"] | components["schemas"]["FluxConditioningOutput"] | components["schemas"]["FluxControlLoRALoaderOutput"] | components["schemas"]["FluxControlNetOutput"] | components["schemas"]["FluxFillOutput"] | components["schemas"]["FluxKontextOutput"] | components["schemas"]["FluxLoRALoaderOutput"] | components["schemas"]["FluxModelLoaderOutput"] | components["schemas"]["FluxReduxOutput"] | components["schemas"]["Gemma2EncoderOutput"] | components["schemas"]["GradientMaskOutput"] | components["schemas"]["IPAdapterOutput"] | components["schemas"]["IdealSizeOutput"] | components["schemas"]["Ideogram4ConditioningOutput"] | components["schemas"]["Ideogram4ModelLoaderOutput"] | components["schemas"]["IfInvocationOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["ImageGeneratorOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["ImagePanelCoordinateOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["IntegerGeneratorOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["Krea2ConditioningOutput"] | components["schemas"]["Krea2LoRALoaderOutput"] | components["schemas"]["Krea2ModelLoaderOutput"] | components["schemas"]["Krea2StyleReferenceOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["LatentsMetaOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["LoRALoaderOutput"] | components["schemas"]["LoRASelectorOutput"] | components["schemas"]["MDControlListOutput"] | components["schemas"]["MDIPAdapterListOutput"] | components["schemas"]["MDT2IAdapterListOutput"] | components["schemas"]["MaskOutput"] | components["schemas"]["MetadataItemOutput"] | components["schemas"]["MetadataOutput"] | components["schemas"]["MetadataToLorasCollectionOutput"] | components["schemas"]["MetadataToModelOutput"] | components["schemas"]["MetadataToSDXLModelOutput"] | components["schemas"]["ModelIdentifierOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["PBRMapsOutput"] | components["schemas"]["PairTileImageOutput"] | components["schemas"]["PiDDecoderOutput"] | components["schemas"]["PromptTemplateOutput"] | components["schemas"]["QwenImageConditioningOutput"] | components["schemas"]["QwenImageLoRALoaderOutput"] | components["schemas"]["QwenImageModelLoaderOutput"] | components["schemas"]["SD3ConditioningOutput"] | components["schemas"]["SDXLLoRALoaderOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["Sd3ModelLoaderOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["String2Output"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["StringGeneratorOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["StringPosNegOutput"] | components["schemas"]["T2IAdapterOutput"] | components["schemas"]["TileToPropertiesOutput"] | components["schemas"]["UNetOutput"] | components["schemas"]["VAEOutput"] | components["schemas"]["VideoOutput"] | components["schemas"]["WanConditioningOutput"] | components["schemas"]["WanLoRALoaderOutput"] | components["schemas"]["WanModelLoaderOutput"] | components["schemas"]["WanRefImageOutput"] | components["schemas"]["WorkflowReturnGetOutput"] | components["schemas"]["WorkflowReturnOutput"] | components["schemas"]["WorkflowReturnValueOutput"] | components["schemas"]["ZImageConditioningOutput"] | components["schemas"]["ZImageControlOutput"] | components["schemas"]["ZImageLoRALoaderOutput"] | components["schemas"]["ZImageModelLoaderOutput"];
};
/**
* Errors
@@ -18333,7 +18333,7 @@ export type components = {
* Invocation
* @description The ID of the invocation
*/
- invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlibabaCloudImageGenerationInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["AnimaDenoiseInvocation"] | components["schemas"]["AnimaImageToLatentsInvocation"] | components["schemas"]["AnimaLLLiteInvocation"] | components["schemas"]["AnimaLatentsToImageInvocation"] | components["schemas"]["AnimaLoRACollectionLoader"] | components["schemas"]["AnimaLoRALoaderInvocation"] | components["schemas"]["AnimaModelLoaderInvocation"] | components["schemas"]["AnimaTextEncoderInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CallSavedWorkflowInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasOutputInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DecodeInvisibleWatermarkInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ErnieImageDenoiseInvocation"] | components["schemas"]["ErnieImageModelLoaderInvocation"] | components["schemas"]["ErnieImagePromptEnhancerInvocation"] | components["schemas"]["ErnieImageTextEncoderInvocation"] | components["schemas"]["ErnieImageVaeDecodeInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["ExtractVideoRangeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["Flux2DenoiseInvocation"] | components["schemas"]["Flux2DevLoRACollectionLoader"] | components["schemas"]["Flux2DevLoRALoaderInvocation"] | components["schemas"]["Flux2DevModelLoaderInvocation"] | components["schemas"]["Flux2DevTextEncoderInvocation"] | components["schemas"]["Flux2KleinLoRACollectionLoader"] | components["schemas"]["Flux2KleinLoRALoaderInvocation"] | components["schemas"]["Flux2KleinModelLoaderInvocation"] | components["schemas"]["Flux2KleinTextEncoderInvocation"] | components["schemas"]["Flux2PiDDecodeInvocation"] | components["schemas"]["Flux2VaeDecodeInvocation"] | components["schemas"]["Flux2VaeEncodeInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxPiDDecodeInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GeminiImageGenerationInvocation"] | components["schemas"]["Gemma2EncoderLoaderInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["Ideogram4CaptionBuilderInvocation"] | components["schemas"]["Ideogram4DenoiseInvocation"] | components["schemas"]["Ideogram4LatentsToImageInvocation"] | components["schemas"]["Ideogram4ModelLoaderInvocation"] | components["schemas"]["Ideogram4TextEncoderInvocation"] | components["schemas"]["IfInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["Krea2ConditioningRebalanceInvocation"] | components["schemas"]["Krea2DenoiseInvocation"] | components["schemas"]["Krea2LoRACollectionLoader"] | components["schemas"]["Krea2LoRALoaderInvocation"] | components["schemas"]["Krea2ModelLoaderInvocation"] | components["schemas"]["Krea2SeedVarianceInvocation"] | components["schemas"]["Krea2TextEncoderInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["OklabUnsharpMaskInvocation"] | components["schemas"]["OklchImageHueAdjustmentInvocation"] | components["schemas"]["OpenAIImageGenerationInvocation"] | components["schemas"]["PBRMapsInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDDecoderLoaderInvocation"] | components["schemas"]["PiDUpscaleInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptTemplateInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["QwenImageDenoiseInvocation"] | components["schemas"]["QwenImageImageToLatentsInvocation"] | components["schemas"]["QwenImageLatentsToImageInvocation"] | components["schemas"]["QwenImageLoRACollectionLoader"] | components["schemas"]["QwenImageLoRALoaderInvocation"] | components["schemas"]["QwenImageModelLoaderInvocation"] | components["schemas"]["QwenImagePiDDecodeInvocation"] | components["schemas"]["QwenImageTextEncoderInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SD3PiDDecodeInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLPiDDecodeInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["SaveImageToFileInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SeedreamImageGenerationInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TextLLMInvocation"] | components["schemas"]["TextLLMWithPresetInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"] | components["schemas"]["VideoConcatInvocation"] | components["schemas"]["VideoFrameExtractInvocation"] | components["schemas"]["VideoInvocation"] | components["schemas"]["WanDenoiseInvocation"] | components["schemas"]["WanI2VIdealDimensionsInvocation"] | components["schemas"]["WanImageToLatentsInvocation"] | components["schemas"]["WanLatentsToImageInvocation"] | components["schemas"]["WanLatentsToVideoInvocation"] | components["schemas"]["WanLoRACollectionLoader"] | components["schemas"]["WanLoRALoaderInvocation"] | components["schemas"]["WanModelLoaderInvocation"] | components["schemas"]["WanRefImageEncoderInvocation"] | components["schemas"]["WanTI2VIdealDimensionsInvocation"] | components["schemas"]["WanTextEncoderInvocation"] | components["schemas"]["WanVideoDenoiseInvocation"] | components["schemas"]["WorkflowReturnGetInvocation"] | components["schemas"]["WorkflowReturnInvocation"] | components["schemas"]["WorkflowReturnValueInvocation"] | components["schemas"]["ZImageControlInvocation"] | components["schemas"]["ZImageDenoiseInvocation"] | components["schemas"]["ZImageDenoiseMetaInvocation"] | components["schemas"]["ZImageImageToLatentsInvocation"] | components["schemas"]["ZImageLatentsToImageInvocation"] | components["schemas"]["ZImageLoRACollectionLoader"] | components["schemas"]["ZImageLoRALoaderInvocation"] | components["schemas"]["ZImageModelLoaderInvocation"] | components["schemas"]["ZImagePiDDecodeInvocation"] | components["schemas"]["ZImageSeedVarianceEnhancerInvocation"] | components["schemas"]["ZImageTextEncoderInvocation"];
+ invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlibabaCloudImageGenerationInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["AnimaDenoiseInvocation"] | components["schemas"]["AnimaImageToLatentsInvocation"] | components["schemas"]["AnimaLLLiteInvocation"] | components["schemas"]["AnimaLatentsToImageInvocation"] | components["schemas"]["AnimaLoRACollectionLoader"] | components["schemas"]["AnimaLoRALoaderInvocation"] | components["schemas"]["AnimaModelLoaderInvocation"] | components["schemas"]["AnimaTextEncoderInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CallSavedWorkflowInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasOutputInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DecodeInvisibleWatermarkInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ErnieImageDenoiseInvocation"] | components["schemas"]["ErnieImageModelLoaderInvocation"] | components["schemas"]["ErnieImagePromptEnhancerInvocation"] | components["schemas"]["ErnieImageTextEncoderInvocation"] | components["schemas"]["ErnieImageVaeDecodeInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["ExtractVideoRangeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["Flux2DenoiseInvocation"] | components["schemas"]["Flux2DevLoRACollectionLoader"] | components["schemas"]["Flux2DevLoRALoaderInvocation"] | components["schemas"]["Flux2DevModelLoaderInvocation"] | components["schemas"]["Flux2DevTextEncoderInvocation"] | components["schemas"]["Flux2KleinLoRACollectionLoader"] | components["schemas"]["Flux2KleinLoRALoaderInvocation"] | components["schemas"]["Flux2KleinModelLoaderInvocation"] | components["schemas"]["Flux2KleinTextEncoderInvocation"] | components["schemas"]["Flux2PiDDecodeInvocation"] | components["schemas"]["Flux2VaeDecodeInvocation"] | components["schemas"]["Flux2VaeEncodeInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxPiDDecodeInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GeminiImageGenerationInvocation"] | components["schemas"]["Gemma2EncoderLoaderInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["Ideogram4CaptionBuilderInvocation"] | components["schemas"]["Ideogram4DenoiseInvocation"] | components["schemas"]["Ideogram4LatentsToImageInvocation"] | components["schemas"]["Ideogram4ModelLoaderInvocation"] | components["schemas"]["Ideogram4TextEncoderInvocation"] | components["schemas"]["IfInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["Krea2ConditioningRebalanceInvocation"] | components["schemas"]["Krea2DenoiseInvocation"] | components["schemas"]["Krea2LoRACollectionLoader"] | components["schemas"]["Krea2LoRALoaderInvocation"] | components["schemas"]["Krea2ModelLoaderInvocation"] | components["schemas"]["Krea2SeedVarianceInvocation"] | components["schemas"]["Krea2StyleReferenceInvocation"] | components["schemas"]["Krea2TextEncoderInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["OklabUnsharpMaskInvocation"] | components["schemas"]["OklchImageHueAdjustmentInvocation"] | components["schemas"]["OpenAIImageGenerationInvocation"] | components["schemas"]["PBRMapsInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDDecoderLoaderInvocation"] | components["schemas"]["PiDUpscaleInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptTemplateInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["QwenImageDenoiseInvocation"] | components["schemas"]["QwenImageImageToLatentsInvocation"] | components["schemas"]["QwenImageLatentsToImageInvocation"] | components["schemas"]["QwenImageLoRACollectionLoader"] | components["schemas"]["QwenImageLoRALoaderInvocation"] | components["schemas"]["QwenImageModelLoaderInvocation"] | components["schemas"]["QwenImagePiDDecodeInvocation"] | components["schemas"]["QwenImageTextEncoderInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SD3PiDDecodeInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLPiDDecodeInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["SaveImageToFileInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SeedreamImageGenerationInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TextLLMInvocation"] | components["schemas"]["TextLLMWithPresetInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"] | components["schemas"]["VideoConcatInvocation"] | components["schemas"]["VideoFrameExtractInvocation"] | components["schemas"]["VideoInvocation"] | components["schemas"]["WanDenoiseInvocation"] | components["schemas"]["WanI2VIdealDimensionsInvocation"] | components["schemas"]["WanImageToLatentsInvocation"] | components["schemas"]["WanLatentsToImageInvocation"] | components["schemas"]["WanLatentsToVideoInvocation"] | components["schemas"]["WanLoRACollectionLoader"] | components["schemas"]["WanLoRALoaderInvocation"] | components["schemas"]["WanModelLoaderInvocation"] | components["schemas"]["WanRefImageEncoderInvocation"] | components["schemas"]["WanTI2VIdealDimensionsInvocation"] | components["schemas"]["WanTextEncoderInvocation"] | components["schemas"]["WanVideoDenoiseInvocation"] | components["schemas"]["WorkflowReturnGetInvocation"] | components["schemas"]["WorkflowReturnInvocation"] | components["schemas"]["WorkflowReturnValueInvocation"] | components["schemas"]["ZImageControlInvocation"] | components["schemas"]["ZImageDenoiseInvocation"] | components["schemas"]["ZImageDenoiseMetaInvocation"] | components["schemas"]["ZImageImageToLatentsInvocation"] | components["schemas"]["ZImageLatentsToImageInvocation"] | components["schemas"]["ZImageLoRACollectionLoader"] | components["schemas"]["ZImageLoRALoaderInvocation"] | components["schemas"]["ZImageModelLoaderInvocation"] | components["schemas"]["ZImagePiDDecodeInvocation"] | components["schemas"]["ZImageSeedVarianceEnhancerInvocation"] | components["schemas"]["ZImageTextEncoderInvocation"];
/**
* Invocation Source Id
* @description The ID of the prepared invocation's source node
@@ -18343,7 +18343,7 @@ export type components = {
* Result
* @description The result of the invocation
*/
- result: components["schemas"]["AnimaConditioningOutput"] | components["schemas"]["AnimaLLLiteOutput"] | components["schemas"]["AnimaLoRALoaderOutput"] | components["schemas"]["AnimaModelLoaderOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["BooleanOutput"] | components["schemas"]["BoundingBoxCollectionOutput"] | components["schemas"]["BoundingBoxOutput"] | components["schemas"]["CLIPOutput"] | components["schemas"]["CLIPSkipInvocationOutput"] | components["schemas"]["CalculateImageTilesOutput"] | components["schemas"]["CogView4ConditioningOutput"] | components["schemas"]["CogView4ModelLoaderOutput"] | components["schemas"]["CollectInvocationOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["ErnieImageConditioningOutput"] | components["schemas"]["ErnieImageModelLoaderOutput"] | components["schemas"]["ExtractVideoRangeOutput"] | components["schemas"]["FaceMaskOutput"] | components["schemas"]["FaceOffOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["FloatGeneratorOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["Flux2DevLoRALoaderOutput"] | components["schemas"]["Flux2DevModelLoaderOutput"] | components["schemas"]["Flux2KleinLoRALoaderOutput"] | components["schemas"]["Flux2KleinModelLoaderOutput"] | components["schemas"]["FluxConditioningCollectionOutput"] | components["schemas"]["FluxConditioningOutput"] | components["schemas"]["FluxControlLoRALoaderOutput"] | components["schemas"]["FluxControlNetOutput"] | components["schemas"]["FluxFillOutput"] | components["schemas"]["FluxKontextOutput"] | components["schemas"]["FluxLoRALoaderOutput"] | components["schemas"]["FluxModelLoaderOutput"] | components["schemas"]["FluxReduxOutput"] | components["schemas"]["Gemma2EncoderOutput"] | components["schemas"]["GradientMaskOutput"] | components["schemas"]["IPAdapterOutput"] | components["schemas"]["IdealSizeOutput"] | components["schemas"]["Ideogram4ConditioningOutput"] | components["schemas"]["Ideogram4ModelLoaderOutput"] | components["schemas"]["IfInvocationOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["ImageGeneratorOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["ImagePanelCoordinateOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["IntegerGeneratorOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["Krea2ConditioningOutput"] | components["schemas"]["Krea2LoRALoaderOutput"] | components["schemas"]["Krea2ModelLoaderOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["LatentsMetaOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["LoRALoaderOutput"] | components["schemas"]["LoRASelectorOutput"] | components["schemas"]["MDControlListOutput"] | components["schemas"]["MDIPAdapterListOutput"] | components["schemas"]["MDT2IAdapterListOutput"] | components["schemas"]["MaskOutput"] | components["schemas"]["MetadataItemOutput"] | components["schemas"]["MetadataOutput"] | components["schemas"]["MetadataToLorasCollectionOutput"] | components["schemas"]["MetadataToModelOutput"] | components["schemas"]["MetadataToSDXLModelOutput"] | components["schemas"]["ModelIdentifierOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["PBRMapsOutput"] | components["schemas"]["PairTileImageOutput"] | components["schemas"]["PiDDecoderOutput"] | components["schemas"]["PromptTemplateOutput"] | components["schemas"]["QwenImageConditioningOutput"] | components["schemas"]["QwenImageLoRALoaderOutput"] | components["schemas"]["QwenImageModelLoaderOutput"] | components["schemas"]["SD3ConditioningOutput"] | components["schemas"]["SDXLLoRALoaderOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["Sd3ModelLoaderOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["String2Output"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["StringGeneratorOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["StringPosNegOutput"] | components["schemas"]["T2IAdapterOutput"] | components["schemas"]["TileToPropertiesOutput"] | components["schemas"]["UNetOutput"] | components["schemas"]["VAEOutput"] | components["schemas"]["VideoOutput"] | components["schemas"]["WanConditioningOutput"] | components["schemas"]["WanLoRALoaderOutput"] | components["schemas"]["WanModelLoaderOutput"] | components["schemas"]["WanRefImageOutput"] | components["schemas"]["WorkflowReturnGetOutput"] | components["schemas"]["WorkflowReturnOutput"] | components["schemas"]["WorkflowReturnValueOutput"] | components["schemas"]["ZImageConditioningOutput"] | components["schemas"]["ZImageControlOutput"] | components["schemas"]["ZImageLoRALoaderOutput"] | components["schemas"]["ZImageModelLoaderOutput"];
+ result: components["schemas"]["AnimaConditioningOutput"] | components["schemas"]["AnimaLLLiteOutput"] | components["schemas"]["AnimaLoRALoaderOutput"] | components["schemas"]["AnimaModelLoaderOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["BooleanOutput"] | components["schemas"]["BoundingBoxCollectionOutput"] | components["schemas"]["BoundingBoxOutput"] | components["schemas"]["CLIPOutput"] | components["schemas"]["CLIPSkipInvocationOutput"] | components["schemas"]["CalculateImageTilesOutput"] | components["schemas"]["CogView4ConditioningOutput"] | components["schemas"]["CogView4ModelLoaderOutput"] | components["schemas"]["CollectInvocationOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["ErnieImageConditioningOutput"] | components["schemas"]["ErnieImageModelLoaderOutput"] | components["schemas"]["ExtractVideoRangeOutput"] | components["schemas"]["FaceMaskOutput"] | components["schemas"]["FaceOffOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["FloatGeneratorOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["Flux2DevLoRALoaderOutput"] | components["schemas"]["Flux2DevModelLoaderOutput"] | components["schemas"]["Flux2KleinLoRALoaderOutput"] | components["schemas"]["Flux2KleinModelLoaderOutput"] | components["schemas"]["FluxConditioningCollectionOutput"] | components["schemas"]["FluxConditioningOutput"] | components["schemas"]["FluxControlLoRALoaderOutput"] | components["schemas"]["FluxControlNetOutput"] | components["schemas"]["FluxFillOutput"] | components["schemas"]["FluxKontextOutput"] | components["schemas"]["FluxLoRALoaderOutput"] | components["schemas"]["FluxModelLoaderOutput"] | components["schemas"]["FluxReduxOutput"] | components["schemas"]["Gemma2EncoderOutput"] | components["schemas"]["GradientMaskOutput"] | components["schemas"]["IPAdapterOutput"] | components["schemas"]["IdealSizeOutput"] | components["schemas"]["Ideogram4ConditioningOutput"] | components["schemas"]["Ideogram4ModelLoaderOutput"] | components["schemas"]["IfInvocationOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["ImageGeneratorOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["ImagePanelCoordinateOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["IntegerGeneratorOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["Krea2ConditioningOutput"] | components["schemas"]["Krea2LoRALoaderOutput"] | components["schemas"]["Krea2ModelLoaderOutput"] | components["schemas"]["Krea2StyleReferenceOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["LatentsMetaOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["LoRALoaderOutput"] | components["schemas"]["LoRASelectorOutput"] | components["schemas"]["MDControlListOutput"] | components["schemas"]["MDIPAdapterListOutput"] | components["schemas"]["MDT2IAdapterListOutput"] | components["schemas"]["MaskOutput"] | components["schemas"]["MetadataItemOutput"] | components["schemas"]["MetadataOutput"] | components["schemas"]["MetadataToLorasCollectionOutput"] | components["schemas"]["MetadataToModelOutput"] | components["schemas"]["MetadataToSDXLModelOutput"] | components["schemas"]["ModelIdentifierOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["PBRMapsOutput"] | components["schemas"]["PairTileImageOutput"] | components["schemas"]["PiDDecoderOutput"] | components["schemas"]["PromptTemplateOutput"] | components["schemas"]["QwenImageConditioningOutput"] | components["schemas"]["QwenImageLoRALoaderOutput"] | components["schemas"]["QwenImageModelLoaderOutput"] | components["schemas"]["SD3ConditioningOutput"] | components["schemas"]["SDXLLoRALoaderOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["Sd3ModelLoaderOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["String2Output"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["StringGeneratorOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["StringPosNegOutput"] | components["schemas"]["T2IAdapterOutput"] | components["schemas"]["TileToPropertiesOutput"] | components["schemas"]["UNetOutput"] | components["schemas"]["VAEOutput"] | components["schemas"]["VideoOutput"] | components["schemas"]["WanConditioningOutput"] | components["schemas"]["WanLoRALoaderOutput"] | components["schemas"]["WanModelLoaderOutput"] | components["schemas"]["WanRefImageOutput"] | components["schemas"]["WorkflowReturnGetOutput"] | components["schemas"]["WorkflowReturnOutput"] | components["schemas"]["WorkflowReturnValueOutput"] | components["schemas"]["ZImageConditioningOutput"] | components["schemas"]["ZImageControlOutput"] | components["schemas"]["ZImageLoRALoaderOutput"] | components["schemas"]["ZImageModelLoaderOutput"];
};
/**
* InvocationErrorEvent
@@ -18397,7 +18397,7 @@ export type components = {
* Invocation
* @description The ID of the invocation
*/
- invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlibabaCloudImageGenerationInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["AnimaDenoiseInvocation"] | components["schemas"]["AnimaImageToLatentsInvocation"] | components["schemas"]["AnimaLLLiteInvocation"] | components["schemas"]["AnimaLatentsToImageInvocation"] | components["schemas"]["AnimaLoRACollectionLoader"] | components["schemas"]["AnimaLoRALoaderInvocation"] | components["schemas"]["AnimaModelLoaderInvocation"] | components["schemas"]["AnimaTextEncoderInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CallSavedWorkflowInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasOutputInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DecodeInvisibleWatermarkInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ErnieImageDenoiseInvocation"] | components["schemas"]["ErnieImageModelLoaderInvocation"] | components["schemas"]["ErnieImagePromptEnhancerInvocation"] | components["schemas"]["ErnieImageTextEncoderInvocation"] | components["schemas"]["ErnieImageVaeDecodeInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["ExtractVideoRangeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["Flux2DenoiseInvocation"] | components["schemas"]["Flux2DevLoRACollectionLoader"] | components["schemas"]["Flux2DevLoRALoaderInvocation"] | components["schemas"]["Flux2DevModelLoaderInvocation"] | components["schemas"]["Flux2DevTextEncoderInvocation"] | components["schemas"]["Flux2KleinLoRACollectionLoader"] | components["schemas"]["Flux2KleinLoRALoaderInvocation"] | components["schemas"]["Flux2KleinModelLoaderInvocation"] | components["schemas"]["Flux2KleinTextEncoderInvocation"] | components["schemas"]["Flux2PiDDecodeInvocation"] | components["schemas"]["Flux2VaeDecodeInvocation"] | components["schemas"]["Flux2VaeEncodeInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxPiDDecodeInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GeminiImageGenerationInvocation"] | components["schemas"]["Gemma2EncoderLoaderInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["Ideogram4CaptionBuilderInvocation"] | components["schemas"]["Ideogram4DenoiseInvocation"] | components["schemas"]["Ideogram4LatentsToImageInvocation"] | components["schemas"]["Ideogram4ModelLoaderInvocation"] | components["schemas"]["Ideogram4TextEncoderInvocation"] | components["schemas"]["IfInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["Krea2ConditioningRebalanceInvocation"] | components["schemas"]["Krea2DenoiseInvocation"] | components["schemas"]["Krea2LoRACollectionLoader"] | components["schemas"]["Krea2LoRALoaderInvocation"] | components["schemas"]["Krea2ModelLoaderInvocation"] | components["schemas"]["Krea2SeedVarianceInvocation"] | components["schemas"]["Krea2TextEncoderInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["OklabUnsharpMaskInvocation"] | components["schemas"]["OklchImageHueAdjustmentInvocation"] | components["schemas"]["OpenAIImageGenerationInvocation"] | components["schemas"]["PBRMapsInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDDecoderLoaderInvocation"] | components["schemas"]["PiDUpscaleInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptTemplateInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["QwenImageDenoiseInvocation"] | components["schemas"]["QwenImageImageToLatentsInvocation"] | components["schemas"]["QwenImageLatentsToImageInvocation"] | components["schemas"]["QwenImageLoRACollectionLoader"] | components["schemas"]["QwenImageLoRALoaderInvocation"] | components["schemas"]["QwenImageModelLoaderInvocation"] | components["schemas"]["QwenImagePiDDecodeInvocation"] | components["schemas"]["QwenImageTextEncoderInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SD3PiDDecodeInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLPiDDecodeInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["SaveImageToFileInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SeedreamImageGenerationInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TextLLMInvocation"] | components["schemas"]["TextLLMWithPresetInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"] | components["schemas"]["VideoConcatInvocation"] | components["schemas"]["VideoFrameExtractInvocation"] | components["schemas"]["VideoInvocation"] | components["schemas"]["WanDenoiseInvocation"] | components["schemas"]["WanI2VIdealDimensionsInvocation"] | components["schemas"]["WanImageToLatentsInvocation"] | components["schemas"]["WanLatentsToImageInvocation"] | components["schemas"]["WanLatentsToVideoInvocation"] | components["schemas"]["WanLoRACollectionLoader"] | components["schemas"]["WanLoRALoaderInvocation"] | components["schemas"]["WanModelLoaderInvocation"] | components["schemas"]["WanRefImageEncoderInvocation"] | components["schemas"]["WanTI2VIdealDimensionsInvocation"] | components["schemas"]["WanTextEncoderInvocation"] | components["schemas"]["WanVideoDenoiseInvocation"] | components["schemas"]["WorkflowReturnGetInvocation"] | components["schemas"]["WorkflowReturnInvocation"] | components["schemas"]["WorkflowReturnValueInvocation"] | components["schemas"]["ZImageControlInvocation"] | components["schemas"]["ZImageDenoiseInvocation"] | components["schemas"]["ZImageDenoiseMetaInvocation"] | components["schemas"]["ZImageImageToLatentsInvocation"] | components["schemas"]["ZImageLatentsToImageInvocation"] | components["schemas"]["ZImageLoRACollectionLoader"] | components["schemas"]["ZImageLoRALoaderInvocation"] | components["schemas"]["ZImageModelLoaderInvocation"] | components["schemas"]["ZImagePiDDecodeInvocation"] | components["schemas"]["ZImageSeedVarianceEnhancerInvocation"] | components["schemas"]["ZImageTextEncoderInvocation"];
+ invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlibabaCloudImageGenerationInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["AnimaDenoiseInvocation"] | components["schemas"]["AnimaImageToLatentsInvocation"] | components["schemas"]["AnimaLLLiteInvocation"] | components["schemas"]["AnimaLatentsToImageInvocation"] | components["schemas"]["AnimaLoRACollectionLoader"] | components["schemas"]["AnimaLoRALoaderInvocation"] | components["schemas"]["AnimaModelLoaderInvocation"] | components["schemas"]["AnimaTextEncoderInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CallSavedWorkflowInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasOutputInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DecodeInvisibleWatermarkInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ErnieImageDenoiseInvocation"] | components["schemas"]["ErnieImageModelLoaderInvocation"] | components["schemas"]["ErnieImagePromptEnhancerInvocation"] | components["schemas"]["ErnieImageTextEncoderInvocation"] | components["schemas"]["ErnieImageVaeDecodeInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["ExtractVideoRangeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["Flux2DenoiseInvocation"] | components["schemas"]["Flux2DevLoRACollectionLoader"] | components["schemas"]["Flux2DevLoRALoaderInvocation"] | components["schemas"]["Flux2DevModelLoaderInvocation"] | components["schemas"]["Flux2DevTextEncoderInvocation"] | components["schemas"]["Flux2KleinLoRACollectionLoader"] | components["schemas"]["Flux2KleinLoRALoaderInvocation"] | components["schemas"]["Flux2KleinModelLoaderInvocation"] | components["schemas"]["Flux2KleinTextEncoderInvocation"] | components["schemas"]["Flux2PiDDecodeInvocation"] | components["schemas"]["Flux2VaeDecodeInvocation"] | components["schemas"]["Flux2VaeEncodeInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxPiDDecodeInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GeminiImageGenerationInvocation"] | components["schemas"]["Gemma2EncoderLoaderInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["Ideogram4CaptionBuilderInvocation"] | components["schemas"]["Ideogram4DenoiseInvocation"] | components["schemas"]["Ideogram4LatentsToImageInvocation"] | components["schemas"]["Ideogram4ModelLoaderInvocation"] | components["schemas"]["Ideogram4TextEncoderInvocation"] | components["schemas"]["IfInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["Krea2ConditioningRebalanceInvocation"] | components["schemas"]["Krea2DenoiseInvocation"] | components["schemas"]["Krea2LoRACollectionLoader"] | components["schemas"]["Krea2LoRALoaderInvocation"] | components["schemas"]["Krea2ModelLoaderInvocation"] | components["schemas"]["Krea2SeedVarianceInvocation"] | components["schemas"]["Krea2StyleReferenceInvocation"] | components["schemas"]["Krea2TextEncoderInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["OklabUnsharpMaskInvocation"] | components["schemas"]["OklchImageHueAdjustmentInvocation"] | components["schemas"]["OpenAIImageGenerationInvocation"] | components["schemas"]["PBRMapsInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDDecoderLoaderInvocation"] | components["schemas"]["PiDUpscaleInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptTemplateInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["QwenImageDenoiseInvocation"] | components["schemas"]["QwenImageImageToLatentsInvocation"] | components["schemas"]["QwenImageLatentsToImageInvocation"] | components["schemas"]["QwenImageLoRACollectionLoader"] | components["schemas"]["QwenImageLoRALoaderInvocation"] | components["schemas"]["QwenImageModelLoaderInvocation"] | components["schemas"]["QwenImagePiDDecodeInvocation"] | components["schemas"]["QwenImageTextEncoderInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SD3PiDDecodeInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLPiDDecodeInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["SaveImageToFileInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SeedreamImageGenerationInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TextLLMInvocation"] | components["schemas"]["TextLLMWithPresetInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"] | components["schemas"]["VideoConcatInvocation"] | components["schemas"]["VideoFrameExtractInvocation"] | components["schemas"]["VideoInvocation"] | components["schemas"]["WanDenoiseInvocation"] | components["schemas"]["WanI2VIdealDimensionsInvocation"] | components["schemas"]["WanImageToLatentsInvocation"] | components["schemas"]["WanLatentsToImageInvocation"] | components["schemas"]["WanLatentsToVideoInvocation"] | components["schemas"]["WanLoRACollectionLoader"] | components["schemas"]["WanLoRALoaderInvocation"] | components["schemas"]["WanModelLoaderInvocation"] | components["schemas"]["WanRefImageEncoderInvocation"] | components["schemas"]["WanTI2VIdealDimensionsInvocation"] | components["schemas"]["WanTextEncoderInvocation"] | components["schemas"]["WanVideoDenoiseInvocation"] | components["schemas"]["WorkflowReturnGetInvocation"] | components["schemas"]["WorkflowReturnInvocation"] | components["schemas"]["WorkflowReturnValueInvocation"] | components["schemas"]["ZImageControlInvocation"] | components["schemas"]["ZImageDenoiseInvocation"] | components["schemas"]["ZImageDenoiseMetaInvocation"] | components["schemas"]["ZImageImageToLatentsInvocation"] | components["schemas"]["ZImageLatentsToImageInvocation"] | components["schemas"]["ZImageLoRACollectionLoader"] | components["schemas"]["ZImageLoRALoaderInvocation"] | components["schemas"]["ZImageModelLoaderInvocation"] | components["schemas"]["ZImagePiDDecodeInvocation"] | components["schemas"]["ZImageSeedVarianceEnhancerInvocation"] | components["schemas"]["ZImageTextEncoderInvocation"];
/**
* Invocation Source Id
* @description The ID of the prepared invocation's source node
@@ -18584,6 +18584,7 @@ export type components = {
krea2_lora_loader: components["schemas"]["Krea2LoRALoaderOutput"];
krea2_model_loader: components["schemas"]["Krea2ModelLoaderOutput"];
krea2_seed_variance: components["schemas"]["Krea2ConditioningOutput"];
+ krea2_style_reference: components["schemas"]["Krea2StyleReferenceOutput"];
krea2_text_encoder: components["schemas"]["Krea2ConditioningOutput"];
l2i: components["schemas"]["ImageOutput"];
latents: components["schemas"]["LatentsOutput"];
@@ -18780,7 +18781,7 @@ export type components = {
* Invocation
* @description The ID of the invocation
*/
- invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlibabaCloudImageGenerationInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["AnimaDenoiseInvocation"] | components["schemas"]["AnimaImageToLatentsInvocation"] | components["schemas"]["AnimaLLLiteInvocation"] | components["schemas"]["AnimaLatentsToImageInvocation"] | components["schemas"]["AnimaLoRACollectionLoader"] | components["schemas"]["AnimaLoRALoaderInvocation"] | components["schemas"]["AnimaModelLoaderInvocation"] | components["schemas"]["AnimaTextEncoderInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CallSavedWorkflowInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasOutputInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DecodeInvisibleWatermarkInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ErnieImageDenoiseInvocation"] | components["schemas"]["ErnieImageModelLoaderInvocation"] | components["schemas"]["ErnieImagePromptEnhancerInvocation"] | components["schemas"]["ErnieImageTextEncoderInvocation"] | components["schemas"]["ErnieImageVaeDecodeInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["ExtractVideoRangeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["Flux2DenoiseInvocation"] | components["schemas"]["Flux2DevLoRACollectionLoader"] | components["schemas"]["Flux2DevLoRALoaderInvocation"] | components["schemas"]["Flux2DevModelLoaderInvocation"] | components["schemas"]["Flux2DevTextEncoderInvocation"] | components["schemas"]["Flux2KleinLoRACollectionLoader"] | components["schemas"]["Flux2KleinLoRALoaderInvocation"] | components["schemas"]["Flux2KleinModelLoaderInvocation"] | components["schemas"]["Flux2KleinTextEncoderInvocation"] | components["schemas"]["Flux2PiDDecodeInvocation"] | components["schemas"]["Flux2VaeDecodeInvocation"] | components["schemas"]["Flux2VaeEncodeInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxPiDDecodeInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GeminiImageGenerationInvocation"] | components["schemas"]["Gemma2EncoderLoaderInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["Ideogram4CaptionBuilderInvocation"] | components["schemas"]["Ideogram4DenoiseInvocation"] | components["schemas"]["Ideogram4LatentsToImageInvocation"] | components["schemas"]["Ideogram4ModelLoaderInvocation"] | components["schemas"]["Ideogram4TextEncoderInvocation"] | components["schemas"]["IfInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["Krea2ConditioningRebalanceInvocation"] | components["schemas"]["Krea2DenoiseInvocation"] | components["schemas"]["Krea2LoRACollectionLoader"] | components["schemas"]["Krea2LoRALoaderInvocation"] | components["schemas"]["Krea2ModelLoaderInvocation"] | components["schemas"]["Krea2SeedVarianceInvocation"] | components["schemas"]["Krea2TextEncoderInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["OklabUnsharpMaskInvocation"] | components["schemas"]["OklchImageHueAdjustmentInvocation"] | components["schemas"]["OpenAIImageGenerationInvocation"] | components["schemas"]["PBRMapsInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDDecoderLoaderInvocation"] | components["schemas"]["PiDUpscaleInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptTemplateInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["QwenImageDenoiseInvocation"] | components["schemas"]["QwenImageImageToLatentsInvocation"] | components["schemas"]["QwenImageLatentsToImageInvocation"] | components["schemas"]["QwenImageLoRACollectionLoader"] | components["schemas"]["QwenImageLoRALoaderInvocation"] | components["schemas"]["QwenImageModelLoaderInvocation"] | components["schemas"]["QwenImagePiDDecodeInvocation"] | components["schemas"]["QwenImageTextEncoderInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SD3PiDDecodeInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLPiDDecodeInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["SaveImageToFileInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SeedreamImageGenerationInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TextLLMInvocation"] | components["schemas"]["TextLLMWithPresetInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"] | components["schemas"]["VideoConcatInvocation"] | components["schemas"]["VideoFrameExtractInvocation"] | components["schemas"]["VideoInvocation"] | components["schemas"]["WanDenoiseInvocation"] | components["schemas"]["WanI2VIdealDimensionsInvocation"] | components["schemas"]["WanImageToLatentsInvocation"] | components["schemas"]["WanLatentsToImageInvocation"] | components["schemas"]["WanLatentsToVideoInvocation"] | components["schemas"]["WanLoRACollectionLoader"] | components["schemas"]["WanLoRALoaderInvocation"] | components["schemas"]["WanModelLoaderInvocation"] | components["schemas"]["WanRefImageEncoderInvocation"] | components["schemas"]["WanTI2VIdealDimensionsInvocation"] | components["schemas"]["WanTextEncoderInvocation"] | components["schemas"]["WanVideoDenoiseInvocation"] | components["schemas"]["WorkflowReturnGetInvocation"] | components["schemas"]["WorkflowReturnInvocation"] | components["schemas"]["WorkflowReturnValueInvocation"] | components["schemas"]["ZImageControlInvocation"] | components["schemas"]["ZImageDenoiseInvocation"] | components["schemas"]["ZImageDenoiseMetaInvocation"] | components["schemas"]["ZImageImageToLatentsInvocation"] | components["schemas"]["ZImageLatentsToImageInvocation"] | components["schemas"]["ZImageLoRACollectionLoader"] | components["schemas"]["ZImageLoRALoaderInvocation"] | components["schemas"]["ZImageModelLoaderInvocation"] | components["schemas"]["ZImagePiDDecodeInvocation"] | components["schemas"]["ZImageSeedVarianceEnhancerInvocation"] | components["schemas"]["ZImageTextEncoderInvocation"];
+ invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlibabaCloudImageGenerationInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["AnimaDenoiseInvocation"] | components["schemas"]["AnimaImageToLatentsInvocation"] | components["schemas"]["AnimaLLLiteInvocation"] | components["schemas"]["AnimaLatentsToImageInvocation"] | components["schemas"]["AnimaLoRACollectionLoader"] | components["schemas"]["AnimaLoRALoaderInvocation"] | components["schemas"]["AnimaModelLoaderInvocation"] | components["schemas"]["AnimaTextEncoderInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CallSavedWorkflowInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasOutputInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DecodeInvisibleWatermarkInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ErnieImageDenoiseInvocation"] | components["schemas"]["ErnieImageModelLoaderInvocation"] | components["schemas"]["ErnieImagePromptEnhancerInvocation"] | components["schemas"]["ErnieImageTextEncoderInvocation"] | components["schemas"]["ErnieImageVaeDecodeInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["ExtractVideoRangeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["Flux2DenoiseInvocation"] | components["schemas"]["Flux2DevLoRACollectionLoader"] | components["schemas"]["Flux2DevLoRALoaderInvocation"] | components["schemas"]["Flux2DevModelLoaderInvocation"] | components["schemas"]["Flux2DevTextEncoderInvocation"] | components["schemas"]["Flux2KleinLoRACollectionLoader"] | components["schemas"]["Flux2KleinLoRALoaderInvocation"] | components["schemas"]["Flux2KleinModelLoaderInvocation"] | components["schemas"]["Flux2KleinTextEncoderInvocation"] | components["schemas"]["Flux2PiDDecodeInvocation"] | components["schemas"]["Flux2VaeDecodeInvocation"] | components["schemas"]["Flux2VaeEncodeInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxPiDDecodeInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GeminiImageGenerationInvocation"] | components["schemas"]["Gemma2EncoderLoaderInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["Ideogram4CaptionBuilderInvocation"] | components["schemas"]["Ideogram4DenoiseInvocation"] | components["schemas"]["Ideogram4LatentsToImageInvocation"] | components["schemas"]["Ideogram4ModelLoaderInvocation"] | components["schemas"]["Ideogram4TextEncoderInvocation"] | components["schemas"]["IfInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["Krea2ConditioningRebalanceInvocation"] | components["schemas"]["Krea2DenoiseInvocation"] | components["schemas"]["Krea2LoRACollectionLoader"] | components["schemas"]["Krea2LoRALoaderInvocation"] | components["schemas"]["Krea2ModelLoaderInvocation"] | components["schemas"]["Krea2SeedVarianceInvocation"] | components["schemas"]["Krea2StyleReferenceInvocation"] | components["schemas"]["Krea2TextEncoderInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["OklabUnsharpMaskInvocation"] | components["schemas"]["OklchImageHueAdjustmentInvocation"] | components["schemas"]["OpenAIImageGenerationInvocation"] | components["schemas"]["PBRMapsInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDDecoderLoaderInvocation"] | components["schemas"]["PiDUpscaleInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptTemplateInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["QwenImageDenoiseInvocation"] | components["schemas"]["QwenImageImageToLatentsInvocation"] | components["schemas"]["QwenImageLatentsToImageInvocation"] | components["schemas"]["QwenImageLoRACollectionLoader"] | components["schemas"]["QwenImageLoRALoaderInvocation"] | components["schemas"]["QwenImageModelLoaderInvocation"] | components["schemas"]["QwenImagePiDDecodeInvocation"] | components["schemas"]["QwenImageTextEncoderInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SD3PiDDecodeInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLPiDDecodeInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["SaveImageToFileInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SeedreamImageGenerationInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TextLLMInvocation"] | components["schemas"]["TextLLMWithPresetInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"] | components["schemas"]["VideoConcatInvocation"] | components["schemas"]["VideoFrameExtractInvocation"] | components["schemas"]["VideoInvocation"] | components["schemas"]["WanDenoiseInvocation"] | components["schemas"]["WanI2VIdealDimensionsInvocation"] | components["schemas"]["WanImageToLatentsInvocation"] | components["schemas"]["WanLatentsToImageInvocation"] | components["schemas"]["WanLatentsToVideoInvocation"] | components["schemas"]["WanLoRACollectionLoader"] | components["schemas"]["WanLoRALoaderInvocation"] | components["schemas"]["WanModelLoaderInvocation"] | components["schemas"]["WanRefImageEncoderInvocation"] | components["schemas"]["WanTI2VIdealDimensionsInvocation"] | components["schemas"]["WanTextEncoderInvocation"] | components["schemas"]["WanVideoDenoiseInvocation"] | components["schemas"]["WorkflowReturnGetInvocation"] | components["schemas"]["WorkflowReturnInvocation"] | components["schemas"]["WorkflowReturnValueInvocation"] | components["schemas"]["ZImageControlInvocation"] | components["schemas"]["ZImageDenoiseInvocation"] | components["schemas"]["ZImageDenoiseMetaInvocation"] | components["schemas"]["ZImageImageToLatentsInvocation"] | components["schemas"]["ZImageLatentsToImageInvocation"] | components["schemas"]["ZImageLoRACollectionLoader"] | components["schemas"]["ZImageLoRALoaderInvocation"] | components["schemas"]["ZImageModelLoaderInvocation"] | components["schemas"]["ZImagePiDDecodeInvocation"] | components["schemas"]["ZImageSeedVarianceEnhancerInvocation"] | components["schemas"]["ZImageTextEncoderInvocation"];
/**
* Invocation Source Id
* @description The ID of the prepared invocation's source node
@@ -18861,7 +18862,7 @@ export type components = {
* Invocation
* @description The ID of the invocation
*/
- invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlibabaCloudImageGenerationInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["AnimaDenoiseInvocation"] | components["schemas"]["AnimaImageToLatentsInvocation"] | components["schemas"]["AnimaLLLiteInvocation"] | components["schemas"]["AnimaLatentsToImageInvocation"] | components["schemas"]["AnimaLoRACollectionLoader"] | components["schemas"]["AnimaLoRALoaderInvocation"] | components["schemas"]["AnimaModelLoaderInvocation"] | components["schemas"]["AnimaTextEncoderInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CallSavedWorkflowInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasOutputInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DecodeInvisibleWatermarkInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ErnieImageDenoiseInvocation"] | components["schemas"]["ErnieImageModelLoaderInvocation"] | components["schemas"]["ErnieImagePromptEnhancerInvocation"] | components["schemas"]["ErnieImageTextEncoderInvocation"] | components["schemas"]["ErnieImageVaeDecodeInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["ExtractVideoRangeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["Flux2DenoiseInvocation"] | components["schemas"]["Flux2DevLoRACollectionLoader"] | components["schemas"]["Flux2DevLoRALoaderInvocation"] | components["schemas"]["Flux2DevModelLoaderInvocation"] | components["schemas"]["Flux2DevTextEncoderInvocation"] | components["schemas"]["Flux2KleinLoRACollectionLoader"] | components["schemas"]["Flux2KleinLoRALoaderInvocation"] | components["schemas"]["Flux2KleinModelLoaderInvocation"] | components["schemas"]["Flux2KleinTextEncoderInvocation"] | components["schemas"]["Flux2PiDDecodeInvocation"] | components["schemas"]["Flux2VaeDecodeInvocation"] | components["schemas"]["Flux2VaeEncodeInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxPiDDecodeInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GeminiImageGenerationInvocation"] | components["schemas"]["Gemma2EncoderLoaderInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["Ideogram4CaptionBuilderInvocation"] | components["schemas"]["Ideogram4DenoiseInvocation"] | components["schemas"]["Ideogram4LatentsToImageInvocation"] | components["schemas"]["Ideogram4ModelLoaderInvocation"] | components["schemas"]["Ideogram4TextEncoderInvocation"] | components["schemas"]["IfInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["Krea2ConditioningRebalanceInvocation"] | components["schemas"]["Krea2DenoiseInvocation"] | components["schemas"]["Krea2LoRACollectionLoader"] | components["schemas"]["Krea2LoRALoaderInvocation"] | components["schemas"]["Krea2ModelLoaderInvocation"] | components["schemas"]["Krea2SeedVarianceInvocation"] | components["schemas"]["Krea2TextEncoderInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["OklabUnsharpMaskInvocation"] | components["schemas"]["OklchImageHueAdjustmentInvocation"] | components["schemas"]["OpenAIImageGenerationInvocation"] | components["schemas"]["PBRMapsInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDDecoderLoaderInvocation"] | components["schemas"]["PiDUpscaleInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptTemplateInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["QwenImageDenoiseInvocation"] | components["schemas"]["QwenImageImageToLatentsInvocation"] | components["schemas"]["QwenImageLatentsToImageInvocation"] | components["schemas"]["QwenImageLoRACollectionLoader"] | components["schemas"]["QwenImageLoRALoaderInvocation"] | components["schemas"]["QwenImageModelLoaderInvocation"] | components["schemas"]["QwenImagePiDDecodeInvocation"] | components["schemas"]["QwenImageTextEncoderInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SD3PiDDecodeInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLPiDDecodeInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["SaveImageToFileInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SeedreamImageGenerationInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TextLLMInvocation"] | components["schemas"]["TextLLMWithPresetInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"] | components["schemas"]["VideoConcatInvocation"] | components["schemas"]["VideoFrameExtractInvocation"] | components["schemas"]["VideoInvocation"] | components["schemas"]["WanDenoiseInvocation"] | components["schemas"]["WanI2VIdealDimensionsInvocation"] | components["schemas"]["WanImageToLatentsInvocation"] | components["schemas"]["WanLatentsToImageInvocation"] | components["schemas"]["WanLatentsToVideoInvocation"] | components["schemas"]["WanLoRACollectionLoader"] | components["schemas"]["WanLoRALoaderInvocation"] | components["schemas"]["WanModelLoaderInvocation"] | components["schemas"]["WanRefImageEncoderInvocation"] | components["schemas"]["WanTI2VIdealDimensionsInvocation"] | components["schemas"]["WanTextEncoderInvocation"] | components["schemas"]["WanVideoDenoiseInvocation"] | components["schemas"]["WorkflowReturnGetInvocation"] | components["schemas"]["WorkflowReturnInvocation"] | components["schemas"]["WorkflowReturnValueInvocation"] | components["schemas"]["ZImageControlInvocation"] | components["schemas"]["ZImageDenoiseInvocation"] | components["schemas"]["ZImageDenoiseMetaInvocation"] | components["schemas"]["ZImageImageToLatentsInvocation"] | components["schemas"]["ZImageLatentsToImageInvocation"] | components["schemas"]["ZImageLoRACollectionLoader"] | components["schemas"]["ZImageLoRALoaderInvocation"] | components["schemas"]["ZImageModelLoaderInvocation"] | components["schemas"]["ZImagePiDDecodeInvocation"] | components["schemas"]["ZImageSeedVarianceEnhancerInvocation"] | components["schemas"]["ZImageTextEncoderInvocation"];
+ invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlibabaCloudImageGenerationInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["AnimaDenoiseInvocation"] | components["schemas"]["AnimaImageToLatentsInvocation"] | components["schemas"]["AnimaLLLiteInvocation"] | components["schemas"]["AnimaLatentsToImageInvocation"] | components["schemas"]["AnimaLoRACollectionLoader"] | components["schemas"]["AnimaLoRALoaderInvocation"] | components["schemas"]["AnimaModelLoaderInvocation"] | components["schemas"]["AnimaTextEncoderInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CallSavedWorkflowInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasOutputInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DecodeInvisibleWatermarkInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ErnieImageDenoiseInvocation"] | components["schemas"]["ErnieImageModelLoaderInvocation"] | components["schemas"]["ErnieImagePromptEnhancerInvocation"] | components["schemas"]["ErnieImageTextEncoderInvocation"] | components["schemas"]["ErnieImageVaeDecodeInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["ExtractVideoRangeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["Flux2DenoiseInvocation"] | components["schemas"]["Flux2DevLoRACollectionLoader"] | components["schemas"]["Flux2DevLoRALoaderInvocation"] | components["schemas"]["Flux2DevModelLoaderInvocation"] | components["schemas"]["Flux2DevTextEncoderInvocation"] | components["schemas"]["Flux2KleinLoRACollectionLoader"] | components["schemas"]["Flux2KleinLoRALoaderInvocation"] | components["schemas"]["Flux2KleinModelLoaderInvocation"] | components["schemas"]["Flux2KleinTextEncoderInvocation"] | components["schemas"]["Flux2PiDDecodeInvocation"] | components["schemas"]["Flux2VaeDecodeInvocation"] | components["schemas"]["Flux2VaeEncodeInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxPiDDecodeInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GeminiImageGenerationInvocation"] | components["schemas"]["Gemma2EncoderLoaderInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["Ideogram4CaptionBuilderInvocation"] | components["schemas"]["Ideogram4DenoiseInvocation"] | components["schemas"]["Ideogram4LatentsToImageInvocation"] | components["schemas"]["Ideogram4ModelLoaderInvocation"] | components["schemas"]["Ideogram4TextEncoderInvocation"] | components["schemas"]["IfInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["Krea2ConditioningRebalanceInvocation"] | components["schemas"]["Krea2DenoiseInvocation"] | components["schemas"]["Krea2LoRACollectionLoader"] | components["schemas"]["Krea2LoRALoaderInvocation"] | components["schemas"]["Krea2ModelLoaderInvocation"] | components["schemas"]["Krea2SeedVarianceInvocation"] | components["schemas"]["Krea2StyleReferenceInvocation"] | components["schemas"]["Krea2TextEncoderInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["OklabUnsharpMaskInvocation"] | components["schemas"]["OklchImageHueAdjustmentInvocation"] | components["schemas"]["OpenAIImageGenerationInvocation"] | components["schemas"]["PBRMapsInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDDecoderLoaderInvocation"] | components["schemas"]["PiDUpscaleInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptTemplateInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["QwenImageDenoiseInvocation"] | components["schemas"]["QwenImageImageToLatentsInvocation"] | components["schemas"]["QwenImageLatentsToImageInvocation"] | components["schemas"]["QwenImageLoRACollectionLoader"] | components["schemas"]["QwenImageLoRALoaderInvocation"] | components["schemas"]["QwenImageModelLoaderInvocation"] | components["schemas"]["QwenImagePiDDecodeInvocation"] | components["schemas"]["QwenImageTextEncoderInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SD3PiDDecodeInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLPiDDecodeInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["SaveImageToFileInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SeedreamImageGenerationInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TextLLMInvocation"] | components["schemas"]["TextLLMWithPresetInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"] | components["schemas"]["VideoConcatInvocation"] | components["schemas"]["VideoFrameExtractInvocation"] | components["schemas"]["VideoInvocation"] | components["schemas"]["WanDenoiseInvocation"] | components["schemas"]["WanI2VIdealDimensionsInvocation"] | components["schemas"]["WanImageToLatentsInvocation"] | components["schemas"]["WanLatentsToImageInvocation"] | components["schemas"]["WanLatentsToVideoInvocation"] | components["schemas"]["WanLoRACollectionLoader"] | components["schemas"]["WanLoRALoaderInvocation"] | components["schemas"]["WanModelLoaderInvocation"] | components["schemas"]["WanRefImageEncoderInvocation"] | components["schemas"]["WanTI2VIdealDimensionsInvocation"] | components["schemas"]["WanTextEncoderInvocation"] | components["schemas"]["WanVideoDenoiseInvocation"] | components["schemas"]["WorkflowReturnGetInvocation"] | components["schemas"]["WorkflowReturnInvocation"] | components["schemas"]["WorkflowReturnValueInvocation"] | components["schemas"]["ZImageControlInvocation"] | components["schemas"]["ZImageDenoiseInvocation"] | components["schemas"]["ZImageDenoiseMetaInvocation"] | components["schemas"]["ZImageImageToLatentsInvocation"] | components["schemas"]["ZImageLatentsToImageInvocation"] | components["schemas"]["ZImageLoRACollectionLoader"] | components["schemas"]["ZImageLoRALoaderInvocation"] | components["schemas"]["ZImageModelLoaderInvocation"] | components["schemas"]["ZImagePiDDecodeInvocation"] | components["schemas"]["ZImageSeedVarianceEnhancerInvocation"] | components["schemas"]["ZImageTextEncoderInvocation"];
/**
* Invocation Source Id
* @description The ID of the prepared invocation's source node
@@ -20245,6 +20246,18 @@ export type components = {
* @default null
*/
shift?: number | null;
+ /**
+ * Style Reference
+ * @description Training-free style reference. Adds one reference forward per step, so generation takes roughly twice as long, and retains the reference's attention keys/values for the whole step (~0.5 GB at 1024x1024, ~1.7 GB at 2560x1440). At 1440p the combined footprint no longer fits a 24 GB card alongside the model.
+ * @default null
+ */
+ style_reference?: components["schemas"]["Krea2StyleReferenceField"] | null;
+ /**
+ * Style Reference Prompt
+ * @description Prompt for the style-reference pass. Leave unconnected to reuse the positive prompt; a short neutral prompt describing the reference can give a purer style transfer.
+ * @default null
+ */
+ style_reference_conditioning?: components["schemas"]["Krea2ConditioningField"] | null;
/**
* type
* @default krea2_denoise
@@ -20515,6 +20528,262 @@ export type components = {
*/
type: "krea2_seed_variance";
};
+ /**
+ * Krea2StyleReferenceField
+ * @description Style-reference conditioning for Krea-2 shared-KV reference attention.
+ *
+ * Carries the VAE-encoded reference latents plus the tuning parameters that shape how strongly, and in
+ * which frequency bands, the reference influences the target. The reference must be encoded at exactly
+ * the denoise node's resolution, so the dims travel with it for an early, legible mismatch error.
+ *
+ * Only ``style_strength`` is meant for everyday use; it modulates several of the others. The remainder
+ * are exposed for tuning and should be left at their defaults.
+ */
+ Krea2StyleReferenceField: {
+ /**
+ * Reference Latents Name
+ * @description Name of the saved [1, 16, 1, H/8, W/8] reference latents.
+ */
+ reference_latents_name: string;
+ /**
+ * Width
+ * @description Image width the reference was encoded at (must match denoise width).
+ */
+ width: number;
+ /**
+ * Height
+ * @description Image height the reference was encoded at (must match denoise height).
+ */
+ height: number;
+ /**
+ * Style Strength
+ * @description Overall style strength. 0 disables the reference.
+ * @default 1
+ */
+ style_strength?: number;
+ /**
+ * Blocks
+ * @description Transformer blocks the reference is injected into.
+ * @default 7-27
+ */
+ blocks?: string;
+ /**
+ * Ref K Strength
+ * @description Multiplier on the reference key path.
+ * @default 1.06
+ */
+ ref_k_strength?: number;
+ /**
+ * Adain Strength
+ * @description Reference statistics applied to the target Q/K.
+ * @default 0.85
+ */
+ adain_strength?: number;
+ /**
+ * Value Mode
+ * @description How the reference value vectors are constructed.
+ * @default target_adain_plus_ref
+ * @enum {string}
+ */
+ value_mode?: "target" | "raw_reference" | "ref_mean" | "target_adain" | "target_adain_plus_ref";
+ /**
+ * Value Adain Strength
+ * @description Reference statistics applied to the target value path. Has no effect while ref_value_mix is 1.0.
+ * @default 0.65
+ */
+ value_adain_strength?: number;
+ /**
+ * Ref Value Mix
+ * @description How much raw reference value signal is kept.
+ * @default 1
+ */
+ ref_value_mix?: number;
+ /**
+ * High Scale Start
+ * @description High-frequency reference key scale at step 0.
+ * @default 1.04
+ */
+ high_scale_start?: number;
+ /**
+ * High Scale End
+ * @description High-frequency reference key scale at the last step.
+ * @default 0
+ */
+ high_scale_end?: number;
+ /**
+ * Low Scale Start
+ * @description Low-frequency reference key scale at step 0.
+ * @default 1
+ */
+ low_scale_start?: number;
+ /**
+ * Low Scale End
+ * @description Low-frequency reference key scale at the last step.
+ * @default 1.1
+ */
+ low_scale_end?: number;
+ /**
+ * Beta
+ * @description Exponent of the high-to-low frequency falloff curve.
+ * @default 2.5
+ */
+ beta?: number;
+ };
+ /**
+ * Style Reference - Krea-2
+ * @description Encode a reference image into Krea-2 style-reference conditioning.
+ *
+ * Transfers the *look* of the reference image -- palette, texture, rendering -- while the prompt keeps
+ * driving the content. No adapter model or LoRA is involved.
+ *
+ * ``width`` and ``height`` must match the Krea-2 denoise node. Everything below ``style_strength`` is
+ * for tuning and should be left at its default; ``style_strength`` already modulates several of them.
+ */
+ Krea2StyleReferenceInvocation: {
+ /**
+ * Id
+ * @description The id of this instance of an invocation. Must be unique among all instances of invocations.
+ */
+ id: string;
+ /**
+ * Is Intermediate
+ * @description Whether or not this is an intermediate invocation.
+ * @default false
+ */
+ is_intermediate?: boolean;
+ /**
+ * Use Cache
+ * @description Whether or not to use the cache
+ * @default true
+ */
+ use_cache?: boolean;
+ /**
+ * @description Reference image whose style should be transferred.
+ * @default null
+ */
+ image?: components["schemas"]["ImageField"] | null;
+ /**
+ * VAE
+ * @description VAE
+ * @default null
+ */
+ vae?: components["schemas"]["VAEField"] | null;
+ /**
+ * Width
+ * @description Width to encode the reference at (must match the denoise node's width).
+ * @default 1024
+ */
+ width?: number;
+ /**
+ * Height
+ * @description Height to encode the reference at (must match the denoise node's height).
+ * @default 1024
+ */
+ height?: number;
+ /**
+ * Fit
+ * @description How to reconcile the reference's aspect ratio with the target size. 'crop' scales to cover and center-crops, 'contain' letterboxes on white, 'stretch' distorts.
+ * @default crop
+ * @enum {string}
+ */
+ fit?: "crop" | "contain" | "stretch";
+ /**
+ * Style Strength
+ * @description Overall style strength. 0 disables the reference; 1.0 is the recommended setting.
+ * @default 1
+ */
+ style_strength?: number;
+ /**
+ * Blocks
+ * @description Transformer blocks to inject the reference into, e.g. '7-27'. Styling the earliest blocks damages composition.
+ * @default 7-27
+ */
+ blocks?: string;
+ /**
+ * Ref K Strength
+ * @description Multiplier on the reference key path. This is the knob that makes the style visible without raising low_scale_end (which would also let reference content leak in).
+ * @default 1.06
+ */
+ ref_k_strength?: number;
+ /**
+ * Adain Strength
+ * @description How strongly the reference's query/key statistics are applied to the target.
+ * @default 0.85
+ */
+ adain_strength?: number;
+ /**
+ * Value Mode
+ * @description How the reference value vectors are built.
+ * @default target_adain_plus_ref
+ * @enum {string}
+ */
+ value_mode?: "target" | "raw_reference" | "ref_mean" | "target_adain" | "target_adain_plus_ref";
+ /**
+ * Value Adain Strength
+ * @description Reference statistics applied to the target value path. Has no effect while ref_value_mix is 1.0.
+ * @default 0.65
+ */
+ value_adain_strength?: number;
+ /**
+ * Ref Value Mix
+ * @description How much raw reference value signal is kept. Higher usually preserves style material.
+ * @default 1
+ */
+ ref_value_mix?: number;
+ /**
+ * High Scale Start
+ * @description Scale on the reference key's high-frequency bands at the first step.
+ * @default 1.04
+ */
+ high_scale_start?: number;
+ /**
+ * High Scale End
+ * @description Scale on the reference key's high-frequency bands at the last step. 0 decays them away, which is what keeps reference content from leaking in.
+ * @default 0
+ */
+ high_scale_end?: number;
+ /**
+ * Low Scale Start
+ * @description Scale on the reference key's low-frequency bands at the first step.
+ * @default 1
+ */
+ low_scale_start?: number;
+ /**
+ * Low Scale End
+ * @description Scale on the reference key's low-frequency bands at the last step. Raising this strengthens the style but also invites content leakage and quality loss.
+ * @default 1.1
+ */
+ low_scale_end?: number;
+ /**
+ * Beta
+ * @description Exponent of the high-to-low frequency falloff curve.
+ * @default 2.5
+ */
+ beta?: number;
+ /**
+ * type
+ * @default krea2_style_reference
+ * @constant
+ */
+ type: "krea2_style_reference";
+ };
+ /**
+ * Krea2StyleReferenceOutput
+ * @description Output of a Krea-2 style-reference encoder.
+ */
+ Krea2StyleReferenceOutput: {
+ /**
+ * Style Reference
+ * @description Style-reference conditioning for Krea-2.
+ */
+ style_reference: components["schemas"]["Krea2StyleReferenceField"];
+ /**
+ * type
+ * @default krea2_style_reference_output
+ * @constant
+ */
+ type: "krea2_style_reference_output";
+ };
/**
* Prompt - Krea-2
* @description Encodes a text prompt for Krea-2 using the Qwen3-VL text encoder.
diff --git a/tests/app/invocations/test_krea2_denoise.py b/tests/app/invocations/test_krea2_denoise.py
index 670bac2d67d..573824343b0 100644
--- a/tests/app/invocations/test_krea2_denoise.py
+++ b/tests/app/invocations/test_krea2_denoise.py
@@ -1,13 +1,21 @@
import math
from contextlib import contextmanager, nullcontext
from types import SimpleNamespace
+from typing import ClassVar
import pytest
import torch
-from invokeai.app.invocations.fields import DenoiseMaskField, Krea2ConditioningField, LatentsField, TensorField
+from invokeai.app.invocations.fields import (
+ DenoiseMaskField,
+ Krea2ConditioningField,
+ Krea2StyleReferenceField,
+ LatentsField,
+ TensorField,
+)
from invokeai.app.invocations.krea2_denoise import KREA2_LATENT_CHANNELS, Krea2DenoiseInvocation
from invokeai.app.invocations.model import ModelIdentifierField, TransformerField
+from invokeai.backend.krea2.style_reference import Krea2StyleReferenceMode, capture_style_reference
from invokeai.backend.model_manager.taxonomy import BaseModelType, Krea2VariantType, ModelFormat, ModelType
from invokeai.backend.stable_diffusion.diffusion.conditioning_data import ConditioningFieldData, Krea2ConditioningInfo
@@ -309,6 +317,8 @@ def __init__(self) -> None:
self.conditioning_values: list[float] = []
self.regional_attention_masks: list[torch.Tensor | None] = []
self.combined_sequence_lengths: list[int] = []
+ self.style_modes: list[object | None] = []
+ self.position_id_lengths: list[int] = []
self.attn_processors = {
"text_fusion.layerwise_blocks.0.attn.processor": object(),
"transformer_blocks.0.attn.processor": object(),
@@ -325,9 +335,19 @@ def __call__(self, *, hidden_states, encoder_hidden_states, **_kwargs):
# The real transformer concatenates [text, image] before attention, so this is the sequence length a
# regional mask has to match.
self.combined_sequence_lengths.append(encoder_hidden_states.shape[1] + hidden_states.shape[1])
- regional_processor = self.installed_processors["transformer_blocks.0.attn.processor"]
- attention_mask = regional_processor.regional_prompting_state.attention_mask
+ processor = self.installed_processors["transformer_blocks.0.attn.processor"]
+ attention_mask = processor.regional_prompting_state.attention_mask
self.regional_attention_masks.append(attention_mask.clone() if attention_mask is not None else None)
+ style_state = processor.style_reference_state
+ self.style_modes.append(style_state.mode if style_state is not None else None)
+ if style_state is not None and style_state.mode is Krea2StyleReferenceMode.CAPTURE:
+ # Stand in for the styled block: the real processor stashes the reference's image-token K/V
+ # here, and the injection pass refuses to run without it.
+ sequence_length = encoder_hidden_states.shape[1] + hidden_states.shape[1]
+ captured = torch.zeros(1, 2, sequence_length, 8)
+ capture_style_reference(style_state, 0, captured, captured, captured)
+ if "position_ids" in _kwargs and _kwargs["position_ids"] is not None:
+ self.position_id_lengths.append(int(_kwargs["position_ids"].shape[0]))
return (torch.zeros_like(hidden_states),)
@@ -381,12 +401,18 @@ def _runtime_context(tmp_path, transformer: _Transformer, *, negative_text_seq_l
"negative": ConditioningFieldData(
conditionings=[Krea2ConditioningInfo(prompt_embeds=torch.zeros(1, negative_text_seq_len, 12, 8))]
),
+ "style-prompt": ConditioningFieldData(
+ conditionings=[Krea2ConditioningInfo(prompt_embeds=torch.full((1, 5, 12, 8), 0.5))]
+ ),
}
tensors = {
"init": torch.zeros(1, KREA2_LATENT_CHANNELS, 2, 2),
"mask": torch.zeros(1, 1, 16, 16),
"positive-region": torch.ones(1, 16, 16),
"negative-region": torch.zeros(1, 16, 16),
+ # width=height=16 -> a 2x2 latent; the Qwen-Image VAE emits a frame dim.
+ "style-ref": torch.zeros(1, KREA2_LATENT_CHANNELS, 1, 2, 2),
+ "style-ref-wrong-size": torch.zeros(1, KREA2_LATENT_CHANNELS, 1, 4, 4),
}
config = SimpleNamespace(format=ModelFormat.Checkpoint, variant=Krea2VariantType.Turbo)
return SimpleNamespace(
@@ -750,6 +776,277 @@ def test_estimate_working_memory_accounts_for_regional_attention_masks() -> None
assert with_regional_masks == without_regional_masks + 1234
+def _style_reference_field(
+ *, latents_name: str = "style-ref", width: int = 16, height: int = 16, **overrides
+) -> Krea2StyleReferenceField:
+ # blocks="0-1" because the stub transformer only exposes two main blocks.
+ return Krea2StyleReferenceField(
+ reference_latents_name=latents_name,
+ width=width,
+ height=height,
+ blocks="0-1",
+ **overrides,
+ )
+
+
+def test_run_diffusion_runs_a_reference_pass_before_each_target_pass(monkeypatch, tmp_path) -> None:
+ # Two passes per step: the reference is captured, then spliced into the target. The reference pass must
+ # never carry a regional mask -- it has its own, different sequence length.
+ _patch_runtime(monkeypatch)
+ transformer = _Transformer()
+ invocation = _runtime_invocation(cfg_scale=1.0)
+ invocation.style_reference = _style_reference_field()
+
+ invocation._run_diffusion(_runtime_context(tmp_path, transformer))
+
+ assert transformer.style_modes == [
+ Krea2StyleReferenceMode.CAPTURE,
+ Krea2StyleReferenceMode.INJECT,
+ Krea2StyleReferenceMode.CAPTURE,
+ Krea2StyleReferenceMode.INJECT,
+ ]
+
+
+def test_run_diffusion_injects_style_into_both_cfg_passes(monkeypatch, tmp_path) -> None:
+ # Styling only the conditional pass would make CFG amplify (styled_cond - plain_uncond). One reference
+ # pass is shared by both, so this is three forwards per step and not four.
+ _patch_runtime(monkeypatch)
+ transformer = _Transformer()
+ invocation = _runtime_invocation(cfg_scale=4.0)
+ invocation.style_reference = _style_reference_field()
+
+ invocation._run_diffusion(_runtime_context(tmp_path, transformer))
+
+ assert (
+ transformer.style_modes
+ == [
+ Krea2StyleReferenceMode.CAPTURE,
+ Krea2StyleReferenceMode.INJECT,
+ Krea2StyleReferenceMode.INJECT,
+ ]
+ * 2
+ )
+
+
+def test_run_diffusion_reuses_the_positive_prompt_for_the_reference_pass_by_default(monkeypatch, tmp_path) -> None:
+ _patch_runtime(monkeypatch)
+ transformer = _Transformer()
+ invocation = _runtime_invocation(cfg_scale=1.0)
+ invocation.style_reference = _style_reference_field()
+
+ invocation._run_diffusion(_runtime_context(tmp_path, transformer))
+
+ # The positive conditioning is all ones; the reference pass sees the same embeddings.
+ assert transformer.conditioning_values == [1.0, 1.0, 1.0, 1.0]
+
+
+def test_run_diffusion_uses_reference_specific_position_ids(monkeypatch, tmp_path) -> None:
+ # The style prompt can tokenize to a different length than the positive prompt. The reference pass needs
+ # its own rotary position ids or the real transformer's apply_rotary_emb sees a mismatched length.
+ _patch_runtime(monkeypatch)
+ transformer = _Transformer()
+ invocation = _runtime_invocation(cfg_scale=1.0)
+ invocation.style_reference = _style_reference_field()
+ invocation.style_reference_conditioning = Krea2ConditioningField(conditioning_name="style-prompt")
+
+ invocation._run_diffusion(_runtime_context(tmp_path, transformer))
+
+ image_seq_len = 1 # width=height=16 -> 2x2 latent -> a single 2x2 patch
+ # Reference prompt is 5 tokens, positive is 2.
+ assert transformer.position_id_lengths == [5 + image_seq_len, 2 + image_seq_len] * 2
+
+
+def test_run_diffusion_clears_the_style_cache_when_the_transformer_raises(monkeypatch, tmp_path) -> None:
+ # The processors stay installed on the *cached* transformer, so a retained cache leaks up to ~1.7 GiB
+ # of VRAM until the app restarts.
+ _patch_runtime(monkeypatch)
+
+ class _FailingTransformer(_Transformer):
+ def __call__(self, **kwargs):
+ super().__call__(**kwargs)
+ raise RuntimeError("transformer failure")
+
+ transformer = _FailingTransformer()
+ invocation = _runtime_invocation(cfg_scale=1.0)
+ invocation.style_reference = _style_reference_field()
+
+ with pytest.raises(RuntimeError, match="transformer failure"):
+ invocation._run_diffusion(_runtime_context(tmp_path, transformer))
+
+ style_state = transformer.installed_processors["transformer_blocks.0.attn.processor"].style_reference_state
+ assert style_state is not None
+ assert style_state._cache == {}
+ assert style_state.mode is Krea2StyleReferenceMode.OFF
+
+
+def test_run_diffusion_rejects_a_style_reference_encoded_at_a_different_size(monkeypatch, tmp_path) -> None:
+ _patch_runtime(monkeypatch)
+ invocation = _runtime_invocation(cfg_scale=1.0)
+ invocation.style_reference = _style_reference_field(width=32, height=32)
+
+ with pytest.raises(ValueError, match="encoded at 32x32 but denoise is set to 16x16"):
+ invocation._run_diffusion(_runtime_context(tmp_path, _Transformer()))
+
+
+def test_run_diffusion_rejects_style_reference_latents_of_the_wrong_shape(monkeypatch, tmp_path) -> None:
+ # The recorded dims agree but the tensor itself does not -- catch it before it reaches attention.
+ _patch_runtime(monkeypatch)
+ invocation = _runtime_invocation(cfg_scale=1.0)
+ invocation.style_reference = _style_reference_field(latents_name="style-ref-wrong-size")
+
+ with pytest.raises(ValueError, match=r"latents are \(4, 4\) but denoise expects \(2, 2\)"):
+ invocation._run_diffusion(_runtime_context(tmp_path, _Transformer()))
+
+
+class _SubclassWithOwnProcessors(Krea2DenoiseInvocation):
+ """Stands in for the prompt-weighting node pack, which overrides the attention-processor seam."""
+
+ installed: ClassVar[bool] = False
+
+ def _install_attention_processors(self, transformer, exit_stack):
+ type(self).installed = True
+ return super()._install_attention_processors(transformer, exit_stack)
+
+
+def test_a_subclass_overriding_the_attention_seam_still_runs_without_style_reference(monkeypatch, tmp_path) -> None:
+ # Regression: style reference must not widen _install_attention_processors' signature. Custom node
+ # packs override that seam with the documented two-argument form, and a third positional argument
+ # broke every generation they ran - style reference connected or not.
+ _patch_runtime(monkeypatch)
+ transformer = _Transformer()
+ invocation = _SubclassWithOwnProcessors.model_construct(**_runtime_invocation(cfg_scale=1.0).__dict__)
+ _SubclassWithOwnProcessors.installed = False
+
+ invocation._run_diffusion(_runtime_context(tmp_path, transformer))
+
+ assert _SubclassWithOwnProcessors.installed is True
+
+
+def test_style_reference_refuses_a_subclass_that_installs_its_own_processors(monkeypatch, tmp_path) -> None:
+ # Re-installing would silently discard the subclass's processors, so say so instead.
+ _patch_runtime(monkeypatch)
+ invocation = _SubclassWithOwnProcessors.model_construct(**_runtime_invocation(cfg_scale=1.0).__dict__)
+ invocation.style_reference = _style_reference_field()
+
+ with pytest.raises(ValueError, match="installs its own Krea-2 attention processors"):
+ invocation._run_diffusion(_runtime_context(tmp_path, _Transformer()))
+
+
+def test_run_diffusion_without_a_style_reference_runs_no_extra_passes(monkeypatch, tmp_path) -> None:
+ _patch_runtime(monkeypatch)
+ transformer = _Transformer()
+
+ _runtime_invocation(cfg_scale=1.0)._run_diffusion(_runtime_context(tmp_path, transformer))
+
+ assert transformer.style_modes == [None, None]
+ assert transformer.installed_processors["transformer_blocks.0.attn.processor"].style_reference_state is None
+
+
+def test_run_diffusion_ignores_a_style_reference_at_strength_zero(monkeypatch, tmp_path) -> None:
+ # 0 is documented as disabling the reference. Running the machinery anyway would cost a capture pass per
+ # step (~2x runtime) and a retained K/V cache, all for an attention mix of 0.
+ _patch_runtime(monkeypatch)
+ transformer = _Transformer()
+ invocation = _runtime_invocation(cfg_scale=1.0)
+ invocation.style_reference = _style_reference_field(style_strength=0.0)
+
+ invocation._run_diffusion(_runtime_context(tmp_path, transformer))
+
+ assert transformer.style_modes == [None, None]
+ assert transformer.installed_processors["transformer_blocks.0.attn.processor"].style_reference_state is None
+
+
+def test_run_diffusion_still_runs_a_style_reference_at_a_small_strength(monkeypatch, tmp_path) -> None:
+ # Only an exact 0 is the bypass; anything above it still styles.
+ _patch_runtime(monkeypatch)
+ transformer = _Transformer()
+ invocation = _runtime_invocation(cfg_scale=1.0)
+ invocation.style_reference = _style_reference_field(style_strength=0.01)
+
+ invocation._run_diffusion(_runtime_context(tmp_path, transformer))
+
+ assert Krea2StyleReferenceMode.CAPTURE in transformer.style_modes
+
+
+def test_estimate_working_memory_accounts_for_the_style_reference_kv_cache() -> None:
+ inv = Krea2DenoiseInvocation.model_construct()
+ kwargs = {
+ "image_seq_len": 3600,
+ "positive_text_seq_len": 64,
+ "negative_text_seq_len": None,
+ "do_cfg": False,
+ "num_loras": 0,
+ }
+ baseline = inv._estimate_working_memory(**kwargs)
+ with_style = inv._estimate_working_memory(**kwargs, style_reference_kv_bytes=1_000_000)
+
+ # The cache is an exact, known size, so it is added after the activation multiplier, not scaled by it.
+ assert with_style == int(baseline * 1.35) + 1_000_000
+
+
+def test_estimate_working_memory_covers_the_measured_style_reference_overhead() -> None:
+ # Measured at 1024x1024 / 8 steps / cfg 1.0: peak VRAM rose ~1.6 GiB over the unstyled run. The
+ # estimate has to stay above that, or the model cache offloads the transformer to RAM and the forward
+ # crawls over PCIe instead of failing outright.
+ inv = Krea2DenoiseInvocation.model_construct()
+ kwargs = {
+ "image_seq_len": 4096,
+ "positive_text_seq_len": 512,
+ "negative_text_seq_len": None,
+ "do_cfg": False,
+ "num_loras": 0,
+ }
+ style_bytes = 21 * 2 * 12 * 4096 * 128 * 2
+ delta = inv._estimate_working_memory(**kwargs, style_reference_kv_bytes=style_bytes) - inv._estimate_working_memory(
+ **kwargs
+ )
+
+ assert delta > int(1.6 * 1024**3)
+
+
+def test_estimate_working_memory_with_style_reference_stays_within_a_24gb_card_at_1024() -> None:
+ # 1024x1024 with the default 7-27 band: 4096 image tokens and ~0.5 GiB of retained reference K/V on
+ # top of a ~12B bf16 model. This is the resolution style reference is expected to be used at.
+ inv = Krea2DenoiseInvocation.model_construct()
+ style_bytes = 21 * 2 * 12 * 4096 * 128 * 2
+ assert style_bytes < int(0.55 * 1024**3)
+
+ estimated = inv._estimate_working_memory(
+ image_seq_len=4096,
+ positive_text_seq_len=512,
+ negative_text_seq_len=None,
+ do_cfg=False,
+ num_loras=0,
+ style_reference_kv_bytes=style_bytes,
+ )
+
+ model_bytes = 12 * 1024**3
+ assert estimated + model_bytes < 24 * 1024**3
+
+
+def test_estimate_working_memory_reports_that_style_reference_does_not_fit_24gb_at_1440p() -> None:
+ """Documents a real limit rather than papering over it.
+
+ At 2560x1440 the baseline activation estimate is already ~10 GiB; the reference pass and its ~1.7 GiB
+ of retained K/V push the total past what a 24 GB card can hold alongside a ~12B bf16 model. The
+ estimate must say so honestly -- under-reporting would make the model cache offload the transformer to
+ RAM and run the forward over PCIe, which looks like a hang rather than an error.
+ """
+ inv = Krea2DenoiseInvocation.model_construct()
+ style_bytes = 21 * 2 * 12 * 14400 * 128 * 2
+
+ estimated = inv._estimate_working_memory(
+ image_seq_len=14400,
+ positive_text_seq_len=512,
+ negative_text_seq_len=512,
+ do_cfg=True,
+ num_loras=0,
+ style_reference_kv_bytes=style_bytes,
+ )
+
+ assert estimated + 12 * 1024**3 > 24 * 1024**3
+
+
def test_regional_attention_memory_includes_masks_build_scratch_and_dtype_sized_attention_bias() -> None:
positive = SimpleNamespace(attention_mask_numel=120, attention_mask_build_scratch_numel=40)
negative = SimpleNamespace(attention_mask_numel=100, attention_mask_build_scratch_numel=40)
diff --git a/tests/app/invocations/test_krea2_extension_hooks.py b/tests/app/invocations/test_krea2_extension_hooks.py
new file mode 100644
index 00000000000..7a841809394
--- /dev/null
+++ b/tests/app/invocations/test_krea2_extension_hooks.py
@@ -0,0 +1,227 @@
+"""The Krea-2 nodes expose two extension seams so node packs can add per-token behaviour without
+copying `_run_diffusion` (281 lines) or restating the encoder's token layout.
+
+These tests pin the contract: the defaults must behave exactly as the inlined code did, and a subclass
+must be able to replace each seam. Without them a refactor could silently narrow the seam and only
+break out-of-tree code.
+"""
+
+from contextlib import ExitStack
+from types import SimpleNamespace
+
+import torch
+
+from invokeai.app.invocations.krea2_denoise import Krea2DenoiseInvocation
+from invokeai.backend.krea2.attention import Krea2RegionalPromptingState
+from invokeai.backend.krea2.regional_prompting import Krea2RegionalPromptingExtension, Krea2TextConditioning
+from invokeai.backend.krea2.text_encoding import KREA2_BODY_MAX_LENGTH, KREA2_START_IDX, encode_krea2_prompt
+
+
+def _extension(mask: torch.Tensor | None) -> Krea2RegionalPromptingExtension:
+ conditioning = Krea2TextConditioning(prompt_embeds=torch.ones(1, 2, 12, 8), mask=mask)
+ return Krea2RegionalPromptingExtension.from_text_conditionings([conditioning], image_seq_len=4)
+
+
+def test_default_attention_payload_is_the_regional_mask() -> None:
+ invocation = Krea2DenoiseInvocation.model_construct()
+ with_regions = _extension(torch.tensor([[[1.0, 0.0, 0.0, 0.0]]]))
+ without_regions = _extension(None)
+
+ payload = invocation._build_attention_payload(with_regions, torch.float32)
+
+ assert payload is not None
+ assert torch.equal(payload, with_regions.get_attention_mask())
+ # No regional masks means no mask is allocated at all -- unchanged from before the refactor.
+ assert invocation._build_attention_payload(without_regions, torch.float32) is None
+
+
+def test_default_install_and_clear_drive_the_shared_state() -> None:
+ state = Krea2RegionalPromptingState()
+ mask = torch.eye(4, dtype=torch.bool)
+
+ Krea2DenoiseInvocation._install_attention_payload(state, mask)
+ assert state.attention_mask is mask
+
+ # Cleanup must not leave a potentially multi-GB mask on the cached transformer's processors.
+ Krea2DenoiseInvocation._clear_attention_state(state)
+ assert state.attention_mask is None
+
+
+def test_install_attention_processors_wires_state_and_registers_cleanup() -> None:
+ invocation = Krea2DenoiseInvocation.model_construct()
+ installed: dict[str, object] = {}
+
+ transformer = SimpleNamespace(
+ attn_processors={"transformer_blocks.0.attn.processor": object()},
+ set_attn_processor=lambda processors: installed.update(processors=processors),
+ )
+
+ with ExitStack() as exit_stack:
+ state = invocation._install_attention_processors(transformer, exit_stack)
+ state.set_attention_mask(torch.eye(4, dtype=torch.bool))
+ assert isinstance(state, Krea2RegionalPromptingState)
+ assert "transformer_blocks.0.attn.processor" in installed["processors"]
+
+ # Leaving the exit stack must have run the cleanup callback.
+ assert state.attention_mask is None
+
+
+def test_a_subclass_can_replace_every_attention_seam() -> None:
+ """The contract a node pack depends on: swap the state, the payload and the per-pass install."""
+
+ class _PackState(Krea2RegionalPromptingState):
+ extra: object = None
+
+ class _PackDenoise(Krea2DenoiseInvocation):
+ def _install_attention_processors(self, transformer, exit_stack):
+ state = _PackState()
+ exit_stack.callback(self._clear_attention_state, state)
+ return state
+
+ @staticmethod
+ def _clear_attention_state(state) -> None:
+ state.attention_mask = None
+ state.extra = "cleared"
+
+ def _build_attention_payload(self, extension, inference_dtype):
+ return ("mask", extension.get_attention_mask())
+
+ @staticmethod
+ def _install_attention_payload(state, payload) -> None:
+ state.extra = payload
+
+ invocation = _PackDenoise.model_construct()
+ with ExitStack() as exit_stack:
+ state = invocation._install_attention_processors(SimpleNamespace(), exit_stack)
+ assert isinstance(state, _PackState)
+
+ payload = invocation._build_attention_payload(_extension(None), torch.float32)
+ invocation._install_attention_payload(state, payload)
+ assert state.extra == ("mask", None)
+
+ assert state.extra == "cleared"
+
+
+class _WordTokenizer:
+ """Whitespace tokenizer with real character offsets, standing in for Qwen2TokenizerFast."""
+
+ is_fast = True
+
+ def __call__(
+ self,
+ text,
+ max_length=None,
+ truncation=False,
+ padding=None,
+ return_tensors=None,
+ return_offsets_mapping=False,
+ ):
+ if max_length is None:
+ input_ids = torch.arange(91, 96, dtype=torch.long).unsqueeze(0)
+ return SimpleNamespace(input_ids=input_ids, attention_mask=torch.ones_like(input_ids))
+
+ offsets = []
+ cursor = 0
+ for word in text.split(" "):
+ if word:
+ start = text.index(word, cursor)
+ offsets.append((start, start + len(word)))
+ cursor = start + len(word)
+ offsets = offsets[:max_length]
+
+ input_ids = torch.zeros((1, max_length), dtype=torch.long)
+ attention_mask = torch.zeros_like(input_ids)
+ input_ids[:, : len(offsets)] = torch.arange(1, len(offsets) + 1, dtype=torch.long)
+ attention_mask[:, : len(offsets)] = 1
+ result = SimpleNamespace(input_ids=input_ids, attention_mask=attention_mask)
+ if return_offsets_mapping:
+ offset_mapping = torch.zeros((1, max_length, 2), dtype=torch.long)
+ offset_mapping[0, : len(offsets)] = torch.tensor(offsets, dtype=torch.long)
+ result.offset_mapping = offset_mapping
+ return result
+
+
+class _StubEncoder(torch.nn.Module):
+ def __init__(self) -> None:
+ super().__init__()
+ self.anchor = torch.nn.Parameter(torch.zeros(1))
+
+ def forward(self, *, input_ids, attention_mask, position_ids, **_kwargs):
+ seq_len = input_ids.shape[1]
+ return SimpleNamespace(hidden_states=tuple(torch.zeros((1, seq_len, 4)) for _ in range(36)))
+
+
+def test_encode_without_the_callback_asks_for_no_offsets(monkeypatch) -> None:
+ # The common path must make the exact same tokenizer call it always did.
+ seen: list[bool] = []
+ tokenizer = _WordTokenizer()
+ original = tokenizer.__call__
+
+ def _spy(text, **kwargs):
+ if kwargs.get("max_length") is not None:
+ seen.append("return_offsets_mapping" in kwargs)
+ return original(text, **kwargs)
+
+ monkeypatch.setattr(
+ "invokeai.backend.krea2.text_encoding.TorchDevice.choose_bfloat16_safe_dtype", lambda _d: torch.float32
+ )
+ embeds, mask, values = encode_krea2_prompt("a prompt", _spy, _StubEncoder())
+
+ assert seen == [False]
+ assert values is None
+ assert embeds.shape == (1, 512, 12, 4)
+ assert mask.shape == (1, 512)
+
+
+def test_encode_aligns_callback_values_with_the_conditioning(monkeypatch) -> None:
+ # Whatever the callback returns is sliced by the same prefix drop as the embeddings, so a caller's
+ # per-token vector lines up with the conditioning without knowing the layout.
+ monkeypatch.setattr(
+ "invokeai.backend.krea2.text_encoding.TorchDevice.choose_bfloat16_safe_dtype", lambda _d: torch.float32
+ )
+ captured: dict[str, torch.Tensor] = {}
+
+ def build(offset_mapping: torch.Tensor) -> torch.Tensor:
+ captured["offsets"] = offset_mapping
+ values = torch.ones(offset_mapping.shape[0], dtype=torch.float32)
+ # Mark the token right after the prefix drop so we can assert where it lands.
+ values[KREA2_START_IDX] = 0.25
+ return values
+
+ filler = " ".join(f"w{i}" for i in range(KREA2_START_IDX + 4))
+ embeds, mask, values = encode_krea2_prompt(filler, _WordTokenizer(), _StubEncoder(), build)
+
+ assert captured["offsets"].shape == (KREA2_BODY_MAX_LENGTH, 2)
+ assert values is not None
+ assert values.shape == mask.shape == (1, 512)
+ assert values[0, 0].item() == 0.25
+ assert values[0, 1].item() == 1.0
+
+
+def test_encode_keeps_the_callback_device_and_dtype(monkeypatch) -> None:
+ # The callback is an out-of-tree extension seam, so it may hand back a tensor on the encoder's device
+ # (or in a different dtype). The suffix must follow it - a CPU suffix would make the concat raise
+ # "Expected all tensors to be on the same device".
+ monkeypatch.setattr(
+ "invokeai.backend.krea2.text_encoding.TorchDevice.choose_bfloat16_safe_dtype", lambda _d: torch.float32
+ )
+
+ def build(offset_mapping: torch.Tensor) -> torch.Tensor:
+ return torch.ones(offset_mapping.shape[0], dtype=torch.float16, device="meta")
+
+ _, _, values = encode_krea2_prompt("a prompt", _WordTokenizer(), _StubEncoder(), build)
+
+ assert values is not None
+ assert values.device.type == "meta"
+ assert values.dtype == torch.float16
+ assert values.shape == (1, 512)
+
+
+def test_encode_returns_none_when_the_callback_yields_nothing(monkeypatch) -> None:
+ monkeypatch.setattr(
+ "invokeai.backend.krea2.text_encoding.TorchDevice.choose_bfloat16_safe_dtype", lambda _d: torch.float32
+ )
+
+ _, _, values = encode_krea2_prompt("a prompt", _WordTokenizer(), _StubEncoder(), lambda _offsets: None)
+
+ assert values is None
diff --git a/tests/app/invocations/test_krea2_style_reference.py b/tests/app/invocations/test_krea2_style_reference.py
new file mode 100644
index 00000000000..df9846b8b25
--- /dev/null
+++ b/tests/app/invocations/test_krea2_style_reference.py
@@ -0,0 +1,126 @@
+from types import SimpleNamespace
+
+import pytest
+import torch
+from PIL import Image as PILImage
+
+from invokeai.app.invocations.krea2_style_reference import (
+ Krea2StyleReferenceInvocation,
+ fit_image_to_box,
+)
+
+
+def _image(width: int, height: int, color: tuple[int, int, int] = (10, 120, 200)) -> PILImage.Image:
+ return PILImage.new("RGB", (width, height), color)
+
+
+@pytest.mark.parametrize("fit", ["crop", "contain", "stretch"])
+@pytest.mark.parametrize(("source_width", "source_height"), [(640, 480), (480, 640), (1024, 1024), (37, 800)])
+def test_every_fit_mode_produces_exactly_the_target_size(fit: str, source_width: int, source_height: int) -> None:
+ # The reference's image tokens are appended to the target's and share its rotary embedding, so an
+ # off-by-one here becomes a shape error deep inside attention.
+ result = fit_image_to_box(_image(source_width, source_height), 512, 256, fit)
+ assert result.size == (512, 256)
+
+
+def test_crop_keeps_the_aspect_ratio_by_discarding_the_overhang() -> None:
+ # A 2x2 checker: cropping a wide source to a square must keep the vertical proportions intact.
+ source = PILImage.new("RGB", (400, 200), (0, 0, 0))
+ source.paste(PILImage.new("RGB", (400, 100), (255, 255, 255)), (0, 0))
+
+ result = fit_image_to_box(source, 200, 200, "crop")
+
+ # The top half stays white and the bottom half black -- no vertical squashing.
+ assert result.getpixel((100, 50)) == (255, 255, 255)
+ assert result.getpixel((100, 150)) == (0, 0, 0)
+
+
+def test_contain_letterboxes_on_white_without_distorting() -> None:
+ result = fit_image_to_box(_image(400, 200, (0, 0, 0)), 200, 200, "contain")
+
+ # 400x200 scaled to fit 200x200 gives 200x100, centred vertically with white bars above and below.
+ assert result.getpixel((100, 100)) == (0, 0, 0)
+ assert result.getpixel((100, 5)) == (255, 255, 255)
+ assert result.getpixel((100, 195)) == (255, 255, 255)
+
+
+def test_stretch_fills_the_whole_box() -> None:
+ result = fit_image_to_box(_image(400, 200, (0, 0, 0)), 200, 200, "stretch")
+ assert result.getpixel((100, 5)) == (0, 0, 0)
+ assert result.getpixel((100, 195)) == (0, 0, 0)
+
+
+def test_fit_rejects_a_degenerate_source() -> None:
+ with pytest.raises(ValueError, match="invalid dimensions"):
+ fit_image_to_box(PILImage.new("RGB", (0, 0)), 64, 64, "crop")
+
+
+def _invocation(**overrides) -> Krea2StyleReferenceInvocation:
+ defaults = {
+ "image": SimpleNamespace(image_name="reference"),
+ "vae": SimpleNamespace(vae=SimpleNamespace()),
+ "width": 64,
+ "height": 64,
+ "fit": "crop",
+ "style_strength": 1.0,
+ "blocks": "7-27",
+ "ref_k_strength": 1.06,
+ "adain_strength": 0.85,
+ "value_mode": "target_adain_plus_ref",
+ "value_adain_strength": 0.65,
+ "ref_value_mix": 1.0,
+ "high_scale_start": 1.04,
+ "high_scale_end": 0.0,
+ "low_scale_start": 1.0,
+ "low_scale_end": 1.10,
+ "beta": 2.5,
+ }
+ defaults.update(overrides)
+ return Krea2StyleReferenceInvocation.model_construct(**defaults)
+
+
+def _context(saved: dict) -> SimpleNamespace:
+ def save(tensor: torch.Tensor) -> str:
+ saved["tensor"] = tensor
+ return "saved"
+
+ return SimpleNamespace(
+ images=SimpleNamespace(get_pil=lambda _name, _mode: _image(400, 200)),
+ models=SimpleNamespace(load=lambda _identifier: object()),
+ tensors=SimpleNamespace(save=save),
+ util=SimpleNamespace(signal_progress=lambda _message: None),
+ )
+
+
+def test_invoke_encodes_the_reference_and_carries_the_settings(monkeypatch) -> None:
+ encoded: dict = {}
+
+ def fake_vae_encode(*, vae_info, image_tensor):
+ encoded["image_tensor"] = image_tensor
+ return torch.zeros(1, 16, 1, 8, 8)
+
+ monkeypatch.setattr(
+ "invokeai.app.invocations.krea2_style_reference.QwenImageImageToLatentsInvocation.vae_encode",
+ staticmethod(fake_vae_encode),
+ )
+ monkeypatch.setattr("invokeai.app.invocations.krea2_style_reference.TorchDevice.empty_cache", lambda: None)
+
+ saved: dict = {}
+ output = _invocation(style_strength=0.6, low_scale_end=1.25).invoke(_context(saved))
+
+ # The image reaches the VAE at exactly the requested size, normalized to [-1, 1].
+ assert encoded["image_tensor"].shape == (1, 3, 64, 64)
+ assert encoded["image_tensor"].min() >= -1.0 and encoded["image_tensor"].max() <= 1.0
+
+ field = output.style_reference
+ assert field.reference_latents_name == "saved"
+ assert (field.width, field.height) == (64, 64)
+ assert field.style_strength == pytest.approx(0.6)
+ assert field.low_scale_end == pytest.approx(1.25)
+ assert field.blocks == "7-27"
+
+
+def test_invoke_rejects_a_malformed_block_spec(monkeypatch) -> None:
+ # Fails here rather than several nodes later, halfway through a denoise.
+ with pytest.raises(ValueError, match="selects blocks"):
+ _invocation(blocks="7-99").invoke(_context({}))
diff --git a/tests/app/invocations/test_krea2_text_encoder.py b/tests/app/invocations/test_krea2_text_encoder.py
index c2686713735..673b1b3ec01 100644
--- a/tests/app/invocations/test_krea2_text_encoder.py
+++ b/tests/app/invocations/test_krea2_text_encoder.py
@@ -147,7 +147,7 @@ def test_encode_preserves_suffix_for_a_prompt_that_overflows_truncation(monkeypa
# Regression: a prompt longer than the tokenizer budget must NOT lose the assistant-turn suffix. The
# encoder tokenizes (prefix + prompt) with truncation and appends the suffix AFTER, so the final tokens
# always end with the suffix template (building one string and truncating it would cut the suffix off).
- from invokeai.app.invocations.krea2_text_encoder import _KREA2_SUFFIX
+ from invokeai.backend.krea2.text_encoding import KREA2_SUFFIX as _KREA2_SUFFIX
suffix_ids = [901, 902, 903, 904, 905]
@@ -240,7 +240,7 @@ def load(identifier):
def test_encode_uses_reference_fixed_length_layout_and_position_ids(monkeypatch) -> None:
- from invokeai.app.invocations.krea2_text_encoder import _KREA2_SUFFIX
+ from invokeai.backend.krea2.text_encoding import KREA2_SUFFIX as _KREA2_SUFFIX
captured: dict = {}
diff --git a/tests/backend/krea2/test_attention.py b/tests/backend/krea2/test_attention.py
index 9b0d8e7b22f..3f268ad9329 100644
--- a/tests/backend/krea2/test_attention.py
+++ b/tests/backend/krea2/test_attention.py
@@ -4,7 +4,16 @@
from torch.nn.attention import SDPBackend
import invokeai.backend.krea2.attention as krea2_attention
-from invokeai.backend.krea2.attention import Krea2MemoryEfficientAttnProcessor, Krea2RegionalPromptingState
+from invokeai.backend.krea2.attention import (
+ Krea2MemoryEfficientAttnProcessor,
+ Krea2RegionalPromptingState,
+ build_krea2_attention_processors,
+)
+from invokeai.backend.krea2.style_reference import (
+ Krea2StyleReferenceSettings,
+ Krea2StyleReferenceState,
+ resolve_effective_settings,
+)
def _build_gqa_attention() -> Krea2Attention:
@@ -121,3 +130,154 @@ def test_cuda_memory_efficient_sdpa_accepts_dense_regional_mask(monkeypatch: pyt
assert output.is_cuda
assert torch.isfinite(output).all()
+
+
+# --- style reference -----------------------------------------------------------------------------
+
+
+class _StubTransformer:
+ def __init__(self, num_blocks: int) -> None:
+ self.attn_processors = {f"transformer_blocks.{i}.attn.processor": object() for i in range(num_blocks)}
+ self.attn_processors["text_fusion.layerwise_blocks.0.attn.processor"] = object()
+
+
+def _style_state(image_seq_len: int, **overrides) -> Krea2StyleReferenceState:
+ # head_dim is 32 for the test attention (hidden 256 / 8 heads), so the axes must sum to 32.
+ return Krea2StyleReferenceState(
+ settings=resolve_effective_settings(Krea2StyleReferenceSettings(**overrides)),
+ image_seq_len=image_seq_len,
+ axes_dims_rope=(8, 12, 12),
+ )
+
+
+def test_builder_gives_the_style_state_only_to_the_configured_blocks() -> None:
+ regional = Krea2RegionalPromptingState()
+ style = _style_state(4)
+
+ processors = build_krea2_attention_processors(
+ _StubTransformer(12), regional, style_reference_state=style, style_reference_blocks={7, 8}
+ )
+
+ styled = {name for name, p in processors.items() if p.style_reference_state is not None}
+ assert styled == {"transformer_blocks.7.attn.processor", "transformer_blocks.8.attn.processor"}
+
+
+def test_builder_keeps_the_regional_mask_on_even_blocks_only_when_style_is_active() -> None:
+ # Style runs over both parities (7-27); that must not widen the regional mask's even-only band.
+ regional = Krea2RegionalPromptingState()
+ processors = build_krea2_attention_processors(
+ _StubTransformer(12), regional, style_reference_state=_style_state(4), style_reference_blocks=set(range(7, 12))
+ )
+
+ for index in range(12):
+ processor = processors[f"transformer_blocks.{index}.attn.processor"]
+ assert (processor.regional_prompting_state is not None) == (index % 2 == 0)
+ # Block 8 is even and inside the style band, so it carries both states at once.
+ both = processors["transformer_blocks.8.attn.processor"]
+ assert both.regional_prompting_state is not None and both.style_reference_state is not None
+
+
+def test_builder_without_style_arguments_reproduces_the_previous_behaviour() -> None:
+ processors = build_krea2_attention_processors(_StubTransformer(4), Krea2RegionalPromptingState())
+ assert all(processor.style_reference_state is None for processor in processors.values())
+
+
+def test_builder_never_styles_the_text_fusion_blocks() -> None:
+ # They only ever see text tokens, so there is no image-token range to capture.
+ processors = build_krea2_attention_processors(
+ _StubTransformer(4), Krea2RegionalPromptingState(), _style_state(4), style_reference_blocks=set(range(4))
+ )
+ assert processors["text_fusion.layerwise_blocks.0.attn.processor"].style_reference_state is None
+
+
+def test_capture_pass_leaves_the_attention_output_unchanged() -> None:
+ # The reference pass must be a plain forward; it only observes.
+ attn = _build_gqa_attention()
+ hidden_states = torch.randn(1, 24, attn.hidden_size)
+ state = _style_state(16)
+ state.begin_capture()
+
+ with torch.no_grad():
+ attn.set_processor(Krea2MemoryEfficientAttnProcessor())
+ out_plain = attn(hidden_states, attention_mask=None, image_rotary_emb=None)
+ attn.set_processor(Krea2MemoryEfficientAttnProcessor(style_reference_state=state, block_index=0))
+ out_capture = attn(hidden_states, attention_mask=None, image_rotary_emb=None)
+
+ assert torch.equal(out_plain, out_capture)
+ assert state.get(0).reference_key.shape == (1, attn.num_kv_heads, 16, attn.head_dim)
+
+
+def test_inject_pass_changes_the_output_and_preserves_its_shape() -> None:
+ attn = _build_gqa_attention()
+ reference = torch.randn(1, 24, attn.hidden_size)
+ target = torch.randn(1, 24, attn.hidden_size)
+ state = _style_state(16)
+
+ with torch.no_grad():
+ attn.set_processor(Krea2MemoryEfficientAttnProcessor())
+ out_plain = attn(target, attention_mask=None, image_rotary_emb=None)
+
+ processor = Krea2MemoryEfficientAttnProcessor(style_reference_state=state, block_index=0)
+ attn.set_processor(processor)
+ state.begin_capture()
+ attn(reference, attention_mask=None, image_rotary_emb=None)
+ state.begin_inject(0.0)
+ out_styled = attn(target, attention_mask=None, image_rotary_emb=None)
+
+ assert out_styled.shape == out_plain.shape
+ assert not torch.allclose(out_styled, out_plain, atol=1e-4)
+
+
+def test_style_strength_of_zero_reproduces_the_unstyled_output() -> None:
+ attn = _build_gqa_attention()
+ reference = torch.randn(1, 24, attn.hidden_size)
+ target = torch.randn(1, 24, attn.hidden_size)
+ state = _style_state(16, style_strength=0.0)
+
+ with torch.no_grad():
+ attn.set_processor(Krea2MemoryEfficientAttnProcessor())
+ out_plain = attn(target, attention_mask=None, image_rotary_emb=None)
+
+ attn.set_processor(Krea2MemoryEfficientAttnProcessor(style_reference_state=state, block_index=0))
+ state.begin_capture()
+ attn(reference, attention_mask=None, image_rotary_emb=None)
+ state.begin_inject(0.5)
+ out_styled = attn(target, attention_mask=None, image_rotary_emb=None)
+
+ assert torch.allclose(out_plain, out_styled, atol=1e-6)
+
+
+def test_regional_mask_is_key_padded_when_the_reference_is_injected(monkeypatch: pytest.MonkeyPatch) -> None:
+ # The reference keys are appended along the token axis, so a square regional mask no longer fits.
+ attn = _build_gqa_attention()
+ reference = torch.randn(1, 24, attn.hidden_size)
+ target = torch.randn(1, 24, attn.hidden_size)
+ style = _style_state(16)
+ regional = Krea2RegionalPromptingState(attention_mask=torch.tril(torch.ones(24, 24, dtype=torch.bool)))
+
+ seen: list[torch.Tensor | None] = []
+ original_sdpa = torch.nn.functional.scaled_dot_product_attention
+
+ def record(query, key, value, attn_mask=None, **kwargs):
+ seen.append(attn_mask)
+ return original_sdpa(query, key, value, attn_mask=attn_mask, **kwargs)
+
+ monkeypatch.setattr(krea2_attention.F, "scaled_dot_product_attention", record)
+
+ with torch.no_grad():
+ processor = Krea2MemoryEfficientAttnProcessor(
+ regional_prompting_state=regional, style_reference_state=style, block_index=0
+ )
+ attn.set_processor(processor)
+ style.begin_capture()
+ regional.set_attention_mask(None)
+ attn(reference, attention_mask=None, image_rotary_emb=None)
+ style.begin_inject(0.0)
+ regional.set_attention_mask(torch.tril(torch.ones(24, 24, dtype=torch.bool)))
+ attn(target, attention_mask=None, image_rotary_emb=None)
+
+ styled_mask = seen[-1]
+ assert styled_mask is not None
+ assert styled_mask.shape == (24, 24 + 16)
+ # Every target query may see the reference, in every region.
+ assert bool(styled_mask[:, 24:].all())
diff --git a/tests/backend/krea2/test_style_reference.py b/tests/backend/krea2/test_style_reference.py
new file mode 100644
index 00000000000..d2be1e4cc0d
--- /dev/null
+++ b/tests/backend/krea2/test_style_reference.py
@@ -0,0 +1,337 @@
+import pytest
+import torch
+
+from invokeai.backend.krea2.style_reference import (
+ KREA2_NUM_BLOCKS,
+ Krea2StyleReferenceMode,
+ Krea2StyleReferenceSettings,
+ Krea2StyleReferenceState,
+ _adain_to_stats,
+ _token_mean_std,
+ apply_style_reference,
+ build_rope_scale_vector,
+ capture_style_reference,
+ lerp_scales,
+ parse_block_spec,
+ resolve_effective_settings,
+)
+
+# Krea-2's real RoPE layout: (temporal, height, width), summing to the 128-dim head.
+KREA2_AXES = (32, 48, 48)
+
+
+def _state(image_seq_len: int = 6, axes: tuple[int, ...] = (2, 3, 3), **overrides) -> Krea2StyleReferenceState:
+ # The test tensors use head_dim 8, so the axes have to sum to 8 (Krea-2's real layout is KREA2_AXES).
+ return Krea2StyleReferenceState(
+ settings=resolve_effective_settings(Krea2StyleReferenceSettings(**overrides)),
+ image_seq_len=image_seq_len,
+ axes_dims_rope=axes,
+ )
+
+
+# --- block spec ----------------------------------------------------------------------------------
+
+
+@pytest.mark.parametrize(
+ ("spec", "expected"),
+ [
+ ("7-27", frozenset(range(7, 28))),
+ ("5", frozenset({5})),
+ ("7-9,3", frozenset({3, 7, 8, 9})),
+ (" 7 - 9 ; 3 ", frozenset({3, 7, 8, 9})),
+ ],
+)
+def test_parse_block_spec_accepts_ranges_lists_and_singletons(spec: str, expected: frozenset[int]) -> None:
+ assert parse_block_spec(spec, KREA2_NUM_BLOCKS) == expected
+
+
+@pytest.mark.parametrize("spec", ["", " ", ",,"])
+def test_parse_block_spec_rejects_specs_that_select_nothing(spec: str) -> None:
+ with pytest.raises(ValueError, match="selects no blocks"):
+ parse_block_spec(spec, KREA2_NUM_BLOCKS)
+
+
+def test_parse_block_spec_rejects_blocks_the_transformer_does_not_have() -> None:
+ # Upstream silently accepts out-of-range indices and then styles nothing. Failing here surfaces the
+ # typo at graph time instead of as a mysteriously unstyled image.
+ with pytest.raises(ValueError, match=r"selects blocks \[28\]"):
+ parse_block_spec("7-28", KREA2_NUM_BLOCKS)
+
+
+def test_parse_block_spec_rejects_a_reversed_range() -> None:
+ with pytest.raises(ValueError, match="end is before start"):
+ parse_block_spec("27-7", KREA2_NUM_BLOCKS)
+
+
+# --- style_strength modulation -------------------------------------------------------------------
+
+
+def test_style_strength_of_one_leaves_every_parameter_at_its_configured_value() -> None:
+ settings = Krea2StyleReferenceSettings()
+ effective = resolve_effective_settings(settings)
+
+ assert effective.high_scale_start == pytest.approx(settings.high_scale_start)
+ assert effective.low_scale_end == pytest.approx(settings.low_scale_end)
+ assert effective.adain_strength == pytest.approx(settings.adain_strength)
+ assert effective.attention_mix == pytest.approx(1.0)
+
+
+def test_style_strength_of_zero_neutralizes_every_modulated_parameter() -> None:
+ # Not just the attention mix: upstream also pulls the frequency scales back to 1.0 (i.e. no scaling)
+ # and zeroes the AdaIN, so a strength of 0 is a true bypass.
+ effective = resolve_effective_settings(Krea2StyleReferenceSettings(style_strength=0.0))
+
+ assert effective.high_scale_start == pytest.approx(1.0)
+ assert effective.low_scale_end == pytest.approx(1.0)
+ assert effective.adain_strength == pytest.approx(0.0)
+ assert effective.attention_mix == pytest.approx(0.0)
+
+
+def test_style_strength_saturates_each_factor_at_its_own_ceiling() -> None:
+ # attention_mix clamps at 1.0, the AdaIN multiplier at 1.25 and the high-scale multiplier at 1.5.
+ effective = resolve_effective_settings(Krea2StyleReferenceSettings(style_strength=2.0, adain_strength=0.5))
+
+ assert effective.attention_mix == pytest.approx(1.0)
+ assert effective.adain_strength == pytest.approx(0.5 * 1.25)
+ assert effective.high_scale_start == pytest.approx(1.0 + (1.04 - 1.0) * 1.5)
+ # low_scale_end is *not* capped.
+ assert effective.low_scale_end == pytest.approx(1.0 + (1.10 - 1.0) * 2.0)
+
+
+# --- RoPE frequency scale vector -----------------------------------------------------------------
+
+
+def test_rope_scale_vector_length_matches_the_head_dim() -> None:
+ vector = build_rope_scale_vector(KREA2_AXES, 1.04, 1.10, 2.5, torch.device("cpu"), torch.float32)
+ assert vector.shape == (sum(KREA2_AXES),)
+
+
+def test_rope_scale_vector_holds_the_temporal_axis_flat_at_the_low_scale() -> None:
+ # Every Krea-2 token sits at t=0, so axis 0's rotation is the identity and has no frequency structure
+ # to shape.
+ vector = build_rope_scale_vector(KREA2_AXES, 1.04, 1.10, 2.5, torch.device("cpu"), torch.float32)
+ assert torch.allclose(vector[: KREA2_AXES[0]], torch.full((KREA2_AXES[0],), 1.10))
+
+
+def test_rope_scale_vector_runs_from_high_to_low_across_each_spatial_axis() -> None:
+ high, low = 1.04, 1.10
+ vector = build_rope_scale_vector(KREA2_AXES, high, low, 2.5, torch.device("cpu"), torch.float32)
+
+ height_axis = vector[KREA2_AXES[0] : KREA2_AXES[0] + KREA2_AXES[1]]
+ width_axis = vector[KREA2_AXES[0] + KREA2_AXES[1] :]
+ for axis in (height_axis, width_axis):
+ # get_1d_rotary_pos_embed puts the highest frequency first, so the curve starts at `high`.
+ assert axis[0].item() == pytest.approx(high)
+ assert axis[-1].item() == pytest.approx(low)
+
+
+def test_rope_scale_vector_repeats_each_frequency_across_its_pair() -> None:
+ # Krea2RotaryPosEmbed uses repeat_interleave_real=True, so each frequency occupies two consecutive
+ # dims. The scale vector has to line up with that or it shifts the bands it is meant to attenuate.
+ vector = build_rope_scale_vector(KREA2_AXES, 1.04, 0.0, 2.5, torch.device("cpu"), torch.float32)
+ assert torch.equal(vector[0::2], vector[1::2])
+
+
+def test_rope_scale_vector_kills_the_highest_bands_when_high_scale_reaches_zero() -> None:
+ # This is the mechanism that stops reference *content* leaking in as the schedule progresses.
+ vector = build_rope_scale_vector(KREA2_AXES, 0.0, 1.0, 2.5, torch.device("cpu"), torch.float32)
+ assert vector[KREA2_AXES[0]].item() == pytest.approx(0.0)
+
+
+def test_lerp_scales_walks_from_the_start_values_to_the_end_values() -> None:
+ settings = resolve_effective_settings(Krea2StyleReferenceSettings())
+
+ assert lerp_scales(settings, 0.0) == pytest.approx((settings.high_scale_start, settings.low_scale_start))
+ assert lerp_scales(settings, 1.0) == pytest.approx((settings.high_scale_end, settings.low_scale_end))
+
+
+# --- AdaIN ---------------------------------------------------------------------------------------
+
+
+def test_adain_at_full_strength_adopts_the_reference_statistics() -> None:
+ torch.manual_seed(0)
+ target = torch.randn(1, 4, 32, 8) * 3.0 + 5.0
+ style = torch.randn(1, 4, 32, 8) * 0.5 - 2.0
+ style_mean, style_std = _token_mean_std(style)
+
+ result = _adain_to_stats(target, style_mean, style_std, 1.0)
+ result_mean, result_std = _token_mean_std(result)
+
+ assert torch.allclose(result_mean, style_mean, atol=1e-5)
+ assert torch.allclose(result_std, style_std, atol=1e-5)
+
+
+def test_adain_at_zero_strength_is_the_identity() -> None:
+ torch.manual_seed(0)
+ target = torch.randn(1, 4, 32, 8)
+ style_mean, style_std = _token_mean_std(torch.randn(1, 4, 32, 8))
+ assert torch.equal(_adain_to_stats(target, style_mean, style_std, 0.0), target)
+
+
+# --- capture / inject ----------------------------------------------------------------------------
+
+
+def test_capture_before_head_expansion_matches_capture_after() -> None:
+ """The load-bearing test for the 4x memory saving.
+
+ Capturing at 12 KV heads instead of 48 is only sound because ``repeat_interleave`` duplicates whole
+ heads, so per-``(head, dim)`` token statistics are identical within a group. If that ever stops
+ holding, the captured cache silently diverges from upstream.
+ """
+ torch.manual_seed(0)
+ query = torch.randn(1, 8, 10, 8)
+ key = torch.randn(1, 2, 10, 8)
+ value = torch.randn(1, 2, 10, 8)
+ repeats = 4
+
+ pre = _state(image_seq_len=6)
+ pre.begin_capture()
+ capture_style_reference(pre, 0, query, key, value)
+
+ post = _state(image_seq_len=6)
+ post.begin_capture()
+ capture_style_reference(
+ post, 0, query, key.repeat_interleave(repeats, dim=1), value.repeat_interleave(repeats, dim=1)
+ )
+
+ pre_cache, post_cache = pre.get(0), post.get(0)
+ assert torch.equal(pre_cache.reference_key.repeat_interleave(repeats, dim=1), post_cache.reference_key)
+ assert torch.equal(pre_cache.reference_value.repeat_interleave(repeats, dim=1), post_cache.reference_value)
+ assert torch.allclose(pre_cache.key_mean.repeat_interleave(repeats, dim=1), post_cache.key_mean)
+ assert torch.allclose(pre_cache.key_std.repeat_interleave(repeats, dim=1), post_cache.key_std)
+ assert torch.equal(pre_cache.query_mean, post_cache.query_mean)
+
+
+def test_capture_only_keeps_the_image_tokens() -> None:
+ torch.manual_seed(0)
+ query = torch.randn(1, 8, 10, 8)
+ key = torch.randn(1, 2, 10, 8)
+ value = torch.randn(1, 2, 10, 8)
+
+ state = _state(image_seq_len=6)
+ state.begin_capture()
+ capture_style_reference(state, 3, query, key, value)
+
+ cache = state.get(3)
+ assert cache.reference_key.shape == (1, 2, 6, 8)
+ # Krea-2 concatenates [text, image], so the image tokens are the tail of the sequence.
+ assert torch.equal(cache.reference_key, key[:, :, 4:, :])
+
+
+def test_capture_rejects_an_image_seq_len_longer_than_the_sequence() -> None:
+ state = _state(image_seq_len=99)
+ state.begin_capture()
+ with pytest.raises(ValueError, match="exceeds the transformer sequence length"):
+ capture_style_reference(state, 0, torch.randn(1, 8, 10, 8), torch.randn(1, 2, 10, 8), torch.randn(1, 2, 10, 8))
+
+
+def test_inject_before_capture_fails_loudly() -> None:
+ state = _state()
+ with pytest.raises(RuntimeError, match="before any reference pass was captured"):
+ state.begin_inject(0.0)
+
+
+def test_inject_on_an_uncaptured_block_fails_loudly() -> None:
+ state = _state(image_seq_len=6)
+ state.begin_capture()
+ capture_style_reference(state, 7, torch.randn(1, 8, 10, 8), torch.randn(1, 2, 10, 8), torch.randn(1, 2, 10, 8))
+ state.begin_inject(0.0)
+
+ with pytest.raises(RuntimeError, match="block 8 was not captured"):
+ apply_style_reference(state, 8, torch.randn(1, 8, 10, 8), torch.randn(1, 2, 10, 8), torch.randn(1, 2, 10, 8))
+
+
+def test_inject_appends_the_reference_image_tokens_to_the_keys_and_values() -> None:
+ torch.manual_seed(0)
+ state = _state(image_seq_len=6)
+ state.begin_capture()
+ capture_style_reference(state, 0, torch.randn(1, 8, 10, 8), torch.randn(1, 2, 10, 8), torch.randn(1, 2, 10, 8))
+ state.begin_inject(0.5)
+
+ injection = apply_style_reference(
+ state, 0, torch.randn(1, 8, 10, 8), torch.randn(1, 2, 10, 8), torch.randn(1, 2, 10, 8)
+ )
+
+ assert injection.query.shape == (1, 8, 10, 8)
+ assert injection.key.shape == (1, 2, 16, 8)
+ assert injection.value.shape == (1, 2, 16, 8)
+
+
+def test_inject_with_the_default_value_mode_passes_the_reference_values_through_untouched() -> None:
+ # value_mode="target_adain_plus_ref" with ref_value_mix=1.0 discards the AdaIN'd blend entirely. This
+ # is why value_adain_strength has no effect at the recommended settings.
+ torch.manual_seed(0)
+ reference_value = torch.randn(1, 2, 6, 8)
+ state = _state(image_seq_len=6)
+ state.begin_capture()
+ capture_style_reference(state, 0, torch.randn(1, 8, 6, 8), torch.randn(1, 2, 6, 8), reference_value)
+ state.begin_inject(0.0)
+
+ injection = apply_style_reference(
+ state, 0, torch.randn(1, 8, 6, 8), torch.randn(1, 2, 6, 8), torch.randn(1, 2, 6, 8)
+ )
+
+ assert torch.equal(injection.value[:, :, 6:, :], reference_value)
+
+
+def test_inject_does_not_mutate_the_caller_tensors() -> None:
+ # The AdaIN writes into the image-token slice; doing that in place would corrupt the value tensor the
+ # processor still needs for the unstyled branch.
+ torch.manual_seed(0)
+ state = _state(image_seq_len=6)
+ state.begin_capture()
+ capture_style_reference(state, 0, torch.randn(1, 8, 10, 8), torch.randn(1, 2, 10, 8), torch.randn(1, 2, 10, 8))
+ state.begin_inject(0.0)
+
+ query = torch.randn(1, 8, 10, 8)
+ key = torch.randn(1, 2, 10, 8)
+ value = torch.randn(1, 2, 10, 8)
+ original = (query.clone(), key.clone(), value.clone())
+ apply_style_reference(state, 0, query, key, value)
+
+ assert torch.equal(query, original[0])
+ assert torch.equal(key, original[1])
+ assert torch.equal(value, original[2])
+
+
+# --- shared state lifecycle ----------------------------------------------------------------------
+
+
+def test_pad_attention_mask_widens_the_key_axis_and_allows_the_reference() -> None:
+ state = _state(image_seq_len=6)
+ mask = torch.zeros(10, 10, dtype=torch.bool)
+
+ padded = state.pad_attention_mask(mask)
+
+ assert padded is not None
+ assert padded.shape == (10, 16)
+ assert torch.equal(padded[:, :10], mask)
+ assert bool(padded[:, 10:].all())
+
+
+def test_pad_attention_mask_is_cached_per_source_mask() -> None:
+ # Rebuilding this for each of the ~21 styled blocks would be a real cost at high resolution.
+ state = _state(image_seq_len=6)
+ mask = torch.zeros(10, 10, dtype=torch.bool)
+ assert state.pad_attention_mask(mask) is state.pad_attention_mask(mask)
+
+
+def test_pad_attention_mask_passes_none_through() -> None:
+ assert _state().pad_attention_mask(None) is None
+
+
+def test_clear_releases_the_captured_cache() -> None:
+ # The processors stay installed on the *cached* transformer, so anything retained here survives the
+ # invocation. At 2560x1440 that would be ~1.7 GiB of leaked VRAM.
+ state = _state(image_seq_len=6)
+ state.begin_capture()
+ capture_style_reference(state, 0, torch.randn(1, 8, 10, 8), torch.randn(1, 2, 10, 8), torch.randn(1, 2, 10, 8))
+ state.begin_inject(0.0)
+ state.pad_attention_mask(torch.zeros(10, 10, dtype=torch.bool))
+
+ state.clear()
+
+ assert state.mode is Krea2StyleReferenceMode.OFF
+ assert state._cache == {}
+ assert state._scale_vector is None
+ assert state._padded_masks == []
diff --git a/tests/backend/krea2/test_style_reference_rf.py b/tests/backend/krea2/test_style_reference_rf.py
new file mode 100644
index 00000000000..79ac263cb1a
--- /dev/null
+++ b/tests/backend/krea2/test_style_reference_rf.py
@@ -0,0 +1,68 @@
+import pytest
+import torch
+
+from invokeai.backend.krea2.style_reference_rf import build_linear_reference_latents
+
+
+def test_linear_schedule_returns_one_latent_per_sigma() -> None:
+ reference = torch.randn(1, 12, 64)
+ sigmas = [1.0, 0.75, 0.5, 0.25]
+ assert len(build_linear_reference_latents(reference, sigmas)) == len(sigmas)
+
+
+def test_linear_schedule_matches_the_closed_form() -> None:
+ reference = torch.randn(1, 12, 64)
+ sigmas = [1.0, 0.5, 0.0]
+ latents = build_linear_reference_latents(reference, sigmas)
+
+ # At sigma 0 the reference is untouched; at sigma 1 it is pure noise.
+ assert torch.allclose(latents[2], reference)
+ noise = latents[0]
+ assert torch.allclose(latents[1], 0.5 * reference + 0.5 * noise, atol=1e-6)
+
+
+def test_linear_schedule_reuses_a_single_noise_draw() -> None:
+ """Upstream draws eps once and reuses it for every sigma.
+
+ Re-sampling per step would make the reference's features jitter from step to step, which is exactly
+ the thing the styled attention must not do.
+ """
+ reference = torch.randn(1, 12, 64)
+ latents = build_linear_reference_latents(reference, [0.8, 0.4])
+
+ # Recover eps from each point: z = (1 - s) * ref + s * eps => eps = (z - (1 - s) * ref) / s
+ eps_from_first = (latents[0] - 0.2 * reference) / 0.8
+ eps_from_second = (latents[1] - 0.6 * reference) / 0.4
+ assert torch.allclose(eps_from_first, eps_from_second, atol=1e-4)
+
+
+def test_linear_schedule_is_deterministic_for_a_fixed_seed() -> None:
+ reference = torch.randn(1, 12, 64)
+ first = build_linear_reference_latents(reference, [0.7])
+ second = build_linear_reference_latents(reference, [0.7])
+ assert torch.equal(first[0], second[0])
+
+
+def test_linear_schedule_responds_to_the_seed() -> None:
+ reference = torch.randn(1, 12, 64)
+ first = build_linear_reference_latents(reference, [0.7], seed=1)
+ second = build_linear_reference_latents(reference, [0.7], seed=2)
+ assert not torch.allclose(first[0], second[0])
+
+
+def test_linear_schedule_clamps_sigmas_into_range() -> None:
+ reference = torch.randn(1, 12, 64)
+ latents = build_linear_reference_latents(reference, [-0.5, 1.5])
+ assert torch.allclose(latents[0], reference)
+
+
+def test_linear_schedule_preserves_dtype_and_shape() -> None:
+ reference = torch.randn(1, 12, 64, dtype=torch.float16)
+ latent = build_linear_reference_latents(reference, [0.5])[0]
+ assert latent.shape == reference.shape
+ assert latent.dtype == torch.float16
+
+
+def test_linear_schedule_rejects_an_empty_schedule() -> None:
+ with pytest.raises(ValueError, match="sigma schedule is empty"):
+ build_linear_reference_latents(torch.randn(1, 12, 64), [])