Clean up per-beat H3 script output
This commit is contained in:
+73
-59
@@ -3247,65 +3247,79 @@ def dialogue_filler_warnings(beats, seconds_per_shot):
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def annotate_script_guards(gens, anatomy_shots, anatomy_mode):
|
def _annotate_shot_refs(gen, ref_slots, shot_index):
|
||||||
"""Human-readable guard report prepended to the script socket.
|
normalized_slots = _normalized_ref_slots(ref_slots)
|
||||||
|
tagged = _slot_refs_for_text(gen, normalized_slots)
|
||||||
The `script` output is for inspection, not for feeding back into the node, so
|
named = _named_refs_for_text(gen, normalized_slots, kinds=("character", "location"))
|
||||||
a compact report there is the quickest way to see whether a guard actually made
|
seen = set()
|
||||||
it into each shot's prompt text.
|
merged = []
|
||||||
"""
|
for slot_number, ref in tagged:
|
||||||
lines = []
|
key = (slot_number, "tag")
|
||||||
if anatomy_mode == "off":
|
if key in seen:
|
||||||
lines.append("# anatomy_guard: off")
|
continue
|
||||||
elif anatomy_shots:
|
seen.add(key)
|
||||||
lines.append(
|
merged.append((slot_number, ref, "tag"))
|
||||||
"# anatomy_guard: injected on shot(s) "
|
for slot_number, ref in named:
|
||||||
+ ",".join(str(n) for n in anatomy_shots)
|
key = (slot_number, "name")
|
||||||
)
|
if key in seen or any(slot_number == existing[0] for existing in merged):
|
||||||
else:
|
continue
|
||||||
lines.append("# anatomy_guard: no shots matched the auto gate")
|
seen.add(key)
|
||||||
body = "\n---\n".join(gens)
|
merged.append((slot_number, ref, "name"))
|
||||||
return "\n".join(lines + ["", body]) if body else "\n".join(lines)
|
if not merged:
|
||||||
|
return f"# shot {shot_index} refs: none", "References used: none"
|
||||||
|
labels = []
|
||||||
def annotate_script_debug(gens, anatomy_shots, anatomy_mode, ref_slots):
|
info_labels = []
|
||||||
parts = [annotate_script_guards(gens, anatomy_shots, anatomy_mode)]
|
for slot_number, ref, source in merged:
|
||||||
ref_report = annotate_script_refs(gens, ref_slots)
|
label = _reference_text(ref.get("name")) or _reference_text(ref.get("id")) or f"reference {slot_number}"
|
||||||
if ref_report:
|
labels.append(f"Picture {slot_number} {label} (by {source})")
|
||||||
parts.insert(1, ref_report)
|
info_labels.append(f"<Picture {slot_number}> {label} (matched by {source})")
|
||||||
return "\n".join(part for part in parts if part)
|
return (
|
||||||
|
f"# shot {shot_index} refs: " + "; ".join(labels),
|
||||||
|
"References used: " + "; ".join(info_labels),
|
||||||
def annotate_script_refs(gens, ref_slots):
|
)
|
||||||
"""Per-shot reference routing summary for the script socket."""
|
|
||||||
lines = []
|
|
||||||
normalized_slots = _normalized_ref_slots(ref_slots)
|
def _annotate_shot_guard(shot_index, anatomy_shots, anatomy_mode):
|
||||||
for shot_index, gen in enumerate(gens or [], 1):
|
anatomy_set = set(anatomy_shots or [])
|
||||||
tagged = _slot_refs_for_text(gen, normalized_slots)
|
if anatomy_mode == "off":
|
||||||
named = _named_refs_for_text(gen, normalized_slots, kinds=("character", "location"))
|
return "Anatomy guard: off"
|
||||||
seen = set()
|
if shot_index in anatomy_set:
|
||||||
merged = []
|
return "Anatomy guard: injected into this prompt"
|
||||||
for slot_number, ref in tagged:
|
if anatomy_mode == "forced":
|
||||||
key = (slot_number, "tag")
|
return "Anatomy guard: forced on, but nothing was injected"
|
||||||
if key in seen:
|
return "Anatomy guard: not injected for this prompt"
|
||||||
continue
|
|
||||||
seen.add(key)
|
|
||||||
merged.append((slot_number, ref, "tag"))
|
def annotate_script_debug(gens, anatomy_shots, anatomy_mode, ref_slots):
|
||||||
for slot_number, ref in named:
|
blocks = []
|
||||||
key = (slot_number, "name")
|
for shot_index, gen in enumerate(gens or [], 1):
|
||||||
if key in seen or any(slot_number == existing[0] for existing in merged):
|
_ref_report, ref_info = _annotate_shot_refs(gen, ref_slots, shot_index)
|
||||||
continue
|
blocks.append(
|
||||||
seen.add(key)
|
"\n".join(
|
||||||
merged.append((slot_number, ref, "name"))
|
[
|
||||||
if not merged:
|
f"Prompt {shot_index}",
|
||||||
lines.append(f"# shot {shot_index} refs: none")
|
gen,
|
||||||
continue
|
"",
|
||||||
labels = []
|
f"Beat {shot_index} info",
|
||||||
for slot_number, ref, source in merged:
|
_annotate_shot_guard(shot_index, anatomy_shots, anatomy_mode),
|
||||||
label = _reference_text(ref.get("name")) or _reference_text(ref.get("id")) or f"reference {slot_number}"
|
ref_info,
|
||||||
labels.append(f"Picture {slot_number} {label} (by {source})")
|
]
|
||||||
lines.append(f"# shot {shot_index} refs: " + "; ".join(labels))
|
)
|
||||||
return "\n".join(lines)
|
)
|
||||||
|
if blocks:
|
||||||
|
return "\n\n---\n\n".join(blocks)
|
||||||
|
if anatomy_mode == "off":
|
||||||
|
return "Beat info\nAnatomy guard: off\nReferences used: none"
|
||||||
|
return "Beat info\nAnatomy guard: not injected for this prompt\nReferences used: none"
|
||||||
|
|
||||||
|
|
||||||
|
def annotate_script_refs(gens, ref_slots):
|
||||||
|
"""Per-shot reference routing summary for the script socket."""
|
||||||
|
lines = []
|
||||||
|
for shot_index, gen in enumerate(gens or [], 1):
|
||||||
|
shot_report, _shot_info = _annotate_shot_refs(gen, ref_slots, shot_index)
|
||||||
|
lines.append(shot_report)
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
def speech_flags(beats):
|
def speech_flags(beats):
|
||||||
|
|||||||
@@ -599,6 +599,25 @@ class DumasH3LongVideosHelperTests(unittest.TestCase):
|
|||||||
self.assertIn("# shot 1 refs: Picture 1 Mara (by name); Picture 2 Hangar (by name)", report)
|
self.assertIn("# shot 1 refs: Picture 1 Mara (by name); Picture 2 Hangar (by name)", report)
|
||||||
self.assertIn("# shot 2 refs: none", report)
|
self.assertIn("# shot 2 refs: none", report)
|
||||||
|
|
||||||
|
def test_annotate_script_debug_groups_each_prompt_with_its_beat_info(self):
|
||||||
|
refs = [
|
||||||
|
{"kind": "character", "image": "img1", "name": "Mara"},
|
||||||
|
{"kind": "location", "image": "img2", "name": "Hangar"},
|
||||||
|
]
|
||||||
|
|
||||||
|
report = self.module.annotate_script_debug(
|
||||||
|
["[Generation 1] Mara waits in the Hangar.", "[Generation 2] Nobody else is here."],
|
||||||
|
[1],
|
||||||
|
"auto",
|
||||||
|
refs,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertIn("Prompt 1\n[Generation 1] Mara waits in the Hangar.", report)
|
||||||
|
self.assertIn("Beat 1 info\nAnatomy guard: injected into this prompt", report)
|
||||||
|
self.assertIn("References used: <Picture 1> Mara (matched by name); <Picture 2> Hangar (matched by name)", report)
|
||||||
|
self.assertIn("Prompt 2\n[Generation 2] Nobody else is here.", report)
|
||||||
|
self.assertIn("Beat 2 info\nAnatomy guard: not injected for this prompt\nReferences used: none", report)
|
||||||
|
|
||||||
def test_input_types_expose_nine_ref_slots(self):
|
def test_input_types_expose_nine_ref_slots(self):
|
||||||
optional = self.module.H3LongVideos.INPUT_TYPES()["optional"]
|
optional = self.module.H3LongVideos.INPUT_TYPES()["optional"]
|
||||||
|
|
||||||
@@ -1038,9 +1057,9 @@ class DumasH3LongVideosHelperTests(unittest.TestCase):
|
|||||||
plan_only=True,
|
plan_only=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertIn("# anatomy_guard: injected on shot(s) 2", result[3])
|
self.assertIn("Prompt 1", result[3])
|
||||||
self.assertIn("# shot 1 refs: none", result[3])
|
self.assertIn("Beat 1 info\nAnatomy guard: not injected for this prompt\nReferences used: none", result[3])
|
||||||
self.assertIn("# shot 2 refs: none", result[3])
|
self.assertIn("Beat 2 info\nAnatomy guard: injected into this prompt\nReferences used: none", result[3])
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
"[Generation 1] editorial room, soft practical lighting. Francine stands alone.",
|
"[Generation 1] editorial room, soft practical lighting. Francine stands alone.",
|
||||||
result[3],
|
result[3],
|
||||||
|
|||||||
Reference in New Issue
Block a user