feat(reports): add overall scores to strategy cards and average row in technical report
Why: - Users need to see each strategy's overall score at a glance in the report - Technical report should show average metrics across all strategies Changes: - Each strategy card now shows its overall score below the metric bars - Technical report aggregate table includes an AVERAGE row across all strategies Impact: - Managerial report: strategy cards now show overall score - Technical report: aggregate table has a new AVERAGE row at the bottom
This commit is contained in:
@@ -633,6 +633,9 @@ def _build_strategy_cards(rankings: list, aggregate: dict) -> str:
|
||||
{_metric_bar("Similarity", m.get("avg_answer_similarity", 0), "accent")}
|
||||
{_metric_bar("Faithfulness", m.get("avg_faithfulness", 0), "violet")}
|
||||
{_metric_bar("No Hallucination", (1 - m.get("hallucination_rate", 0)) * 10, "teal" if m.get("hallucination_rate", 0) <= 0.1 else "rose")}
|
||||
<div style="margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border); font-family: {FONT_DATA}; font-size: 13px; color: var(--text-muted);">
|
||||
Overall: <span style="color: var(--accent); font-weight: 600;">{overall:.2f}</span>
|
||||
</div>
|
||||
</div>"""
|
||||
|
||||
return cards
|
||||
@@ -690,7 +693,7 @@ def _generate_decision_insights(rankings: list, aggregate: dict) -> str:
|
||||
|
||||
|
||||
def _build_technical_aggregate_rows(rankings: list, aggregate: dict) -> str:
|
||||
"""Build technical aggregate table rows."""
|
||||
"""Build technical aggregate table rows with an average row at the end."""
|
||||
rows = ""
|
||||
for rank, (strategy, overall) in enumerate(rankings, 1):
|
||||
m = aggregate.get(strategy, {})
|
||||
@@ -705,6 +708,28 @@ def _build_technical_aggregate_rows(rankings: list, aggregate: dict) -> str:
|
||||
<td>{m.get('failed_questions', 0)}</td>
|
||||
<td><strong style="font-family: {FONT_DATA};">{overall:.2f}</strong></td>
|
||||
</tr>"""
|
||||
|
||||
# Average row across all strategies
|
||||
n = len(rankings)
|
||||
if n > 0:
|
||||
avg_ctx = sum(aggregate.get(s, {}).get('avg_context_relevance', 0) for s, _ in rankings) / n
|
||||
avg_sim = sum(aggregate.get(s, {}).get('avg_answer_similarity', 0) for s, _ in rankings) / n
|
||||
avg_faith = sum(aggregate.get(s, {}).get('avg_faithfulness', 0) for s, _ in rankings) / n
|
||||
avg_hall = sum(aggregate.get(s, {}).get('hallucination_rate', 0) for s, _ in rankings) / n
|
||||
avg_total = sum(aggregate.get(s, {}).get('total_questions', 0) for s, _ in rankings) / n
|
||||
avg_failed = sum(aggregate.get(s, {}).get('failed_questions', 0) for s, _ in rankings) / n
|
||||
avg_overall = sum(overall for _, overall in rankings) / n
|
||||
rows += f"""
|
||||
<tr style="background: var(--surface); border-top: 2px solid var(--border);">
|
||||
<td><strong style="color: var(--accent);">AVERAGE</strong></td>
|
||||
<td>{_pill(avg_ctx)}</td>
|
||||
<td>{_pill(avg_sim)}</td>
|
||||
<td>{_pill(avg_faith)}</td>
|
||||
<td>{_hall_pill(avg_hall)}</td>
|
||||
<td>{avg_total:.0f}</td>
|
||||
<td>{avg_failed:.0f}</td>
|
||||
<td><strong style="font-family: {FONT_DATA}; color: var(--accent);">{avg_overall:.2f}</strong></td>
|
||||
</tr>"""
|
||||
return rows
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user