diff --git "a/app.py" "b/app.py" --- "a/app.py" +++ "b/app.py" @@ -1,2185 +1,1047 @@ -# app.py - Complete fixed version -# ๐Ÿš€ ARF Ultimate Investor Demo v3.8.0 - ENTERPRISE EDITION -# ENHANCED VERSION WITH CLEAR BOUNDARIES AND RELIABLE VISUALIZATIONS -# Fixed to show clear OSS vs Enterprise boundaries with architectural honesty -import logging -import sys -import traceback +# app.py - FIXED VERSION WITH PROPER DATA TYPES +""" +ARF OSS v3.3.9 Demo Application +Fixed to return correct data types for UI components: +- Plotly figures for visualizations +- JSON/dict for analysis functions +""" + +import os import json -import datetime -import asyncio -import time +import plotly.graph_objects as go +import plotly.express as px +import pandas as pd +import numpy as np +from datetime import datetime, timedelta +import gradio as gr import random -from pathlib import Path -from typing import Dict, List, Any, Optional, Tuple +import logging +from typing import Dict, Any, Optional, Tuple -# =========================================== -# CONFIGURE LOGGING FIRST -# =========================================== -logging.basicConfig( - level=logging.INFO, - format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - handlers=[ - logging.StreamHandler(sys.stdout), - logging.FileHandler('arf_demo.log') - ] -) +# Configure logging +logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) -# Add parent directory to path -sys.path.insert(0, str(Path(__file__).parent)) +# ARF OSS imports +try: + from arf_core.monitoring import TelemetryCollector + from arf_core.analysis import ReliabilityAnalyzer + from arf_core.healing import AutoHealingEngine + ARF_OSS_AVAILABLE = True + logger.info("โœ… ARF OSS v3.3.9 detected") +except ImportError: + ARF_OSS_AVAILABLE = False + logger.warning("โš ๏ธ ARF OSS components not found, using mock implementations") -# =========================================== -# IMPORT UTILITY CLASSES FIRST -# =========================================== -from utils.installation import InstallationHelper -from demo.guidance import DemoPsychologyController, get_demo_controller +# Configuration +DEMO_CONFIG = { + "version": "3.3.9", + "mode": "demo", + "show_boundaries": True, + "use_true_arf": True +} # =========================================== -# BOUNDARY MANAGEMENT SYSTEM +# FIXED VISUALIZATION FUNCTIONS - RETURN PLOTLY FIGURES # =========================================== -class BoundaryManager: - """Manages clear boundaries between OSS and Enterprise""" - - @staticmethod - def get_system_boundaries(): - """Get current system boundaries""" - installation = get_installation_status() - - return { - "oss": { - "available": installation["oss_installed"], - "version": installation["oss_version"] or "mock", - "label": installation["badges"]["oss"]["text"], - "color": installation["badges"]["oss"]["color"], - "icon": installation["badges"]["oss"]["icon"], - "capabilities": ["advisory_analysis", "rag_search", "healing_intent"], - "license": "Apache 2.0" - }, - "enterprise": { - "available": installation["enterprise_installed"], - "version": installation["enterprise_version"] or "simulated", - "label": installation["badges"]["enterprise"]["text"], - "color": installation["badges"]["enterprise"]["color"], - "icon": installation["badges"]["enterprise"]["icon"], - "capabilities": ["autonomous_execution", "rollback_guarantee", "mcp_integration", "enterprise_support"], - "license": "Commercial" - }, - "demo_mode": { - "active": True, - "architecture": "OSS advises โ†’ Enterprise executes", - "boundary_visible": settings.show_boundaries - } - } - - @staticmethod - def get_boundary_badges() -> str: - """Get HTML badges showing system boundaries""" - boundaries = BoundaryManager.get_system_boundaries() - - return f""" -
-
-
{boundaries['oss']['icon']}
-
-
- {boundaries['oss']['label']} -
-
- Apache 2.0 โ€ข Advisory Intelligence -
-
-
- -
-
{boundaries['enterprise']['icon']}
-
-
- {boundaries['enterprise']['label']} -
-
- Commercial โ€ข Autonomous Execution -
-
-
- -
-
๐Ÿ—๏ธ
-
-
- Architecture Boundary -
-
- OSS advises โ†’ Enterprise executes -
-
-
-
- """ - - @staticmethod - def create_boundary_indicator(action: str, is_simulated: bool = True) -> str: - """Create clear execution boundary indicator""" - if is_simulated: - return f""" -
-
๐ŸŽญ
-

- SIMULATED ENTERPRISE EXECUTION -

-

- Action: {action}
- Mode: Enterprise Simulation (not real execution)
- Boundary: OSS advises โ†’ Enterprise would execute -

-
- DEMO BOUNDARY -
-

- In production, Enterprise edition would execute against real infrastructure -

-
- """ - else: - return f""" -
-
โšก
-

- REAL ENTERPRISE EXECUTION -

-

- Action: {action}
- Mode: Enterprise Autonomous
- Boundary: Real execution with safety guarantees -

-
- ENTERPRISE+ -
-
- """ -# =========================================== -# ASYNC UTILITIES -# =========================================== -class AsyncRunner: - """Enhanced async runner with better error handling""" - - @staticmethod - def run_async(coro): - """Run async coroutine in sync context""" - try: - loop = asyncio.get_event_loop() - except RuntimeError: - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - - try: - return loop.run_until_complete(coro) - except Exception as e: - logger.error(f"Async execution failed: {e}") - return {"error": str(e), "status": "failed", "boundary_note": "Execution boundary reached"} - - @staticmethod - def async_to_sync(async_func): - """Decorator to convert async function to sync""" - def wrapper(*args, **kwargs): - try: - return AsyncRunner.run_async(async_func(*args, **kwargs)) - except Exception as e: - logger.error(f"Async to sync conversion failed: {e}") - return {"error": str(e), "status": "failed", "boundary_context": "OSS advisory only - execution requires Enterprise"} - return wrapper - -# =========================================== -# SIMPLE SETTINGS -# =========================================== -class Settings: - """Simple settings class""" - def __init__(self): - self.arf_mode = "demo" - self.use_true_arf = True - self.default_scenario = "Cache Miss Storm" - self.max_history_items = 100 - self.auto_refresh_seconds = 30 - self.show_boundaries = True - self.architectural_honesty = True - self.engineer_annual_cost = 200000 - -settings = Settings() - -# =========================================== -# ARF INSTALLATION CHECK - FIXED VERSION -# =========================================== -def check_arf_installation(): - """Check if real ARF packages are installed - Fixed version""" - results = { - "oss_installed": False, - "enterprise_installed": False, - "oss_version": None, - "enterprise_version": None, - "oss_edition": "unknown", - "oss_license": "unknown", - "execution_allowed": False, - "recommendations": [], - "boundaries": { - "oss_can": ["advisory_analysis", "rag_search", "healing_intent"], - "oss_cannot": ["execute", "modify_infra", "autonomous_healing"], - "enterprise_requires": ["license", "infra_access", "safety_controls"] - }, - "badges": { - "oss": {"text": "โš ๏ธ Mock ARF", "color": "#f59e0b", "icon": "โš ๏ธ"}, - "enterprise": {"text": "๐Ÿ”’ Enterprise Required", "color": "#64748b", "icon": "๐Ÿ”’"} - }, - "timestamp": datetime.datetime.now().isoformat() - } - - # Check OSS package using InstallationHelper - installation_helper = InstallationHelper() - status = installation_helper.check_installation() - - results["oss_installed"] = status["oss_installed"] - results["oss_version"] = status["oss_version"] - results["enterprise_installed"] = status["enterprise_installed"] - results["enterprise_version"] = status["enterprise_version"] - results["recommendations"] = status["recommendations"] - - if results["oss_installed"]: - results["badges"]["oss"] = { - "text": f"โœ… ARF OSS v{results['oss_version']}", - "color": "#10b981", - "icon": "โœ…" - } - logger.info(f"โœ… ARF OSS v{results['oss_version']} detected") - else: - logger.info("โš ๏ธ ARF OSS not installed - using mock mode") - - if results["enterprise_installed"]: - results["badges"]["enterprise"] = { - "text": f"๐Ÿš€ Enterprise v{results['enterprise_version']}", - "color": "#8b5cf6", - "icon": "๐Ÿš€" - } - logger.info(f"โœ… ARF Enterprise v{results['enterprise_version']} detected") - else: - logger.info("โš ๏ธ ARF Enterprise not installed - using simulation") - - return results - -_installation_status = None - -def get_installation_status(): - """Get cached installation status""" - global _installation_status - if _installation_status is None: - _installation_status = check_arf_installation() - return _installation_status - -# =========================================== -# RELIABLE VISUALIZATION HELPERS -# =========================================== -def create_simple_telemetry_plot(scenario_name: str, is_real_arf: bool = True): - """Simple guaranteed-to-work telemetry plot with boundary indicators""" - try: - # Try to use real visualization if available - components = get_components() - if components["all_available"] and "EnhancedVisualizationEngine" in components: - viz_engine = components["EnhancedVisualizationEngine"] - return viz_engine.create_telemetry_plot(scenario_name, True, is_real_arf) - except Exception as e: - logger.warning(f"Real telemetry plot failed, using fallback: {e}") - - # Fallback to HTML - return create_html_telemetry_fallback(scenario_name, is_real_arf) - -def create_html_telemetry_fallback(scenario_name: str, is_real_arf: bool) -> str: - """HTML fallback for telemetry visualization""" - severity_colors = { - "Cache Miss Storm": "#f59e0b", - "Database Connection Pool Exhaustion": "#ef4444", - "Kubernetes Memory Leak": "#8b5cf6", - "API Rate Limit Storm": "#ec4899", - "Network Partition": "#14b8a6", - "Storage I/O Saturation": "#84cc16" - } - - color = severity_colors.get(scenario_name, "#64748b") - boundary_indicator = "๐Ÿข ENTERPRISE" if is_real_arf else "๐Ÿ”“ OSS ONLY" - - return f""" -
- - -
- {boundary_indicator} -
- -
-
-

- ๐Ÿ“Š Telemetry: {scenario_name} -

-

- Real-time metrics showing anomalous behavior pattern detection. - ARF analyzes 45+ data points per second. -

-
- -
-
- 94% -
-
- Anomaly Confidence -
-
-
- - -
-
- - -
-
- ANOMALY -
-
- - -
-
-
- - -
-
-
45s
-
Detection Time
-
-
-
12/min
-
Data Points
-
-
-
3
-
Similar Patterns
-
-
- - -
- Boundary: This visualization shows {'real' if is_real_arf else 'simulated'} - telemetry analysis. {'Enterprise' if is_real_arf else 'OSS'} edition provides enhanced - anomaly detection. -
-
+def create_simple_telemetry_plot(scenario_name: str, is_real_arf: bool = True) -> go.Figure: + """ + Create telemetry plot using Plotly - returns Plotly figure object + FIXED: Returns Plotly figure instead of HTML string """ - -def create_simple_impact_plot(scenario_name: str, is_real_arf: bool = True): - """Simple guaranteed-to-work impact plot with boundary indicators""" try: - components = get_components() - if components["all_available"] and "EnhancedVisualizationEngine" in components: - viz_engine = components["EnhancedVisualizationEngine"] - return viz_engine.create_impact_gauge(scenario_name, is_real_arf) - except Exception as e: - logger.warning(f"Real impact plot failed, using fallback: {e}") - - return create_html_impact_fallback(scenario_name, is_real_arf) - -def create_html_impact_fallback(scenario_name: str, is_real_arf: bool) -> str: - """HTML fallback for impact visualization""" - impact_values = { - "Cache Miss Storm": 8500, - "Database Connection Pool Exhaustion": 4200, - "Kubernetes Memory Leak": 5500, - "API Rate Limit Storm": 3800, - "Network Partition": 12000, - "Storage I/O Saturation": 6800 - } - - impact = impact_values.get(scenario_name, 5000) - savings = int(impact * 0.85) - boundary_text = "Enterprise Autonomous" if is_real_arf else "OSS Advisory" - boundary_color = "#8b5cf6" if is_real_arf else "#10b981" - - return f""" -
- -
-
-

- ๐Ÿ’ฐ Business Impact Analysis -

-
- {boundary_text} -
-
- -
-
- ${impact:,} -
-
- Revenue Loss/Hour -
-
-
- - -
- -
- - -
-
- - -
-
- - -
- $0 -
-
- ${impact//2:,} -
-
- ${impact:,} -
- - -
-
-
- ${savings:,} SAVED -
-
-
+ # Generate sample telemetry data + times = pd.date_range(start=datetime.now() - timedelta(minutes=10), + end=datetime.now(), + periods=60) + + # Different patterns based on scenario + if "Cache" in scenario_name: + normal_values = np.random.normal(30, 5, 30).tolist() + anomaly_values = np.random.normal(85, 10, 30).tolist() + data = normal_values + anomaly_values + title = f"Cache Hit Rate: {scenario_name}" + y_label = "Hit Rate (%)" + threshold = 75 + elif "Database" in scenario_name: + normal_values = np.random.normal(15, 3, 30).tolist() + anomaly_values = np.random.normal(95, 5, 30).tolist() + data = normal_values + anomaly_values + title = f"Database Connections: {scenario_name}" + y_label = "Connections (%)" + threshold = 90 + elif "Kubernetes" in scenario_name: + normal_values = np.random.normal(40, 8, 30).tolist() + anomaly_values = np.random.normal(95, 2, 30).tolist() + data = normal_values + anomaly_values + title = f"Memory Usage: {scenario_name}" + y_label = "Memory (%)" + threshold = 85 + else: + normal_values = np.random.normal(50, 10, 30).tolist() + anomaly_values = np.random.normal(90, 5, 30).tolist() + data = normal_values + anomaly_values + title = f"System Metrics: {scenario_name}" + y_label = "Metric (%)" + threshold = 80 + + # Create Plotly figure + fig = go.Figure() + + # Add normal region + fig.add_trace(go.Scatter( + x=times[:30], + y=data[:30], + mode='lines', + name='Normal', + line=dict(color='#10b981', width=3), + fill='tozeroy', + fillcolor='rgba(16, 185, 129, 0.1)' + )) + + # Add anomaly region + fig.add_trace(go.Scatter( + x=times[30:], + y=data[30:], + mode='lines', + name='Anomaly', + line=dict(color='#ef4444', width=3), + fill='tozeroy', + fillcolor='rgba(239, 68, 68, 0.1)' + )) + + # Add threshold line + fig.add_hline(y=threshold, line_dash="dash", + line_color="#f59e0b", + annotation_text="Threshold", + annotation_position="top right") + + # Update layout + fig.update_layout( + title=dict( + text=title, + font=dict(size=18, color='#1e293b'), + x=0.5 + ), + xaxis_title="Time", + yaxis_title=y_label, + height=300, + margin=dict(l=20, r=20, t=40, b=20), + plot_bgcolor='white', + showlegend=True, + legend=dict( + orientation="h", + yanchor="bottom", + y=1.02, + xanchor="right", + x=1 + ), + xaxis=dict( + showgrid=True, + gridcolor='#f1f5f9', + gridwidth=1 + ), + yaxis=dict( + showgrid=True, + gridcolor='#f1f5f9', + gridwidth=1, + range=[0, 100] + ) + ) - -
-
-
Without ARF
-
45 min
-
Mean time to resolve
-
- -
-
With ARF
-
12 min
-
Autonomous recovery
-
-
+ # Add ARF badge based on mode + if is_real_arf: + fig.add_annotation( + x=0.01, y=0.99, + xref="paper", yref="paper", + text="โœ… ARF OSS v3.3.9", + showarrow=False, + font=dict(size=10, color="#10b981"), + bgcolor="rgba(16, 185, 129, 0.1)", + borderpad=4 + ) + else: + fig.add_annotation( + x=0.01, y=0.99, + xref="paper", yref="paper", + text="โš ๏ธ Mock Mode", + showarrow=False, + font=dict(size=10, color="#f59e0b"), + bgcolor="rgba(245, 158, 11, 0.1)", + borderpad=4 + ) - -
-
๐Ÿ“ˆ
-
-
- Potential ROI: 5.2ร— -
-
- ARF saves 85% of potential revenue loss through autonomous recovery -
-
-
+ return fig - -
- Boundary Context: {'Enterprise' if is_real_arf else 'OSS'} analysis shows - {'real' if is_real_arf else 'simulated'} impact metrics. - {'Commercial license enables autonomous execution.' if is_real_arf else 'Upgrade to Enterprise for autonomous recovery.'} -
-
- """ + except Exception as e: + logger.error(f"Error creating telemetry plot: {e}") + # Return empty figure as fallback + fig = go.Figure() + fig.update_layout( + title="Error loading telemetry", + height=300, + plot_bgcolor='white' + ) + return fig -def create_empty_plot(title: str, is_real_arf: bool = True): - """Create an empty placeholder plot with boundary indicators""" - boundary_color = "#8b5cf6" if is_real_arf else "#10b981" - boundary_text = "Enterprise" if is_real_arf else "OSS" - - return f""" -
-
- ๐Ÿ“Š -
-

- {title} -

-

- Visualization placeholder for {boundary_text} edition. - Install real ARF for enhanced charts. -

-
+def create_simple_impact_plot(scenario_name: str, is_real_arf: bool = True) -> go.Figure: """ - -def get_inactive_agent_html(agent_name: str, description: str, is_real_arf: bool = False): - """Get HTML for inactive agent state with boundary indicators""" - boundary_color = "#8b5cf6" if is_real_arf else "#10b981" - status_color = "#64748b" - - return f""" -
- - -
- - -
-
- ๐Ÿค– -
-
-

- {agent_name} -

-
- INACTIVE -
-
-
- - -

- {description} -

- - -
-
- - Requires { 'Enterprise' if is_real_arf else 'OSS' } activation -
-
-
+ Create impact gauge chart using Plotly - returns Plotly figure object + FIXED: Returns Plotly figure instead of HTML string """ - -# =========================================== -# IMPORT MODULAR COMPONENTS -# =========================================== -def import_components() -> Dict[str, Any]: - """Safely import all components with proper error handling""" - components = { - "all_available": False, - "error": None, - "get_styles": lambda: "", - "show_boundaries": settings.show_boundaries, - } - try: - logger.info("Starting component import...") - - # First, import gradio - import gradio as gr - components["gr"] = gr - - # Import UI styles - from ui.styles import get_styles - components["get_styles"] = get_styles + # Impact values based on scenario + impact_values = { + "Cache Miss Storm": 8500, + "Database Connection Pool Exhaustion": 4200, + "Kubernetes Memory Leak": 5500, + "API Rate Limit Storm": 3800, + "Network Partition": 12000, + "Storage I/O Saturation": 6800 + } - # Import UI components - from ui.components import ( - create_header, create_status_bar, create_tab1_incident_demo, - create_tab2_business_roi, create_tab3_enterprise_features, - create_tab4_audit_trail, create_tab5_learning_engine, - create_footer + impact = impact_values.get(scenario_name, 5000) + savings = int(impact * 0.85) + + # Create gauge chart + fig = go.Figure(go.Indicator( + mode = "gauge+number+delta", + value = impact, + domain = {'x': [0, 1], 'y': [0, 1]}, + title = {'text': f"Revenue Impact: {scenario_name}", 'font': {'size': 16}}, + delta = {'reference': 0, 'position': "top", 'prefix': "Potential loss: $"}, + number = {'prefix': "$", 'suffix': "/hour", 'font': {'size': 28}}, + gauge = { + 'axis': {'range': [None, impact * 1.2], 'tickwidth': 1, 'tickcolor': "darkblue"}, + 'bar': {'color': "#ef4444"}, + 'bgcolor': "white", + 'borderwidth': 2, + 'bordercolor': "gray", + 'steps': [ + {'range': [0, impact * 0.3], 'color': '#10b981'}, + {'range': [impact * 0.3, impact * 0.7], 'color': '#f59e0b'}, + {'range': [impact * 0.7, impact], 'color': '#ef4444'} + ], + 'threshold': { + 'line': {'color': "red", 'width': 4}, + 'thickness': 0.75, + 'value': impact + } + } + )) + + # Add savings annotation + fig.add_annotation( + x=0.5, y=0.2, + text=f"ARF saves: ${savings:,}/hour", + showarrow=False, + font=dict(size=14, color="#10b981", weight="bold"), + bgcolor="rgba(16, 185, 129, 0.1)", + bordercolor="#10b981", + borderwidth=2, + borderpad=4 ) - components.update({ - "create_header": create_header, - "create_status_bar": create_status_bar, - "create_tab1_incident_demo": create_tab1_incident_demo, - "create_tab2_business_roi": create_tab2_business_roi, - "create_tab3_enterprise_features": create_tab3_enterprise_features, - "create_tab4_audit_trail": create_tab4_audit_trail, - "create_tab5_learning_engine": create_tab5_learning_engine, - "create_footer": create_footer, - }) - - # Import scenarios - from demo.scenarios import INCIDENT_SCENARIOS - components["INCIDENT_SCENARIOS"] = INCIDENT_SCENARIOS - - # Try to import TrueARF337Orchestrator - try: - from core.true_arf_orchestrator import TrueARF337Orchestrator - components["DemoOrchestrator"] = TrueARF337Orchestrator - except ImportError: - # Fallback to real ARF integration - try: - from core.real_arf_integration import RealARFIntegration - components["DemoOrchestrator"] = RealARFIntegration - except ImportError: - # Create a minimal mock orchestrator - class MockOrchestrator: - async def analyze_incident(self, scenario_name, scenario_data): - return { - "status": "mock", - "scenario": scenario_name, - "message": "Mock analysis (no real ARF available)", - "boundary_note": "OSS advisory mode - execution requires Enterprise", - "demo_display": { - "real_arf_version": "mock", - "true_oss_used": False, - "enterprise_simulated": True, - "architectural_boundary": "OSS advises โ†’ Enterprise would execute" - } - } - async def execute_healing(self, scenario_name, mode="autonomous"): - return { - "status": "mock", - "scenario": scenario_name, - "message": "Mock execution (no real ARF available)", - "boundary_note": "Simulated Enterprise execution - real execution requires infrastructure", - "enterprise_features_used": ["simulated_execution", "mock_rollback", "demo_mode"] - } - components["DemoOrchestrator"] = MockOrchestrator - - # Try to import ROI calculator - try: - from core.calculators import EnhancedROICalculator - components["EnhancedROICalculator"] = EnhancedROICalculator() - except ImportError: - class MockCalculator: - def calculate_comprehensive_roi(self, **kwargs): - return { - "status": "โœ… Calculated Successfully", - "summary": { - "your_annual_impact": "$1,530,000", - "potential_savings": "$1,254,600", - "enterprise_cost": "$625,000", - "roi_multiplier": "5.2ร—", - "payback_months": "6.0", - "annual_roi_percentage": "420%", - "boundary_context": "Based on OSS analysis + simulated Enterprise execution" - }, - "boundary_note": "ROI calculation includes OSS advisory value and simulated Enterprise execution benefits" - } - components["EnhancedROICalculator"] = MockCalculator() + # Update layout + fig.update_layout( + height=400, + margin=dict(l=20, r=20, t=60, b=20), + paper_bgcolor='white', + font=dict(color='#1e293b') + ) - # Try to import visualization engine - try: - from core.visualizations import EnhancedVisualizationEngine - components["EnhancedVisualizationEngine"] = EnhancedVisualizationEngine() - except ImportError: - class MockVisualizationEngine: - def create_executive_dashboard(self, data=None, is_real_arf=True): - return create_empty_plot("Executive Dashboard", is_real_arf) - def create_telemetry_plot(self, scenario_name, anomaly_detected=True, is_real_arf=True): - return create_simple_telemetry_plot(scenario_name, is_real_arf) - def create_impact_gauge(self, scenario_name, is_real_arf=True): - return create_simple_impact_plot(scenario_name, is_real_arf) - def create_timeline_comparison(self, is_real_arf=True): - return create_empty_plot("Timeline Comparison", is_real_arf) - components["EnhancedVisualizationEngine"] = MockVisualizationEngine() + # Add ARF mode indicator + if is_real_arf: + fig.add_annotation( + x=0.99, y=0.99, + xref="paper", yref="paper", + text="โœ… Real ARF Analysis", + showarrow=False, + font=dict(size=10, color="#10b981"), + bgcolor="rgba(16, 185, 129, 0.1)", + borderpad=4, + xanchor="right" + ) + else: + fig.add_annotation( + x=0.99, y=0.99, + xref="paper", yref="paper", + text="โš ๏ธ Mock Analysis", + showarrow=False, + font=dict(size=10, color="#f59e0b"), + bgcolor="rgba(245, 158, 11, 0.1)", + borderpad=4, + xanchor="right" + ) - components["all_available"] = True - components["error"] = None - logger.info("โœ… Successfully imported all modular components") + return fig except Exception as e: - logger.error(f"โŒ IMPORT ERROR: {e}") - components["error"] = str(e) - components["all_available"] = False - - # Ensure we have minimal components - if "gr" not in components: - import gradio as gr - components["gr"] = gr - - if "INCIDENT_SCENARIOS" not in components: - components["INCIDENT_SCENARIOS"] = { - "Cache Miss Storm": { - "component": "Redis Cache Cluster", - "severity": "HIGH", - "business_impact": {"revenue_loss_per_hour": 8500}, - "boundary_note": "OSS analysis only - execution requires Enterprise" - } - } - - return components - -_components = None -_audit_manager = None + logger.error(f"Error creating impact plot: {e}") + # Return empty gauge as fallback + fig = go.Figure(go.Indicator( + mode="gauge", + value=0, + title="Error loading impact data" + )) + fig.update_layout(height=400) + return fig -def get_components() -> Dict[str, Any]: - """Lazy load components singleton""" - global _components - if _components is None: - _components = import_components() - return _components - -# =========================================== -# AUDIT TRAIL MANAGER -# =========================================== -class AuditTrailManager: - """Enhanced audit trail manager with boundary tracking""" +def create_empty_plot(title: str, is_real_arf: bool = True) -> go.Figure: + """ + Create empty placeholder plot - returns Plotly figure object + FIXED: Returns Plotly figure instead of HTML string + """ + fig = go.Figure() - def __init__(self): - self.executions = [] - self.incidents = [] - self.boundary_crossings = [] - self.max_items = settings.max_history_items + # Add text annotation + fig.add_annotation( + x=0.5, y=0.5, + text=title, + showarrow=False, + font=dict(size=16, color="#64748b"), + xref="paper", + yref="paper" + ) - def add_execution(self, scenario_name: str, mode: str, result: Dict): - """Add an execution record""" - record = { - "timestamp": datetime.datetime.now().isoformat(), - "scenario": scenario_name, - "mode": mode, - "result": result, - "boundary_context": "Enterprise execution simulated" if "simulated" in str(result) else "OSS advisory" - } - self.executions.insert(0, record) - if len(self.executions) > self.max_items: - self.executions = self.executions[:self.max_items] - - # Track boundary crossing - if "enterprise" in mode.lower(): - self.boundary_crossings.append({ - "timestamp": record["timestamp"], - "from": "OSS", - "to": "Enterprise", - "action": scenario_name - }) - - logger.info(f"๐Ÿ“ Execution recorded: {scenario_name} ({mode})") - return record + # Add mode indicator + if is_real_arf: + mode_text = "โœ… ARF OSS v3.3.9" + color = "#10b981" + else: + mode_text = "โš ๏ธ Mock Mode" + color = "#f59e0b" - def add_incident(self, scenario_name: str, analysis_result: Dict): - """Add an incident analysis record""" - record = { - "timestamp": datetime.datetime.now().isoformat(), - "scenario": scenario_name, - "analysis": analysis_result, - "boundary_context": analysis_result.get("boundary_note", "OSS analysis") - } - self.incidents.insert(0, record) - if len(self.incidents) > self.max_items: - self.incidents = self.incidents[:self.max_items] - - logger.info(f"๐Ÿ“ Incident analysis recorded: {scenario_name}") - return record + fig.add_annotation( + x=0.5, y=0.4, + text=mode_text, + showarrow=False, + font=dict(size=12, color=color), + xref="paper", + yref="paper" + ) - def get_execution_table(self): - """Get executions as HTML table""" - if not self.executions: - return """ -
-
๐Ÿ“ญ
-

No executions yet

-

Run scenarios to see execution history

-
- """ - - rows = [] - for i, exec in enumerate(self.executions[:10]): - status = "โœ…" if "success" in exec["result"].get("status", "").lower() else "โš ๏ธ" - boundary = exec["boundary_context"] - boundary_color = "#10b981" if "OSS" in boundary else "#8b5cf6" - - rows.append(f""" - - - {status} {exec["scenario"]} - - - {exec["mode"]} - - -
- {boundary} -
- - - {exec["timestamp"][11:19]} - - - """) - - return f""" -
- - - - - - - - - - - {''.join(rows)} - -
ScenarioModeBoundaryTime
-
- """ + fig.update_layout( + title=dict( + text="Visualization Placeholder", + font=dict(size=14, color="#94a3b8") + ), + height=300, + plot_bgcolor='white', + xaxis=dict(visible=False), + yaxis=dict(visible=False), + margin=dict(l=20, r=20, t=40, b=20) + ) - def get_incident_table(self): - """Get incidents as HTML table""" - if not self.incidents: - return """ -
-
๐Ÿ“ญ
-

No incidents analyzed yet

-

Run OSS analysis to see incident history

-
- """ - - rows = [] - for i, incident in enumerate(self.incidents[:10]): - scenario = incident["scenario"] - analysis = incident["analysis"] - boundary = incident["boundary_context"] - boundary_color = "#10b981" if "OSS" in boundary else "#8b5cf6" - - rows.append(f""" - - - {scenario} - - - {analysis.get('status', 'analyzed')} - - -
- {boundary} -
- - - {incident["timestamp"][11:19]} - - - """) - - return f""" -
- - - - - - - - - - - {''.join(rows)} - -
ScenarioStatusBoundaryTime
-
- """ + return fig + +def create_timeline_plot(scenario_name: str, is_real_arf: bool = True) -> go.Figure: + """ + Create timeline comparison plot - returns Plotly figure object + FIXED: Returns Plotly figure instead of HTML string + """ + # Timeline data + stages = ["Detection", "Analysis", "Response", "Resolution", "Verification"] - def clear(self): - """Clear all audit trails""" - self.executions = [] - self.incidents = [] - self.boundary_crossings = [] - logger.info("๐Ÿงน Audit trail cleared") + # Without ARF (manual) + manual_times = [5, 15, 20, 45, 10] - def export_json(self): - """Export audit trail as JSON""" - return { - "executions": self.executions, - "incidents": self.incidents, - "boundary_crossings": self.boundary_crossings, - "export_time": datetime.datetime.now().isoformat(), - "version": "3.3.7", - "architecture": "OSS advises โ†’ Enterprise executes" - } - -def get_audit_manager() -> AuditTrailManager: - """Lazy load audit manager singleton""" - global _audit_manager - if _audit_manager is None: - _audit_manager = AuditTrailManager() - return _audit_manager - -# =========================================== -# HELPER FUNCTIONS -# =========================================== -def get_scenario_impact(scenario_name: str) -> float: - """Get average impact for a given scenario""" - impact_map = { - "Cache Miss Storm": 8500, - "Database Connection Pool Exhaustion": 4200, - "Kubernetes Memory Leak": 5500, - "API Rate Limit Storm": 3800, - "Network Partition": 12000, - "Storage I/O Saturation": 6800 - } - return impact_map.get(scenario_name, 5000) - -def extract_roi_multiplier(roi_result: Dict) -> float: - """Extract ROI multiplier from EnhancedROICalculator result""" - try: - if "summary" in roi_result and "roi_multiplier" in roi_result["summary"]: - roi_str = roi_result["summary"]["roi_multiplier"] - if "ร—" in roi_str: - return float(roi_str.replace("ร—", "")) - return float(roi_str) - return 5.2 - except Exception as e: - logger.warning(f"Failed to extract ROI multiplier: {e}") - return 5.2 - -# =========================================== -# SCENARIO UPDATE HANDLER -# =========================================== -def update_scenario_display(scenario_name: str) -> tuple: - """Update all scenario-related displays with scenario-specific data""" - components = get_components() - scenarios = components["INCIDENT_SCENARIOS"] + # With ARF + arf_times = [0.75, 2, 5, 12, 2] - scenario = scenarios.get(scenario_name, { - "component": "Unknown System", - "severity": "MEDIUM", - "business_impact": {"revenue_loss_per_hour": 5000}, - "boundary_note": "Scenario not found" - }) + fig = go.Figure() - # Create scenario card - severity_colors = { - "HIGH": "#ef4444", - "MEDIUM": "#f59e0b", - "LOW": "#10b981" - } - severity_color = severity_colors.get(scenario["severity"], "#64748b") + # Add manual timeline + fig.add_trace(go.Bar( + name='Without ARF', + x=manual_times, + y=stages, + orientation='h', + marker_color='#ef4444', + text=[f'{t}min' for t in manual_times], + textposition='auto', + )) - impact = scenario["business_impact"].get("revenue_loss_per_hour", get_scenario_impact(scenario_name)) + # Add ARF timeline + fig.add_trace(go.Bar( + name='With ARF', + x=arf_times, + y=stages, + orientation='h', + marker_color='#10b981', + text=[f'{t}min' for t in arf_times], + textposition='auto', + )) - scenario_card_html = f""" -
- -
-
-

- {scenario_name} -

-
-
- {scenario["severity"]} SEVERITY -
-
- {scenario["component"]} -
-
-
- -
-
- ${impact:,} -
-
- Revenue Loss/Hour -
-
-
- - -
-
- Business Impact Analysis -
-
-
-
45 min
-
Without ARF
-
-
-
12 min
-
With ARF
-
-
-
${int(impact * 0.85):,}
-
Savings
-
-
-
- - -
- Boundary Context: {scenario.get('boundary_note', 'OSS analyzes, Enterprise executes')} -
-
- """ + # Calculate savings + total_manual = sum(manual_times) + total_arf = sum(arf_times) + savings = total_manual - total_arf + savings_percent = int((savings / total_manual) * 100) + + # Update layout + fig.update_layout( + title=dict( + text=f"Timeline Comparison: {scenario_name}", + font=dict(size=18, color='#1e293b'), + x=0.5 + ), + barmode='group', + height=400, + xaxis_title="Time (minutes)", + yaxis_title="Stage", + plot_bgcolor='white', + showlegend=True, + legend=dict( + orientation="h", + yanchor="bottom", + y=1.02, + xanchor="right", + x=1 + ), + margin=dict(l=20, r=20, t=60, b=20) + ) - # Get visualizations - telemetry_viz = create_simple_telemetry_plot(scenario_name, settings.use_true_arf) - impact_viz = create_simple_impact_plot(scenario_name, settings.use_true_arf) + # Add savings annotation + fig.add_annotation( + x=0.5, y=1.12, + xref="paper", yref="paper", + text=f"ARF saves {savings_percent}% ({savings} minutes)", + showarrow=False, + font=dict(size=14, color="#10b981", weight="bold"), + bgcolor="rgba(16, 185, 129, 0.1)", + borderpad=4 + ) - # Create timeline visualization - timeline_viz = create_empty_plot("Incident Timeline", settings.use_true_arf) + # Add ARF mode indicator + if is_real_arf: + fig.add_annotation( + x=0.01, y=1.12, + xref="paper", yref="paper", + text="โœ… ARF OSS v3.3.9", + showarrow=False, + font=dict(size=10, color="#10b981"), + bgcolor="rgba(16, 185, 129, 0.1)", + borderpad=4 + ) - return scenario_card_html, telemetry_viz, impact_viz, timeline_viz + return fig # =========================================== -# TRUE ARF ANALYSIS HANDLER +# FIXED ANALYSIS FUNCTIONS - RETURN JSON/DICT # =========================================== -@AsyncRunner.async_to_sync -async def run_true_arf_analysis(scenario_name: str): - """Run true ARF v3.3.7 analysis with OSS + Enterprise simulation""" - - components = get_components() - installation = get_installation_status() - boundaries = BoundaryManager.get_system_boundaries() - - logger.info(f"๐Ÿ” Running True ARF analysis for: {scenario_name}") - + +def run_true_arf_analysis(scenario_name: str) -> Dict[str, Any]: + """ + Run ARF analysis - returns JSON/dict instead of HTML + FIXED: Returns dict for gr.JSON() component + """ try: - # Get orchestrator - orchestrator = components["DemoOrchestrator"]() - - # Get scenario data - scenarios = components["INCIDENT_SCENARIOS"] - scenario_data = scenarios.get(scenario_name, {}) + # Simulate analysis time + import time + time.sleep(0.5) - # Run analysis - analysis_result = await orchestrator.analyze_incident(scenario_name, scenario_data) - - # Add to audit trail - get_audit_manager().add_incident(scenario_name, analysis_result) - - # Check if we have real ARF - is_real_arf = installation["oss_installed"] or settings.use_true_arf + # Analysis results based on scenario + analysis_results = { + "status": "success", + "scenario": scenario_name, + "timestamp": datetime.now().isoformat(), + "analysis": { + "detection_time": "45 seconds", + "confidence": "94%", + "similar_incidents_found": 3, + "pattern_match": "87% similarity", + "severity": "HIGH", + "component_affected": "Redis Cache Cluster" if "Cache" in scenario_name else "Database Pool" if "Database" in scenario_name else "Kubernetes Pod", + "affected_users": 45000, + "revenue_risk_per_hour": 8500 if "Cache" in scenario_name else 4200 + }, + "agents": { + "detection": { + "status": "active", + "confidence": 94, + "data_points_analyzed": 1245, + "anomaly_score": 0.92 + }, + "recall": { + "status": "active", + "similar_incidents": 3, + "best_match_similarity": 87, + "previous_success_rate": "92%" + }, + "decision": { + "status": "active", + "healing_intent_created": True, + "confidence": 89, + "recommended_action": "Scale Redis cluster from 3 to 5 nodes", + "estimated_recovery": "12 minutes", + "safety_check": "passed" + } + }, + "healing_intent": { + "action": "Scale Redis cluster from 3 to 5 nodes", + "confidence": 89, + "estimated_impact": "Reduce MTTR from 45min to 12min", + "cost_savings": 6375, + "safety_guarantees": ["rollback_available", "atomic_execution", "resource_isolation"] + }, + "boundary_note": "OSS analysis complete. HealingIntent created. Requires Enterprise license for execution.", + "arf_version": "3.3.9", + "license_required": "Enterprise for execution" + } - # Create agent displays based on analysis - if is_real_arf and "real" in str(analysis_result).lower(): - # Real ARF detected - detection_html = f""" -
-
-
๐Ÿ•ต๏ธ
-
-

- Detection Agent (ARF v3.3.7) -

-
- โœ… ACTIVE -
-
-
-

- Real ARF v3.3.7 detected anomaly in 45 seconds with 94% confidence. - Analyzed 12 data points per minute across 4 dimensions. -

-
- Boundary: OSS analysis completed โ†’ Ready for Enterprise execution -
-
- """ - - recall_html = f""" -
-
-
๐Ÿง 
-
-

- Recall Agent (RAG Memory) -

-
- โœ… ACTIVE -
-
-
-

- Found 3 similar incidents in RAG memory with 87% similarity. - Previous resolution time: 38 minutes. Healing success rate: 92%. -

-
- Boundary: Apache 2.0 licensed RAG memory accessible to both OSS and Enterprise -
-
- """ - - decision_html = f""" -
-
-
๐Ÿค”
-
-

- Decision Agent (HealingIntent) -

-
- โœ… ACTIVE -
-
-
-

- Created HealingIntent with 94% confidence. Autonomous recovery estimated at 12 minutes. - Manual alternative: 45 minutes. Rollback guarantee: 100%. -

-
- Boundary: OSS creates HealingIntent โ†’ Enterprise executes it (requires license) -
-
- """ - - results_html = f""" -
-
-
โœ…
-

- True ARF v3.3.7 Analysis Complete -

-

- Real ARF detected and analyzed successfully -

-
- -
-
-
45s
-
Detection Time
-
-
-
94%
-
Confidence
-
-
-
3
-
Similar Incidents
-
-
- - -
-
-
๐Ÿ—๏ธ
-
-
Architecture Boundary Reached
-
OSS analysis complete โ†’ Ready for Enterprise execution
-
-
-

- True ARF OSS has completed advisory analysis and created a HealingIntent. - Autonomous execution requires ARF Enterprise license (commercial). -

-
- - -
-
- ๐Ÿš€ Next: Execute with Enterprise -
-

- Click "Execute Enterprise Healing" to simulate autonomous recovery. - In production, Enterprise would execute against real infrastructure. -

-
-
- """ - + # Check if real ARF is available + if ARF_OSS_AVAILABLE: + analysis_results["arf_mode"] = "real" + analysis_results["arf_components"] = ["TelemetryCollector", "ReliabilityAnalyzer", "AutoHealingEngine"] else: - # Mock analysis (no real ARF) - detection_html = get_inactive_agent_html( - "Detection Agent", - "Would detect anomalies using ARF's pattern recognition.", - False - ) - - recall_html = get_inactive_agent_html( - "Recall Agent", - "Would search RAG memory for similar incidents.", - False - ) - - decision_html = get_inactive_agent_html( - "Decision Agent", - "Would create HealingIntent based on analysis.", - False - ) - - results_html = f""" -
-
โš ๏ธ
-

- Mock Analysis (ARF OSS Not Installed) -

-

- Install agentic-reliability-framework==3.3.7 for real analysis -

- -
-
- Architecture Demo Mode -
-

- Showing the complete ARF architecture: OSS analyzes โ†’ Enterprise executes. - Install real ARF OSS for production-grade anomaly detection. -

-
- -
- pip install agentic-reliability-framework==3.3.7 -
-
- """ + analysis_results["arf_mode"] = "mock" + analysis_results["arf_components"] = ["simulated"] - return detection_html, recall_html, decision_html, results_html + logger.info(f"โœ… ARF analysis completed for {scenario_name}") + return analysis_results except Exception as e: - logger.error(f"True ARF analysis failed: {e}") - - # Fallback to mock analysis - detection_html = get_inactive_agent_html( - "Detection Agent", - f"Error: {str(e)[:100]}...", - False - ) - - recall_html = get_inactive_agent_html( - "Recall Agent", - "Error during analysis", - False - ) - - decision_html = get_inactive_agent_html( - "Decision Agent", - "Unable to create HealingIntent", - False - ) + logger.error(f"Error in ARF analysis: {e}") + return { + "status": "error", + "error": str(e), + "scenario": scenario_name, + "timestamp": datetime.now().isoformat(), + "arf_version": "3.3.9", + "recommendation": "Check ARF installation: pip install agentic-reliability-framework==3.3.9" + } + +def execute_enterprise_healing(scenario_name: str, approval_required: bool = False, + mcp_mode: str = "advisory") -> Dict[str, Any]: + """ + Execute enterprise healing - returns JSON/dict instead of HTML + FIXED: Returns dict for gr.JSON() component + """ + try: + # Simulate execution time + import time + time.sleep(0.7) + + # Calculate impact based on scenario + impact_values = { + "Cache Miss Storm": 8500, + "Database Connection Pool Exhaustion": 4200, + "Kubernetes Memory Leak": 5500, + "API Rate Limit Storm": 3800, + "Network Partition": 12000, + "Storage I/O Saturation": 6800 + } - results_html = f""" -
-
-
โŒ
-

- Analysis Failed -

-

- Error: {str(e)[:200]} -

-

- This demonstrates the boundary: OSS analysis would have succeeded with real ARF installed. -

-
-
- """ + impact = impact_values.get(scenario_name, 5000) + savings = int(impact * 0.85) - return detection_html, recall_html, decision_html, results_html - -# =========================================== -# ENTERPRISE EXECUTION HANDLER -# =========================================== -def execute_enterprise_healing(scenario_name, approval_required, mcp_mode_value): - """Execute enterprise healing with clear boundary indicators""" - import gradio as gr - - components = get_components() - installation = get_installation_status() - boundaries = BoundaryManager.get_system_boundaries() - - logger.info(f"โšก Executing enterprise healing for: {scenario_name}") - logger.info(f" Approval required: {approval_required}") - logger.info(f" MCP mode: {mcp_mode_value}") - - # Check if Enterprise is actually available - is_real_enterprise = installation["enterprise_installed"] - is_simulated = not is_real_enterprise - - # Get scenario impact - scenario = components["INCIDENT_SCENARIOS"].get(scenario_name, {}) - impact = scenario.get("business_impact", {}) - revenue_loss = impact.get("revenue_loss_per_hour", get_scenario_impact(scenario_name)) - savings = int(revenue_loss * 0.85) - - # Create approval display - if approval_required: - approval_display = """ -
-
โณ
-

- HUMAN APPROVAL REQUIRED -

-

- Based on your safety settings, this execution requires human approval.
- Click "Approve" in the interface to proceed with autonomous healing. -

-
- AWAITING APPROVAL -
-

- This demonstrates ARF's safety-first approach to autonomous operations -

-
- """ - else: - approval_display = """ -
-
โšก
-

- AUTONOMOUS APPROVAL GRANTED -

-

- Based on HealingIntent confidence (94%) and safety checks passed.
- Proceeding with autonomous execution. -

-
- APPROVED FOR AUTONOMOUS EXECUTION -
-
- """ - - # Execute healing (async) - @AsyncRunner.async_to_sync - async def execute_async(): - try: - orchestrator = components["DemoOrchestrator"]() - execution_result = await orchestrator.execute_healing(scenario_name, "autonomous") - - # Add to audit trail - get_audit_manager().add_execution(scenario_name, "enterprise_autonomous", execution_result) - - return execution_result - - except Exception as e: - logger.error(f"Execution failed: {e}") - return { - "status": "failed", - "error": str(e), - "boundary_note": "Execution boundary reached - requires real Enterprise", - "demo_display": { - "recovery_time": "simulated", - "cost_saved": f"${savings:,} (simulated)", - "rollback_guarantee": "simulated" - } - } - - execution_result = execute_async() - - # Create results display - if is_real_enterprise: - # Real Enterprise execution - enterprise_results = { - "demo_mode": "Real Enterprise", + # Execution results + execution_results = { + "status": "success", "scenario": scenario_name, - "arf_version": boundaries["enterprise"]["version"], - "true_enterprise_used": True, - "execution_mode": "autonomous" if not approval_required else "human_approved", - "boundary_crossed": True, - "mcp_integration": mcp_mode_value, - "execution_result": execution_result, - "outcome": { + "execution_timestamp": datetime.now().isoformat(), + "mode": mcp_mode, + "approval_required": approval_required, + "approval_status": "auto_approved" if not approval_required else "pending_human", + "execution": { + "action_executed": "Scale Redis cluster from 3 to 5 nodes", + "execution_time": "2 minutes", + "start_time": (datetime.now() - timedelta(minutes=2)).isoformat(), + "end_time": datetime.now().isoformat(), + "status": "completed", + "rollback_available": True, + "atomic_guarantee": True + }, + "results": { "recovery_time": "12 minutes", "manual_comparison": "45 minutes", + "time_saved": "33 minutes (73%)", "cost_saved": f"${savings:,}", - "users_protected": "45,000", - "learning": "Pattern added to RAG memory" + "users_protected": 45000, + "services_restored": 12, + "error_rate_reduction": "94%", + "latency_improvement": "67%" }, - "safety_features": [ - "Rollback guarantee: 100%", - "Atomic execution", - "MCP validation", - "Resource isolation" - ], - "architectural_summary": f"This demonstrates real ARF Enterprise v{boundaries['enterprise']['version']} execution with commercial license." + "safety_features": { + "rollback_guarantee": "100%", + "mcp_validation": "passed", + "resource_isolation": "enforced", + "blast_radius": "2 services", + "dry_run_completed": True, + "safety_checks_passed": 8 + }, + "learning": { + "pattern_added_to_memory": True, + "similarity_score": 87, + "success_marked": True, + "next_improvement": "Optimize cache eviction policy" + }, + "enterprise_features": { + "autonomous_execution": True, + "mcp_integration": True, + "audit_trail": True, + "compliance_logging": True, + "multi_cloud_support": True + }, + "boundary_context": "Enterprise execution simulated. Real execution requires ARF Enterprise license.", + "arf_version": "3.3.9", + "enterprise_required": True, + "license_status": "simulated" # Changed from "required" to be more accurate } - else: - # Simulated Enterprise execution - enterprise_results = { - "demo_mode": "Enterprise Simulation", + + # Add approval-specific info + if approval_required: + execution_results["human_workflow"] = { + "step": "awaiting_approval", + "approver": "system_admin", + "timeout": "5 minutes", + "escalation_path": "senior_engineer" + } + + logger.info(f"โœ… Enterprise healing executed for {scenario_name}") + return execution_results + + except Exception as e: + logger.error(f"Error in enterprise execution: {e}") + return { + "status": "error", + "error": str(e), "scenario": scenario_name, - "arf_version": boundaries["enterprise"]["version"], - "true_enterprise_used": False, - "execution_mode": "simulated_autonomous", - "boundary_crossed": False, # Didn't really cross boundary - "mcp_integration": mcp_mode_value, - "execution_result": execution_result, - "outcome": { - "recovery_time": "12 minutes (simulated)", - "manual_comparison": "45 minutes", - "cost_saved": f"${savings:,} (simulated)", - "users_protected": "45,000 (simulated)", - "learning": "Pattern would be added to RAG memory" - }, - "safety_features": [ - "Rollback guarantee: 100% (simulated)", - "Atomic execution (simulated)", - "MCP validation (simulated)", - "Resource isolation (simulated)" - ], - "architectural_summary": f"This simulates ARF Enterprise execution. Requires commercial license for real execution.", - "boundary_indicator": BoundaryManager.create_boundary_indicator( - f"Autonomous healing for {scenario_name}", - is_simulated=True - ) + "timestamp": datetime.now().isoformat(), + "recommendation": "Enterprise license required for execution", + "contact": "sales@arf.dev" } - - # Get execution table - execution_table = get_audit_manager().get_execution_table() - - return approval_display, enterprise_results, execution_table # =========================================== -# ROI CALCULATION FUNCTION +# FIXED SCENARIO UPDATE FUNCTION # =========================================== -def calculate_roi(scenario_name, monthly_incidents, team_size): - """Calculate ROI with boundary context""" - components = get_components() - + +def update_scenario_display(scenario_name: str) -> Tuple[Any, go.Figure, go.Figure, go.Figure]: + """ + Update scenario display - returns Plotly figures, not HTML strings + FIXED: Returns tuple of (scenario_card_html, telemetry_fig, impact_fig, timeline_fig) + Note: First element is still HTML for the scenario card, but visualizations are Plotly figures + """ try: - # Try to use real ROI calculator - calculator = components["EnhancedROICalculator"] - roi_result = calculator.calculate_comprehensive_roi( - scenario_name=scenario_name, - monthly_incidents=monthly_incidents, - team_size=team_size - ) - except Exception as e: - logger.warning(f"ROI calculation failed, using mock: {e}") - # Mock ROI calculation - impact_per_incident = get_scenario_impact(scenario_name) - annual_impact = impact_per_incident * monthly_incidents * 12 - potential_savings = int(annual_impact * 0.82) - enterprise_cost = 625000 # Annual enterprise license - roi_multiplier = round(potential_savings / enterprise_cost, 1) - payback_months = round((enterprise_cost / (potential_savings / 12)), 1) - - roi_result = { - "status": "โœ… Calculated Successfully", - "summary": { - "your_annual_impact": f"${annual_impact:,}", - "potential_savings": f"${potential_savings:,}", - "enterprise_cost": f"${enterprise_cost:,}", - "roi_multiplier": f"{roi_multiplier}ร—", - "payback_months": f"{payback_months}", - "annual_roi_percentage": f"{int((potential_savings - enterprise_cost) / enterprise_cost * 100)}%", - "boundary_context": "Based on OSS analysis + simulated Enterprise execution" + # Get scenario data + scenarios = { + "Cache Miss Storm": { + "component": "Redis Cache Cluster", + "severity": "HIGH", + "business_impact": {"revenue_loss_per_hour": 8500}, + "metrics": {"affected_users": 45000} + }, + "Database Connection Pool Exhaustion": { + "component": "PostgreSQL Database", + "severity": "HIGH", + "business_impact": {"revenue_loss_per_hour": 4200}, + "metrics": {"affected_users": 28000} }, - "boundary_note": "ROI calculation includes OSS advisory value and simulated Enterprise execution benefits" + "Kubernetes Memory Leak": { + "component": "Kubernetes Worker Node", + "severity": "MEDIUM", + "business_impact": {"revenue_loss_per_hour": 5500}, + "metrics": {"affected_users": 32000} + } } - - # Create HTML output - roi_multiplier_val = extract_roi_multiplier(roi_result) - - roi_html = f""" -
-
-
๐Ÿ’ฐ
-

- ROI Analysis Complete -

-

- Scenario: {scenario_name} โ€ข {monthly_incidents} incidents/month โ€ข {team_size}-person team -

-
+ scenario = scenarios.get(scenario_name, { + "component": "Unknown System", + "severity": "MEDIUM", + "business_impact": {"revenue_loss_per_hour": 5000}, + "metrics": {"affected_users": 25000} + }) - -
-
-
- {roi_result['summary']['roi_multiplier']} -
-
- ROI Multiplier -
-
- -
-
- {roi_result['summary']['payback_months']}m -
-
- Payback Period -
-
- -
-
- {roi_result['summary']['annual_roi_percentage']} -
-
- Annual ROI -
-
-
+ # Create scenario card HTML (this is still HTML for the gr.HTML component) + severity_colors = { + "HIGH": "#ef4444", + "MEDIUM": "#f59e0b", + "LOW": "#10b981" + } + severity_color = severity_colors.get(scenario["severity"], "#64748b") - -
-
- Financial Impact Analysis -
+ scenario_card_html = f""" +
-
+
-
Annual Impact Without ARF
-
- {roi_result['summary']['your_annual_impact']} +

+ {scenario_name} +

+
+
+ {scenario["severity"]} SEVERITY +
+
+ {scenario["component"]} +
-
-
Potential Savings with ARF
-
- {roi_result['summary']['potential_savings']} +
+
+ ${scenario["business_impact"]["revenue_loss_per_hour"]:,} +
+
+ Revenue Loss/Hour
-
-
ARF Enterprise Annual Cost
-
- {roi_result['summary']['enterprise_cost']} + +
+
+ Business Impact Analysis
-
-
- - -
-
-
๐Ÿ—๏ธ
-
- Architecture Boundary Context +
+
+
45 min
+
Without ARF
+
+
+
12 min
+
With ARF
+
+
+
${int(scenario["business_impact"]["revenue_loss_per_hour"] * 0.85):,}
+
Savings/Hour
+
-

- ROI includes value from both OSS advisory analysis and Enterprise autonomous execution. - This demonstrates the complete ARF value proposition across the architectural boundary. -

+ + +
+ ARF Detection: Detected in 45s with 94% confidence. + {scenario["metrics"]["affected_users"]:,} users affected. +
+ """ + + # Get visualizations as Plotly figures + telemetry_fig = create_simple_telemetry_plot(scenario_name, DEMO_CONFIG["use_true_arf"]) + impact_fig = create_simple_impact_plot(scenario_name, DEMO_CONFIG["use_true_arf"]) + timeline_fig = create_timeline_plot(scenario_name, DEMO_CONFIG["use_true_arf"]) + + return scenario_card_html, telemetry_fig, impact_fig, timeline_fig - -
- Ready to realize these savings? - Contact sales for Enterprise license โ†’ + except Exception as e: + logger.error(f"Error updating scenario display: {e}") + # Return fallback values + error_html = f""" +
+

Error loading scenario

+

{str(e)}

-
+ """ + return error_html, create_empty_plot("Error"), create_empty_plot("Error"), create_empty_plot("Error") + +# =========================================== +# ADDITIONAL FIXED FUNCTIONS +# =========================================== + +def get_installation_status() -> Dict[str, Any]: """ + Get installation status - returns JSON/dict + FIXED: Returns dict for gr.JSON() component + """ + installation = { + "oss_installed": ARF_OSS_AVAILABLE, + "enterprise_installed": False, # Enterprise would require separate check + "oss_version": "3.3.9" if ARF_OSS_AVAILABLE else "not_installed", + "enterprise_version": "not_installed", + "execution_allowed": False, # OSS doesn't allow execution + "recommendations": [ + "OSS provides advisory analysis only", + "Enterprise required for autonomous execution" + ], + "badges": { + "oss": { + "text": "โœ… ARF OSS v3.3.9" if ARF_OSS_AVAILABLE else "โš ๏ธ Mock ARF", + "color": "#10b981" if ARF_OSS_AVAILABLE else "#f59e0b", + "icon": "โœ…" if ARF_OSS_AVAILABLE else "โš ๏ธ" + }, + "enterprise": { + "text": "๐Ÿ”’ Enterprise Required", + "color": "#64748b", + "icon": "๐Ÿ”’" + } + }, + "timestamp": datetime.now().isoformat(), + "components_available": ["TelemetryCollector", "ReliabilityAnalyzer", "AutoHealingEngine"] if ARF_OSS_AVAILABLE else ["simulated"], + "license": "Apache 2.0" if ARF_OSS_AVAILABLE else "demo" + } + return installation + +def get_installation_badges() -> str: + """ + Get installation badges as HTML + This is fine as it's used by gr.HTML() + """ + installation = get_installation_status() + oss_badge = installation["badges"]["oss"] + enterprise_badge = installation["badges"]["enterprise"] - # Create simple ROI chart - roi_chart = create_empty_plot("ROI Analysis Chart", True) - - return roi_html, roi_chart + return f""" +
+ + {oss_badge['icon']} {oss_badge['text']} + + + {enterprise_badge['icon']} {enterprise_badge['text']} + +
+ """ # =========================================== -# CREATE DEMO INTERFACE - FIXED VERSION +# ROI CALCULATION FUNCTION (Fixed) # =========================================== -def create_demo_interface(): - """Create demo interface using modular components with boundary awareness""" - - import gradio as gr - - # Get components - components = get_components() - - # Get CSS styles - css_styles = components["get_styles"]() - - # Store CSS for later use in launch() - global _demo_css - _demo_css = css_styles - - # Get boundary badges for the interface - boundary_badges = BoundaryManager.get_boundary_badges() - - # Create interface without css parameter (will be added in launch) - with gr.Blocks( - title=f"๐Ÿš€ ARF Investor Demo v3.8.0 - TRUE ARF v3.3.7" - ) as demo: - - # Header - header_html = components["create_header"]("3.3.7", settings.use_true_arf) - - # Status bar with boundary badges - status_html = components["create_status_bar"]() + +def calculate_roi(scenario_name: str, monthly_incidents: int, team_size: int) -> Tuple[Dict[str, Any], go.Figure]: + """ + Calculate ROI - returns dict and Plotly figure + FIXED: Returns (dict, Plotly figure) for (gr.JSON(), gr.Plot()) + """ + try: + # Calculate ROI based on inputs + impact_per_incident = { + "Cache Miss Storm": 8500, + "Database Connection Pool Exhaustion": 4200, + "Kubernetes Memory Leak": 5500, + "API Rate Limit Storm": 3800, + "Network Partition": 12000, + "Storage I/O Saturation": 6800 + }.get(scenario_name, 5000) + + # Calculations + annual_impact = impact_per_incident * monthly_incidents * 12 + potential_savings = int(annual_impact * 0.82) # ARF saves 82% + enterprise_cost = 625000 # Annual enterprise license + roi_multiplier = round(potential_savings / enterprise_cost, 1) + payback_months = round((enterprise_cost / (potential_savings / 12)), 1) + annual_roi = int((potential_savings - enterprise_cost) / enterprise_cost * 100) - # Add boundary badges as a separate element - boundary_display = gr.HTML(value=boundary_badges, visible=settings.show_boundaries) + # ROI results dict + roi_results = { + "status": "success", + "scenario": scenario_name, + "inputs": { + "monthly_incidents": monthly_incidents, + "team_size": team_size, + "impact_per_incident": f"${impact_per_incident:,}" + }, + "calculations": { + "annual_impact_without_arf": f"${annual_impact:,}", + "potential_savings_with_arf": f"${potential_savings:,}", + "enterprise_annual_cost": f"${enterprise_cost:,}", + "roi_multiplier": f"{roi_multiplier}ร—", + "payback_months": f"{payback_months}", + "annual_roi_percentage": f"{annual_roi}%", + "net_annual_savings": f"${potential_savings - enterprise_cost:,}" + }, + "breakdown": { + "engineer_cost_savings": f"${team_size * 200000 * 0.3:,}", # 30% engineer time saved + "incident_cost_savings": f"${potential_savings - (team_size * 200000 * 0.3):,}", + "total_opportunity": f"${potential_savings:,}" + }, + "recommendation": f"ARF Enterprise provides {roi_multiplier}ร— ROI with {payback_months}-month payback", + "timestamp": datetime.now().isoformat(), + "arf_version": "3.3.9" + } - # ============ 5 TABS ============ - with gr.Tabs(elem_classes="tab-nav"): - - # TAB 1: Live Incident Demo - with gr.TabItem("๐Ÿ”ฅ Live Incident Demo", id="tab1"): - (scenario_dropdown, scenario_card, telemetry_viz, impact_viz, - workflow_header, detection_agent, recall_agent, decision_agent, - oss_section, enterprise_section, oss_btn, enterprise_btn, - approval_toggle, mcp_mode, timeline_viz, - detection_time, mttr, auto_heal, savings, - oss_results_display, enterprise_results_display, approval_display, demo_btn) = components["create_tab1_incident_demo"]() - - # TAB 2: Business ROI - with gr.TabItem("๐Ÿ’ฐ Business Impact & ROI", id="tab2"): - (dashboard_output, roi_scenario_dropdown, monthly_slider, team_slider, - calculate_btn, roi_output, roi_chart) = components["create_tab2_business_roi"](components["INCIDENT_SCENARIOS"]) - - # TAB 3: Enterprise Features - with gr.TabItem("๐Ÿข Enterprise Features", id="tab3"): - (license_display, validate_btn, trial_btn, upgrade_btn, - mcp_mode_tab3, mcp_mode_info, features_table, integrations_table) = components["create_tab3_enterprise_features"]() - - # TAB 4: Audit Trail - with gr.TabItem("๐Ÿ“œ Audit Trail & History", id="tab4"): - (refresh_btn, clear_btn, export_btn, execution_table, - incident_table, export_text) = components["create_tab4_audit_trail"]() - - # TAB 5: Learning Engine - with gr.TabItem("๐Ÿง  Learning Engine", id="tab5"): - (learning_graph, graph_type, show_labels, search_query, search_btn, - clear_btn_search, search_results, stats_display, patterns_display, - performance_display) = components["create_tab5_learning_engine"]() + # Create ROI visualization + categories = ['Without ARF', 'With ARF', 'Net Savings'] + values = [annual_impact, annual_impact - potential_savings, potential_savings - enterprise_cost] + colors = ['#ef4444', '#10b981', '#8b5cf6'] + + fig = go.Figure(data=[ + go.Bar( + name='Annual Cost', + x=categories, + y=values, + marker_color=colors, + text=[f'${v:,.0f}' for v in values], + textposition='auto', + ) + ]) + + fig.update_layout( + title=dict( + text=f"ROI Analysis: {scenario_name}", + font=dict(size=18, color='#1e293b') + ), + xaxis_title="Scenario", + yaxis_title="Annual Cost ($)", + height=400, + plot_bgcolor='white', + showlegend=False, + margin=dict(l=20, r=20, t=60, b=20) + ) - # Footer - footer_html = components["create_footer"]() + # Add ROI multiplier annotation + fig.add_annotation( + x=2, y=values[2] * 1.1, + text=f"ROI: {roi_multiplier}ร—", + showarrow=False, + font=dict(size=14, color="#8b5cf6", weight="bold"), + bgcolor="rgba(139, 92, 246, 0.1)", + borderpad=4 + ) - # ============ EVENT HANDLERS ============ + logger.info(f"โœ… ROI calculated for {scenario_name}") + return roi_results, fig - # Update scenario display when dropdown changes - scenario_dropdown.change( - fn=update_scenario_display, - inputs=[scenario_dropdown], - outputs=[scenario_card, telemetry_viz, impact_viz, timeline_viz] - ) + except Exception as e: + logger.error(f"Error calculating ROI: {e}") + error_results = { + "status": "error", + "error": str(e), + "scenario": scenario_name, + "timestamp": datetime.now().isoformat() + } + return error_results, create_empty_plot("ROI Calculation Error") + +# =========================================== +# MAIN APPLICATION +# =========================================== + +def create_demo_interface(): + """Create the demo interface with fixed data types""" + with gr.Blocks(title="ARF OSS v3.3.9 Demo", theme=gr.themes.Soft()) as demo: + gr.Markdown("# ๐Ÿš€ ARF OSS v3.3.9 Demo") + gr.Markdown("### Agentic Reliability Framework - OSS Edition") - # Run OSS Analysis - oss_btn.click( - fn=run_true_arf_analysis, - inputs=[scenario_dropdown], - outputs=[ - detection_agent, recall_agent, decision_agent, - oss_results_display, incident_table - ] + # Installation status + installation = get_installation_status() + gr.Markdown(f"**Status:** {installation['badges']['oss']['text']}") + + # Scenario selection + scenario_dropdown = gr.Dropdown( + choices=[ + "Cache Miss Storm", + "Database Connection Pool Exhaustion", + "Kubernetes Memory Leak", + "API Rate Limit Storm", + "Network Partition", + "Storage I/O Saturation" + ], + value="Cache Miss Storm", + label="Select Scenario" ) - # Execute Enterprise Healing - enterprise_btn.click( - fn=execute_enterprise_healing, - inputs=[scenario_dropdown, approval_toggle, mcp_mode], - outputs=[approval_display, enterprise_results_display, execution_table] - ) + # Update button + update_btn = gr.Button("Update Display", variant="primary") - # Run Complete Demo with boundary progression - @AsyncRunner.async_to_sync - async def run_complete_demo_async(scenario_name): - """Run a complete demo walkthrough with true ARF and boundary awareness""" - # Step 1: Update scenario - update_result = update_scenario_display(scenario_name) - - # Step 2: Run true ARF analysis - oss_result = await run_true_arf_analysis(scenario_name) - - # Step 3: Execute Enterprise (simulation) with boundary context - await asyncio.sleep(1) - - scenario = components["INCIDENT_SCENARIOS"].get(scenario_name, {}) - impact = scenario.get("business_impact", {}) - revenue_loss = impact.get("revenue_loss_per_hour", get_scenario_impact(scenario_name)) - savings = int(revenue_loss * 0.85) + # Results area + with gr.Row(): + with gr.Column(scale=1): + scenario_card = gr.HTML(label="Scenario Details") - # Get boundary context - boundaries = BoundaryManager.get_system_boundaries() + with gr.Column(scale=2): + telemetry_plot = gr.Plot(label="Telemetry") + impact_plot = gr.Plot(label="Business Impact") + timeline_plot = gr.Plot(label="Timeline Comparison") + + # Analysis controls + with gr.Row(): + analyze_btn = gr.Button("๐Ÿ” Run OSS Analysis", variant="secondary") + execute_btn = gr.Button("โšก Execute Enterprise Healing", variant="primary") + + # Results displays + with gr.Row(): + with gr.Column(scale=1): + analysis_results = gr.JSON(label="OSS Analysis Results") - # Get orchestrator for execution simulation - orchestrator = components["DemoOrchestrator"]() - execution_result = await orchestrator.execute_healing(scenario_name, "autonomous") - - enterprise_results = { - "demo_mode": "Complete Walkthrough", - "scenario": scenario_name, - "arf_version": "3.3.7", - "true_oss_used": True, - "enterprise_simulated": True, - "boundary_progression": [ - f"1. Incident detected - {boundaries['oss']['label']}", - f"2. OSS analysis completed - {boundaries['oss']['label']}", - f"3. HealingIntent created - {boundaries['oss']['label']}", - f"4. Enterprise license validated ({boundaries['enterprise']['label']})", - f"5. Autonomous execution simulated ({boundaries['enterprise']['label']}+)", - f"6. Outcome recorded in RAG memory" + with gr.Column(scale=1): + execution_results = gr.JSON(label="Enterprise Execution Results") + + # ROI Calculator + gr.Markdown("## ๐Ÿ’ฐ ROI Calculator") + with gr.Row(): + roi_scenario = gr.Dropdown( + choices=[ + "Cache Miss Storm", + "Database Connection Pool Exhaustion", + "Kubernetes Memory Leak" ], - "execution_result": execution_result, - "outcome": { - "recovery_time": "12 minutes", - "manual_comparison": "45 minutes", - "cost_saved": f"${savings:,}", - "users_protected": "45,000", - "learning": "Pattern added to RAG memory" - }, - "architectural_summary": f"This demonstrates the complete ARF v3.3.7 architecture: {boundaries['oss']['label']} for advisory analysis โ†’ {boundaries['enterprise']['label']} for autonomous execution" - } - - # Create demo completion message with enhanced boundary context - demo_message = f""" -
- - -
-
-

- โœ… Complete Demo: Architecture Validated -

-

- ARF v3.3.7 โ€ข OSS advises โ†’ Enterprise executes -

-
-
- - BOUNDARY VALIDATED - -
-
- - -
- -
-
- - {boundaries['oss']['label']} -
-
- โ€ข Anomaly detected in 45s
- โ€ข 3 similar incidents recalled
- โ€ข 94% confidence healing plan
- โ€ข Apache 2.0 license validated -
-
- - -
-
- - {boundaries['enterprise']['label']} -
-
- โ€ข Autonomous execution simulated
- โ€ข Rollback guarantee: 100%
- โ€ข 12min vs 45min recovery
- โ€ข ${savings:,} saved -
-
-
- - -
-
- ๐Ÿ—๏ธ Architecture Flow -
-
- -
-
OSS Advisory
-
Apache 2.0
-
- - -
-
-
- advises -
-
- - -
-
Enterprise
-
Commercial
-
-
-
- - -
-
-
-
Time Saved
-
73%
-
-
-
Cost Saved
-
${savings:,}
-
-
-
ROI Multiplier
-
5.2ร—
-
-
-
- - -
-
-
โœ…
-
-
- Architecture Successfully Validated -
-
- Clear separation maintained: OSS for advisory intelligence, Enterprise for autonomous execution -
-
-
-
- - -
- Ready for production? - Install ARF Enterprise โ†’ -
-
- """ - - # IMPORTANT FIX: The demo_message should update approval_display, not create a new output - # Update the enterprise_results_display to include demo completion info - enterprise_results["demo_completion_message"] = demo_message - - # Get updated tables - incident_table_data = get_audit_manager().get_incident_table() - execution_table_data = get_audit_manager().get_execution_table() - - # Combine all results - FIXED OUTPUT COUNT - return ( - *update_result, # 4 outputs: scenario_card, telemetry_viz, impact_viz, timeline_viz - *oss_result[:3], # 3 outputs: detection_agent, recall_agent, decision_agent - oss_result[3], # 1 output: oss_results_display - enterprise_results, # 1 output: enterprise_results_display - demo_message, # 1 output: approval_display - incident_table_data, # 1 output: incident_table - execution_table_data # 1 output: execution_table - ) # TOTAL: 4 + 3 + 1 + 1 + 1 + 1 + 1 = 12 outputs (matches expectations) - - # FIXED: demo_btn.click with correct output count - demo_btn.click( - fn=run_complete_demo_async, - inputs=[scenario_dropdown], - outputs=[ - scenario_card, telemetry_viz, impact_viz, timeline_viz, # 4 - detection_agent, recall_agent, decision_agent, # 3 - oss_results_display, # 1 - enterprise_results_display, # 1 - approval_display, # 1 - incident_table, # 1 - execution_table # 1 - ] # TOTAL: 12 outputs - ) - - # ROI Calculation - calculate_btn.click( - fn=calculate_roi, - inputs=[roi_scenario_dropdown, monthly_slider, team_slider], - outputs=[roi_output, roi_chart] - ) - - # Update ROI scenario - roi_scenario_dropdown.change( - fn=lambda x: get_components()["EnhancedROICalculator"]().calculate_comprehensive_roi(), - inputs=[], - outputs=[roi_output] - ) - - # Update ROI chart - monthly_slider.change( - fn=lambda x, y: calculate_roi(roi_scenario_dropdown.value, x, y)[1], - inputs=[monthly_slider, team_slider], - outputs=[roi_chart] - ) - - team_slider.change( - fn=lambda x, y: calculate_roi(roi_scenario_dropdown.value, x, y)[1], - inputs=[monthly_slider, team_slider], - outputs=[roi_chart] - ) - - # Audit Trail Functions - def refresh_audit_trail(): - """Refresh audit trail tables""" - return ( - get_audit_manager().get_execution_table(), - get_audit_manager().get_incident_table() + value="Cache Miss Storm", + label="Scenario" ) + monthly_incidents = gr.Slider(1, 50, value=15, label="Monthly Incidents") + team_size = gr.Slider(1, 20, value=5, label="Team Size") - def clear_audit_trail(): - """Clear audit trail""" - get_audit_manager().clear() - return [], [] + roi_btn = gr.Button("Calculate ROI", variant="primary") - def export_audit_trail(): - """Export audit trail as JSON""" - audit_data = { - "executions": get_audit_manager().executions, - "incidents": get_audit_manager().incidents, - "boundary_crossings": get_audit_manager().boundary_crossings, - "export_time": datetime.datetime.now().isoformat(), - "arf_version": "3.3.7", - "architecture": "OSS advises โ†’ Enterprise executes" - } - return json.dumps(audit_data, indent=2) + with gr.Row(): + roi_output = gr.JSON(label="ROI Results") + roi_chart = gr.Plot(label="ROI Visualization") - refresh_btn.click( - fn=refresh_audit_trail, - inputs=[], - outputs=[execution_table, incident_table] - ) + # ===== Event Handlers ===== - clear_btn.click( - fn=clear_audit_trail, - inputs=[], - outputs=[execution_table, incident_table] + # Update scenario display + update_btn.click( + fn=update_scenario_display, + inputs=[scenario_dropdown], + outputs=[scenario_card, telemetry_plot, impact_plot, timeline_plot] ) - export_btn.click( - fn=export_audit_trail, - inputs=[], - outputs=[export_text] + scenario_dropdown.change( + fn=update_scenario_display, + inputs=[scenario_dropdown], + outputs=[scenario_card, telemetry_plot, impact_plot, timeline_plot] ) - # Enterprise Features - def validate_license(): - """Validate enterprise license with boundary context""" - boundaries = BoundaryManager.get_system_boundaries() - - if boundaries["enterprise"]["available"]: - return { - "status": "โœ… Valid License", - "license_type": "Enterprise", - "version": boundaries["enterprise"]["version"], - "expires": "2025-12-31", - "capabilities": boundaries["enterprise"]["capabilities"], - "boundary_context": f"Real {boundaries['enterprise']['label']} detected" - } - else: - return { - "status": "โš ๏ธ Demo Mode", - "license_type": "Simulated", - "version": boundaries["enterprise"]["version"], - "expires": "Demo only", - "capabilities": boundaries["enterprise"]["capabilities"], - "boundary_context": f"Simulating {boundaries['enterprise']['label']} - requires license", - "contact": "sales@arf.dev" - } - - validate_btn.click( - fn=validate_license, - inputs=[], - outputs=[license_display] + # Run OSS analysis + analyze_btn.click( + fn=run_true_arf_analysis, + inputs=[scenario_dropdown], + outputs=[analysis_results] ) - # Initialize with boundary badges - demo.load( - fn=lambda: boundary_badges, - inputs=[], - outputs=[boundary_display] + # Execute enterprise healing + execute_btn.click( + fn=execute_enterprise_healing, + inputs=[scenario_dropdown], + outputs=[execution_results] ) - # Load default scenario - demo.load( - fn=lambda: update_scenario_display(settings.default_scenario), - inputs=[], - outputs=[scenario_card, telemetry_viz, impact_viz, timeline_viz] + # Calculate ROI + roi_btn.click( + fn=calculate_roi, + inputs=[roi_scenario, monthly_incidents, team_size], + outputs=[roi_output, roi_chart] ) - # Load ROI data + # Initialize with default scenario demo.load( - fn=lambda: calculate_roi(settings.default_scenario, 15, 5), + fn=lambda: update_scenario_display("Cache Miss Storm"), inputs=[], - outputs=[roi_output, roi_chart] + outputs=[scenario_card, telemetry_plot, impact_plot, timeline_plot] ) - - logger.info("โœ… Demo interface created successfully with boundary awareness") return demo -# =========================================== -# LAUNCH FUNCTION -# =========================================== -def launch_demo(): - """Launch the demo application with proper configuration""" - try: - logger.info("๐Ÿš€ Starting ARF Ultimate Investor Demo v3.8.0 - ENTERPRISE EDITION") - - # Check installation - installation = get_installation_status() - boundaries = BoundaryManager.get_system_boundaries() - - logger.info("=" * 60) - logger.info("๐Ÿ—๏ธ SYSTEM ARCHITECTURE BOUNDARIES:") - logger.info(f" OSS: {boundaries['oss']['label']} v{boundaries['oss']['version']}") - logger.info(f" Enterprise: {boundaries['enterprise']['label']} v{boundaries['enterprise']['version']}") - logger.info(f" Mode: {boundaries['demo_mode']['architecture']}") - logger.info("=" * 60) - - # Create interface - demo = create_demo_interface() - - # Get CSS styles - components = get_components() - css_styles = components["get_styles"]() - - # Configure for Hugging Face Spaces - launch_config = { - "server_name": "0.0.0.0", - "server_port": 7860, - "share": False, - "favicon_path": None, - "quiet": False, - "show_error": True, - "debug": False, - "max_threads": 40, - } - - # Add CSS if available - if css_styles: - launch_config["css"] = css_styles - - logger.info("โœ… Launch configuration ready") - - return demo, launch_config - - except Exception as e: - logger.error(f"โŒ Launch failed: {e}", exc_info=True) - - # Create minimal fallback interface - import gradio as gr - - with gr.Blocks(title="ARF Demo - Fallback Mode") as fallback_demo: - gr.HTML(f""" -
-

๐Ÿšจ ARF Demo Failed to Start

-

Error: {str(e)}

-
-

Troubleshooting Steps:

-
    -
  1. Check logs for detailed error
  2. -
  3. Ensure all dependencies are installed
  4. -
  5. Try: pip install agentic-reliability-framework==3.3.7
  6. -
  7. Restart the application
  8. -
-
-
- """) - - return fallback_demo, {"server_name": "0.0.0.0", "server_port": 7860} +def main(): + """Main entry point""" + logger.info("=" * 60) + logger.info("๐Ÿš€ ARF OSS v3.3.9 Demo Application") + logger.info(f"โœ… ARF OSS Available: {ARF_OSS_AVAILABLE}") + logger.info("=" * 60) + + demo = create_demo_interface() + demo.launch( + server_name="0.0.0.0", + server_port=7860, + share=False + ) -# =========================================== -# MAIN EXECUTION -# =========================================== if __name__ == "__main__": - try: - logger.info("๐Ÿš€ ARF Ultimate Investor Demo v3.8.0 - ENTERPRISE EDITION") - logger.info("=" * 60) - logger.info("Enhanced version with clear boundaries and reliable visualizations") - logger.info("Fixed to show clear OSS vs Enterprise boundaries with architectural honesty") - logger.info("=" * 60) - - # Launch the demo - demo, config = launch_demo() - - print("\n" + "="*60) - print("๐Ÿš€ ARF Ultimate Investor Demo v3.8.0 - ENTERPRISE EDITION") - print("๐Ÿ“Š Architecture: OSS advises โ†’ Enterprise executes") - print("๐ŸŒ Starting on http://localhost:7860") - print("="*60 + "\n") - - # Launch with error handling - try: - demo.launch(**config) - except Exception as launch_error: - logger.error(f"โŒ Launch error: {launch_error}") - - # Try alternative launch without CSS - if "css" in config: - logger.info("โš ๏ธ Retrying without CSS...") - config.pop("css", None) - demo.launch(**config) - else: - # Last resort: simple launch - demo.launch(server_name="0.0.0.0", server_port=7860) - - except KeyboardInterrupt: - logger.info("๐Ÿ‘‹ Demo stopped by user") - except Exception as e: - logger.error(f"โŒ Fatal error: {e}", exc_info=True) - sys.exit(1) \ No newline at end of file + main() \ No newline at end of file