| """Agent-trace export + redaction (server/trace.py) and the UI download handler."""
|
| import json
|
|
|
| from server import events as bus
|
| from server import trace
|
| from ui.blocks import _on_analyze, _on_download_trace
|
|
|
|
|
| def _drive_a_run():
|
|
|
| list(_on_analyze("Mom: dinner Sunday 6pm", None, None))
|
|
|
|
|
| def test_export_run_shape_after_analyze():
|
| _drive_a_run()
|
| t = trace.export_run()
|
| assert t["schema"] == "imessage-cal-trace"
|
| assert t["version"] == 1
|
| assert t["run_id"]
|
| assert t["steps"], "expected at least one step from the run"
|
| assert t["summary"]["events"] >= 1
|
| allowed = {
|
| "stage", "level", "ts", "latency_ms", "events",
|
| "conflicts", "images", "tokens", "message",
|
| }
|
| for step in t["steps"]:
|
| assert set(step).issubset(allowed), f"unexpected keys: {set(step) - allowed}"
|
|
|
|
|
| def test_redaction_strips_chat_names():
|
| with bus.run_scope("analyze"):
|
| bus.emit("ingest", "2 msg(s) from 3rd grade chat", images=0)
|
| bus.emit("decision", "1 event(s) detected", events=1)
|
| rid = trace.export_run()["run_id"]
|
|
|
| redacted = trace.export_run(run_id=rid, redact=True)
|
| assert all("3rd grade chat" not in s["message"] for s in redacted["steps"])
|
| assert redacted["redacted"] is True
|
|
|
| full = trace.export_run(run_id=rid, redact=False)
|
| assert any("3rd grade chat" in s["message"] for s in full["steps"])
|
|
|
|
|
| def test_empty_envelope_when_no_run():
|
|
|
| t = trace.export_run(run_id="nonexistent")
|
| assert t["steps"] == []
|
| assert t["summary"]["events"] == 0
|
|
|
|
|
| def test_write_trace_roundtrips(tmp_path):
|
| _drive_a_run()
|
| t = trace.export_run()
|
| path = trace.write_trace(t, path=str(tmp_path / "t.json"))
|
| with open(path, encoding="utf-8") as f:
|
| assert json.load(f) == t
|
|
|
|
|
| def test_download_handler_paths():
|
| _drive_a_run()
|
| path, msg = _on_download_trace(True)
|
| assert path and "step" in msg
|
|
|
| bus._BUF.clear()
|
| none_path, none_msg = _on_download_trace(True)
|
| assert none_path is None and "No agent run" in none_msg
|
|
|