diff --git a/eval/tenant_panel/bank.py b/eval/tenant_panel/bank.py index eed8d8fc..e8ccb25e 100644 --- a/eval/tenant_panel/bank.py +++ b/eval/tenant_panel/bank.py @@ -107,10 +107,17 @@ STOP_WHOLE = {"自己", "已经", "现在", "眼中", "心中", "一个", "什 _MATERIAL = None +# ⚠ КАССА СБОРКИ. Для zh — прежняя «Ф0» эксп-22, побайтно как было. Для новых пар банк есть +# покупка ФАЗЫ Д (пре-рег: «ФД-B — Д3 en→ru: банк, контам, армы, пол»), и биллить её в Ф0 значит +# сделать трату невидимой потолку фазы — тот же класс, что увёл 7 клеток пробы в чужой каталог. +_PHASE = "Ф0" +_TAGPFX = "tp0" + + def _term_tag() -> str: """Тег покупки терминолога. Несёт пару, иначе кэш `purchase` смешивает пары.""" P = pair() - return "tp0-bank-terminolog" if P.key == "zh-ru" else f"tp0-bank-terminolog-{P.key}" + return "tp0-bank-terminolog" if P.key == "zh-ru" else f"{_TAGPFX}-bank-terminolog" def source_text() -> str: @@ -189,7 +196,7 @@ def cmd_ask() -> None: brief = getattr(PR, pair().brief_key) msgs = [{"role": "system", "content": PR.render(core, brief, "", "")}, {"role": "user", "content": PR.render(user, brief, _payload(), "")}] - led = MONEY.Guarded("Ф0", default_expect=0.02) + led = MONEY.Guarded(_PHASE, default_expect=0.02) base, env, *_ = CANDIDATES[TERM_MODEL] cl = OpenAI(api_key=os.environ[env], base_url=base, timeout=600) kw = dict(model=TERM_MODEL, messages=msgs, max_completion_tokens=4000, @@ -242,7 +249,7 @@ DROP = {"瞬间", "声音", "仿佛", "庭院"} def cmd_canon() -> None: - f = OUT / f"{_term_tag()}.json" + f = MONEY.OUT / f"{_term_tag()}.json" if not f.exists(): print("нет ответа терминолога — сначала --ask") return @@ -344,8 +351,65 @@ def selfcheck() -> int: return bad +def _select_pair(argv: list[str]) -> None: + """`--pair=en-ru` переводит сборку на пару ЦЕЛИКОМ: бриф, тег покупки, банк-файл, материал. + + Материал берётся из ПРОЗЫ книги пары, а не из отобранных единиц: терминолог по замыслу роли + «видит всю книгу сразу», и канон, собранный по 16 отрывкам, не был бы каноном книги. Термин, + не встреченный в единице, покрытию не мешает — `coverage` пропускает нулевой знаменатель. + """ + key = next((a.split("=", 1)[1] for a in argv if a.startswith("--pair=")), "zh-ru") + if key == "zh-ru": + return + import importlib.util # noqa: PLC0415 + sp = importlib.util.spec_from_file_location("para", REPO / "eval" / "dovodka" / "para.py") + para = importlib.util.module_from_spec(sp) + sys.modules["para"] = para + sp.loader.exec_module(para) + if key == "en-ru": + sp2 = importlib.util.spec_from_file_location( + "pair_en_b", REPO / "eval" / "role_topology" / "pair_en.py") + PE = importlib.util.module_from_spec(sp2) + sys.modules["pair_en_b"] = PE + sp2.loader.exec_module(PE) + mat = lambda: "\n".join(c for c in PE.chunks() if PE.is_prose(c)) # noqa: E731 + elif key == "ja-ru": + sp2 = importlib.util.spec_from_file_location( + "mat_ja_b", REPO / "eval" / "dovodka" / "material_ja.py") + MJ = importlib.util.module_from_spec(sp2) + sys.modules["mat_ja_b"] = MJ + sp2.loader.exec_module(MJ) + mat = lambda: MJ.text() # noqa: E731 + else: + raise SystemExit(f"⛔ пара {key} харнессу неизвестна") + # Касса фазы Д. `money_d.configure` перенастраивает ТОТ ЖЕ модуль `money`, который bank.py + # держит как MONEY, поэтому после загрузки OUT/TAGS/CEILINGS становятся фазовыми. Проверяем + # ассертом, а не верим: молчаливое расхождение здесь стоит невидимых денег. + global _PHASE, _TAGPFX + spm = importlib.util.spec_from_file_location( + "money_d_bank", REPO / "eval" / "dovodka" / "money_d.py") + MD = importlib.util.module_from_spec(spm) + sys.modules["money_d_bank"] = MD + spm.loader.exec_module(MD) + _PHASE = {"en-ru": "ФД-B", "ja-ru": "ФД-C"}[key] + _TAGPFX = {"en-ru": "dv-b", "ja-ru": "dv-c"}[key] + # ⚠ `money_d` настраивает СВОЙ экземпляр кассы (`M22`), а не тот `money`, который держит этот + # модуль, — ассерт ниже это и поймал. Настраиваем наш экземпляр явно, тем же приёмом, каким + # касса перенастраивается под любой пак, и лишь потом проверяем. + import roster as _ROSTER # noqa: PLC0415 + MONEY.configure(ZONE=REPO / "eval" / "dovodka", OUT=MD.OUT, TAGS=MD.TAGS, + CEILINGS=MD.CEILINGS, PACK_CEILING=MD.PACK_CEILING, + GLOB_ALL="dv-*.json", ROSTER=_ROSTER) + if MONEY.OUT != MD.OUT: + raise SystemExit(f"⛔ касса банка {MONEY.OUT} против фазы {MD.OUT} — трата уедет мимо " + "потолка фазы, СТОП") + configure(para.PAIRS[key], material=mat) + print(f"пара: {key} · банк → {para.PAIRS[key].bank_file} · терминолог {TERMINOLOGIST}") + + if __name__ == "__main__": - a = sys.argv[1:] or ["--mine"] + a = [x for x in sys.argv[1:] if not x.startswith("--pair=")] or ["--mine"] + _select_pair(sys.argv[1:]) fn = {"--mine": cmd_mine, "--ask": cmd_ask, "--canon": cmd_canon, "--show": cmd_show, "--selfcheck": lambda: sys.exit(1 if selfcheck() else 0)}.get(a[0]) fn() if fn else print(__doc__)