| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- from __future__ import annotations
- import argparse
- import json
- from pathlib import Path
- from statistics import median
- from typing import Any
- def _bucket_key(member: dict[str, Any]) -> tuple[str, str, str]:
- return (
- str(member.get("registration_proxy_region") or "unknown").strip() or "unknown",
- str(member.get("registration_post_create_gate") or "none").strip() or "none",
- "consistent" if bool(member.get("fingerprint_consistent")) else "mismatch_or_unknown",
- )
- def _median_survival_seconds(members: list[dict[str, Any]]) -> float | None:
- values = [
- int(member.get("survival_seconds"))
- for member in members
- if member.get("survival_seconds") is not None
- ]
- if not values:
- return None
- return float(median(values))
- def build_report(payload: dict[str, Any]) -> dict[str, Any]:
- members = [item for item in payload.get("members") or [] if isinstance(item, dict)]
- buckets: dict[tuple[str, str, str], list[dict[str, Any]]] = {}
- for member in members:
- buckets.setdefault(_bucket_key(member), []).append(member)
- grouped: list[dict[str, Any]] = []
- for (proxy_region, post_create_gate, fingerprint_consistency), group_members in sorted(buckets.items()):
- invalid_members = [item for item in group_members if str(item.get("first_invalid_at") or "").strip()]
- grouped.append(
- {
- "registration_proxy_region": proxy_region,
- "registration_post_create_gate": post_create_gate,
- "fingerprint_consistency": fingerprint_consistency,
- "tracked": len(group_members),
- "invalid": len(invalid_members),
- "median_survival_seconds": _median_survival_seconds(invalid_members),
- }
- )
- return {
- "updated_at": payload.get("updated_at"),
- "probe_mode": payload.get("probe_mode"),
- "probe_fingerprint_profile": payload.get("probe_fingerprint_profile"),
- "summary": payload.get("summary") or {},
- "groups": grouped,
- }
- def main() -> int:
- parser = argparse.ArgumentParser(description="Summarize survival experiment buckets from tracker state")
- parser.add_argument(
- "--state-file",
- default="/home/sophomores/zhuce6/state/responses_survival_tracker.json",
- help="responses survival state file",
- )
- args = parser.parse_args()
- state_file = Path(args.state_file).expanduser().resolve()
- payload = json.loads(state_file.read_text(encoding="utf-8"))
- print(json.dumps(build_report(payload), ensure_ascii=False, indent=2))
- return 0
- if __name__ == "__main__":
- raise SystemExit(main())
|