Nodes/ComfyUI-GTE/Candidate Select (gte)
ComfyUI Node

Candidate Select (gte)

Actually pick one instead of squinting at a contact sheet

By mgkgng·Created 2 days ago·Updated 2 days ago· 4
Candidate Select (gte)
  • latents
  • denoised
  • images
  • latent
  • denoised
  • image
  • seed
  • index
index0
origin_seed0

Step one of any "throw lots of seeds at it" workflow ends with twenty thumbnails in a Save Image grid, and a decision you make by alt-tabbing. Then you have to get the good one back, and that's where it falls apart: the grid node doesn't tell you which seed you just liked, and a seed is the entire identity of a candidate.

Candidate Select is the cursor. Click a tile, see it large, keep one - and it hands you back the latent and the seed that produced it, together, so the thing you chose is a number you can write down.

Why you'd reach for it

Core's Latent From Batch can slice one item out of a batch, and that's genuinely all it does. It won't tell you which seed you picked, it can't slice a matching denoised_output at the same time, and once you have a batch of four candidates you have four separate decisions to keep in sync.

The seed arithmetic mirrors Seed Range Noise on purpose: candidate i was drawn from origin_seed + i, so selecting index i reports origin_seed + i. Feed the same origin seed that fed the noise node and the integer that comes out is directly re-usable in any stock workflow, months later.

How it works

The node publishes each candidate to ComfyUI's temp directory at two sizes - a 320px thumbnail for the grid, a 1024px copy for the single view - using the same /view?...&type=temp route PreviewImage uses. The browser only fetches a full-size image for the one candidate you're actually looking at, so the grid stays cheap and the inspection stays honest. A thumbnail is enough to tell two compositions apart and never enough to judge one, which is the whole reason there are two views.

The widget has a grid view (every candidate at once, click to select) and a single view (that one large, with ◀ ▶ to walk the batch). Those buttons move the index widget, which means choosing is an ordinary graph edit - you re-queue when you've picked. The readout says so, so a stale selection is never mistaken for a live one. A cursor that pointed somewhere other than index would be this pack's founding bug in miniature: a picture that has moved while the number under it hasn't.

Index is 0-based on the wire and 1-based in the readout, which keeps seed = origin_seed + index free of an off-by-one. Out-of-range clamps rather than raising - a cursor that refuses to move is worse than one that stops at the end, and the readout always shows where you actually are.

Inputs and outputs

Required: latents (the candidate batch - the sampler output from Step A) and index.

Optional but you want them: denoised (the matching denoised_output batch, sliced at the same index so the pair stays together - Noise Rotate needs both, and one ◀ ▶ choice shouldn't have to be repeated on a second node that could drift out of step), images (the decoded previews, which is what feeds the grid), and origin_seed (the seed that fed Seed Range Noise - this is what makes the emitted seed meaningful).

Five outputs: latent (the chosen candidate, carrying its batch_index), denoised, image, seed, and index (the one actually used, after clamping).

Wire latent and denoised into Noise Rotate to branch again; wire image to Preview or Save; wire seed anywhere a seed goes - that's the portable part.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/mgkgng/ComfyUI-GTE

Restart ComfyUI; the console prints [gte] loaded 8 node(s). Or install through ComfyUI Manager by searching the pack title, ComfyUI-GTE (display name "Generative Trajectory Explorer"). No Python dependencies - the pack's requirements.txt is empty on purpose - and no model files.

Common issues

"denoised holds 20 latents but latents holds 4." The two inputs aren't from the same sampler run, so the index would point at different candidates. Wire one sampler's output and denoised_output.

No grid, but the pick still works. The preview widget is a frontend extension served from the pack's web/ directory. When it can't draw - a frontend rewrite, a cached page, a temp-dir problem - the node prints [gte] Candidate Select: preview grid unavailable (...) and carries on. You lose the convenience, never the pick, and the console line [gte] Candidate Select: 2/20 seed 701 still tells you exactly what you kept.

The cursor seems dead. You moved it; the graph hasn't run. Re-queue.

Everything looks fine but you can't reproduce the image. That's the batch-size kernel difference, not this node: re-running a candidate alone lands ~2.2/255 away from its batched original via the UNet's batch-dependent reductions. The noise is exact; the arithmetic order isn't. Continue from the saved latent instead of regenerating if you need the same pixels.

Node IDs are GTE_-prefixed. Graphs saved against an earlier build of this pack won't resolve the nodes; open them and re-add the affected ones.

Categorygte/sampling

Inputs (5)

NameTypeDefaultDescription
latentsLATENTThe candidate batch — the sampler output from Step 1.
indexINT00–99999Which candidate to keep. Use the ◀ ▶ buttons; the readout counts from 1 the way the previews do.
denoisedoptLATENTThe matching `denoised_output` batch. Sliced at the same index, so the pair stays together for a further Noise Rotate.
imagesoptIMAGEThe decoded previews, so the chosen one can be routed on its own.
origin_seedoptINT00–18446744073709550000The seed that fed Seed Range Noise. Candidate i came from origin_seed + i, so this is what makes `seed` meaningful.

Outputs (5)

NameTypeDescription
latentLATENTThe chosen candidate, carrying its batch_index.
denoisedLATENTIts denoised_output, when `denoised` was supplied — wire both into Noise Rotate.
imageIMAGEIts preview, when `images` was supplied.
seedINTorigin_seed + index — the candidate's portable identity.
indexINTThe index actually used, after clamping.