diff --git a/conditioning.py b/conditioning.py index 92597f66..8d597f80 100644 --- a/conditioning.py +++ b/conditioning.py @@ -414,12 +414,17 @@ def latent_from_tensor_bundle(bundle): # Transition phrases sorted longest-first so regex alternation picks the most specific match. # These mark scene or temporal cuts in video prompts and drive prompt splitting. _PROMPT_TRANSITION_PHRASES = sorted([ - # Ordinal scene markers - let users explicitly label scenes + # Ordinal and narrative scene markers "the tenth scene", "the ninth scene", "the eighth scene", "the seventh scene", "the sixth scene", "the fifth scene", "the fourth scene", "the third scene", "the second scene", "the first scene", "the final scene", "the last scene", "scene ten", "scene nine", "scene eight", "scene seven", "scene six", "scene five", "scene four", "scene three", "scene two", "scene one", + # Explicit scene-boundary phrases + "after a brief scene cut", "as the scene transitions", + "the scene begins with", "in the next scene", + "later, another scene shows", "another scene shows", + "the video concludes", # Multi-word scene-cut language "the scene then cuts to", "the scene cuts to", "the scene then transitions to", "the scene transitions to", "the scene then fades to", "the scene fades to", @@ -6096,6 +6101,19 @@ class FunPackVideoRefinerV2(FunPackVideoRefiner): i += 2 if current: segments.append(current) + + # Stacking fix: if a segment consists entirely of transition markers with no real content, + # two transition phrases were adjacent ("after a brief scene cut, in the next scene ..."). + # Prepend the pure-transition segment to the FOLLOWING segment so they read as one unit. + i = 0 + while i < len(segments): + stripped = _TRANSITION_SPLIT_PATTERN.sub("", segments[i]).strip().strip(",;. ") + if not stripped and i + 1 < len(segments): + segments[i + 1] = segments[i] + ", " + segments[i + 1] + segments.pop(i) + else: + i += 1 + return segments if len(segments) > 1 else [text] def _v2_split_char_from_scene(self, first_segment): diff --git a/context_transition.py b/context_transition.py index 65dbb20c..19ffca6b 100644 --- a/context_transition.py +++ b/context_transition.py @@ -108,10 +108,16 @@ class FunPackTransitionContextHandler(comfy.context_windows.IndexListContextHand # conds = [uncond_list, cond_list, ...] - we read the MAX across all groups # because conds[0] is the negative conditioning which always has 1 entry. try: - num_windows = max((len(c) for c in conds if c), default=1) + group_sizes = [len(c) for c in conds if c] + num_windows = max(group_sizes, default=1) except Exception: + group_sizes = [] num_windows = 1 self.auto_num_windows = num_windows + logging.info( + "FunPack context windows: cond group sizes=%s, num_windows=%s, dim=%s, x_in=%s.", + group_sizes, num_windows, self.dim, list(x_in.shape), + ) # Set context_length to segment size (total / N) for accurate VRAM estimation if num_windows > 1: