textmachine/eval/editor_tier/panel.py

200 lines
9.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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__)