Nodes/H3 Relay/H3RelayEditHistory
ComfyUI Node

H3RelayEditHistory

Handing the model 18 frames of its own past

By akatz-ai·Created 3 months ago·Updated 10 days ago· 44
H3RelayEditHistory
  • conditioning
  • latent
  • vae
  • audio_vae
  • previous_frames
  • previous_audio
  • CONDITIONING
  • LATENT
◄history_frames—►

Every long video workflow in ComfyUI eventually hits the same wall: the model has no memory. Wan's native context is 81 frames; MiniMax H3's trained range is roughly 5–15 seconds. Anything longer is stitching, and stitching is where faces drift, colours shift and seams appear.

H3RelayEditHistory is where H3 Relay does the stitching properly for character-swap edits. It's an internal node - H3 Relay Windowed Edit · Character Swap creates it when it expands, one per continuation window - and its job is narrow: take the frames the model already generated for the previous window and feed them back in as context, so window four knows what window three looked like.

How the slide works

H3's sliding history isn't "give the model the last 18 frames and let it continue." It's subtler than that, and getting it wrong is why hand-rolled continuation graphs wander.

The history is added before the sampled target, and it includes one repeated boundary frame. So history_frames = 18 means 17 frames of genuine past plus one boundary frame the model regenerates from. The conditioning and latent are extended to carry that extra prefix, then trimmed so the target the sampler actually denoises is exactly the window size you asked for. Nothing is lost from the delivery - the boundary is thrown away during assembly, not consumed out of your duration.

This node wraps that contraction and refuses to proceed on anything unexpected: it computes the sliding history and if the resulting trim isn't exactly 1 frame, it raises. That check exists because a silently-wrong trim is invisible in the output - you just get a subtly shorter or doubled-up video, which is far worse than an error message.

Inputs and outputs

Seven required inputs, all wired by the parent node:

  • conditioning and latent - the Ref2VA conditioning and empty latent for this window, straight from the native H3 encode.
  • vae and audio_vae - both, because H3 is generating picture and audio together. Wiring only the video VAE is a common mistake in hand-built variants.
  • previous_frames - the generated video history. In the edit graph this comes from H3RelayEditWindow's generated_history output, which is the model's frames, not your source footage.
  • previous_audio - the matching generated audio prefix, so the audio doesn't get a discontinuity at the seam either.
  • history_frames - 0, 1, or 17k+1 (18, 35, 52 …). Set it on the parent node: 0 gives independent windows with no memory, 1 carries only a generated boundary frame, 18 is the default and the one the pack is validated around.

Outputs are CONDITIONING and LATENT, which go into the sampler. That's the whole node.

You will not drag this out yourself

It only makes sense in the middle of a graph that has already produced a previous window's raw decoded frames and its audio, with both still in memory. That's the thing a wrapper node like windowed edit is for.

Installation is the pack's: H3 Relay in ComfyUI Manager, or

cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/akatz-ai/h3-relay.git

then restart. ComfyUI 0.32.0+ and the MiniMax H3 weights (see the pack's MODELS.md) are the real requirements. No pip installs.

Where it breaks

  • H3 history contract changed; refusing to sample. The sliding-history implementation it calls into returned an unexpected shape. In practice this means a ComfyUI build or an upstream H3 node version that has moved relative to what the pack expects. Update the pack - the check is deliberately fail-closed rather than letting a misaligned history through.
  • Missing native H3 history anchor support. Long continuations need ComfyUI to understand packed-layout history. H3 Relay ships a guarded compatibility layer for older builds, but the parent node preflights this before the first GPU window so you find out at zero cost rather than after a render.
  • A window that moved backwards in the source. If you see a stretch where the boundary frame doubles up, check the window plan the parent node logs. The plan should always advance; the last window rounds up and pads its tail rather than shifting earlier windows.
  • Ceiling confusion. History isn't free: a bigger history_frames means more conditioning to run per window. 18 is a well-tested default; treat larger values as experiments, and keep history_frames strictly smaller than window_frames - the parent node enforces that.
CategoryH3 Relay/internal

Inputs (7)

NameTypeDefaultDescription
conditioningCONDITIONING—
latentLATENT—
vaeVAE—
audio_vaeVAE—
previous_framesIMAGE—
previous_audioAUDIO—
history_framesINT—

Outputs (2)

NameTypeDescription
CONDITIONINGCONDITIONING—
LATENTLATENT—