"""Aggregate metrics over feedback labels. Default aggregates exclude source_text, images, raw sheet content, and reviewer free-text comments; include_text=True is the only path that embeds the raw labels. """ from collections import Counter from typing import Dict, List def aggregate_labels(labels: List[dict], include_text: bool = False) -> Dict: decisions = Counter(label.get("decision") or "unknown" for label in labels) reasons = Counter(label.get("reason_code") or "none" for label in labels if label.get("decision") == "reject") summary = { "total": len(labels), "decisions": dict(decisions), "reject_reasons": dict(reasons), } for label in labels: decision = label.get("decision") or "unknown" summary[decision] = summary.get(decision, 0) + 1 if include_text: summary["labels"] = labels return summary