refactor(tree): subtitle 迁入 L3Card/L2Card + 建树管线修正
- L3Card/L2Card 新增 subtitle: str 字段(L1Card 不加) - L3Node 移除 subtitle 字段(数据迁入 Card) - assign_subtitles_voronoi 改写 Card.subtitle + L2 聚合 - _collect_card_strings 增加 skip_fields 排除 subtitle - _node_full_text/_node_anchored_text 保持 字幕:/[sN] 语义 - get_subtitle 读 Card.subtitle(L2/L3) - verify.py/synthesizer.py: l3.subtitle → l3.card.subtitle - 迁移脚本 tools/migrate_subtitle_to_card.py(幂等,300 棵树已迁移) - 9→6 个测试文件适配(3 个无需改动) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -97,10 +97,10 @@ class TestTreeModuleE2E:
|
||||
SRTEntry(start=5.0, end=7.0, text="The crowd goes wild!"),
|
||||
]
|
||||
assign_subtitles_voronoi(index, srt_entries)
|
||||
assert l3_0.subtitle is not None
|
||||
assert "sprints" in l3_0.subtitle
|
||||
assert l3_1.subtitle is not None
|
||||
assert "crowd" in l3_1.subtitle
|
||||
assert l3_0.card.subtitle != ""
|
||||
assert "sprints" in l3_0.card.subtitle
|
||||
assert l3_1.card.subtitle != ""
|
||||
assert "crowd" in l3_1.card.subtitle
|
||||
|
||||
# Step 3: TreeEnvironment 查询
|
||||
env = TreeEnvironment(index)
|
||||
@@ -139,8 +139,8 @@ class TestTreeModuleE2E:
|
||||
|
||||
assert len(loaded.roots) == 1
|
||||
assert loaded.roots[0].card.scene_summary == "百米短跑决赛"
|
||||
assert loaded.roots[0].children[0].children[0].subtitle is not None
|
||||
assert "sprints" in loaded.roots[0].children[0].children[0].subtitle
|
||||
assert loaded.roots[0].children[0].children[0].card.subtitle != ""
|
||||
assert "sprints" in loaded.roots[0].children[0].children[0].card.subtitle
|
||||
# verify 的修改也被保留
|
||||
assert "幻觉实体XYZ" not in loaded.roots[0].children[0].card.entities
|
||||
|
||||
|
||||
@@ -111,10 +111,10 @@ def _make_test_tree() -> TreeIndex:
|
||||
visible_text=[],
|
||||
spatial_layout="center",
|
||||
visual_attributes={},
|
||||
subtitle="test subtitle text",
|
||||
),
|
||||
timestamp=10.0,
|
||||
frame_path="frames/L1_000_L2_000_L3_000.jpg",
|
||||
subtitle="test subtitle text",
|
||||
)
|
||||
l2 = L2Node(
|
||||
id="vid_L1_000_L2_000",
|
||||
|
||||
@@ -112,7 +112,11 @@ class TestVoronoiAssign:
|
||||
entries = [SRTEntry(1.0, 3.0, "hello"), SRTEntry(5.0, 7.0, "world")]
|
||||
assign_subtitles_voronoi(index, entries)
|
||||
|
||||
assert l3_0.subtitle is not None
|
||||
assert "hello" in l3_0.subtitle
|
||||
assert l3_1.subtitle is not None
|
||||
assert "world" in l3_1.subtitle
|
||||
assert l3_0.card.subtitle != ""
|
||||
assert "hello" in l3_0.card.subtitle
|
||||
assert l3_1.card.subtitle != ""
|
||||
assert "world" in l3_1.card.subtitle
|
||||
# L2 字幕应聚合 L3 子节点字幕
|
||||
assert l2.card.subtitle != ""
|
||||
assert "hello" in l2.card.subtitle
|
||||
assert "world" in l2.card.subtitle
|
||||
|
||||
@@ -31,10 +31,10 @@ def _make_test_index() -> TreeIndex:
|
||||
["Nike"],
|
||||
"居中",
|
||||
{"lighting": "明亮"},
|
||||
subtitle="he is running",
|
||||
),
|
||||
timestamp=1.0,
|
||||
frame_path="frames/L1_000_L2_000_L3_000.jpg",
|
||||
subtitle="he is running",
|
||||
)
|
||||
l3_1 = L3Node(
|
||||
id="vid_L1_000_L2_000_L3_001",
|
||||
|
||||
@@ -130,9 +130,9 @@ class TestNodes:
|
||||
node = _make_l3()
|
||||
assert node.embedding is None
|
||||
|
||||
def test_l3_subtitle_default_none(self):
|
||||
def test_l3_card_subtitle_default_empty(self):
|
||||
node = _make_l3()
|
||||
assert node.subtitle is None
|
||||
assert node.card.subtitle == ""
|
||||
|
||||
|
||||
class TestTreeIndex:
|
||||
|
||||
@@ -55,9 +55,9 @@ class TestVerifyTree:
|
||||
visible_text=["Nike", "2024"],
|
||||
spatial_layout="居中",
|
||||
visual_attributes={},
|
||||
subtitle="the athlete is running fast",
|
||||
),
|
||||
timestamp=1.0,
|
||||
subtitle="the athlete is running fast",
|
||||
)
|
||||
l3_1 = L3Node(
|
||||
id="l1_0_l2_0_l3_1",
|
||||
|
||||
Reference in New Issue
Block a user