mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 01:01:59 +00:00
78252fdfa2
typesEval.ts 的联合类型(状态、发起方式、题目种类、结论、作答路径、期望种类、期望答案来源、升版处置、试算结论、各期望的结论、 转移、归因、目录视图、E1/E3 档位)和 termsEval.ts 里对应的叫法表,直接读文件和 app/eval、app/core/job_runtime、api/evals 的常量比: 服务端加了一种(比如作答路径「被驳回」)前端没跟上,界面会写出英文原值;同 test_frontend_type_unions.py 的写法,另开一个文件 免得和别的包改同一个文件。
96 lines
4.4 KiB
Python
96 lines
4.4 KiB
Python
"""评测页的前端约定(frontend/src/typesEval.ts)和文案(lib/termsEval.ts 的 EVAL_TEXT)里的取值,和服务端的常量逐个对上。
|
||
|
||
评测页上的结论、作答路径、转移、归因、目录视图、状态都是服务端给的取值,前端照着写叫法(界面层不放逻辑,叫法在 termsEval)。
|
||
服务端加了一种(比如作答路径「被驳回」),前端的联合类型和叫法表没跟上,界面就写出英文原值;前端多写了一种,就在等一个
|
||
永远不会来的值。这里直接读两份 .ts 文件比(同 test_frontend_type_unions.py 的写法),改了一边没改另一边就过不去。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import re
|
||
from pathlib import Path
|
||
|
||
ROOT = Path(__file__).resolve().parents[2]
|
||
TYPES_EVAL = ROOT / "frontend" / "src" / "typesEval.ts"
|
||
TERMS_EVAL = ROOT / "frontend" / "src" / "lib" / "termsEval.ts"
|
||
|
||
_COMMENT = re.compile(r"/\*.*?\*/|//[^\n]*", re.S)
|
||
|
||
|
||
def _source(path: Path) -> str:
|
||
return _COMMENT.sub("", path.read_text(encoding="utf-8"))
|
||
|
||
|
||
def _union(name: str) -> list[str]:
|
||
text = _source(TYPES_EVAL)
|
||
found = re.search(rf"export type {name} =(.*?)(?=\nexport |\n\n|\Z)", text, re.S)
|
||
assert found is not None, f"typesEval.ts 里没有 export type {name}"
|
||
return re.findall(r"'([^']+)'", found.group(1))
|
||
|
||
|
||
def _labels(path: str) -> list[str]:
|
||
"""EVAL_TEXT 里某一张叫法表(a.b 这样的路径)的键,按写的顺序。只认一行写完、或几行写完的对象字面量。"""
|
||
text = _source(TERMS_EVAL)
|
||
*parents, leaf = path.split(".")
|
||
start = 0
|
||
for part in parents:
|
||
hit = re.search(rf"\n\s*{part}: \{{", text[start:])
|
||
assert hit is not None, f"EVAL_TEXT 里没有 {part}"
|
||
start += hit.end()
|
||
hit = re.search(rf"\n\s*{leaf}: \{{(.*?)\}}( as Record<[^>]+>)?,", text[start:], re.S)
|
||
assert hit is not None, f"EVAL_TEXT 里没有 {path}"
|
||
return re.findall(r"(\w+): '", hit.group(1))
|
||
|
||
|
||
def test_statuses_triggers_and_kinds():
|
||
from app.core.job_runtime import ACTIVE, FINISHED
|
||
from app.db.models_eval import CASE_KINDS, RESULT_PATHS, RUN_TRIGGERS, VERDICTS
|
||
|
||
assert _union("EvalStatus") == [*ACTIVE, *FINISHED]
|
||
assert _union("EvalTrigger") == list(RUN_TRIGGERS)
|
||
assert _union("EvalCaseKind") == list(CASE_KINDS)
|
||
assert _union("EvalVerdict") == list(VERDICTS)
|
||
assert _union("EvalPath") == list(RESULT_PATHS)
|
||
assert _labels("status") == [*ACTIVE, *FINISHED]
|
||
assert _labels("trigger") == list(RUN_TRIGGERS)
|
||
assert _labels("verdict") == list(VERDICTS)
|
||
assert _labels("path") == list(RESULT_PATHS)
|
||
|
||
|
||
def test_expectations_gold_and_trial():
|
||
from app.eval.cases import EXPECTATION_KINDS, GOLD_KINDS
|
||
from app.eval.gold import STATUSES, UPGRADE_LABEL
|
||
|
||
assert _union("EvalExpectationKind") == list(EXPECTATION_KINDS)
|
||
assert _labels("expectation.kind") == list(EXPECTATION_KINDS)
|
||
assert _union("EvalGoldKind") == list(GOLD_KINDS)
|
||
assert _labels("gold.kind") == list(GOLD_KINDS)
|
||
assert _union("EvalUpgradePolicy") == list(UPGRADE_LABEL)
|
||
# 试算的结论:服务端的几种,加上作答前后算出来不一样时的 drifted(gold.settle)
|
||
assert set(STATUSES) | {"drifted"} == set(_union("EvalTrialStatus"))
|
||
assert set(_union("EvalTrialStatus")) <= set(_labels("trialStatus"))
|
||
|
||
|
||
def test_scores_compare_and_catalog_modes():
|
||
from app.eval.compare import CAUSES, TRANSITIONS
|
||
from app.eval.score import OUTCOMES, TEXT_OUTCOMES
|
||
from app.eval.variants import CATALOG_MODES
|
||
|
||
assert _union("EvalOutcome") == list(OUTCOMES)
|
||
assert _labels("outcome") == list(OUTCOMES)
|
||
assert _union("EvalTextOutcome") == list(TEXT_OUTCOMES)
|
||
assert _labels("textOutcome") == list(TEXT_OUTCOMES)
|
||
assert _union("EvalTransition") == list(TRANSITIONS)
|
||
assert _labels("compare.transition") == list(TRANSITIONS)
|
||
assert _union("EvalCause") == list(CAUSES)
|
||
assert _labels("compare.cause") == list(CAUSES)
|
||
assert _union("EvalCatalogMode") == list(CATALOG_MODES)
|
||
assert _labels("start.catalogMode") == list(CATALOG_MODES)
|
||
|
||
|
||
def test_signal_bands_follow_the_server():
|
||
from app.api.evals import SIGNAL_CRITERIA
|
||
|
||
assert _union("EvalE1Band") == [c["band"] for c in SIGNAL_CRITERIA["e1"]]
|
||
assert _union("EvalE3Band") == [c["band"] for c in SIGNAL_CRITERIA["e3"]]
|
||
assert set(_labels("signals.band")) == {c["band"] for c in [*SIGNAL_CRITERIA["e1"], *SIGNAL_CRITERIA["e3"]]}
|