Align beat prompt with upstream Long Videos

This commit is contained in:
2026-09-10 10:34:53 +00:00
parent 72f9b07ed8
commit ea6fae7e56
4 changed files with 169 additions and 119 deletions
+55 -8
View File
@@ -2,11 +2,46 @@ import json
_DEFAULT_BEAT = "Describe this beat."
_DEFAULT_STATE = {"beats": [{"text": _DEFAULT_BEAT}]}
_DEFAULT_STATE = {"scene": "", "character_sheet": "", "beats": [{"text": _DEFAULT_BEAT}]}
_LEGACY_DIRECTIVE_PREFIXES = (
"seconds",
"duration",
"continuity",
"ref_mode",
"ref_noise_aug",
"anchor_add",
"overall_soundscape",
"soundscape",
"non_diegetic_music",
"music",
"wardrobe",
"enter",
"exit",
)
def _clone_default_state():
return {"beats": [{"text": _DEFAULT_BEAT}]}
return {
"scene": "",
"character_sheet": "",
"beats": [{"text": _DEFAULT_BEAT}],
}
def _strip_legacy_directives(text):
"""Remove directives from the abandoned Dumas Long Videos fork.
The upstream Long Videos node sends unknown field labels to the model as text,
so this builder strips the old managed controls rather than emitting prompts
that ask H3 to draw labels such as "seconds:" or "music:" in the frame.
"""
kept = []
for line in str(text or "").splitlines():
lowered = line.strip().lower()
if any(lowered.startswith(f"{name}:") for name in _LEGACY_DIRECTIVE_PREFIXES):
continue
kept.append(line)
return "\n".join(kept).strip()
def _parse_beat_prompt_state(value):
@@ -21,6 +56,8 @@ def _parse_beat_prompt_state(value):
except Exception:
return _clone_default_state()
scene = str(raw.get("scene") or "")
character_sheet = str(raw.get("character_sheet") or "")
beats = []
for item in list(raw.get("beats") or []):
if isinstance(item, dict):
@@ -30,15 +67,25 @@ def _parse_beat_prompt_state(value):
beats.append({"text": text})
if not beats:
return _clone_default_state()
return {"beats": beats}
beats = [{"text": _DEFAULT_BEAT}]
return {
"scene": scene,
"character_sheet": character_sheet,
"beats": beats,
}
def _assemble_beat_prompt(state):
parsed = _parse_beat_prompt_state(state)
chunks = []
scene = str(parsed.get("scene") or "").strip()
if scene:
chunks.append(scene)
character_sheet = str(parsed.get("character_sheet") or "").strip()
if character_sheet:
chunks.append(character_sheet)
for beat in parsed["beats"]:
text = str(beat.get("text") or "").strip()
text = _strip_legacy_directives(beat.get("text") or "")
if text:
chunks.append(text)
return "\n\n".join(chunks)
@@ -46,9 +93,9 @@ def _assemble_beat_prompt(state):
class DumasH3BeatPromptNode:
DESCRIPTION = (
"Build a MiniMax H3 prompt from one textbox per beat, with a front-end beat "
"editor that can append directive examples and expose per-shot controls for "
"timing, continuity, ref behavior, anchor additions, soundscape, and music."
"Build an upstream MiniMax H3 Long Videos prompt: optional scene paragraph, "
"optional character sheet, then one blank-line-separated textbox per beat. "
"Per-beat helpers only emit directives the upstream node understands."
)
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("prompt",)