"""临时 E2E(M3):知识检索→报告生成→偏好个性化。跑完可删。""" from __future__ import annotations import json import sys import urllib.request # Windows 控制台 UTF-8 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 text_of(events: list[dict]) -> str: return "".join(e.get("text", "") for e in events if e.get("type") == "token") def blocks_of(events: list[dict]) -> list[dict]: return [e["block"] for e in events if e.get("type") == "block"] def get(url: str): with urllib.request.urlopen(url, timeout=30) as r: return r.read() def main() -> None: sid = "e2e-m3" # 1) 知识检索:带出处 ev = chat("换线有什么规定", sid) t = text_of(ev) assert "出处" in t and "换线标准SOP" in t, t[:200] assert any(b["type"] == "evidence" for b in blocks_of(ev)), "缺 evidence 块" print("K1 知识检索带出处 OK") # 1b) @知识 直达 ev = chat("@知识:插单审批流程", sid) assert "插单审批流程" in text_of(ev), text_of(ev)[:120] print("K1b @知识 引用 OK") # 2) 试排两版(第二版不点名策略 → 偏好个性化生效) chat("试排一版交期优先", sid) ev = chat("再试排一版", sid) t = text_of(ev) assert "排产完成" in t, t[:200] print("K3 偏好个性化:", "使用偏好" in t or "偏好" in t) # 3) 日报 ev = chat("生成日报", sid) rblocks = [b for b in blocks_of(ev) if b["type"] == "report"] assert rblocks and "排产日报" in rblocks[0]["props"]["title"], blocks_of(ev) print("K2 日报 OK:", rblocks[0]["props"]["title"]) # 4) 版本对比 ev = chat("生成版本对比报告", sid) rblocks = [b for b in blocks_of(ev) if b["type"] == "report"] assert rblocks, text_of(ev)[:200] print("K2 版本对比 OK:", rblocks[0]["props"]["title"]) # 5) 导出端点 md = get("http://localhost:8000/api/reports/daily").decode("utf-8") assert md.startswith("# 排产日报"), md[:60] print("导出端点 OK") # 6) 知识资产清单(报告应已入库) assets = json.loads(get("http://localhost:8000/api/knowledge/assets"))["assets"] kinds = {a["kind"] for a in assets} assert "report" in kinds and "sop" in kinds, kinds print(f"知识库资产 {len(assets)} 条(含 report)") print("E2E M3 PASS") if __name__ == "__main__": main()