from __future__ import annotations import json from pathlib import Path from typing import Any def _provider_table_rows(scored: dict[str, Any]) -> list[tuple[str, dict[str, Any]]]: return sorted( scored.get("providers", {}).items(), key=lambda item: item[1].get("accuracy", 0.0), reverse=True, ) def build_markdown_report(run_id: str, scored: dict[str, Any], pairwise: list[dict[str, Any]]) -> str: lines: list[str] = [] lines.append(f"# Evaluation Report: {run_id}") lines.append("") lines.append(f"- Status: `{scored.get('status', 'unknown')}`") lines.append(f"- Total evaluated rows: `{scored.get('total_rows', 0)}`") lines.append("") lines.append("## Leaderboard") lines.append("") lines.append("| System | Attempted | Correct | Accuracy | CI95 | Avg Latency (ms) | Errors |") lines.append("|---|---:|---:|---:|---:|---:|---:|") for provider, metrics in _provider_table_rows(scored): ci = metrics.get("accuracy_ci95", {"low": 0.0, "high": 0.0}) lines.append( "| " f"{provider} | {metrics.get('attempted', 0)} | {metrics.get('correct', 0)} | " f"{metrics.get('accuracy', 0.0):.3f} | " f"[{ci.get('low', 0.0):.3f}, {ci.get('high', 0.0):.3f}] | " f"{metrics.get('avg_latency_ms', 0.0):.1f} | {metrics.get('errors', 0)} |" ) lines.append("") lines.append("## Pairwise Significance (Matched Samples)") lines.append("") if not pairwise: lines.append("No provider pairs available.") else: lines.append("| System A | System B | Wins A | Wins B | Ties | p-value |") lines.append("|---|---|---:|---:|---:|---:|") for row in pairwise: lines.append( f"| {row['provider_a']} | {row['provider_b']} | {row['wins_a']} | " f"{row['wins_b']} | {row['ties']} | {row['p_value_two_sided']:.4f} |" ) lines.append("") lines.append("## Category Breakdown") lines.append("") for provider, metrics in _provider_table_rows(scored): lines.append(f"### {provider}") lines.append("") lines.append("| Category | Attempted | Correct | Accuracy |") lines.append("|---|---:|---:|---:|") categories = sorted(metrics.get("categories", {}).items(), key=lambda x: x[0]) for cat_name, cat in categories: lines.append( f"| {cat_name} | {cat.get('attempted', 0)} | {cat.get('correct', 0)} | " f"{cat.get('accuracy', 0.0):.3f} |" ) lines.append("") return "\n".join(lines).strip() + "\n" def build_html_report(run_id: str, scored: dict[str, Any], pairwise: list[dict[str, Any]]) -> str: rows = _provider_table_rows(scored) provider_rows = [] for provider, metrics in rows: ci = metrics.get("accuracy_ci95", {"low": 0.0, "high": 0.0}) provider_rows.append( "
Status: {scored.get('status', 'unknown')}
"
f"Total evaluated rows: {scored.get('total_rows', 0)}
| System | Attempted | Correct | Accuracy | " "CI95 | Avg Latency (ms) | Errors | " "
|---|
| System A | System B | Wins A | Wins B | Ties | p-value | " "
|---|---|---|---|---|---|
| No pairs available | |||||