import os import json from datetime import datetime from src.gemini_utils import SESSION_TRACKER REPORT_PATH = "report.html" def generate_visual_report(metrics: list) -> str: """Genera un reporte HTML con gráficos y tabla detallada.""" # REPORT_PATH is now relative to current working directory # No need to create directory as it goes to root of project or where script runs timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") # Cálculos básicos total = len(metrics) included = len([m for m in metrics if m['status'] == 'INCLUDED']) filtered = len([m for m in metrics if m['status'] == 'FILTERED']) duplicates = len([m for m in metrics if m['status'] == 'DUPLICATE']) html = f""" Nubenetes Curation Health Dashboard

💎 Nubenetes Curation Dashboard

Run Timestamp: {timestamp}

{total}

Processed

{included}

Included

{filtered}

Filtered

{duplicates}

Duplicates

🧠 AI Intelligence & Infrastructure

🤖 Model Usage

    {''.join([f"
  • {m}: {c} calls
  • " for m, c in SESSION_TRACKER.model_usage.items()]) or "
  • No AI calls recorded
  • "}

🔑 API Key Health

{''.join([f"" for idx, s in SESSION_TRACKER.key_stats.items()])}
KeyTypeUsageFailures
{idx+1}{s['type']}{s['calls']}{s['429s']}/{s['404s']}

📋 Detailed Curation Matrix

""" sources = {} for i, m in enumerate(metrics, 1): status_class = f"status-{m['status']}" stars = "🌟" if m.get('impact_score', 0) > 80 else "" impact = f"{m.get('impact_score', 0)} {stars}" sources[m['source']] = sources.get(m['source'], 0) + 1 html += f""" """ html += f"""
# Status Title Primary Category Impact Source Reason
{i} {m['status']} {m.get('title', 'N/A')[:60]}... {m['category']} {impact} {m['source']} {m['reason']}
""" with open(REPORT_PATH, "w") as f: f.write(html) return REPORT_PATH