aps-agent/scripts/_e2e_m2.py

89 lines
3.2 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.

"""临时 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()