Update app.py
Browse files
app.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
| 1 |
-
# app.py - Complete fixed version with Plotly compatibility
|
| 2 |
# π ARF Ultimate Investor Demo v3.3.9 - ENTERPRISE EDITION
|
| 3 |
# Enhanced with clear OSS vs Enterprise boundaries
|
| 4 |
# UPDATED: Added realism panel integration for enterprise-seasoned SRE experience
|
| 5 |
# UPDATED: Added dynamic performance metrics for Phase 2
|
| 6 |
# SURGICAL FIX: Fixed AsyncRunner.async_to_sync contract violation
|
| 7 |
# DOCTRINAL FIX: Updated unpacking contract from 24 to 26 values
|
|
|
|
| 8 |
|
| 9 |
import logging
|
| 10 |
import sys
|
|
@@ -33,6 +34,25 @@ logger = logging.getLogger(__name__)
|
|
| 33 |
# Add parent directory to path
|
| 34 |
sys.path.insert(0, str(Path(__file__).parent))
|
| 35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
# ===========================================
|
| 37 |
# FIX FOR ASYNC EVENT LOOP ISSUES
|
| 38 |
# ===========================================
|
|
@@ -388,7 +408,6 @@ def check_arf_installation():
|
|
| 388 |
}
|
| 389 |
logger.info(f"β
ARF Enterprise v{results['enterprise_version']} detected")
|
| 390 |
else:
|
| 391 |
-
# β
ADD THIS MISSING ENTERPRISE ELSE BLOCK:
|
| 392 |
results["badges"]["enterprise"] = {
|
| 393 |
"text": "π’ Enterprise Edition", # Changed from "π Enterprise Required"
|
| 394 |
"color": "#3b82f6", # Changed from "#64748b" (gray to blue)
|
|
@@ -420,6 +439,112 @@ import numpy as np
|
|
| 420 |
pio.templates.default = "plotly_white"
|
| 421 |
logger.info("β
Plotly configured for Gradio compatibility")
|
| 422 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 423 |
# ===========================================
|
| 424 |
# ENHANCED VISUALIZATION FUNCTIONS WITH GRADIO COMPATIBILITY
|
| 425 |
# ===========================================
|
|
@@ -1863,74 +1988,99 @@ def update_scenario_display(scenario_name: str) -> tuple:
|
|
| 1863 |
"boundary_note": "Scenario not found"
|
| 1864 |
})
|
| 1865 |
|
| 1866 |
-
# Create scenario card HTML (
|
| 1867 |
-
|
| 1868 |
-
|
| 1869 |
-
|
| 1870 |
-
|
| 1871 |
-
|
| 1872 |
-
|
| 1873 |
-
|
| 1874 |
-
|
| 1875 |
-
|
| 1876 |
-
scenario_card_html = f"""
|
| 1877 |
-
<div style="border: 1px solid {severity_color}; border-radius: 14px; padding: 20px;
|
| 1878 |
-
background: linear-gradient(135deg, {severity_color}10 0%, #ffffff 100%);">
|
| 1879 |
-
|
| 1880 |
-
<div style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 15px;">
|
| 1881 |
-
<div>
|
| 1882 |
-
<h3 style="margin: 0 0 8px 0; font-size: 18px; color: #1e293b; font-weight: 700;">
|
| 1883 |
-
{scenario_name}
|
| 1884 |
-
</h3>
|
| 1885 |
-
<div style="display: flex; align-items: center; gap: 10px;">
|
| 1886 |
-
<div style="padding: 4px 12px; background: {severity_color}; color: white;
|
| 1887 |
border-radius: 12px; font-size: 12px; font-weight: bold;">
|
| 1888 |
{scenario["severity"]} SEVERITY
|
| 1889 |
</div>
|
| 1890 |
-
<div style="font-size: 13px; color:
|
| 1891 |
{scenario["component"]}
|
| 1892 |
</div>
|
| 1893 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1894 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1895 |
|
| 1896 |
-
<div style="
|
| 1897 |
-
<div
|
| 1898 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1899 |
</div>
|
| 1900 |
-
|
| 1901 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1902 |
</div>
|
| 1903 |
</div>
|
| 1904 |
-
|
| 1905 |
-
|
| 1906 |
-
|
| 1907 |
-
|
| 1908 |
-
|
| 1909 |
-
Business Impact Analysis
|
| 1910 |
-
</div>
|
| 1911 |
-
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px;">
|
| 1912 |
-
<div style="text-align: center;">
|
| 1913 |
-
<div style="font-size: 16px; font-weight: 700; color: {severity_color};">45 min</div>
|
| 1914 |
-
<div style="font-size: 11px; color: #64748b;">Without ARF</div>
|
| 1915 |
-
</div>
|
| 1916 |
-
<div style="text-align: center;">
|
| 1917 |
-
<div style="font-size: 16px; font-weight: 700; color: #10b981;">12 min</div>
|
| 1918 |
-
<div style="font-size: 11px; color: #64748b;">With ARF</div>
|
| 1919 |
</div>
|
| 1920 |
-
<div style="
|
| 1921 |
-
<div style="
|
| 1922 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1923 |
</div>
|
| 1924 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1925 |
</div>
|
| 1926 |
-
|
| 1927 |
-
<!-- Boundary context -->
|
| 1928 |
-
<div style="margin-top: 20px; padding: 12px; background: #f8fafc; border-radius: 8px;
|
| 1929 |
-
border-left: 3px solid {severity_color}; font-size: 12px; color: #475569;">
|
| 1930 |
-
<strong>Boundary Context:</strong> {scenario.get('boundary_note', 'OSS analyzes, Enterprise executes')}
|
| 1931 |
-
</div>
|
| 1932 |
-
</div>
|
| 1933 |
-
"""
|
| 1934 |
|
| 1935 |
# Get visualizations as Plotly figures (ENHANCED)
|
| 1936 |
telemetry_fig = create_simple_telemetry_plot(scenario_name, settings.use_true_arf)
|
|
@@ -2170,10 +2320,10 @@ def calculate_roi(scenario_name, monthly_incidents, team_size):
|
|
| 2170 |
return roi_result, fig
|
| 2171 |
|
| 2172 |
# ===========================================
|
| 2173 |
-
# CREATE DEMO INTERFACE - UPDATED WITH
|
| 2174 |
# ===========================================
|
| 2175 |
def create_demo_interface():
|
| 2176 |
-
"""Create demo interface using modular components with boundary awareness and
|
| 2177 |
|
| 2178 |
import gradio as gr
|
| 2179 |
|
|
@@ -2181,17 +2331,25 @@ def create_demo_interface():
|
|
| 2181 |
components = get_components()
|
| 2182 |
|
| 2183 |
# Get CSS styles
|
| 2184 |
-
css_styles =
|
| 2185 |
|
| 2186 |
# Store CSS for later use in launch()
|
| 2187 |
global _demo_css
|
| 2188 |
_demo_css = css_styles
|
| 2189 |
|
| 2190 |
-
# Create interface
|
| 2191 |
with gr.Blocks(
|
| 2192 |
-
title=f"π ARF Investor Demo v3.3.9 - TRUE ARF OSS Integration"
|
|
|
|
| 2193 |
) as demo:
|
| 2194 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2195 |
# Header
|
| 2196 |
header_html = components["create_header"]("3.3.9")
|
| 2197 |
|
|
@@ -2202,7 +2360,7 @@ def create_demo_interface():
|
|
| 2202 |
# ============ 5 TABS ============
|
| 2203 |
with gr.Tabs(elem_classes="tab-nav"):
|
| 2204 |
|
| 2205 |
-
# TAB 1: Live Incident Demo - NOW WITH
|
| 2206 |
with gr.TabItem("π₯ Live Incident Demo", id="tab1"):
|
| 2207 |
# ===== SURGICAL FIX: SAFE UNPACKING WITH ERROR HANDLING =====
|
| 2208 |
try:
|
|
@@ -2692,7 +2850,7 @@ def create_demo_interface():
|
|
| 2692 |
outputs=[roi_output, roi_chart]
|
| 2693 |
)
|
| 2694 |
|
| 2695 |
-
logger.info("β
Demo interface created successfully with
|
| 2696 |
|
| 2697 |
return demo
|
| 2698 |
# ===========================================
|
|
@@ -2712,15 +2870,12 @@ def launch_demo():
|
|
| 2712 |
logger.info(f" OSS: {boundaries['oss']['label']} v{boundaries['oss']['version']}")
|
| 2713 |
logger.info(f" Enterprise: {boundaries['enterprise']['label']} v{boundaries['enterprise']['version']}")
|
| 2714 |
logger.info(f" Mode: {boundaries['demo_mode']['architecture']}")
|
|
|
|
| 2715 |
logger.info("=" * 60)
|
| 2716 |
|
| 2717 |
# Create interface
|
| 2718 |
demo = create_demo_interface()
|
| 2719 |
|
| 2720 |
-
# Get CSS styles
|
| 2721 |
-
components = get_components()
|
| 2722 |
-
css_styles = components["get_styles"]()
|
| 2723 |
-
|
| 2724 |
# Configure for Hugging Face Spaces
|
| 2725 |
launch_config = {
|
| 2726 |
"server_name": "0.0.0.0",
|
|
@@ -2734,6 +2889,7 @@ def launch_demo():
|
|
| 2734 |
}
|
| 2735 |
|
| 2736 |
# Add CSS if available
|
|
|
|
| 2737 |
if css_styles:
|
| 2738 |
launch_config["css"] = css_styles
|
| 2739 |
|
|
@@ -2776,6 +2932,7 @@ if __name__ == "__main__":
|
|
| 2776 |
logger.info("Enhanced with clear OSS vs Enterprise boundaries")
|
| 2777 |
logger.info("DOCTRINAL COMPLIANCE: Historical Evidence, Observation Gate, Sequencing")
|
| 2778 |
logger.info("PHASE 2: Dynamic Performance Metrics by Scenario")
|
|
|
|
| 2779 |
logger.info(f"True ARF OSS v3.3.9 integration with simulated Enterprise execution")
|
| 2780 |
logger.info("=" * 60)
|
| 2781 |
|
|
@@ -2786,6 +2943,7 @@ if __name__ == "__main__":
|
|
| 2786 |
print("π ARF Ultimate Investor Demo v3.3.9 - ENTERPRISE EDITION")
|
| 2787 |
print("π Architecture: OSS advises β Enterprise executes")
|
| 2788 |
print("π DOCTRINAL: Historical Evidence + Observation Gate + Sequencing")
|
|
|
|
| 2789 |
print("π Starting on http://localhost:7860")
|
| 2790 |
print("="*60 + "\n")
|
| 2791 |
|
|
|
|
| 1 |
+
# app.py - Complete fixed version with Plotly compatibility AND MODERN COMPONENTS
|
| 2 |
# π ARF Ultimate Investor Demo v3.3.9 - ENTERPRISE EDITION
|
| 3 |
# Enhanced with clear OSS vs Enterprise boundaries
|
| 4 |
# UPDATED: Added realism panel integration for enterprise-seasoned SRE experience
|
| 5 |
# UPDATED: Added dynamic performance metrics for Phase 2
|
| 6 |
# SURGICAL FIX: Fixed AsyncRunner.async_to_sync contract violation
|
| 7 |
# DOCTRINAL FIX: Updated unpacking contract from 24 to 26 values
|
| 8 |
+
# MODERN UI: Integrated modern_components.py for enhanced UI foundation
|
| 9 |
|
| 10 |
import logging
|
| 11 |
import sys
|
|
|
|
| 34 |
# Add parent directory to path
|
| 35 |
sys.path.insert(0, str(Path(__file__).parent))
|
| 36 |
|
| 37 |
+
# ===========================================
|
| 38 |
+
# MODERN UI FEATURE FLAGS
|
| 39 |
+
# ===========================================
|
| 40 |
+
# Feature flags configuration for safe rollout
|
| 41 |
+
FEATURE_FLAGS = {
|
| 42 |
+
'modern_ui': True, # Use modern components
|
| 43 |
+
'dark_mode': True, # Enable dark mode toggle
|
| 44 |
+
'responsive_design': True, # Use responsive CSS
|
| 45 |
+
'progressive_disclosure': False, # Start disabled
|
| 46 |
+
'keyboard_nav': False,
|
| 47 |
+
'realtime_updates': False
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
# Check URL parameters for feature flag overrides (placeholder)
|
| 51 |
+
def get_feature_flags():
|
| 52 |
+
flags = FEATURE_FLAGS.copy()
|
| 53 |
+
# TODO: Add URL parameter parsing if needed
|
| 54 |
+
return flags
|
| 55 |
+
|
| 56 |
# ===========================================
|
| 57 |
# FIX FOR ASYNC EVENT LOOP ISSUES
|
| 58 |
# ===========================================
|
|
|
|
| 408 |
}
|
| 409 |
logger.info(f"β
ARF Enterprise v{results['enterprise_version']} detected")
|
| 410 |
else:
|
|
|
|
| 411 |
results["badges"]["enterprise"] = {
|
| 412 |
"text": "π’ Enterprise Edition", # Changed from "π Enterprise Required"
|
| 413 |
"color": "#3b82f6", # Changed from "#64748b" (gray to blue)
|
|
|
|
| 439 |
pio.templates.default = "plotly_white"
|
| 440 |
logger.info("β
Plotly configured for Gradio compatibility")
|
| 441 |
|
| 442 |
+
# ===========================================
|
| 443 |
+
# MODERN UI COMPONENTS IMPORT
|
| 444 |
+
# ===========================================
|
| 445 |
+
# Import modern components with fallback
|
| 446 |
+
try:
|
| 447 |
+
from ui.modern_components import (
|
| 448 |
+
initialize_modern_ui,
|
| 449 |
+
Card, Grid, ObservationGate,
|
| 450 |
+
SequencingFlow, ProcessDisplay,
|
| 451 |
+
DESIGN_TOKENS, Button, Badge,
|
| 452 |
+
ResponsiveUtils, Accessibility, DarkMode,
|
| 453 |
+
create_example_dashboard
|
| 454 |
+
)
|
| 455 |
+
MODERN_UI_AVAILABLE = True
|
| 456 |
+
logger.info("β
Modern UI components loaded successfully")
|
| 457 |
+
except ImportError as e:
|
| 458 |
+
MODERN_UI_AVAILABLE = False
|
| 459 |
+
logger.warning(f"β οΈ Modern UI components not available: {e}")
|
| 460 |
+
|
| 461 |
+
# Create minimal fallback classes
|
| 462 |
+
class Card:
|
| 463 |
+
@staticmethod
|
| 464 |
+
def create(content, **kwargs):
|
| 465 |
+
return f"<div class='card'>{content}</div>"
|
| 466 |
+
|
| 467 |
+
class ObservationGate:
|
| 468 |
+
@staticmethod
|
| 469 |
+
def create(confidence=65.0, **kwargs):
|
| 470 |
+
return f"<div>Observation Gate: {confidence}%</div>"
|
| 471 |
+
|
| 472 |
+
# ===========================================
|
| 473 |
+
# CSS LOADING FUNCTION
|
| 474 |
+
# ===========================================
|
| 475 |
+
def load_css_files():
|
| 476 |
+
"""Load CSS files for modern UI with fallback"""
|
| 477 |
+
css_content = ""
|
| 478 |
+
|
| 479 |
+
if get_feature_flags().get('modern_ui', False) and MODERN_UI_AVAILABLE:
|
| 480 |
+
try:
|
| 481 |
+
# Try to load modern CSS files
|
| 482 |
+
with open("ui/styles/modern.css", "r") as f:
|
| 483 |
+
css_content += f.read()
|
| 484 |
+
logger.info("β
Loaded modern.css")
|
| 485 |
+
except FileNotFoundError:
|
| 486 |
+
# Fallback inline modern CSS
|
| 487 |
+
css_content += """
|
| 488 |
+
:root {
|
| 489 |
+
--color-primary: #3b82f6;
|
| 490 |
+
--color-success: #10b981;
|
| 491 |
+
--color-warning: #f59e0b;
|
| 492 |
+
--color-danger: #ef4444;
|
| 493 |
+
--bg-primary: #ffffff;
|
| 494 |
+
--text-primary: #1e293b;
|
| 495 |
+
--border-color: #e2e8f0;
|
| 496 |
+
}
|
| 497 |
+
|
| 498 |
+
.container {
|
| 499 |
+
width: 100%;
|
| 500 |
+
max-width: 1200px;
|
| 501 |
+
margin: 0 auto;
|
| 502 |
+
padding: 0 1rem;
|
| 503 |
+
}
|
| 504 |
+
|
| 505 |
+
.grid {
|
| 506 |
+
display: grid;
|
| 507 |
+
gap: 1rem;
|
| 508 |
+
}
|
| 509 |
+
|
| 510 |
+
@media (min-width: 640px) {
|
| 511 |
+
.grid-2 { grid-template-columns: repeat(2, 1fr); }
|
| 512 |
+
.grid-4 { grid-template-columns: repeat(4, 1fr); }
|
| 513 |
+
}
|
| 514 |
+
|
| 515 |
+
@media (max-width: 640px) {
|
| 516 |
+
.grid-2, .grid-4 { grid-template-columns: 1fr; }
|
| 517 |
+
}
|
| 518 |
+
"""
|
| 519 |
+
|
| 520 |
+
try:
|
| 521 |
+
with open("ui/styles/responsive.css", "r") as f:
|
| 522 |
+
css_content += f.read()
|
| 523 |
+
logger.info("β
Loaded responsive.css")
|
| 524 |
+
except FileNotFoundError:
|
| 525 |
+
# Fallback responsive utilities
|
| 526 |
+
css_content += """
|
| 527 |
+
.mobile-only { display: block; }
|
| 528 |
+
.desktop-only { display: none; }
|
| 529 |
+
|
| 530 |
+
@media (min-width: 768px) {
|
| 531 |
+
.mobile-only { display: none; }
|
| 532 |
+
.desktop-only { display: block; }
|
| 533 |
+
}
|
| 534 |
+
|
| 535 |
+
@media (max-width: 768px) {
|
| 536 |
+
.grid-2, .grid-4 { grid-template-columns: 1fr !important; }
|
| 537 |
+
}
|
| 538 |
+
"""
|
| 539 |
+
else:
|
| 540 |
+
# Minimal fallback CSS
|
| 541 |
+
css_content = """
|
| 542 |
+
:root { --color-primary: #3b82f6; }
|
| 543 |
+
.container { max-width: 1200px; margin: 0 auto; }
|
| 544 |
+
"""
|
| 545 |
+
|
| 546 |
+
return f"<style>{css_content}</style>"
|
| 547 |
+
|
| 548 |
# ===========================================
|
| 549 |
# ENHANCED VISUALIZATION FUNCTIONS WITH GRADIO COMPATIBILITY
|
| 550 |
# ===========================================
|
|
|
|
| 1988 |
"boundary_note": "Scenario not found"
|
| 1989 |
})
|
| 1990 |
|
| 1991 |
+
# Create scenario card HTML (MODERN: Use Card component if available)
|
| 1992 |
+
if get_feature_flags().get('modern_ui', False) and MODERN_UI_AVAILABLE:
|
| 1993 |
+
# Use modern Card component
|
| 1994 |
+
scenario_card_html = Card.create(
|
| 1995 |
+
title=scenario_name,
|
| 1996 |
+
content=f"""
|
| 1997 |
+
<div style="margin: 15px 0;">
|
| 1998 |
+
<div style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px;">
|
| 1999 |
+
<div style="padding: 4px 12px; background: var(--color-primary); color: white;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2000 |
border-radius: 12px; font-size: 12px; font-weight: bold;">
|
| 2001 |
{scenario["severity"]} SEVERITY
|
| 2002 |
</div>
|
| 2003 |
+
<div style="font-size: 13px; color: var(--text-secondary);">
|
| 2004 |
{scenario["component"]}
|
| 2005 |
</div>
|
| 2006 |
</div>
|
| 2007 |
+
|
| 2008 |
+
<div style="font-size: 14px; color: var(--text-secondary); line-height: 1.5;">
|
| 2009 |
+
<strong>Boundary Context:</strong> {scenario.get('boundary_note', 'OSS analyzes, Enterprise executes')}
|
| 2010 |
+
</div>
|
| 2011 |
</div>
|
| 2012 |
+
""",
|
| 2013 |
+
footer=f"Revenue Impact: ${scenario['business_impact'].get('revenue_loss_per_hour', get_scenario_impact(scenario_name)):,}/hour"
|
| 2014 |
+
)
|
| 2015 |
+
else:
|
| 2016 |
+
# Legacy scenario card
|
| 2017 |
+
severity_colors = {
|
| 2018 |
+
"HIGH": "#ef4444",
|
| 2019 |
+
"MEDIUM": "#f59e0b",
|
| 2020 |
+
"LOW": "#10b981"
|
| 2021 |
+
}
|
| 2022 |
+
severity_color = severity_colors.get(scenario["severity"], "#64748b")
|
| 2023 |
+
|
| 2024 |
+
impact = scenario["business_impact"].get("revenue_loss_per_hour", get_scenario_impact(scenario_name))
|
| 2025 |
+
|
| 2026 |
+
scenario_card_html = f"""
|
| 2027 |
+
<div style="border: 1px solid {severity_color}; border-radius: 14px; padding: 20px;
|
| 2028 |
+
background: linear-gradient(135deg, {severity_color}10 0%, #ffffff 100%);">
|
| 2029 |
|
| 2030 |
+
<div style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 15px;">
|
| 2031 |
+
<div>
|
| 2032 |
+
<h3 style="margin: 0 0 8px 0; font-size: 18px; color: #1e293b; font-weight: 700;">
|
| 2033 |
+
{scenario_name}
|
| 2034 |
+
</h3>
|
| 2035 |
+
<div style="display: flex; align-items: center; gap: 10px;">
|
| 2036 |
+
<div style="padding: 4px 12px; background: {severity_color}; color: white;
|
| 2037 |
+
border-radius: 12px; font-size: 12px; font-weight: bold;">
|
| 2038 |
+
{scenario["severity"]} SEVERITY
|
| 2039 |
+
</div>
|
| 2040 |
+
<div style="font-size: 13px; color: #64748b;">
|
| 2041 |
+
{scenario["component"]}
|
| 2042 |
+
</div>
|
| 2043 |
+
</div>
|
| 2044 |
</div>
|
| 2045 |
+
|
| 2046 |
+
<div style="text-align: right;">
|
| 2047 |
+
<div style="font-size: 28px; font-weight: 700; color: {severity_color};">
|
| 2048 |
+
${impact:,}
|
| 2049 |
+
</div>
|
| 2050 |
+
<div style="font-size: 12px; color: #64748b;">
|
| 2051 |
+
Revenue Loss/Hour
|
| 2052 |
+
</div>
|
| 2053 |
</div>
|
| 2054 |
</div>
|
| 2055 |
+
|
| 2056 |
+
<!-- Impact breakdown -->
|
| 2057 |
+
<div style="margin-top: 20px; padding-top: 20px; border-top: 1px solid #f1f5f9;">
|
| 2058 |
+
<div style="font-size: 14px; color: #475569; font-weight: 600; margin-bottom: 10px;">
|
| 2059 |
+
Business Impact Analysis
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2060 |
</div>
|
| 2061 |
+
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px;">
|
| 2062 |
+
<div style="text-align: center;">
|
| 2063 |
+
<div style="font-size: 16px; font-weight: 700; color: {severity_color};">45 min</div>
|
| 2064 |
+
<div style="font-size: 11px; color: #64748b;">Without ARF</div>
|
| 2065 |
+
</div>
|
| 2066 |
+
<div style="text-align: center;">
|
| 2067 |
+
<div style="font-size: 16px; font-weight: 700; color: #10b981;">12 min</div>
|
| 2068 |
+
<div style="font-size: 11px; color: #64748b;">With ARF</div>
|
| 2069 |
+
</div>
|
| 2070 |
+
<div style="text-align: center;">
|
| 2071 |
+
<div style="font-size: 16px; font-weight: 700; color: #10b981;">${int(impact * 0.85):,}</div>
|
| 2072 |
+
<div style="font-size: 11px; color: #64748b;">Savings</div>
|
| 2073 |
+
</div>
|
| 2074 |
</div>
|
| 2075 |
</div>
|
| 2076 |
+
|
| 2077 |
+
<!-- Boundary context -->
|
| 2078 |
+
<div style="margin-top: 20px; padding: 12px; background: #f8fafc; border-radius: 8px;
|
| 2079 |
+
border-left: 3px solid {severity_color}; font-size: 12px; color: #475569;">
|
| 2080 |
+
<strong>Boundary Context:</strong> {scenario.get('boundary_note', 'OSS analyzes, Enterprise executes')}
|
| 2081 |
+
</div>
|
| 2082 |
</div>
|
| 2083 |
+
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2084 |
|
| 2085 |
# Get visualizations as Plotly figures (ENHANCED)
|
| 2086 |
telemetry_fig = create_simple_telemetry_plot(scenario_name, settings.use_true_arf)
|
|
|
|
| 2320 |
return roi_result, fig
|
| 2321 |
|
| 2322 |
# ===========================================
|
| 2323 |
+
# CREATE DEMO INTERFACE - UPDATED WITH MODERN UI INTEGRATION
|
| 2324 |
# ===========================================
|
| 2325 |
def create_demo_interface():
|
| 2326 |
+
"""Create demo interface using modular components with boundary awareness and modern UI"""
|
| 2327 |
|
| 2328 |
import gradio as gr
|
| 2329 |
|
|
|
|
| 2331 |
components = get_components()
|
| 2332 |
|
| 2333 |
# Get CSS styles
|
| 2334 |
+
css_styles = load_css_files()
|
| 2335 |
|
| 2336 |
# Store CSS for later use in launch()
|
| 2337 |
global _demo_css
|
| 2338 |
_demo_css = css_styles
|
| 2339 |
|
| 2340 |
+
# Create interface with modern UI initialization
|
| 2341 |
with gr.Blocks(
|
| 2342 |
+
title=f"π ARF Investor Demo v3.3.9 - TRUE ARF OSS Integration",
|
| 2343 |
+
css=css_styles
|
| 2344 |
) as demo:
|
| 2345 |
|
| 2346 |
+
# MODERN UI INITIALIZATION
|
| 2347 |
+
if get_feature_flags().get('modern_ui', False) and MODERN_UI_AVAILABLE:
|
| 2348 |
+
modern_ui_init = gr.HTML(initialize_modern_ui())
|
| 2349 |
+
logger.info("β
Modern UI initialized")
|
| 2350 |
+
else:
|
| 2351 |
+
modern_ui_init = gr.HTML("<!-- Modern UI not enabled -->")
|
| 2352 |
+
|
| 2353 |
# Header
|
| 2354 |
header_html = components["create_header"]("3.3.9")
|
| 2355 |
|
|
|
|
| 2360 |
# ============ 5 TABS ============
|
| 2361 |
with gr.Tabs(elem_classes="tab-nav"):
|
| 2362 |
|
| 2363 |
+
# TAB 1: Live Incident Demo - NOW WITH MODERN COMPONENTS
|
| 2364 |
with gr.TabItem("π₯ Live Incident Demo", id="tab1"):
|
| 2365 |
# ===== SURGICAL FIX: SAFE UNPACKING WITH ERROR HANDLING =====
|
| 2366 |
try:
|
|
|
|
| 2850 |
outputs=[roi_output, roi_chart]
|
| 2851 |
)
|
| 2852 |
|
| 2853 |
+
logger.info("β
Demo interface created successfully with modern UI integration")
|
| 2854 |
|
| 2855 |
return demo
|
| 2856 |
# ===========================================
|
|
|
|
| 2870 |
logger.info(f" OSS: {boundaries['oss']['label']} v{boundaries['oss']['version']}")
|
| 2871 |
logger.info(f" Enterprise: {boundaries['enterprise']['label']} v{boundaries['enterprise']['version']}")
|
| 2872 |
logger.info(f" Mode: {boundaries['demo_mode']['architecture']}")
|
| 2873 |
+
logger.info(f" Modern UI: {'Enabled' if get_feature_flags().get('modern_ui', False) else 'Disabled'}")
|
| 2874 |
logger.info("=" * 60)
|
| 2875 |
|
| 2876 |
# Create interface
|
| 2877 |
demo = create_demo_interface()
|
| 2878 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2879 |
# Configure for Hugging Face Spaces
|
| 2880 |
launch_config = {
|
| 2881 |
"server_name": "0.0.0.0",
|
|
|
|
| 2889 |
}
|
| 2890 |
|
| 2891 |
# Add CSS if available
|
| 2892 |
+
css_styles = load_css_files()
|
| 2893 |
if css_styles:
|
| 2894 |
launch_config["css"] = css_styles
|
| 2895 |
|
|
|
|
| 2932 |
logger.info("Enhanced with clear OSS vs Enterprise boundaries")
|
| 2933 |
logger.info("DOCTRINAL COMPLIANCE: Historical Evidence, Observation Gate, Sequencing")
|
| 2934 |
logger.info("PHASE 2: Dynamic Performance Metrics by Scenario")
|
| 2935 |
+
logger.info(f"Modern UI: {'Enabled' if get_feature_flags().get('modern_ui', False) else 'Disabled'}")
|
| 2936 |
logger.info(f"True ARF OSS v3.3.9 integration with simulated Enterprise execution")
|
| 2937 |
logger.info("=" * 60)
|
| 2938 |
|
|
|
|
| 2943 |
print("π ARF Ultimate Investor Demo v3.3.9 - ENTERPRISE EDITION")
|
| 2944 |
print("π Architecture: OSS advises β Enterprise executes")
|
| 2945 |
print("π DOCTRINAL: Historical Evidence + Observation Gate + Sequencing")
|
| 2946 |
+
print("π¨ MODERN UI: Design system with responsive components")
|
| 2947 |
print("π Starting on http://localhost:7860")
|
| 2948 |
print("="*60 + "\n")
|
| 2949 |
|