ComfyUI Node

AP Loop Close (Latent)

The latent loop's return wire — collect processed latents without touching the VAE

By adampolczynski·Created 6 months ago·Updated 6 months ago· 1
AP Loop Close (Latent)
  • loop_token
  • processed_latent
  • processed_mask
  • additional_data
  • processed_latents
  • processed_masks
  • processed_additional_data

The closing half of the latent loop pair. AP Latent Loop Open (Latent) opens a per-latent recursion; this node closes it - taking your processed latent from the loop body, accumulating it into the output sequence, and feeding it back as processed history for the next iteration. All in latent space, so your iterative latent workflow never pays a VAE encode/decode per frame.

In the simplified API it needs just two things: the loop_token from the Open node and your processed_latent. That's it. The token carries iteration index, total count, and history depth, so you don't wire those manually - the same "clean API" philosophy the author built the whole loop system around.

The mechanism

Same recursion machinery as APImageLoopClose, latent-flavored. It reads the loop state from the token, appends your processed latent to an accumulator (and to the running history buffer), then either returns the accumulated sequence when the last latent is reached, or re-triggers the loop with an incremented iteration index carrying the state forward. The latent dict metadata - shape, noise, whatever your sampler attached - travels with each entry, so the accumulated output is a real batch of latents you can decode once at the end.

Inputs and outputs

  • loop_token (required, FLOW_CONTROL) - from APLatentLoopOpen.
  • processed_latent (required) - the output of your per-iteration processing (warped+sampled latent, blended latent, etc.).
  • processed_mask (optional) - per-iteration mask if your loop produces one.
  • additional_data (optional, *) - a per-iteration payload aggregated across the loop.

Outputs: processed_latents (the accumulated batch - decode or save it once, at the end), processed_masks, and processed_additional_data.

Installing it

Pack-wide install: ComfyUI Manager (search "AP_OpticalFlow"), or

cd ComfyUI/custom_nodes
git clone https://github.com/adampolczynski/ComfyUI_AP_OpticalFlow
python -m pip install -r custom_nodes/ComfyUI_AP_OpticalFlow/requirements.txt

Restart. Dependency is torchvision>=0.15.

Where it fits

The README's latent warp pipeline is the textbook shape: APLatentLoopOpen (Latent) → per-iteration APApplyRAFTOpticalFlowLatent (or masked) warp → sampler → APLatentLoopClose (Latent). On the next iteration, Loop Open hands you your previous processed latent in processed_previous_latent_1, so the warp has real temporal history to work from. Run the whole thing and the single VAE decode at the end is the only pixel-space step in the sequence.

The pairing rule (same as the image loop)

The loop_token is the link, and it's load-bearing. Disconnect it or mix up tokens between the image and latent loops and the pair desyncs - the Open node will raise its "expected previous processed latent" error, which is the loop telling you the return path broke. Keep token wired, keep processed_latent fed from actual processed output, and the recursion handles the rest. If you find yourself with a latent loop that seems to only run one iteration, check that the token path from Open to Close is intact - that's the whole connection.

CategoryAP_OpticalFlow

Inputs (4)

NameTypeDefaultDescription
loop_tokenFLOW_CONTROL
processed_latentLATENT
processed_maskoptMASK
additional_dataopt*

Outputs (3)

NameTypeDescription
processed_latentsLATENT
processed_masksMASK
processed_additional_data*