petter2025 commited on
Commit
adb7e74
·
verified ·
1 Parent(s): dddcb49

Update ui/components.py

Browse files
Files changed (1) hide show
  1. ui/components.py +438 -597
ui/components.py CHANGED
@@ -1,646 +1,487 @@
1
  """
2
- UI components for the 5-tab demo - COMPLETE FIXED VERSION
3
- ALL TABS WORKING - Tab 1 now updates dynamically
4
  """
5
-
6
- import gradio as gr
7
- from typing import Dict, List, Any, Optional, Tuple
8
  import plotly.graph_objects as go
 
 
 
 
 
 
 
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
- def create_header(oss_version: str, oss_available: bool) -> gr.HTML:
12
- """Create the demo header - FIXED VERSION"""
13
- status_badge = "✅ Connected" if oss_available else "⚠️ Mock Mode"
 
 
14
 
15
- return gr.HTML(f"""
16
- <div style="text-align: center; padding: 30px 20px 20px 20px; background: linear-gradient(135deg, #f8fafc 0%, #ffffff 100%); border-radius: 0 0 20px 20px; margin-bottom: 30px; border-bottom: 3px solid #4ECDC4;">
17
- <h1 style="margin-bottom: 10px;">🚀 Agentic Reliability Framework</h1>
18
- <h2 style="color: #4a5568; font-weight: 600; margin-bottom: 20px;">Investor Demo v3.8.0</h2>
19
 
20
- <div style="display: flex; justify-content: center; gap: 20px; flex-wrap: wrap; margin-bottom: 20px;">
21
- <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 8px 16px; border-radius: 20px; font-weight: 700; font-size: 0.85rem;">
22
- 🏢 Enterprise Edition
23
- </div>
24
- <div style="background: linear-gradient(135deg, #4299e1 0%, #38b2ac 100%); color: white; padding: 8px 16px; border-radius: 20px; font-weight: 700; font-size: 0.85rem;">
25
- 🆓 OSS v{oss_version}
26
- </div>
27
- <div style="background: #e8f5e8; color: #2d3748; padding: 8px 16px; border-radius: 20px; font-weight: 600; font-size: 0.85rem;">
28
- 📈 5.2× ROI
29
- </div>
30
- <div style="background: #fff3cd; color: #856404; padding: 8px 16px; border-radius: 20px; font-weight: 600; font-size: 0.85rem;">
31
- ⚡ 85% MTTR Reduction
32
- </div>
33
- </div>
34
 
35
- <div style="color: #718096; font-size: 16px; max-width: 800px; margin: 0 auto; line-height: 1.6;">
36
- From <span style="font-weight: 700; color: #4299e1;">OSS Advisory</span>
37
- to <span style="font-weight: 700; color: #764ba2;">Enterprise Autonomous Healing</span>.
38
- </div>
39
-
40
- <div style="margin-top: 15px; font-size: 0.9rem; color: #4ECDC4; font-weight: 600;">
41
- {status_badge}
42
- </div>
43
- </div>
44
- """)
45
-
46
-
47
- def create_status_bar() -> gr.HTML:
48
- """Create system status bar - FIXED VERSION"""
49
- return gr.HTML("""
50
- <div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; margin-bottom: 25px;">
51
- <div style="background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); border-left: 4px solid #4ECDC4;">
52
- <div style="font-size: 0.9rem; color: #718096; margin-bottom: 5px;">System Status</div>
53
- <div style="display: flex; align-items: center; gap: 8px;">
54
- <div style="width: 10px; height: 10px; background: #4ECDC4; border-radius: 50%;"></div>
55
- <div style="font-weight: 700; color: #2d3748;">Operational</div>
56
- </div>
57
- </div>
58
 
59
- <div style="background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); border-left: 4px solid #FFA726;">
60
- <div style="font-size: 0.9rem; color: #718096; margin-bottom: 5px;">Performance</div>
61
- <div style="font-weight: 700; color: #2d3748; font-size: 1.1rem;">8.2 min avg resolution</div>
62
- </div>
 
 
 
 
 
63
 
64
- <div style="background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); border-left: 4px solid #42A5F5;">
65
- <div style="font-size: 0.9rem; color: #718096; margin-bottom: 5px;">Learning Engine</div>
66
- <div style="font-weight: 700; color: #2d3748; font-size: 1.1rem;">6 patterns detected</div>
67
- </div>
68
- </div>
69
- """)
70
-
71
-
72
- def create_tab1_incident_demo(scenarios: Dict, default_scenario: str = "Cache Miss Storm") -> Tuple:
73
- """Create Tab 1: Live Incident Demo - COMPLETE FIXED VERSION WITH DYNAMIC UPDATES"""
74
- with gr.Row():
75
- # Left Panel
76
- with gr.Column(scale=1):
77
- gr.Markdown("### 🎬 Select Incident Scenario")
78
-
79
- scenario_dropdown = gr.Dropdown(
80
- choices=list(scenarios.keys()),
81
- value=default_scenario,
82
- label="Choose an incident to analyze:",
83
- interactive=True
84
  )
85
 
86
- # Initialize with default scenario data
87
- scenario_description = gr.Markdown(
88
- value=scenarios[default_scenario]["description"]
 
 
 
 
 
89
  )
90
-
91
- gr.Markdown("### 📊 Current Metrics")
92
- metrics_display = gr.JSON(
93
- value=scenarios[default_scenario].get("metrics", {}),
94
- label="",
95
- show_label=False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  )
97
 
98
- gr.Markdown("### 💰 Business Impact")
99
- impact_display = gr.JSON(
100
- value=scenarios[default_scenario].get("business_impact", {}),
101
- label="",
102
- show_label=False
 
 
103
  )
104
 
105
- # Right Panel
106
- with gr.Column(scale=2):
107
- gr.Markdown("### 📈 Incident Timeline")
108
- timeline_output = gr.Plot(label="", show_label=False)
109
-
110
- gr.Markdown("### ⚡ Take Action")
111
- with gr.Row():
112
- oss_btn = gr.Button(
113
- "🆓 Run OSS Analysis",
114
- variant="secondary",
115
- size="lg",
116
- elem_id="oss_btn"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  )
118
- enterprise_btn = gr.Button(
119
- "🚀 Execute Enterprise Healing",
120
- variant="primary",
121
- size="lg",
122
- elem_id="enterprise_btn"
123
  )
124
-
125
- with gr.Row():
126
- approval_toggle = gr.Checkbox(
127
- label="🔐 Require Manual Approval",
128
- value=True,
129
- interactive=True
130
  )
131
- demo_btn = gr.Button(
132
- "⚡ Quick Demo",
133
- variant="secondary",
134
- size="sm"
 
 
135
  )
136
-
137
- approval_display = gr.HTML(
138
- value="<div style='padding: 15px; background: #f8f9fa; border-radius: 8px; color: #6c757d;'>"
139
- "Approval workflow will appear here after execution"
140
- "</div>"
141
- )
142
-
143
- with gr.Row():
144
- with gr.Column():
145
- gr.Markdown("### 📋 OSS Results")
146
- oss_results_display = gr.JSON(label="", value={})
147
-
148
- with gr.Column():
149
- gr.Markdown("### 🎯 Enterprise Results")
150
- enterprise_results_display = gr.JSON(label="", value={})
151
 
152
- # Define function to update scenario details when dropdown changes
153
- def update_scenario_details(scenario_name):
154
- """Update all scenario details when dropdown changes"""
155
- # Get the selected scenario, fallback to default if not found
156
- scenario = scenarios.get(scenario_name, scenarios[default_scenario])
157
 
158
- # Update the timeline visualization based on scenario
159
- timeline_fig = create_scenario_timeline(scenario_name)
160
 
161
- return (
162
- scenario.get("description", "No description available"),
163
- scenario.get("metrics", {}),
164
- scenario.get("business_impact", {}),
165
- timeline_fig
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  )
167
-
168
- # Helper function to create timeline visualization
169
- def create_scenario_timeline(scenario_name):
170
- """Create a timeline visualization for the selected scenario"""
171
- fig = go.Figure()
172
 
173
- # Different timeline events for different scenarios
174
- scenario_timelines = {
175
- "Cache Miss Storm": [
176
- {"time": "T-5m", "event": "📉 Cache hit rate drops below 20%", "type": "problem"},
177
- {"time": "T-4m", "event": "⚠️ Database load exceeds 90%", "type": "alert"},
178
- {"time": "T-3m", "event": "🤖 ARF detects cache pattern", "type": "detection"},
179
- {"time": "T-2m", "event": "🧠 Cache analysis complete", "type": "analysis"},
180
- {"time": "T-1m", "event": "⚡ Redis cluster scaled", "type": "action"},
181
- {"time": "T-0m", "event": "✅ Cache performance restored", "type": "recovery"}
182
- ],
183
- "Database Connection Pool Exhaustion": [
184
- {"time": "T-5m", "event": "📉 Connection pool reaches 95%", "type": "problem"},
185
- {"time": "T-4m", "event": "⚠️ API latency spikes to 2s+", "type": "alert"},
186
- {"time": "T-3m", "event": "🤖 ARF detects connection pattern", "type": "detection"},
187
- {"time": "T-2m", "event": "🧠 Pool analysis complete", "type": "analysis"},
188
- {"time": "T-1m", "event": "⚡ Connection pool increased", "type": "action"},
189
- {"time": "T-0m", "event": "✅ Database connections stable", "type": "recovery"}
190
- ],
191
- "Kubernetes Memory Leak": [
192
- {"time": "T-5m", "event": "📉 Memory usage hits 95%", "type": "problem"},
193
- {"time": "T-4m", "event": "⚠️ Pod restarts every 5 minutes", "type": "alert"},
194
- {"time": "T-3m", "event": "🤖 ARF detects memory pattern", "type": "detection"},
195
- {"time": "T-2m", "event": "🧠 Heap analysis complete", "type": "analysis"},
196
- {"time": "T-1m", "event": "⚡ Memory limits adjusted", "type": "action"},
197
- {"time": "T-0m", "event": "✅ JVM memory stabilized", "type": "recovery"}
198
- ],
199
- "API Rate Limit Storm": [
200
- {"time": "T-5m", "event": "📉 429 errors exceed 40%", "type": "problem"},
201
- {"time": "T-4m", "event": "⚠️ Partner API calls failing", "type": "alert"},
202
- {"time": "T-3m", "event": "🤖 ARF detects rate limit pattern", "type": "detection"},
203
- {"time": "T-2m", "event": "🧠 Backoff strategy analyzed", "type": "analysis"},
204
- {"time": "T-1m", "event": "⚡ Circuit breaker implemented", "type": "action"},
205
- {"time": "T-0m", "event": "✅ API calls normalized", "type": "recovery"}
206
- ],
207
- "Network Partition": [
208
- {"time": "T-5m", "event": "📉 Network partition detected", "type": "problem"},
209
- {"time": "T-4m", "event": "⚠️ Database split-brain risk", "type": "alert"},
210
- {"time": "T-3m", "event": "🤖 ARF detects partition pattern", "type": "detection"},
211
- {"time": "T-2m", "event": "🧠 Consensus analysis complete", "type": "analysis"},
212
- {"time": "T-1m", "event": "⚡ Quorum restored", "type": "action"},
213
- {"time": "T-0m", "event": "✅ Cluster consistency restored", "type": "recovery"}
214
- ],
215
- "Storage I/O Saturation": [
216
- {"time": "T-5m", "event": "📉 I/O utilization hits 98%", "type": "problem"},
217
- {"time": "T-4m", "event": "⚠️ Application timeouts increasing", "type": "alert"},
218
- {"time": "T-3m", "event": "🤖 ARF detects storage pattern", "type": "detection"},
219
- {"time": "T-2m", "event": "🧠 I/O analysis complete", "type": "analysis"},
220
- {"time": "T-1m", "event": "⚡ Storage optimized", "type": "action"},
221
- {"time": "T-0m", "event": "✅ I/O performance restored", "type": "recovery"}
222
- ]
223
- }
224
 
225
- # Get timeline for this scenario, default to Cache Miss Storm
226
- events = scenario_timelines.get(scenario_name, scenario_timelines["Cache Miss Storm"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
 
228
- # Color mapping
229
- color_map = {
230
- "problem": "#FF6B6B",
231
- "alert": "#FFE66D",
232
- "detection": "#45B7D1",
233
- "analysis": "#9B59B6",
234
- "action": "#4ECDC4",
235
- "recovery": "#2ECC71"
236
- }
 
 
 
237
 
238
- # Add events
239
- for event in events:
240
- fig.add_trace(go.Scatter(
241
- x=[event["time"]],
242
- y=[1],
243
- mode='markers+text',
244
- marker=dict(
245
- size=20,
246
- color=color_map[event["type"]],
247
- symbol='circle',
248
- line=dict(width=2, color='white')
249
- ),
250
- text=[event["event"]],
251
- textposition="top center",
252
- hoverinfo='text',
253
- name=event["type"].capitalize(),
254
- hovertemplate="<b>%{text}</b><br>Click for details<extra></extra>"
255
- ))
256
 
257
- # Add connecting line
258
- fig.add_trace(go.Scatter(
259
- x=[e["time"] for e in events],
260
- y=[1] * len(events),
261
- mode='lines',
262
- line=dict(color='gray', width=2, dash='dash'),
263
- hoverinfo='none',
264
- showlegend=False
265
- ))
266
 
267
- fig.update_layout(
268
- title=f"<b>Incident Timeline: {scenario_name}</b>",
269
- height=450,
270
- paper_bgcolor="rgba(0,0,0,0)",
271
- plot_bgcolor="rgba(0,0,0,0)",
272
- hovermode='closest',
273
- clickmode='event+select',
274
- yaxis=dict(
275
- showticklabels=False,
276
- range=[0.5, 1.5],
277
- gridcolor="rgba(200,200,200,0.1)"
278
- ),
279
- xaxis=dict(
280
- gridcolor="rgba(200,200,200,0.1)"
281
- ),
282
- showlegend=True,
283
- legend=dict(
284
- yanchor="top",
285
- y=0.99,
286
- xanchor="left",
287
- x=0.01
288
- )
289
- )
290
 
291
- return fig
 
 
 
 
 
 
 
 
 
 
 
 
292
 
293
- # Create initial timeline
294
- initial_timeline = create_scenario_timeline(default_scenario)
 
295
 
296
- # Connect the dropdown change event to update all components
297
- scenario_dropdown.change(
298
- fn=update_scenario_details,
299
- inputs=[scenario_dropdown],
300
- outputs=[scenario_description, metrics_display, impact_display, timeline_output]
301
- )
 
 
 
 
 
302
 
303
- # Initialize timeline output with the default scenario timeline
304
- timeline_output.value = initial_timeline
305
 
306
- return (scenario_dropdown, scenario_description, metrics_display, impact_display,
307
- timeline_output, oss_btn, enterprise_btn, approval_toggle, demo_btn,
308
- approval_display, oss_results_display, enterprise_results_display)
309
-
310
-
311
- def create_tab2_business_roi(scenarios: Dict) -> Tuple:
312
- """Create Tab 2: Business Impact & ROI - FIXED VERSION"""
313
- with gr.Column():
314
- gr.Markdown("### 📊 Executive Dashboard")
315
- dashboard_output = gr.Plot(label="", show_label=False)
316
-
317
- gr.Markdown("### 🧮 ROI Calculator")
318
- with gr.Row():
319
- with gr.Column(scale=1):
320
- # Scenario selector - FIXED: Initialize with scenarios
321
- roi_scenario_dropdown = gr.Dropdown(
322
- choices=list(scenarios.keys()),
323
- value="Cache Miss Storm",
324
- label="Select scenario for ROI calculation:",
325
- interactive=True
326
- )
327
-
328
- monthly_slider = gr.Slider(
329
- 1, 100, value=15, step=1,
330
- label="Monthly similar incidents",
331
- interactive=True
332
- )
333
-
334
- team_slider = gr.Slider(
335
- 1, 20, value=5, step=1,
336
- label="Reliability team size",
337
- interactive=True
338
- )
339
-
340
- calculate_btn = gr.Button(
341
- "Calculate ROI",
342
- variant="primary",
343
- size="lg"
344
- )
345
-
346
- with gr.Column(scale=2):
347
- roi_output = gr.JSON(
348
- label="ROI Analysis Results",
349
- value={}
350
- )
351
-
352
- roi_chart = gr.Plot(label="Cost Comparison", show_label=False)
353
 
354
- return (dashboard_output, roi_scenario_dropdown, monthly_slider, team_slider,
355
- calculate_btn, roi_output, roi_chart)
356
-
 
 
 
 
 
 
 
 
 
357
 
358
- def create_tab3_enterprise_features() -> Tuple:
359
- """Create Tab 3: Enterprise Features - UPDATED"""
360
- with gr.Row():
361
- # Left Column
362
- with gr.Column(scale=1):
363
- gr.Markdown("### 🔐 License Management")
364
-
365
- license_display = gr.JSON(
366
- value={
367
- "status": "Active",
368
- "tier": "Enterprise",
369
- "expires": "2026-12-31",
370
- "features": ["autonomous_healing", "compliance", "audit_trail",
371
- "predictive_analytics", "multi_cloud", "role_based_access"]
372
- },
373
- label="Current License"
374
- )
375
-
376
- with gr.Row():
377
- validate_btn = gr.Button("🔍 Validate", variant="secondary")
378
- trial_btn = gr.Button("🆓 Start Trial", variant="primary")
379
- upgrade_btn = gr.Button("🚀 Upgrade", variant="secondary")
380
-
381
- gr.Markdown("### ⚡ MCP Execution Modes")
382
-
383
- mcp_mode = gr.Radio(
384
- choices=["advisory", "approval", "autonomous"],
385
- value="advisory",
386
- label="Execution Mode",
387
- interactive=True,
388
- info="advisory = OSS only, approval = human review, autonomous = AI-driven"
389
- )
390
-
391
- mcp_mode_info = gr.JSON(
392
- value={
393
- "current_mode": "advisory",
394
- "description": "OSS Edition - Analysis only, no execution",
395
- "features": ["Incident analysis", "RAG similarity", "HealingIntent creation"]
396
- },
397
- label="Mode Details"
398
- )
399
-
400
- # Right Column
401
- with gr.Column(scale=1):
402
- gr.Markdown("### 📋 Feature Comparison")
403
-
404
- features_table = gr.Dataframe(
405
- headers=["Feature", "OSS", "Enterprise"],
406
- value=[
407
- ["Autonomous Healing", "❌", "✅"],
408
- ["Compliance Automation", "❌", "✅"],
409
- ["Predictive Analytics", "❌", "✅"],
410
- ["Multi-Cloud Support", "❌", "✅"],
411
- ["Audit Trail", "Basic", "Comprehensive"],
412
- ["Role-Based Access", "❌", "✅"],
413
- ["Custom Dashboards", "❌", "✅"],
414
- ["Enterprise Support", "Community", "24/7 SLA"],
415
- ["Custom Integrations", "❌", "✅"],
416
- ["Advanced Analytics", "❌", "✅"]
417
- ],
418
- label="",
419
- interactive=False
420
- )
421
-
422
- gr.Markdown("### 🔗 Integrations")
423
-
424
- integrations_table = gr.Dataframe(
425
- headers=["Platform", "Status", "Type"],
426
- value=[
427
- ["AWS", "✅ Connected", "Cloud"],
428
- ["Azure", "✅ Connected", "Cloud"],
429
- ["GCP", "✅ Connected", "Cloud"],
430
- ["Datadog", "✅ Connected", "Monitoring"],
431
- ["PagerDuty", "✅ Connected", "Alerting"],
432
- ["ServiceNow", "✅ Connected", "ITSM"],
433
- ["Slack", "✅ Connected", "Collaboration"],
434
- ["Teams", "✅ Connected", "Collaboration"],
435
- ["GitHub", "✅ Connected", "DevOps"],
436
- ["GitLab", "✅ Connected", "DevOps"],
437
- ["Jira", "✅ Connected", "Project Management"],
438
- ["Splunk", "✅ Connected", "Monitoring"],
439
- ["New Relic", "✅ Connected", "APM"],
440
- ["Prometheus", "✅ Connected", "Metrics"],
441
- ["Elasticsearch", "✅ Connected", "Logging"]
442
- ],
443
- label="",
444
- interactive=False
445
- )
446
 
447
- return (license_display, validate_btn, trial_btn, upgrade_btn,
448
- mcp_mode, mcp_mode_info, features_table, integrations_table)
449
-
450
-
451
- def create_tab4_audit_trail() -> Tuple:
452
- """Create Tab 4: Audit Trail & History - WITH DEMO DATA"""
453
- # Demo data
454
- demo_executions = [
455
- ["14:30", "Cache Miss Storm", "Autonomous", "✅ Success", "$7,225", "Auto-execution"],
456
- ["14:15", "Database Connection Pool", "Approval", "✅ Success", "$3,570", "Approved by admin"],
457
- ["13:45", "Memory Leak", "Advisory", "⚠️ Analysis", "$0", "OSS analysis only"],
458
- ["13:20", "Cache Miss Storm", "Autonomous", "✅ Success", "$7,225", "Pattern match"],
459
- ["12:50", "API Rate Limit", "Approval", "✅ Success", "$3,230", "Scheduled fix"],
460
- ["12:15", "Network Partition", "Autonomous", "✅ Success", "$10,200", "Emergency response"],
461
- ["11:40", "Storage I/O", "Advisory", "⚠️ Analysis", "$0", "Performance review"]
462
- ]
463
 
464
- demo_incidents = [
465
- ["14:30", "redis_cache", "Cache Miss Storm", "CRITICAL", "Resolved"],
466
- ["14:15", "postgresql", "Database Connection Pool", "HIGH", "Resolved"],
467
- ["13:45", "java_service", "Memory Leak", "HIGH", "Analyzed"],
468
- ["13:20", "redis_cache", "Cache Miss Storm", "CRITICAL", "Resolved"],
469
- ["12:50", "api_gateway", "API Rate Limit", "MEDIUM", "Resolved"],
470
- ["12:15", "database", "Network Partition", "CRITICAL", "Resolved"],
471
- ["11:40", "storage", "Storage I/O", "HIGH", "Analyzed"],
472
- ["11:10", "redis_cache", "Cache Performance", "LOW", "Monitoring"],
473
- ["10:45", "load_balancer", "Traffic Spike", "MEDIUM", "Auto-scaled"],
474
- ["10:20", "api_gateway", "Rate Limit", "MEDIUM", "Resolved"]
475
- ]
 
476
 
477
- with gr.Row():
478
- # Left Column
479
- with gr.Column(scale=1):
480
- gr.Markdown("### 📋 Execution History")
481
-
482
- with gr.Row():
483
- refresh_btn = gr.Button("🔄 Refresh", variant="secondary", size="sm")
484
- clear_btn = gr.Button("🗑️ Clear", variant="stop", size="sm")
485
- export_btn = gr.Button("📥 Export", variant="secondary", size="sm")
486
-
487
- execution_table = gr.Dataframe(
488
- headers=["Time", "Scenario", "Mode", "Status", "Savings", "Details"],
489
- value=demo_executions,
490
- label="",
491
- interactive=False
492
- )
493
 
494
- # Right Column
495
- with gr.Column(scale=1):
496
- gr.Markdown("### 📊 Incident History")
497
-
498
- incident_table = gr.Dataframe(
499
- headers=["Time", "Component", "Scenario", "Severity", "Status"],
500
- value=demo_incidents,
501
- label="",
502
- interactive=False
503
- )
504
-
505
- gr.Markdown("### 📤 Export")
506
- export_text = gr.Textbox(
507
- label="Audit Trail (JSON)",
508
- lines=6,
509
- interactive=False
510
- )
511
 
512
- return (refresh_btn, clear_btn, export_btn, execution_table,
513
- incident_table, export_text)
514
-
 
 
 
 
 
 
 
 
 
 
 
 
 
515
 
516
- def create_tab5_learning_engine() -> Tuple:
517
- """Create Tab 5: Learning Engine - WITH DEMO DATA"""
518
- # Demo data
519
- demo_search_results = [
520
- ["Cache Miss Storm", "92%", "Scale Redis + Circuit Breaker", "✅ Auto-healed"],
521
- ["Database Connection", "85%", "Increase pool + Monitoring", "✅ Approved"],
522
- ["Memory Leak Pattern", "78%", "Heap analysis + Restart", "⚠️ Advisory"],
523
- ["API Rate Limit", "72%", "Backoff + Queue", "✅ Auto-healed"],
524
- ["Network Partition", "65%", "Quorum + Consensus", "✅ Emergency"]
525
- ]
526
 
527
- # Create a simple demo graph
528
- fig = go.Figure(data=go.Scatter(
529
- x=[1, 2, 3, 4, 5],
530
- y=[2, 5, 3, 8, 7],
531
- mode='markers+text',
532
- marker=dict(size=[20, 30, 25, 40, 35], color=['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFE66D', '#9B59B6']),
533
- text=['Cache', 'DB', 'Memory', 'API', 'Network'],
534
- textposition="top center"
535
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
536
 
537
- fig.update_layout(
538
- title="Incident Pattern Relationships",
539
- height=400,
540
- paper_bgcolor="rgba(0,0,0,0)",
541
- plot_bgcolor="rgba(0,0,0,0)"
 
542
  )
543
 
544
- with gr.Row():
545
- # Left Column
546
- with gr.Column(scale=2):
547
- gr.Markdown("### 🧠 Incident Memory Graph")
548
-
549
- learning_graph = gr.Plot(value=fig, label="", show_label=False)
550
-
551
- with gr.Row():
552
- graph_type = gr.Radio(
553
- choices=["Force", "Hierarchical", "Circular"],
554
- value="Force",
555
- label="Layout",
556
- interactive=True
557
- )
558
- show_labels = gr.Checkbox(label="Show Labels", value=True, interactive=True)
559
-
560
- gr.Markdown("### 🔍 Similarity Search")
561
-
562
- search_query = gr.Textbox(
563
- label="Describe incident or paste metrics",
564
- placeholder="e.g., 'Redis cache miss causing database overload'",
565
- lines=2,
566
- interactive=True
567
- )
568
-
569
- with gr.Row():
570
- search_btn = gr.Button("🔍 Search", variant="primary")
571
- clear_btn = gr.Button("Clear", variant="secondary")
572
-
573
- search_results = gr.Dataframe(
574
- headers=["Incident", "Similarity", "Resolution", "Actions"],
575
- value=demo_search_results,
576
- label="",
577
- interactive=False
578
- )
579
-
580
- # Right Column
581
- with gr.Column(scale=1):
582
- gr.Markdown("### 📊 Learning Stats")
583
-
584
- stats_display = gr.JSON(
585
- value={
586
- "total_incidents": 42,
587
- "patterns_detected": 6,
588
- "similarity_searches": 128,
589
- "confidence_threshold": 0.85,
590
- "successful_predictions": 38,
591
- "accuracy_rate": "90.5%"
592
- },
593
- label="Statistics"
594
- )
595
-
596
- gr.Markdown("### 🎯 Pattern Detection")
597
-
598
- patterns_display = gr.JSON(
599
- value={
600
- "cache_miss_storm": {"occurrences": 12, "confidence": 0.92, "auto_heal": True},
601
- "db_connection_exhaustion": {"occurrences": 8, "confidence": 0.88, "auto_heal": True},
602
- "memory_leak_java": {"occurrences": 5, "confidence": 0.85, "auto_heal": False},
603
- "api_rate_limit": {"occurrences": 10, "confidence": 0.91, "auto_heal": True},
604
- "network_partition": {"occurrences": 3, "confidence": 0.79, "auto_heal": True},
605
- "storage_io_saturation": {"occurrences": 4, "confidence": 0.86, "auto_heal": False}
606
- },
607
- label="Detected Patterns"
608
- )
609
-
610
- gr.Markdown("### 📈 Performance")
611
-
612
- performance_display = gr.JSON(
613
- value={
614
- "avg_resolution_time": "8.2 min",
615
- "success_rate": "95.2%",
616
- "auto_heal_rate": "78.6%",
617
- "mttr_reduction": "85%",
618
- "cost_savings": "$1.2M",
619
- "roi_multiplier": "5.2×"
620
- },
621
- label="Performance Metrics"
622
- )
623
 
624
- return (learning_graph, graph_type, show_labels, search_query, search_btn,
625
- clear_btn, search_results, stats_display, patterns_display, performance_display)
626
-
627
-
628
- def create_footer() -> gr.HTML:
629
- """Create the demo footer - UPDATED FOR 2026"""
630
- return gr.HTML("""
631
- <div style="margin-top: 40px; padding: 30px; background: linear-gradient(135deg, #1a365d 0%, #2d3748 100%); border-radius: 20px; color: white;">
632
- <div style="border-top: 1px solid #4a5568; padding-top: 20px; text-align: center; color: #a0aec0; font-size: 0.9rem;">
633
- <p style="margin: 0;">© 2026 Agentic Reliability Framework. Demo v3.8.0 Enterprise Edition.</p>
634
- <p style="margin: 10px 0 0 0; font-size: 0.85rem; color: #cbd5e0;">
635
- This is a demonstration environment showcasing ARF capabilities.<br>
636
- Actual implementation results may vary based on specific use cases and configurations.
637
- </p>
638
- <p style="margin: 15px 0 0 0; font-size: 0.8rem; color: #718096;">
639
- For production inquiries or enterprise licensing, visit
640
- <a href="https://arf.dev/enterprise" style="color: #4ECDC4; text-decoration: none; font-weight: 600;">
641
- arf.dev/enterprise
642
- </a>
643
- </p>
644
- </div>
645
- </div>
646
- """)
 
 
 
 
1
  """
2
+ Enhanced components with real ARF integration
 
3
  """
4
+ import streamlit as st
 
 
5
  import plotly.graph_objects as go
6
+ import plotly.express as px
7
+ from datetime import datetime, timedelta
8
+ import pandas as pd
9
+ import numpy as np
10
+ from typing import List, Dict, Any, Optional
11
+ import time
12
+ import json
13
 
14
+ # Mock imports for ARF objects (in real app, import from actual packages)
15
+ class MockHealingIntent:
16
+ """Mock HealingIntent for demo purposes"""
17
+ def __init__(self, action, component, confidence, status, rag_similarity_score=None):
18
+ self.action = action
19
+ self.component = component
20
+ self.confidence = confidence
21
+ self.status = status
22
+ self.rag_similarity_score = rag_similarity_score
23
+ self.deterministic_id = f"intent_{int(time.time())}"
24
+ self.created_at = time.time()
25
+
26
+ def get_execution_summary(self):
27
+ return {
28
+ "intent_id": self.deterministic_id,
29
+ "action": self.action,
30
+ "component": self.component,
31
+ "confidence": self.confidence,
32
+ "status": self.status.value if hasattr(self.status, 'value') else self.status,
33
+ "rag_similarity_score": self.rag_similarity_score
34
+ }
35
 
36
+ def create_arf_enhanced_timeline(incident_data: Dict[str, Any], healing_intents: List[Dict[str, Any]] = None):
37
+ """
38
+ Create an enhanced incident timeline with real ARF integration
39
+ """
40
+ col1, col2 = st.columns([2, 1])
41
 
42
+ with col1:
43
+ st.markdown("### 📈 ARF-Enhanced Incident Timeline")
 
 
44
 
45
+ # Create timeline events based on ARF processing pipeline
46
+ events = [
47
+ {"time": "-5m", "event": "📡 Alert Triggered", "phase": "detection", "color": "#FF6B6B"},
48
+ {"time": "-4m", "event": "🧠 ARF Analysis Started", "phase": "analysis", "color": "#4ECDC4"},
49
+ {"time": "-3.5m", "event": "🔍 RAG Similarity Search", "phase": "rag", "color": "#1E90FF"},
50
+ {"time": "-2.5m", "event": "🎯 Pattern Detection", "phase": "pattern", "color": "#9D4EDD"},
51
+ {"time": "-1.5m", "event": "💡 HealingIntent Generated", "phase": "intent", "color": "#FFD166"},
52
+ {"time": "-1m", "event": "⚡ MCP Execution", "phase": "execution", "color": "#06D6A0"},
53
+ {"time": "Now", "event": "✅ Resolution Complete", "phase": "resolution", "color": "#118AB2"}
54
+ ]
 
 
 
 
55
 
56
+ # Create enhanced timeline with ARF phases
57
+ fig = go.Figure()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
+ # Add ARF processing phases as background
60
+ phases = [
61
+ {"name": "Detection", "x_range": [0, 1], "color": "rgba(255, 107, 107, 0.1)"},
62
+ {"name": "Analysis", "x_range": [1, 2.5], "color": "rgba(78, 205, 196, 0.1)"},
63
+ {"name": "RAG Search", "x_range": [2.5, 3.5], "color": "rgba(30, 144, 255, 0.1)"},
64
+ {"name": "Intent Gen", "x_range": [3.5, 4.5], "color": "rgba(157, 78, 221, 0.1)"},
65
+ {"name": "Execution", "x_range": [4.5, 5.5], "color": "rgba(6, 214, 160, 0.1)"},
66
+ {"name": "Resolution", "x_range": [5.5, 6], "color": "rgba(17, 138, 178, 0.1)"}
67
+ ]
68
 
69
+ for phase in phases:
70
+ fig.add_shape(
71
+ type="rect",
72
+ x0=phase["x_range"][0] - 0.5,
73
+ x1=phase["x_range"][1] - 0.5,
74
+ y0=-0.3,
75
+ y1=0.3,
76
+ fillcolor=phase["color"],
77
+ line=dict(width=0),
78
+ layer="below"
 
 
 
 
 
 
 
 
 
 
79
  )
80
 
81
+ # Add phase labels
82
+ fig.add_annotation(
83
+ x=(phase["x_range"][0] + phase["x_range"][1] - 1) / 2,
84
+ y=0.4,
85
+ text=phase["name"],
86
+ showarrow=False,
87
+ font=dict(size=9, color="#64748B"),
88
+ yshift=10
89
  )
90
+
91
+ # Add timeline line with markers
92
+ fig.add_trace(go.Scatter(
93
+ x=[i for i in range(len(events))],
94
+ y=[0] * len(events),
95
+ mode='lines+markers+text',
96
+ line=dict(color='#334155', width=2, dash='solid'),
97
+ marker=dict(
98
+ size=18,
99
+ color=[e['color'] for e in events],
100
+ line=dict(width=2, color='white')
101
+ ),
102
+ text=[e['event'][0] for e in events], # Use emoji as marker text
103
+ textposition="middle center",
104
+ textfont=dict(size=10, color='white'),
105
+ hoverinfo='text',
106
+ hovertext=[f"<b>{e['event']}</b><br>Phase: {e['phase'].title()}<br>Time: {e['time']}" for e in events],
107
+ hovertemplate='%{hovertext}<extra></extra>'
108
+ ))
109
+
110
+ # Add event descriptions
111
+ for i, event in enumerate(events):
112
+ fig.add_annotation(
113
+ x=i,
114
+ y=-0.2,
115
+ text=event['event'].split(' ')[1] if ' ' in event['event'] else event['event'][1:],
116
+ showarrow=False,
117
+ yshift=-30,
118
+ font=dict(size=9, color=event['color'])
119
  )
120
 
121
+ fig.add_annotation(
122
+ x=i,
123
+ y=0.1,
124
+ text=event['time'],
125
+ showarrow=False,
126
+ yshift=25,
127
+ font=dict(size=8, color="#94A3B8")
128
  )
129
 
130
+ # Update layout
131
+ fig.update_layout(
132
+ height=250,
133
+ showlegend=False,
134
+ plot_bgcolor='rgba(0,0,0,0)',
135
+ paper_bgcolor='rgba(0,0,0,0)',
136
+ xaxis=dict(
137
+ range=[-1, len(events)],
138
+ showticklabels=False,
139
+ showgrid=False,
140
+ zeroline=False
141
+ ),
142
+ yaxis=dict(
143
+ range=[-0.5, 0.5],
144
+ showticklabels=False,
145
+ showgrid=False,
146
+ zeroline=False
147
+ ),
148
+ margin=dict(l=20, r=20, t=20, b=50)
149
+ )
150
+
151
+ st.plotly_chart(fig, use_container_width=True)
152
+
153
+ # Add ARF processing metrics
154
+ if healing_intents:
155
+ cols = st.columns(4)
156
+ with cols[0]:
157
+ intent_conf = healing_intents[0].get('confidence', 0.7) if healing_intents else 0.7
158
+ st.metric(
159
+ label="🧠 ARF Confidence",
160
+ value=f"{intent_conf*100:.1f}%",
161
+ delta="+15% with RAG"
162
  )
163
+ with cols[1]:
164
+ st.metric(
165
+ label="🔍 Similar Incidents",
166
+ value=f"{len(healing_intents[0].get('similar_incidents', [])) if healing_intents else 0}",
167
+ delta="Pattern detected"
168
  )
169
+ with cols[2]:
170
+ st.metric(
171
+ label="⚡ Resolution Time",
172
+ value="8.2min",
173
+ delta="-85% vs OSS"
 
174
  )
175
+ with cols[3]:
176
+ cost_savings = incident_data.get('revenue_loss_per_hour', 8500) * 0.5 # 30min saved
177
+ st.metric(
178
+ label="💰 Cost Avoided",
179
+ value=f"${cost_savings:,.0f}",
180
+ delta_color="normal"
181
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
 
183
+ with col2:
184
+ st.markdown("### 🎯 ARF Pattern Detection")
 
 
 
185
 
186
+ # Pattern confidence from ARF RAG similarity
187
+ rag_score = healing_intents[0].get('rag_similarity_score', 0.85) if healing_intents else 0.85
188
 
189
+ # Confidence gauge using actual ARF confidence
190
+ fig = go.Figure(go.Indicator(
191
+ mode="gauge+number",
192
+ value=rag_score * 100,
193
+ domain={'x': [0, 1], 'y': [0, 1]},
194
+ title={'text': "RAG Similarity Score", 'font': {'size': 14}},
195
+ gauge={
196
+ 'axis': {'range': [0, 100], 'tickwidth': 1, 'tickcolor': "darkblue"},
197
+ 'bar': {'color': "#06D6A0" if rag_score > 0.85 else "#FFD166"},
198
+ 'steps': [
199
+ {'range': [0, 70], 'color': "rgba(255, 107, 107, 0.3)"},
200
+ {'range': [70, 85], 'color': "rgba(255, 209, 102, 0.3)"},
201
+ {'range': [85, 100], 'color': "rgba(6, 214, 160, 0.3)"}
202
+ ],
203
+ 'threshold': {
204
+ 'line': {'color': "red", 'width': 4},
205
+ 'thickness': 0.75,
206
+ 'value': 85
207
+ }
208
+ }
209
+ ))
210
+
211
+ fig.update_layout(
212
+ height=200,
213
+ margin=dict(l=30, r=30, t=50, b=20)
214
  )
215
+ st.plotly_chart(fig, use_container_width=True)
 
 
 
 
216
 
217
+ # Pattern details based on ARF analysis
218
+ pattern_type = "cache_miss_storm"
219
+ if incident_data.get('database_load', 0) > 90:
220
+ pattern_type = "database_overload"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
 
222
+ st.info(f"""
223
+ **Detected Pattern**: `{pattern_type}`
224
+ **Confidence**: {rag_score*100:.1f}%
225
+ **Auto-Heal Eligible**: {'✅ Yes' if rag_score > 0.85 else '❌ Manual Review'}
226
+ **Similar Incidents**: {len(healing_intents[0].get('similar_incidents', [])) if healing_intents else 0}
227
+ """)
228
+
229
+ def create_healing_intent_visualizer(healing_intent: Dict[str, Any]):
230
+ """
231
+ Visualize a HealingIntent object from ARF
232
+ """
233
+ st.markdown("### 💡 ARF HealingIntent")
234
+
235
+ # Create columns for intent visualization
236
+ col1, col2 = st.columns([1, 2])
237
+
238
+ with col1:
239
+ # Confidence indicator
240
+ confidence = healing_intent.get('confidence', 0.85)
241
+ fig = go.Figure(go.Indicator(
242
+ mode="gauge+number",
243
+ value=confidence * 100,
244
+ domain={'x': [0, 1], 'y': [0, 1]},
245
+ title={'text': "Confidence"},
246
+ gauge={
247
+ 'axis': {'range': [0, 100]},
248
+ 'bar': {'color': "#06D6A0" if confidence > 0.85 else "#FFD166"},
249
+ 'steps': [
250
+ {'range': [0, 70], 'color': "rgba(255, 107, 107, 0.3)"},
251
+ {'range': [70, 85], 'color': "rgba(255, 209, 102, 0.3)"},
252
+ {'range': [85, 100], 'color': "rgba(6, 214, 160, 0.3)"}
253
+ ],
254
+ 'threshold': {
255
+ 'line': {'color': "red", 'width': 4},
256
+ 'thickness': 0.75,
257
+ 'value': 85
258
+ }
259
+ }
260
+ ))
261
+ fig.update_layout(height=180)
262
+ st.plotly_chart(fig, use_container_width=True)
263
 
264
+ # Intent metadata
265
+ st.caption("Intent Metadata")
266
+ st.code(f"""
267
+ ID: {healing_intent.get('deterministic_id', 'N/A')}
268
+ Status: {healing_intent.get('status', 'created')}
269
+ Source: {healing_intent.get('source', 'oss_analysis')}
270
+ Created: {datetime.fromtimestamp(healing_intent.get('created_at', time.time())).strftime('%H:%M:%S')}
271
+ """)
272
+
273
+ with col2:
274
+ # Intent details
275
+ st.markdown("#### Action Details")
276
 
277
+ # Action card
278
+ action = healing_intent.get('action', 'scale_out')
279
+ component = healing_intent.get('component', 'redis_cache')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
 
281
+ st.info(f"""
282
+ **Action**: `{action}`
283
+ **Component**: `{component}`
284
+ **Justification**: {healing_intent.get('justification', 'Based on historical pattern analysis')}
285
+ """)
 
 
 
 
286
 
287
+ # Parameters
288
+ params = healing_intent.get('parameters', {})
289
+ if params:
290
+ st.markdown("#### Parameters")
291
+ for key, value in params.items():
292
+ st.metric(label=key, value=str(value))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293
 
294
+ # Similar incidents
295
+ similar = healing_intent.get('similar_incidents', [])
296
+ if similar:
297
+ st.markdown(f"#### Similar Incidents ({len(similar)})")
298
+ for i, incident in enumerate(similar[:2]): # Show top 2
299
+ with st.expander(f"Similar Incident #{i+1}"):
300
+ st.json(incident)
301
+
302
+ def create_rag_similarity_panel(query: str, similar_incidents: List[Dict[str, Any]]):
303
+ """
304
+ Display RAG similarity search results
305
+ """
306
+ st.markdown("### 🔍 RAG Similarity Search")
307
 
308
+ if not similar_incidents:
309
+ st.info("No similar incidents found in memory")
310
+ return
311
 
312
+ # Create similarity results table
313
+ df_data = []
314
+ for i, incident in enumerate(similar_incidents):
315
+ df_data.append({
316
+ "Rank": i + 1,
317
+ "Component": incident.get('component', 'unknown'),
318
+ "Similarity": f"{incident.get('similarity_score', 0)*100:.1f}%",
319
+ "Resolution": incident.get('resolution', 'Unknown'),
320
+ "Success": "✅" if incident.get('success', False) else "❌",
321
+ "Actions": len(incident.get('actions_taken', []))
322
+ })
323
 
324
+ df = pd.DataFrame(df_data)
 
325
 
326
+ # Display as styled table
327
+ st.dataframe(
328
+ df,
329
+ use_container_width=True,
330
+ column_config={
331
+ "Rank": st.column_config.NumberColumn(width="small"),
332
+ "Similarity": st.column_config.ProgressColumn(
333
+ width="medium",
334
+ format="%f%%",
335
+ min_value=0,
336
+ max_value=100,
337
+ ),
338
+ },
339
+ hide_index=True
340
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341
 
342
+ # Similarity distribution chart
343
+ if len(similar_incidents) > 1:
344
+ fig = px.bar(
345
+ df,
346
+ x="Rank",
347
+ y=df["Similarity"].str.rstrip('%').astype(float),
348
+ color=df["Similarity"].str.rstrip('%').astype(float),
349
+ color_continuous_scale=["#FF6B6B", "#FFD166", "#06D6A0"],
350
+ title="Similarity Scores Distribution"
351
+ )
352
+ fig.update_layout(height=200, showlegend=False)
353
+ st.plotly_chart(fig, use_container_width=True)
354
 
355
+ def create_learning_engine_panel(learning_stats: Dict[str, Any]):
356
+ """
357
+ Display ARF learning engine insights
358
+ """
359
+ st.markdown("### 🧠 ARF Learning Engine")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
360
 
361
+ cols = st.columns(2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362
 
363
+ with cols[0]:
364
+ # Pattern detection stats
365
+ st.metric(
366
+ label="Patterns Detected",
367
+ value=learning_stats.get('patterns_detected', 6),
368
+ delta="+2 this week"
369
+ )
370
+
371
+ st.metric(
372
+ label="Success Rate",
373
+ value=f"{learning_stats.get('success_rate', '95.2%')}",
374
+ delta="+5.2%"
375
+ )
376
 
377
+ with cols[1]:
378
+ # Learning metrics
379
+ st.metric(
380
+ label="Auto-Heal Rate",
381
+ value=f"{learning_stats.get('auto_heal_rate', '78.6%')}",
382
+ delta="+12.4%"
383
+ )
 
 
 
 
 
 
 
 
 
384
 
385
+ st.metric(
386
+ label="Confidence Threshold",
387
+ value=f"{learning_stats.get('confidence_threshold', 0.85)}",
388
+ delta="Optimized"
389
+ )
 
 
 
 
 
 
 
 
 
 
 
 
390
 
391
+ # Detected patterns
392
+ patterns = learning_stats.get('detected_patterns', {})
393
+ if patterns:
394
+ st.markdown("#### Detected Patterns")
395
+
396
+ pattern_data = []
397
+ for pattern_name, pattern_info in patterns.items():
398
+ pattern_data.append({
399
+ "Pattern": pattern_name,
400
+ "Occurrences": pattern_info.get('occurrences', 0),
401
+ "Confidence": f"{pattern_info.get('confidence', 0)*100:.1f}%",
402
+ "Auto-Heal": "✅" if pattern_info.get('auto_heal', False) else "❌"
403
+ })
404
+
405
+ pattern_df = pd.DataFrame(pattern_data)
406
+ st.dataframe(pattern_df, use_container_width=True, hide_index=True)
407
 
408
+ def create_execution_mode_toggle(current_mode: str = "advisory"):
409
+ """
410
+ Show OSS vs Enterprise execution mode differences
411
+ """
412
+ st.markdown("### ARF Execution Modes")
 
 
 
 
 
413
 
414
+ # Mode selector
415
+ modes = {
416
+ "advisory": {
417
+ "name": "OSS Advisory",
418
+ "description": "Analysis only, no execution",
419
+ "color": "#FF6B6B",
420
+ "features": [
421
+ "Incident analysis",
422
+ "RAG similarity search",
423
+ "HealingIntent creation",
424
+ "Pattern detection"
425
+ ]
426
+ },
427
+ "approval": {
428
+ "name": "Enterprise (Approval)",
429
+ "description": "Human-in-the-loop execution",
430
+ "color": "#FFD166",
431
+ "features": [
432
+ "All OSS features",
433
+ "Human approval workflow",
434
+ "Audit trail",
435
+ "Compliance reporting"
436
+ ]
437
+ },
438
+ "autonomous": {
439
+ "name": "Enterprise (Autonomous)",
440
+ "description": "AI-driven auto-healing",
441
+ "color": "#06D6A0",
442
+ "features": [
443
+ "All approval features",
444
+ "Auto-execution",
445
+ "Learning engine",
446
+ "Predictive analytics"
447
+ ]
448
+ }
449
+ }
450
 
451
+ # Create mode selection
452
+ selected_mode = st.selectbox(
453
+ "Execution Mode",
454
+ options=list(modes.keys()),
455
+ format_func=lambda x: modes[x]["name"],
456
+ index=list(modes.keys()).index(current_mode) if current_mode in modes else 0
457
  )
458
 
459
+ # Display mode details
460
+ mode = modes[selected_mode]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
 
462
+ # Mode indicator
463
+ st.info(f"""
464
+ **Current Mode**: {mode['name']}
465
+ **Description**: {mode['description']}
466
+ """)
467
+
468
+ # Feature comparison
469
+ st.markdown("#### Features Available")
470
+
471
+ for feature in mode['features']:
472
+ st.markdown(f" {feature}")
473
+
474
+ # Mode differences
475
+ st.markdown("#### Mode Differences")
476
+
477
+ diff_data = {
478
+ "Feature": ["Execution", "Human Review", "Audit Trail", "Learning", "Compliance"],
479
+ "OSS Advisory": ["❌", "❌", "Basic", "❌", "❌"],
480
+ "Enterprise (Approval)": ["✅", "✅", "Full", "Basic", "✅"],
481
+ "Enterprise (Autonomous)": ["✅", "Optional", "Full", "Advanced", "✅"]
482
+ }
483
+
484
+ diff_df = pd.DataFrame(diff_data)
485
+ st.dataframe(diff_df, use_container_width=True, hide_index=True)
486
+
487
+ return selected_mode