# gradio_analytics.py import gradio as gr import logging import json import sqlite3 import os from datetime import datetime logger = logging.getLogger(__name__) try: from app import ( get_trackio_database_path, get_project_statistics_with_nulls, get_recent_interactions_with_nulls, create_dashboard_html_with_nulls, calculate_response_quality, refresh_analytics_data_persistent as refresh_analytics_data, export_metrics_json_persistent as export_metrics_json, export_metrics_csv_persistent as export_metrics_csv, load_analytics_state, get_global_state_debug_info, sync_trackio_with_global_state, global_state_manager, evaluate_educational_quality_with_tracking, ) except ImportError: def get_trackio_database_path(project_name): return None def get_project_statistics_with_nulls(cursor, project_name): return { "total_conversations": None, "avg_session_length": None, "success_rate": None } def get_recent_interactions_with_nulls(cursor, project_name, limit=10): return [] def create_dashboard_html_with_nulls(project_name, project_stats): return f"
Mock dashboard for {project_name}
" def calculate_response_quality(response): return 3.0 def refresh_analytics_data(): return {}, [], "
Mock analytics
" def export_metrics_json(): gr.Info("Mock JSON export") def export_metrics_csv(): gr.Info("Mock CSV export") def load_analytics_state(): return {}, [], "
Mock analytics state
" def get_global_state_debug_info(): return {"status": "mock"} def sync_trackio_with_global_state(): pass def evaluate_educational_quality_with_tracking(*args, **kwargs): return {"educational_score": 0.5} class MockStateManager: def get_cache_status(self): return {"status": "mock"} def get_evaluation_summary(self, include_history=False): return {"aggregate_metrics": {}, "total_evaluations": {}} def clear_all_states(self): pass def _backup_to_hf_dataset(self): pass global_state_manager = MockStateManager() def load_custom_css(): try: with open("styles.css", "r", encoding="utf-8") as css_file: css_content = css_file.read() logger.info(f"CSS loaded successfully for analytics page") return css_content except FileNotFoundError: logger.warning("styles.css file not found for analytics page") return "" except Exception as e: logger.warning(f"Error reading styles.css: {e}") return "" def show_cache_info(): try: from pathlib import Path from huggingface_hub import scan_cache_dir cache_info = scan_cache_dir(cache_dir="/tmp/huggingface") info_text = f""" **HuggingFace Cache Status:** **Total Size:** {cache_info.size_on_disk / (1024**3):.2f} GB **Number of Repos:** {len(cache_info.repos)} **Cached Models:** """ for repo in cache_info.repos: size_gb = repo.size_on_disk / (1024**3) info_text += f""" - **{repo.repo_id}** - Size: {size_gb:.2f} GB - Type: {repo.repo_type} - Revisions: {len(repo.revisions)} """ return info_text except Exception as e: return f"Error inspecting cache: {str(e)}" def launch_external_trackio(): try: import subprocess result = subprocess.run( ["trackio", "show", "--project", "Mimir"], capture_output=False, text=True ) if result.returncode == 0: gr.Info("Trackio dashboard launched in browser") else: gr.Warning("Could not launch trackio dashboard") except Exception as e: logger.error(f"Failed to launch trackio: {e}") gr.Warning(f"Failed to launch trackio dashboard: {str(e)}") def show_cache_status(): try: debug_info = get_global_state_debug_info() cache_status = debug_info.get("cache_status", {}) status_text = f""" **Global State Cache Status:** - Session ID: {cache_status.get('session_id', 'Unknown')} - Analytics Cached: {'Yes' if cache_status.get('analytics_cached') else 'No'} - Conversation Cached: {'Yes' if cache_status.get('conversation_cached') else 'No'} - Analytics Last Refresh: {cache_status.get('analytics_last_refresh', 'Never')} - Total Analytics Sessions: {cache_status.get('total_analytics_sessions', 0)} - Total Conversation Sessions: {cache_status.get('total_conversation_sessions', 0)} **Analytics Data Status:** - Has Analytics Data: {'Yes' if cache_status.get('analytics_has_data') else 'No'} - Conversation Length: {cache_status.get('conversation_length', 0)} messages - Chat History Length: {cache_status.get('chat_history_length', 0)} messages *Last Updated: {datetime.now().strftime('%H:%M:%S')}* """ gr.Info("Cache status updated - check the Status panel") return status_text except Exception as e: error_text = f"Error getting cache status: {str(e)}" gr.Warning(error_text) return error_text def manual_backup_to_hf(): try: global_state_manager._backup_to_hf_dataset() gr.Info("Manual backup to HF dataset completed successfully") return f"Backup completed at {datetime.now().strftime('%H:%M:%S')}" except Exception as e: gr.Warning(f"Backup failed: {str(e)}") return f"Backup failed: {str(e)}" def get_persistence_status(): try: status_info = { "SQLite DB": "Active" if os.path.exists(global_state_manager._db_path) else "Not Found", "HF Dataset": global_state_manager.dataset_repo, "Last HF Backup": global_state_manager._last_hf_backup.strftime('%Y-%m-%d %H:%M:%S'), "DB Path": global_state_manager._db_path, "Backup Interval": f"{global_state_manager._hf_backup_interval}s" } return status_info except Exception as e: return {"error": str(e)} def clear_all_global_states(): try: global_state_manager.clear_all_states() gr.Info("All global states cleared successfully") empty_stats = { "total_conversations": None, "avg_session_length": None, "success_rate": None, "model_type": "Cleared", "last_updated": datetime.now().strftime("%Y-%m-%d %H:%M:%S") } empty_html = """

States Cleared

All global states have been cleared.

Click "Refresh Data" to reload analytics.

""" return empty_stats, [], empty_html except Exception as e: gr.Warning(f"Failed to clear states: {str(e)}") return load_analytics_state() def show_evaluation_metrics(): try: eval_summary = global_state_manager.get_evaluation_summary(include_history=True) metrics_data = [ ["Educational Quality", f"{eval_summary['aggregate_metrics']['avg_educational_quality']:.3f}"], ["User Satisfaction", f"{eval_summary['aggregate_metrics']['user_satisfaction_rate']:.3f}"] ] recent_evaluations = [] if 'history' in eval_summary: for eval_item in eval_summary['history']['recent_educational_scores'][-5:]: recent_evaluations.append([ eval_item['timestamp'][:16], f"{eval_item['educational_score']:.3f}", f"{eval_item['semantic_quality']:.3f}", f"{eval_item['response_time']:.3f}s" ]) return eval_summary, metrics_data, recent_evaluations except Exception as e: logger.error(f"Error getting evaluation metrics: {e}") return {}, [], [] def sync_and_refresh_all(): try: sync_trackio_with_global_state() project_stats, recent_interactions, dashboard_html = refresh_analytics_data() eval_summary, metrics_data, recent_evaluations = show_evaluation_metrics() gr.Info("All data synced and refreshed successfully") return project_stats, recent_interactions, dashboard_html, eval_summary, metrics_data, recent_evaluations except Exception as e: logger.error(f"Sync and refresh failed: {e}") gr.Warning(f"Sync failed: {str(e)}") return load_analytics_state() + ({}, [], []) with gr.Blocks() as demo: custom_css = load_custom_css() if custom_css: gr.HTML(f'') gr.HTML('

Mimir Analytics Dashboard

') gr.Markdown("Monitor educational AI performance and effectiveness metrics with persistent state management.") with gr.Tabs(): with gr.TabItem("Traditional Analytics"): with gr.Row(): with gr.Column(scale=1): gr.Markdown("## Controls") refresh_btn = gr.Button("Refresh Data", variant="primary") sync_all_btn = gr.Button("Sync & Refresh All", variant="primary") with gr.Row(): export_json_btn = gr.Button("Export JSON", variant="secondary", size="sm") export_csv_btn = gr.Button("Export CSV", variant="secondary", size="sm") launch_trackio_btn = gr.Button("Launch Trackio Dashboard", variant="secondary") gr.Markdown("### State Management") with gr.Row(): cache_status_btn = gr.Button("Cache Status", size="sm") clear_states_btn = gr.Button("Clear All States", size="sm", variant="stop") with gr.Group(): gr.Markdown("### Project Information") project_info = gr.JSON( value={ "total_conversations": None, "avg_session_length": None, "success_rate": None, "model_type": None }, label="Project Stats" ) with gr.Group(): gr.Markdown("### System Status") status_panel = gr.Markdown( "Click 'Cache Status' to view global state information.", label="Status Information" ) with gr.Column(scale=2): gr.Markdown("## Key Metrics Dashboard") trackio_iframe = gr.HTML( value="""

Trackio Dashboard

Analytics data will appear here after conversations.

Data is automatically cached and persists across page navigation.

To launch trackio dashboard separately, run:

trackio show --project "Mimir"
""", label="Dashboard" ) with gr.Row(): with gr.Column(): gr.Markdown("## Recent Interactions") gr.Markdown("*Data persists when switching between Chatbot and Analytics pages*") recent_metrics = gr.Dataframe( headers=["Timestamp", "Response Time", "Prompt Mode", "Tools Used", "Quality Score", "Adapter"], datatype=["str", "number", "str", "bool", "number", "str"], row_count=10, col_count=6, interactive=False, label="Latest Sessions", value=[], show_label=True ) with gr.TabItem("ML Performance"): gr.Markdown("## Agent-Based Performance & Global State Metrics") with gr.Row(): with gr.Column(scale=1): eval_metrics_btn = gr.Button("Get Evaluation Metrics", variant="primary") with gr.Group(): gr.Markdown("### Model Cache Status") cache_status_display = gr.JSON( value={}, label="Cache Information" ) with gr.Column(scale=2): gr.Markdown("### Aggregate Performance Metrics") eval_metrics_table = gr.Dataframe( headers=["Metric", "Score"], datatype=["str", "str"], label="Model Performance", value=[] ) eval_summary_display = gr.JSON( value={}, label="Detailed Evaluation Summary" ) with gr.Row(): with gr.Column(): gr.Markdown("### Recent Quality Evaluations") recent_evaluations_table = gr.Dataframe( headers=["Timestamp", "Educational Score", "Semantic Quality", "Response Time"], datatype=["str", "str", "str", "str"], label="Recent Evaluations", value=[] ) with gr.TabItem("System Status"): gr.Markdown("## Global State Manager & System Diagnostics") with gr.Row(): with gr.Column(): gr.Markdown("### Global State Cache") cache_details = gr.Markdown("Click 'Show Cache Status' to view detailed information.") show_cache_btn = gr.Button("Show Cache Status", variant="primary") refresh_cache_btn = gr.Button("Refresh Cache Info", variant="secondary") gr.Markdown("### Persistence Controls") backup_btn = gr.Button("Manual Backup to HF Dataset", variant="primary") backup_status = gr.Textbox(label="Backup Status", value="No recent backup", interactive=False) with gr.Column(): gr.Markdown("### System Actions") sync_trackio_btn = gr.Button("Sync to Database", variant="secondary") clear_all_btn = gr.Button("Clear All Global States", variant="stop") gr.Markdown("### Persistence Status") persistence_info = gr.JSON( value={}, label="Persistence Information" ) gr.Markdown("### Performance Monitor") perf_info = gr.JSON( value={}, label="Performance Information" ) # NEW: HuggingFace Cache Viewer Section with gr.Row(): with gr.Column(): gr.Markdown("### 🗂️ HuggingFace Model Cache") gr.Markdown("*View cached models and disk usage*") cache_viewer_btn = gr.Button("Inspect Model Cache", variant="primary", size="lg") with gr.Row(): clear_cache_btn = gr.Button("Clear Cache (⚠️ Dangerous)", variant="stop", size="sm") refresh_models_btn = gr.Button("Re-download Models", variant="secondary", size="sm") cache_info_display = gr.Markdown( "Click **Inspect Model Cache** to view detailed cache information.", label="Cache Details" ) demo.load( load_analytics_state, inputs=None, outputs=[project_info, recent_metrics, trackio_iframe], show_progress="hidden" ) demo.load( fn=lambda: global_state_manager.get_cache_status(), inputs=None, outputs=[cache_status_display], show_progress="hidden" ) demo.load( fn=get_persistence_status, inputs=None, outputs=[persistence_info], show_progress="hidden" ) refresh_btn.click( fn=refresh_analytics_data, inputs=[], outputs=[project_info, recent_metrics, trackio_iframe], show_progress="full" ) sync_all_btn.click( fn=sync_and_refresh_all, inputs=[], outputs=[project_info, recent_metrics, trackio_iframe, eval_summary_display, eval_metrics_table, recent_evaluations_table], show_progress="full" ) export_json_btn.click( fn=export_metrics_json, inputs=[], outputs=[], show_progress="full" ) export_csv_btn.click( fn=export_metrics_csv, inputs=[], outputs=[], show_progress="full" ) launch_trackio_btn.click( fn=launch_external_trackio, inputs=[], outputs=[], show_progress="full" ) cache_status_btn.click( fn=show_cache_status, inputs=[], outputs=[status_panel], show_progress="full" ) clear_states_btn.click( fn=clear_all_global_states, inputs=[], outputs=[project_info, recent_metrics, trackio_iframe], show_progress="full" ) eval_metrics_btn.click( fn=show_evaluation_metrics, inputs=[], outputs=[eval_summary_display, eval_metrics_table, recent_evaluations_table], show_progress="full" ) show_cache_btn.click( fn=show_cache_status, inputs=[], outputs=[cache_details], show_progress="full" ) refresh_cache_btn.click( fn=lambda: global_state_manager.get_cache_status(), inputs=[], outputs=[perf_info], show_progress="full" ) backup_btn.click( fn=manual_backup_to_hf, inputs=[], outputs=[backup_status], show_progress="full" ) sync_trackio_btn.click( fn=sync_trackio_with_global_state, inputs=[], outputs=[], show_progress="full" ) clear_all_btn.click( fn=clear_all_global_states, inputs=[], outputs=[project_info, recent_metrics, trackio_iframe], show_progress="full" ) if __name__ == "__main__": logger.info("Running analytics dashboard standalone with global state management") demo.launch(server_name="0.0.0.0", server_port=7861)