aps-agent/scripts/_e2e_m2.py

89 lines
3.2 KiB
Python
Raw Normal View History

2026-07-21 11:05:57 +08:00
"""临时 E2E:对比 → 采用 → 存档 → 回滚。跑完可删。"""
from __future__ import annotations
import json
import sys
import urllib.request
# Windows 控制台避免 ✅ 等字符触发 GBK 编码错误
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
def chat(text: str, sid: str | None = None) -> list[dict]:
body = json.dumps({"text": text, "sessionId": sid}).encode()
req = urllib.request.Request(
"http://localhost:8000/api/chat",
data=body,
headers={"Content-Type": "application/json"},
)
events: list[dict] = []
with urllib.request.urlopen(req, timeout=60) as resp:
buf = ""
for chunk in resp:
buf += chunk.decode()
while "\n\n" in buf:
frame, buf = buf.split("\n\n", 1)
if frame.startswith("data: "):
events.append(json.loads(frame[6:]))
return events
def get(url: str) -> dict:
with urllib.request.urlopen(url, timeout=30) as r:
return json.loads(r.read())
def post(url: str, data: dict) -> dict:
body = json.dumps(data).encode()
req = urllib.request.Request(url, data=body, headers={"Content-Type": "application/json"})
with urllib.request.urlopen(req, timeout=60) as r:
return json.loads(r.read())
def main() -> None:
# 1) compare
ev = chat("对比几种策略", "e2e-m2")
blocks = [e for e in ev if e.get("type") == "block"]
assert any(b["block"]["type"] == "scenario-cards" for b in blocks), blocks
cards = next(b["block"]["props"]["cards"] for b in blocks if b["block"]["type"] == "scenario-cards")
print("compare OK", len(cards), "cards:", [c["label"] for c in cards])
tl0 = get("http://localhost:8000/api/timeline")
v0 = len(tl0["versions"])
# 2) apply best
best = min(cards, key=lambda c: (c["kpi"]["totalTardiness"], c["kpi"]["conflictCount"]))
r = post(
"http://localhost:8000/api/actions/scenario/apply",
{"sessionId": "e2e-m2", "strategy": best["strategy"], "engine": best["engine"]},
)
print("apply OK", (r.get("message") or "")[:80])
tl1 = get("http://localhost:8000/api/timeline")
assert len(tl1["versions"]) >= v0, (v0, len(tl1["versions"]))
print("versions", v0, "->", len(tl1["versions"]))
# 3) checkpoint create
ev2 = chat("存个档 叫 e2e基线", "e2e-m2")
text = "".join(e.get("text", "") for e in ev2 if e.get("type") == "token")
print("checkpoint create:", text[:100])
tl2 = get("http://localhost:8000/api/timeline")
assert tl2["checkpoints"], tl2
pair = tl2["checkpoints"][-1]
print("pair", pair["pairId"], pair["label"])
# 4) rollback stage + approve
ev3 = chat(f"回滚到检查点 {pair['pairId']}", "e2e-m2")
blocks3 = [e for e in ev3 if e.get("type") == "block"]
assert any(b["block"]["type"] == "confirm-card" for b in blocks3), blocks3
cid = next(b["block"]["props"]["confirmId"] for b in blocks3 if b["block"]["type"] == "confirm-card")
print("rollback staged", cid)
r2 = post(
"http://localhost:8000/api/actions/confirm",
{"sessionId": "e2e-m2", "confirmId": cid, "approve": True},
)
print("rollback OK", (r2.get("message") or "")[:100])
print("E2E M2 PASS")
if __name__ == "__main__":
main()