Update ui/components.py
Browse files- ui/components.py +157 -1
ui/components.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
"""
|
| 2 |
UI components for the 5-tab demo - COMPLETE FIXED VERSION
|
|
|
|
| 3 |
"""
|
| 4 |
|
| 5 |
import gradio as gr
|
|
@@ -69,7 +70,7 @@ def create_status_bar() -> gr.HTML:
|
|
| 69 |
|
| 70 |
|
| 71 |
def create_tab1_incident_demo(scenarios: Dict, default_scenario: str = "Cache Miss Storm") -> Tuple:
|
| 72 |
-
"""Create Tab 1: Live Incident Demo - FIXED
|
| 73 |
with gr.Row():
|
| 74 |
# Left Panel
|
| 75 |
with gr.Column(scale=1):
|
|
@@ -82,6 +83,7 @@ def create_tab1_incident_demo(scenarios: Dict, default_scenario: str = "Cache Mi
|
|
| 82 |
interactive=True
|
| 83 |
)
|
| 84 |
|
|
|
|
| 85 |
scenario_description = gr.Markdown(
|
| 86 |
value=scenarios[default_scenario]["description"]
|
| 87 |
)
|
|
@@ -147,6 +149,160 @@ def create_tab1_incident_demo(scenarios: Dict, default_scenario: str = "Cache Mi
|
|
| 147 |
gr.Markdown("### π― Enterprise Results")
|
| 148 |
enterprise_results_display = gr.JSON(label="", value={})
|
| 149 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
return (scenario_dropdown, scenario_description, metrics_display, impact_display,
|
| 151 |
timeline_output, oss_btn, enterprise_btn, approval_toggle, demo_btn,
|
| 152 |
approval_display, oss_results_display, enterprise_results_display)
|
|
|
|
| 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
|
|
|
|
| 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):
|
|
|
|
| 83 |
interactive=True
|
| 84 |
)
|
| 85 |
|
| 86 |
+
# Initialize with default scenario data
|
| 87 |
scenario_description = gr.Markdown(
|
| 88 |
value=scenarios[default_scenario]["description"]
|
| 89 |
)
|
|
|
|
| 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)
|