File size: 4,985 Bytes
e488ce7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | """ComfyUI MiniMax H3 Context Loop 0.6.
Disk-backed recursive MiniMax H3 scene loops with frame-exact picture/audio
continuation, review gates, checkpoint resume, and final assembly.
This project continues the looping work that grew from NikoDemon80's original
ComfyUI-H3-Motion-Context. It intentionally uses distinct public node ids and
vendors upstream's shared runtime-patch ABI so both packs can be installed
together without wrapping ComfyUI twice. The
original Motion Context, Save Latent, and Load Latent ids remain exclusively
owned by Niko's upstream pack; this pack exports its stricter Loop Trim, a
distinctly named Seam Probe adaptation, and the specialized H3 Chain nodes.
Registers the loop nodes without changing ordinary ComfyUI or general Qwen
behavior. On older ComfyUI builds, startup adds the released H3-only tokenizer
tokens through a module-local alias, and Chain Context activates two internal
fallback patches inline on first execution:
patch_layout lifts the first/last-only keyframe anchor restriction,
moves pinned audio onto the clip's own timeline, and
keeps anchor coordinates aligned when refs shift the
layout cursor
patch_payload stops the refs branch clobbering keyframe cond latents,
so pinned video and pinned audio can be used together
Both wrappers are marker-gated. Niko's upstream copy and this vendored copy
recognize the same patch-ownership markers; whichever activates second stands
down. H3 workflows that use neither pack remain stock. If either self-test
fails the nodes still load but refuse the affected path, so an upstream
ComfyUI change produces a clear message rather than a silently wrong render.
When ComfyUI's native MiniMax H3 Add Guide API from merged PR #15439 is
available, core owns arbitrary-position video/audio guides, Ref2VA target
alignment, and keyframe/ref payload merging. This pack switches automatically
to native guide records and installs no H3 layout or payload wrapper. Version
0.6 emits a one-time update warning before using the legacy fallback.
"""
from .tokenizer_compat import (
install_minimax_tokenizer_compat as _install_minimax_tokenizer_compat,
)
_MINIMAX_TOKENIZER_COMPAT_STATUS = _install_minimax_tokenizer_compat()
from .nodes import (
NODE_CLASS_MAPPINGS as _CONTEXT_NODE_CLASS_MAPPINGS,
NODE_DISPLAY_NAME_MAPPINGS as _CONTEXT_NODE_DISPLAY_NAME_MAPPINGS,
)
from .chain_nodes import (
CHAIN_NODE_CLASS_MAPPINGS,
CHAIN_NODE_DISPLAY_NAME_MAPPINGS,
)
from .upscale_nodes import (
UPSCALE_NODE_CLASS_MAPPINGS,
UPSCALE_NODE_DISPLAY_NAME_MAPPINGS,
)
from .probe_node import (
NODE_CLASS_MAPPINGS as _PROBE_NODE_CLASS_MAPPINGS,
NODE_DISPLAY_NAME_MAPPINGS as _PROBE_NODE_DISPLAY_NAME_MAPPINGS,
)
from .masking_nodes import (
NODE_CLASS_MAPPINGS as _MASKING_NODE_CLASS_MAPPINGS,
NODE_DISPLAY_NAME_MAPPINGS as _MASKING_NODE_DISPLAY_NAME_MAPPINGS,
)
from .master_audio_context import (
NODE_CLASS_MAPPINGS as _MASTER_AUDIO_NODE_CLASS_MAPPINGS,
NODE_DISPLAY_NAME_MAPPINGS as _MASTER_AUDIO_NODE_DISPLAY_NAME_MAPPINGS,
)
from .masked_bridge import (
NODE_CLASS_MAPPINGS as _MASKED_BRIDGE_NODE_CLASS_MAPPINGS,
NODE_DISPLAY_NAME_MAPPINGS as _MASKED_BRIDGE_NODE_DISPLAY_NAME_MAPPINGS,
)
from .source_av_target import (
NODE_CLASS_MAPPINGS as _SOURCE_AV_TARGET_NODE_CLASS_MAPPINGS,
NODE_DISPLAY_NAME_MAPPINGS as _SOURCE_AV_TARGET_NODE_DISPLAY_NAME_MAPPINGS,
)
from .reference_video_fade import (
NODE_CLASS_MAPPINGS as _REFERENCE_VIDEO_FADE_NODE_CLASS_MAPPINGS,
NODE_DISPLAY_NAME_MAPPINGS as _REFERENCE_VIDEO_FADE_DISPLAY_NAMES,
)
NODE_CLASS_MAPPINGS = dict(_CONTEXT_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(CHAIN_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(UPSCALE_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(_PROBE_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(_MASKING_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(_MASTER_AUDIO_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(_MASKED_BRIDGE_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(_SOURCE_AV_TARGET_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(_REFERENCE_VIDEO_FADE_NODE_CLASS_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS = dict(_CONTEXT_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(CHAIN_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(UPSCALE_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(_PROBE_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(_MASKING_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(_MASTER_AUDIO_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(_MASKED_BRIDGE_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(_SOURCE_AV_TARGET_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(
_REFERENCE_VIDEO_FADE_DISPLAY_NAMES)
WEB_DIRECTORY = "./web"
__all__ = [
"NODE_CLASS_MAPPINGS",
"NODE_DISPLAY_NAME_MAPPINGS",
"WEB_DIRECTORY",
]
|