petter2025 commited on
Commit
bf68103
·
verified ·
1 Parent(s): 409be37

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +269 -320
app.py CHANGED
@@ -3,6 +3,7 @@
3
  MODULAR VERSION - Properly integrated with all components
4
  ULTIMATE FIXED VERSION with all critical issues resolved
5
  NOW WITH TRUE ARF v3.3.7 INTEGRATION AND DYNAMIC SCENARIO METRICS
 
6
  """
7
 
8
  import logging
@@ -32,6 +33,108 @@ logger = logging.getLogger(__name__)
32
  # Add parent directory to path
33
  sys.path.insert(0, str(Path(__file__).parent))
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  # ===========================================
36
  # ASYNC UTILITIES - ENHANCED VERSION
37
  # ===========================================
@@ -67,38 +170,16 @@ class AsyncRunner:
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,50 +188,43 @@ settings = Settings()
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,157 +249,7 @@ def get_inactive_agent_html(agent_name: str, description: str):
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"""
@@ -333,7 +257,6 @@ def import_components() -> Dict[str, Any]:
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:
@@ -358,8 +281,22 @@ def import_components() -> Dict[str, Any]:
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,
@@ -391,14 +328,25 @@ def import_components() -> Dict[str, Any]:
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:
@@ -433,7 +381,6 @@ def import_components() -> Dict[str, Any]:
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:
@@ -503,6 +450,16 @@ def import_components() -> Dict[str, Any]:
503
  components["gr"] = gr
504
  except:
505
  pass
 
 
 
 
 
 
 
 
 
 
506
 
507
  return components
508
 
@@ -632,10 +589,7 @@ def create_telemetry_plot(scenario_name: str):
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,10 +598,7 @@ def create_impact_plot(scenario_name: str):
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,10 +607,7 @@ def create_timeline_plot(scenario_name: str):
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,9 +685,8 @@ async def run_true_arf_analysis(scenario_name: str):
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,6 +701,8 @@ async def run_true_arf_analysis(scenario_name: str):
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,7 +825,7 @@ async def run_true_arf_analysis(scenario_name: str):
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,10 +900,9 @@ def create_agent_html(agent_name: str, status: str, metrics: str, is_real_arf: b
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,7 +950,7 @@ def execute_enterprise_healing(scenario_name, approval_required, mcp_mode_value)
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:
@@ -1185,79 +1133,26 @@ def execute_enterprise_healing(scenario_name, approval_required, mcp_mode_value)
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",
1260
- css=css_styles
1261
  ) as demo:
1262
 
1263
  # Header - Updated to show true ARF version
@@ -1418,6 +1313,58 @@ def create_demo_interface():
1418
  )
1419
 
1420
  # ============ TAB 2 HANDLERS ============
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1421
  calculate_btn.click(
1422
  fn=calculate_roi,
1423
  inputs=[roi_scenario_dropdown, monthly_slider, team_slider],
@@ -1425,6 +1372,7 @@ def create_demo_interface():
1425
  )
1426
 
1427
  # ============ TAB 3 HANDLERS ============
 
1428
  def validate_license():
1429
  installation = get_installation_status()
1430
  return {
@@ -1505,6 +1453,7 @@ def create_demo_interface():
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
 
@@ -1579,6 +1528,8 @@ def create_demo_interface():
1579
 
1580
  return demo
1581
 
 
 
1582
 
1583
  # ===========================================
1584
  # MAIN EXECUTION - HUGGING FACE COMPATIBLE
@@ -1591,8 +1542,8 @@ def main():
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,21 +1558,19 @@ def main():
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
 
3
  MODULAR VERSION - Properly integrated with all components
4
  ULTIMATE FIXED VERSION with all critical issues resolved
5
  NOW WITH TRUE ARF v3.3.7 INTEGRATION AND DYNAMIC SCENARIO METRICS
6
+ FIXED VERSION: Added scenario_config_path and fixed get_styles
7
  """
8
 
9
  import logging
 
33
  # Add parent directory to path
34
  sys.path.insert(0, str(Path(__file__).parent))
35
 
36
+ # ===========================================
37
+ # ARF INSTALLATION CHECK SYSTEM - NEW
38
+ # ===========================================
39
+ def check_arf_installation():
40
+ """
41
+ Check if real ARF packages are installed
42
+ Returns detailed installation status
43
+ """
44
+ results = {
45
+ "oss_installed": False,
46
+ "enterprise_installed": False,
47
+ "oss_version": None,
48
+ "enterprise_version": None,
49
+ "oss_edition": "unknown",
50
+ "oss_license": "unknown",
51
+ "execution_allowed": False,
52
+ "recommendations": [],
53
+ "badges": {
54
+ "oss": {"text": "⚠️ Mock ARF", "color": "#f59e0b", "icon": "⚠️"},
55
+ "enterprise": {"text": "🔒 Enterprise Required", "color": "#64748b", "icon": "🔒"}
56
+ },
57
+ "timestamp": datetime.datetime.now().isoformat()
58
+ }
59
+
60
+ # Check OSS package
61
+ try:
62
+ import agentic_reliability_framework as arf_oss
63
+ results["oss_installed"] = True
64
+ results["oss_version"] = getattr(arf_oss, '__version__', '3.3.7')
65
+
66
+ # Try to get more info
67
+ try:
68
+ results["oss_edition"] = arf_oss.OSS_EDITION
69
+ results["oss_license"] = arf_oss.OSS_LICENSE
70
+ results["execution_allowed"] = arf_oss.EXECUTION_ALLOWED
71
+ except Exception as e:
72
+ logger.debug(f"Could not get OSS details: {e}")
73
+
74
+ results["badges"]["oss"] = {
75
+ "text": f"✅ ARF OSS v{results['oss_version']}",
76
+ "color": "#10b981",
77
+ "icon": "✅"
78
+ }
79
+
80
+ logger.info(f"✅ ARF OSS v{results['oss_version']} detected")
81
+
82
+ except ImportError as e:
83
+ results["recommendations"].append(
84
+ "Install real ARF OSS: `pip install agentic-reliability-framework==3.3.7`"
85
+ )
86
+ logger.info("⚠️ ARF OSS not installed - using mock mode")
87
+
88
+ # Check Enterprise package
89
+ try:
90
+ import arf_enterprise
91
+ results["enterprise_installed"] = True
92
+ results["enterprise_version"] = getattr(arf_enterprise, '__version__', '1.0.2')
93
+ results["badges"]["enterprise"] = {
94
+ "text": f"🚀 Enterprise v{results['enterprise_version']}",
95
+ "color": "#8b5cf6",
96
+ "icon": "🚀"
97
+ }
98
+ logger.info(f"✅ ARF Enterprise v{results['enterprise_version']} detected")
99
+ except ImportError as e:
100
+ results["recommendations"].append(
101
+ "Install ARF Enterprise: `pip install agentic-reliability-enterprise` (requires license)"
102
+ )
103
+ logger.info("⚠️ ARF Enterprise not installed - using simulation")
104
+
105
+ return results
106
+
107
+ # Global installation status cache
108
+ _installation_status = None
109
+
110
+ def get_installation_status():
111
+ """Get cached installation status"""
112
+ global _installation_status
113
+ if _installation_status is None:
114
+ _installation_status = check_arf_installation()
115
+ return _installation_status
116
+
117
+ def get_installation_badges():
118
+ """Get formatted badge HTML for UI"""
119
+ installation = get_installation_status()
120
+ oss_badge = installation["badges"]["oss"]
121
+ enterprise_badge = installation["badges"]["enterprise"]
122
+
123
+ return f"""
124
+ <div style="display: flex; justify-content: center; gap: 10px; margin-top: 10px; flex-wrap: wrap;">
125
+ <span style="padding: 4px 12px; background: {oss_badge['color']};
126
+ color: white; border-radius: 20px; font-size: 12px; font-weight: bold;
127
+ display: flex; align-items: center; gap: 6px;">
128
+ {oss_badge['icon']} {oss_badge['text']}
129
+ </span>
130
+ <span style="padding: 4px 12px; background: {enterprise_badge['color']};
131
+ color: white; border-radius: 20px; font-size: 12px; font-weight: bold;
132
+ display: flex; align-items: center; gap: 6px;">
133
+ {enterprise_badge['icon']} {enterprise_badge['text']}
134
+ </span>
135
+ </div>
136
+ """
137
+
138
  # ===========================================
139
  # ASYNC UTILITIES - ENHANCED VERSION
140
  # ===========================================
 
170
  return wrapper
171
 
172
  # ===========================================
173
+ # SIMPLE SETTINGS
174
  # ===========================================
175
  class Settings:
176
+ """Simple settings class"""
177
  def __init__(self):
178
  self.arf_mode = "demo"
179
  self.use_true_arf = True # Use true ARF integration
180
  self.default_scenario = "Cache Miss Storm"
181
  self.max_history_items = 100
182
  self.auto_refresh_seconds = 30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
 
184
  settings = Settings()
185
 
 
188
  # ===========================================
189
  def create_empty_plot(title: str):
190
  """Create an empty placeholder plot"""
191
+ import plotly.graph_objects as go
192
+ fig = go.Figure()
193
+ fig.add_annotation(
194
+ text="👆 Select a scenario<br>to view data",
195
+ xref="paper", yref="paper",
196
+ x=0.5, y=0.5, showarrow=False,
197
+ font=dict(size=14, color="#64748b")
198
+ )
199
+ fig.update_layout(
200
+ height=300,
201
+ title=title,
202
+ paper_bgcolor="rgba(0,0,0,0)",
203
+ plot_bgcolor="rgba(0,0,0,0)",
204
+ xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
205
+ yaxis=dict(showgrid=False, zeroline=False, showticklabels=False)
206
+ )
207
+ return fig
 
 
 
 
208
 
209
  def create_empty_dashboard():
210
  """Create empty dashboard"""
211
+ import plotly.graph_objects as go
212
+ fig = go.Figure()
213
+ fig.add_annotation(
214
+ text="📊 Dashboard will populate<br>after ROI calculation",
215
+ xref="paper", yref="paper",
216
+ x=0.5, y=0.5, showarrow=False,
217
+ font=dict(size=16, color="#64748b")
218
+ )
219
+ fig.update_layout(
220
+ height=700,
221
+ paper_bgcolor="rgba(0,0,0,0)",
222
+ plot_bgcolor="rgba(0,0,0,0)",
223
+ xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
224
+ yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
225
+ title=""
226
+ )
227
+ return fig
 
 
 
228
 
229
  def get_inactive_agent_html(agent_name: str, description: str):
230
  """Get HTML for inactive agent state"""
 
249
  """
250
 
251
  # ===========================================
252
+ # IMPORT MODULAR COMPONENTS - FIXED VERSION WITH ERROR HANDLING
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  # ===========================================
254
  def import_components() -> Dict[str, Any]:
255
  """Safely import all components with proper error handling - FIXED"""
 
257
  "all_available": False,
258
  "error": None,
259
  "get_styles": lambda: "", # Default empty styles
 
260
  }
261
 
262
  try:
 
281
  # Use empty styles as fallback
282
  components["get_styles"] = lambda: ""
283
 
284
+ # Import UI components with better error handling
285
  try:
286
+ # First try to create a scenarios fallback
287
+ FALLBACK_SCENARIOS = {
288
+ "Cache Miss Storm": {
289
+ "component": "Redis Cache Cluster",
290
+ "severity": "HIGH",
291
+ "impact_radius": "85% of users",
292
+ "business_impact": {"revenue_loss_per_hour": 8500},
293
+ "detection_time": "45 seconds",
294
+ "tags": ["cache", "redis", "latency"],
295
+ "metrics": {"affected_users": 45000}
296
+ }
297
+ }
298
+
299
+ # Now try to import UI components
300
  from ui.components import (
301
  create_header, create_status_bar, create_tab1_incident_demo,
302
  create_tab2_business_roi, create_tab3_enterprise_features,
 
328
  "create_footer": lambda: gr.HTML("<footer>ARF v3.3.7</footer>"),
329
  })
330
 
331
+ # Try to import scenarios from demo module (fallback)
332
  try:
333
  from demo.scenarios import INCIDENT_SCENARIOS
334
  components["INCIDENT_SCENARIOS"] = INCIDENT_SCENARIOS
335
  logger.info(f"✅ Loaded {len(INCIDENT_SCENARIOS)} scenarios from demo module")
336
  except ImportError as e:
337
+ logger.warning(f"⚠️ Demo scenarios not available: {e}")
338
+ # Create minimal fallback scenarios
339
+ components["INCIDENT_SCENARIOS"] = {
340
+ "Cache Miss Storm": {
341
+ "component": "Redis Cache Cluster",
342
+ "severity": "HIGH",
343
+ "impact_radius": "85% of users",
344
+ "business_impact": {"revenue_loss_per_hour": 8500},
345
+ "detection_time": "45 seconds",
346
+ "tags": ["cache", "redis", "latency"],
347
+ "metrics": {"affected_users": 45000}
348
+ }
349
+ }
350
 
351
  # Try to import TrueARF337Orchestrator
352
  try:
 
381
 
382
  # Try to import ROI calculator (but don't let it crash)
383
  try:
 
384
  import importlib.util
385
  spec = importlib.util.find_spec("core.calculators")
386
  if spec is not None:
 
450
  components["gr"] = gr
451
  except:
452
  pass
453
+
454
+ # Ensure we have scenarios
455
+ if "INCIDENT_SCENARIOS" not in components:
456
+ components["INCIDENT_SCENARIOS"] = {
457
+ "Cache Miss Storm": {
458
+ "component": "Redis Cache Cluster",
459
+ "severity": "HIGH",
460
+ "business_impact": {"revenue_loss_per_hour": 8500}
461
+ }
462
+ }
463
 
464
  return components
465
 
 
589
  """Create a telemetry visualization for the selected scenario"""
590
  try:
591
  viz_engine = get_components()["EnhancedVisualizationEngine"]
592
+ return viz_engine.create_telemetry_plot(scenario_name, anomaly_detected=True)
 
 
 
593
  except Exception as e:
594
  logger.error(f"Failed to create telemetry plot: {e}")
595
  return create_empty_plot(f"Telemetry: {scenario_name}")
 
598
  """Create a business impact visualization"""
599
  try:
600
  viz_engine = get_components()["EnhancedVisualizationEngine"]
601
+ return viz_engine.create_impact_gauge(scenario_name)
 
 
 
602
  except Exception as e:
603
  logger.error(f"Failed to create impact plot: {e}")
604
  return create_empty_plot(f"Impact: {scenario_name}")
 
607
  """Create an incident timeline visualization"""
608
  try:
609
  viz_engine = get_components()["EnhancedVisualizationEngine"]
610
+ return viz_engine.create_timeline_comparison()
 
 
 
611
  except Exception as e:
612
  logger.error(f"Failed to create timeline plot: {e}")
613
  return create_empty_plot("Timeline Comparison")
 
685
  installation = get_installation_status()
686
  real_arf_available = installation["oss_installed"]
687
 
688
+ # Use TrueARF337Orchestrator if available
689
+ orchestrator = get_components()["DemoOrchestrator"]()
 
690
  analysis = await orchestrator.analyze_incident(scenario_name, scenario)
691
 
692
  # Check for errors
 
701
  incident_table_data = get_audit_manager().get_incident_table()
702
 
703
  # Extract values from analysis
704
+ demo_display = analysis.get("demo_display", {})
705
+ real_arf_version = demo_display.get("real_arf_version", "mock")
706
  true_oss_used = analysis.get("true_oss_used", False)
707
  enterprise_simulated = analysis.get("enterprise_simulated", False)
708
 
 
825
  is_real_arf=true_oss_used
826
  )
827
 
828
+ logger.info(f"Analysis completed successfully for {scenario_name} (True ARF: {real_arf_version})")
829
  return (
830
  detection_html, recall_html, decision_html,
831
  oss_results, incident_table_data
 
900
  # ===========================================
901
  def execute_enterprise_healing(scenario_name, approval_required, mcp_mode_value):
902
  """Execute enterprise healing with true ARF simulation"""
903
+ import gradio as gr
 
904
 
905
+ scenario = get_components()["INCIDENT_SCENARIOS"].get(scenario_name, {})
906
 
907
  # Determine mode
908
  mode = "Approval" if approval_required else "Autonomous"
 
950
  get_audit_manager().add_execution(scenario_name, mode, savings=savings)
951
 
952
  # Get orchestrator for execution simulation
953
+ orchestrator = get_components()["DemoOrchestrator"]()
954
 
955
  # Create approval display
956
  if approval_required:
 
1133
  return gr.HTML.update(value=approval_html), enterprise_results, execution_table_data
1134
 
1135
  # ===========================================
1136
+ # CREATE DEMO INTERFACE - FIXED FOR GRADIO 6.0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1137
  # ===========================================
1138
  def create_demo_interface():
1139
  """Create demo interface using modular components"""
1140
 
1141
+ import gradio as gr
1142
+
1143
  # Get components
1144
  components = get_components()
 
 
 
 
 
1145
 
1146
  # Get CSS styles
1147
  css_styles = components["get_styles"]()
1148
 
1149
+ # Store CSS for later use in launch()
1150
+ global _demo_css
1151
+ _demo_css = css_styles
1152
+
1153
+ # Create interface without css parameter (will be added in launch)
1154
  with gr.Blocks(
1155
+ title=f"🚀 ARF Investor Demo v3.8.0 - TRUE ARF v3.3.7"
 
1156
  ) as demo:
1157
 
1158
  # Header - Updated to show true ARF version
 
1313
  )
1314
 
1315
  # ============ TAB 2 HANDLERS ============
1316
+
1317
+ def calculate_roi(scenario_name, monthly_incidents, team_size):
1318
+ """Calculate ROI"""
1319
+ try:
1320
+ logger.info(f"Calculating ROI for {scenario_name}")
1321
+
1322
+ # Validate inputs
1323
+ monthly_incidents = int(monthly_incidents) if monthly_incidents else 15
1324
+ team_size = int(team_size) if team_size else 5
1325
+
1326
+ # Get scenario-specific impact
1327
+ avg_impact = get_scenario_impact(scenario_name)
1328
+
1329
+ # Calculate ROI
1330
+ roi_calculator = components["EnhancedROICalculator"]
1331
+ roi_result = roi_calculator.calculate_comprehensive_roi(
1332
+ monthly_incidents=monthly_incidents,
1333
+ avg_impact=float(avg_impact),
1334
+ team_size=team_size
1335
+ )
1336
+
1337
+ # Extract ROI multiplier for visualization
1338
+ roi_multiplier = extract_roi_multiplier(roi_result)
1339
+
1340
+ # Create visualization
1341
+ viz_engine = components["EnhancedVisualizationEngine"]
1342
+ chart = viz_engine.create_executive_dashboard({"roi_multiplier": roi_multiplier})
1343
+
1344
+ return roi_result, chart
1345
+
1346
+ except Exception as e:
1347
+ logger.error(f"ROI calculation error: {e}")
1348
+
1349
+ # Provide fallback results
1350
+ fallback_result = {
1351
+ "status": "✅ Calculated Successfully",
1352
+ "summary": {
1353
+ "your_annual_impact": "$1,530,000",
1354
+ "potential_savings": "$1,254,600",
1355
+ "enterprise_cost": "$625,000",
1356
+ "roi_multiplier": "5.2×",
1357
+ "payback_months": "6.0",
1358
+ "annual_roi_percentage": "420%"
1359
+ }
1360
+ }
1361
+
1362
+ # Always return a valid chart
1363
+ viz_engine = components["EnhancedVisualizationEngine"]
1364
+ fallback_chart = viz_engine.create_executive_dashboard({"roi_multiplier": 5.2})
1365
+
1366
+ return fallback_result, fallback_chart
1367
+
1368
  calculate_btn.click(
1369
  fn=calculate_roi,
1370
  inputs=[roi_scenario_dropdown, monthly_slider, team_slider],
 
1372
  )
1373
 
1374
  # ============ TAB 3 HANDLERS ============
1375
+
1376
  def validate_license():
1377
  installation = get_installation_status()
1378
  return {
 
1453
  )
1454
 
1455
  # ============ TAB 4 HANDLERS ============
1456
+
1457
  def refresh_audit_trail():
1458
  return get_audit_manager().get_execution_table(), get_audit_manager().get_incident_table()
1459
 
 
1528
 
1529
  return demo
1530
 
1531
+ # Global variable for CSS
1532
+ _demo_css = ""
1533
 
1534
  # ===========================================
1535
  # MAIN EXECUTION - HUGGING FACE COMPATIBLE
 
1542
  # Check installation status first
1543
  installation = get_installation_status()
1544
  print(f"📦 Package Status:")
1545
+ print(f" • ARF OSS: {'✅ v' + installation['oss_version'] if installation['oss_installed'] else '⚠️ Not installed'}")
1546
+ print(f" • Enterprise: {'✅ v' + installation['enterprise_version'] if installation['enterprise_installed'] else '⚠️ Not installed'}")
1547
  print(f" • Execution Allowed: {'✅ Yes' if installation['execution_allowed'] else '❌ No (OSS only)'}")
1548
 
1549
  print(f"📊 Mode: {settings.arf_mode.upper()}")
 
1558
  print(f" • {rec}")
1559
  print("=" * 70)
1560
 
1561
+ import gradio as gr
1562
+
1563
  # Create and launch demo
1564
+ demo = create_demo_interface()
1565
+
1566
+ # Hugging Face Spaces compatible launch WITH CSS for Gradio 6.0
1567
+ demo.launch(
1568
+ server_name="0.0.0.0",
1569
+ server_port=7860,
1570
+ share=False,
1571
+ show_error=True, # Show errors in UI
1572
+ css=_demo_css # CSS parameter moved here for Gradio 6.0
1573
+ )
 
 
 
 
1574
 
1575
 
1576
  # Hugging Face Spaces entry point