Skip to content

[Partner Nodes] fix(ByteDance): Layer Separation wiring tooltips + exact 2K price - #15366

Closed
christian-byrne wants to merge 20 commits into
feat/api-nodes/bytedance-layer-separationfrom
fix/seedream-layer-separation-wiring
Closed

[Partner Nodes] fix(ByteDance): Layer Separation wiring tooltips + exact 2K price#15366
christian-byrne wants to merge 20 commits into
feat/api-nodes/bytedance-layer-separationfrom
fix/seedream-layer-separation-wiring

Conversation

@christian-byrne

@christian-byrne christian-byrne commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Targets feat/api-nodes/bytedance-layer-separation so it can land inside #15351 without disturbing its approval. Two independent commits — drop the second freely if the rate card says otherwise.

1. The wiring tooltips point at sockets that no longer exist

Five tooltips on ByteDanceSeedreamLayerSeparationNode tell the user to wire into image_0, mask_0, image_1 and mask_1 of Create Layered Image.

ImageCompositor replaced its two io.Autogrow.Inputs with a single io.Image.Input("image") + io.Mask.Input("mask") in commit 9232943a on #15317 ("feat: single batched inputs, transparent default, experimental flag", 2026-08-06T23:06Z) — after this branch's only commit (15:13Z). Those sockets are gone, so the instructions cannot be followed as written. Anyone doing QA from the tooltips stalls on step one.

Rewritten to describe the real path: batch base_image ahead of layers (and base_mask ahead of masks) with Batch Images / Batch Masks, then feed the batches to image / mask. Base-first is what the bboxes list already assumes, so the index alignment is preserved.

2. Two statements that were wrong independently of that change

Both are in the crop_layers tooltip:

  • It calls minimal-size "the pairing expected by Create Layered Image". It is the opposite. batch_images (comfy_extras/nodes_post_processing.py:514) resizes every frame to the first frame's size via common_upscale(..., "bilinear", "center"). Cropped layers are not base-sized, so batching them behind the base silently centre-crops and rescales each one, destroying exactly the placement the mode exists to preserve. Full canvas is the mode that survives batching — and it is already the default.
  • It says full canvas lets you "recompose directly with ImageCompositeMasked". That node does mask = torch.ones_like(source) when no mask is given (comfy_extras/nodes_mask.py:25-26), i.e. 1 = opaque — the inverse of this node's LoadImage convention. An InvertMask is required first, as the masks tooltip already correctly says.

Tooltip text only; no behaviour change.

3. 2K renders as a price range when its price is known

size has four options: auto, 1K, 1.5K, 2K. The badge returns an exact 0.032 for 1K/1.5K and falls through to a 0.032–0.064 range for everything else — so 2K shows a range even though only auto is genuinely unresolved at graph-build time. Added a 2K branch returning the range's own upper bound.

Evaluated against jsonata 2.x with the frontend's normalisation (normalizeWidgetValue lowercases COMBO values before evaluation, src/composables/node/useNodePricing.ts:229-233):

auto -> range_usd 0.032-0.064
1k   -> usd 0.032
1.5k -> usd 0.032
2k   -> usd 0.064

0.064 is inferred from the existing range's max_usdplease confirm against the Metronome rate card before merging, since the pricing checkbox on #15351 is still unticked. It is a standalone commit precisely so it can be dropped.

Note on a non-issue

The lowercase ["1k", "1.5k"] comparison against uppercase combo options is correct, not a case bug. The frontend lowercases COMBO widget values before JSONata evaluation, and the sibling Seedream badge in the same file uses the same convention ($contains($sp, "1k"), nodes_bytedance.py:917). Flagging it here because it has been raised as a suspected bug more than once.

API Node PR Checklist

Scope

  • Is API Node Change

Pricing & Billing

  • Need pricing update
  • No pricing update

If Need pricing update:

  • Metronome rate cards updated
  • Auto‑billing tests updated and passing

QA

  • QA done
  • QA not required

Comms

  • Informed Kosinkadink

comfyanonymous and others added 17 commits August 3, 2026 16:29
…l Try-On API (#15249)

Signed-off-by: bigcat88 <bigcat88@icloud.com>
This is performance critical for ACE step.
…ort (#15294)

Signed-off-by: Alexander Piskun <bigcat88@icloud.com>
* [Partner Nodes] feat(BFL): add Flux 3 video model

Signed-off-by: Alexander Piskun <bigcat88@icloud.com>

* [Partner Nodes] fix(BFL): harden keyframe value check

Signed-off-by: Alexander Piskun <bigcat88@icloud.com>

---------

Signed-off-by: Alexander Piskun <bigcat88@icloud.com>
Co-authored-by: Jedrzej Kosinski <kosinkadink1@gmail.com>
Co-authored-by: Jedrzej Kosinski <kosinkadink1@gmail.com>
Comfy-aimdo 0.4.12 increases error logging reliablity to help root
cause os errors in some of the C APIs that are causing issues for
some users.

The log is also unified with python logging, so non-terminal users
see the logs properly.

Aimdo 0.4.13 fixes a bug in async-offload + MRU primary weights
allocation. #15284
Signed-off-by: Alexander Piskun <bigcat88@icloud.com>
Signed-off-by: bigcat88 <bigcat88@icloud.com>
The five output/crop tooltips tell the user to wire into image_0, mask_0,
image_1 and mask_1 of "Create Layered Image". ImageCompositor dropped its
Autogrow inputs in favour of a single batched image + mask
(comfy_extras/nodes_compositor.py), so those sockets no longer exist and
the instructions cannot be followed.

Describe the actual path instead: batch base_image ahead of layers (and
base_mask ahead of masks) and feed the batches to the image/mask inputs.
Batching keeps the base first, which is what the bboxes list already
assumes.

Also correct two statements that were wrong independently of that change:

- crop_layers said minimal size was "the pairing expected by Create
  Layered Image". It is the opposite: cropped layers are not base-sized,
  so batching them with the base rescales them to the base resolution
  (batch_images resizes every frame to the first). Full canvas is the
  mode that survives batching.
- crop_layers said full canvas lets you "recompose directly with
  ImageCompositeMasked". That node treats mask value 1 as opaque, the
  inverse of this node's LoadImage convention, so an InvertMask is
  required first - as the masks tooltip already says.

No behaviour change; tooltip text only.

Signed-off-by: Christian Byrne <cbyrne@comfy.org>
size has four options: auto, 1K, 1.5K and 2K. The badge gives an exact
0.032 for 1K/1.5K and falls through to a 0.032-0.064 range for everything
else, so 2K renders as a range even though its price is determined - only
auto is genuinely unknown at graph-build time.

Add a 2K branch returning the exact 0.064 (the range's own upper bound)
and leave the range for auto.

Verified against jsonata 2.x with the frontend's normalisation (combo
values are lowercased before evaluation, useNodePricing.ts):
  auto -> range_usd 0.032-0.064
  1k   -> usd 0.032
  1.5k -> usd 0.032
  2k   -> usd 0.064

Signed-off-by: Christian Byrne <cbyrne@comfy.org>
…ot ImageBatch's

The wiring tooltips added in this PR named "image1 = base_image,
image2 = layers" and "mask1 = base_mask, mask2 = masks". Those are the
socket ids of ImageBatch, which is DEPRECATED (nodes.py:1945-1956).

The live node is BatchImagesNode / BatchMasksNode
(comfy_extras/nodes_post_processing.py:568, :590). Both use
io.Autogrow.TemplatePrefix(..., prefix="image"/"mask"), and
TemplatePrefix builds its names as [f"{prefix}{i}" for i in range(max)]
(comfy_api/latest/_io.py:1071), so the sockets are zero-indexed:
image0, image1, ... and mask0, mask1, ...

comfy_extras/nodes_replacements.py:36-42 confirms the mapping, migrating
ImageBatch's old "image1" to the new "images.image0".

This matters because image1 also exists on the live node - it is the
second slot. A user following the old text wires base_image into slot 2,
which reverses the batch order, and the compositor stacks the background
plate on top of every layer. It fails silently rather than erroring,
which is the same failure mode these tooltips were rewritten to prevent.

Also documents the metadata "flags" key on the bboxes output, which the
node emits (flags is written at both bbox construction sites) but the
tooltip did not list. A layer flagged bbox_degenerate or
bbox_out_of_canvas is returned fully transparent and nothing is logged,
so metadata.flags is the only way a user can discover a lost layer.

Drops "in either mode" from the same tooltip: the crop_layers tooltip now
tells users that minimal size is not the mode to feed Create Layered
Image, so describing the bbox behaviour as identical in both modes is
dead advice.

@bigcat88 bigcat88 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching the stale socket references — the Autogrow removal in 9232943a is real, and the current tooltips do point at sockets that no longer exist.
Commit 2 (flat 2K price): the premise doesn't hold — element layers don't come back at 2K resolution. Measured on live 2K runs, element layers arrive as tight crops at e.g. 1501×1506 (2.26 MP), 1491×1492 (2.22 MP), 932×2061 (1.92 MP) — consistently under the 2.61 MP per-image tier boundary; only the 2048×2048 background (4.19 MP) crosses it. The rate card itself expects this: elements are usually cropped regions below the boundary, with the full-size background above it. With per-image tiering, a typical 1-background + 3-element 2K job comes to 0.064 + 3×0.032 = 0.160, while the flat badge suggests 4×0.064 = 0.256 — roughly 60% over. Elements can exceed the boundary ("usually" isn't "always"), which is exactly what the range badge communicates. Per the note in your description, I'd drop this commit and keep range_usd for 2K.

@bigcat88
bigcat88 force-pushed the feat/api-nodes/bytedance-layer-separation branch 3 times, most recently from 278b024 to 573850c Compare August 7, 2026 08:18
@bigcat88

bigcat88 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Tool-tip changes were taken. Pricing was correct in our PR.

Big thanks for this and for reviews on parent PR. Closing this PR as everything is already incorporated into a single parent PR.

@bigcat88 bigcat88 closed this Aug 7, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 7, 2026
@bigcat88
bigcat88 deleted the fix/seedream-layer-separation-wiring branch August 7, 2026 14:02
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants