200 lines
9.5 KiB
Python
200 lines
9.5 KiB
Python
#!/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__)
|