Implement structured H3 reference objects

This commit is contained in:
2026-08-26 16:19:35 +00:00
parent 0b20381c5c
commit c37498c175
6 changed files with 1042 additions and 214 deletions
+101 -26
View File
@@ -154,9 +154,19 @@ class DumasH3LongVideosHelperTests(unittest.TestCase):
self.assertGreaterEqual(fn.cache_info().hits, 2)
def test_resolve_tagged_refs_preserves_sparse_socket_numbers(self):
refs = [None, "img2", None, None, None, None, "img7", None, "img9"]
refs = [
None,
{"kind": "character", "image": "img2", "name": "Jon"},
None,
None,
None,
None,
{"kind": "character", "image": "img7", "name": "Mara"},
None,
{"kind": "location", "image": "img9", "name": "Watchtower"},
]
text, images, dropped = self.module.resolve_tagged_refs(
text, references, dropped = self.module.resolve_tagged_refs(
"Mara <Picture 7> turns toward Jon <Picture 2> while <Picture 9> watches.",
refs,
)
@@ -165,42 +175,61 @@ class DumasH3LongVideosHelperTests(unittest.TestCase):
text,
"Mara <Picture 2> turns toward Jon <Picture 1> while <Picture 3> watches.",
)
self.assertEqual(images, ["img2", "img7", "img9"])
self.assertEqual(
[self.module._reference_image(ref) for ref in references],
["img2", "img7", "img9"],
)
self.assertEqual(dropped, [])
def test_resolve_tagged_refs_drops_unconnected_sparse_slots(self):
refs = [None, "img2", None, None, None, None, "img7", None, None]
refs = [
None,
{"kind": "character", "image": "img2", "name": "Jon"},
None,
None,
None,
None,
{"kind": "character", "image": "img7", "name": "Mara"},
None,
None,
]
text, images, dropped = self.module.resolve_tagged_refs(
text, references, dropped = self.module.resolve_tagged_refs(
"Use <Picture 7>, skip <Picture 4>, keep <Picture 2>.",
refs,
)
self.assertEqual(text, "Use <Picture 2>, skip, keep <Picture 1>.")
self.assertEqual(images, ["img2", "img7"])
self.assertEqual(
[self.module._reference_image(ref) for ref in references],
["img2", "img7"],
)
self.assertEqual(dropped, [4])
def test_shot_references_uses_all_connected_sparse_slots(self):
refs = [None, "img2", None, "img4", None, None, "img7", None, None]
refs = [
None,
{"kind": "character", "image": "img2"},
None,
{"kind": "character", "image": "img4"},
None,
None,
{"kind": "location", "image": "img7"},
None,
None,
]
self.assertEqual(
self.module.shot_references(refs, "auto ref2v", 0, None),
["img2", "img4", "img7"],
)
self.assertEqual(
self.module.shot_references(refs, "first shot", 0, None),
["img2", "img4", "img7"],
)
self.assertEqual(
self.module.shot_references(refs, "every shot", 3, None),
["img2", "img4", "img7"],
)
for mode, shot_index in (("auto ref2v", 0), ("first shot", 0), ("every shot", 3)):
self.assertEqual(
[self.module._reference_image(ref) for ref in self.module.shot_references(refs, mode, shot_index, None)],
["img2", "img4", "img7"],
)
def test_input_types_expose_nine_ref_slots(self):
optional = self.module.H3LongVideos.INPUT_TYPES()["optional"]
for index in range(1, 10):
self.assertIn(f"ref_image_{index}", optional)
self.assertIn(f"ref_{index}", optional)
self.assertIn("plan", optional)
self.assertIn("plan_scene_index", optional)
@@ -215,18 +244,64 @@ class DumasH3LongVideosHelperTests(unittest.TestCase):
self.assertEqual(len(refs), 9)
self.assertIsNone(refs[0])
self.assertIs(refs[1], image2)
self.assertIs(refs[6], image7)
self.assertIs(self.module._reference_image(refs[1]), image2)
self.assertIs(self.module._reference_image(refs[6]), image7)
def test_merge_ref_slots_prefers_direct_refs_over_plan_refs(self):
merged = self.module._merge_ref_slots(
(None, "direct2", None, None, "direct5", None, None, None, None),
("plan1", "plan2", "plan3", None, "plan5", None, "plan7", None, None),
(
None,
{"kind": "character", "image": "direct2"},
None,
None,
{"kind": "character", "image": "direct5"},
None,
None,
None,
None,
),
(
{"kind": "location", "image": "plan1"},
{"kind": "location", "image": "plan2"},
{"kind": "location", "image": "plan3"},
None,
{"kind": "location", "image": "plan5"},
None,
{"kind": "location", "image": "plan7"},
None,
None,
),
)
self.assertEqual(
merged,
("plan1", "direct2", "plan3", None, "direct5", None, "plan7", None, None),
[self.module._reference_image(ref) if ref is not None else None for ref in merged],
["plan1", "direct2", "plan3", None, "direct5", None, "plan7", None, None],
)
def test_reference_context_matches_character_names_and_location_tags(self):
refs = [
{"kind": "character", "image": "img1", "name": "Mara", "description": "silver hair", "wardrobe": "red jacket"},
{"kind": "location", "image": "img2", "name": "Hangar", "description": "wet concrete floor"},
]
context = self.module._reference_context_for_text(
"[Generation 1] Mara crosses the room toward <Picture 2>.",
refs,
)
self.assertIn("Persistent appearance for Mara: silver hair.", context)
self.assertIn("Persistent wardrobe/style for Mara: red jacket.", context)
self.assertIn("Location context for Hangar: wet concrete floor.", context)
def test_reference_character_memory_uses_character_wardrobe_only(self):
refs = [
{"kind": "character", "image": "img1", "name": "Mara", "wardrobe": "red jacket, black boots"},
{"kind": "location", "image": "img2", "name": "Hangar", "description": "wet concrete floor", "wardrobe": "should be ignored"},
]
self.assertEqual(
self.module._reference_character_memory(refs),
"Mara = red jacket, black boots",
)
def test_ref_mode_defaults_are_ref2v_biased(self):