"""动作词镜像(prompts.mirror_action):纯 CPU。""" import json import os import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from actionrope.prompts import ACTIONS, MIRROR_ACTION, mirror_action, split_prompt, strip_action # noqa: E402 ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) def test_mirror_is_involution_and_flips_both_axes(): assert [MIRROR_ACTION[MIRROR_ACTION[i]] for i in range(9)] == list(range(9)) assert ACTIONS[MIRROR_ACTION[ACTIONS.index("moving right")]] == "moving left" assert ACTIONS[MIRROR_ACTION[ACTIONS.index("moving up")]] == "moving down" assert ACTIONS[MIRROR_ACTION[ACTIONS.index("moving up-left")]] == "moving down-right" assert MIRROR_ACTION[0] == 0 def test_mirror_keeps_scene_and_trigger(): p = "In a 2.5D top down view, in a high rocky mountain pass, the player is moving right." q = mirror_action(p) assert q == "In a 2.5D top down view, in a high rocky mountain pass, the player is moving left." assert strip_action(q) == strip_action(p) t = ("In a 2.5D top down view, in a pale tidal flat strewn with wreckage burning away into " "a warm farmland hamlet, the player is moving up.") assert split_prompt(mirror_action(t))[0] == split_prompt(t)[0] assert mirror_action(t).endswith("the player is moving down.") bare = "In a 2.5D top down view, the player is moving down-left." assert mirror_action(bare) == "In a 2.5D top down view, the player is moving up-right." assert mirror_action(mirror_action(p)) == p def test_mirrored_prompts_exist_in_mirror_table(): """翻完的串必须都在 text_table_eybx_mirror.pt 里(原 eybx 表缺 530 条镜像转场串,所以要建它)。""" import torch path = os.path.join(ROOT, "data/latent/text_table_eybx_mirror.pt") if not os.path.exists(path): import pytest pytest.skip("没有 text_table_eybx_mirror.pt,先跑 python -m actionrope.build_mirror_table") keys = set(torch.load(path, map_location="cpu", weights_only=False, mmap=True).keys()) need = set() for f in ["20260821_190601_787.jsonl", "20260823_201942_753.jsonl", "transition.jsonl"]: with open(os.path.join(ROOT, "data/meta", f), encoding="utf-8") as fh: for line in fh: r = json.loads(line) need.update(mirror_action(p) for p in r["prompts"]) need.update(mirror_action(p) for p in r.get("prompts_bossdrop", [])) assert need <= keys