petter2025 commited on
Commit
fc65cce
Β·
verified Β·
1 Parent(s): 3fcbb60

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +427 -311
app.py CHANGED
@@ -32,108 +32,6 @@ logger = logging.getLogger(__name__)
32
  # Add parent directory to path
33
  sys.path.insert(0, str(Path(__file__).parent))
34
 
35
- # ===========================================
36
- # ARF INSTALLATION CHECK SYSTEM - NEW
37
- # ===========================================
38
- def check_arf_installation():
39
- """
40
- Check if real ARF packages are installed
41
- Returns detailed installation status
42
- """
43
- results = {
44
- "oss_installed": False,
45
- "enterprise_installed": False,
46
- "oss_version": None,
47
- "enterprise_version": None,
48
- "oss_edition": "unknown",
49
- "oss_license": "unknown",
50
- "execution_allowed": False,
51
- "recommendations": [],
52
- "badges": {
53
- "oss": {"text": "⚠️ Mock ARF", "color": "#f59e0b", "icon": "⚠️"},
54
- "enterprise": {"text": "πŸ”’ Enterprise Required", "color": "#64748b", "icon": "πŸ”’"}
55
- },
56
- "timestamp": datetime.datetime.now().isoformat()
57
- }
58
-
59
- # Check OSS package
60
- try:
61
- import agentic_reliability_framework as arf_oss
62
- results["oss_installed"] = True
63
- results["oss_version"] = getattr(arf_oss, '__version__', '3.3.7')
64
-
65
- # Try to get more info
66
- try:
67
- results["oss_edition"] = arf_oss.OSS_EDITION
68
- results["oss_license"] = arf_oss.OSS_LICENSE
69
- results["execution_allowed"] = arf_oss.EXECUTION_ALLOWED
70
- except Exception as e:
71
- logger.debug(f"Could not get OSS details: {e}")
72
-
73
- results["badges"]["oss"] = {
74
- "text": f"βœ… ARF OSS v{results['oss_version']}",
75
- "color": "#10b981",
76
- "icon": "βœ…"
77
- }
78
-
79
- logger.info(f"βœ… ARF OSS v{results['oss_version']} detected")
80
-
81
- except ImportError as e:
82
- results["recommendations"].append(
83
- "Install real ARF OSS: `pip install agentic-reliability-framework==3.3.7`"
84
- )
85
- logger.info("⚠️ ARF OSS not installed - using mock mode")
86
-
87
- # Check Enterprise package
88
- try:
89
- import arf_enterprise
90
- results["enterprise_installed"] = True
91
- results["enterprise_version"] = getattr(arf_enterprise, '__version__', '1.0.2')
92
- results["badges"]["enterprise"] = {
93
- "text": f"πŸš€ Enterprise v{results['enterprise_version']}",
94
- "color": "#8b5cf6",
95
- "icon": "πŸš€"
96
- }
97
- logger.info(f"βœ… ARF Enterprise v{results['enterprise_version']} detected")
98
- except ImportError as e:
99
- results["recommendations"].append(
100
- "Install ARF Enterprise: `pip install agentic-reliability-enterprise` (requires license)"
101
- )
102
- logger.info("⚠️ ARF Enterprise not installed - using simulation")
103
-
104
- return results
105
-
106
- # Global installation status cache
107
- _installation_status = None
108
-
109
- def get_installation_status():
110
- """Get cached installation status"""
111
- global _installation_status
112
- if _installation_status is None:
113
- _installation_status = check_arf_installation()
114
- return _installation_status
115
-
116
- def get_installation_badges():
117
- """Get formatted badge HTML for UI"""
118
- installation = get_installation_status()
119
- oss_badge = installation["badges"]["oss"]
120
- enterprise_badge = installation["badges"]["enterprise"]
121
-
122
- return f"""
123
- <div style="display: flex; justify-content: center; gap: 10px; margin-top: 10px; flex-wrap: wrap;">
124
- <span style="padding: 4px 12px; background: {oss_badge['color']};
125
- color: white; border-radius: 20px; font-size: 12px; font-weight: bold;
126
- display: flex; align-items: center; gap: 6px;">
127
- {oss_badge['icon']} {oss_badge['text']}
128
- </span>
129
- <span style="padding: 4px 12px; background: {enterprise_badge['color']};
130
- color: white; border-radius: 20px; font-size: 12px; font-weight: bold;
131
- display: flex; align-items: center; gap: 6px;">
132
- {enterprise_badge['icon']} {enterprise_badge['text']}
133
- </span>
134
- </div>
135
- """
136
-
137
  # ===========================================
138
  # ASYNC UTILITIES - ENHANCED VERSION
139
  # ===========================================
@@ -169,16 +67,38 @@ class AsyncRunner:
169
  return wrapper
170
 
171
  # ===========================================
172
- # SIMPLE SETTINGS
173
  # ===========================================
174
  class Settings:
175
- """Simple settings class"""
176
  def __init__(self):
177
  self.arf_mode = "demo"
178
  self.use_true_arf = True # Use true ARF integration
179
  self.default_scenario = "Cache Miss Storm"
180
  self.max_history_items = 100
181
  self.auto_refresh_seconds = 30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
 
183
  settings = Settings()
184
 
@@ -187,43 +107,50 @@ settings = Settings()
187
  # ===========================================
188
  def create_empty_plot(title: str):
189
  """Create an empty placeholder plot"""
190
- import plotly.graph_objects as go
191
- fig = go.Figure()
192
- fig.add_annotation(
193
- text="πŸ‘† Select a scenario<br>to view data",
194
- xref="paper", yref="paper",
195
- x=0.5, y=0.5, showarrow=False,
196
- font=dict(size=14, color="#64748b")
197
- )
198
- fig.update_layout(
199
- height=300,
200
- title=title,
201
- paper_bgcolor="rgba(0,0,0,0)",
202
- plot_bgcolor="rgba(0,0,0,0)",
203
- xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
204
- yaxis=dict(showgrid=False, zeroline=False, showticklabels=False)
205
- )
206
- return fig
 
 
 
 
207
 
208
  def create_empty_dashboard():
209
  """Create empty dashboard"""
210
- import plotly.graph_objects as go
211
- fig = go.Figure()
212
- fig.add_annotation(
213
- text="πŸ“Š Dashboard will populate<br>after ROI calculation",
214
- xref="paper", yref="paper",
215
- x=0.5, y=0.5, showarrow=False,
216
- font=dict(size=16, color="#64748b")
217
- )
218
- fig.update_layout(
219
- height=700,
220
- paper_bgcolor="rgba(0,0,0,0)",
221
- plot_bgcolor="rgba(0,0,0,0)",
222
- xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
223
- yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
224
- title=""
225
- )
226
- return fig
 
 
 
227
 
228
  def get_inactive_agent_html(agent_name: str, description: str):
229
  """Get HTML for inactive agent state"""
@@ -248,77 +175,275 @@ def get_inactive_agent_html(agent_name: str, description: str):
248
  """
249
 
250
  # ===========================================
251
- # IMPORT MODULAR COMPONENTS - UPDATED FOR TRUE ARF
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  # ===========================================
253
  def import_components() -> Dict[str, Any]:
254
- """Safely import all components with proper error handling"""
255
  components = {
256
  "all_available": False,
257
- "error": None
 
 
258
  }
259
 
260
  try:
 
 
261
  # First, import gradio (always available in Hugging Face Spaces)
262
- import gradio as gr
263
- components["gr"] = gr
 
 
 
 
 
264
 
265
- # Import scenarios
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
  try:
267
  from demo.scenarios import INCIDENT_SCENARIOS
268
- logger.info(f"Loaded {len(INCIDENT_SCENARIOS)} scenarios from demo module")
269
  components["INCIDENT_SCENARIOS"] = INCIDENT_SCENARIOS
 
270
  except ImportError as e:
271
- logger.warning(f"Demo scenarios not available: {e}")
272
- # Create minimal fallback
273
- components["INCIDENT_SCENARIOS"] = {
274
- "Cache Miss Storm": {
275
- "component": "Redis Cache Cluster",
276
- "severity": "HIGH",
277
- "impact_radius": "85% of users",
278
- "business_impact": {"revenue_loss_per_hour": 8500},
279
- "detection_time": "45 seconds",
280
- "tags": ["cache", "redis", "latency"],
281
- "metrics": {"affected_users": 45000}
282
- }
283
- }
284
 
285
- # Use TrueARF337Orchestrator for true ARF integration
286
  try:
287
  from core.true_arf_orchestrator import TrueARF337Orchestrator
288
  components["DemoOrchestrator"] = TrueARF337Orchestrator
289
  logger.info("βœ… Using TrueARF337Orchestrator with real v3.3.7 integration")
290
  except ImportError as e:
291
- logger.warning(f"TrueARF337Orchestrator not available: {e}")
292
- # Fall back to old implementation
293
  try:
294
  from core.real_arf_integration import RealARFIntegration
295
  components["DemoOrchestrator"] = RealARFIntegration
296
- logger.info("⚠️ Falling back to RealARFIntegration")
297
  except ImportError as e2:
298
- logger.error(f"RealARFIntegration also not available: {e2}")
299
  # Create a minimal mock orchestrator
300
  class MockOrchestrator:
301
  async def analyze_incident(self, scenario_name, scenario_data):
302
  return {
303
- "status": "error",
304
- "error": "No orchestrator available",
305
- "scenario": scenario_name
306
  }
307
  async def execute_healing(self, scenario_name, mode="autonomous"):
308
  return {
309
- "status": "error",
310
- "error": "No orchestrator available",
311
- "scenario": scenario_name
312
  }
313
  components["DemoOrchestrator"] = MockOrchestrator
 
314
 
315
- # Import ROI calculator
316
  try:
317
- from core.calculators import EnhancedROICalculator
318
- components["EnhancedROICalculator"] = EnhancedROICalculator()
319
- logger.info("EnhancedROICalculator imported successfully")
 
 
 
 
 
 
320
  except ImportError as e:
321
- logger.warning(f"EnhancedROICalculator not available: {e}")
322
  class MockCalculator:
323
  def calculate_comprehensive_roi(self, **kwargs):
324
  return {
@@ -333,14 +458,19 @@ def import_components() -> Dict[str, Any]:
333
  }
334
  }
335
  components["EnhancedROICalculator"] = MockCalculator()
 
336
 
337
- # Import visualizations
338
  try:
339
- from core.visualizations import EnhancedVisualizationEngine
340
- components["EnhancedVisualizationEngine"] = EnhancedVisualizationEngine()
341
- logger.info("EnhancedVisualizationEngine imported successfully")
 
 
 
 
342
  except ImportError as e:
343
- logger.warning(f"EnhancedVisualizationEngine not available: {e}")
344
  class MockVisualizationEngine:
345
  def create_executive_dashboard(self, data=None):
346
  return create_empty_dashboard()
@@ -354,57 +484,25 @@ def import_components() -> Dict[str, Any]:
354
  def create_timeline_comparison(self):
355
  return create_empty_plot("Timeline Comparison")
356
  components["EnhancedVisualizationEngine"] = MockVisualizationEngine()
357
-
358
- # Import UI components
359
- try:
360
- from ui.components import (
361
- create_header, create_status_bar, create_tab1_incident_demo,
362
- create_tab2_business_roi, create_tab3_enterprise_features,
363
- create_tab4_audit_trail, create_tab5_learning_engine,
364
- create_footer
365
- )
366
- components.update({
367
- "create_header": create_header,
368
- "create_status_bar": create_status_bar,
369
- "create_tab1_incident_demo": create_tab1_incident_demo,
370
- "create_tab2_business_roi": create_tab2_business_roi,
371
- "create_tab3_enterprise_features": create_tab3_enterprise_features,
372
- "create_tab4_audit_trail": create_tab4_audit_trail,
373
- "create_tab5_learning_engine": create_tab5_learning_engine,
374
- "create_footer": create_footer,
375
- })
376
- logger.info("UI components imported successfully")
377
- except ImportError as e:
378
- logger.error(f"UI components not available: {e}")
379
- # Create minimal UI fallbacks
380
- components.update({
381
- "create_header": lambda version="3.3.7", mock=False: gr.HTML(f"<h2>πŸš€ ARF v{version} TRUE</h2>"),
382
- "create_status_bar": lambda: gr.HTML("<div>Status</div>"),
383
- "create_tab1_incident_demo": lambda *args: [gr.Dropdown()] * 24,
384
- "create_tab2_business_roi": lambda *args: [gr.Plot()] * 7,
385
- "create_tab3_enterprise_features": lambda: [gr.JSON()] * 8,
386
- "create_tab4_audit_trail": lambda: [gr.Button()] * 6,
387
- "create_tab5_learning_engine": lambda: [gr.Plot()] * 10,
388
- "create_footer": lambda: gr.HTML("<footer>ARF v3.3.7</footer>"),
389
- })
390
-
391
- # Import styles
392
- try:
393
- from ui.styles import get_styles
394
- components["get_styles"] = get_styles
395
- except ImportError as e:
396
- logger.warning(f"Styles not available: {e}")
397
- components["get_styles"] = lambda: ""
398
 
399
  components["all_available"] = True
400
  components["error"] = None
401
- logger.info("βœ… Successfully imported all modular components with True ARF")
402
 
403
  except Exception as e:
404
  logger.error(f"❌ CRITICAL IMPORT ERROR: {e}")
405
  logger.error(traceback.format_exc())
406
  components["error"] = str(e)
407
  components["all_available"] = False
 
 
 
 
 
 
 
 
408
 
409
  return components
410
 
@@ -534,7 +632,10 @@ def create_telemetry_plot(scenario_name: str):
534
  """Create a telemetry visualization for the selected scenario"""
535
  try:
536
  viz_engine = get_components()["EnhancedVisualizationEngine"]
537
- return viz_engine.create_telemetry_plot(scenario_name, anomaly_detected=True)
 
 
 
538
  except Exception as e:
539
  logger.error(f"Failed to create telemetry plot: {e}")
540
  return create_empty_plot(f"Telemetry: {scenario_name}")
@@ -543,7 +644,10 @@ def create_impact_plot(scenario_name: str):
543
  """Create a business impact visualization"""
544
  try:
545
  viz_engine = get_components()["EnhancedVisualizationEngine"]
546
- return viz_engine.create_impact_gauge(scenario_name)
 
 
 
547
  except Exception as e:
548
  logger.error(f"Failed to create impact plot: {e}")
549
  return create_empty_plot(f"Impact: {scenario_name}")
@@ -552,7 +656,10 @@ def create_timeline_plot(scenario_name: str):
552
  """Create an incident timeline visualization"""
553
  try:
554
  viz_engine = get_components()["EnhancedVisualizationEngine"]
555
- return viz_engine.create_timeline_comparison()
 
 
 
556
  except Exception as e:
557
  logger.error(f"Failed to create timeline plot: {e}")
558
  return create_empty_plot("Timeline Comparison")
@@ -630,8 +737,9 @@ async def run_true_arf_analysis(scenario_name: str):
630
  installation = get_installation_status()
631
  real_arf_available = installation["oss_installed"]
632
 
633
- # Use TrueARF337Orchestrator if available
634
- orchestrator = get_components()["DemoOrchestrator"]()
 
635
  analysis = await orchestrator.analyze_incident(scenario_name, scenario)
636
 
637
  # Check for errors
@@ -646,8 +754,6 @@ async def run_true_arf_analysis(scenario_name: str):
646
  incident_table_data = get_audit_manager().get_incident_table()
647
 
648
  # Extract values from analysis
649
- demo_display = analysis.get("demo_display", {})
650
- real_arf_version = demo_display.get("real_arf_version", "mock")
651
  true_oss_used = analysis.get("true_oss_used", False)
652
  enterprise_simulated = analysis.get("enterprise_simulated", False)
653
 
@@ -770,7 +876,7 @@ async def run_true_arf_analysis(scenario_name: str):
770
  is_real_arf=true_oss_used
771
  )
772
 
773
- logger.info(f"Analysis completed successfully for {scenario_name} (True ARF: {real_arf_version})")
774
  return (
775
  detection_html, recall_html, decision_html,
776
  oss_results, incident_table_data
@@ -845,9 +951,10 @@ def create_agent_html(agent_name: str, status: str, metrics: str, is_real_arf: b
845
  # ===========================================
846
  def execute_enterprise_healing(scenario_name, approval_required, mcp_mode_value):
847
  """Execute enterprise healing with true ARF simulation"""
848
- import gradio as gr
 
849
 
850
- scenario = get_components()["INCIDENT_SCENARIOS"].get(scenario_name, {})
851
 
852
  # Determine mode
853
  mode = "Approval" if approval_required else "Autonomous"
@@ -895,7 +1002,7 @@ def execute_enterprise_healing(scenario_name, approval_required, mcp_mode_value)
895
  get_audit_manager().add_execution(scenario_name, mode, savings=savings)
896
 
897
  # Get orchestrator for execution simulation
898
- orchestrator = get_components()["DemoOrchestrator"]()
899
 
900
  # Create approval display
901
  if approval_required:
@@ -1077,16 +1184,76 @@ def execute_enterprise_healing(scenario_name, approval_required, mcp_mode_value)
1077
 
1078
  return gr.HTML.update(value=approval_html), enterprise_results, execution_table_data
1079
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1080
  # ===========================================
1081
  # CREATE DEMO INTERFACE
1082
  # ===========================================
1083
  def create_demo_interface():
1084
  """Create demo interface using modular components"""
1085
 
1086
- import gradio as gr
 
 
 
 
 
 
1087
 
1088
  # Get CSS styles
1089
- css_styles = get_components()["get_styles"]()
1090
 
1091
  with gr.Blocks(
1092
  title=f"πŸš€ ARF Investor Demo v3.8.0 - TRUE ARF v3.3.7",
@@ -1094,10 +1261,10 @@ def create_demo_interface():
1094
  ) as demo:
1095
 
1096
  # Header - Updated to show true ARF version
1097
- header_html = get_components()["create_header"]("3.3.7", settings.use_true_arf)
1098
 
1099
  # Status bar
1100
- status_html = get_components()["create_status_bar"]()
1101
 
1102
  # ============ 5 TABS ============
1103
  with gr.Tabs(elem_classes="tab-nav"):
@@ -1109,31 +1276,31 @@ def create_demo_interface():
1109
  oss_section, enterprise_section, oss_btn, enterprise_btn,
1110
  approval_toggle, mcp_mode, timeline_viz,
1111
  detection_time, mttr, auto_heal, savings,
1112
- oss_results_display, enterprise_results_display, approval_display, demo_btn) = get_components()["create_tab1_incident_demo"]()
1113
 
1114
  # TAB 2: Business ROI
1115
  with gr.TabItem("πŸ’° Business Impact & ROI", id="tab2"):
1116
  (dashboard_output, roi_scenario_dropdown, monthly_slider, team_slider,
1117
- calculate_btn, roi_output, roi_chart) = get_components()["create_tab2_business_roi"](get_components()["INCIDENT_SCENARIOS"])
1118
 
1119
  # TAB 3: Enterprise Features
1120
  with gr.TabItem("🏒 Enterprise Features", id="tab3"):
1121
  (license_display, validate_btn, trial_btn, upgrade_btn,
1122
- mcp_mode_tab3, mcp_mode_info, features_table, integrations_table) = get_components()["create_tab3_enterprise_features"]()
1123
 
1124
  # TAB 4: Audit Trail
1125
  with gr.TabItem("πŸ“œ Audit Trail & History", id="tab4"):
1126
  (refresh_btn, clear_btn, export_btn, execution_table,
1127
- incident_table, export_text) = get_components()["create_tab4_audit_trail"]()
1128
 
1129
  # TAB 5: Learning Engine
1130
  with gr.TabItem("🧠 Learning Engine", id="tab5"):
1131
  (learning_graph, graph_type, show_labels, search_query, search_btn,
1132
  clear_btn_search, search_results, stats_display, patterns_display,
1133
- performance_display) = get_components()["create_tab5_learning_engine"]()
1134
 
1135
  # Footer
1136
- footer_html = get_components()["create_footer"]()
1137
 
1138
  # ============ EVENT HANDLERS ============
1139
 
@@ -1174,13 +1341,13 @@ def create_demo_interface():
1174
  # Step 3: Execute Enterprise (simulation)
1175
  await asyncio.sleep(1)
1176
 
1177
- scenario = get_components()["INCIDENT_SCENARIOS"].get(scenario_name, {})
1178
  impact = scenario.get("business_impact", {})
1179
  revenue_loss = impact.get("revenue_loss_per_hour", get_scenario_impact(scenario_name))
1180
  savings = int(revenue_loss * 0.85)
1181
 
1182
  # Get orchestrator for execution simulation
1183
- orchestrator = get_components()["DemoOrchestrator"]()
1184
  execution_result = await orchestrator.execute_healing(scenario_name, "autonomous")
1185
 
1186
  enterprise_results = {
@@ -1251,58 +1418,6 @@ def create_demo_interface():
1251
  )
1252
 
1253
  # ============ TAB 2 HANDLERS ============
1254
-
1255
- def calculate_roi(scenario_name, monthly_incidents, team_size):
1256
- """Calculate ROI"""
1257
- try:
1258
- logger.info(f"Calculating ROI for {scenario_name}")
1259
-
1260
- # Validate inputs
1261
- monthly_incidents = int(monthly_incidents) if monthly_incidents else 15
1262
- team_size = int(team_size) if team_size else 5
1263
-
1264
- # Get scenario-specific impact
1265
- avg_impact = get_scenario_impact(scenario_name)
1266
-
1267
- # Calculate ROI
1268
- roi_calculator = get_components()["EnhancedROICalculator"]
1269
- roi_result = roi_calculator.calculate_comprehensive_roi(
1270
- monthly_incidents=monthly_incidents,
1271
- avg_impact=float(avg_impact),
1272
- team_size=team_size
1273
- )
1274
-
1275
- # Extract ROI multiplier for visualization
1276
- roi_multiplier = extract_roi_multiplier(roi_result)
1277
-
1278
- # Create visualization
1279
- viz_engine = get_components()["EnhancedVisualizationEngine"]
1280
- chart = viz_engine.create_executive_dashboard({"roi_multiplier": roi_multiplier})
1281
-
1282
- return roi_result, chart
1283
-
1284
- except Exception as e:
1285
- logger.error(f"ROI calculation error: {e}")
1286
-
1287
- # Provide fallback results
1288
- fallback_result = {
1289
- "status": "βœ… Calculated Successfully",
1290
- "summary": {
1291
- "your_annual_impact": "$1,530,000",
1292
- "potential_savings": "$1,254,600",
1293
- "enterprise_cost": "$625,000",
1294
- "roi_multiplier": "5.2Γ—",
1295
- "payback_months": "6.0",
1296
- "annual_roi_percentage": "420%"
1297
- }
1298
- }
1299
-
1300
- # Always return a valid chart
1301
- viz_engine = get_components()["EnhancedVisualizationEngine"]
1302
- fallback_chart = viz_engine.create_executive_dashboard({"roi_multiplier": 5.2})
1303
-
1304
- return fallback_result, fallback_chart
1305
-
1306
  calculate_btn.click(
1307
  fn=calculate_roi,
1308
  inputs=[roi_scenario_dropdown, monthly_slider, team_slider],
@@ -1310,7 +1425,6 @@ def create_demo_interface():
1310
  )
1311
 
1312
  # ============ TAB 3 HANDLERS ============
1313
-
1314
  def validate_license():
1315
  installation = get_installation_status()
1316
  return {
@@ -1391,7 +1505,6 @@ def create_demo_interface():
1391
  )
1392
 
1393
  # ============ TAB 4 HANDLERS ============
1394
-
1395
  def refresh_audit_trail():
1396
  return get_audit_manager().get_execution_table(), get_audit_manager().get_incident_table()
1397
 
@@ -1478,8 +1591,8 @@ def main():
1478
  # Check installation status first
1479
  installation = get_installation_status()
1480
  print(f"πŸ“¦ Package Status:")
1481
- print(f" β€’ ARF OSS: {'βœ… v' + installation['oss_version'] if installation['oss_installed'] else '⚠️ Not installed'}")
1482
- print(f" β€’ Enterprise: {'βœ… v' + installation['enterprise_version'] if installation['enterprise_installed'] else '⚠️ Not installed'}")
1483
  print(f" β€’ Execution Allowed: {'βœ… Yes' if installation['execution_allowed'] else '❌ No (OSS only)'}")
1484
 
1485
  print(f"πŸ“Š Mode: {settings.arf_mode.upper()}")
@@ -1494,18 +1607,21 @@ def main():
1494
  print(f" β€’ {rec}")
1495
  print("=" * 70)
1496
 
1497
- import gradio as gr
1498
-
1499
  # Create and launch demo
1500
- demo = create_demo_interface()
1501
-
1502
- # Hugging Face Spaces compatible launch
1503
- demo.launch(
1504
- server_name="0.0.0.0",
1505
- server_port=7860,
1506
- share=False,
1507
- show_error=True # Show errors in UI
1508
- )
 
 
 
 
 
1509
 
1510
 
1511
  # Hugging Face Spaces entry point
 
32
  # Add parent directory to path
33
  sys.path.insert(0, str(Path(__file__).parent))
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  # ===========================================
36
  # ASYNC UTILITIES - ENHANCED VERSION
37
  # ===========================================
 
67
  return wrapper
68
 
69
  # ===========================================
70
+ # SIMPLE SETTINGS - AVOID PYDANTIC ISSUES
71
  # ===========================================
72
  class Settings:
73
+ """Simple settings class that avoids pydantic issues"""
74
  def __init__(self):
75
  self.arf_mode = "demo"
76
  self.use_true_arf = True # Use true ARF integration
77
  self.default_scenario = "Cache Miss Storm"
78
  self.max_history_items = 100
79
  self.auto_refresh_seconds = 30
80
+
81
+ # Check for real ARF packages
82
+ self.oss_installed = False
83
+ self.enterprise_installed = False
84
+ self.oss_version = None
85
+ self.enterprise_version = None
86
+
87
+ try:
88
+ import agentic_reliability_framework as arf_oss
89
+ self.oss_installed = True
90
+ self.oss_version = getattr(arf_oss, '__version__', '3.3.7')
91
+ logger.info(f"βœ… ARF OSS v{self.oss_version} detected")
92
+ except ImportError:
93
+ logger.info("⚠️ ARF OSS not installed - using mock mode")
94
+
95
+ try:
96
+ import arf_enterprise
97
+ self.enterprise_installed = True
98
+ self.enterprise_version = getattr(arf_enterprise, '__version__', '1.0.2')
99
+ logger.info(f"βœ… ARF Enterprise v{self.enterprise_version} detected")
100
+ except ImportError:
101
+ logger.info("⚠️ ARF Enterprise not installed - using simulation")
102
 
103
  settings = Settings()
104
 
 
107
  # ===========================================
108
  def create_empty_plot(title: str):
109
  """Create an empty placeholder plot"""
110
+ try:
111
+ import plotly.graph_objects as go
112
+ fig = go.Figure()
113
+ fig.add_annotation(
114
+ text="πŸ‘† Select a scenario<br>to view data",
115
+ xref="paper", yref="paper",
116
+ x=0.5, y=0.5, showarrow=False,
117
+ font=dict(size=14, color="#64748b")
118
+ )
119
+ fig.update_layout(
120
+ height=300,
121
+ title=title,
122
+ paper_bgcolor="rgba(0,0,0,0)",
123
+ plot_bgcolor="rgba(0,0,0,0)",
124
+ xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
125
+ yaxis=dict(showgrid=False, zeroline=False, showticklabels=False)
126
+ )
127
+ return fig
128
+ except ImportError:
129
+ # Return None if plotly not available
130
+ return None
131
 
132
  def create_empty_dashboard():
133
  """Create empty dashboard"""
134
+ try:
135
+ import plotly.graph_objects as go
136
+ fig = go.Figure()
137
+ fig.add_annotation(
138
+ text="πŸ“Š Dashboard will populate<br>after ROI calculation",
139
+ xref="paper", yref="paper",
140
+ x=0.5, y=0.5, showarrow=False,
141
+ font=dict(size=16, color="#64748b")
142
+ )
143
+ fig.update_layout(
144
+ height=700,
145
+ paper_bgcolor="rgba(0,0,0,0)",
146
+ plot_bgcolor="rgba(0,0,0,0)",
147
+ xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
148
+ yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
149
+ title=""
150
+ )
151
+ return fig
152
+ except ImportError:
153
+ return None
154
 
155
  def get_inactive_agent_html(agent_name: str, description: str):
156
  """Get HTML for inactive agent state"""
 
175
  """
176
 
177
  # ===========================================
178
+ # ARF INSTALLATION CHECK SYSTEM - NEW
179
+ # ===========================================
180
+ def check_arf_installation():
181
+ """
182
+ Check if real ARF packages are installed
183
+ Returns detailed installation status
184
+ """
185
+ results = {
186
+ "oss_installed": settings.oss_installed,
187
+ "enterprise_installed": settings.enterprise_installed,
188
+ "oss_version": settings.oss_version,
189
+ "enterprise_version": settings.enterprise_version,
190
+ "oss_edition": "unknown",
191
+ "oss_license": "unknown",
192
+ "execution_allowed": False,
193
+ "recommendations": [],
194
+ "badges": {
195
+ "oss": {"text": "⚠️ Mock ARF", "color": "#f59e0b", "icon": "⚠️"},
196
+ "enterprise": {"text": "πŸ”’ Enterprise Required", "color": "#64748b", "icon": "πŸ”’"}
197
+ },
198
+ "timestamp": datetime.datetime.now().isoformat()
199
+ }
200
+
201
+ # Check OSS package
202
+ if settings.oss_installed:
203
+ results["badges"]["oss"] = {
204
+ "text": f"βœ… ARF OSS v{settings.oss_version}",
205
+ "color": "#10b981",
206
+ "icon": "βœ…"
207
+ }
208
+
209
+ # Try to get more info
210
+ try:
211
+ import agentic_reliability_framework as arf_oss
212
+ results["oss_edition"] = getattr(arf_oss, 'OSS_EDITION', 'oss')
213
+ results["oss_license"] = getattr(arf_oss, 'OSS_LICENSE', 'Apache 2.0')
214
+ results["execution_allowed"] = getattr(arf_oss, 'EXECUTION_ALLOWED', False)
215
+ except Exception as e:
216
+ logger.debug(f"Could not get OSS details: {e}")
217
+ else:
218
+ results["recommendations"].append(
219
+ "Install real ARF OSS: `pip install agentic-reliability-framework==3.3.7`"
220
+ )
221
+
222
+ # Check Enterprise package
223
+ if settings.enterprise_installed:
224
+ results["badges"]["enterprise"] = {
225
+ "text": f"πŸš€ Enterprise v{settings.enterprise_version}",
226
+ "color": "#8b5cf6",
227
+ "icon": "πŸš€"
228
+ }
229
+ else:
230
+ results["recommendations"].append(
231
+ "Install ARF Enterprise: `pip install agentic-reliability-enterprise` (requires license)"
232
+ )
233
+
234
+ return results
235
+
236
+ # Global installation status cache
237
+ _installation_status = None
238
+
239
+ def get_installation_status():
240
+ """Get cached installation status"""
241
+ global _installation_status
242
+ if _installation_status is None:
243
+ _installation_status = check_arf_installation()
244
+ return _installation_status
245
+
246
+ def get_installation_badges():
247
+ """Get formatted badge HTML for UI"""
248
+ installation = get_installation_status()
249
+ oss_badge = installation["badges"]["oss"]
250
+ enterprise_badge = installation["badges"]["enterprise"]
251
+
252
+ return f"""
253
+ <div style="display: flex; justify-content: center; gap: 10px; margin-top: 10px; flex-wrap: wrap;">
254
+ <span style="padding: 4px 12px; background: {oss_badge['color']};
255
+ color: white; border-radius: 20px; font-size: 12px; font-weight: bold;
256
+ display: flex; align-items: center; gap: 6px;">
257
+ {oss_badge['icon']} {oss_badge['text']}
258
+ </span>
259
+ <span style="padding: 4px 12px; background: {enterprise_badge['color']};
260
+ color: white; border-radius: 20px; font-size: 12px; font-weight: bold;
261
+ display: flex; align-items: center; gap: 6px;">
262
+ {enterprise_badge['icon']} {enterprise_badge['text']}
263
+ </span>
264
+ </div>
265
+ """
266
+
267
+ # ===========================================
268
+ # SCENARIO DATA (Fallback if scenarios module fails)
269
+ # ===========================================
270
+ FALLBACK_SCENARIOS = {
271
+ "Cache Miss Storm": {
272
+ "component": "Redis Cache Cluster",
273
+ "severity": "HIGH",
274
+ "impact_radius": "85% of users",
275
+ "business_impact": {"revenue_loss_per_hour": 8500},
276
+ "detection_time": "45 seconds",
277
+ "tags": ["cache", "redis", "latency"],
278
+ "metrics": {"affected_users": 45000}
279
+ },
280
+ "Database Connection Pool Exhaustion": {
281
+ "component": "PostgreSQL Connection Pool",
282
+ "severity": "HIGH",
283
+ "impact_radius": "Database queries",
284
+ "business_impact": {"revenue_loss_per_hour": 4200},
285
+ "detection_time": "30 seconds",
286
+ "tags": ["database", "connections", "exhaustion"],
287
+ "metrics": {"affected_queries": 12000}
288
+ },
289
+ "Kubernetes Memory Leak": {
290
+ "component": "K8s Pod Memory",
291
+ "severity": "MEDIUM",
292
+ "impact_radius": "Node failure",
293
+ "business_impact": {"revenue_loss_per_hour": 5500},
294
+ "detection_time": "60 seconds",
295
+ "tags": ["kubernetes", "memory", "leak"],
296
+ "metrics": {"affected_pods": 15}
297
+ },
298
+ "API Rate Limit Storm": {
299
+ "component": "API Gateway",
300
+ "severity": "MEDIUM",
301
+ "impact_radius": "API consumers",
302
+ "business_impact": {"revenue_loss_per_hour": 3800},
303
+ "detection_time": "25 seconds",
304
+ "tags": ["api", "rate_limit", "throttling"],
305
+ "metrics": {"affected_apis": 45}
306
+ },
307
+ "Network Partition": {
308
+ "component": "Network Layer",
309
+ "severity": "CRITICAL",
310
+ "impact_radius": "Availability zones",
311
+ "business_impact": {"revenue_loss_per_hour": 12000},
312
+ "detection_time": "90 seconds",
313
+ "tags": ["network", "partition", "availability"],
314
+ "metrics": {"affected_zones": 2}
315
+ },
316
+ "Storage I/O Saturation": {
317
+ "component": "Storage System",
318
+ "severity": "HIGH",
319
+ "impact_radius": "File operations",
320
+ "business_impact": {"revenue_loss_per_hour": 6800},
321
+ "detection_time": "40 seconds",
322
+ "tags": ["storage", "io", "saturation"],
323
+ "metrics": {"affected_operations": 25000}
324
+ }
325
+ }
326
+
327
+ # ===========================================
328
+ # IMPORT MODULAR COMPONENTS - FIXED VERSION
329
  # ===========================================
330
  def import_components() -> Dict[str, Any]:
331
+ """Safely import all components with proper error handling - FIXED"""
332
  components = {
333
  "all_available": False,
334
+ "error": None,
335
+ "get_styles": lambda: "", # Default empty styles
336
+ "INCIDENT_SCENARIOS": FALLBACK_SCENARIOS # Default scenarios
337
  }
338
 
339
  try:
340
+ logger.info("Starting component import...")
341
+
342
  # First, import gradio (always available in Hugging Face Spaces)
343
+ try:
344
+ import gradio as gr
345
+ components["gr"] = gr
346
+ logger.info("βœ… Gradio imported successfully")
347
+ except ImportError as e:
348
+ logger.error(f"❌ Gradio not available: {e}")
349
+ raise ImportError("Gradio is required but not available")
350
 
351
+ # Import UI styles FIRST (to avoid circular dependencies)
352
+ try:
353
+ from ui.styles import get_styles
354
+ components["get_styles"] = get_styles
355
+ logger.info("βœ… UI styles imported successfully")
356
+ except ImportError as e:
357
+ logger.warning(f"⚠️ UI styles not available: {e}")
358
+ # Use empty styles as fallback
359
+ components["get_styles"] = lambda: ""
360
+
361
+ # Import UI components
362
+ try:
363
+ from ui.components import (
364
+ create_header, create_status_bar, create_tab1_incident_demo,
365
+ create_tab2_business_roi, create_tab3_enterprise_features,
366
+ create_tab4_audit_trail, create_tab5_learning_engine,
367
+ create_footer
368
+ )
369
+ components.update({
370
+ "create_header": create_header,
371
+ "create_status_bar": create_status_bar,
372
+ "create_tab1_incident_demo": create_tab1_incident_demo,
373
+ "create_tab2_business_roi": create_tab2_business_roi,
374
+ "create_tab3_enterprise_features": create_tab3_enterprise_features,
375
+ "create_tab4_audit_trail": create_tab4_audit_trail,
376
+ "create_tab5_learning_engine": create_tab5_learning_engine,
377
+ "create_footer": create_footer,
378
+ })
379
+ logger.info("βœ… UI components imported successfully")
380
+ except ImportError as e:
381
+ logger.error(f"❌ UI components not available: {e}")
382
+ # Create minimal UI fallbacks
383
+ components.update({
384
+ "create_header": lambda version="3.3.7", mock=False: gr.HTML(f"<h2>πŸš€ ARF v{version} Demo</h2>"),
385
+ "create_status_bar": lambda: gr.HTML("<div>Status Bar</div>"),
386
+ "create_tab1_incident_demo": lambda *args: [gr.Dropdown()] * 24,
387
+ "create_tab2_business_roi": lambda *args: [gr.Plot()] * 7,
388
+ "create_tab3_enterprise_features": lambda: [gr.JSON()] * 8,
389
+ "create_tab4_audit_trail": lambda: [gr.Button()] * 6,
390
+ "create_tab5_learning_engine": lambda: [gr.Plot()] * 10,
391
+ "create_footer": lambda: gr.HTML("<footer>ARF v3.3.7</footer>"),
392
+ })
393
+
394
+ # Try to import scenarios (but don't fail if it doesn't work)
395
  try:
396
  from demo.scenarios import INCIDENT_SCENARIOS
 
397
  components["INCIDENT_SCENARIOS"] = INCIDENT_SCENARIOS
398
+ logger.info(f"βœ… Loaded {len(INCIDENT_SCENARIOS)} scenarios from demo module")
399
  except ImportError as e:
400
+ logger.warning(f"⚠️ Demo scenarios not available: {e}, using fallback scenarios")
401
+ components["INCIDENT_SCENARIOS"] = FALLBACK_SCENARIOS
 
 
 
 
 
 
 
 
 
 
 
402
 
403
+ # Try to import TrueARF337Orchestrator
404
  try:
405
  from core.true_arf_orchestrator import TrueARF337Orchestrator
406
  components["DemoOrchestrator"] = TrueARF337Orchestrator
407
  logger.info("βœ… Using TrueARF337Orchestrator with real v3.3.7 integration")
408
  except ImportError as e:
409
+ logger.warning(f"⚠️ TrueARF337Orchestrator not available: {e}")
410
+ # Fall back to real ARF integration
411
  try:
412
  from core.real_arf_integration import RealARFIntegration
413
  components["DemoOrchestrator"] = RealARFIntegration
414
+ logger.info("βœ… Falling back to RealARFIntegration")
415
  except ImportError as e2:
416
+ logger.warning(f"⚠️ RealARFIntegration also not available: {e2}")
417
  # Create a minimal mock orchestrator
418
  class MockOrchestrator:
419
  async def analyze_incident(self, scenario_name, scenario_data):
420
  return {
421
+ "status": "mock",
422
+ "scenario": scenario_name,
423
+ "message": "Mock analysis (no real ARF available)"
424
  }
425
  async def execute_healing(self, scenario_name, mode="autonomous"):
426
  return {
427
+ "status": "mock",
428
+ "scenario": scenario_name,
429
+ "message": "Mock execution (no real ARF available)"
430
  }
431
  components["DemoOrchestrator"] = MockOrchestrator
432
+ logger.info("⚠️ Using mock orchestrator")
433
 
434
+ # Try to import ROI calculator (but don't let it crash)
435
  try:
436
+ # First, try to import without triggering settings
437
+ import importlib.util
438
+ spec = importlib.util.find_spec("core.calculators")
439
+ if spec is not None:
440
+ from core.calculators import EnhancedROICalculator
441
+ components["EnhancedROICalculator"] = EnhancedROICalculator()
442
+ logger.info("βœ… EnhancedROICalculator imported successfully")
443
+ else:
444
+ raise ImportError("core.calculators module not found")
445
  except ImportError as e:
446
+ logger.warning(f"⚠️ EnhancedROICalculator not available: {e}")
447
  class MockCalculator:
448
  def calculate_comprehensive_roi(self, **kwargs):
449
  return {
 
458
  }
459
  }
460
  components["EnhancedROICalculator"] = MockCalculator()
461
+ logger.info("⚠️ Using mock ROI calculator")
462
 
463
+ # Try to import visualization engine (but don't let it crash)
464
  try:
465
+ spec = importlib.util.find_spec("core.visualizations")
466
+ if spec is not None:
467
+ from core.visualizations import EnhancedVisualizationEngine
468
+ components["EnhancedVisualizationEngine"] = EnhancedVisualizationEngine()
469
+ logger.info("βœ… EnhancedVisualizationEngine imported successfully")
470
+ else:
471
+ raise ImportError("core.visualizations module not found")
472
  except ImportError as e:
473
+ logger.warning(f"⚠️ EnhancedVisualizationEngine not available: {e}")
474
  class MockVisualizationEngine:
475
  def create_executive_dashboard(self, data=None):
476
  return create_empty_dashboard()
 
484
  def create_timeline_comparison(self):
485
  return create_empty_plot("Timeline Comparison")
486
  components["EnhancedVisualizationEngine"] = MockVisualizationEngine()
487
+ logger.info("⚠️ Using mock visualization engine")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488
 
489
  components["all_available"] = True
490
  components["error"] = None
491
+ logger.info("βœ… Successfully imported all modular components")
492
 
493
  except Exception as e:
494
  logger.error(f"❌ CRITICAL IMPORT ERROR: {e}")
495
  logger.error(traceback.format_exc())
496
  components["error"] = str(e)
497
  components["all_available"] = False
498
+
499
+ # Ensure we have minimal components
500
+ if "gr" not in components:
501
+ try:
502
+ import gradio as gr
503
+ components["gr"] = gr
504
+ except:
505
+ pass
506
 
507
  return components
508
 
 
632
  """Create a telemetry visualization for the selected scenario"""
633
  try:
634
  viz_engine = get_components()["EnhancedVisualizationEngine"]
635
+ plot = viz_engine.create_telemetry_plot(scenario_name, anomaly_detected=True)
636
+ if plot is None:
637
+ return create_empty_plot(f"Telemetry: {scenario_name}")
638
+ return plot
639
  except Exception as e:
640
  logger.error(f"Failed to create telemetry plot: {e}")
641
  return create_empty_plot(f"Telemetry: {scenario_name}")
 
644
  """Create a business impact visualization"""
645
  try:
646
  viz_engine = get_components()["EnhancedVisualizationEngine"]
647
+ plot = viz_engine.create_impact_gauge(scenario_name)
648
+ if plot is None:
649
+ return create_empty_plot(f"Impact: {scenario_name}")
650
+ return plot
651
  except Exception as e:
652
  logger.error(f"Failed to create impact plot: {e}")
653
  return create_empty_plot(f"Impact: {scenario_name}")
 
656
  """Create an incident timeline visualization"""
657
  try:
658
  viz_engine = get_components()["EnhancedVisualizationEngine"]
659
+ plot = viz_engine.create_timeline_comparison()
660
+ if plot is None:
661
+ return create_empty_plot("Timeline Comparison")
662
+ return plot
663
  except Exception as e:
664
  logger.error(f"Failed to create timeline plot: {e}")
665
  return create_empty_plot("Timeline Comparison")
 
737
  installation = get_installation_status()
738
  real_arf_available = installation["oss_installed"]
739
 
740
+ # Use orchestrator for analysis
741
+ orchestrator_class = get_components()["DemoOrchestrator"]
742
+ orchestrator = orchestrator_class()
743
  analysis = await orchestrator.analyze_incident(scenario_name, scenario)
744
 
745
  # Check for errors
 
754
  incident_table_data = get_audit_manager().get_incident_table()
755
 
756
  # Extract values from analysis
 
 
757
  true_oss_used = analysis.get("true_oss_used", False)
758
  enterprise_simulated = analysis.get("enterprise_simulated", False)
759
 
 
876
  is_real_arf=true_oss_used
877
  )
878
 
879
+ logger.info(f"Analysis completed successfully for {scenario_name}")
880
  return (
881
  detection_html, recall_html, decision_html,
882
  oss_results, incident_table_data
 
951
  # ===========================================
952
  def execute_enterprise_healing(scenario_name, approval_required, mcp_mode_value):
953
  """Execute enterprise healing with true ARF simulation"""
954
+ components = get_components()
955
+ gr = components["gr"]
956
 
957
+ scenario = components["INCIDENT_SCENARIOS"].get(scenario_name, {})
958
 
959
  # Determine mode
960
  mode = "Approval" if approval_required else "Autonomous"
 
1002
  get_audit_manager().add_execution(scenario_name, mode, savings=savings)
1003
 
1004
  # Get orchestrator for execution simulation
1005
+ orchestrator = components["DemoOrchestrator"]()
1006
 
1007
  # Create approval display
1008
  if approval_required:
 
1184
 
1185
  return gr.HTML.update(value=approval_html), enterprise_results, execution_table_data
1186
 
1187
+ # ===========================================
1188
+ # ROI CALCULATION FUNCTION
1189
+ # ===========================================
1190
+ def calculate_roi(scenario_name, monthly_incidents, team_size):
1191
+ """Calculate ROI"""
1192
+ try:
1193
+ logger.info(f"Calculating ROI for {scenario_name}")
1194
+
1195
+ # Validate inputs
1196
+ monthly_incidents = int(monthly_incidents) if monthly_incidents else 15
1197
+ team_size = int(team_size) if team_size else 5
1198
+
1199
+ # Get scenario-specific impact
1200
+ avg_impact = get_scenario_impact(scenario_name)
1201
+
1202
+ # Calculate ROI
1203
+ roi_calculator = get_components()["EnhancedROICalculator"]
1204
+ roi_result = roi_calculator.calculate_comprehensive_roi(
1205
+ monthly_incidents=monthly_incidents,
1206
+ avg_impact=float(avg_impact),
1207
+ team_size=team_size
1208
+ )
1209
+
1210
+ # Extract ROI multiplier for visualization
1211
+ roi_multiplier = extract_roi_multiplier(roi_result)
1212
+
1213
+ # Create visualization
1214
+ viz_engine = get_components()["EnhancedVisualizationEngine"]
1215
+ chart = viz_engine.create_executive_dashboard({"roi_multiplier": roi_multiplier})
1216
+
1217
+ return roi_result, chart
1218
+
1219
+ except Exception as e:
1220
+ logger.error(f"ROI calculation error: {e}")
1221
+
1222
+ # Provide fallback results
1223
+ fallback_result = {
1224
+ "status": "βœ… Calculated Successfully",
1225
+ "summary": {
1226
+ "your_annual_impact": "$1,530,000",
1227
+ "potential_savings": "$1,254,600",
1228
+ "enterprise_cost": "$625,000",
1229
+ "roi_multiplier": "5.2Γ—",
1230
+ "payback_months": "6.0",
1231
+ "annual_roi_percentage": "420%"
1232
+ }
1233
+ }
1234
+
1235
+ # Always return a valid chart
1236
+ viz_engine = get_components()["EnhancedVisualizationEngine"]
1237
+ fallback_chart = viz_engine.create_executive_dashboard({"roi_multiplier": 5.2})
1238
+
1239
+ return fallback_result, fallback_chart
1240
+
1241
  # ===========================================
1242
  # CREATE DEMO INTERFACE
1243
  # ===========================================
1244
  def create_demo_interface():
1245
  """Create demo interface using modular components"""
1246
 
1247
+ # Get components
1248
+ components = get_components()
1249
+ if "gr" not in components:
1250
+ logger.error("❌ Gradio not available - cannot create interface")
1251
+ raise ImportError("Gradio is required but not available")
1252
+
1253
+ gr = components["gr"]
1254
 
1255
  # Get CSS styles
1256
+ css_styles = components["get_styles"]()
1257
 
1258
  with gr.Blocks(
1259
  title=f"πŸš€ ARF Investor Demo v3.8.0 - TRUE ARF v3.3.7",
 
1261
  ) as demo:
1262
 
1263
  # Header - Updated to show true ARF version
1264
+ header_html = components["create_header"]("3.3.7", settings.use_true_arf)
1265
 
1266
  # Status bar
1267
+ status_html = components["create_status_bar"]()
1268
 
1269
  # ============ 5 TABS ============
1270
  with gr.Tabs(elem_classes="tab-nav"):
 
1276
  oss_section, enterprise_section, oss_btn, enterprise_btn,
1277
  approval_toggle, mcp_mode, timeline_viz,
1278
  detection_time, mttr, auto_heal, savings,
1279
+ oss_results_display, enterprise_results_display, approval_display, demo_btn) = components["create_tab1_incident_demo"]()
1280
 
1281
  # TAB 2: Business ROI
1282
  with gr.TabItem("πŸ’° Business Impact & ROI", id="tab2"):
1283
  (dashboard_output, roi_scenario_dropdown, monthly_slider, team_slider,
1284
+ calculate_btn, roi_output, roi_chart) = components["create_tab2_business_roi"](components["INCIDENT_SCENARIOS"])
1285
 
1286
  # TAB 3: Enterprise Features
1287
  with gr.TabItem("🏒 Enterprise Features", id="tab3"):
1288
  (license_display, validate_btn, trial_btn, upgrade_btn,
1289
+ mcp_mode_tab3, mcp_mode_info, features_table, integrations_table) = components["create_tab3_enterprise_features"]()
1290
 
1291
  # TAB 4: Audit Trail
1292
  with gr.TabItem("πŸ“œ Audit Trail & History", id="tab4"):
1293
  (refresh_btn, clear_btn, export_btn, execution_table,
1294
+ incident_table, export_text) = components["create_tab4_audit_trail"]()
1295
 
1296
  # TAB 5: Learning Engine
1297
  with gr.TabItem("🧠 Learning Engine", id="tab5"):
1298
  (learning_graph, graph_type, show_labels, search_query, search_btn,
1299
  clear_btn_search, search_results, stats_display, patterns_display,
1300
+ performance_display) = components["create_tab5_learning_engine"]()
1301
 
1302
  # Footer
1303
+ footer_html = components["create_footer"]()
1304
 
1305
  # ============ EVENT HANDLERS ============
1306
 
 
1341
  # Step 3: Execute Enterprise (simulation)
1342
  await asyncio.sleep(1)
1343
 
1344
+ scenario = components["INCIDENT_SCENARIOS"].get(scenario_name, {})
1345
  impact = scenario.get("business_impact", {})
1346
  revenue_loss = impact.get("revenue_loss_per_hour", get_scenario_impact(scenario_name))
1347
  savings = int(revenue_loss * 0.85)
1348
 
1349
  # Get orchestrator for execution simulation
1350
+ orchestrator = components["DemoOrchestrator"]()
1351
  execution_result = await orchestrator.execute_healing(scenario_name, "autonomous")
1352
 
1353
  enterprise_results = {
 
1418
  )
1419
 
1420
  # ============ TAB 2 HANDLERS ============
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1421
  calculate_btn.click(
1422
  fn=calculate_roi,
1423
  inputs=[roi_scenario_dropdown, monthly_slider, team_slider],
 
1425
  )
1426
 
1427
  # ============ TAB 3 HANDLERS ============
 
1428
  def validate_license():
1429
  installation = get_installation_status()
1430
  return {
 
1505
  )
1506
 
1507
  # ============ TAB 4 HANDLERS ============
 
1508
  def refresh_audit_trail():
1509
  return get_audit_manager().get_execution_table(), get_audit_manager().get_incident_table()
1510
 
 
1591
  # Check installation status first
1592
  installation = get_installation_status()
1593
  print(f"πŸ“¦ Package Status:")
1594
+ print(f" β€’ ARF OSS: {'βœ… v' + str(installation['oss_version']) if installation['oss_installed'] else '⚠️ Not installed'}")
1595
+ print(f" β€’ Enterprise: {'βœ… v' + str(installation['enterprise_version']) if installation['enterprise_installed'] else '⚠️ Not installed'}")
1596
  print(f" β€’ Execution Allowed: {'βœ… Yes' if installation['execution_allowed'] else '❌ No (OSS only)'}")
1597
 
1598
  print(f"πŸ“Š Mode: {settings.arf_mode.upper()}")
 
1607
  print(f" β€’ {rec}")
1608
  print("=" * 70)
1609
 
 
 
1610
  # Create and launch demo
1611
+ try:
1612
+ demo = create_demo_interface()
1613
+
1614
+ # Hugging Face Spaces compatible launch
1615
+ demo.launch(
1616
+ server_name="0.0.0.0",
1617
+ server_port=7860,
1618
+ share=False,
1619
+ show_error=True # Show errors in UI
1620
+ )
1621
+ except Exception as e:
1622
+ logger.error(f"❌ Failed to launch demo: {e}")
1623
+ logger.error(traceback.format_exc())
1624
+ raise
1625
 
1626
 
1627
  # Hugging Face Spaces entry point