petter2025 commited on
Commit
f2d0bd7
Β·
verified Β·
1 Parent(s): 5a8e8df

Update ui/components.py

Browse files
Files changed (1) hide show
  1. ui/components.py +317 -1
ui/components.py CHANGED
@@ -1047,11 +1047,12 @@ def create_historical_evidence_panel(scenario_data: Dict[str, Any]) -> gr.HTML:
1047
  # -----------------------------
1048
  # Performance Metrics Function - DOCTRINAL METRICS
1049
  # -----------------------------
 
1050
  def update_performance_metrics(scenario_name: str, scenarios=INCIDENT_SCENARIOS) -> tuple:
1051
  """
1052
  Update performance metrics based on scenario
1053
  Returns: (detection_time_html, recall_quality_html, confidence_score_html, sequencing_stage_html)
1054
- Doctrinal: No red/green colors, use gradient colors instead of binary thresholds
1055
  """
1056
 
1057
  # Scenario-specific metrics mapping WITH GRADIENT COLORS
@@ -1155,6 +1156,321 @@ def update_performance_metrics(scenario_name: str, scenarios=INCIDENT_SCENARIOS)
1155
  logger.info(f"βœ… Updated performance metrics for {scenario_name} ({scenario_type} type)")
1156
  return detection_time_html, recall_quality_html, confidence_score_html, sequencing_stage_html
1157
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1158
  # -----------------------------
1159
  # Tab 1: Live Incident Demo - UPDATED WITH RESTORED FUNCTIONS
1160
  # -----------------------------
 
1047
  # -----------------------------
1048
  # Performance Metrics Function - DOCTRINAL METRICS
1049
  # -----------------------------
1050
+ # 1. First, update the update_performance_metrics function to return what app.py expects:
1051
  def update_performance_metrics(scenario_name: str, scenarios=INCIDENT_SCENARIOS) -> tuple:
1052
  """
1053
  Update performance metrics based on scenario
1054
  Returns: (detection_time_html, recall_quality_html, confidence_score_html, sequencing_stage_html)
1055
+ MUST MATCH what app.py demo_btn.click() expects!
1056
  """
1057
 
1058
  # Scenario-specific metrics mapping WITH GRADIENT COLORS
 
1156
  logger.info(f"βœ… Updated performance metrics for {scenario_name} ({scenario_type} type)")
1157
  return detection_time_html, recall_quality_html, confidence_score_html, sequencing_stage_html
1158
 
1159
+ # 2. Update create_tab1_incident_demo to use the SAME variable names:
1160
+ def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Cache Miss Storm") -> tuple:
1161
+ """
1162
+ Create doctrinally compliant incident demo tab.
1163
+ Doctrinal: Language discipline, sequencing display, no early "critical"
1164
+ """
1165
+
1166
+ # Get the default scenario data
1167
+ default_scenario_data = scenarios.get(default_scenario, {})
1168
+ business_impact = default_scenario_data.get("business_impact", {})
1169
+ metrics = default_scenario_data.get("metrics", {})
1170
+
1171
+ with gr.Row():
1172
+ # Left Column: Scenario Selection & Live Visualization
1173
+ with gr.Column(scale=1, variant="panel") as left_col:
1174
+ # Scenario Selection with rich preview
1175
+ scenario_dropdown = gr.Dropdown(
1176
+ choices=list(scenarios.keys()),
1177
+ value=default_scenario,
1178
+ label="🎯 Select Variance Scenario",
1179
+ info="Choose a production variance pattern to analyze",
1180
+ interactive=True,
1181
+ container=False
1182
+ )
1183
+
1184
+ # ============ HISTORICAL EVIDENCE PANEL FIRST (RECALL DOMINANCE) ============
1185
+ historical_panel = create_historical_evidence_panel(default_scenario_data)
1186
+
1187
+ # Scenario Card with doctrinally compliant language
1188
+ scenario_card = gr.HTML(f"""
1189
+ <div style="border: 1px solid #e2e8f0; border-radius: 14px; padding: 20px; background: white; box-shadow: 0 4px 12px rgba(0,0,0,0.05); margin-bottom: 20px;">
1190
+ <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; padding-bottom: 12px; border-bottom: 2px solid #f1f5f9;">
1191
+ <h3 style="margin: 0; font-size: 18px; color: #1e293b;">πŸ“Š {default_scenario}</h3>
1192
+ <span style="padding: 4px 12px; background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); border-radius: 20px; font-size: 12px; font-weight: bold; color: white; text-transform: uppercase; letter-spacing: 0.5px;">{default_scenario_data.get('severity', 'HIGH_VARIANCE')}</span>
1193
+ </div>
1194
+ <div style="margin-top: 15px;">
1195
+ <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; padding: 4px 0;">
1196
+ <span style="font-size: 13px; color: #64748b; font-weight: 500;">Component:</span>
1197
+ <span style="font-size: 14px; color: #1e293b; font-weight: 600;">{default_scenario_data.get('component', 'Unknown').replace('_', ' ').title()}</span>
1198
+ </div>
1199
+ <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; padding: 4px 0;">
1200
+ <span style="font-size: 13px; color: #64748b; font-weight: 500;">Users Affected:</span>
1201
+ <span style="font-size: 14px; color: #1e293b; font-weight: 600;">{metrics.get('affected_users', 'Unknown') if 'affected_users' in metrics else 'Unknown'}</span>
1202
+ </div>
1203
+ <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; padding: 4px 0;">
1204
+ <span style="font-size: 13px; color: #64748b; font-weight: 500;">Revenue Risk:</span>
1205
+ <span style="font-size: 14px; color: #f59e0b; font-weight: 700;">${business_impact.get('revenue_risk_per_hour', 0):,}/hour</span>
1206
+ </div>
1207
+ <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; padding: 4px 0;">
1208
+ <span style="font-size: 13px; color: #64748b; font-weight: 500;">Detection Time:</span>
1209
+ <span style="font-size: 14px; color: #1e293b; font-weight: 600;">45 seconds (Policy System)</span>
1210
+ </div>
1211
+ <div style="display: flex; flex-wrap: wrap; gap: 6px; margin-top: 15px; padding-top: 12px; border-top: 1px solid #f1f5f9;">
1212
+ <span style="padding: 3px 8px; background: #f1f5f9; border-radius: 6px; font-size: 11px; color: #475569; font-weight: 500;">{default_scenario_data.get('component', 'unknown').split('_')[0]}</span>
1213
+ <span style="padding: 3px 8px; background: #f1f5f9; border-radius: 6px; font-size: 11px; color: #475569; font-weight: 500;">variance</span>
1214
+ <span style="padding: 3px 8px; background: #f1f5f9; border-radius: 6px; font-size: 11px; color: #475569; font-weight: 500;">production</span>
1215
+ <span style="padding: 3px 8px; background: #f1f5f9; border-radius: 6px; font-size: 11px; color: #475569; font-weight: 500;">pattern</span>
1216
+ </div>
1217
+ </div>
1218
+ </div>
1219
+ """)
1220
+
1221
+ # Visualization section
1222
+ with gr.Row():
1223
+ with gr.Column(scale=1):
1224
+ telemetry_header = gr.Markdown("### πŸ“ˆ Live Telemetry")
1225
+ telemetry_viz = gr.Plot(
1226
+ label="",
1227
+ show_label=False,
1228
+ elem_id="telemetry_plot"
1229
+ )
1230
+
1231
+ with gr.Column(scale=1):
1232
+ impact_header = gr.Markdown("### πŸ’° Business Impact")
1233
+ impact_viz = gr.Plot(
1234
+ label="",
1235
+ show_label=False,
1236
+ elem_id="impact_plot"
1237
+ )
1238
+
1239
+ # Middle Column: Process Workflow (NOT Agent Workflow)
1240
+ with gr.Column(scale=2, variant="panel") as middle_col:
1241
+ # ============ OBSERVATION GATE PLACEHOLDER ============
1242
+ observation_gate_placeholder = create_observation_gate_placeholder()
1243
+
1244
+ # ============ SEQUENCING VISUALIZATION ============
1245
+ sequencing_header = gr.Markdown("### πŸ”„ Sequencing Logic: Dampening β†’ Concurrency β†’ Observe β†’ Scale")
1246
+ sequencing_panel = create_sequencing_visualization()
1247
+
1248
+ # Process Workflow Header (NOT Agent Workflow)
1249
+ workflow_header = gr.Markdown("## πŸ”„ Policy Process Workflow")
1250
+ workflow_subheader = gr.Markdown("### How the system transforms variance into policy execution")
1251
+
1252
+ # Process Status Cards (NOT Agent Status Cards)
1253
+ with gr.Row():
1254
+ detection_process = create_detection_display()
1255
+ recall_process = create_recall_display()
1256
+ decision_process = create_decision_display()
1257
+
1258
+ # Mode Selection & Safety Controls
1259
+ with gr.Row():
1260
+ with gr.Column(scale=1):
1261
+ approval_toggle = gr.CheckboxGroup(
1262
+ choices=["πŸ‘€ Require Human Approval"],
1263
+ label="Safety Controls",
1264
+ value=[],
1265
+ info="Toggle human oversight"
1266
+ )
1267
+
1268
+ with gr.Column(scale=2):
1269
+ mcp_mode = gr.Radio(
1270
+ choices=["πŸ›‘οΈ Advisory (OSS Only)", "πŸ‘₯ Approval", "⚑ Autonomous"],
1271
+ value="πŸ›‘οΈ Advisory (OSS Only)",
1272
+ label="Policy Safety Mode",
1273
+ info="Control execution safety level",
1274
+ interactive=True
1275
+ )
1276
+
1277
+ # OSS vs Enterprise Boundary Visualization
1278
+ boundary_header = gr.Markdown("### 🎭 Policy vs Execution: The Safety Boundary")
1279
+
1280
+ with gr.Row():
1281
+ oss_section = create_oss_advisory_section()
1282
+
1283
+ enterprise_section = gr.HTML("""
1284
+ <div style="padding: 25px; border-radius: 16px; margin-bottom: 15px; flex: 1; min-height: 320px;
1285
+ background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%); border: 2px solid #10b981;">
1286
+ <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 2px solid rgba(16, 185, 129, 0.2);">
1287
+ <div style="font-size: 32px;">πŸ’°</div>
1288
+ <div>
1289
+ <h3 style="margin: 0 0 5px 0; font-size: 20px; color: #1e293b;">Execution Edition</h3>
1290
+ <p style="margin: 0; font-size: 14px; color: #64748b;">Full Execution & Learning - Commercial</p>
1291
+ </div>
1292
+ <div style="margin-left: auto; padding: 6px 14px; background: rgba(255, 255, 255, 0.9);
1293
+ border-radius: 10px; font-size: 11px; font-weight: bold; color: #475569;">
1294
+ REQUIRES LICENSE
1295
+ </div>
1296
+ </div>
1297
+
1298
+ <div style="background: white; border-radius: 12px; padding: 20px; box-shadow: 0 4px 12px rgba(0,0,0,0.05); margin-bottom: 20px;">
1299
+ <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; padding-bottom: 12px; border-bottom: 1px solid #f1f5f9;">
1300
+ <h4 style="margin: 0; font-size: 16px; color: #1e293b;">⚑ Ready to Execute</h4>
1301
+ <span style="padding: 6px 12px; background: #10b981; color: white; border-radius: 8px; font-size: 12px; font-weight: bold; text-transform: uppercase;">AUTONOMOUS</span>
1302
+ </div>
1303
+
1304
+ <div style="margin-bottom: 15px;">
1305
+ <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px;">
1306
+ <div style="width: 24px; height: 24px; background: #3b82f6; color: white; border-radius: 50%;
1307
+ display: flex; align-items: center; justify-content: center; font-size: 12px;">
1308
+ βš™οΈ
1309
+ </div>
1310
+ <div>
1311
+ <div style="font-size: 14px; color: #475569; font-weight: 500;">Mode</div>
1312
+ <div style="font-size: 13px; color: #1e293b;">Autonomous (Requires Enterprise license)</div>
1313
+ </div>
1314
+ </div>
1315
+
1316
+ <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px;">
1317
+ <div style="width: 24px; height: 24px; background: #10b981; color: white; border-radius: 50%;
1318
+ display: flex; align-items: center; justify-content: center; font-size: 12px;">
1319
+ ⚑
1320
+ </div>
1321
+ <div>
1322
+ <div style="font-size: 14px; color: #475569; font-weight: 500;">Expected Recovery</div>
1323
+ <div style="font-size: 13px; color: #1e293b;">12 minutes (vs 45 min manual)</div>
1324
+ </div>
1325
+ </div>
1326
+
1327
+ <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px;">
1328
+ <div style="width: 24px; height: 24px; background: #f59e0b; color: white; border-radius: 50%;
1329
+ display: flex; align-items: center; justify-content: center; font-size: 12px;">
1330
+ πŸ’°
1331
+ </div>
1332
+ <div>
1333
+ <div style="font-size: 14px; color: #475569; font-weight: 500;">Cost Avoided</div>
1334
+ <div style="font-size: 13px; color: #10b981; font-weight: 700;">$6,375</div>
1335
+ </div>
1336
+ </div>
1337
+
1338
+ <div style="display: flex; align-items: center; gap: 10px;">
1339
+ <div style="width: 24px; height: 24px; background: #8b5cf6; color: white; border-radius: 50%;
1340
+ display: flex; align-items: center; justify-content: center; font-size: 12px;">
1341
+ πŸ‘₯
1342
+ </div>
1343
+ <div>
1344
+ <div style="font-size: 14px; color: #475569; font-weight: 500;">Users Protected</div>
1345
+ <div style="font-size: 13px; color: #1e293b;">45,000 β†’ 0 impacted</div>
1346
+ </div>
1347
+ </div>
1348
+ </div>
1349
+ </div>
1350
+
1351
+ <!-- Enterprise Boundary -->
1352
+ <div style="text-align: center;">
1353
+ <div style="height: 2px; background: linear-gradient(90deg, transparent, #10b981, transparent); margin: 8px 0;"></div>
1354
+ <div style="padding: 10px; background: #dcfce7; color: #166534; border-radius: 10px;
1355
+ font-size: 14px; font-weight: bold; display: inline-block; border: 2px solid #10b981;">
1356
+ βœ… Enterprise executes with MCP safety
1357
+ </div>
1358
+ <div style="height: 2px; background: linear-gradient(90deg, transparent, #10b981, transparent); margin: 8px 0;"></div>
1359
+
1360
+ <div style="margin-top: 15px; padding: 12px; background: rgba(255, 255, 255, 0.8); border-radius: 10px;">
1361
+ <div style="font-size: 13px; color: #475569; font-weight: 500;">
1362
+ Enterprise edition adds execution, learning, and safety guarantees.
1363
+ </div>
1364
+ <div style="font-size: 12px; color: #64748b; margin-top: 5px;">
1365
+ MCP safety modes: Advisory β†’ Approval β†’ Autonomous
1366
+ </div>
1367
+ </div>
1368
+ </div>
1369
+ </div>
1370
+ """)
1371
+
1372
+ # Execution Controls
1373
+ with gr.Row():
1374
+ with gr.Column(scale=1):
1375
+ oss_btn = gr.Button(
1376
+ "πŸ†“ Run Policy Analysis",
1377
+ variant="secondary",
1378
+ size="lg"
1379
+ )
1380
+ oss_info = gr.Markdown("*Free, policy-only analysis*")
1381
+
1382
+ with gr.Column(scale=1):
1383
+ enterprise_btn = gr.Button(
1384
+ "πŸ’° Execute Enterprise Healing",
1385
+ variant="primary",
1386
+ size="lg"
1387
+ )
1388
+ enterprise_info = gr.Markdown("*Requires Enterprise license*")
1389
+
1390
+ # Timeline visualization
1391
+ timeline_header = gr.Markdown("### ⏰ Incident Timeline")
1392
+ timeline_viz = gr.Plot(
1393
+ create_timeline_comparison_plot(),
1394
+ label="",
1395
+ show_label=False,
1396
+ elem_id="timeline_plot"
1397
+ )
1398
+
1399
+ # Right Column: Results & Metrics
1400
+ with gr.Column(scale=1, variant="panel") as right_col:
1401
+ # Real-time Metrics Dashboard
1402
+ metrics_header = gr.Markdown("## πŸ“Š Performance Metrics")
1403
+
1404
+ # Metric Cards Grid - MUST MATCH app.py demo_btn.click() expectations!
1405
+ detection_time = gr.HTML()
1406
+ recall_quality = gr.HTML() # Changed from mttr to match demo_btn.click()
1407
+ confidence_score = gr.HTML() # Changed from auto_heal to match demo_btn.click()
1408
+ sequencing_stage = gr.HTML() # Changed from savings to match demo_btn.click()
1409
+
1410
+ # Results Display Areas
1411
+ oss_results_header = gr.Markdown("### πŸ†“ Policy Analysis Results")
1412
+ oss_results_display = gr.JSON(
1413
+ label="",
1414
+ value={
1415
+ "status": "Analysis Pending",
1416
+ "processes": ["Detection", "Recall", "Decision"],
1417
+ "mode": "Advisory Only",
1418
+ "action": "Generate Formal HealingIntent"
1419
+ },
1420
+ height=200
1421
+ )
1422
+
1423
+ enterprise_results_header = gr.Markdown("### πŸ’° Execution Results")
1424
+ enterprise_results_display = gr.JSON(
1425
+ label="",
1426
+ value={
1427
+ "status": "Execution Pending",
1428
+ "requires_license": True,
1429
+ "available_modes": ["Approval", "Autonomous"],
1430
+ "expected_outcome": "12m MTTR, $6.3K saved"
1431
+ },
1432
+ height=200
1433
+ )
1434
+
1435
+ # Approval Status
1436
+ approval_display = gr.HTML("""
1437
+ <div style="border: 2px solid #e2e8f0; border-radius: 14px; padding: 20px; background: white; margin-top: 20px;">
1438
+ <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; padding-bottom: 12px; border-bottom: 2px solid #f1f5f9;">
1439
+ <h4 style="margin: 0; font-size: 16px; color: #1e293b;">πŸ‘€ Human Approval Status</h4>
1440
+ <span style="padding: 4px 12px; background: #10b981; color: white; border-radius: 8px; font-size: 12px; font-weight: bold; text-transform: uppercase;">Not Required</span>
1441
+ </div>
1442
+ <div style="margin-top: 15px;">
1443
+ <p style="margin: 8px 0; font-size: 14px; color: #475569;"><strong>Current Mode:</strong> Advisory (Policy Only)</p>
1444
+ <p style="margin: 8px 0; font-size: 14px; color: #475569; font-style: italic;">Switch to "Approval" mode to enable human-in-the-loop workflows</p>
1445
+ <div style="display: flex; flex-direction: column; gap: 10px; margin-top: 20px;">
1446
+ <div style="padding: 12px; background: #f8fafc; border-radius: 10px; border-left: 4px solid #3b82f6; font-size: 14px; color: #475569; font-weight: 500;">1. System generates formal HealingIntent</div>
1447
+ <div style="padding: 12px; background: #f8fafc; border-radius: 10px; border-left: 4px solid #3b82f6; font-size: 14px; color: #475569; font-weight: 500;">2. Human reviews & approves contraindications</div>
1448
+ <div style="padding: 12px; background: #f8fafc; border-radius: 10px; border-left: 4px solid #3b82f6; font-size: 14px; color: #475569; font-weight: 500;">3. System executes with sequencing constraints</div>
1449
+ </div>
1450
+ </div>
1451
+ </div>
1452
+ """)
1453
+
1454
+ # Demo Actions
1455
+ demo_btn = gr.Button(
1456
+ "▢️ Run Complete Walkthrough",
1457
+ variant="secondary",
1458
+ size="lg"
1459
+ )
1460
+ demo_info = gr.Markdown("*Experience the full workflow from detection to resolution*")
1461
+
1462
+ # CRITICAL: Return EXACTLY 26 values that match app.py expectations
1463
+ return (
1464
+ # Left column returns (5 values)
1465
+ scenario_dropdown, historical_panel, scenario_card, telemetry_viz, impact_viz,
1466
+ # Middle column returns (13 values)
1467
+ observation_gate_placeholder, sequencing_panel, workflow_header, detection_process,
1468
+ recall_process, decision_process, oss_section, enterprise_section, oss_btn, enterprise_btn,
1469
+ approval_toggle, mcp_mode, timeline_viz,
1470
+ # Right column returns (8 values) - MUST MATCH demo_btn.click() expectations!
1471
+ detection_time, recall_quality, confidence_score, sequencing_stage, # Changed to match app.py
1472
+ oss_results_display, enterprise_results_display, approval_display, demo_btn
1473
+ )
1474
  # -----------------------------
1475
  # Tab 1: Live Incident Demo - UPDATED WITH RESTORED FUNCTIONS
1476
  # -----------------------------