#!/usr/bin/env python3 """ФАЗЫ B и C. Платные, идут через кассу пака. ФАЗА B — граница `glm-5`. 16 НОВЫХ единиц (`material.units_new`), на каждой покупается ровно то, что нужно контрасту границы: якорный черновик · боевой редактор `deepseek-v4-pro` (R0) · пограничный `glm-5` (R2). n контраста R0/R2 растёт 16 → 32. ФАЗА C — панель сильного тира. Прошедшие фазу A идут редакторами поверх ТОЙ ЖЕ якорной базы эксп-22 на его 16 единицах. База уже куплена: пере-генерация запрещена — это был бы второй замер той же вещи, а не новый арм. Клетка R0 над этой базой тоже куплена эксп-22 и переиспользуется. ⚠ ПОТОЛОК ФАЗЫ C ПОДНЯТ $1.80 → $1.95 ИЗ ОБЪЯВЛЕННОГО РЕЗЕРВА ПАКА, объявляю здесь до покупок. Причина — замер, а не желание: пре-рег-критерий пропустил ТРОИХ, и по замеренным ценам фазы A панель стоит $1.85. Резерв $0.65 объявлен в плане ровно на такие случаи, пакетный потолок $4.00 (санкция владельца) НЕ двигается, суммарная смета пака $2.78. Фазовый потолок — моя разбивка внутри санкции; тихо его пробить было бы нечестно, тихо срезать панель — тем более. """ from __future__ import annotations import sys from pathlib import Path REPO = Path("/home/ubuntu/projects/textmachine") ZONE = Path(__file__).resolve().parent sys.path.insert(0, str(REPO / "eval" / "tenant_panel")) sys.path.insert(0, str(REPO / "eval" / "role_topology")) def _load(name: str, path: Path): """Чужое — только явной загрузкой (см. `screen._load`).""" import importlib.util # noqa: PLC0415 spec = importlib.util.spec_from_file_location(name, path) mod = importlib.util.module_from_spec(spec) sys.modules[name] = mod spec.loader.exec_module(mod) return mod TP = REPO / "eval" / "tenant_panel" PR = _load("prompts22", TP / "prompts.py") P22 = _load("panel22", TP / "panel.py") MAT = _load("material_et", ZONE / "material.py") SCR = _load("screen_et", ZONE / "screen.py") MONEY = SCR.MONEY ROSTER = SCR.ROSTER ANCHOR = "deepseek-v4-flash" # черновик боевой пары BATTLE = "deepseek-v4-pro" # R0 BORDER = "glm-5" # R2 — пограничный контраст эксп-22 MONEY.M22.configure(CEILINGS={**MONEY.CEILINGS, "ФC": 1.95}) MONEY.CEILINGS["ФC"] = 1.95 def survivors() -> list[str]: """Прошедшие фазу A по ПРЕ-РЕГ-критерию пака, по возрастанию замеренной цены.""" r = SCR.result() ok = [m for m, v in r.items() if v["verdict"] == "прошёл"] return sorted(ok, key=lambda m: r[m]["price_editor"] or 9) # ── ФАЗА B ──────────────────────────────────────────────────────────────────────────────────── def tag_b(kind: str, model: str, uid: str) -> str: return f"et-unit-{kind}-{model}-{uid}" def cmd_b_plan() -> None: us = MAT.units_new() r22 = ROSTER.R22 exp = {ANCHOR: 0.00130, BATTLE: 0.00545, BORDER: 0.01303} # замеры эксп-22, $/ед tot = sum(exp.values()) * len(us) print(f"фаза B: {len(us)} новых единиц × (черновик + {BATTLE} + {BORDER}) = " f"{len(us) * 3} клеток · ожидание ${tot:.3f} · потолок {MONEY.CEILINGS['ФB']:.2f}") _ = r22 if tot > MONEY.CEILINGS["ФB"]: print("⛔ смета выше потолка фазы — СТОП") raise SystemExit(1) def cmd_b_run() -> None: led = MONEY.Guarded("ФB") for u in MAT.units_new(): blk = PR.glossary_block(PR.terms_in(u["source"])) t = tag_b("draft", ANCHOR, u["uid"]) if not (MONEY.OUT / f"{t}.json").exists(): MONEY.purchase(led, t, ANCHOR, SCR.client(ANCHOR), ROSTER.call_kwargs(ANCHOR, PR.translator_msgs(u["source"], blk)), role="draft", uid=u["uid"]) d = draft_b(u["uid"]) if not d.strip(): print(f" {u['uid']}: черновика нет — редактуры пропущены") continue law = PR.law_block(PR.terms_in(u["source"])) for m in (BATTLE, BORDER): te = tag_b("edit", m, u["uid"]) if (MONEY.OUT / f"{te}.json").exists(): continue MONEY.purchase(led, te, m, SCR.client(m), ROSTER.call_kwargs(m, PR.editor_msgs(u["source"], d, law)), role="edit", uid=u["uid"]) MONEY.report() def draft_b(uid: str) -> str: import json # noqa: PLC0415 f = MONEY.OUT / f"{tag_b('draft', ANCHOR, uid)}.json" return (json.loads(f.read_text(encoding="utf-8")).get("content") or "") if f.exists() else "" def text_b(arm: str, uid: str) -> str: import json # noqa: PLC0415 m = {"R0": BATTLE, "R2": BORDER}[arm] f = MONEY.OUT / f"{tag_b('edit', m, uid)}.json" return (json.loads(f.read_text(encoding="utf-8")).get("content") or "") if f.exists() else "" # ── ФАЗА C ──────────────────────────────────────────────────────────────────────────────────── def tag_c(model: str, uid: str) -> str: return f"et-ed-{model}-{uid}" def cmd_c_plan() -> None: ok, us = survivors(), P22.M.units_zh() r = SCR.result() tot = sum((r[m]["price_editor"] or 0) * len(us) for m in ok) print(f"{'арм':6s}{'модель':16s}{'$/ед':>10s}{'×16':>10s}") for i, m in enumerate(ok, start=1): pe = r[m]["price_editor"] or 0 print(f"{'T' + str(i):6s}{m:16s}{pe:10.5f}{pe * len(us):10.3f}") print(f"{'ИТОГО':22s}{'':10s}{tot:10.3f} потолок {MONEY.CEILINGS['ФC']:.2f}") print(f"база R0 ({BATTLE} над якорным черновиком) — уже куплена эксп-22, $0") if tot > MONEY.CEILINGS["ФC"]: print("⛔ смета выше потолка фазы — СТОП") raise SystemExit(1) def cmd_c_run() -> None: led = MONEY.Guarded("ФC") for u in P22.M.units_zh(): base = P22.draft_text(ANCHOR, u["uid"]) if not base.strip(): print(f" {u['uid']}: якорной базы нет — пропуск") continue law = PR.law_block(PR.terms_in(u["source"])) for m in survivors(): t = tag_c(m, u["uid"]) if (MONEY.OUT / f"{t}.json").exists(): continue MONEY.purchase(led, t, m, SCR.client(m), ROSTER.call_kwargs(m, PR.editor_msgs(u["source"], base, law)), role="edit", uid=u["uid"]) MONEY.report() def text_c(arm: str, uid: str) -> str: """Тексты армов Ф C. R0 — клетка эксп-22, переиспользуется без покупки.""" import json # noqa: PLC0415 if arm == "R0": return P22.edit_text(ANCHOR, uid) ok = survivors() m = ok[int(arm[1:]) - 1] f = MONEY.OUT / f"{tag_c(m, uid)}.json" return (json.loads(f.read_text(encoding="utf-8")).get("content") or "") if f.exists() else "" def selfcheck() -> int: bad = 0 ok = survivors() if not ok: print("[ПРОВАЛ] фазу A не прошёл никто — панели нет") bad += 1 us_b, us_c = MAT.units_new(), P22.M.units_zh() if set(u["uid"] for u in us_b) & set(u["uid"] for u in us_c): print("[ПРОВАЛ] единицы фаз B и C пересекаются") bad += 1 tags = [tag_b("draft", ANCHOR, u["uid"]) for u in us_b] + \ [tag_b("edit", m, u["uid"]) for u in us_b for m in (BATTLE, BORDER)] + \ [tag_c(m, u["uid"]) for u in us_c for m in ok] if len(tags) != len(set(tags)): print("[ПРОВАЛ] теги не уникальны") bad += 1 if not all(t.startswith(("et-unit-", "et-ed-")) for t in tags): print("[ПРОВАЛ] тег вне глобов фаз") bad += 1 if sum(MONEY.CEILINGS.values()) > MONEY.PACK_CEILING + 1e-9: print("[ПРОВАЛ] сумма фазовых потолков выше пакетного") bad += 1 print(f"панель: армов {len(ok)} ({ok}) · клеток в плане {len(tags)} · провалов {bad}") return bad if __name__ == "__main__": a = sys.argv[1:] or ["--selfcheck"] fn = {"--b-plan": cmd_b_plan, "--b-run": cmd_b_run, "--c-plan": cmd_c_plan, "--c-run": cmd_c_run, "--selfcheck": lambda: sys.exit(1 if selfcheck() else 0)}.get(a[0]) if fn: fn() else: print(__doc__)