""" UI Helpers Module Contains UI formatting and helper functions for the Gradio interface. """ import logging import random import math from typing import Dict, Any, List # Configure logging logger = logging.getLogger(__name__) def get_model_display_name(model_name: str) -> str: """Get the display name for a model.""" model_names = { "gemini": "Gemini 2.0 Flash", "mistral": "Mistral OCR", "openai": "OpenAI GPT-4o", "gpt5": "OpenAI GPT-5" } return model_names.get(model_name, model_name) def select_random_models() -> tuple[str, str]: """Randomly select two models from the available list including gpt5.""" models = ["gemini", "mistral", "openai", "gpt5"] selected_models = random.sample(models, 2) return selected_models[0], selected_models[1] def format_votes_table(votes: List[Dict[str, Any]]) -> str: """Format votes data into an HTML table with OCR outputs and image thumbnails.""" if not votes: return "

No votes found in the database.

" # Sort votes by timestamp (latest first) sorted_votes = sorted(votes, key=lambda x: x.get('timestamp', ''), reverse=True) html = """
""" for vote in sorted_votes: timestamp = vote.get('timestamp', 'N/A') username = vote.get('username', 'N/A') model_a = vote.get('model_a', 'N/A') model_b = vote.get('model_b', 'N/A') vote_choice = vote.get('vote', 'N/A') model_a_output = vote.get('model_a_output', 'N/A') model_b_output = vote.get('model_b_output', 'N/A') image_url = vote.get('image_url', 'N/A') # Format timestamp - handle both ISO format and our custom format if timestamp != 'N/A': try: from datetime import datetime # Check if it's already in our desired format if len(timestamp) == 19 and timestamp[10] == ' ': # Already in YYYY-MM-DD HH:MM:SS format formatted_time = timestamp else: # Convert from ISO format to our format dt = datetime.fromisoformat(timestamp.replace('Z', '+00:00')) formatted_time = dt.strftime('%Y-%m-%d %H:%M:%S') except: formatted_time = timestamp else: formatted_time = 'N/A' # Get model display names model_a_name = get_model_display_name(model_a) model_b_name = get_model_display_name(model_b) models_display = f"{model_a_name} vs {model_b_name}" # Determine which model was voted for and get its display name voted_model_name = "" vote_color = "gray" if vote_choice == "model_a": voted_model_name = model_a_name vote_color = "green" elif vote_choice == "model_b": voted_model_name = model_b_name vote_color = "blue" # Truncate OCR outputs for table display (shorter for better fit) model_a_preview = model_a_output[:80] + "..." if len(model_a_output) > 80 else model_a_output model_b_preview = model_b_output[:80] + "..." if len(model_b_output) > 80 else model_b_output # Fix image URL - use the correct Supabase storage URL format if image_url and image_url != 'N/A' and not image_url.startswith('http'): # If it's just a path, construct the full URL import os image_url = f"{os.getenv('SUPABASE_URL')}/storage/v1/object/public/images/{image_url}" # Create image thumbnail or placeholder if image_url and image_url != 'N/A': image_html = f'OCR Image' else: image_html = 'No image' html += f""" """ html += """
Timestamp Username Models Vote Model A Output Model B Output Image
{formatted_time} {username} {models_display} {voted_model_name} {model_a_preview} {model_b_preview} {image_html}
""" return html def format_elo_leaderboard(elo_ratings: Dict[str, float], vote_counts: Dict[str, int] = None) -> str: """Format ELO ratings into a leaderboard HTML table.""" # Sort models by ELO rating (highest first) sorted_models = sorted(elo_ratings.items(), key=lambda x: x[1], reverse=True) html = """

ELO Leaderboard

Models are ranked by their ELO rating. Higher ratings indicate better performance.

""" for rank, (model, rating) in enumerate(sorted_models, 1): # Get model display name display_name = get_model_display_name(model) # Get vote count for this model vote_count = vote_counts.get(model, 0) if vote_counts else 0 html += f""" """ html += """
Rank Model ELO Rating Total Votes
{rank} {display_name} {rating:.0f} {vote_count}
""" return html